diff options
author | Dave Hansen <haveblue@us.ibm.com> | 2008-02-15 17:37:31 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-04-19 00:25:32 -0400 |
commit | aceaf78da92a53f5e1b105649a1b8c0afdb2135c (patch) | |
tree | cab04e05f8b504b0a11d4986045bc3b08a3a1e75 /fs/file_table.c | |
parent | 8366025eb80dfa0d8d94b286d53027081c280ef1 (diff) |
[PATCH] r/o bind mounts: create helper to drop file write access
If someone decides to demote a file from r/w to just
r/o, they can use this same code as __fput().
NFS does just that, and will use this in the next
patch.
AV: drop write access in __fput() only after we evict from file list.
Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
Cc: Erez Zadok <ezk@cs.sunysb.edu>
Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
Cc: "J Bruce Fields" <bfields@fieldses.org>
Acked-by: Al Viro <viro@ZenIV.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/file_table.c')
-rw-r--r-- | fs/file_table.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/fs/file_table.c b/fs/file_table.c index 986ff4ed0a7c..3f73eb1f195a 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -211,6 +211,23 @@ void fput(struct file *file) | |||
211 | 211 | ||
212 | EXPORT_SYMBOL(fput); | 212 | EXPORT_SYMBOL(fput); |
213 | 213 | ||
214 | /** | ||
215 | * drop_file_write_access - give up ability to write to a file | ||
216 | * @file: the file to which we will stop writing | ||
217 | * | ||
218 | * This is a central place which will give up the ability | ||
219 | * to write to @file, along with access to write through | ||
220 | * its vfsmount. | ||
221 | */ | ||
222 | void drop_file_write_access(struct file *file) | ||
223 | { | ||
224 | struct dentry *dentry = file->f_path.dentry; | ||
225 | struct inode *inode = dentry->d_inode; | ||
226 | |||
227 | put_write_access(inode); | ||
228 | } | ||
229 | EXPORT_SYMBOL_GPL(drop_file_write_access); | ||
230 | |||
214 | /* __fput is called from task context when aio completion releases the last | 231 | /* __fput is called from task context when aio completion releases the last |
215 | * last use of a struct file *. Do not use otherwise. | 232 | * last use of a struct file *. Do not use otherwise. |
216 | */ | 233 | */ |
@@ -236,10 +253,10 @@ void __fput(struct file *file) | |||
236 | if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL)) | 253 | if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL)) |
237 | cdev_put(inode->i_cdev); | 254 | cdev_put(inode->i_cdev); |
238 | fops_put(file->f_op); | 255 | fops_put(file->f_op); |
239 | if (file->f_mode & FMODE_WRITE) | ||
240 | put_write_access(inode); | ||
241 | put_pid(file->f_owner.pid); | 256 | put_pid(file->f_owner.pid); |
242 | file_kill(file); | 257 | file_kill(file); |
258 | if (file->f_mode & FMODE_WRITE) | ||
259 | drop_file_write_access(file); | ||
243 | file->f_path.dentry = NULL; | 260 | file->f_path.dentry = NULL; |
244 | file->f_path.mnt = NULL; | 261 | file->f_path.mnt = NULL; |
245 | file_free(file); | 262 | file_free(file); |