aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-02-03 16:14:41 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2018-02-03 16:14:41 -0500
commit6ec4de89b478043aa1c33f89f68f62ebf61b3e43 (patch)
treeb12bd5cc52adb750af7330f9de80ec74640d087d
parentabbbd0211ddfc6e525b00b3c8c84032f705e4a5d (diff)
parent7ac07fdaf840f9b141c6d5c286805107227c0e68 (diff)
Merge tag 'gfs2-4.16.fixes2' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2
Pull GFS2 fixes from Bob Peterson: "Andreas Gruenbacher wrote two additional patches that we would like merged in this time. Both are regressions: - fix another kernel build dependency problem - fix a performance regression in glock dumps" * tag 'gfs2-4.16.fixes2' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2: gfs2: Glock dump performance regression fix gfs2: Fix the crc32c dependency
-rw-r--r--fs/gfs2/Kconfig3
-rw-r--r--fs/gfs2/glock.c65
2 files changed, 44 insertions, 24 deletions
diff --git a/fs/gfs2/Kconfig b/fs/gfs2/Kconfig
index c0225d4b5435..3ed2b088dcfd 100644
--- a/fs/gfs2/Kconfig
+++ b/fs/gfs2/Kconfig
@@ -3,8 +3,7 @@ config GFS2_FS
3 depends on (64BIT || LBDAF) 3 depends on (64BIT || LBDAF)
4 select FS_POSIX_ACL 4 select FS_POSIX_ACL
5 select CRC32 5 select CRC32
6 select CRYPTO 6 select LIBCRC32C
7 select CRYPTO_CRC32C
8 select QUOTACTL 7 select QUOTACTL
9 select FS_IOMAP 8 select FS_IOMAP
10 help 9 help
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 90af87ff29ba..82fb5583445c 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -1921,19 +1921,29 @@ void gfs2_glock_exit(void)
1921 destroy_workqueue(gfs2_delete_workqueue); 1921 destroy_workqueue(gfs2_delete_workqueue);
1922} 1922}
1923 1923
1924static void gfs2_glock_iter_next(struct gfs2_glock_iter *gi) 1924static void gfs2_glock_iter_next(struct gfs2_glock_iter *gi, loff_t n)
1925{ 1925{
1926 while ((gi->gl = rhashtable_walk_next(&gi->hti))) { 1926 if (n == 0)
1927 if (IS_ERR(gi->gl)) { 1927 gi->gl = rhashtable_walk_peek(&gi->hti);
1928 if (PTR_ERR(gi->gl) == -EAGAIN) 1928 else {
1929 continue; 1929 gi->gl = rhashtable_walk_next(&gi->hti);
1930 gi->gl = NULL; 1930 n--;
1931 return; 1931 }
1932 for (;;) {
1933 if (IS_ERR_OR_NULL(gi->gl)) {
1934 if (!gi->gl)
1935 return;
1936 if (PTR_ERR(gi->gl) != -EAGAIN) {
1937 gi->gl = NULL;
1938 return;
1939 }
1940 n = 0;
1941 } else if (gi->sdp == gi->gl->gl_name.ln_sbd &&
1942 !__lockref_is_dead(&gi->gl->gl_lockref)) {
1943 if (!n--)
1944 break;
1932 } 1945 }
1933 /* Skip entries for other sb and dead entries */ 1946 gi->gl = rhashtable_walk_next(&gi->hti);
1934 if (gi->sdp == gi->gl->gl_name.ln_sbd &&
1935 !__lockref_is_dead(&gi->gl->gl_lockref))
1936 return;
1937 } 1947 }
1938} 1948}
1939 1949
@@ -1941,18 +1951,24 @@ static void *gfs2_glock_seq_start(struct seq_file *seq, loff_t *pos)
1941 __acquires(RCU) 1951 __acquires(RCU)
1942{ 1952{
1943 struct gfs2_glock_iter *gi = seq->private; 1953 struct gfs2_glock_iter *gi = seq->private;
1944 loff_t n = *pos; 1954 loff_t n;
1945 1955
1946 rhashtable_walk_enter(&gl_hash_table, &gi->hti); 1956 /*
1947 if (rhashtable_walk_start_check(&gi->hti) != 0) 1957 * We can either stay where we are, skip to the next hash table
1948 return NULL; 1958 * entry, or start from the beginning.
1959 */
1960 if (*pos < gi->last_pos) {
1961 rhashtable_walk_exit(&gi->hti);
1962 rhashtable_walk_enter(&gl_hash_table, &gi->hti);
1963 n = *pos + 1;
1964 } else {
1965 n = *pos - gi->last_pos;
1966 }
1949 1967
1950 do { 1968 rhashtable_walk_start(&gi->hti);
1951 gfs2_glock_iter_next(gi);
1952 } while (gi->gl && n--);
1953 1969
1970 gfs2_glock_iter_next(gi, n);
1954 gi->last_pos = *pos; 1971 gi->last_pos = *pos;
1955
1956 return gi->gl; 1972 return gi->gl;
1957} 1973}
1958 1974
@@ -1963,8 +1979,7 @@ static void *gfs2_glock_seq_next(struct seq_file *seq, void *iter_ptr,
1963 1979
1964 (*pos)++; 1980 (*pos)++;
1965 gi->last_pos = *pos; 1981 gi->last_pos = *pos;
1966 gfs2_glock_iter_next(gi); 1982 gfs2_glock_iter_next(gi, 1);
1967
1968 return gi->gl; 1983 return gi->gl;
1969} 1984}
1970 1985
@@ -1975,7 +1990,6 @@ static void gfs2_glock_seq_stop(struct seq_file *seq, void *iter_ptr)
1975 1990
1976 gi->gl = NULL; 1991 gi->gl = NULL;
1977 rhashtable_walk_stop(&gi->hti); 1992 rhashtable_walk_stop(&gi->hti);
1978 rhashtable_walk_exit(&gi->hti);
1979} 1993}
1980 1994
1981static int gfs2_glock_seq_show(struct seq_file *seq, void *iter_ptr) 1995static int gfs2_glock_seq_show(struct seq_file *seq, void *iter_ptr)
@@ -2041,7 +2055,13 @@ static int __gfs2_glocks_open(struct inode *inode, struct file *file,
2041 seq->buf = kmalloc(GFS2_SEQ_GOODSIZE, GFP_KERNEL | __GFP_NOWARN); 2055 seq->buf = kmalloc(GFS2_SEQ_GOODSIZE, GFP_KERNEL | __GFP_NOWARN);
2042 if (seq->buf) 2056 if (seq->buf)
2043 seq->size = GFS2_SEQ_GOODSIZE; 2057 seq->size = GFS2_SEQ_GOODSIZE;
2058 /*
2059 * Initially, we are "before" the first hash table entry; the
2060 * first call to rhashtable_walk_next gets us the first entry.
2061 */
2062 gi->last_pos = -1;
2044 gi->gl = NULL; 2063 gi->gl = NULL;
2064 rhashtable_walk_enter(&gl_hash_table, &gi->hti);
2045 } 2065 }
2046 return ret; 2066 return ret;
2047} 2067}
@@ -2057,6 +2077,7 @@ static int gfs2_glocks_release(struct inode *inode, struct file *file)
2057 struct gfs2_glock_iter *gi = seq->private; 2077 struct gfs2_glock_iter *gi = seq->private;
2058 2078
2059 gi->gl = NULL; 2079 gi->gl = NULL;
2080 rhashtable_walk_exit(&gi->hti);
2060 return seq_release_private(inode, file); 2081 return seq_release_private(inode, file);
2061} 2082}
2062 2083