diff options
-rw-r--r-- | drivers/staging/lustre/lustre/llite/file.c | 8 | ||||
-rw-r--r-- | fs/9p/vfs_file.c | 4 | ||||
-rw-r--r-- | fs/ceph/locks.c | 4 | ||||
-rw-r--r-- | fs/cifs/file.c | 2 | ||||
-rw-r--r-- | fs/dlm/plock.c | 4 | ||||
-rw-r--r-- | fs/fuse/file.c | 2 | ||||
-rw-r--r-- | fs/gfs2/file.c | 8 | ||||
-rw-r--r-- | fs/lockd/clntproc.c | 13 | ||||
-rw-r--r-- | fs/locks.c | 106 | ||||
-rw-r--r-- | fs/nfs/file.c | 13 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 13 | ||||
-rw-r--r-- | fs/ocfs2/locks.c | 8 | ||||
-rw-r--r-- | include/linux/fs.h | 21 | ||||
-rw-r--r-- | include/trace/events/filelock.h | 38 |
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 | } |
237 | out: | 237 | out: |
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 | ||
1554 | out: | 1554 | out: |
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 | ||
475 | static int do_vfs_lock(struct file_lock *fl) | 475 | static 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; | |||
205 | static struct file_lock_context * | 205 | static struct file_lock_context * |
206 | locks_get_lock_context(struct inode *inode, int type) | 206 | locks_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 | } | ||
228 | out: | 232 | out: |
229 | return inode->i_flctx; | 233 | return ctx; |
230 | } | 234 | } |
231 | 235 | ||
232 | void | 236 | void |
@@ -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 | */ |
1173 | int posix_lock_inode_wait(struct inode *inode, struct file_lock *fl) | 1176 | static 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 | } |
1190 | EXPORT_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) | |||
1388 | int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) | 1390 | int __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); | |||
1494 | void lease_get_mtime(struct inode *inode, struct timespec *time) | 1497 | void 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) | |||
1751 | int generic_setlease(struct file *filp, long arg, struct file_lock **flp, | 1756 | int 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 | */ |
1859 | int flock_lock_inode_wait(struct inode *inode, struct file_lock *fl) | 1863 | static 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 | } |
1876 | EXPORT_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 | */ | ||
1888 | int 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 | } | ||
1903 | EXPORT_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 */ |
2111 | static int | 2138 | static int |
2112 | check_fmode_for_setlk(struct file_lock *fl) | 2139 | check_fmode_for_setlk(struct file_lock *fl) |
2113 | { | 2140 | { |
@@ -2359,13 +2386,14 @@ out: | |||
2359 | void locks_remove_posix(struct file *filp, fl_owner_t owner) | 2386 | void 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 */ |
2391 | static void | 2419 | static void |
2392 | locks_remove_flock(struct file *filp) | 2420 | locks_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 */ |
2418 | static void | 2445 | static void |
2419 | locks_remove_lease(struct file *filp) | 2446 | locks_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 | */ |
2440 | void locks_remove_file(struct file *filp) | 2465 | void 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 | ||
739 | static int do_vfs_lock(struct file *file, struct file_lock *fl) | 739 | static 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 | ||
755 | static int | 744 | static 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 | ||
5514 | static int do_vfs_lock(struct inode *inode, struct file_lock *fl) | 5514 | static 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 | ||
5530 | struct nfs4_unlockdata { | 5519 | struct 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 *); | |||
1053 | extern void locks_release_private(struct file_lock *); | 1053 | extern void locks_release_private(struct file_lock *); |
1054 | extern void posix_test_lock(struct file *, struct file_lock *); | 1054 | extern void posix_test_lock(struct file *, struct file_lock *); |
1055 | extern int posix_lock_file(struct file *, struct file_lock *, struct file_lock *); | 1055 | extern int posix_lock_file(struct file *, struct file_lock *, struct file_lock *); |
1056 | extern int posix_lock_inode_wait(struct inode *, struct file_lock *); | ||
1057 | extern int posix_unblock_lock(struct file_lock *); | 1056 | extern int posix_unblock_lock(struct file_lock *); |
1058 | extern int vfs_test_lock(struct file *, struct file_lock *); | 1057 | extern int vfs_test_lock(struct file *, struct file_lock *); |
1059 | extern int vfs_lock_file(struct file *, unsigned int, struct file_lock *, struct file_lock *); | 1058 | extern int vfs_lock_file(struct file *, unsigned int, struct file_lock *, struct file_lock *); |
1060 | extern int vfs_cancel_lock(struct file *filp, struct file_lock *fl); | 1059 | extern int vfs_cancel_lock(struct file *filp, struct file_lock *fl); |
1061 | extern int flock_lock_inode_wait(struct inode *inode, struct file_lock *fl); | 1060 | extern int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl); |
1062 | extern int __break_lease(struct inode *inode, unsigned int flags, unsigned int type); | 1061 | extern int __break_lease(struct inode *inode, unsigned int flags, unsigned int type); |
1063 | extern void lease_get_mtime(struct inode *, struct timespec *time); | 1062 | extern void lease_get_mtime(struct inode *, struct timespec *time); |
1064 | extern int generic_setlease(struct file *, long, struct file_lock **, void **priv); | 1063 | extern 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 | ||
1147 | static inline int posix_lock_inode_wait(struct inode *inode, | ||
1148 | struct file_lock *fl) | ||
1149 | { | ||
1150 | return -ENOLCK; | ||
1151 | } | ||
1152 | |||
1153 | static inline int posix_unblock_lock(struct file_lock *waiter) | 1146 | static 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 | ||
1174 | static inline int flock_lock_inode_wait(struct inode *inode, | 1167 | static 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 | ||
1218 | static inline int posix_lock_file_wait(struct file *filp, struct file_lock *fl) | 1210 | static 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 | |||
1223 | static 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 | ||
1228 | struct fasync_struct { | 1215 | struct 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 | |||
81 | DEFINE_EVENT(filelock_lease, break_lease_unblock, TP_PROTO(struct inode *inode, struct file_lock *fl), | 81 | DEFINE_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 | ||
84 | DEFINE_EVENT(filelock_lease, generic_add_lease, TP_PROTO(struct inode *inode, struct file_lock *fl), | ||
85 | TP_ARGS(inode, fl)); | ||
86 | |||
87 | DEFINE_EVENT(filelock_lease, generic_delete_lease, TP_PROTO(struct inode *inode, struct file_lock *fl), | 84 | DEFINE_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 | ||
90 | DEFINE_EVENT(filelock_lease, time_out_leases, TP_PROTO(struct inode *inode, struct file_lock *fl), | 87 | DEFINE_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 | ||
90 | TRACE_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 */ |