]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From: Jan Kara <jack@suse.cz> |
2 | References: fate#302681 | |
3 | Subject: ocfs2: Fix hang in quota recovery code | |
4 | Patch-mainline: 2.6.29? | |
5 | ||
6 | It could happen that some node started using a recovered slot before we got to | |
7 | quota recovery on it and it crashed. Recovery thread would then hang waiting | |
8 | for quota file lock which could never be obtained because it first has to be | |
9 | recovered by the recovery thread. We move ocfs2_begin_quota_recovery() | |
10 | under super block cluster lock so no node can start using recovered slot before | |
11 | we start quota recovery on it. | |
12 | ||
13 | Signed-off-by: Jan Kara <jack@suse.cz> | |
14 | ||
15 | --- | |
16 | fs/ocfs2/journal.c | 4 ++-- | |
17 | fs/ocfs2/quota_local.c | 11 ++--------- | |
18 | 2 files changed, 4 insertions(+), 11 deletions(-) | |
19 | ||
20 | --- a/fs/ocfs2/journal.c | |
21 | +++ b/fs/ocfs2/journal.c | |
22 | @@ -1127,8 +1127,6 @@ skip_recovery: | |
23 | if (status < 0) | |
24 | mlog_errno(status); | |
25 | ||
26 | - ocfs2_super_unlock(osb, 1); | |
27 | - | |
28 | /* Now it is right time to recover quotas... */ | |
29 | for (i = 0; i < rm_quota_used; i++) { | |
30 | qrec = ocfs2_begin_quota_recovery(osb, rm_quota[i]); | |
31 | @@ -1141,6 +1139,8 @@ skip_recovery: | |
32 | NULL, NULL, qrec); | |
33 | } | |
34 | ||
35 | + ocfs2_super_unlock(osb, 1); | |
36 | + | |
37 | /* We always run recovery on our own orphan dir - the dead | |
38 | * node(s) may have disallowd a previos inode delete. Re-processing | |
39 | * is therefore required. */ | |
40 | --- a/fs/ocfs2/quota_local.c | |
41 | +++ b/fs/ocfs2/quota_local.c | |
42 | @@ -383,15 +383,8 @@ struct ocfs2_quota_recovery *ocfs2_begin | |
43 | goto out; | |
44 | } | |
45 | status = ocfs2_inode_lock_full(lqinode, NULL, 1, | |
46 | - OCFS2_META_LOCK_NOQUEUE); | |
47 | - /* Someone else is holding the lock? Then he must be | |
48 | - * doing the recovery. Just skip the file... */ | |
49 | - if (status == -EAGAIN) { | |
50 | - mlog(ML_NOTICE, "skipping quota recovery for slot %d " | |
51 | - "because quota file is locked.\n", slot_num); | |
52 | - status = 0; | |
53 | - goto out_put; | |
54 | - } else if (status < 0) { | |
55 | + OCFS2_META_LOCK_RECOVERY); | |
56 | + if (status < 0) { | |
57 | mlog_errno(status); | |
58 | goto out_put; | |
59 | } |