3333#include <linux/list_sort.h>
3434#include <linux/lockref.h>
3535#include <linux/rhashtable.h>
36+ #include <linux/pid_namespace.h>
37+ #include <linux/fdtable.h>
38+ #include <linux/file.h>
3639
3740#include "gfs2.h"
3841#include "incore.h"
@@ -1456,6 +1459,15 @@ void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...)
14561459 va_end (args );
14571460}
14581461
1462+ static inline bool pid_is_meaningful (const struct gfs2_holder * gh )
1463+ {
1464+ if (!(gh -> gh_flags & GL_NOPID ))
1465+ return true;
1466+ if (gh -> gh_state == LM_ST_UNLOCKED )
1467+ return true;
1468+ return false;
1469+ }
1470+
14591471/**
14601472 * add_to_queue - Add a holder to the wait queue (but look for recursion)
14611473 * @gh: the holder structure to add
@@ -1492,10 +1504,17 @@ __acquires(&gl->gl_lockref.lock)
14921504 }
14931505
14941506 list_for_each_entry (gh2 , & gl -> gl_holders , gh_list ) {
1495- if (unlikely (gh2 -> gh_owner_pid == gh -> gh_owner_pid &&
1496- (gh -> gh_gl -> gl_ops -> go_type != LM_TYPE_FLOCK ) &&
1497- !test_bit (HIF_MAY_DEMOTE , & gh2 -> gh_iflags )))
1498- goto trap_recursive ;
1507+ if (likely (gh2 -> gh_owner_pid != gh -> gh_owner_pid ))
1508+ continue ;
1509+ if (gh -> gh_gl -> gl_ops -> go_type == LM_TYPE_FLOCK )
1510+ continue ;
1511+ if (test_bit (HIF_MAY_DEMOTE , & gh2 -> gh_iflags ))
1512+ continue ;
1513+ if (!pid_is_meaningful (gh2 ))
1514+ continue ;
1515+ goto trap_recursive ;
1516+ }
1517+ list_for_each_entry (gh2 , & gl -> gl_holders , gh_list ) {
14991518 if (try_futile &&
15001519 !(gh2 -> gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB ))) {
15011520fail :
@@ -2306,19 +2325,24 @@ static const char *hflags2str(char *buf, u16 flags, unsigned long iflags)
23062325static void dump_holder (struct seq_file * seq , const struct gfs2_holder * gh ,
23072326 const char * fs_id_buf )
23082327{
2309- struct task_struct * gh_owner = NULL ;
2328+ const char * comm = "(none)" ;
2329+ pid_t owner_pid = 0 ;
23102330 char flags_buf [32 ];
23112331
23122332 rcu_read_lock ();
2313- if (gh -> gh_owner_pid )
2333+ if (pid_is_meaningful (gh )) {
2334+ struct task_struct * gh_owner ;
2335+
2336+ comm = "(ended)" ;
2337+ owner_pid = pid_nr (gh -> gh_owner_pid );
23142338 gh_owner = pid_task (gh -> gh_owner_pid , PIDTYPE_PID );
2339+ if (gh_owner )
2340+ comm = gh_owner -> comm ;
2341+ }
23152342 gfs2_print_dbg (seq , "%s H: s:%s f:%s e:%d p:%ld [%s] %pS\n" ,
23162343 fs_id_buf , state2str (gh -> gh_state ),
23172344 hflags2str (flags_buf , gh -> gh_flags , gh -> gh_iflags ),
2318- gh -> gh_error ,
2319- gh -> gh_owner_pid ? (long )pid_nr (gh -> gh_owner_pid ) : -1 ,
2320- gh_owner ? gh_owner -> comm : "(ended)" ,
2321- (void * )gh -> gh_ip );
2345+ gh -> gh_error , (long )owner_pid , comm , (void * )gh -> gh_ip );
23222346 rcu_read_unlock ();
23232347}
23242348
@@ -2733,6 +2757,172 @@ static const struct file_operations gfs2_glstats_fops = {
27332757 .release = gfs2_glocks_release ,
27342758};
27352759
2760+ struct gfs2_glockfd_iter {
2761+ struct super_block * sb ;
2762+ unsigned int tgid ;
2763+ struct task_struct * task ;
2764+ unsigned int fd ;
2765+ struct file * file ;
2766+ };
2767+
2768+ static struct task_struct * gfs2_glockfd_next_task (struct gfs2_glockfd_iter * i )
2769+ {
2770+ struct pid_namespace * ns = task_active_pid_ns (current );
2771+ struct pid * pid ;
2772+
2773+ if (i -> task )
2774+ put_task_struct (i -> task );
2775+
2776+ rcu_read_lock ();
2777+ retry :
2778+ i -> task = NULL ;
2779+ pid = find_ge_pid (i -> tgid , ns );
2780+ if (pid ) {
2781+ i -> tgid = pid_nr_ns (pid , ns );
2782+ i -> task = pid_task (pid , PIDTYPE_TGID );
2783+ if (!i -> task ) {
2784+ i -> tgid ++ ;
2785+ goto retry ;
2786+ }
2787+ get_task_struct (i -> task );
2788+ }
2789+ rcu_read_unlock ();
2790+ return i -> task ;
2791+ }
2792+
2793+ static struct file * gfs2_glockfd_next_file (struct gfs2_glockfd_iter * i )
2794+ {
2795+ if (i -> file ) {
2796+ fput (i -> file );
2797+ i -> file = NULL ;
2798+ }
2799+
2800+ rcu_read_lock ();
2801+ for (;; i -> fd ++ ) {
2802+ struct inode * inode ;
2803+
2804+ i -> file = task_lookup_next_fd_rcu (i -> task , & i -> fd );
2805+ if (!i -> file ) {
2806+ i -> fd = 0 ;
2807+ break ;
2808+ }
2809+ inode = file_inode (i -> file );
2810+ if (inode -> i_sb != i -> sb )
2811+ continue ;
2812+ if (get_file_rcu (i -> file ))
2813+ break ;
2814+ }
2815+ rcu_read_unlock ();
2816+ return i -> file ;
2817+ }
2818+
2819+ static void * gfs2_glockfd_seq_start (struct seq_file * seq , loff_t * pos )
2820+ {
2821+ struct gfs2_glockfd_iter * i = seq -> private ;
2822+
2823+ if (* pos )
2824+ return NULL ;
2825+ while (gfs2_glockfd_next_task (i )) {
2826+ if (gfs2_glockfd_next_file (i ))
2827+ return i ;
2828+ i -> tgid ++ ;
2829+ }
2830+ return NULL ;
2831+ }
2832+
2833+ static void * gfs2_glockfd_seq_next (struct seq_file * seq , void * iter_ptr ,
2834+ loff_t * pos )
2835+ {
2836+ struct gfs2_glockfd_iter * i = seq -> private ;
2837+
2838+ (* pos )++ ;
2839+ i -> fd ++ ;
2840+ do {
2841+ if (gfs2_glockfd_next_file (i ))
2842+ return i ;
2843+ i -> tgid ++ ;
2844+ } while (gfs2_glockfd_next_task (i ));
2845+ return NULL ;
2846+ }
2847+
2848+ static void gfs2_glockfd_seq_stop (struct seq_file * seq , void * iter_ptr )
2849+ {
2850+ struct gfs2_glockfd_iter * i = seq -> private ;
2851+
2852+ if (i -> file )
2853+ fput (i -> file );
2854+ if (i -> task )
2855+ put_task_struct (i -> task );
2856+ }
2857+
2858+ static void gfs2_glockfd_seq_show_flock (struct seq_file * seq ,
2859+ struct gfs2_glockfd_iter * i )
2860+ {
2861+ struct gfs2_file * fp = i -> file -> private_data ;
2862+ struct gfs2_holder * fl_gh = & fp -> f_fl_gh ;
2863+ struct lm_lockname gl_name = { .ln_type = LM_TYPE_RESERVED };
2864+
2865+ if (!READ_ONCE (fl_gh -> gh_gl ))
2866+ return ;
2867+
2868+ spin_lock (& i -> file -> f_lock );
2869+ if (gfs2_holder_initialized (fl_gh ))
2870+ gl_name = fl_gh -> gh_gl -> gl_name ;
2871+ spin_unlock (& i -> file -> f_lock );
2872+
2873+ if (gl_name .ln_type != LM_TYPE_RESERVED ) {
2874+ seq_printf (seq , "%d %u %u/%llx\n" ,
2875+ i -> tgid , i -> fd , gl_name .ln_type ,
2876+ (unsigned long long )gl_name .ln_number );
2877+ }
2878+ }
2879+
2880+ static int gfs2_glockfd_seq_show (struct seq_file * seq , void * iter_ptr )
2881+ {
2882+ struct gfs2_glockfd_iter * i = seq -> private ;
2883+ struct inode * inode = file_inode (i -> file );
2884+ struct gfs2_glock * gl ;
2885+
2886+ inode_lock_shared (inode );
2887+ gl = GFS2_I (inode )-> i_iopen_gh .gh_gl ;
2888+ if (gl ) {
2889+ seq_printf (seq , "%d %u %u/%llx\n" ,
2890+ i -> tgid , i -> fd , gl -> gl_name .ln_type ,
2891+ (unsigned long long )gl -> gl_name .ln_number );
2892+ }
2893+ gfs2_glockfd_seq_show_flock (seq , i );
2894+ inode_unlock_shared (inode );
2895+ return 0 ;
2896+ }
2897+
2898+ static const struct seq_operations gfs2_glockfd_seq_ops = {
2899+ .start = gfs2_glockfd_seq_start ,
2900+ .next = gfs2_glockfd_seq_next ,
2901+ .stop = gfs2_glockfd_seq_stop ,
2902+ .show = gfs2_glockfd_seq_show ,
2903+ };
2904+
2905+ static int gfs2_glockfd_open (struct inode * inode , struct file * file )
2906+ {
2907+ struct gfs2_glockfd_iter * i ;
2908+ struct gfs2_sbd * sdp = inode -> i_private ;
2909+
2910+ i = __seq_open_private (file , & gfs2_glockfd_seq_ops ,
2911+ sizeof (struct gfs2_glockfd_iter ));
2912+ if (!i )
2913+ return - ENOMEM ;
2914+ i -> sb = sdp -> sd_vfs ;
2915+ return 0 ;
2916+ }
2917+
2918+ static const struct file_operations gfs2_glockfd_fops = {
2919+ .owner = THIS_MODULE ,
2920+ .open = gfs2_glockfd_open ,
2921+ .read = seq_read ,
2922+ .llseek = seq_lseek ,
2923+ .release = seq_release_private ,
2924+ };
2925+
27362926DEFINE_SEQ_ATTRIBUTE (gfs2_sbstats );
27372927
27382928void gfs2_create_debugfs_file (struct gfs2_sbd * sdp )
@@ -2742,6 +2932,9 @@ void gfs2_create_debugfs_file(struct gfs2_sbd *sdp)
27422932 debugfs_create_file ("glocks" , S_IFREG | S_IRUGO , sdp -> debugfs_dir , sdp ,
27432933 & gfs2_glocks_fops );
27442934
2935+ debugfs_create_file ("glockfd" , S_IFREG | S_IRUGO , sdp -> debugfs_dir , sdp ,
2936+ & gfs2_glockfd_fops );
2937+
27452938 debugfs_create_file ("glstats" , S_IFREG | S_IRUGO , sdp -> debugfs_dir , sdp ,
27462939 & gfs2_glstats_fops );
27472940
0 commit comments