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
141142static 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+
273290void
274291locks_free_lock_context (struct inode * inode )
275292{
@@ -733,7 +750,6 @@ static void locks_wake_up_blocks(struct file_lock *blocker)
733750static void
734751locks_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}
20492059EXPORT_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+
20512085static 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
20732107static 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 */
20872121int 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 );
21222157out :
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 */
22992335int 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 );
23312370out :
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 , "" );
0 commit comments