[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>
This commit is contained in:
parent
8366025eb8
commit
aceaf78da9
3 changed files with 22 additions and 3 deletions
|
@ -211,6 +211,23 @@ void fput(struct file *file)
|
|||
|
||||
EXPORT_SYMBOL(fput);
|
||||
|
||||
/**
|
||||
* drop_file_write_access - give up ability to write to a file
|
||||
* @file: the file to which we will stop writing
|
||||
*
|
||||
* This is a central place which will give up the ability
|
||||
* to write to @file, along with access to write through
|
||||
* its vfsmount.
|
||||
*/
|
||||
void drop_file_write_access(struct file *file)
|
||||
{
|
||||
struct dentry *dentry = file->f_path.dentry;
|
||||
struct inode *inode = dentry->d_inode;
|
||||
|
||||
put_write_access(inode);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(drop_file_write_access);
|
||||
|
||||
/* __fput is called from task context when aio completion releases the last
|
||||
* last use of a struct file *. Do not use otherwise.
|
||||
*/
|
||||
|
@ -236,10 +253,10 @@ void __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)
|
||||
put_write_access(inode);
|
||||
put_pid(file->f_owner.pid);
|
||||
file_kill(file);
|
||||
if (file->f_mode & FMODE_WRITE)
|
||||
drop_file_write_access(file);
|
||||
file->f_path.dentry = NULL;
|
||||
file->f_path.mnt = NULL;
|
||||
file_free(file);
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfsd/cache.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/smp_lock.h>
|
||||
|
@ -1239,7 +1240,7 @@ static inline void
|
|||
nfs4_file_downgrade(struct file *filp, unsigned int share_access)
|
||||
{
|
||||
if (share_access & NFS4_SHARE_ACCESS_WRITE) {
|
||||
put_write_access(filp->f_path.dentry->d_inode);
|
||||
drop_file_write_access(filp);
|
||||
filp->f_mode = (filp->f_mode | FMODE_READ) & ~FMODE_WRITE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ extern struct kmem_cache *filp_cachep;
|
|||
|
||||
extern void __fput(struct file *);
|
||||
extern void fput(struct file *);
|
||||
extern void drop_file_write_access(struct file *file);
|
||||
|
||||
struct file_operations;
|
||||
struct vfsmount;
|
||||
|
|
Loading…
Reference in a new issue