Skip to content

Commit 066dea8

Browse files
committed
Merge tag 'locks-v4.14-1' of git://git.kernel.org/pub/scm/linux/kernel/git/jlayton/linux
Pull file locking updates from Jeff Layton: "This pile just has a few file locking fixes from Ben Coddington. There are a couple of cleanup patches + an attempt to bring sanity to the l_pid value that is reported back to userland on an F_GETLK request. After a few gyrations, he came up with a way for filesystems to communicate to the VFS layer code whether the pid should be translated according to the namespace or presented as-is to userland" * tag 'locks-v4.14-1' of git://git.kernel.org/pub/scm/linux/kernel/git/jlayton/linux: locks: restore a warn for leaked locks on close fs/locks: Remove fl_nspid and use fs-specific l_pid for remote locks fs/locks: Use allocation rather than the stack in fcntl_getlk()
2 parents c7f396f + 3953704 commit 066dea8

File tree

8 files changed

+93
-54
lines changed

8 files changed

+93
-54
lines changed

drivers/staging/lustre/lustre/ldlm/ldlm_flock.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ ldlm_flock_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
596596
default:
597597
getlk->fl_type = F_UNLCK;
598598
}
599-
getlk->fl_pid = (pid_t)lock->l_policy_data.l_flock.pid;
599+
getlk->fl_pid = -(pid_t)lock->l_policy_data.l_flock.pid;
600600
getlk->fl_start = (loff_t)lock->l_policy_data.l_flock.start;
601601
getlk->fl_end = (loff_t)lock->l_policy_data.l_flock.end;
602602
} else {

fs/9p/vfs_file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
288288
fl->fl_end = OFFSET_MAX;
289289
else
290290
fl->fl_end = glock.start + glock.length - 1;
291-
fl->fl_pid = glock.proc_id;
291+
fl->fl_pid = -glock.proc_id;
292292
}
293293
kfree(glock.client_id);
294294
return res;

fs/ceph/locks.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file,
7979
err = ceph_mdsc_do_request(mdsc, inode, req);
8080

8181
if (operation == CEPH_MDS_OP_GETFILELOCK) {
82-
fl->fl_pid = le64_to_cpu(req->r_reply_info.filelock_reply->pid);
82+
fl->fl_pid = -le64_to_cpu(req->r_reply_info.filelock_reply->pid);
8383
if (CEPH_LOCK_SHARED == req->r_reply_info.filelock_reply->type)
8484
fl->fl_type = F_RDLCK;
8585
else if (CEPH_LOCK_EXCL == req->r_reply_info.filelock_reply->type)

fs/cifs/cifssmb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2522,7 +2522,7 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
25222522
pLockData->fl_start = le64_to_cpu(parm_data->start);
25232523
pLockData->fl_end = pLockData->fl_start +
25242524
le64_to_cpu(parm_data->length) - 1;
2525-
pLockData->fl_pid = le32_to_cpu(parm_data->pid);
2525+
pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
25262526
}
25272527
}
25282528

fs/dlm/plock.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file,
367367
locks_init_lock(fl);
368368
fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK;
369369
fl->fl_flags = FL_POSIX;
370-
fl->fl_pid = op->info.pid;
370+
fl->fl_pid = -op->info.pid;
371371
fl->fl_start = op->info.start;
372372
fl->fl_end = op->info.end;
373373
rv = 0;

