Skip to content

Commit 73fa58d

Browse files
committed
Merge tag 'locks-v6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/jlayton/linux
Pull file locking updates from Jeff Layton: "The main change here is to add the new locks_inode_context helper, and convert all of the places that dereference inode->i_flctx directly to use that instead. There is a new helper to indicate whether any locks are held on an inode. This is mostly for Ceph but may be usable elsewhere too. Andi Kleen requested that we print the PID when the LOCK_MAND warning fires, to help track down applications trying to use it. Finally, we added some new warnings to some of the file locking functions that fire when the ->fl_file and filp arguments differ. This helped us find some long-standing bugs in lockd. Patches for those are in Chuck Lever's tree and should be in his v6.2 PR. After that patch, people using NFSv2/v3 locking may see some warnings fire until those go in. Happy Holidays!" * tag 'locks-v6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/jlayton/linux: Add process name and pid to locks warning nfsd: use locks_inode_context helper nfs: use locks_inode_context helper lockd: use locks_inode_context helper ksmbd: use locks_inode_context helper cifs: use locks_inode_context helper ceph: use locks_inode_context helper filelock: add a new locks_inode_context accessor function filelock: new helper: vfs_inode_has_locks filelock: WARN_ON_ONCE when ->fl_file and filp don't match
2 parents 7fc0350 + f2f2494 commit 73fa58d

File tree

11 files changed

+72
-26
lines changed

11 files changed

+72
-26
lines changed

fs/ceph/locks.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ void ceph_count_locks(struct inode *inode, int *fcntl_count, int *flock_count)
364364
*fcntl_count = 0;
365365
*flock_count = 0;
366366

