Skip to content

Commit 4875d2f

Browse files
committed
Merge tag 'gfs2-v6.0-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2
Pull gfs2 updates from Andreas Gruenbacher: - Make sure to initialize the filesystem work queues before registering the filesystem; this prevents them from being used uninitialized. - On filesystem withdraw: prevent a a double iput() and immediately reject pending locking requests that can no longer succeed. - Use TRY lock in gfs2_inode_lookup() to prevent a rare glock hang during evict. - During filesystem mount, explicitly make sure that the sb_bsize and sb_bsize_shift super block fields are consistent with each other. This prevents messy error messages during fuzz testing. - Switch from strlcpy to strscpy. * tag 'gfs2-v6.0-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2: gfs2: Register fs after creating workqueues gfs2: Check sb_bsize_shift after reading superblock gfs2: Switch from strlcpy to strscpy gfs2: Clear flags when withdraw prevents xmote gfs2: Dequeue waiters when withdrawn gfs2: Prevent double iput for journal on error gfs2: Use TRY lock in gfs2_inode_lookup for UNLINKED inodes
2 parents ac1e8c6 + 74b1b10 commit 4875d2f

File tree

6 files changed

+77
-25
lines changed

6 files changed

+77
-25
lines changed

fs/gfs2/glock.c

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ typedef void (*glock_examiner) (struct gfs2_glock * gl);
5959

6060
static void do_xmote(struct gfs2_glock *gl, struct gfs2_holder *gh, unsigned int target);
6161
static void __gfs2_glock_dq(struct gfs2_holder *gh);
62+
static void handle_callback(struct gfs2_glock *gl, unsigned int state,
63+
unsigned long delay, bool remote);
6264

6365
static struct dentry *gfs2_root;
6466
static struct workqueue_struct *glock_workqueue;
@@ -730,7 +732,8 @@ static bool is_system_glock(struct gfs2_glock *gl)
730732
*
731733
*/
732734

733-
static void do_xmote(struct gfs2_glock *gl, struct gfs2_holder *gh, unsigned int target)
735+
static void do_xmote(struct gfs2_glock *gl, struct gfs2_holder *gh,
736+
unsigned int target)
734737
__releases(&gl->gl_lockref.lock)
735738
__acquires(&gl->gl_lockref.lock)
736739
{
@@ -741,7 +744,8 @@ __acquires(&gl->gl_lockref.lock)
741744

742745
if (target != LM_ST_UNLOCKED && glock_blocked_by_withdraw(gl) &&
743746
gh && !(gh->gh_flags & LM_FLAG_NOEXP))
744-
return;
747+
goto skip_inval;
748+
745749
lck_flags &= (LM_FLAG_TRY | LM_FLAG_TRY_1CB | LM_FLAG_NOEXP |
746750
LM_FLAG_PRIORITY);
747751
GLOCK_BUG_ON(gl, gl->gl_state == target);
@@ -826,6 +830,20 @@ __acquires(&gl->gl_lockref.lock)
826830
(target != LM_ST_UNLOCKED ||
827831
test_bit(SDF_WITHDRAW_RECOVERY, &sdp->sd_flags))) {
828832
if (!is_system_glock(gl)) {
833+
handle_callback(gl, LM_ST_UNLOCKED, 0, false); /* sets demote */
834+
/*
835+
* Ordinarily, we would call dlm and its callback would call
836+
* finish_xmote, which would call state_change() to the new state.
837+
* Since we withdrew, we won't call dlm, so call state_change
838+
* manually, but to the UNLOCKED state we desire.
839+
*/
840+
state_change(gl, LM_ST_UNLOCKED);
841+
/*
842+
* We skip telling dlm to do the locking, so we won't get a
843+
* reply that would otherwise clear GLF_LOCK. So we clear it here.
844+
*/
845+
clear_bit(GLF_LOCK, &gl->gl_flags);
846+
clear_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags);
829847
gfs2_glock_queue_work(gl, GL_GLOCK_DFT_HOLD);
830848
goto out;
831849
} else {
@@ -1018,16 +1036,18 @@ static void delete_work_func(struct work_struct *work)
10181036
if (gfs2_queue_delete_work(gl, 5 * HZ))
10191037
return;
10201038
}
1021-
goto out;
10221039
}
10231040

