[PATCH 05/24] elevate write count open()'d files

!MAILaRCHIVE_VOTE_RePLACE
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: <akpm@...>
Cc: <linux-kernel@...>, <hch@...>, Dave Hansen <haveblue@...>
Date: Monday, September 17, 2007 - 2:27 pm

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 needs to be kept elevated
all the way into the may_open() call.  Otherwise, when the
write is dropped, a ro->rw transisition could occur.  This
would lead to having rw access on the newly created file,
while the vfsmount is ro.  That is bad.

Some filesystems forego the use of normal vfs calls to create
struct files.  Make sure that these users elevate the mnt writer
count because they will get __fput(), and we need to make
sure they're balanced.

Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
---

 lxc-dave/fs/file_table.c |    9 ++++++++-
 lxc-dave/fs/namei.c      |   20 ++++++++++++++++----
 lxc-dave/ipc/mqueue.c    |    3 +++
 3 files changed, 27 insertions(+), 5 deletions(-)

diff -puN fs/file_table.c~tricky-elevate-write-count-files-are-open-ed fs/file_table.c
--- lxc/fs/file_table.c~tricky-elevate-write-count-files-are-open-ed	2007-09-17 09:43:57.000000000 -0700
+++ lxc-dave/fs/file_table.c	2007-09-17 09:43:57.000000000 -0700
@@ -167,6 +167,10 @@ int init_file(struct file *file, struct 
 	file->f_mapping = dentry->d_inode->i_mapping;
 	file->f_mode = mode;
 	file->f_op = fop;
+	if (mode & FMODE_WRITE) {
+		error = mnt_want_write(mnt);
+		WARN_ON(error);
+	}
 	return error;
 }
 EXPORT_SYMBOL(init_file);
@@ -204,8 +208,11 @@ void fastcall __fput(struct file *file)
 	if (unlikely(S_ISCHR(inode->i_mode) && 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);
+	}
 	put_pid(file->f_owner.pid);
 	file_kill(file);
 	file->f_path.dentry = NULL;
diff -puN fs/namei.c~tricky-elevate-write-count-files-are-open-ed fs/namei.c
--- lxc/fs/namei.c~tricky-elevate-write-count-files-are-open-ed	2007-09-17 09:43:57.000000000 -0700
+++ lxc-dave/fs/namei.c	2007-09-17 09:43:57.000000000 -0700
@@ -1620,8 +1620,15 @@ 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;
+	}
 
 	error = vfs_permission(nd, acc_mode);
 	if (error)
@@ -1764,14 +1771,17 @@ do_last:
 	}
 
 	if (IS_ERR(nd->intent.open.file)) {
-		mutex_unlock(&dir->d_inode->i_mutex);
 		error = PTR_ERR(nd->intent.open.file);
-		goto exit_dput;
+		goto exit_mutex_unlock;
 	}
 
 	/* Negative dentry, just create the file */
 	if (!path.dentry->d_inode) {
+		error = mnt_want_write(nd->mnt);
+		if (error)
+			goto exit_mutex_unlock;
 		error = open_namei_create(nd, &path, flag, mode);
+		mnt_drop_write(nd->mnt);
 		if (error)
 			goto exit;
 		return 0;
@@ -1809,6 +1819,8 @@ ok:
 		goto exit;
 	return 0;
 
+exit_mutex_unlock:
+	mutex_unlock(&dir->d_inode->i_mutex);
 exit_dput:
 	dput_path(&path, nd);
 exit:
diff -puN ipc/mqueue.c~tricky-elevate-write-count-files-are-open-ed ipc/mqueue.c
--- lxc/ipc/mqueue.c~tricky-elevate-write-count-files-are-open-ed	2007-09-17 09:43:57.000000000 -0700
+++ lxc-dave/ipc/mqueue.c	2007-09-17 09:43:57.000000000 -0700
@@ -683,6 +683,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);
 		}
