Skip to content

Commit bdff777

Browse files
author
Andreas Gruenbacher
committed
gfs2: Fix up gfs2_glock_async_wait
Since commit 1fc05c8 ("gfs2: cancel timed-out glock requests"), a pending locking request can be canceled by calling gfs2_glock_dq() on the pending holder. In gfs2_glock_async_wait(), when we time out, use that to cancel the remaining locking requests and dequeue the locking requests already granted. That's simpler as well as more efficient than waiting for all locking requests to eventually be granted and dequeuing them then. In addition, gfs2_glock_async_wait() promises that by the time the function completes, all glocks are either granted or dequeued, but the implementation doesn't keep that promise if individual locking requests fail. Fix that as well. Signed-off-by: Andreas Gruenbacher <[email protected]>
1 parent 03c765b commit bdff777

File tree

1 file changed

+15
-38
lines changed

1 file changed

+15
-38
lines changed

fs/gfs2/glock.c

Lines changed: 15 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,7 +1355,6 @@ int gfs2_glock_async_wait(unsigned int num_gh, struct gfs2_holder *ghs)
13551355
struct gfs2_sbd *sdp = ghs[0].gh_gl->gl_name.ln_sbd;
13561356
int i, ret = 0, timeout = 0;
13571357
unsigned long start_time = jiffies;
1358-
bool keep_waiting;
13591358

13601359
might_sleep();
13611360
/*
@@ -1365,53 +1364,31 @@ int gfs2_glock_async_wait(unsigned int num_gh, struct gfs2_holder *ghs)
13651364
for (i = 0; i < num_gh; i++)
13661365
timeout += ghs[i].gh_gl->gl_hold_time << 1;
13671366

1368-
wait_for_dlm:
13691367
if (!wait_event_timeout(sdp->sd_async_glock_wait,
1370-
!glocks_pending(num_gh, ghs), timeout))
1368+
!glocks_pending(num_gh, ghs), timeout)) {
13711369
ret = -ESTALE; /* request timed out. */
1370+
goto out;
1371+
}
13721372

1373-
/*
1374-
* If dlm granted all our requests, we need to adjust the glock
1375-
* minimum hold time values according to how long we waited.
1376-
*
1377-
* If our request timed out, we need to repeatedly release any held
1378-
* glocks we acquired thus far to allow dlm to acquire the remaining
1379-
* glocks without deadlocking. We cannot currently cancel outstanding
1380-
* glock acquisitions.
1381-
*
1382-
* The HIF_WAIT bit tells us which requests still need a response from
1383-
* dlm.
1384-
*
1385-
* If dlm sent us any errors, we return the first error we find.
1386-
*/
1387-
keep_waiting = false;
13881373
for (i = 0; i < num_gh; i++) {
1389-
/* Skip holders we have already dequeued below. */
1390-
if (!gfs2_holder_queued(&ghs[i]))
1391-
continue;
1392-
/* Skip holders with a pending DLM response. */
1393-
if (test_bit(HIF_WAIT, &ghs[i].gh_iflags)) {
1394-
keep_waiting = true;
1395-
continue;
1396-
}
1374+
struct gfs2_holder *gh = &ghs[i];
13971375

1398-
if (test_bit(HIF_HOLDER, &ghs[i].gh_iflags)) {
1399-
if (ret == -ESTALE)
1400-
gfs2_glock_dq(&ghs[i]);
1401-
else
1402-
gfs2_glock_update_hold_time(ghs[i].gh_gl,
1403-
start_time);
1376+
if (test_bit(HIF_HOLDER, &gh->gh_iflags)) {
1377+
gfs2_glock_update_hold_time(gh->gh_gl,
1378+
start_time);
14041379
}
14051380
if (!ret)
1406-
ret = ghs[i].gh_error;
1381+
ret = gh->gh_error;
14071382
}
14081383

1409-
if (keep_waiting)
1410-
goto wait_for_dlm;
1384+
out:
1385+
if (ret) {
1386+
for (i = 0; i < num_gh; i++) {
1387+
struct gfs2_holder *gh = &ghs[i];
14111388

1412-
/*
1413-
* At this point, we've either acquired all locks or released them all.
1414-
*/
1389+
gfs2_glock_dq(gh);
1390+
}
1391+
}
14151392
return ret;
14161393
}
14171394

0 commit comments

Comments
 (0)