diff options
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r-- | fs/gfs2/glock.c | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index dab2526071cc..1ed81f40da0d 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -46,10 +46,11 @@ | |||
46 | #include "trace_gfs2.h" | 46 | #include "trace_gfs2.h" |
47 | 47 | ||
48 | struct gfs2_glock_iter { | 48 | struct gfs2_glock_iter { |
49 | int hash; /* hash bucket index */ | 49 | int hash; /* hash bucket index */ |
50 | struct gfs2_sbd *sdp; /* incore superblock */ | 50 | unsigned nhash; /* Index within current bucket */ |
51 | struct gfs2_glock *gl; /* current glock struct */ | 51 | struct gfs2_sbd *sdp; /* incore superblock */ |
52 | char string[512]; /* scratch space */ | 52 | struct gfs2_glock *gl; /* current glock struct */ |
53 | loff_t last_pos; /* last position */ | ||
53 | }; | 54 | }; |
54 | 55 | ||
55 | typedef void (*glock_examiner) (struct gfs2_glock * gl); | 56 | typedef void (*glock_examiner) (struct gfs2_glock * gl); |
@@ -767,6 +768,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, | |||
767 | gl->gl_stats.stats[GFS2_LKS_DCOUNT] = 0; | 768 | gl->gl_stats.stats[GFS2_LKS_DCOUNT] = 0; |
768 | gl->gl_stats.stats[GFS2_LKS_QCOUNT] = 0; | 769 | gl->gl_stats.stats[GFS2_LKS_QCOUNT] = 0; |
769 | memset(&gl->gl_lksb, 0, sizeof(struct dlm_lksb)); | 770 | memset(&gl->gl_lksb, 0, sizeof(struct dlm_lksb)); |
771 | memset(gl->gl_lvb, 0, 32 * sizeof(char)); | ||
770 | gl->gl_lksb.sb_lvbptr = gl->gl_lvb; | 772 | gl->gl_lksb.sb_lvbptr = gl->gl_lvb; |
771 | gl->gl_tchange = jiffies; | 773 | gl->gl_tchange = jiffies; |
772 | gl->gl_object = NULL; | 774 | gl->gl_object = NULL; |
@@ -948,9 +950,7 @@ void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...) | |||
948 | va_start(args, fmt); | 950 | va_start(args, fmt); |
949 | 951 | ||
950 | if (seq) { | 952 | if (seq) { |
951 | struct gfs2_glock_iter *gi = seq->private; | 953 | seq_vprintf(seq, fmt, args); |
952 | vsprintf(gi->string, fmt, args); | ||
953 | seq_printf(seq, gi->string); | ||
954 | } else { | 954 | } else { |
955 | vaf.fmt = fmt; | 955 | vaf.fmt = fmt; |
956 | vaf.va = &args; | 956 | vaf.va = &args; |
@@ -1854,8 +1854,14 @@ static int gfs2_glock_iter_next(struct gfs2_glock_iter *gi) | |||
1854 | gl = gi->gl; | 1854 | gl = gi->gl; |
1855 | if (gl) { | 1855 | if (gl) { |
1856 | gi->gl = glock_hash_next(gl); | 1856 | gi->gl = glock_hash_next(gl); |
1857 | gi->nhash++; | ||
1857 | } else { | 1858 | } else { |
1859 | if (gi->hash >= GFS2_GL_HASH_SIZE) { | ||
1860 | rcu_read_unlock(); | ||
1861 | return 1; | ||
1862 | } | ||
1858 | gi->gl = glock_hash_chain(gi->hash); | 1863 | gi->gl = glock_hash_chain(gi->hash); |
1864 | gi->nhash = 0; | ||
1859 | } | 1865 | } |
1860 | while (gi->gl == NULL) { | 1866 | while (gi->gl == NULL) { |
1861 | gi->hash++; | 1867 | gi->hash++; |
@@ -1864,6 +1870,7 @@ static int gfs2_glock_iter_next(struct gfs2_glock_iter *gi) | |||
1864 | return 1; | 1870 | return 1; |
1865 | } | 1871 | } |
1866 | gi->gl = glock_hash_chain(gi->hash); | 1872 | gi->gl = glock_hash_chain(gi->hash); |
1873 | gi->nhash = 0; | ||
1867 | } | 1874 | } |
1868 | /* Skip entries for other sb and dead entries */ | 1875 | /* Skip entries for other sb and dead entries */ |
1869 | } while (gi->sdp != gi->gl->gl_sbd || atomic_read(&gi->gl->gl_ref) == 0); | 1876 | } while (gi->sdp != gi->gl->gl_sbd || atomic_read(&gi->gl->gl_ref) == 0); |
@@ -1876,7 +1883,12 @@ static void *gfs2_glock_seq_start(struct seq_file *seq, loff_t *pos) | |||
1876 | struct gfs2_glock_iter *gi = seq->private; | 1883 | struct gfs2_glock_iter *gi = seq->private; |
1877 | loff_t n = *pos; | 1884 | loff_t n = *pos; |
1878 | 1885 | ||
1879 | gi->hash = 0; | 1886 | if (gi->last_pos <= *pos) |
1887 | n = gi->nhash + (*pos - gi->last_pos); | ||
1888 | else | ||
1889 | gi->hash = 0; | ||
1890 | |||
1891 | gi->nhash = 0; | ||
1880 | rcu_read_lock(); | 1892 | rcu_read_lock(); |
1881 | 1893 | ||
1882 | do { | 1894 | do { |
@@ -1884,6 +1896,7 @@ static void *gfs2_glock_seq_start(struct seq_file *seq, loff_t *pos) | |||
1884 | return NULL; | 1896 | return NULL; |
1885 | } while (n--); | 1897 | } while (n--); |
1886 | 1898 | ||
1899 | gi->last_pos = *pos; | ||
1887 | return gi->gl; | 1900 | return gi->gl; |
1888 | } | 1901 | } |
1889 | 1902 | ||
@@ -1893,7 +1906,7 @@ static void *gfs2_glock_seq_next(struct seq_file *seq, void *iter_ptr, | |||
1893 | struct gfs2_glock_iter *gi = seq->private; | 1906 | struct gfs2_glock_iter *gi = seq->private; |
1894 | 1907 | ||
1895 | (*pos)++; | 1908 | (*pos)++; |
1896 | 1909 | gi->last_pos = *pos; | |
1897 | if (gfs2_glock_iter_next(gi)) | 1910 | if (gfs2_glock_iter_next(gi)) |
1898 | return NULL; | 1911 | return NULL; |
1899 | 1912 | ||
@@ -1964,6 +1977,8 @@ static const struct seq_operations gfs2_sbstats_seq_ops = { | |||
1964 | .show = gfs2_sbstats_seq_show, | 1977 | .show = gfs2_sbstats_seq_show, |
1965 | }; | 1978 | }; |
1966 | 1979 | ||
1980 | #define GFS2_SEQ_GOODSIZE min(PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER, 65536UL) | ||
1981 | |||
1967 | static int gfs2_glocks_open(struct inode *inode, struct file *file) | 1982 | static int gfs2_glocks_open(struct inode *inode, struct file *file) |
1968 | { | 1983 | { |
1969 | int ret = seq_open_private(file, &gfs2_glock_seq_ops, | 1984 | int ret = seq_open_private(file, &gfs2_glock_seq_ops, |
@@ -1972,6 +1987,9 @@ static int gfs2_glocks_open(struct inode *inode, struct file *file) | |||
1972 | struct seq_file *seq = file->private_data; | 1987 | struct seq_file *seq = file->private_data; |
1973 | struct gfs2_glock_iter *gi = seq->private; | 1988 | struct gfs2_glock_iter *gi = seq->private; |
1974 | gi->sdp = inode->i_private; | 1989 | gi->sdp = inode->i_private; |
1990 | seq->buf = kmalloc(GFS2_SEQ_GOODSIZE, GFP_KERNEL | __GFP_NOWARN); | ||
1991 | if (seq->buf) | ||
1992 | seq->size = GFS2_SEQ_GOODSIZE; | ||
1975 | } | 1993 | } |
1976 | return ret; | 1994 | return ret; |
1977 | } | 1995 | } |
@@ -1984,6 +2002,9 @@ static int gfs2_glstats_open(struct inode *inode, struct file *file) | |||
1984 | struct seq_file *seq = file->private_data; | 2002 | struct seq_file *seq = file->private_data; |
1985 | struct gfs2_glock_iter *gi = seq->private; | 2003 | struct gfs2_glock_iter *gi = seq->private; |
1986 | gi->sdp = inode->i_private; | 2004 | gi->sdp = inode->i_private; |
2005 | seq->buf = kmalloc(GFS2_SEQ_GOODSIZE, GFP_KERNEL | __GFP_NOWARN); | ||
2006 | if (seq->buf) | ||
2007 | seq->size = GFS2_SEQ_GOODSIZE; | ||
1987 | } | 2008 | } |
1988 | return ret; | 2009 | return ret; |
1989 | } | 2010 | } |