fs/fuse/file.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2102,11 +2102,11 @@ static int convert_fuse_file_lock(struct fuse_conn *fc,
21022102
fl->fl_end = ffl->end;
21032103

21042104
/*
2105-
* Convert pid into the caller's pid namespace. If the pid
2106-
* does not map into the namespace fl_pid will get set to 0.
2105+
* Convert pid into init's pid namespace. The locks API will
2106+
* translate it into the caller's pid namespace.
21072107
*/
21082108
rcu_read_lock();
2109-
fl->fl_pid = pid_vnr(find_pid_ns(ffl->pid, fc->pid_ns));
2109+
fl->fl_pid = pid_nr_ns(find_pid_ns(ffl->pid, fc->pid_ns), &init_pid_ns);
21102110
rcu_read_unlock();
21112111
break;
21122112

fs/locks.c

Lines changed: 85 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@
137137
#define IS_FLOCK(fl) (fl->fl_flags & FL_FLOCK)
138138
#define IS_LEASE(fl) (fl->fl_flags & (FL_LEASE|FL_DELEG|FL_LAYOUT))
139139
#define IS_OFDLCK(fl) (fl->fl_flags & FL_OFDLCK)
140+
#define IS_REMOTELCK(fl) (fl->fl_pid <= 0)
140141

141142
static inline bool is_remote_lock(struct file *filp)
142143
{
@@ -270,6 +271,22 @@ locks_check_ctx_lists(struct inode *inode)
270271
}
271272
}
272273

274+
static void
275+
locks_check_ctx_file_list(struct file *filp, struct list_head *list,
276+
char *list_type)
277+
{
278+
struct file_lock *fl;
279+
struct inode *inode = locks_inode(filp);
280+
281+
list_for_each_entry(fl, list, fl_list)
282+
if (fl->fl_file == filp)
283+
pr_warn("Leaked %s lock on dev=0x%x:0x%x ino=0x%lx "
284+
" fl_owner=%p fl_flags=0x%x fl_type=0x%x fl_pid=%u\n",
285+
list_type, MAJOR(inode->i_sb->s_dev),
286+
MINOR(inode->i_sb->s_dev), inode->i_ino,
287+
fl->fl_owner, fl->fl_flags, fl->fl_type, fl->fl_pid);
288+
}
289+
273290
void
274291
locks_free_lock_context(struct inode *inode)
275292
{
@@ -733,7 +750,6 @@ static void locks_wake_up_blocks(struct file_lock *blocker)
733750
static void
734751
locks_insert_lock_ctx(struct file_lock *fl, struct list_head *before)
735752
{
736-
fl->fl_nspid = get_pid(task_tgid(current));
737753
list_add_tail(&fl->fl_list, before);
738754
locks_insert_global_locks(fl);
739755
}
@@ -743,10 +759,6 @@ locks_unlink_lock_ctx(struct file_lock *fl)
743759
{
744760
locks_delete_global_locks(fl);
745761
list_del_init(&fl->fl_list);
746-
if (fl->fl_nspid) {
747-
put_pid(fl->fl_nspid);
748-
fl->fl_nspid = NULL;
749-
}
750762
locks_wake_up_blocks(fl);
751763
}
752764

@@ -823,8 +835,6 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
823835
list_for_each_entry(cfl, &ctx->flc_posix, fl_list) {
824836
if (posix_locks_conflict(fl, cfl)) {
825837
locks_copy_conflock(fl, cfl);
826-
if (cfl->fl_nspid)
827-
fl->fl_pid = pid_vnr(cfl->fl_nspid);
828838
goto out;
829839
}
830840
}
@@ -2048,9 +2058,33 @@ int vfs_test_lock(struct file *filp, struct file_lock *fl)
20482058
}
20492059
EXPORT_SYMBOL_GPL(vfs_test_lock);
20502060

