aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/glock.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 1c4cddf42a66..3ad8cb3eeb88 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -46,10 +46,12 @@
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 */
54 char string[512]; /* scratch space */
53}; 55};
54 56
55typedef void (*glock_examiner) (struct gfs2_glock * gl); 57typedef void (*glock_examiner) (struct gfs2_glock * gl);
@@ -950,7 +952,7 @@ void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...)
950 if (seq) { 952 if (seq) {
951 struct gfs2_glock_iter *gi = seq->private; 953 struct gfs2_glock_iter *gi = seq->private;
952 vsprintf(gi->string, fmt, args); 954 vsprintf(gi->string, fmt, args);
953 seq_printf(seq, gi->string); 955 seq_puts(seq, gi->string);
954 } else { 956 } else {
955 vaf.fmt = fmt; 957 vaf.fmt = fmt;
956 vaf.va = &args; 958 vaf.va = &args;
@@ -1854,8 +1856,14 @@ static int gfs2_glock_iter_next(struct gfs2_glock_iter *gi)
1854 gl = gi->gl; 1856 gl = gi->gl;
1855 if (gl) { 1857 if (gl) {
1856 gi->gl = glock_hash_next(gl); 1858 gi->gl = glock_hash_next(gl);
1859 gi->nhash++;
1857 } else { 1860 } else {
1861 if (gi->hash >= GFS2_GL_HASH_SIZE) {
1862 rcu_read_unlock();
1863 return 1;
1864 }
1858 gi->gl = glock_hash_chain(gi->hash); 1865 gi->gl = glock_hash_chain(gi->hash);
1866 gi->nhash = 0;
1859 } 1867 }
1860 while (gi->gl == NULL) { 1868 while (gi->gl == NULL) {
1861 gi->hash++; 1869 gi->hash++;
@@ -1864,6 +1872,7 @@ static int gfs2_glock_iter_next(struct gfs2_glock_iter *gi)
1864 return 1; 1872 return 1;
1865 } 1873 }
1866 gi->gl = glock_hash_chain(gi->hash); 1874 gi->gl = glock_hash_chain(gi->hash);
1875 gi->nhash = 0;
1867 } 1876 }
1868 /* Skip entries for other sb and dead entries */ 1877 /* Skip entries for other sb and dead entries */
1869 } while (gi->sdp != gi->gl->gl_sbd || atomic_read(&gi->gl->gl_ref) == 0); 1878 } while (gi->sdp != gi->gl->gl_sbd || atomic_read(&gi->gl->gl_ref) == 0);
@@ -1876,7 +1885,12 @@ static void *gfs2_glock_seq_start(struct seq_file *seq, loff_t *pos)
1876 struct gfs2_glock_iter *gi = seq->private; 1885 struct gfs2_glock_iter *gi = seq->private;
1877 loff_t n = *pos; 1886 loff_t n = *pos;
1878 1887
1879 gi->hash = 0; 1888 if (gi->last_pos <= *pos)
1889 n = gi->nhash + (*pos - gi->last_pos);
1890 else
1891 gi->hash = 0;
1892
1893 gi->nhash = 0;
1880 rcu_read_lock(); 1894 rcu_read_lock();
1881 1895
1882 do { 1896 do {
@@ -1884,6 +1898,7 @@ static void *gfs2_glock_seq_start(struct seq_file *seq, loff_t *pos)
1884 return NULL; 1898 return NULL;
1885 } while (n--); 1899 } while (n--);
1886 1900
1901 gi->last_pos = *pos;
1887 return gi->gl; 1902 return gi->gl;
1888} 1903}
1889 1904
@@ -1893,7 +1908,7 @@ static void *gfs2_glock_seq_next(struct seq_file *seq, void *iter_ptr,
1893 struct gfs2_glock_iter *gi = seq->private; 1908 struct gfs2_glock_iter *gi = seq->private;
1894 1909
1895 (*pos)++; 1910 (*pos)++;
1896 1911 gi->last_pos = *pos;
1897 if (gfs2_glock_iter_next(gi)) 1912 if (gfs2_glock_iter_next(gi))
1898 return NULL; 1913 return NULL;
1899 1914