aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-09-06 16:43:26 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-09-06 16:43:26 -0400
commit066dea8c30ae7d8e061145bcf5422ce0773582eb (patch)
tree2de9df544b2961bb5a6690978908e7749c7f19c0
parentc7f396f12fb3644ff325acb2384b64c8eea7a746 (diff)
parent3953704fde7ec47f452ce6446fb7a0d5dc2f74df (diff)
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()
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_flock.c2
-rw-r--r--fs/9p/vfs_file.c2
-rw-r--r--fs/ceph/locks.c2
-rw-r--r--fs/cifs/cifssmb.c2
-rw-r--r--fs/dlm/plock.c2
-rw-r--r--fs/fuse/file.c6
-rw-r--r--fs/locks.c130
-rw-r--r--include/linux/fs.h1
8 files changed, 93 insertions, 54 deletions
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
index d571b8b050d8..cb826e9e840e 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
@@ -596,7 +596,7 @@ granted:
596 default: 596 default:
597 getlk->fl_type = F_UNLCK; 597 getlk->fl_type = F_UNLCK;
598 } 598 }
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;
600 getlk->fl_start = (loff_t)lock->l_policy_data.l_flock.start; 600 getlk->fl_start = (loff_t)lock->l_policy_data.l_flock.start;
601 getlk->fl_end = (loff_t)lock->l_policy_data.l_flock.end; 601 getlk->fl_end = (loff_t)lock->l_policy_data.l_flock.end;
602 } else { 602 } else {
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 3de3b4a89d89..43c242e17132 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -288,7 +288,7 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
288 fl->fl_end = OFFSET_MAX; 288 fl->fl_end = OFFSET_MAX;
289 else 289 else
290 fl->fl_end = glock.start + glock.length - 1; 290 fl->fl_end = glock.start + glock.length - 1;
291 fl->fl_pid = glock.proc_id; 291 fl->fl_pid = -glock.proc_id;
292 } 292 }
293 kfree(glock.client_id); 293 kfree(glock.client_id);
294 return res; 294 return res;
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c
index 64ae74472046..8cd63e8123d8 100644
--- a/fs/ceph/locks.c
+++ b/fs/ceph/locks.c
@@ -79,7 +79,7 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file,
79 err = ceph_mdsc_do_request(mdsc, inode, req); 79 err = ceph_mdsc_do_request(mdsc, inode, req);
80 80
81 if (operation == CEPH_MDS_OP_GETFILELOCK) { 81 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);
83 if (CEPH_LOCK_SHARED == req->r_reply_info.filelock_reply->type) 83 if (CEPH_LOCK_SHARED == req->r_reply_info.filelock_reply->type)
84 fl->fl_type = F_RDLCK; 84 fl->fl_type = F_RDLCK;
85 else if (CEPH_LOCK_EXCL == req->r_reply_info.filelock_reply->type) 85 else if (CEPH_LOCK_EXCL == req->r_reply_info.filelock_reply->type)
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 72a53bd19865..118a63e7e221 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -2522,7 +2522,7 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
2522 pLockData->fl_start = le64_to_cpu(parm_data->start); 2522 pLockData->fl_start = le64_to_cpu(parm_data->start);
2523 pLockData->fl_end = pLockData->fl_start + 2523 pLockData->fl_end = pLockData->fl_start +
2524 le64_to_cpu(parm_data->length) - 1; 2524 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);
2526 } 2526 }
2527 } 2527 }
2528 2528
diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c
index d401425f602a..e631b1689228 100644
--- a/fs/dlm/plock.c
+++ b/fs/dlm/plock.c
@@ -367,7 +367,7 @@ int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file,
367 locks_init_lock(fl); 367 locks_init_lock(fl);
368 fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK; 368 fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK;
369 fl->fl_flags = FL_POSIX; 369 fl->fl_flags = FL_POSIX;
370 fl->fl_pid = op->info.pid; 370 fl->fl_pid = -op->info.pid;
371 fl->fl_start = op->info.start; 371 fl->fl_start = op->info.start;
372 fl->fl_end = op->info.end; 372 fl->fl_end = op->info.end;
373 rv = 0; 373 rv = 0;
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index ab60051be6e5..0273029b1220 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -2102,11 +2102,11 @@ static int convert_fuse_file_lock(struct fuse_conn *fc,
2102 fl->fl_end = ffl->end; 2102 fl->fl_end = ffl->end;
2103 2103
2104 /* 2104 /*
2105 * Convert pid into the caller's pid namespace. If the pid 2105 * Convert pid into init's pid namespace. The locks API will
2106 * does not map into the namespace fl_pid will get set to 0. 2106 * translate it into the caller's pid namespace.
2107 */ 2107 */
2108 rcu_read_lock(); 2108 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);
2110 rcu_read_unlock(); 2110 rcu_read_unlock();
2111 break; 2111 break;
2112 2112
diff --git a/fs/locks.c b/fs/locks.c
index afefeb4ad6de..1bd71c4d663a 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -137,6 +137,7 @@
137#define IS_FLOCK(fl) (fl->fl_flags & FL_FLOCK) 137#define IS_FLOCK(fl) (fl->fl_flags & FL_FLOCK)
138#define IS_LEASE(fl) (fl->fl_flags & (FL_LEASE|FL_DELEG|FL_LAYOUT)) 138#define IS_LEASE(fl) (fl->fl_flags & (FL_LEASE|FL_DELEG|FL_LAYOUT))
139#define IS_OFDLCK(fl) (fl->fl_flags & FL_OFDLCK) 139#define IS_OFDLCK(fl) (fl->fl_flags & FL_OFDLCK)
140#define IS_REMOTELCK(fl) (fl->fl_pid <= 0)
140 141
141static inline bool is_remote_lock(struct file *filp) 142static inline bool is_remote_lock(struct file *filp)
142{ 143{
@@ -270,6 +271,22 @@ locks_check_ctx_lists(struct inode *inode)
270 } 271 }
271} 272}
272 273
274static void
275locks_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
273void 290void
274locks_free_lock_context(struct inode *inode) 291locks_free_lock_context(struct inode *inode)
275{ 292{
@@ -733,7 +750,6 @@ static void locks_wake_up_blocks(struct file_lock *blocker)
733static void 750static void
734locks_insert_lock_ctx(struct file_lock *fl, struct list_head *before) 751locks_insert_lock_ctx(struct file_lock *fl, struct list_head *before)
735{ 752{
736 fl->fl_nspid = get_pid(task_tgid(current));
737 list_add_tail(&fl->fl_list, before); 753 list_add_tail(&fl->fl_list, before);
738 locks_insert_global_locks(fl); 754 locks_insert_global_locks(fl);
739} 755}
@@ -743,10 +759,6 @@ locks_unlink_lock_ctx(struct file_lock *fl)
743{ 759{
744 locks_delete_global_locks(fl); 760 locks_delete_global_locks(fl);
745 list_del_init(&fl->fl_list); 761 list_del_init(&fl->fl_list);
746 if (fl->fl_nspid) {
747 put_pid(fl->fl_nspid);
748 fl->fl_nspid = NULL;
749 }
750 locks_wake_up_blocks(fl); 762 locks_wake_up_blocks(fl);
751} 763}
752 764
@@ -823,8 +835,6 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
823 list_for_each_entry(cfl, &ctx->flc_posix, fl_list) { 835 list_for_each_entry(cfl, &ctx->flc_posix, fl_list) {
824 if (posix_locks_conflict(fl, cfl)) { 836 if (posix_locks_conflict(fl, cfl)) {
825 locks_copy_conflock(fl, cfl); 837 locks_copy_conflock(fl, cfl);
826 if (cfl->fl_nspid)
827 fl->fl_pid = pid_vnr(cfl->fl_nspid);
828 goto out; 838 goto out;
829 } 839 }
830 } 840 }
@@ -2048,9 +2058,33 @@ int vfs_test_lock(struct file *filp, struct file_lock *fl)
2048} 2058}
2049EXPORT_SYMBOL_GPL(vfs_test_lock); 2059EXPORT_SYMBOL_GPL(vfs_test_lock);
2050 2060
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 */
2068static 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
2051static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl) 2085static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl)
2052{ 2086{
2053 flock->l_pid = IS_OFDLCK(fl) ? -1 : fl->fl_pid; 2087 flock->l_pid = locks_translate_pid(fl, task_active_pid_ns(current));
2054#if BITS_PER_LONG == 32 2088#if BITS_PER_LONG == 32
2055 /* 2089 /*
2056 * Make sure we can represent the posix lock via 2090 * 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)
2072#if BITS_PER_LONG == 32 2106#if BITS_PER_LONG == 32
2073static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl) 2107static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl)
2074{ 2108{
2075 flock->l_pid = IS_OFDLCK(fl) ? -1 : fl->fl_pid; 2109 flock->l_pid = locks_translate_pid(fl, task_active_pid_ns(current));
2076 flock->l_start = fl->fl_start; 2110 flock->l_start = fl->fl_start;
2077 flock->l_len = fl->fl_end == OFFSET_MAX ? 0 : 2111 flock->l_len = fl->fl_end == OFFSET_MAX ? 0 :
2078 fl->fl_end - fl->fl_start + 1; 2112 fl->fl_end - fl->fl_start + 1;
@@ -2086,14 +2120,17 @@ static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl)
2086 */ 2120 */
2087int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock *flock) 2121int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock *flock)
2088{ 2122{
2089 struct file_lock file_lock; 2123 struct file_lock *fl;
2090 int error; 2124 int error;
2091 2125
2126 fl = locks_alloc_lock();
2127 if (fl == NULL)
2128 return -ENOMEM;
2092 error = -EINVAL; 2129 error = -EINVAL;
2093 if (flock->l_type != F_RDLCK && flock->l_type != F_WRLCK) 2130 if (flock->l_type != F_RDLCK && flock->l_type != F_WRLCK)
2094 goto out; 2131 goto out;
2095 2132
2096 error = flock_to_posix_lock(filp, &file_lock, flock); 2133 error = flock_to_posix_lock(filp, fl, flock);
2097 if (error) 2134 if (error)
2098 goto out; 2135 goto out;
2099 2136
@@ -2103,23 +2140,22 @@ int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock *flock)
2103 goto out; 2140 goto out;
2104 2141
2105 cmd = F_GETLK; 2142 cmd = F_GETLK;
2106 file_lock.fl_flags |= FL_OFDLCK; 2143 fl->fl_flags |= FL_OFDLCK;
2107 file_lock.fl_owner = filp; 2144 fl->fl_owner = filp;
2108 } 2145 }
2109 2146
2110 error = vfs_test_lock(filp, &file_lock); 2147 error = vfs_test_lock(filp, fl);
2111 if (error) 2148 if (error)
2112 goto out; 2149 goto out;
2113 2150
2114 flock->l_type = file_lock.fl_type; 2151 flock->l_type = fl->fl_type;
2115 if (file_lock.fl_type != F_UNLCK) { 2152 if (fl->fl_type != F_UNLCK) {
2116 error = posix_lock_to_flock(flock, &file_lock); 2153 error = posix_lock_to_flock(flock, fl);
2117 if (error) 2154 if (error)
2118 goto rel_priv; 2155 goto out;
2119 } 2156 }
2120rel_priv:
2121 locks_release_private(&file_lock);
2122out: 2157out:
2158 locks_free_lock(fl);
2123 return error; 2159 return error;
2124} 2160}
2125 2161
@@ -2298,14 +2334,18 @@ out:
2298 */ 2334 */
2299int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 *flock) 2335int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 *flock)
2300{ 2336{
2301 struct file_lock file_lock; 2337 struct file_lock *fl;
2302 int error; 2338 int error;
2303 2339
2340 fl = locks_alloc_lock();
2341 if (fl == NULL)
2342 return -ENOMEM;
2343
2304 error = -EINVAL; 2344 error = -EINVAL;
2305 if (flock->l_type != F_RDLCK && flock->l_type != F_WRLCK) 2345 if (flock->l_type != F_RDLCK && flock->l_type != F_WRLCK)
2306 goto out; 2346 goto out;
2307 2347
2308 error = flock64_to_posix_lock(filp, &file_lock, flock); 2348 error = flock64_to_posix_lock(filp, fl, flock);
2309 if (error) 2349 if (error)
2310 goto out; 2350 goto out;
2311 2351
@@ -2315,20 +2355,20 @@ int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 *flock)
2315 goto out; 2355 goto out;
2316 2356
2317 cmd = F_GETLK64; 2357 cmd = F_GETLK64;
2318 file_lock.fl_flags |= FL_OFDLCK; 2358 fl->fl_flags |= FL_OFDLCK;
2319 file_lock.fl_owner = filp; 2359 fl->fl_owner = filp;
2320 } 2360 }
2321 2361
2322 error = vfs_test_lock(filp, &file_lock); 2362 error = vfs_test_lock(filp, fl);
2323 if (error) 2363 if (error)
2324 goto out; 2364 goto out;
2325 2365
2326 flock->l_type = file_lock.fl_type; 2366 flock->l_type = fl->fl_type;
2327 if (file_lock.fl_type != F_UNLCK) 2367 if (fl->fl_type != F_UNLCK)
2328 posix_lock_to_flock64(flock, &file_lock); 2368 posix_lock_to_flock64(flock, fl);
2329 2369
2330 locks_release_private(&file_lock);
2331out: 2370out:
2371 locks_free_lock(fl);
2332 return error; 2372 return error;
2333} 2373}
2334 2374
@@ -2525,6 +2565,12 @@ void locks_remove_file(struct file *filp)
2525 2565
2526 /* remove any leases */ 2566 /* remove any leases */
2527 locks_remove_lease(filp, ctx); 2567 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);
2528} 2574}
2529 2575
2530/** 2576/**
@@ -2578,22 +2624,16 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
2578{ 2624{
2579 struct inode *inode = NULL; 2625 struct inode *inode = NULL;
2580 unsigned int fl_pid; 2626 unsigned int fl_pid;
2627 struct pid_namespace *proc_pidns = file_inode(f->file)->i_sb->s_fs_info;
2581 2628
2582 if (fl->fl_nspid) { 2629 fl_pid = locks_translate_pid(fl, proc_pidns);
2583 struct pid_namespace *proc_pidns = file_inode(f->file)->i_sb->s_fs_info; 2630 /*
2584 2631 * If there isn't a fl_pid don't display who is waiting on
2585 /* Don't let fl_pid change based on who is reading the file */ 2632 * the lock if we are called from locks_show, or if we are
2586 fl_pid = pid_nr_ns(fl->fl_nspid, proc_pidns); 2633 * called from __show_fd_info - skip lock entirely
2587 2634 */
2588 /* 2635 if (fl_pid == 0)
2589 * If there isn't a fl_pid don't display who is waiting on 2636 return;
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;
2597 2637
2598 if (fl->fl_file != NULL) 2638 if (fl->fl_file != NULL)
2599 inode = locks_inode(fl->fl_file); 2639 inode = locks_inode(fl->fl_file);
@@ -2668,7 +2708,7 @@ static int locks_show(struct seq_file *f, void *v)
2668 2708
2669 fl = hlist_entry(v, struct file_lock, fl_link); 2709 fl = hlist_entry(v, struct file_lock, fl_link);
2670 2710
2671 if (fl->fl_nspid && !pid_nr_ns(fl->fl_nspid, proc_pidns)) 2711 if (locks_translate_pid(fl, proc_pidns) == 0)
2672 return 0; 2712 return 0;
2673 2713
2674 lock_get_status(f, fl, iter->li_pos, ""); 2714 lock_get_status(f, fl, iter->li_pos, "");
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 495b5c2e430e..0a51a8b197f7 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1002,7 +1002,6 @@ struct file_lock {
1002 unsigned char fl_type; 1002 unsigned char fl_type;
1003 unsigned int fl_pid; 1003 unsigned int fl_pid;
1004 int fl_link_cpu; /* what cpu's list is this on? */ 1004 int fl_link_cpu; /* what cpu's list is this on? */
1005 struct pid *fl_nspid;
1006 wait_queue_head_t fl_wait; 1005 wait_queue_head_t fl_wait;
1007 struct file *fl_file; 1006 struct file *fl_file;
1008 loff_t fl_start; 1007 loff_t fl_start;