2061+
/**
2062+
* locks_translate_pid - translate a file_lock's fl_pid number into a namespace
2063+
* @fl: The file_lock who's fl_pid should be translated
2064+
* @ns: The namespace into which the pid should be translated
2065+
*
2066+
* Used to tranlate a fl_pid into a namespace virtual pid number
2067+
*/
2068+
static pid_t locks_translate_pid(struct file_lock *fl, struct pid_namespace *ns)
2069+
{
2070+
pid_t vnr;
2071+
struct pid *pid;
2072+
2073+
if (IS_OFDLCK(fl))
2074+
return -1;
2075+
if (IS_REMOTELCK(fl))
2076+
return fl->fl_pid;
2077+
2078+
rcu_read_lock();
2079+
pid = find_pid_ns(fl->fl_pid, &init_pid_ns);
2080+
vnr = pid_nr_ns(pid, ns);
2081+
rcu_read_unlock();
2082+
return vnr;
2083+
}
2084+
20512085
static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl)
20522086
{
2053-
flock->l_pid = IS_OFDLCK(fl) ? -1 : fl->fl_pid;
2087+
flock->l_pid = locks_translate_pid(fl, task_active_pid_ns(current));
20542088
#if BITS_PER_LONG == 32
20552089
/*
20562090
* Make sure we can represent the posix lock via
@@ -2072,7 +2106,7 @@ static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl)
20722106
#if BITS_PER_LONG == 32
20732107
static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl)
20742108
{
2075-
flock->l_pid = IS_OFDLCK(fl) ? -1 : fl->fl_pid;
2109+
flock->l_pid = locks_translate_pid(fl, task_active_pid_ns(current));
20762110
flock->l_start = fl->fl_start;
20772111
flock->l_len = fl->fl_end == OFFSET_MAX ? 0 :
20782112
fl->fl_end - fl->fl_start + 1;
@@ -2086,14 +2120,17 @@ static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl)
20862120
*/
20872121
int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock *flock)
20882122
{
2089-
struct file_lock file_lock;
2123+
struct file_lock *fl;
20902124
int error;
20912125

2126+
fl = locks_alloc_lock();
2127+
if (fl == NULL)
2128+
return -ENOMEM;
20922129
error = -EINVAL;
20932130
if (flock->l_type != F_RDLCK && flock->l_type != F_WRLCK)
20942131
goto out;
20952132

2096-
error = flock_to_posix_lock(filp, &file_lock, flock);
2133+
error = flock_to_posix_lock(filp, fl, flock);
20972134
if (error)
20982135
goto out;
20992136

@@ -2103,23 +2140,22 @@ int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock *flock)
21032140
goto out;
21042141

21052142
cmd = F_GETLK;
2106-
file_lock.fl_flags |= FL_OFDLCK;
2107-
file_lock.fl_owner = filp;
2143+
fl->fl_flags |= FL_OFDLCK;
2144+
fl->fl_owner = filp;
21082145
}
21092146

2110-
error = vfs_test_lock(filp, &file_lock);
2147+
error = vfs_test_lock(filp, fl);
21112148
if (error)
21122149
goto out;
21132150

2114-
flock->l_type = file_lock.fl_type;
2115-
if (file_lock.fl_type != F_UNLCK) {
2116-
error = posix_lock_to_flock(flock, &file_lock);
2151+
flock->l_type = fl->fl_type;
2152+
if (fl->fl_type != F_UNLCK) {
2153+
error = posix_lock_to_flock(flock, fl);
21172154
if (error)
2118-
goto rel_priv;
2155+
goto out;
21192156
}
2120-
rel_priv:
2121-
locks_release_private(&file_lock);
21222157
out:
2158+
locks_free_lock(fl);
21232159
return error;
21242160
}
21252161

@@ -2298,14 +2334,18 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
22982334
*/
22992335
int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 *flock)
23002336
{
2301-
struct file_lock file_lock;
2337+
struct file_lock *fl;
23022338
int error;
23032339

2340+
fl = locks_alloc_lock();
2341+
if (fl == NULL)
2342+
return -ENOMEM;
2343+
23042344
error = -EINVAL;
23052345
if (flock->l_type != F_RDLCK && flock->l_type != F_WRLCK)
23062346
goto out;
23072347

2308-
error = flock64_to_posix_lock(filp, &file_lock, flock);
2348+
error = flock64_to_posix_lock(filp, fl, flock);
23092349
if (error)
23102350
goto out;
23112351

@@ -2315,20 +2355,20 @@ int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 *flock)
23152355
goto out;
23162356

