From: Dave Hansen <haveblue@us.ibm.com>
To: linux-fsdevel@vger.kernel.org
Cc: herbert@13thfloor.at, viro@ftp.linux.org.uk, hch@infradead.org,
trond.myklebust@fys.uio.no, Dave Hansen <haveblue@us.ibm.com>
Subject: [RFC][PATCH 14/27] tricky: elevate write count files are open()ed
Date: Wed, 07 Jun 2006 17:10:25 -0700 [thread overview]
Message-ID: <20060608001025.B1665091@localhost.localdomain> (raw)
In-Reply-To: <20060608001013.0D041507@localhost.localdomain>
This is the first really tricky patch in the series. It
elevates the writer count on a mount each time a
non-special file is opened for write.
This is not completely apparent in the patch because the
two if() conditions in may_open() above the
mnt_want_write() call are, combined, equivalent to
special_file().
There is also an elevated count around the vfs_create()
call in open_namei(). The count does not need to be
kept elevated all the way into the may_open() call because
after creation, the write bits of the acc_mode are cleared.
This keeps may_open() from ever failing. Howver, this may
open one potential race where a change from a r/w to a r/o
mount could occur between the mnt_drop_write() and may_open()
allowing a user to obtain a r/w file on what is now a r/w
mount. But, this functionality does not yet exist.
Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
---
lxc-dave/fs/file_table.c | 5 ++++-
lxc-dave/fs/namei.c | 29 ++++++++++++++++++++++++++---
lxc-dave/ipc/mqueue.c | 3 +++
3 files changed, 33 insertions(+), 4 deletions(-)
diff -puN fs/namei.c~elevate-writers-opens-part1 fs/namei.c
--- lxc/fs/namei.c~elevate-writers-opens-part1 2006-06-07 16:53:20.000000000 -0700
+++ lxc-dave/fs/namei.c 2006-06-07 16:53:20.000000000 -0700
@@ -1511,8 +1511,17 @@ int may_open(struct nameidata *nd, int a
return -EACCES;
flag &= ~O_TRUNC;
- } else if (IS_RDONLY(inode) && (flag & FMODE_WRITE))
- return -EROFS;
+ } else if (flag & FMODE_WRITE) {
+ /*
+ * effectively: !special_file()
+ * balanced by __fput()
+ */
+ error = mnt_want_write(nd->mnt);
+ if (error)
+ return error;
+ if (IS_RDONLY(inode))
+ return -EROFS;
+ }
/*
* An append-only file must be opened in append mode for writing.
*/
@@ -1642,10 +1651,24 @@ do_last:
if (!path.dentry->d_inode) {
if (!IS_POSIXACL(dir->d_inode))
mode &= ~current->fs->umask;
- error = vfs_create(dir->d_inode, path.dentry, mode, nd);
+ /*
+ * this serves dual roles, it makes sure there is no
+ * r/o mount, and keeps the write count for what is
+ * the newly created file
+ */
+ error = mnt_want_write(nd->mnt);
+ if (!error)
+ error = vfs_create(dir->d_inode, path.dentry, mode, nd);
mutex_unlock(&dir->d_inode->i_mutex);
dput(nd->dentry);
nd->dentry = path.dentry;
+ /*
+ * Unconditionally drop the write access because
+ * the acc_mode=0 set below will keep may_open()
+ * from ever failing if there was a r/o mount
+ * between here and there
+ */
+ mnt_drop_write(nd->mnt);
if (error)
goto exit;
/* Don't check for write permission, don't truncate */
diff -puN fs/open.c~elevate-writers-opens-part1 fs/open.c
diff -puN include/linux/mount.h~elevate-writers-opens-part1 include/linux/mount.h
diff -puN fs/file_table.c~elevate-writers-opens-part1 fs/file_table.c
--- lxc/fs/file_table.c~elevate-writers-opens-part1 2006-06-07 16:53:20.000000000 -0700
+++ lxc-dave/fs/file_table.c 2006-06-07 16:53:20.000000000 -0700
@@ -180,8 +180,11 @@ void fastcall __fput(struct file *file)
if (unlikely(inode->i_cdev != NULL))
cdev_put(inode->i_cdev);
fops_put(file->f_op);
- if (file->f_mode & FMODE_WRITE)
+ if (file->f_mode & FMODE_WRITE) {
put_write_access(inode);
+ if(!special_file(inode->i_mode))
+ mnt_drop_write(mnt);
+ }
file_kill(file);
file->f_dentry = NULL;
file->f_vfsmnt = NULL;
diff -puN ipc/mqueue.c~elevate-writers-opens-part1 ipc/mqueue.c
--- lxc/ipc/mqueue.c~elevate-writers-opens-part1 2006-06-07 16:53:20.000000000 -0700
+++ lxc-dave/ipc/mqueue.c 2006-06-07 16:53:20.000000000 -0700
@@ -679,6 +679,9 @@ asmlinkage long sys_mq_open(const char _
goto out;
filp = do_open(dentry, oflag);
} else {
+ error = mnt_want_write(mqueue_mnt);
+ if (error)
+ goto out;
filp = do_create(mqueue_mnt->mnt_root, dentry,
oflag, mode, u_attr);
}
_
next prev parent reply other threads:[~2006-06-08 0:10 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-06-08 0:10 [RFC][PATCH 00/27] Read-only bind mounts Dave Hansen
2006-06-08 0:10 ` [RFC][PATCH 01/27] Add vfsmount writer count Dave Hansen
2006-06-08 10:33 ` Herbert Poetzl
2006-06-08 0:10 ` [RFC][PATCH 02/27] vfs_rmdir: change if() into goto Dave Hansen
2006-06-08 10:37 ` Herbert Poetzl
2006-06-08 0:10 ` [RFC][PATCH 04/27] elevate mnt writers for vfs_unlink() callers Dave Hansen
2006-06-08 0:10 ` [RFC][PATCH 03/27] do_rmdir(): elevate write count Dave Hansen
2006-06-08 10:42 ` Herbert Poetzl
2006-06-08 15:04 ` Dave Hansen
2006-06-08 0:10 ` [RFC][PATCH 05/27] elevate mnt writers for nfsd caller of vfs_mkdir() Dave Hansen
2006-06-08 0:10 ` [RFC][PATCH 06/27] elevate write count during entire ncp_ioctl() Dave Hansen
2006-06-08 10:44 ` Herbert Poetzl
2006-06-08 15:07 ` Dave Hansen
2006-06-08 0:10 ` [RFC][PATCH 07/27] sys_mkdirat(): collapse if() Dave Hansen
2006-06-08 10:46 ` Herbert Poetzl
2006-06-08 15:10 ` Dave Hansen
2006-06-08 15:54 ` Herbert Poetzl
2006-06-08 0:10 ` [RFC][PATCH 09/27] elevate mnt writers for sys_mkdirat() call of vfs_mkdir() Dave Hansen
2006-06-08 0:10 ` [RFC][PATCH 08/27] sys_mkdirat(): one more goto Dave Hansen
2006-06-08 10:48 ` Herbert Poetzl
2006-06-08 0:10 ` [RFC][PATCH 10/27] sys_symlinkat() collapse if()s Dave Hansen
2006-06-08 0:10 ` [RFC][PATCH 11/27] sys_symlinkat() collapse one more if () Dave Hansen
2006-06-08 10:49 ` Herbert Poetzl
2006-06-08 0:10 ` [RFC][PATCH 13/27] sys_linkat(): elevate write count around vfs_link() Dave Hansen
2006-06-08 0:10 ` [RFC][PATCH 12/27] sys_symlinkat() elevate write count around vfs_symlink() Dave Hansen
2006-06-08 0:10 ` Dave Hansen [this message]
2006-06-08 10:54 ` [RFC][PATCH 14/27] tricky: elevate write count files are open()ed Herbert Poetzl
2006-06-08 15:12 ` Dave Hansen
2006-06-08 16:07 ` Herbert Poetzl
2006-06-08 0:10 ` [RFC][PATCH 15/27] elevate writer count for do_sys_truncate() Dave Hansen
2006-06-08 0:10 ` [RFC][PATCH 16/27] elevate write count for do_sys_utime() Dave Hansen
2006-06-08 0:10 ` [RFC][PATCH 17/27] elevate write count for do_utimes() Dave Hansen
2006-06-08 0:10 ` [RFC][PATCH 19/27] sys_faccessat() elevate writer count Dave Hansen
2006-06-08 11:03 ` Herbert Poetzl
2006-06-08 15:15 ` Dave Hansen
2006-06-08 0:10 ` [RFC][PATCH 18/27] sys_faccessat(): collapse if() Dave Hansen
2006-06-08 11:05 ` Herbert Poetzl
2006-06-08 0:10 ` [RFC][PATCH 20/27] unix_find_other() elevate write count for touch_atime() Dave Hansen
2006-06-08 11:07 ` Herbert Poetzl
2006-06-08 0:10 ` [RFC][PATCH 21/27] mount_is_safe(): add comment Dave Hansen
2006-06-08 0:10 ` [RFC][PATCH 22/27] sys_mknodat(): elevate write count for vfs_mknod/create() Dave Hansen
2006-06-08 11:16 ` Herbert Poetzl
2006-06-08 15:23 ` Dave Hansen
2006-06-08 0:10 ` [RFC][PATCH 23/27] elevate write count over calls to vfs_rename() Dave Hansen
2006-06-08 11:23 ` Herbert Poetzl
2006-06-08 15:24 ` Dave Hansen
2006-06-12 18:18 ` Al Viro
2006-06-12 18:29 ` Dave Hansen
2006-06-12 19:03 ` Al Viro
2006-06-08 0:10 ` [RFC][PATCH 24/27] elevate mount count for extended attributes Dave Hansen
2006-06-08 0:10 ` [RFC][PATCH 25/27] /proc/mounts: prep for flags from sb or mnt Dave Hansen
2006-06-08 11:25 ` Herbert Poetzl
2006-06-08 0:10 ` [RFC][PATCH 27/27] create and pass read-only mnt flag into do_loopback() Dave Hansen
2006-06-08 0:10 ` [RFC][PATCH 26/27] /proc/mounts: treat ro/rw like the rest Dave Hansen
2006-06-08 11:26 ` Herbert Poetzl
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060608001025.B1665091@localhost.localdomain \
--to=haveblue@us.ibm.com \
--cc=hch@infradead.org \
--cc=herbert@13thfloor.at \
--cc=linux-fsdevel@vger.kernel.org \
--cc=trond.myklebust@fys.uio.no \
--cc=viro@ftp.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).