Skip to content

Commit 77d0ab6

Browse files
committed
Merge tag 'gfs2-4.14.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2
Pull GFS2 updates from Bob Peterson: "We've got a whopping 29 GFS2 patches for this merge window, mainly because we held some back from the previous merge window until we could get them perfected and well tested. We have a couple patch sets, including my patch set for protecting glock gl_object and Andreas Gruenbacher's patch set to fix the long-standing shrink- slab hang, plus a bunch of assorted bugs and cleanups. Summary: - I fixed a bug whereby an IO error would lead to a double-brelse. - Andreas Gruenbacher made a minor cleanup to call his relatively new function, gfs2_holder_initialized, rather than doing it manually. This was just missed by a previous patch set. - Jan Kara fixed a bug whereby the SGID was being cleared when inheriting ACLs. - Andreas found a bug and fixed it in his previous patch, "Get rid of flush_delayed_work in gfs2_evict_inode". A call to flush_delayed_work was deleted from *gfs2_inode_lookup and added to gfs2_create_inode. - Wang Xibo found and fixed a list_add call in inode_go_lock that specified the parameters in the wrong order. - Coly Li submitted a patch to add the REQ_PRIO to some of GFS2's metadata reads that were accidentally missing them. - I submitted a 4-patch set to protect the glock gl_object field. GFS2 was setting and checking gl_object with no locking mechanism, so the value was occasionally stomped on, which caused file system corruption. - I submitted a small cleanup to function gfs2_clear_rgrpd. It was needlessly adding rgrp glocks to the lru list, then pulling them back off immediately. The rgrp glocks don't use the lru list anyway, so doing so was just a waste of time. - I submitted a patch that checks the GLOF_LRU flag on a glock before trying to remove it from the lru_list. This avoids a lot of unnecessary spin_lock contention. - I submitted a patch to delete GFS2's debugfs files only after we evict all the glocks. Before this patch, GFS2 would delete the debugfs files, and if unmount hung waiting for a glock, there was no way to debug the problem. Now, if a hang occurs during umount, we can examine the debugfs files to figure out why it's hung. - Andreas Gruenbacher submitted a patch to fix some trivial typos. - Andreas also submitted a five-part patch set to fix the longstanding hang involving the slab shrinker: dlm requires memory, calls the inode shrinker, which calls gfs2's evict, which calls back into DLM before it can evict an inode. - Abhi Das submitted a patch to forcibly flush the active items list to relieve memory pressure. This fixes a long-standing bug whereby GFS2 was getting hung permanently in balance_dirty_pages. - Thomas Tai submitted a patch to fix a slab corruption problem due to a residual pointer left in the lock_dlm lockstruct. - I submitted a patch to withdraw the file system if IO errors are encountered while writing to the journals or statfs system file which were previously not being sent back up. Before, some IO errors were sometimes not be detected for several hours, and at recovery time, the journal errors made journal replay impossible. - Andreas has a patch to fix an annoying format-truncation compiler warning so GFS2 compiles cleanly. - I have a patch that fixes a handful of sparse compiler warnings. - Andreas fixed up an useless gl_object warning caused by an earlier patch. - Arvind Yadav added a patch to properly constify our rhashtable params declare. - I added a patch to fix a regression caused by the non-recursive delete and truncate patch that caused file system blocks to not be properly freed. - Ernesto A. Fernández added a patch to fix a place where GFS2 would send back the wrong return code setting extended attributes. - Ernesto also added a patch to fix a case in which GFS2 was improperly setting an inode's i_mode, potentially granting access to the wrong users" * tag 'gfs2-4.14.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2: (29 commits) gfs2: preserve i_mode if __gfs2_set_acl() fails gfs2: don't return ENODATA in __gfs2_xattr_set unless replacing GFS2: Fix non-recursive truncate bug gfs2: constify rhashtable_params GFS2: Fix gl_object warnings GFS2: Fix up some sparse warnings gfs2: Silence gcc format-truncation warning GFS2: Withdraw for IO errors writing to the journal or statfs gfs2: fix slab corruption during mounting and umounting gfs file system gfs2: forcibly flush ail to relieve memory pressure gfs2: Clean up waiting on glocks gfs2: Defer deleting inodes under memory pressure gfs2: gfs2_evict_inode: Put glocks asynchronously gfs2: Get rid of gfs2_set_nlink gfs2: gfs2_glock_get: Wait on freeing glocks gfs2: Fix trivial typos GFS2: Delete debugfs files only after we evict the glocks GFS2: Don't waste time locking lru_lock for non-lru glocks GFS2: Don't bother trying to add rgrps to the lru list GFS2: Clear gl_object when deleting an inode in gfs2_delete_inode ...
2 parents e7d0c41 + 309e8cd commit 77d0ab6

File tree

20 files changed

+321
-110
lines changed

20 files changed

+321
-110
lines changed

fs/gfs2/acl.c

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,19 +86,6 @@ int __gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
8686
char *data;
8787
const char *name = gfs2_acl_name(type);
8888

