summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/lustre/lustre/llite/file.c8
-rw-r--r--fs/9p/vfs_file.c4
-rw-r--r--fs/ceph/locks.c4
-rw-r--r--fs/cifs/file.c2
-rw-r--r--fs/dlm/plock.c4
-rw-r--r--fs/fuse/file.c2
-rw-r--r--fs/gfs2/file.c8
-rw-r--r--fs/lockd/clntproc.c13
-rw-r--r--fs/locks.c106
-rw-r--r--fs/nfs/file.c13
-rw-r--r--fs/nfs/nfs4proc.c13
-rw-r--r--fs/ocfs2/locks.c8
-rw-r--r--include/linux/fs.h21
-rw-r--r--include/trace/events/filelock.h38
14 files changed, 127 insertions, 117 deletions
diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c
index 11bf2c60c31a..02f27593013e 100644
--- a/drivers/staging/lustre/lustre/llite/file.c
+++ b/drivers/staging/lustre/lustre/llite/file.c
@@ -2750,13 +2750,9 @@ ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
2750 rc = md_enqueue(sbi->ll_md_exp, &einfo, NULL, 2750 rc = md_enqueue(sbi->ll_md_exp, &einfo, NULL,
2751 op_data, &lockh, &flock, 0, NULL /* req */, flags); 2751 op_data, &lockh, &flock, 0, NULL /* req */, flags);
2752 2752
2753 if ((file_lock->fl_flags & FL_FLOCK) && 2753 if ((rc == 0 || file_lock->fl_type == F_UNLCK) &&
2754 (rc == 0 || file_lock->fl_type == F_UNLCK))
2755 rc2 = flock_lock_file_wait(file, file_lock);
2756 if ((file_lock->fl_flags & FL_POSIX) &&
2757 (rc == 0 || file_lock->fl_type == F_UNLCK) &&
2758 !(flags & LDLM_FL_TEST_LOCK)) 2754 !(flags & LDLM_FL_TEST_LOCK))
2759 rc2 = posix_lock_file_wait(file, file_lock); 2755 rc2 = locks_lock_file_wait(file, file_lock);
2760 2756
2761 if (rc2 && file_lock->fl_type != F_UNLCK) { 2757 if (rc2 && file_lock->fl_type != F_UNLCK) {
2762 einfo.ei_mode = LCK_NL; 2758 einfo.ei_mode = LCK_NL;
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 3abc447783aa..f23fd86697ea 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -161,7 +161,7 @@ static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl)
161 if ((fl->fl_flags & FL_POSIX) != FL_POSIX) 161 if ((fl->fl_flags & FL_POSIX) != FL_POSIX)
162 BUG(); 162 BUG();
163 163
164 res = posix_lock_file_wait(filp, fl); 164 res = locks_lock_file_wait(filp, fl);
165 if (res < 0) 165 if (res < 0)
166 goto out; 166 goto out;
167 167
@@ -231,7 +231,7 @@ out_unlock:
231 if (res < 0 && fl->fl_type != F_UNLCK) { 231 if (res < 0 && fl->fl_type != F_UNLCK) {
232 fl_type = fl->fl_type; 232 fl_type = fl->fl_type;
233 fl->fl_type = F_UNLCK; 233 fl->fl_type = F_UNLCK;
234 res = posix_lock_file_wait(filp, fl); 234 res = locks_lock_file_wait(filp, fl);
235 fl->fl_type = fl_type; 235 fl->fl_type = fl_type;
236 } 236 }
237out: 237out:
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c
index 6706bde9ad1b..a2cb0c254060 100644
--- a/fs/ceph/locks.c
+++ b/fs/ceph/locks.c
@@ -228,12 +228,12 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
228 err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK, 228 err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK,
229 file, lock_cmd, wait, fl); 229 file, lock_cmd, wait, fl);
230 if (!err) { 230 if (!err) {
231 err = flock_lock_file_wait(file, fl); 231 err = locks_lock_file_wait(file, fl);
232 if (err) { 232 if (err) {
233 ceph_lock_message(CEPH_LOCK_FLOCK, 233 ceph_lock_message(CEPH_LOCK_FLOCK,
234 CEPH_MDS_OP_SETFILELOCK, 234 CEPH_MDS_OP_SETFILELOCK,
235 file, CEPH_LOCK_UNLOCK, 0, fl); 235 file, CEPH_LOCK_UNLOCK, 0, fl);
236 dout("got %d on flock_lock_file_wait, undid lock", err); 236 dout("got %d on locks_lock_file_wait, undid lock", err);
237 } 237 }
238 } 238 }
239 return err; 239 return err;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 62203c387db4..47c5c97e2dd3 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1553,7 +1553,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
1553 1553
1554out: 1554out:
1555 if (flock->fl_flags & FL_POSIX && !rc) 1555 if (flock->fl_flags & FL_POSIX && !rc)
1556 rc = posix_lock_file_wait(file, flock); 1556 rc = locks_lock_file_wait(file, flock);
1557 return rc; 1557 return rc;
1558} 1558}
1559 1559
diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c
index 5532f097f6da..3585cc056fd1 100644
--- a/fs/dlm/plock.c
+++ b/fs/dlm/plock.c
@@ -172,7 +172,7 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
172 rv = op->info.rv; 172 rv = op->info.rv;
173 173
174 if (!rv) { 174 if (!rv) {
175 if (posix_lock_file_wait(file, fl) < 0) 175 if (locks_lock_file_wait(file, fl) < 0)
176 log_error(ls, "dlm_posix_lock: vfs lock error %llx", 176 log_error(ls, "dlm_posix_lock: vfs lock error %llx",
177 (unsigned long long)number); 177 (unsigned long long)number);
178 } 178 }
@@ -262,7 +262,7 @@ int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
262 /* cause the vfs unlock to return ENOENT if lock is not found */ 262 /* cause the vfs unlock to return ENOENT if lock is not found */
263 fl->fl_flags |= FL_EXISTS; 263 fl->fl_flags |= FL_EXISTS;
264 264
265 rv = posix_lock_file_wait(file, fl); 265 rv = locks_lock_file_wait(file, fl);
266 if (rv == -ENOENT) { 266 if (rv == -ENOENT) {
267 rv = 0; 267 rv = 0;
268 goto out_free; 268 goto out_free;
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index f523f2f04c19..e0faf8f2c868 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -2189,7 +2189,7 @@ static int fuse_file_flock(struct file *file, int cmd, struct file_lock *fl)
2189 int err; 2189 int err;
2190 2190
2191 if (fc->no_flock) { 2191 if (fc->no_flock) {
2192 err = flock_lock_file_wait(file, fl); 2192 err = locks_lock_file_wait(file, fl);
2193 } else { 2193 } else {
2194 struct fuse_file *ff = file->private_data; 2194 struct fuse_file *ff = file->private_data;
2195 2195
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index cf4ab89159f4..9287a2d17b8c 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -1000,7 +1000,7 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl)
1000 } 1000 }
1001 if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) { 1001 if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) {
1002 if (fl->fl_type == F_UNLCK) 1002 if (fl->fl_type == F_UNLCK)
1003 posix_lock_file_wait(file, fl); 1003 locks_lock_file_wait(file, fl);
1004 return -EIO; 1004 return -EIO;
1005 } 1005 }
1006 if (IS_GETLK(cmd)) 1006 if (IS_GETLK(cmd))
@@ -1031,7 +1031,7 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl)
1031 if (gl) { 1031 if (gl) {
1032 if (fl_gh->gh_state == state) 1032 if (fl_gh->gh_state == state)
1033 goto out; 1033 goto out;
1034 flock_lock_file_wait(file, 1034 locks_lock_file_wait(file,
1035 &(struct file_lock){.fl_type = F_UNLCK}); 1035 &(struct file_lock){.fl_type = F_UNLCK});
1036 gfs2_glock_dq(fl_gh); 1036 gfs2_glock_dq(fl_gh);
1037 gfs2_holder_reinit(state, flags, fl_gh); 1037 gfs2_holder_reinit(state, flags, fl_gh);
@@ -1056,7 +1056,7 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl)
1056 if (error == GLR_TRYFAILED) 1056 if (error == GLR_TRYFAILED)
1057 error = -EAGAIN; 1057 error = -EAGAIN;
1058 } else { 1058 } else {
1059 error = flock_lock_file_wait(file, fl); 1059 error = locks_lock_file_wait(file, fl);
1060 gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); 1060 gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error);
1061 } 1061 }
1062 1062
@@ -1071,7 +1071,7 @@ static void do_unflock(struct file *file, struct file_lock *fl)
1071 struct gfs2_holder *fl_gh = &fp->f_fl_gh; 1071 struct gfs2_holder *fl_gh = &fp->f_fl_gh;
1072 1072
1073 mutex_lock(&fp->f_fl_mutex); 1073 mutex_lock(&fp->f_fl_mutex);
1074 flock_lock_file_wait(file, fl); 1074 locks_lock_file_wait(file, fl);
1075 if (fl_gh->gh_gl) { 1075 if (fl_gh->gh_gl) {
1076 gfs2_glock_dq(fl_gh); 1076 gfs2_glock_dq(fl_gh);
1077 gfs2_holder_uninit(fl_gh); 1077 gfs2_holder_uninit(fl_gh);
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index acd394716349..112952037933 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -474,18 +474,7 @@ static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *ho
474 474
475static int do_vfs_lock(struct file_lock *fl) 475static int do_vfs_lock(struct file_lock *fl)
476{ 476{
477 int res = 0; 477 return locks_lock_file_wait(fl->fl_file, fl);
478 switch (fl->fl_flags & (FL_POSIX|FL_FLOCK)) {
479 case FL_POSIX:
480 res = posix_lock_file_wait(fl->fl_file, fl);
481 break;
482 case FL_FLOCK:
483 res = flock_lock_file_wait(fl->fl_file, fl);
484 break;
485 default:
486 BUG();
487 }
488 return res;
489} 478}
490 479
491/* 480/*
diff --git a/fs/locks.c b/fs/locks.c
index 2a54c800a223..0d2b3267e2a3 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -205,28 +205,32 @@ static struct kmem_cache *filelock_cache __read_mostly;
205static struct file_lock_context * 205static struct file_lock_context *
206locks_get_lock_context(struct inode *inode, int type) 206locks_get_lock_context(struct inode *inode, int type)
207{ 207{
208 struct file_lock_context *new; 208 struct file_lock_context *ctx;
209 209
210 if (likely(inode->i_flctx) || type == F_UNLCK) 210 /* paired with cmpxchg() below */
211 ctx = smp_load_acquire(&inode->i_flctx);
212 if (likely(ctx) || type == F_UNLCK)
211 goto out; 213 goto out;
212 214
213 new = kmem_cache_alloc(flctx_cache, GFP_KERNEL); 215 ctx = kmem_cache_alloc(flctx_cache, GFP_KERNEL);
214 if (!new) 216 if (!ctx)
215 goto out; 217 goto out;
216 218
217 spin_lock_init(&new->flc_lock); 219 spin_lock_init(&ctx->flc_lock);
218 INIT_LIST_HEAD(&new->flc_flock); 220 INIT_LIST_HEAD(&ctx->flc_flock);
219 INIT_LIST_HEAD(&new->flc_posix); 221 INIT_LIST_HEAD(&ctx->flc_posix);
220 INIT_LIST_HEAD(&new->flc_lease); 222 INIT_LIST_HEAD(&ctx->flc_lease);
221 223
222 /* 224 /*
223 * Assign the pointer if it's not already assigned. If it is, then 225 * Assign the pointer if it's not already assigned. If it is, then
224 * free the context we just allocated. 226 * free the context we just allocated.
225 */ 227 */
226 if (cmpxchg(&inode->i_flctx, NULL, new)) 228 if (cmpxchg(&inode->i_flctx, NULL, ctx)) {
227 kmem_cache_free(flctx_cache, new); 229 kmem_cache_free(flctx_cache, ctx);
230 ctx = smp_load_acquire(&inode->i_flctx);
231 }
228out: 232out:
229 return inode->i_flctx; 233 return ctx;
230} 234}
231 235
232void 236void
@@ -762,7 +766,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
762 struct file_lock_context *ctx; 766 struct file_lock_context *ctx;
763 struct inode *inode = file_inode(filp); 767 struct inode *inode = file_inode(filp);
764 768
765 ctx = inode->i_flctx; 769 ctx = smp_load_acquire(&inode->i_flctx);
766 if (!ctx || list_empty_careful(&ctx->flc_posix)) { 770 if (!ctx || list_empty_careful(&ctx->flc_posix)) {
767 fl->fl_type = F_UNLCK; 771 fl->fl_type = F_UNLCK;
768 return; 772 return;
@@ -1167,10 +1171,9 @@ EXPORT_SYMBOL(posix_lock_file);
1167 * @inode: inode of file to which lock request should be applied 1171 * @inode: inode of file to which lock request should be applied
1168 * @fl: The lock to be applied 1172 * @fl: The lock to be applied
1169 * 1173 *
1170 * Variant of posix_lock_file_wait that does not take a filp, and so can be 1174 * Apply a POSIX style lock request to an inode.
1171 * used after the filp has already been torn down.
1172 */ 1175 */
1173int posix_lock_inode_wait(struct inode *inode, struct file_lock *fl) 1176static int posix_lock_inode_wait(struct inode *inode, struct file_lock *fl)
1174{ 1177{
1175 int error; 1178 int error;
1176 might_sleep (); 1179 might_sleep ();
@@ -1187,7 +1190,6 @@ int posix_lock_inode_wait(struct inode *inode, struct file_lock *fl)
1187 } 1190 }
1188 return error; 1191 return error;
1189} 1192}
1190EXPORT_SYMBOL(posix_lock_inode_wait);
1191 1193
1192/** 1194/**
1193 * locks_mandatory_locked - Check for an active lock 1195 * locks_mandatory_locked - Check for an active lock
@@ -1203,7 +1205,7 @@ int locks_mandatory_locked(struct file *file)
1203 struct file_lock_context *ctx; 1205 struct file_lock_context *ctx;
1204 struct file_lock *fl; 1206 struct file_lock *fl;
1205 1207
1206 ctx = inode->i_flctx; 1208 ctx = smp_load_acquire(&inode->i_flctx);
1207 if (!ctx || list_empty_careful(&ctx->flc_posix)) 1209 if (!ctx || list_empty_careful(&ctx->flc_posix))
1208 return 0; 1210 return 0;
1209 1211
@@ -1388,7 +1390,7 @@ any_leases_conflict(struct inode *inode, struct file_lock *breaker)
1388int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) 1390int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)
1389{ 1391{
1390 int error = 0; 1392 int error = 0;
1391 struct file_lock_context *ctx = inode->i_flctx; 1393 struct file_lock_context *ctx;
1392 struct file_lock *new_fl, *fl, *tmp; 1394 struct file_lock *new_fl, *fl, *tmp;
1393 unsigned long break_time; 1395 unsigned long break_time;
1394 int want_write = (mode & O_ACCMODE) != O_RDONLY; 1396 int want_write = (mode & O_ACCMODE) != O_RDONLY;
@@ -1400,6 +1402,7 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)
1400 new_fl->fl_flags = type; 1402 new_fl->fl_flags = type;
1401 1403
1402 /* typically we will check that ctx is non-NULL before calling */ 1404 /* typically we will check that ctx is non-NULL before calling */
1405 ctx = smp_load_acquire(&inode->i_flctx);
1403 if (!ctx) { 1406 if (!ctx) {
1404 WARN_ON_ONCE(1); 1407 WARN_ON_ONCE(1);
1405 return error; 1408 return error;
@@ -1494,9 +1497,10 @@ EXPORT_SYMBOL(__break_lease);
1494void lease_get_mtime(struct inode *inode, struct timespec *time) 1497void lease_get_mtime(struct inode *inode, struct timespec *time)
1495{ 1498{
1496 bool has_lease = false; 1499 bool has_lease = false;
1497 struct file_lock_context *ctx = inode->i_flctx; 1500 struct file_lock_context *ctx;
1498 struct file_lock *fl; 1501 struct file_lock *fl;
1499 1502
1503 ctx = smp_load_acquire(&inode->i_flctx);
1500 if (ctx && !list_empty_careful(&ctx->flc_lease)) { 1504 if (ctx && !list_empty_careful(&ctx->flc_lease)) {
1501 spin_lock(&ctx->flc_lock); 1505 spin_lock(&ctx->flc_lock);
1502 if (!list_empty(&ctx->flc_lease)) { 1506 if (!list_empty(&ctx->flc_lease)) {
@@ -1543,10 +1547,11 @@ int fcntl_getlease(struct file *filp)
1543{ 1547{
1544 struct file_lock *fl; 1548 struct file_lock *fl;
1545 struct inode *inode = file_inode(filp); 1549 struct inode *inode = file_inode(filp);
1546 struct file_lock_context *ctx = inode->i_flctx; 1550 struct file_lock_context *ctx;
1547 int type = F_UNLCK; 1551 int type = F_UNLCK;
1548 LIST_HEAD(dispose); 1552 LIST_HEAD(dispose);
1549 1553
1554 ctx = smp_load_acquire(&inode->i_flctx);
1550 if (ctx && !list_empty_careful(&ctx->flc_lease)) { 1555 if (ctx && !list_empty_careful(&ctx->flc_lease)) {
1551 spin_lock(&ctx->flc_lock); 1556 spin_lock(&ctx->flc_lock);
1552 time_out_leases(file_inode(filp), &dispose); 1557 time_out_leases(file_inode(filp), &dispose);
@@ -1711,11 +1716,11 @@ static int generic_delete_lease(struct file *filp, void *owner)
1711{ 1716{
1712 int error = -EAGAIN; 1717 int error = -EAGAIN;
1713 struct file_lock *fl, *victim = NULL; 1718 struct file_lock *fl, *victim = NULL;
1714 struct dentry *dentry = filp->f_path.dentry; 1719 struct inode *inode = file_inode(filp);
1715 struct inode *inode = dentry->d_inode; 1720 struct file_lock_context *ctx;
1716 struct file_lock_context *ctx = inode->i_flctx;
1717 LIST_HEAD(dispose); 1721 LIST_HEAD(dispose);
1718 1722
1723 ctx = smp_load_acquire(&inode->i_flctx);
1719 if (!ctx) { 1724 if (!ctx) {
1720 trace_generic_delete_lease(inode, NULL); 1725 trace_generic_delete_lease(inode, NULL);
1721 return error; 1726 return error;
@@ -1751,8 +1756,7 @@ static int generic_delete_lease(struct file *filp, void *owner)
1751int generic_setlease(struct file *filp, long arg, struct file_lock **flp, 1756int generic_setlease(struct file *filp, long arg, struct file_lock **flp,
1752 void **priv) 1757 void **priv)
1753{ 1758{
1754 struct dentry *dentry = filp->f_path.dentry; 1759 struct inode *inode = file_inode(filp);
1755 struct inode *inode = dentry->d_inode;
1756 int error; 1760 int error;
1757 1761
1758 if ((!uid_eq(current_fsuid(), inode->i_uid)) && !capable(CAP_LEASE)) 1762 if ((!uid_eq(current_fsuid(), inode->i_uid)) && !capable(CAP_LEASE))
@@ -1856,7 +1860,7 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
1856 * 1860 *
1857 * Apply a FLOCK style lock request to an inode. 1861 * Apply a FLOCK style lock request to an inode.
1858 */ 1862 */
1859int flock_lock_inode_wait(struct inode *inode, struct file_lock *fl) 1863static int flock_lock_inode_wait(struct inode *inode, struct file_lock *fl)
1860{ 1864{
1861 int error; 1865 int error;
1862 might_sleep(); 1866 might_sleep();
@@ -1873,7 +1877,30 @@ int flock_lock_inode_wait(struct inode *inode, struct file_lock *fl)
1873 } 1877 }
1874 return error; 1878 return error;
1875} 1879}
1876EXPORT_SYMBOL(flock_lock_inode_wait); 1880
1881/**
1882 * locks_lock_inode_wait - Apply a lock to an inode
1883 * @inode: inode of the file to apply to
1884 * @fl: The lock to be applied
1885 *
1886 * Apply a POSIX or FLOCK style lock request to an inode.
1887 */
1888int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl)
1889{
1890 int res = 0;
1891 switch (fl->fl_flags & (FL_POSIX|FL_FLOCK)) {
1892 case FL_POSIX:
1893 res = posix_lock_inode_wait(inode, fl);
1894 break;
1895 case FL_FLOCK:
1896 res = flock_lock_inode_wait(inode, fl);
1897 break;
1898 default:
1899 BUG();
1900 }
1901 return res;
1902}
1903EXPORT_SYMBOL(locks_lock_inode_wait);
1877 1904
1878/** 1905/**
1879 * sys_flock: - flock() system call. 1906 * sys_flock: - flock() system call.
@@ -1931,7 +1958,7 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
1931 (can_sleep) ? F_SETLKW : F_SETLK, 1958 (can_sleep) ? F_SETLKW : F_SETLK,
1932 lock); 1959 lock);
1933 else 1960 else
1934 error = flock_lock_file_wait(f.file, lock); 1961 error = locks_lock_file_wait(f.file, lock);
1935 1962
1936 out_free: 1963 out_free:
1937 locks_free_lock(lock); 1964 locks_free_lock(lock);
@@ -2107,7 +2134,7 @@ static int do_lock_file_wait(struct file *filp, unsigned int cmd,
2107 return error; 2134 return error;
2108} 2135}
2109 2136
2110/* Ensure that fl->fl_filp has compatible f_mode for F_SETLK calls */ 2137/* Ensure that fl->fl_file has compatible f_mode for F_SETLK calls */
2111static int 2138static int
2112check_fmode_for_setlk(struct file_lock *fl) 2139check_fmode_for_setlk(struct file_lock *fl)
2113{ 2140{
@@ -2359,13 +2386,14 @@ out:
2359void locks_remove_posix(struct file *filp, fl_owner_t owner) 2386void locks_remove_posix(struct file *filp, fl_owner_t owner)
2360{ 2387{
2361 struct file_lock lock; 2388 struct file_lock lock;
2362 struct file_lock_context *ctx = file_inode(filp)->i_flctx; 2389 struct file_lock_context *ctx;
2363 2390
2364 /* 2391 /*
2365 * If there are no locks held on this file, we don't need to call 2392 * If there are no locks held on this file, we don't need to call
2366 * posix_lock_file(). Another process could be setting a lock on this 2393 * posix_lock_file(). Another process could be setting a lock on this
2367 * file at the same time, but we wouldn't remove that lock anyway. 2394 * file at the same time, but we wouldn't remove that lock anyway.
2368 */ 2395 */
2396 ctx = smp_load_acquire(&file_inode(filp)->i_flctx);
2369 if (!ctx || list_empty(&ctx->flc_posix)) 2397 if (!ctx || list_empty(&ctx->flc_posix))
2370 return; 2398 return;
2371 2399
@@ -2389,7 +2417,7 @@ EXPORT_SYMBOL(locks_remove_posix);
2389 2417
2390/* The i_flctx must be valid when calling into here */ 2418/* The i_flctx must be valid when calling into here */
2391static void 2419static void
2392locks_remove_flock(struct file *filp) 2420locks_remove_flock(struct file *filp, struct file_lock_context *flctx)
2393{ 2421{
2394 struct file_lock fl = { 2422 struct file_lock fl = {
2395 .fl_owner = filp, 2423 .fl_owner = filp,
@@ -2400,7 +2428,6 @@ locks_remove_flock(struct file *filp)
2400 .fl_end = OFFSET_MAX, 2428 .fl_end = OFFSET_MAX,
2401 }; 2429 };
2402 struct inode *inode = file_inode(filp); 2430 struct inode *inode = file_inode(filp);
2403 struct file_lock_context *flctx = inode->i_flctx;
2404 2431
2405 if (list_empty(&flctx->flc_flock)) 2432 if (list_empty(&flctx->flc_flock))
2406 return; 2433 return;
@@ -2416,10 +2443,8 @@ locks_remove_flock(struct file *filp)
2416 2443
2417/* The i_flctx must be valid when calling into here */ 2444/* The i_flctx must be valid when calling into here */
2418static void 2445static void
2419locks_remove_lease(struct file *filp) 2446locks_remove_lease(struct file *filp, struct file_lock_context *ctx)
2420{ 2447{
2421 struct inode *inode = file_inode(filp);
2422 struct file_lock_context *ctx = inode->i_flctx;
2423 struct file_lock *fl, *tmp; 2448 struct file_lock *fl, *tmp;
2424 LIST_HEAD(dispose); 2449 LIST_HEAD(dispose);
2425 2450
@@ -2439,17 +2464,20 @@ locks_remove_lease(struct file *filp)
2439 */ 2464 */
2440void locks_remove_file(struct file *filp) 2465void locks_remove_file(struct file *filp)
2441{ 2466{
2442 if (!file_inode(filp)->i_flctx) 2467 struct file_lock_context *ctx;
2468
2469 ctx = smp_load_acquire(&file_inode(filp)->i_flctx);
2470 if (!ctx)
2443 return; 2471 return;
2444 2472
2445 /* remove any OFD locks */ 2473 /* remove any OFD locks */
2446 locks_remove_posix(filp, filp); 2474 locks_remove_posix(filp, filp);
2447 2475
2448 /* remove flock locks */ 2476 /* remove flock locks */
2449 locks_remove_flock(filp); 2477 locks_remove_flock(filp, ctx);
2450 2478
2451 /* remove any leases */ 2479 /* remove any leases */
2452 locks_remove_lease(filp); 2480 locks_remove_lease(filp, ctx);
2453} 2481}
2454 2482
2455/** 2483/**
@@ -2616,7 +2644,7 @@ void show_fd_locks(struct seq_file *f,
2616 struct file_lock_context *ctx; 2644 struct file_lock_context *ctx;
2617 int id = 0; 2645 int id = 0;
2618 2646
2619 ctx = inode->i_flctx; 2647 ctx = smp_load_acquire(&inode->i_flctx);
2620 if (!ctx) 2648 if (!ctx)
2621 return; 2649 return;
2622 2650
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index c0f9b1ed12b9..37f639d50af5 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -738,18 +738,7 @@ out_noconflict:
738 738
739static int do_vfs_lock(struct file *file, struct file_lock *fl) 739static int do_vfs_lock(struct file *file, struct file_lock *fl)
740{ 740{
741 int res = 0; 741 return locks_lock_file_wait(file, fl);
742 switch (fl->fl_flags & (FL_POSIX|FL_FLOCK)) {
743 case FL_POSIX:
744 res = posix_lock_file_wait(file, fl);
745 break;
746 case FL_FLOCK:
747 res = flock_lock_file_wait(file, fl);
748 break;
749 default:
750 BUG();
751 }
752 return res;
753} 742}
754 743
755static int 744static int
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 5133bb18830e..0e5ff69455c7 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5513,18 +5513,7 @@ static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *
5513 5513
5514static int do_vfs_lock(struct inode *inode, struct file_lock *fl) 5514static int do_vfs_lock(struct inode *inode, struct file_lock *fl)
5515{ 5515{
5516 int res = 0; 5516 return locks_lock_inode_wait(inode, fl);
5517 switch (fl->fl_flags & (FL_POSIX|FL_FLOCK)) {
5518 case FL_POSIX:
5519 res = posix_lock_inode_wait(inode, fl);
5520 break;
5521 case FL_FLOCK:
5522 res = flock_lock_inode_wait(inode, fl);
5523 break;
5524 default:
5525 BUG();
5526 }
5527 return res;
5528} 5517}
5529 5518
5530struct nfs4_unlockdata { 5519struct nfs4_unlockdata {
diff --git a/fs/ocfs2/locks.c b/fs/ocfs2/locks.c
index 6b6d092b0998..652ece4a9d9e 100644
--- a/fs/ocfs2/locks.c
+++ b/fs/ocfs2/locks.c
@@ -66,7 +66,7 @@ static int ocfs2_do_flock(struct file *file, struct inode *inode,
66 * level. 66 * level.
67 */ 67 */
68 68
69 flock_lock_file_wait(file, 69 locks_lock_file_wait(file,
70 &(struct file_lock){.fl_type = F_UNLCK}); 70 &(struct file_lock){.fl_type = F_UNLCK});
71 71
72 ocfs2_file_unlock(file); 72 ocfs2_file_unlock(file);
@@ -81,7 +81,7 @@ static int ocfs2_do_flock(struct file *file, struct inode *inode,
81 goto out; 81 goto out;
82 } 82 }
83 83
84 ret = flock_lock_file_wait(file, fl); 84 ret = locks_lock_file_wait(file, fl);
85 if (ret) 85 if (ret)
86 ocfs2_file_unlock(file); 86 ocfs2_file_unlock(file);
87 87
@@ -98,7 +98,7 @@ static int ocfs2_do_funlock(struct file *file, int cmd, struct file_lock *fl)
98 98
99 mutex_lock(&fp->fp_mutex); 99 mutex_lock(&fp->fp_mutex);
100 ocfs2_file_unlock(file); 100 ocfs2_file_unlock(file);
101 ret = flock_lock_file_wait(file, fl); 101 ret = locks_lock_file_wait(file, fl);
102 mutex_unlock(&fp->fp_mutex); 102 mutex_unlock(&fp->fp_mutex);
103 103
104 return ret; 104 return ret;
@@ -119,7 +119,7 @@ int ocfs2_flock(struct file *file, int cmd, struct file_lock *fl)
119 119
120 if ((osb->s_mount_opt & OCFS2_MOUNT_LOCALFLOCKS) || 120 if ((osb->s_mount_opt & OCFS2_MOUNT_LOCALFLOCKS) ||
121 ocfs2_mount_local(osb)) 121 ocfs2_mount_local(osb))
122 return flock_lock_file_wait(file, fl); 122 return locks_lock_file_wait(file, fl);
123 123
124 if (fl->fl_type == F_UNLCK) 124 if (fl->fl_type == F_UNLCK)
125 return ocfs2_do_funlock(file, cmd, fl); 125 return ocfs2_do_funlock(file, cmd, fl);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 72d8a844c692..49749688156d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1053,12 +1053,11 @@ extern void locks_remove_file(struct file *);
1053extern void locks_release_private(struct file_lock *); 1053extern void locks_release_private(struct file_lock *);
1054extern void posix_test_lock(struct file *, struct file_lock *); 1054extern void posix_test_lock(struct file *, struct file_lock *);
1055extern int posix_lock_file(struct file *, struct file_lock *, struct file_lock *); 1055extern int posix_lock_file(struct file *, struct file_lock *, struct file_lock *);
1056extern int posix_lock_inode_wait(struct inode *, struct file_lock *);
1057extern int posix_unblock_lock(struct file_lock *); 1056extern int posix_unblock_lock(struct file_lock *);
1058extern int vfs_test_lock(struct file *, struct file_lock *); 1057extern int vfs_test_lock(struct file *, struct file_lock *);
1059extern int vfs_lock_file(struct file *, unsigned int, struct file_lock *, struct file_lock *); 1058extern int vfs_lock_file(struct file *, unsigned int, struct file_lock *, struct file_lock *);
1060extern int vfs_cancel_lock(struct file *filp, struct file_lock *fl); 1059extern int vfs_cancel_lock(struct file *filp, struct file_lock *fl);
1061extern int flock_lock_inode_wait(struct inode *inode, struct file_lock *fl); 1060extern int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl);
1062extern int __break_lease(struct inode *inode, unsigned int flags, unsigned int type); 1061extern int __break_lease(struct inode *inode, unsigned int flags, unsigned int type);
1063extern void lease_get_mtime(struct inode *, struct timespec *time); 1062extern void lease_get_mtime(struct inode *, struct timespec *time);
1064extern int generic_setlease(struct file *, long, struct file_lock **, void **priv); 1063extern int generic_setlease(struct file *, long, struct file_lock **, void **priv);
@@ -1144,12 +1143,6 @@ static inline int posix_lock_file(struct file *filp, struct file_lock *fl,
1144 return -ENOLCK; 1143 return -ENOLCK;
1145} 1144}
1146 1145
1147static inline int posix_lock_inode_wait(struct inode *inode,
1148 struct file_lock *fl)
1149{
1150 return -ENOLCK;
1151}
1152
1153static inline int posix_unblock_lock(struct file_lock *waiter) 1146static inline int posix_unblock_lock(struct file_lock *waiter)
1154{ 1147{
1155 return -ENOENT; 1148 return -ENOENT;
@@ -1171,8 +1164,7 @@ static inline int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
1171 return 0; 1164 return 0;
1172} 1165}
1173 1166
1174static inline int flock_lock_inode_wait(struct inode *inode, 1167static inline int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl)
1175 struct file_lock *request)
1176{ 1168{
1177 return -ENOLCK; 1169 return -ENOLCK;
1178} 1170}
@@ -1215,14 +1207,9 @@ static inline struct inode *file_inode(const struct file *f)
1215 return f->f_inode; 1207 return f->f_inode;
1216} 1208}
1217 1209
1218static inline int posix_lock_file_wait(struct file *filp, struct file_lock *fl) 1210static inline int locks_lock_file_wait(struct file *filp, struct file_lock *fl)
1219{
1220 return posix_lock_inode_wait(file_inode(filp), fl);
1221}
1222
1223static inline int flock_lock_file_wait(struct file *filp, struct file_lock *fl)
1224{ 1211{
1225 return flock_lock_inode_wait(file_inode(filp), fl); 1212 return locks_lock_inode_wait(file_inode(filp), fl);
1226} 1213}
1227 1214
1228struct fasync_struct { 1215struct fasync_struct {
diff --git a/include/trace/events/filelock.h b/include/trace/events/filelock.h
index a0d008070962..c72f2dc01d0b 100644
--- a/include/trace/events/filelock.h
+++ b/include/trace/events/filelock.h
@@ -81,15 +81,47 @@ DEFINE_EVENT(filelock_lease, break_lease_block, TP_PROTO(struct inode *inode, st
81DEFINE_EVENT(filelock_lease, break_lease_unblock, TP_PROTO(struct inode *inode, struct file_lock *fl), 81DEFINE_EVENT(filelock_lease, break_lease_unblock, TP_PROTO(struct inode *inode, struct file_lock *fl),
82 TP_ARGS(inode, fl)); 82 TP_ARGS(inode, fl));
83 83
84DEFINE_EVENT(filelock_lease, generic_add_lease, TP_PROTO(struct inode *inode, struct file_lock *fl),
85 TP_ARGS(inode, fl));
86
87DEFINE_EVENT(filelock_lease, generic_delete_lease, TP_PROTO(struct inode *inode, struct file_lock *fl), 84DEFINE_EVENT(filelock_lease, generic_delete_lease, TP_PROTO(struct inode *inode, struct file_lock *fl),
88 TP_ARGS(inode, fl)); 85 TP_ARGS(inode, fl));
89 86
90DEFINE_EVENT(filelock_lease, time_out_leases, TP_PROTO(struct inode *inode, struct file_lock *fl), 87DEFINE_EVENT(filelock_lease, time_out_leases, TP_PROTO(struct inode *inode, struct file_lock *fl),
91 TP_ARGS(inode, fl)); 88 TP_ARGS(inode, fl));
92 89
90TRACE_EVENT(generic_add_lease,
91 TP_PROTO(struct inode *inode, struct file_lock *fl),
92
93 TP_ARGS(inode, fl),
94
95 TP_STRUCT__entry(
96 __field(unsigned long, i_ino)
97 __field(int, wcount)
98 __field(int, dcount)
99 __field(int, icount)
100 __field(dev_t, s_dev)
101 __field(fl_owner_t, fl_owner)
102 __field(unsigned int, fl_flags)
103 __field(unsigned char, fl_type)
104 ),
105
106 TP_fast_assign(
107 __entry->s_dev = inode->i_sb->s_dev;
108 __entry->i_ino = inode->i_ino;
109 __entry->wcount = atomic_read(&inode->i_writecount);
110 __entry->dcount = d_count(fl->fl_file->f_path.dentry);
111 __entry->icount = atomic_read(&inode->i_count);
112 __entry->fl_owner = fl ? fl->fl_owner : NULL;
113 __entry->fl_flags = fl ? fl->fl_flags : 0;
114 __entry->fl_type = fl ? fl->fl_type : 0;
115 ),
116
117 TP_printk("dev=0x%x:0x%x ino=0x%lx wcount=%d dcount=%d icount=%d fl_owner=0x%p fl_flags=%s fl_type=%s",
118 MAJOR(__entry->s_dev), MINOR(__entry->s_dev),
119 __entry->i_ino, __entry->wcount, __entry->dcount,
120 __entry->icount, __entry->fl_owner,
121 show_fl_flags(__entry->fl_flags),
122 show_fl_type(__entry->fl_type))
123);
124
93#endif /* _TRACE_FILELOCK_H */ 125#endif /* _TRACE_FILELOCK_H */
94 126
95/* This part must be outside protection */ 127/* This part must be outside protection */