From: Miklos Szeredi 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: Miklos Szeredi Cc: Trond Myklebust Cc: Al Viro Signed-off-by: Andrew Morton --- arch/ia64/kernel/perfmon.c | 3 +-- drivers/input/evdev.c | 2 +- drivers/scsi/osst.c | 2 +- drivers/scsi/st.c | 2 +- fs/cifs/cifsfs.h | 2 +- fs/cifs/file.c | 2 +- fs/coda/file.c | 2 +- fs/fuse/file.c | 2 +- fs/locks.c | 2 +- fs/nfs/file.c | 4 ++-- fs/open.c | 2 +- include/linux/coda_linux.h | 2 +- include/linux/fs.h | 3 ++- ipc/mqueue.c | 2 +- 14 files changed, 16 insertions(+), 16 deletions(-) diff -puN fs/locks.c~vfs-add-lock-owner-argument-to-flush-operation fs/locks.c --- devel/fs/locks.c~vfs-add-lock-owner-argument-to-flush-operation 2006-05-19 16:00:41.000000000 -0700 +++ devel-akpm/fs/locks.c 2006-05-19 16:00:41.000000000 -0700 @@ -1905,7 +1905,7 @@ void locks_remove_posix(struct file *fil return; lock.fl_type = F_UNLCK; - lock.fl_flags = FL_POSIX; + lock.fl_flags = FL_POSIX | FL_CLOSE; lock.fl_start = 0; lock.fl_end = OFFSET_MAX; lock.fl_owner = owner; diff -puN fs/open.c~vfs-add-lock-owner-argument-to-flush-operation fs/open.c --- devel/fs/open.c~vfs-add-lock-owner-argument-to-flush-operation 2006-05-19 16:00:41.000000000 -0700 +++ devel-akpm/fs/open.c 2006-05-19 16:00:41.000000000 -0700 @@ -1152,7 +1152,7 @@ int filp_close(struct file *filp, fl_own } 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); locks_remove_posix(filp, id); diff -puN include/linux/fs.h~vfs-add-lock-owner-argument-to-flush-operation include/linux/fs.h --- devel/include/linux/fs.h~vfs-add-lock-owner-argument-to-flush-operation 2006-05-19 16:00:41.000000000 -0700 +++ devel-akpm/include/linux/fs.h 2006-05-19 16:00:41.000000000 -0700 @@ -679,6 +679,7 @@ extern spinlock_t files_lock; #define FL_FLOCK 2 #define FL_ACCESS 8 /* not trying to lock, just looking */ #define FL_LEASE 32 /* lease held on this file */ +#define FL_CLOSE 64 /* unlock on close */ #define FL_SLEEP 128 /* A blocking lock */ /* @@ -1024,7 +1025,7 @@ struct file_operations { long (*compat_ioctl) (struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *); 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 (*fsync) (struct file *, struct dentry *, int datasync); int (*aio_fsync) (struct kiocb *, int datasync); diff -puN arch/ia64/kernel/perfmon.c~vfs-add-lock-owner-argument-to-flush-operation arch/ia64/kernel/perfmon.c --- devel/arch/ia64/kernel/perfmon.c~vfs-add-lock-owner-argument-to-flush-operation 2006-05-19 16:00:41.000000000 -0700 +++ devel-akpm/arch/ia64/kernel/perfmon.c 2006-05-19 16:00:41.000000000 -0700 @@ -532,7 +532,6 @@ static ctl_table pfm_sysctl_root[] = { 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_flush(struct file *filp); #define pfm_get_cpu_var(v) __ia64_per_cpu_var(v) #define pfm_get_cpu_data(a,b) per_cpu(a, b) @@ -1773,7 +1772,7 @@ pfm_syswide_cleanup_other_cpu(pfm_contex * When caller is self-monitoring, the context is unloaded. */ static int -pfm_flush(struct file *filp) +pfm_flush(struct file *filp, fl_owner_t id) { pfm_context_t *ctx; struct task_struct *task; diff -puN drivers/input/evdev.c~vfs-add-lock-owner-argument-to-flush-operation drivers/input/evdev.c --- devel/drivers/input/evdev.c~vfs-add-lock-owner-argument-to-flush-operation 2006-05-19 16:00:41.000000000 -0700 +++ devel-akpm/drivers/input/evdev.c 2006-05-19 16:00:41.000000000 -0700 @@ -82,7 +82,7 @@ static int evdev_fasync(int fd, struct f 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; if (!list->evdev->exist) return -ENODEV; diff -puN drivers/scsi/osst.c~vfs-add-lock-owner-argument-to-flush-operation drivers/scsi/osst.c --- devel/drivers/scsi/osst.c~vfs-add-lock-owner-argument-to-flush-operation 2006-05-19 16:00:41.000000000 -0700 +++ devel-akpm/drivers/scsi/osst.c 2006-05-19 16:00:41.000000000 -0700 @@ -4724,7 +4724,7 @@ err_out: /* 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; struct osst_tape * STp = filp->private_data; diff -puN drivers/scsi/st.c~vfs-add-lock-owner-argument-to-flush-operation drivers/scsi/st.c --- devel/drivers/scsi/st.c~vfs-add-lock-owner-argument-to-flush-operation 2006-05-19 16:00:41.000000000 -0700 +++ devel-akpm/drivers/scsi/st.c 2006-05-19 16:00:41.000000000 -0700 @@ -1193,7 +1193,7 @@ static int st_open(struct inode *inode, /* 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; unsigned char cmd[MAX_COMMAND_SIZE]; diff -puN fs/cifs/cifsfs.h~vfs-add-lock-owner-argument-to-flush-operation fs/cifs/cifsfs.h --- devel/fs/cifs/cifsfs.h~vfs-add-lock-owner-argument-to-flush-operation 2006-05-19 16:00:41.000000000 -0700 +++ devel-akpm/fs/cifs/cifsfs.h 2006-05-19 16:00:41.000000000 -0700 @@ -75,7 +75,7 @@ extern ssize_t cifs_user_write(struct fi size_t write_size, loff_t * poffset); extern int cifs_lock(struct file *, int, struct file_lock *); 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 const struct file_operations cifs_dir_ops; extern int cifs_dir_open(struct inode *inode, struct file *file); diff -puN fs/cifs/file.c~vfs-add-lock-owner-argument-to-flush-operation fs/cifs/file.c --- devel/fs/cifs/file.c~vfs-add-lock-owner-argument-to-flush-operation 2006-05-19 16:00:41.000000000 -0700 +++ devel-akpm/fs/cifs/file.c 2006-05-19 16:00:41.000000000 -0700 @@ -1415,7 +1415,7 @@ int cifs_fsync(struct file *file, struct * As file closes, flush all cached write data for this inode checking * 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; int rc = 0; diff -puN fs/coda/file.c~vfs-add-lock-owner-argument-to-flush-operation fs/coda/file.c --- devel/fs/coda/file.c~vfs-add-lock-owner-argument-to-flush-operation 2006-05-19 16:00:41.000000000 -0700 +++ devel-akpm/fs/coda/file.c 2006-05-19 16:00:41.000000000 -0700 @@ -164,7 +164,7 @@ int coda_open(struct inode *coda_inode, 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 coda_flags = coda_flags_to_cflags(flags); diff -puN fs/fuse/file.c~vfs-add-lock-owner-argument-to-flush-operation fs/fuse/file.c --- devel/fs/fuse/file.c~vfs-add-lock-owner-argument-to-flush-operation 2006-05-19 16:00:41.000000000 -0700 +++ devel-akpm/fs/fuse/file.c 2006-05-19 16:00:41.000000000 -0700 @@ -169,7 +169,7 @@ static int fuse_release(struct inode *in 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 fuse_conn *fc = get_fuse_conn(inode); diff -puN fs/nfs/file.c~vfs-add-lock-owner-argument-to-flush-operation fs/nfs/file.c --- devel/fs/nfs/file.c~vfs-add-lock-owner-argument-to-flush-operation 2006-05-19 16:00:41.000000000 -0700 +++ devel-akpm/fs/nfs/file.c 2006-05-19 16:00:41.000000000 -0700 @@ -43,7 +43,7 @@ static int nfs_file_mmap(struct file *, 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_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_check_flags(int flags); static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); @@ -188,7 +188,7 @@ static loff_t nfs_file_llseek(struct fil * */ 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 inode *inode = file->f_dentry->d_inode; diff -puN include/linux/coda_linux.h~vfs-add-lock-owner-argument-to-flush-operation include/linux/coda_linux.h --- devel/include/linux/coda_linux.h~vfs-add-lock-owner-argument-to-flush-operation 2006-05-19 16:00:41.000000000 -0700 +++ devel-akpm/include/linux/coda_linux.h 2006-05-19 16:00:41.000000000 -0700 @@ -36,7 +36,7 @@ extern const struct file_operations coda /* operations shared over more than one file */ 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_permission(struct inode *inode, int mask, struct nameidata *nd); int coda_revalidate_inode(struct dentry *); diff -puN ipc/mqueue.c~vfs-add-lock-owner-argument-to-flush-operation ipc/mqueue.c --- devel/ipc/mqueue.c~vfs-add-lock-owner-argument-to-flush-operation 2006-05-19 16:00:41.000000000 -0700 +++ devel-akpm/ipc/mqueue.c 2006-05-19 16:00:41.000000000 -0700 @@ -356,7 +356,7 @@ static ssize_t mqueue_read_file(struct f 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); _