89-
if (acl && acl->a_count > GFS2_ACL_MAX_ENTRIES(GFS2_SB(inode)))
90-
return -E2BIG;
91-
92-
if (type == ACL_TYPE_ACCESS) {
93-
umode_t mode = inode->i_mode;
94-
95-
error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
96-
if (error)
97-
return error;
98-
if (mode != inode->i_mode)
99-
mark_inode_dirty(inode);
100-
}
101-
10289
if (acl) {
10390
len = posix_acl_to_xattr(&init_user_ns, acl, NULL, 0);
10491
if (len == 0)
@@ -129,6 +116,10 @@ int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
129116
struct gfs2_holder gh;
130117
bool need_unlock = false;
131118
int ret;
119+
umode_t mode;
120+
121+
if (acl && acl->a_count > GFS2_ACL_MAX_ENTRIES(GFS2_SB(inode)))
122+
return -E2BIG;
132123

133124
ret = gfs2_rsqa_alloc(ip);
134125
if (ret)
@@ -140,7 +131,20 @@ int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
140131
return ret;
141132
need_unlock = true;
142133
}
134+
135+
mode = inode->i_mode;
136+
if (type == ACL_TYPE_ACCESS && acl) {
137+
ret = posix_acl_update_mode(inode, &mode, &acl);
138+
if (ret)
139+
goto unlock;
140+
}
141+
143142
ret = __gfs2_set_acl(inode, acl, type);
143+
if (!ret && mode != inode->i_mode) {
144+
inode->i_mode = mode;
145+
mark_inode_dirty(inode);
146+
}
147+
unlock:
144148
if (need_unlock)
145149
gfs2_glock_dq_uninit(&gh);
146150
return ret;

fs/gfs2/aops.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,19 @@ static int gfs2_jdata_writepage(struct page *page, struct writeback_control *wbc
234234
static int gfs2_writepages(struct address_space *mapping,
235235
struct writeback_control *wbc)
236236
{
237-
return mpage_writepages(mapping, wbc, gfs2_get_block_noalloc);
237+
struct gfs2_sbd *sdp = gfs2_mapping2sbd(mapping);
238+
int ret = mpage_writepages(mapping, wbc, gfs2_get_block_noalloc);
239+
240+
/*
241+
* Even if we didn't write any pages here, we might still be holding
242+
* dirty pages in the ail. We forcibly flush the ail because we don't
243+
* want balance_dirty_pages() to loop indefinitely trying to write out
244+
* pages held in the ail that it can't find.
245+
*/
246+
if (ret == 0)
247+
set_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags);
248+
249+
return ret;
238250
}
239251

240252
/**

fs/gfs2/bmap.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,9 @@ static void gfs2_metapath_ra(struct gfs2_glock *gl,
291291
if (trylock_buffer(rabh)) {
292292
if (!buffer_uptodate(rabh)) {
293293
rabh->b_end_io = end_buffer_read_sync;
294-
submit_bh(REQ_OP_READ, REQ_RAHEAD | REQ_META,
295-
rabh);
294+
submit_bh(REQ_OP_READ,
295+
REQ_RAHEAD | REQ_META | REQ_PRIO,
296+
rabh);
296297
continue;
297298
}
298299
unlock_buffer(rabh);
@@ -1103,8 +1104,15 @@ static bool find_nonnull_ptr(struct gfs2_sbd *sdp, struct metapath *mp,
11031104

11041105
while (true) {
11051106
ptr = metapointer(h, mp);
1106-
if (*ptr) /* if we have a non-null pointer */
1107+
if (*ptr) { /* if we have a non-null pointer */
1108+
/* Now zero the metapath after the current height. */
1109+
h++;
1110+
if (h < GFS2_MAX_META_HEIGHT)
1111+
memset(&mp->mp_list[h], 0,
1112+
(GFS2_MAX_META_HEIGHT - h) *
1113+
sizeof(mp->mp_list[0]));
11071114
return true;
1115+
}
11081116

11091117
if (mp->mp_list[h] < ptrs)
11101118
mp->mp_list[h]++;
@@ -1120,6 +1128,13 @@ enum dealloc_states {
11201128
DEALLOC_DONE = 3, /* process complete */
11211129
};
11221130

1131+
static bool mp_eq_to_hgt(struct metapath *mp, __u16 *nbof, unsigned int h)
1132+
{
1133+
if (memcmp(mp->mp_list, nbof, h * sizeof(mp->mp_list[0])))
1134+
return false;
1135+
return true;
1136+
}
1137+
11231138
/**
11241139
* trunc_dealloc - truncate a file down to a desired size
11251140
* @ip: inode to truncate
@@ -1197,8 +1212,7 @@ static int trunc_dealloc(struct gfs2_inode *ip, u64 newsize)
11971212
/* If we're truncating to a non-zero size and the mp is
11981213
at the beginning of file for the strip height, we
11991214
need to preserve the first metadata pointer. */
1200-
preserve1 = (newsize &&
1201-
(mp.mp_list[mp_h] == nbof[mp_h]));
1215+
preserve1 = (newsize && mp_eq_to_hgt(&mp, nbof, mp_h));
12021216
bh = mp.mp_bh[mp_h];
12031217
gfs2_assert_withdraw(sdp, bh);
12041218
if (gfs2_assert_withdraw(sdp,

fs/gfs2/dir.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1513,7 +1513,9 @@ static void gfs2_dir_readahead(struct inode *inode, unsigned hsize, u32 index,
15131513
continue;
15141514
}
15151515
bh->b_end_io = end_buffer_read_sync;
1516-
submit_bh(REQ_OP_READ, REQ_RAHEAD | REQ_META, bh);
1516+
submit_bh(REQ_OP_READ,
1517+
REQ_RAHEAD | REQ_META | REQ_PRIO,
1518+
bh);
15171519
continue;
15181520
}
15191521
brelse(bh);

fs/gfs2/file.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,8 +1030,7 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl)
10301030

10311031
mutex_lock(&fp->f_fl_mutex);
10321032

1033-
gl = fl_gh->gh_gl;
1034-
if (gl) {
1033+
if (gfs2_holder_initialized(fl_gh)) {
10351034
if (fl_gh->gh_state == state)
10361035
goto out;
10371036
locks_lock_file_wait(file,

0 commit comments

Comments
 (0)