23172357
cmd = F_GETLK64;
2318-
file_lock.fl_flags |= FL_OFDLCK;
2319-
file_lock.fl_owner = filp;
2358+
fl->fl_flags |= FL_OFDLCK;
2359+
fl->fl_owner = filp;
23202360
}
23212361

2322-
error = vfs_test_lock(filp, &file_lock);
2362+
error = vfs_test_lock(filp, fl);
23232363
if (error)
23242364
goto out;
23252365

2326-
flock->l_type = file_lock.fl_type;
2327-
if (file_lock.fl_type != F_UNLCK)
2328-
posix_lock_to_flock64(flock, &file_lock);
2366+
flock->l_type = fl->fl_type;
2367+
if (fl->fl_type != F_UNLCK)
2368+
posix_lock_to_flock64(flock, fl);
23292369

2330-
locks_release_private(&file_lock);
23312370
out:
2371+
locks_free_lock(fl);
23322372
return error;
23332373
}
23342374

@@ -2525,6 +2565,12 @@ void locks_remove_file(struct file *filp)
25252565

25262566
/* remove any leases */
25272567
locks_remove_lease(filp, ctx);
2568+
2569+
spin_lock(&ctx->flc_lock);
2570+
locks_check_ctx_file_list(filp, &ctx->flc_posix, "POSIX");
2571+
locks_check_ctx_file_list(filp, &ctx->flc_flock, "FLOCK");
2572+
locks_check_ctx_file_list(filp, &ctx->flc_lease, "LEASE");
2573+
spin_unlock(&ctx->flc_lock);
25282574
}
25292575

25302576
/**
@@ -2578,22 +2624,16 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
25782624
{
25792625
struct inode *inode = NULL;
25802626
unsigned int fl_pid;
2627+
struct pid_namespace *proc_pidns = file_inode(f->file)->i_sb->s_fs_info;
25812628

2582-
if (fl->fl_nspid) {
2583-
struct pid_namespace *proc_pidns = file_inode(f->file)->i_sb->s_fs_info;
2584-
2585-
/* Don't let fl_pid change based on who is reading the file */
2586-
fl_pid = pid_nr_ns(fl->fl_nspid, proc_pidns);
2587-
2588-
/*
2589-
* If there isn't a fl_pid don't display who is waiting on
2590-
* the lock if we are called from locks_show, or if we are
2591-
* called from __show_fd_info - skip lock entirely
2592-
*/
2593-
if (fl_pid == 0)
2594-
return;
2595-
} else
2596-
fl_pid = fl->fl_pid;
2629+
fl_pid = locks_translate_pid(fl, proc_pidns);
2630+
/*
2631+
* If there isn't a fl_pid don't display who is waiting on
2632+
* the lock if we are called from locks_show, or if we are
2633+
* called from __show_fd_info - skip lock entirely
2634+
*/
2635+
if (fl_pid == 0)
2636+
return;
25972637

25982638
if (fl->fl_file != NULL)
25992639
inode = locks_inode(fl->fl_file);
@@ -2668,7 +2708,7 @@ static int locks_show(struct seq_file *f, void *v)
26682708

26692709
fl = hlist_entry(v, struct file_lock, fl_link);
26702710

2671-
if (fl->fl_nspid && !pid_nr_ns(fl->fl_nspid, proc_pidns))
2711+
if (locks_translate_pid(fl, proc_pidns) == 0)
26722712
return 0;
26732713

26742714
lock_get_status(f, fl, iter->li_pos, "");

include/linux/fs.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1002,7 +1002,6 @@ struct file_lock {
10021002
unsigned char fl_type;
10031003
unsigned int fl_pid;
10041004
int fl_link_cpu; /* what cpu's list is this on? */
1005-
struct pid *fl_nspid;
10061005
wait_queue_head_t fl_wait;
10071006
struct file *fl_file;
10081007
loff_t fl_start;

0 commit comments

Comments
 (0)