aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-10 18:34:42 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-10 18:34:42 -0500
commit4b4f8580a4b77126733db8072862793d4deae66a (patch)
tree0d6ab49f4fe61ca96fd513b6dfae8be541796320 /include/linux
parent872912352c5be930e9568e5f3b6d73107d9f278d (diff)
parent8116bf4cb62d337c953cfa5369ef4cf83e73140c (diff)
Merge tag 'locks-v3.20-1' of git://git.samba.org/jlayton/linux
Pull file locking related changes #1 from Jeff Layton: "This patchset contains a fairly major overhaul of how file locks are tracked within the inode. Rather than a single list, we now create a per-inode "lock context" that contains individual lists for the file locks, and a new dedicated spinlock for them. There are changes in other trees that are based on top of this set so it may be easiest to pull this in early" * tag 'locks-v3.20-1' of git://git.samba.org/jlayton/linux: locks: update comments that refer to inode->i_flock locks: consolidate NULL i_flctx checks in locks_remove_file locks: keep a count of locks on the flctx lists locks: clean up the lm_change prototype locks: add a dedicated spinlock to protect i_flctx lists locks: remove i_flock field from struct inode locks: convert lease handling to file_lock_context locks: convert posix locks to file_lock_context locks: move flock locks to file_lock_context ceph: move spinlocking into ceph_encode_locks_to_buffer and ceph_count_locks locks: add a new struct file_locking_context pointer to struct inode locks: have locks_release_file use flock_lock_file to release generic flock locks locks: add new struct list_head to struct file_lock
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/fs.h52
1 files changed, 36 insertions, 16 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 42efe13077b6..ddd2fa7cefd3 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -625,7 +625,7 @@ struct inode {
625 atomic_t i_readcount; /* struct files open RO */ 625 atomic_t i_readcount; /* struct files open RO */
626#endif 626#endif
627 const struct file_operations *i_fop; /* former ->i_op->default_file_ops */ 627 const struct file_operations *i_fop; /* former ->i_op->default_file_ops */
628 struct file_lock *i_flock; 628 struct file_lock_context *i_flctx;
629 struct address_space i_data; 629 struct address_space i_data;
630 struct list_head i_devices; 630 struct list_head i_devices;
631 union { 631 union {
@@ -885,6 +885,8 @@ static inline struct file *get_file(struct file *f)
885/* legacy typedef, should eventually be removed */ 885/* legacy typedef, should eventually be removed */
886typedef void *fl_owner_t; 886typedef void *fl_owner_t;
887 887
888struct file_lock;
889
888struct file_lock_operations { 890struct file_lock_operations {
889 void (*fl_copy_lock)(struct file_lock *, struct file_lock *); 891 void (*fl_copy_lock)(struct file_lock *, struct file_lock *);
890 void (*fl_release_private)(struct file_lock *); 892 void (*fl_release_private)(struct file_lock *);
@@ -898,7 +900,7 @@ struct lock_manager_operations {
898 void (*lm_notify)(struct file_lock *); /* unblock callback */ 900 void (*lm_notify)(struct file_lock *); /* unblock callback */
899 int (*lm_grant)(struct file_lock *, int); 901 int (*lm_grant)(struct file_lock *, int);
900 bool (*lm_break)(struct file_lock *); 902 bool (*lm_break)(struct file_lock *);
901 int (*lm_change)(struct file_lock **, int, struct list_head *); 903 int (*lm_change)(struct file_lock *, int, struct list_head *);
902 void (*lm_setup)(struct file_lock *, void **); 904 void (*lm_setup)(struct file_lock *, void **);
903}; 905};
904 906
@@ -923,17 +925,17 @@ int locks_in_grace(struct net *);
923 * FIXME: should we create a separate "struct lock_request" to help distinguish 925 * FIXME: should we create a separate "struct lock_request" to help distinguish
924 * these two uses? 926 * these two uses?
925 * 927 *
926 * The i_flock list is ordered by: 928 * The varous i_flctx lists are ordered by:
927 * 929 *
928 * 1) lock type -- FL_LEASEs first, then FL_FLOCK, and finally FL_POSIX 930 * 1) lock owner
929 * 2) lock owner 931 * 2) lock range start
930 * 3) lock range start 932 * 3) lock range end
931 * 4) lock range end
932 * 933 *
933 * Obviously, the last two criteria only matter for POSIX locks. 934 * Obviously, the last two criteria only matter for POSIX locks.
934 */ 935 */
935struct file_lock { 936struct file_lock {
936 struct file_lock *fl_next; /* singly linked list for this inode */ 937 struct file_lock *fl_next; /* singly linked list for this inode */
938 struct list_head fl_list; /* link into file_lock_context */
937 struct hlist_node fl_link; /* node in global lists */ 939 struct hlist_node fl_link; /* node in global lists */
938 struct list_head fl_block; /* circular list of blocked processes */ 940 struct list_head fl_block; /* circular list of blocked processes */
939 fl_owner_t fl_owner; 941 fl_owner_t fl_owner;
@@ -964,6 +966,16 @@ struct file_lock {
964 } fl_u; 966 } fl_u;
965}; 967};
966 968
969struct file_lock_context {
970 spinlock_t flc_lock;
971 struct list_head flc_flock;
972 struct list_head flc_posix;
973 struct list_head flc_lease;
974 int flc_flock_cnt;
975 int flc_posix_cnt;
976 int flc_lease_cnt;
977};
978
967/* The following constant reflects the upper bound of the file/locking space */ 979/* The following constant reflects the upper bound of the file/locking space */
968#ifndef OFFSET_MAX 980#ifndef OFFSET_MAX
969#define INT_LIMIT(x) (~((x)1 << (sizeof(x)*8 - 1))) 981#define INT_LIMIT(x) (~((x)1 << (sizeof(x)*8 - 1)))
@@ -990,6 +1002,7 @@ extern int fcntl_setlease(unsigned int fd, struct file *filp, long arg);
990extern int fcntl_getlease(struct file *filp); 1002extern int fcntl_getlease(struct file *filp);
991 1003
992/* fs/locks.c */ 1004/* fs/locks.c */
1005void locks_free_lock_context(struct file_lock_context *ctx);
993void locks_free_lock(struct file_lock *fl); 1006void locks_free_lock(struct file_lock *fl);
994extern void locks_init_lock(struct file_lock *); 1007extern void locks_init_lock(struct file_lock *);
995extern struct file_lock * locks_alloc_lock(void); 1008extern struct file_lock * locks_alloc_lock(void);
@@ -1010,7 +1023,7 @@ extern int __break_lease(struct inode *inode, unsigned int flags, unsigned int t
1010extern void lease_get_mtime(struct inode *, struct timespec *time); 1023extern void lease_get_mtime(struct inode *, struct timespec *time);
1011extern int generic_setlease(struct file *, long, struct file_lock **, void **priv); 1024extern int generic_setlease(struct file *, long, struct file_lock **, void **priv);
1012extern int vfs_setlease(struct file *, long, struct file_lock **, void **); 1025extern int vfs_setlease(struct file *, long, struct file_lock **, void **);
1013extern int lease_modify(struct file_lock **, int, struct list_head *); 1026extern int lease_modify(struct file_lock *, int, struct list_head *);
1014#else /* !CONFIG_FILE_LOCKING */ 1027#else /* !CONFIG_FILE_LOCKING */
1015static inline int fcntl_getlk(struct file *file, unsigned int cmd, 1028static inline int fcntl_getlk(struct file *file, unsigned int cmd,
1016 struct flock __user *user) 1029 struct flock __user *user)
@@ -1047,6 +1060,11 @@ static inline int fcntl_getlease(struct file *filp)
1047 return F_UNLCK; 1060 return F_UNLCK;
1048} 1061}
1049 1062
1063static inline void
1064locks_free_lock_context(struct file_lock_context *ctx)
1065{
1066}
1067
1050static inline void locks_init_lock(struct file_lock *fl) 1068static inline void locks_init_lock(struct file_lock *fl)
1051{ 1069{
1052 return; 1070 return;
@@ -1137,7 +1155,7 @@ static inline int vfs_setlease(struct file *filp, long arg,
1137 return -EINVAL; 1155 return -EINVAL;
1138} 1156}
1139 1157
1140static inline int lease_modify(struct file_lock **before, int arg, 1158static inline int lease_modify(struct file_lock *fl, int arg,
1141 struct list_head *dispose) 1159 struct list_head *dispose)
1142{ 1160{
1143 return -EINVAL; 1161 return -EINVAL;
@@ -1959,7 +1977,7 @@ static inline int locks_verify_truncate(struct inode *inode,
1959 struct file *filp, 1977 struct file *filp,
1960 loff_t size) 1978 loff_t size)
1961{ 1979{
1962 if (inode->i_flock && mandatory_lock(inode)) 1980 if (inode->i_flctx && mandatory_lock(inode))
1963 return locks_mandatory_area( 1981 return locks_mandatory_area(
1964 FLOCK_VERIFY_WRITE, inode, filp, 1982 FLOCK_VERIFY_WRITE, inode, filp,
1965 size < inode->i_size ? size : inode->i_size, 1983 size < inode->i_size ? size : inode->i_size,
@@ -1973,11 +1991,12 @@ static inline int break_lease(struct inode *inode, unsigned int mode)
1973{ 1991{
1974 /* 1992 /*
1975 * Since this check is lockless, we must ensure that any refcounts 1993 * Since this check is lockless, we must ensure that any refcounts
1976 * taken are done before checking inode->i_flock. Otherwise, we could 1994 * taken are done before checking i_flctx->flc_lease. Otherwise, we
1977 * end up racing with tasks trying to set a new lease on this file. 1995 * could end up racing with tasks trying to set a new lease on this
1996 * file.
1978 */ 1997 */
1979 smp_mb(); 1998 smp_mb();
1980 if (inode->i_flock) 1999 if (inode->i_flctx && !list_empty_careful(&inode->i_flctx->flc_lease))
1981 return __break_lease(inode, mode, FL_LEASE); 2000 return __break_lease(inode, mode, FL_LEASE);
1982 return 0; 2001 return 0;
1983} 2002}
@@ -1986,11 +2005,12 @@ static inline int break_deleg(struct inode *inode, unsigned int mode)
1986{ 2005{
1987 /* 2006 /*
1988 * Since this check is lockless, we must ensure that any refcounts 2007 * Since this check is lockless, we must ensure that any refcounts
1989 * taken are done before checking inode->i_flock. Otherwise, we could 2008 * taken are done before checking i_flctx->flc_lease. Otherwise, we
1990 * end up racing with tasks trying to set a new lease on this file. 2009 * could end up racing with tasks trying to set a new lease on this
2010 * file.
1991 */ 2011 */
1992 smp_mb(); 2012 smp_mb();
1993 if (inode->i_flock) 2013 if (inode->i_flctx && !list_empty_careful(&inode->i_flctx->flc_lease))
1994 return __break_lease(inode, mode, FL_DELEG); 2014 return __break_lease(inode, mode, FL_DELEG);
1995 return 0; 2015 return 0;
1996} 2016}