Skip to content

Commit 53d6913

Browse files
author
Andreas Gruenbacher
committed
gfs2: Instantiate glocks ouside of glock state engine
Instantiate glocks outside of the glock state engine: there is no real reason for instantiating them inside the glock state engine; it only complicates the code. Instead, instantiate them in gfs2_glock_wait() and gfs2_glock_async_wait() using the new gfs2_glock_holder_ready() helper. On top of that, the only other place that acquires a glock without using gfs2_glock_wait() or gfs2_glock_async_wait() is gfs2_upgrade_iopen_glock(), so call gfs2_glock_holder_ready() there as well. If a dinode has a pending truncate, the glock-specific instantiate function for inodes wakes up the truncate function in the quota daemon. Waiting for the completion of the truncate was previously done by the glock state engine, but we now need to wait in inode_go_instantiate(). This also means that gfs2_instantiate() will now no longer return any "special" error codes. Signed-off-by: Andreas Gruenbacher <[email protected]>
1 parent bdff777 commit 53d6913

File tree

4 files changed

+37
-35
lines changed

4 files changed

+37
-35
lines changed

fs/gfs2/glock.c

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -478,8 +478,7 @@ find_first_strong_holder(struct gfs2_glock *gl)
478478
* gfs2_instantiate - Call the glops instantiate function
479479
* @gh: The glock holder
480480
*
481-
* Returns: 0 if instantiate was successful, 2 if type specific operation is
482-
* underway, or error.
481+
* Returns: 0 if instantiate was successful, or error.
483482
*/
484483
int gfs2_instantiate(struct gfs2_holder *gh)
485484
{
@@ -524,18 +523,12 @@ int gfs2_instantiate(struct gfs2_holder *gh)
524523
*/
525524

526525
static int do_promote(struct gfs2_glock *gl)
527-
__releases(&gl->gl_lockref.lock)
528-
__acquires(&gl->gl_lockref.lock)
529526
{
530527
struct gfs2_holder *gh, *tmp, *first_gh;
531528
bool incompat_holders_demoted = false;
532-
bool lock_released;
533-
int ret;
534529

535-
restart:
536530
first_gh = find_first_strong_holder(gl);
537531
list_for_each_entry_safe(gh, tmp, &gl->gl_holders, gh_list) {
538-
lock_released = false;
539532
if (test_bit(HIF_HOLDER, &gh->gh_iflags))
540533
continue;
541534
if (!may_grant(gl, first_gh, gh)) {
@@ -554,32 +547,9 @@ __acquires(&gl->gl_lockref.lock)
554547
incompat_holders_demoted = true;
555548
first_gh = gh;
556549
}
557-
if (test_bit(GLF_INSTANTIATE_NEEDED, &gl->gl_flags) &&
558-
!(gh->gh_flags & GL_SKIP) && gl->gl_ops->go_instantiate) {
559-
lock_released = true;
560-
spin_unlock(&gl->gl_lockref.lock);
561-
ret = gfs2_instantiate(gh);
562-
spin_lock(&gl->gl_lockref.lock);
563-
if (ret) {
564-
if (ret == 1)
565-
return 2;
566-
gh->gh_error = ret;
567-
list_del_init(&gh->gh_list);
568-
trace_gfs2_glock_queue(gh, 0);
569-
gfs2_holder_wake(gh);
570-
goto restart;
571-
}
572-
}
573550
set_bit(HIF_HOLDER, &gh->gh_iflags);
574551
trace_gfs2_promote(gh);
575552
gfs2_holder_wake(gh);
576-
/*
577-
* If we released the gl_lockref.lock the holders list may have
578-
* changed. For that reason, we start again at the start of
579-
* the holders queue.
580-
*/
581-
if (lock_released)
582-
goto restart;
583553
}
584554
return 0;
585555
}
@@ -1313,6 +1283,25 @@ static void gfs2_glock_update_hold_time(struct gfs2_glock *gl,
13131283
}
13141284
}
13151285

