Commit 75e1fcc0 authored by Miklos Szeredi's avatar Miklos Szeredi Committed by Linus Torvalds

[PATCH] vfs: add lock owner argument to flush operation

Pass the POSIX lock owner ID to the flush operation.

This is useful for filesystems which don't want to store any locking state
in inode->i_flock but want to handle locking/unlocking POSIX locks
internally.  FUSE is one such filesystem but I think it possible that some
network filesystems would need this also.

Also add a flag to indicate that a POSIX locking request was generated by
close(), so filesystems using the above feature won't send an extra locking
request in this case.
Signed-off-by: default avatarMiklos Szeredi <miklos@szeredi.hu>
Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent ff7b86b8
...@@ -532,7 +532,6 @@ static ctl_table pfm_sysctl_root[] = { ...@@ -532,7 +532,6 @@ static ctl_table pfm_sysctl_root[] = {
static struct ctl_table_header *pfm_sysctl_header; static struct ctl_table_header *pfm_sysctl_header;
static int pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs); static int pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs);
static int pfm_flush(struct file *filp);
#define pfm_get_cpu_var(v) __ia64_per_cpu_var(v) #define pfm_get_cpu_var(v) __ia64_per_cpu_var(v)
#define pfm_get_cpu_data(a,b) per_cpu(a, b) #define pfm_get_cpu_data(a,b) per_cpu(a, b)
...@@ -1774,7 +1773,7 @@ pfm_syswide_cleanup_other_cpu(pfm_context_t *ctx) ...@@ -1774,7 +1773,7 @@ pfm_syswide_cleanup_other_cpu(pfm_context_t *ctx)
* When caller is self-monitoring, the context is unloaded. * When caller is self-monitoring, the context is unloaded.
*/ */
static int static int
pfm_flush(struct file *filp) pfm_flush(struct file *filp, fl_owner_t id)
{ {
pfm_context_t *ctx; pfm_context_t *ctx;
struct task_struct *task; struct task_struct *task;
......
...@@ -82,7 +82,7 @@ static int evdev_fasync(int fd, struct file *file, int on) ...@@ -82,7 +82,7 @@ static int evdev_fasync(int fd, struct file *file, int on)
return retval < 0 ? retval : 0; return retval < 0 ? retval : 0;
} }
static int evdev_flush(struct file * file) static int evdev_flush(struct file * file, fl_owner_t id)
{ {
struct evdev_list *list = file->private_data; struct evdev_list *list = file->private_data;
if (!list->evdev->exist) return -ENODEV; if (!list->evdev->exist) return -ENODEV;
......
...@@ -4724,7 +4724,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) ...@@ -4724,7 +4724,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp)
/* Flush the tape buffer before close */ /* Flush the tape buffer before close */
static int os_scsi_tape_flush(struct file * filp) static int os_scsi_tape_flush(struct file * filp, fl_owner_t id)
{ {
int result = 0, result2; int result = 0, result2;
struct osst_tape * STp = filp->private_data; struct osst_tape * STp = filp->private_data;
......
...@@ -1193,7 +1193,7 @@ static int st_open(struct inode *inode, struct file *filp) ...@@ -1193,7 +1193,7 @@ static int st_open(struct inode *inode, struct file *filp)
/* Flush the tape buffer before close */ /* Flush the tape buffer before close */
static int st_flush(struct file *filp) static int st_flush(struct file *filp, fl_owner_t id)
{ {
int result = 0, result2; int result = 0, result2;
unsigned char cmd[MAX_COMMAND_SIZE]; unsigned char cmd[MAX_COMMAND_SIZE];
......
...@@ -74,7 +74,7 @@ extern ssize_t cifs_user_write(struct file *file, const char __user *write_data, ...@@ -74,7 +74,7 @@ extern ssize_t cifs_user_write(struct file *file, const char __user *write_data,
size_t write_size, loff_t * poffset); size_t write_size, loff_t * poffset);
extern int cifs_lock(struct file *, int, struct file_lock *); extern int cifs_lock(struct file *, int, struct file_lock *);
extern int cifs_fsync(struct file *, struct dentry *, int); extern int cifs_fsync(struct file *, struct dentry *, int);
extern int cifs_flush(struct file *); extern int cifs_flush(struct file *, fl_owner_t id);
extern int cifs_file_mmap(struct file * , struct vm_area_struct *); extern int cifs_file_mmap(struct file * , struct vm_area_struct *);
extern const struct file_operations cifs_dir_ops; extern const struct file_operations cifs_dir_ops;
extern int cifs_dir_open(struct inode *inode, struct file *file); extern int cifs_dir_open(struct inode *inode, struct file *file);
......
...@@ -1417,7 +1417,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) ...@@ -1417,7 +1417,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
* As file closes, flush all cached write data for this inode checking * As file closes, flush all cached write data for this inode checking
* for write behind errors. * for write behind errors.
*/ */
int cifs_flush(struct file *file) int cifs_flush(struct file *file, fl_owner_t id)
{ {
struct inode * inode = file->f_dentry->d_inode; struct inode * inode = file->f_dentry->d_inode;
int rc = 0; int rc = 0;
......
...@@ -164,7 +164,7 @@ int coda_open(struct inode *coda_inode, struct file *coda_file) ...@@ -164,7 +164,7 @@ int coda_open(struct inode *coda_inode, struct file *coda_file)
return 0; return 0;
} }
int coda_flush(struct file *coda_file) int coda_flush(struct file *coda_file, fl_owner_t id)
{ {
unsigned short flags = coda_file->f_flags & ~O_EXCL; unsigned short flags = coda_file->f_flags & ~O_EXCL;
unsigned short coda_flags = coda_flags_to_cflags(flags); unsigned short coda_flags = coda_flags_to_cflags(flags);
......
...@@ -169,7 +169,7 @@ static int fuse_release(struct inode *inode, struct file *file) ...@@ -169,7 +169,7 @@ static int fuse_release(struct inode *inode, struct file *file)
return fuse_release_common(inode, file, 0); return fuse_release_common(inode, file, 0);
} }
static int fuse_flush(struct file *file) static int fuse_flush(struct file *file, fl_owner_t id)
{ {
struct inode *inode = file->f_dentry->d_inode; struct inode *inode = file->f_dentry->d_inode;
struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_conn *fc = get_fuse_conn(inode);
......
...@@ -1907,7 +1907,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner) ...@@ -1907,7 +1907,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner)
return; return;
lock.fl_type = F_UNLCK; lock.fl_type = F_UNLCK;
lock.fl_flags = FL_POSIX; lock.fl_flags = FL_POSIX | FL_CLOSE;
lock.fl_start = 0; lock.fl_start = 0;
lock.fl_end = OFFSET_MAX; lock.fl_end = OFFSET_MAX;
lock.fl_owner = owner; lock.fl_owner = owner;
......
...@@ -43,7 +43,7 @@ static int nfs_file_mmap(struct file *, struct vm_area_struct *); ...@@ -43,7 +43,7 @@ static int nfs_file_mmap(struct file *, struct vm_area_struct *);
static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *); static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *);
static ssize_t nfs_file_read(struct kiocb *, char __user *, size_t, loff_t); static ssize_t nfs_file_read(struct kiocb *, char __user *, size_t, loff_t);
static ssize_t nfs_file_write(struct kiocb *, const char __user *, size_t, loff_t); static ssize_t nfs_file_write(struct kiocb *, const char __user *, size_t, loff_t);
static int nfs_file_flush(struct file *); static int nfs_file_flush(struct file *, fl_owner_t id);
static int nfs_fsync(struct file *, struct dentry *dentry, int datasync); static int nfs_fsync(struct file *, struct dentry *dentry, int datasync);
static int nfs_check_flags(int flags); static int nfs_check_flags(int flags);
static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
...@@ -188,7 +188,7 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin) ...@@ -188,7 +188,7 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
* *
*/ */
static int static int
nfs_file_flush(struct file *file) nfs_file_flush(struct file *file, fl_owner_t id)
{ {
struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data; struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data;
struct inode *inode = file->f_dentry->d_inode; struct inode *inode = file->f_dentry->d_inode;
......
...@@ -1152,7 +1152,7 @@ int filp_close(struct file *filp, fl_owner_t id) ...@@ -1152,7 +1152,7 @@ int filp_close(struct file *filp, fl_owner_t id)
} }
if (filp->f_op && filp->f_op->flush) if (filp->f_op && filp->f_op->flush)
retval = filp->f_op->flush(filp); retval = filp->f_op->flush(filp, id);
dnotify_flush(filp, id); dnotify_flush(filp, id);
locks_remove_posix(filp, id); locks_remove_posix(filp, id);
......
...@@ -36,7 +36,7 @@ extern const struct file_operations coda_ioctl_operations; ...@@ -36,7 +36,7 @@ extern const struct file_operations coda_ioctl_operations;
/* operations shared over more than one file */ /* operations shared over more than one file */
int coda_open(struct inode *i, struct file *f); int coda_open(struct inode *i, struct file *f);
int coda_flush(struct file *f); int coda_flush(struct file *f, fl_owner_t id);
int coda_release(struct inode *i, struct file *f); int coda_release(struct inode *i, struct file *f);
int coda_permission(struct inode *inode, int mask, struct nameidata *nd); int coda_permission(struct inode *inode, int mask, struct nameidata *nd);
int coda_revalidate_inode(struct dentry *); int coda_revalidate_inode(struct dentry *);
......
...@@ -683,6 +683,7 @@ extern spinlock_t files_lock; ...@@ -683,6 +683,7 @@ extern spinlock_t files_lock;
#define FL_FLOCK 2 #define FL_FLOCK 2
#define FL_ACCESS 8 /* not trying to lock, just looking */ #define FL_ACCESS 8 /* not trying to lock, just looking */
#define FL_LEASE 32 /* lease held on this file */ #define FL_LEASE 32 /* lease held on this file */
#define FL_CLOSE 64 /* unlock on close */
#define FL_SLEEP 128 /* A blocking lock */ #define FL_SLEEP 128 /* A blocking lock */
/* /*
...@@ -1025,7 +1026,7 @@ struct file_operations { ...@@ -1025,7 +1026,7 @@ struct file_operations {
long (*compat_ioctl) (struct file *, unsigned int, unsigned long); long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *); int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *); int (*open) (struct inode *, struct file *);
int (*flush) (struct file *); int (*flush) (struct file *, fl_owner_t id);
int (*release) (struct inode *, struct file *); int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, struct dentry *, int datasync); int (*fsync) (struct file *, struct dentry *, int datasync);
int (*aio_fsync) (struct kiocb *, int datasync); int (*aio_fsync) (struct kiocb *, int datasync);
......
...@@ -359,7 +359,7 @@ static ssize_t mqueue_read_file(struct file *filp, char __user *u_data, ...@@ -359,7 +359,7 @@ static ssize_t mqueue_read_file(struct file *filp, char __user *u_data,
return count; return count;
} }
static int mqueue_flush_file(struct file *filp) static int mqueue_flush_file(struct file *filp, fl_owner_t id)
{ {
struct mqueue_inode_info *info = MQUEUE_I(filp->f_dentry->d_inode); struct mqueue_inode_info *info = MQUEUE_I(filp->f_dentry->d_inode);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment