aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/glock.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r--fs/gfs2/glock.c39
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
48struct gfs2_glock_iter { 48struct 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
55typedef void (*glock_examiner) (struct gfs2_glock * gl); 56typedef 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
1967static int gfs2_glocks_open(struct inode *inode, struct file *file) 1982static 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}