diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-03 16:14:41 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-03 16:14:41 -0500 |
commit | 6ec4de89b478043aa1c33f89f68f62ebf61b3e43 (patch) | |
tree | b12bd5cc52adb750af7330f9de80ec74640d087d | |
parent | abbbd0211ddfc6e525b00b3c8c84032f705e4a5d (diff) | |
parent | 7ac07fdaf840f9b141c6d5c286805107227c0e68 (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/Kconfig | 3 | ||||
-rw-r--r-- | fs/gfs2/glock.c | 65 |
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 | ||
1924 | static void gfs2_glock_iter_next(struct gfs2_glock_iter *gi) | 1924 | static 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 | ||
1981 | static int gfs2_glock_seq_show(struct seq_file *seq, void *iter_ptr) | 1995 | static 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 | ||