367-
ctx = inode->i_flctx;
367+
ctx = locks_inode_context(inode);
368368
if (ctx) {
369369
spin_lock(&ctx->flc_lock);
370370
list_for_each_entry(lock, &ctx->flc_posix, fl_list)
@@ -418,7 +418,7 @@ int ceph_encode_locks_to_buffer(struct inode *inode,
418418
int num_fcntl_locks, int num_flock_locks)
419419
{
420420
struct file_lock *lock;
421-
struct file_lock_context *ctx = inode->i_flctx;
421+
struct file_lock_context *ctx = locks_inode_context(inode);
422422
int err = 0;
423423
int seen_fcntl = 0;
424424
int seen_flock = 0;

fs/cifs/file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1413,7 +1413,7 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
14131413
struct inode *inode = d_inode(cfile->dentry);
14141414
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
14151415
struct file_lock *flock;
1416-
struct file_lock_context *flctx = inode->i_flctx;
1416+
struct file_lock_context *flctx = locks_inode_context(inode);
14171417
unsigned int count = 0, i;
14181418
int rc = 0, xid, type;
14191419
struct list_head locks_to_send, *el;

fs/ksmbd/vfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ static int check_lock_range(struct file *filp, loff_t start, loff_t end,
321321
unsigned char type)
322322
{
323323
struct file_lock *flock;
324-
struct file_lock_context *ctx = file_inode(filp)->i_flctx;
324+
struct file_lock_context *ctx = locks_inode_context(file_inode(filp));
325325
int error = 0;
326326

327327
if (!ctx || list_empty_careful(&ctx->flc_posix))

fs/lockd/svcsubs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ nlm_traverse_locks(struct nlm_host *host, struct nlm_file *file,
207207
{
208208
struct inode *inode = nlmsvc_file_inode(file);
209209
struct file_lock *fl;
210-
struct file_lock_context *flctx = inode->i_flctx;
210+
struct file_lock_context *flctx = locks_inode_context(inode);
211211
struct nlm_host *lockhost;
212212

213213
if (!flctx || list_empty_careful(&flctx->flc_posix))
@@ -262,7 +262,7 @@ nlm_file_inuse(struct nlm_file *file)
262262
{
263263
struct inode *inode = nlmsvc_file_inode(file);
264264
struct file_lock *fl;
265-
struct file_lock_context *flctx = inode->i_flctx;
265+
struct file_lock_context *flctx = locks_inode_context(inode);
266266

267267
if (file->f_count || !list_empty(&file->f_blocks) || file->f_shares)
268268
return 1;

fs/locks.c

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ locks_get_lock_context(struct inode *inode, int type)
175175
struct file_lock_context *ctx;
176176

177177
/* paired with cmpxchg() below */
178-
ctx = smp_load_acquire(&inode->i_flctx);
178+
ctx = locks_inode_context(inode);
179179
if (likely(ctx) || type == F_UNLCK)
180180
goto out;
181181

@@ -194,7 +194,7 @@ locks_get_lock_context(struct inode *inode, int type)
194194
*/
195195
if (cmpxchg(&inode->i_flctx, NULL, ctx)) {
196196
kmem_cache_free(flctx_cache, ctx);
197-
ctx = smp_load_acquire(&inode->i_flctx);
197+
ctx = locks_inode_context(inode);
198198
}
199199
out:
200200
trace_locks_get_lock_context(inode, type, ctx);
@@ -247,7 +247,7 @@ locks_check_ctx_file_list(struct file *filp, struct list_head *list,
247247
void
248248
locks_free_lock_context(struct inode *inode)
249249
{
250-
struct file_lock_context *ctx = inode->i_flctx;
250+
struct file_lock_context *ctx = locks_inode_context(inode);
251251

252252
if (unlikely(ctx)) {
253253
locks_check_ctx_lists(inode);
@@ -891,7 +891,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
891891
void *owner;
892892
void (*func)(void);
893893

894-
ctx = smp_load_acquire(&inode->i_flctx);
894+
ctx = locks_inode_context(inode);
895895
if (!ctx || list_empty_careful(&ctx->flc_posix)) {
896896
fl->fl_type = F_UNLCK;
897897
return;
@@ -1483,7 +1483,7 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)
14831483
new_fl->fl_flags = type;
14841484

14851485
/* typically we will check that ctx is non-NULL before calling */
1486-
ctx = smp_load_acquire(&inode->i_flctx);
1486+
ctx = locks_inode_context(inode);
14871487
if (!ctx) {
14881488
WARN_ON_ONCE(1);
14891489
goto free_lock;
@@ -1588,7 +1588,7 @@ void lease_get_mtime(struct inode *inode, struct timespec64 *time)
15881588
struct file_lock_context *ctx;
15891589
struct file_lock *fl;
15901590

1591-
ctx = smp_load_acquire(&inode->i_flctx);
1591+
ctx = locks_inode_context(inode);
15921592
if (ctx && !list_empty_careful(&ctx->flc_lease)) {
15931593
spin_lock(&ctx->flc_lock);
15941594
fl = list_first_entry_or_null(&ctx->flc_lease,
@@ -1634,7 +1634,7 @@ int fcntl_getlease(struct file *filp)
16341634
int type = F_UNLCK;
16351635
LIST_HEAD(dispose);
16361636

1637-
ctx = smp_load_acquire(&inode->i_flctx);
1637+
ctx = locks_inode_context(inode);
16381638
if (ctx && !list_empty_careful(&ctx->flc_lease)) {
16391639
percpu_down_read(&file_rwsem);
16401640
spin_lock(&ctx->flc_lock);
@@ -1823,7 +1823,7 @@ static int generic_delete_lease(struct file *filp, void *owner)
18231823
struct file_lock_context *ctx;
18241824
LIST_HEAD(dispose);
18251825

1826-
ctx = smp_load_acquire(&inode->i_flctx);
1826+
ctx = locks_inode_context(inode);
18271827
if (!ctx) {
18281828
trace_generic_delete_lease(inode, NULL);
18291829
return error;
@@ -2096,7 +2096,7 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
20962096
* throw a warning to let people know that they don't actually work.
20972097
*/
20982098
if (cmd & LOCK_MAND) {
2099-
pr_warn_once("Attempt to set a LOCK_MAND lock via flock(2). This support has been removed and the request ignored.\n");
2099+
pr_warn_once("%s(%d): Attempt to set a LOCK_MAND lock via flock(2). This support has been removed and the request ignored.\n", current->comm, current->pid);
21002100
return 0;
21012101
}
21022102

@@ -2146,6 +2146,7 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
21462146
*/
21472147
int vfs_test_lock(struct file *filp, struct file_lock *fl)
21482148
{
2149+
WARN_ON_ONCE(filp != fl->fl_file);
21492150
if (filp->f_op->lock)
21502151
return filp->f_op->lock(filp, F_GETLK, fl);
21512152
posix_test_lock(filp, fl);
@@ -2295,6 +2296,7 @@ int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock *flock)
22952296
*/
22962297
int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl, struct file_lock *conf)
22972298
{
2299+
WARN_ON_ONCE(filp != fl->fl_file);
22982300
if (filp->f_op->lock)
22992301
return filp->f_op->lock(filp, cmd, fl);
23002302
else
@@ -2561,7 +2563,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner)
25612563
* posix_lock_file(). Another process could be setting a lock on this
25622564
* file at the same time, but we wouldn't remove that lock anyway.
25632565
*/
2564-
ctx = smp_load_acquire(&inode->i_flctx);
2566+
ctx = locks_inode_context(inode);
25652567
if (!ctx || list_empty(&ctx->flc_posix))
25662568
return;
25672569

@@ -2634,7 +2636,7 @@ void locks_remove_file(struct file *filp)
26342636
{
26352637
struct file_lock_context *ctx;
26362638

2637-
ctx = smp_load_acquire(&locks_inode(filp)->i_flctx);
2639+
ctx = locks_inode_context(locks_inode(filp));
26382640
if (!ctx)
26392641
return;
26402642

@@ -2663,12 +2665,36 @@ void locks_remove_file(struct file *filp)
26632665
*/
26642666
int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
26652667
{
2668+
WARN_ON_ONCE(filp != fl->fl_file);
26662669
if (filp->f_op->lock)
26672670
return filp->f_op->lock(filp, F_CANCELLK, fl);
26682671
return 0;
26692672
}
26702673
EXPORT_SYMBOL_GPL(vfs_cancel_lock);
26712674

2675+
/**
2676+
* vfs_inode_has_locks - are any file locks held on @inode?
2677+
* @inode: inode to check for locks
2678+
*
2679+
* Return true if there are any FL_POSIX or FL_FLOCK locks currently
2680+
* set on @inode.
2681+
*/
2682+
bool vfs_inode_has_locks(struct inode *inode)
2683+
{
2684+
struct file_lock_context *ctx;
2685+
bool ret;
2686+
2687+
ctx = locks_inode_context(inode);
2688+
if (!ctx)
2689+
return false;
2690+
2691+
spin_lock(&ctx->flc_lock);
2692+
ret = !list_empty(&ctx->flc_posix) || !list_empty(&ctx->flc_flock);
2693+
spin_unlock(&ctx->flc_lock);
2694+
return ret;
2695+
}
2696+
EXPORT_SYMBOL_GPL(vfs_inode_has_locks);
2697+
26722698
#ifdef CONFIG_PROC_FS
26732699
#include <linux/proc_fs.h>
26742700
#include <linux/seq_file.h>
@@ -2839,7 +2865,7 @@ void show_fd_locks(struct seq_file *f,
28392865
struct file_lock_context *ctx;
28402866
int id = 0;
28412867

2842-
ctx = smp_load_acquire(&inode->i_flctx);
2868+
ctx = locks_inode_context(inode);
28432869
if (!ctx)
28442870
return;
28452871

fs/nfs/delegation.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ static int nfs_delegation_claim_locks(struct nfs4_state *state, const nfs4_state
146146
{
147147
struct inode *inode = state->inode;
148148
struct file_lock *fl;
149-
struct file_lock_context *flctx = inode->i_flctx;
149+
struct file_lock_context *flctx = locks_inode_context(inode);
150150
struct list_head *list;
151151
int status = 0;
152152

fs/nfs/nfs4state.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1501,7 +1501,7 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_
15011501
struct file_lock *fl;
15021502
struct nfs4_lock_state *lsp;
15031503
int status = 0;
1504-
struct file_lock_context *flctx = inode->i_flctx;
1504+
struct file_lock_context *flctx = locks_inode_context(inode);
15051505
struct list_head *list;
15061506

15071507
if (flctx == NULL)

fs/nfs/pagelist.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1055,7 +1055,7 @@ static unsigned int nfs_coalesce_size(struct nfs_page *prev,
10551055
if (prev) {
10561056
if (!nfs_match_open_context(nfs_req_openctx(req), nfs_req_openctx(prev)))
10571057
return 0;
1058-
flctx = d_inode(nfs_req_openctx(req)->dentry)->i_flctx;
1058+
flctx = locks_inode_context(d_inode(nfs_req_openctx(req)->dentry));
10591059
if (flctx != NULL &&
10601060
!(list_empty_careful(&flctx->flc_posix) &&
10611061
list_empty_careful(&flctx->flc_flock)) &&

fs/nfs/write.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,7 +1185,7 @@ int nfs_flush_incompatible(struct file *file, struct page *page)
11851185
{
11861186
struct nfs_open_context *ctx = nfs_file_open_context(file);
11871187
struct nfs_lock_context *l_ctx;
1188-
struct file_lock_context *flctx = file_inode(file)->i_flctx;
1188+
struct file_lock_context *flctx = locks_inode_context(file_inode(file));
11891189
struct nfs_page *req;
11901190
int do_flush, status;
11911191
/*
@@ -1321,7 +1321,7 @@ static int nfs_can_extend_write(struct file *file, struct page *page,
13211321
struct inode *inode, unsigned int pagelen)
13221322
{
13231323
int ret;
1324-
struct file_lock_context *flctx = inode->i_flctx;
1324+
struct file_lock_context *flctx = locks_inode_context(inode);
13251325
struct file_lock *fl;
13261326

13271327
if (file->f_flags & O_DSYNC)

fs/nfsd/nfs4state.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4758,7 +4758,7 @@ nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type)
47584758

47594759
static bool nfsd4_deleg_present(const struct inode *inode)
47604760
{
4761-
struct file_lock_context *ctx = smp_load_acquire(&inode->i_flctx);
4761+
struct file_lock_context *ctx = locks_inode_context(inode);
47624762

47634763
return ctx && !list_empty_careful(&ctx->flc_lease);
47644764
}
@@ -5897,7 +5897,7 @@ nfs4_lockowner_has_blockers(struct nfs4_lockowner *lo)
58975897

58985898
list_for_each_entry(stp, &lo->lo_owner.so_stateids, st_perstateowner) {
58995899
nf = stp->st_stid.sc_file;
5900-
ctx = nf->fi_inode->i_flctx;
5900+
ctx = locks_inode_context(nf->fi_inode);
59015901
if (!ctx)
59025902
continue;
59035903
if (locks_owner_has_blockers(ctx, lo))
@@ -7713,7 +7713,7 @@ check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner)
77137713
}
77147714

77157715
inode = locks_inode(nf->nf_file);
7716-
flctx = inode->i_flctx;
7716+
flctx = locks_inode_context(inode);
77177717

77187718
if (flctx && !list_empty_careful(&flctx->flc_posix)) {
77197719
spin_lock(&flctx->flc_lock);

0 commit comments

Comments
 (0)