10241041
inode = gfs2_lookup_by_inum(sdp, no_addr, gl->gl_no_formal_ino,
10251042
GFS2_BLKST_UNLINKED);
1026-
if (!IS_ERR_OR_NULL(inode)) {
1043+
if (IS_ERR(inode)) {
1044+
if (PTR_ERR(inode) == -EAGAIN &&
1045+
(gfs2_queue_delete_work(gl, 5 * HZ)))
1046+
return;
1047+
} else {
10271048
d_prune_aliases(inode);
10281049
iput(inode);
10291050
}
1030-
out:
10311051
gfs2_glock_put(gl);
10321052
}
10331053

@@ -2194,6 +2214,20 @@ static void dump_glock_func(struct gfs2_glock *gl)
21942214
dump_glock(NULL, gl, true);
21952215
}
21962216

2217+
static void withdraw_dq(struct gfs2_glock *gl)
2218+
{
2219+
spin_lock(&gl->gl_lockref.lock);
2220+
if (!__lockref_is_dead(&gl->gl_lockref) &&
2221+
glock_blocked_by_withdraw(gl))
2222+
do_error(gl, LM_OUT_ERROR); /* remove pending waiters */
2223+
spin_unlock(&gl->gl_lockref.lock);
2224+
}
2225+
2226+
void gfs2_gl_dq_holders(struct gfs2_sbd *sdp)
2227+
{
2228+
glock_hash_walk(withdraw_dq, sdp);
2229+
}
2230+
21972231
/**
21982232
* gfs2_gl_hash_clear - Empty out the glock hash table
21992233
* @sdp: the filesystem

fs/gfs2/glock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ extern void gfs2_cancel_delete_work(struct gfs2_glock *gl);
274274
extern bool gfs2_delete_work_queued(const struct gfs2_glock *gl);
275275
extern void gfs2_flush_delete_work(struct gfs2_sbd *sdp);
276276
extern void gfs2_gl_hash_clear(struct gfs2_sbd *sdp);
277+
extern void gfs2_gl_dq_holders(struct gfs2_sbd *sdp);
277278
extern void gfs2_glock_thaw(struct gfs2_sbd *sdp);
278279
extern void gfs2_glock_add_to_lru(struct gfs2_glock *gl);
279280
extern void gfs2_glock_free(struct gfs2_glock *gl);

fs/gfs2/inode.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
130130
if (inode->i_state & I_NEW) {
131131
struct gfs2_sbd *sdp = GFS2_SB(inode);
132132
struct gfs2_glock *io_gl;
133+
int extra_flags = 0;
133134

134135
error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE,
135136
&ip->i_gl);
@@ -141,9 +142,12 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
141142
if (unlikely(error))
142143
goto fail;
143144

144-
if (blktype != GFS2_BLKST_UNLINKED)
145+
if (blktype == GFS2_BLKST_UNLINKED)
146+
extra_flags |= LM_FLAG_TRY;
147+
else
145148
gfs2_cancel_delete_work(io_gl);
146-
error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT,
149+
error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED,
150+
GL_EXACT | extra_flags,
147151
&ip->i_iopen_gh);
148152
gfs2_glock_put(io_gl);
149153
if (unlikely(error))
@@ -210,6 +214,8 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
210214
return inode;
211215

212216
fail:
217+
if (error == GLR_TRYFAILED)
218+
error = -EAGAIN;
213219
if (gfs2_holder_initialized(&ip->i_iopen_gh))
214220
gfs2_glock_dq_uninit(&ip->i_iopen_gh);
215221
if (gfs2_holder_initialized(&i_gh))

fs/gfs2/main.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -151,14 +151,6 @@ static int __init init_gfs2_fs(void)
151151
if (error)
152152
goto fail_shrinker;
153153

154-
error = register_filesystem(&gfs2_fs_type);
155-
if (error)
156-
goto fail_fs1;
157-
158-
error = register_filesystem(&gfs2meta_fs_type);
159-
if (error)
160-
goto fail_fs2;
161-
162154
error = -ENOMEM;
163155
gfs_recovery_wq = alloc_workqueue("gfs_recovery",
164156
WQ_MEM_RECLAIM | WQ_FREEZABLE, 0);
@@ -180,22 +172,30 @@ static int __init init_gfs2_fs(void)
180172
goto fail_mempool;
181173

182174
gfs2_register_debugfs();
175+
error = register_filesystem(&gfs2_fs_type);
176+
if (error)
177+
goto fail_fs1;
178+
179+
error = register_filesystem(&gfs2meta_fs_type);
180+
if (error)
181+
goto fail_fs2;
182+
183183

184184
pr_info("GFS2 installed\n");
185185

186186
return 0;
187187

188+
fail_fs2:
189+
unregister_filesystem(&gfs2_fs_type);
190+
fail_fs1:
191+
mempool_destroy(gfs2_page_pool);
188192
fail_mempool:
189193
destroy_workqueue(gfs2_freeze_wq);
190194
fail_wq3:
191195
destroy_workqueue(gfs2_control_wq);
192196
fail_wq2:
193197
destroy_workqueue(gfs_recovery_wq);
194198
fail_wq1:
195-
unregister_filesystem(&gfs2meta_fs_type);
196-
fail_fs2:
197-
unregister_filesystem(&gfs2_fs_type);
198-
fail_fs1:
199199
unregister_shrinker(&gfs2_qd_shrinker);
200200
fail_shrinker:
201201
kmem_cache_destroy(gfs2_trans_cachep);

fs/gfs2/ops_fstype.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,10 @@ static int gfs2_check_sb(struct gfs2_sbd *sdp, int silent)
178178
pr_warn("Invalid block size\n");
179179
return -EINVAL;
180180
}
181-
181+
if (sb->sb_bsize_shift != ffs(sb->sb_bsize) - 1) {
182+
pr_warn("Invalid block size shift\n");
183+
return -EINVAL;
184+
}
182185
return 0;
183186
}
184187

@@ -381,8 +384,10 @@ static int init_names(struct gfs2_sbd *sdp, int silent)
381384
if (!table[0])
382385
table = sdp->sd_vfs->s_id;
383386

384-
strlcpy(sdp->sd_proto_name, proto, GFS2_FSNAME_LEN);
385-
strlcpy(sdp->sd_table_name, table, GFS2_FSNAME_LEN);
387+
BUILD_BUG_ON(GFS2_LOCKNAME_LEN > GFS2_FSNAME_LEN);
388+
389+
strscpy(sdp->sd_proto_name, proto, GFS2_LOCKNAME_LEN);
390+
strscpy(sdp->sd_table_name, table, GFS2_LOCKNAME_LEN);
386391

387392
table = sdp->sd_table_name;
388393
while ((table = strchr(table, '/')))
@@ -1439,13 +1444,13 @@ static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
14391444

14401445
switch (o) {
14411446
case Opt_lockproto:
1442-
strlcpy(args->ar_lockproto, param->string, GFS2_LOCKNAME_LEN);
1447+
strscpy(args->ar_lockproto, param->string, GFS2_LOCKNAME_LEN);
14431448
break;
14441449
case Opt_locktable:
1445-
strlcpy(args->ar_locktable, param->string, GFS2_LOCKNAME_LEN);
1450+
strscpy(args->ar_locktable, param->string, GFS2_LOCKNAME_LEN);
14461451
break;
14471452
case Opt_hostdata:
1448-
strlcpy(args->ar_hostdata, param->string, GFS2_LOCKNAME_LEN);
1453+
strscpy(args->ar_hostdata, param->string, GFS2_LOCKNAME_LEN);
14491454
break;
14501455
case Opt_spectator:
14511456
args->ar_spectator = 1;

fs/gfs2/util.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,11 @@ static void signal_our_withdraw(struct gfs2_sbd *sdp)
164164
}
165165
if (!ret)
166166
gfs2_make_fs_ro(sdp);
167+
/*
168+
* Dequeue any pending non-system glock holders that can no
169+
* longer be granted because the file system is withdrawn.
170+
*/
171+
gfs2_gl_dq_holders(sdp);
167172
gfs2_freeze_unlock(&freeze_gh);
168173
}
169174

@@ -204,6 +209,7 @@ static void signal_our_withdraw(struct gfs2_sbd *sdp)
204209
* exception code in glock_dq.
205210
*/
206211
iput(inode);
212+
sdp->sd_jdesc->jd_inode = NULL;
207213
/*
208214
* Wait until the journal inode's glock is freed. This allows try locks
209215
* on other nodes to be successful, otherwise we remain the owner of

0 commit comments

Comments
 (0)