33
33
#include <linux/list_sort.h>
34
34
#include <linux/lockref.h>
35
35
#include <linux/rhashtable.h>
36
+ #include <linux/pid_namespace.h>
37
+ #include <linux/fdtable.h>
38
+ #include <linux/file.h>
36
39
37
40
#include "gfs2.h"
38
41
#include "incore.h"
@@ -1456,6 +1459,15 @@ void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...)
1456
1459
va_end (args );
1457
1460
}
1458
1461
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
+
1459
1471
/**
1460
1472
* add_to_queue - Add a holder to the wait queue (but look for recursion)
1461
1473
* @gh: the holder structure to add
@@ -1492,10 +1504,17 @@ __acquires(&gl->gl_lockref.lock)
1492
1504
}
1493
1505
1494
1506
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 ) {
1499
1518
if (try_futile &&
1500
1519
!(gh2 -> gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB ))) {
1501
1520
fail :
@@ -2306,19 +2325,24 @@ static const char *hflags2str(char *buf, u16 flags, unsigned long iflags)
2306
2325
static void dump_holder (struct seq_file * seq , const struct gfs2_holder * gh ,
2307
2326
const char * fs_id_buf )
2308
2327
{
2309
- struct task_struct * gh_owner = NULL ;
2328
+ const char * comm = "(none)" ;
2329
+ pid_t owner_pid = 0 ;
2310
2330
char flags_buf [32 ];
2311
2331
2312
2332
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 );
2314
2338
gh_owner = pid_task (gh -> gh_owner_pid , PIDTYPE_PID );
2339
+ if (gh_owner )
2340
+ comm = gh_owner -> comm ;
2341
+ }
2315
2342
gfs2_print_dbg (seq , "%s H: s:%s f:%s e:%d p:%ld [%s] %pS\n" ,
2316
2343
fs_id_buf , state2str (gh -> gh_state ),
2317
2344
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 );
2322
2346
rcu_read_unlock ();
2323
2347
}
2324
2348
@@ -2733,6 +2757,172 @@ static const struct file_operations gfs2_glstats_fops = {
2733
2757
.release = gfs2_glocks_release ,
2734
2758
};
2735
2759
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
+
2736
2926
DEFINE_SEQ_ATTRIBUTE (gfs2_sbstats );
2737
2927
2738
2928
void gfs2_create_debugfs_file (struct gfs2_sbd * sdp )
@@ -2742,6 +2932,9 @@ void gfs2_create_debugfs_file(struct gfs2_sbd *sdp)
2742
2932
debugfs_create_file ("glocks" , S_IFREG | S_IRUGO , sdp -> debugfs_dir , sdp ,
2743
2933
& gfs2_glocks_fops );
2744
2934
2935
+ debugfs_create_file ("glockfd" , S_IFREG | S_IRUGO , sdp -> debugfs_dir , sdp ,
2936
+ & gfs2_glockfd_fops );
2937
+
2745
2938
debugfs_create_file ("glstats" , S_IFREG | S_IRUGO , sdp -> debugfs_dir , sdp ,
2746
2939
& gfs2_glstats_fops );
2747
2940
0 commit comments