1286+
/**
1287+
* gfs2_glock_holder_ready - holder is ready and its error code can be collected
1288+
* @gh: the glock holder
1289+
*
1290+
* Called when a glock holder no longer needs to be waited for because it is
1291+
* now either held (HIF_HOLDER set; gh_error == 0), or acquiring the lock has
1292+
* failed (gh_error != 0).
1293+
*/
1294+
1295+
int gfs2_glock_holder_ready(struct gfs2_holder *gh)
1296+
{
1297+
if (gh->gh_error || (gh->gh_flags & GL_SKIP))
1298+
return gh->gh_error;
1299+
gh->gh_error = gfs2_instantiate(gh);
1300+
if (gh->gh_error)
1301+
gfs2_glock_dq(gh);
1302+
return gh->gh_error;
1303+
}
1304+
13161305
/**
13171306
* gfs2_glock_wait - wait on a glock acquisition
13181307
* @gh: the glock holder
@@ -1327,7 +1316,7 @@ int gfs2_glock_wait(struct gfs2_holder *gh)
13271316
might_sleep();
13281317
wait_on_bit(&gh->gh_iflags, HIF_WAIT, TASK_UNINTERRUPTIBLE);
13291318
gfs2_glock_update_hold_time(gh->gh_gl, start_time);
1330-
return gh->gh_error;
1319+
return gfs2_glock_holder_ready(gh);
13311320
}
13321321

13331322
static int glocks_pending(unsigned int num_gh, struct gfs2_holder *ghs)
@@ -1372,13 +1361,15 @@ int gfs2_glock_async_wait(unsigned int num_gh, struct gfs2_holder *ghs)
13721361

13731362
for (i = 0; i < num_gh; i++) {
13741363
struct gfs2_holder *gh = &ghs[i];
1364+
int ret2;
13751365

13761366
if (test_bit(HIF_HOLDER, &gh->gh_iflags)) {
13771367
gfs2_glock_update_hold_time(gh->gh_gl,
13781368
start_time);
13791369
}
1370+
ret2 = gfs2_glock_holder_ready(gh);
13801371
if (!ret)
1381-
ret = gh->gh_error;
1372+
ret = ret2;
13821373
}
13831374

13841375
out:
@@ -2233,9 +2224,18 @@ void gfs2_glock_finish_truncate(struct gfs2_inode *ip)
22332224
spin_lock(&gl->gl_lockref.lock);
22342225
clear_bit(GLF_LOCK, &gl->gl_flags);
22352226
run_queue(gl, 1);
2227+
wake_up_glock(gl);
22362228
spin_unlock(&gl->gl_lockref.lock);
22372229
}
22382230

2231+
void gfs2_wait_truncate(struct gfs2_inode *ip)
2232+
{
2233+
struct gfs2_glock *gl = ip->i_gl;
2234+
wait_queue_head_t *wq = glock_waitqueue(&gl->gl_name);
2235+
2236+
wait_event(*wq, !(ip->i_diskflags & GFS2_DIF_TRUNC_IN_PROG));
2237+
}
2238+
22392239
static const char *state2str(unsigned state)
22402240
{
22412241
switch(state) {

fs/gfs2/glock.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ extern void gfs2_holder_uninit(struct gfs2_holder *gh);
213213
extern int gfs2_glock_nq(struct gfs2_holder *gh);
214214
extern int gfs2_glock_poll(struct gfs2_holder *gh);
215215
extern int gfs2_instantiate(struct gfs2_holder *gh);
216+
extern int gfs2_glock_holder_ready(struct gfs2_holder *gh);
216217
extern int gfs2_glock_wait(struct gfs2_holder *gh);
217218
extern int gfs2_glock_async_wait(unsigned int num_gh, struct gfs2_holder *ghs);
218219
extern void gfs2_glock_dq(struct gfs2_holder *gh);
@@ -274,6 +275,7 @@ extern bool gfs2_delete_work_queued(const struct gfs2_glock *gl);
274275
extern void gfs2_flush_delete_work(struct gfs2_sbd *sdp);
275276
extern void gfs2_gl_hash_clear(struct gfs2_sbd *sdp);
276277
extern void gfs2_glock_finish_truncate(struct gfs2_inode *ip);
278+
extern void gfs2_wait_truncate(struct gfs2_inode *ip);
277279
extern void gfs2_glock_thaw(struct gfs2_sbd *sdp);
278280
extern void gfs2_glock_add_to_lru(struct gfs2_glock *gl);
279281
extern void gfs2_glock_free(struct gfs2_glock *gl);

fs/gfs2/glops.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ static int inode_go_instantiate(struct gfs2_holder *gh)
510510
list_add(&ip->i_trunc_list, &sdp->sd_trunc_list);
511511
spin_unlock(&sdp->sd_trunc_lock);
512512
wake_up(&sdp->sd_quota_wait);
513-
error = 1;
513+
gfs2_wait_truncate(ip);
514514
}
515515

516516
out:

fs/gfs2/super.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1196,7 +1196,7 @@ static bool gfs2_upgrade_iopen_glock(struct inode *inode)
11961196
gfs2_glock_dq(gh);
11971197
return false;
11981198
}
1199-
return true;
1199+
return gfs2_glock_holder_ready(gh) == 0;
12001200
}
12011201

12021202
/**

0 commit comments

Comments
 (0)