_
-
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[PATCH 00/24] Read-only bind mounts, Dave Hansen, (Mon Sep 17, 2:27 pm)
Re: [PATCH 00/24] Read-only bind mounts, Christoph Hellwig, (Wed Sep 19, 1:44 pm)
Re: [PATCH 00/24] Read-only bind mounts, Andrew Morton, (Wed Sep 19, 5:24 pm)
Re: [PATCH 00/24] Read-only bind mounts, Dave Hansen, (Wed Sep 19, 5:56 pm)
Re: [PATCH 00/24] Read-only bind mounts, Andrew Morton, (Wed Sep 19, 6:06 pm)
Re: [PATCH 00/24] Read-only bind mounts, Miklos Szeredi, (Thu Sep 20, 5:58 am)
Re: [PATCH 00/24] Read-only bind mounts, Serge E. Hallyn, (Wed Sep 19, 10:21 am)
Re: [PATCH 14/24] unix_find_other() elevate write count for ..., Christoph Hellwig, (Wed Sep 19, 1:35 pm)
[PATCH 22/24] do_rmdir(): elevate write count, Dave Hansen, (Mon Sep 17, 2:27 pm)
Re: [PATCH 22/24] do_rmdir(): elevate write count, Christoph Hellwig, (Wed Sep 19, 1:39 pm)
Re: [PATCH 21/24] elevate mnt writers for vfs_unlink() callers, Christoph Hellwig, (Wed Sep 19, 1:38 pm)
Re: [PATCH 19/24] elevate write count for do_sys_utime() and..., Christoph Hellwig, (Wed Sep 19, 1:36 pm)
Re: [PATCH 20/24] sys_mknodat(): elevate write count for vfs..., Christoph Hellwig, (Wed Sep 19, 1:38 pm)
Re: [PATCH 09/24] elevate mnt writers for callers of vfs_mkd..., Christoph Hellwig, (Wed Sep 19, 1:32 pm)
[PATCH 04/24] r/o bind mounts: stub functions, Dave Hansen, (Mon Sep 17, 2:27 pm)
Re: [PATCH 04/24] r/o bind mounts: stub functions, Christoph Hellwig, (Wed Sep 19, 1:28 pm)
Re: [PATCH 11/24] elevate write count for link and symlink c..., Christoph Hellwig, (Wed Sep 19, 1:33 pm)
Re: [PATCH 06/24] r/o bind mounts: elevate write count for s..., Christoph Hellwig, (Wed Sep 19, 1:31 pm)
[PATCH 18/24] elevate write count for do_utimes(), Dave Hansen, (Mon Sep 17, 2:27 pm)
Re: [PATCH 18/24] elevate write count for do_utimes(), Christoph Hellwig, (Wed Sep 19, 1:36 pm)
Re: [PATCH 16/24] nfs: check mnt instead of superblock direc..., Christoph Hellwig, (Wed Sep 19, 1:36 pm)
Re: [PATCH 17/24] elevate writer count for do_sys_truncate(), Christoph Hellwig, (Wed Sep 19, 1:36 pm)
Re: [PATCH 15/24] elevate write count over calls to vfs_rena..., Christoph Hellwig, (Wed Sep 19, 1:35 pm)
Re: [PATCH 12/24] elevate mount count for extended attributes, Christoph Hellwig, (Wed Sep 19, 1:34 pm)
Re: [PATCH 10/24] elevate write count during entire ncp_ioct..., Christoph Hellwig, (Wed Sep 19, 1:33 pm)
Re: [PATCH 01/24] filesystem helpers for custom 'struct file's, Christoph Hellwig, (Wed Sep 19, 1:26 pm)
Re: [PATCH] docuement filesystem helpers for custom 'struct ..., Christoph Hellwig, (Thu Sep 20, 1:30 pm)
[PATCH 05/24] elevate write count open()'d files, Dave Hansen, (Mon Sep 17, 2:27 pm)
Re: [PATCH 05/24] elevate write count open()'d files, Christoph Hellwig, (Wed Sep 19, 1:30 pm)
Re: [PATCH 07/24] elevate writer count for chown and friends, Christoph Hellwig, (Wed Sep 19, 1:31 pm)
Re: [PATCH 13/24] elevate write count for file_update_time(), Christoph Hellwig, (Wed Sep 19, 1:35 pm)
[PATCH 08/24] make access() use mnt check, Dave Hansen, (Mon Sep 17, 2:27 pm)
Re: [PATCH 08/24] make access() use mnt check, Christoph Hellwig, (Wed Sep 19, 1:32 pm)
[PATCH 03/24] create cleanup helper svc_msnfs(), Dave Hansen, (Mon Sep 17, 2:27 pm)
Re: [PATCH 03/24] create cleanup helper svc_msnfs(), Jan Engelhardt, (Wed Sep 19, 1:39 pm)
Re: [PATCH 03/24] create cleanup helper svc_msnfs(), Dave Hansen, (Wed Sep 19, 1:45 pm)
Re: [PATCH 03/24] create cleanup helper svc_msnfs(), Trond Myklebust, (Wed Sep 19, 1:54 pm)
Re: [PATCH 03/24] create cleanup helper svc_msnfs(), Christoph Hellwig, (Wed Sep 19, 1:59 pm)
Re: [PATCH 03/24] create cleanup helper svc_msnfs(), Trond Myklebust, (Wed Sep 19, 2:10 pm)
Re: [PATCH 03/24] create cleanup helper svc_msnfs(), Christoph Hellwig, (Wed Sep 19, 1:28 pm)
[PATCH 02/24] rearrange may_open() to be r/o friendly, Dave Hansen, (Mon Sep 17, 2:27 pm)
Re: [PATCH 02/24] rearrange may_open() to be r/o friendly, Christoph Hellwig, (Wed Sep 19, 1:27 pm)