Skip to content

Commit ed460cf

Browse files
josephhztorvalds
authored andcommitted
ocfs2: add orphan recovery types in ocfs2_recover_orphans
Define two orphan recovery types, which indicates if need truncate file or not. Signed-off-by: Joseph Qi <joseph.qi@huawei.com> Cc: Weiwei Wang <wangww631@huawei.com> Cc: Junxiao Bi <junxiao.bi@oracle.com> Cc: Joel Becker <jlbec@evilplan.org> Cc: Mark Fasheh <mfasheh@suse.com> Cc: Xuejiufei <xuejiufei@huawei.com> Cc: alex chen <alex.chen@huawei.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 06ee5c7 commit ed460cf

File tree

2 files changed

+93
-20
lines changed

2 files changed

+93
-20
lines changed

fs/ocfs2/journal.c

Lines changed: 88 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
#include "sysfile.h"
5151
#include "uptodate.h"
5252
#include "quota.h"
53+
#include "file.h"
54+
#include "namei.h"
5355

5456
#include "buffer_head_io.h"
5557
#include "ocfs2_trace.h"
@@ -69,13 +71,15 @@ static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb,
6971
static int ocfs2_trylock_journal(struct ocfs2_super *osb,
7072
int slot_num);
7173
static int ocfs2_recover_orphans(struct ocfs2_super *osb,
72-
int slot);
74+
int slot,
75+
enum ocfs2_orphan_reco_type orphan_reco_type);
7376
static int ocfs2_commit_thread(void *arg);
7477
static void ocfs2_queue_recovery_completion(struct ocfs2_journal *journal,
7578
int slot_num,
7679
struct ocfs2_dinode *la_dinode,
7780
struct ocfs2_dinode *tl_dinode,
78-
struct ocfs2_quota_recovery *qrec);
81+
struct ocfs2_quota_recovery *qrec,
82+
enum ocfs2_orphan_reco_type orphan_reco_type);
7983

8084
static inline int ocfs2_wait_on_mount(struct ocfs2_super *osb)
8185
{
@@ -149,7 +153,8 @@ int ocfs2_compute_replay_slots(struct ocfs2_super *osb)
149153
return 0;
150154
}
151155

152-
void ocfs2_queue_replay_slots(struct ocfs2_super *osb)
156+
void ocfs2_queue_replay_slots(struct ocfs2_super *osb,
157+
enum ocfs2_orphan_reco_type orphan_reco_type)
153158
{
154159
struct ocfs2_replay_map *replay_map = osb->replay_map;
155160
int i;
@@ -163,7 +168,8 @@ void ocfs2_queue_replay_slots(struct ocfs2_super *osb)
163168
for (i = 0; i < replay_map->rm_slots; i++)
164169
if (replay_map->rm_replay_slots[i])
165170
ocfs2_queue_recovery_completion(osb->journal, i, NULL,
166-
NULL, NULL);
171+
NULL, NULL,
172+
orphan_reco_type);
167173
replay_map->rm_state = REPLAY_DONE;
168174
}
169175

@@ -1174,6 +1180,7 @@ struct ocfs2_la_recovery_item {
11741180
struct ocfs2_dinode *lri_la_dinode;
11751181
struct ocfs2_dinode *lri_tl_dinode;
11761182
struct ocfs2_quota_recovery *lri_qrec;
1183+
enum ocfs2_orphan_reco_type lri_orphan_reco_type;
11771184
};
11781185

11791186
/* Does the second half of the recovery process. By this point, the
@@ -1195,6 +1202,7 @@ void ocfs2_complete_recovery(struct work_struct *work)
11951202
struct ocfs2_dinode *la_dinode, *tl_dinode;
11961203
struct ocfs2_la_recovery_item *item, *n;
11971204
struct ocfs2_quota_recovery *qrec;
1205+
enum ocfs2_orphan_reco_type orphan_reco_type;
11981206
LIST_HEAD(tmp_la_list);
11991207

12001208
trace_ocfs2_complete_recovery(
@@ -1212,6 +1220,7 @@ void ocfs2_complete_recovery(struct work_struct *work)
12121220
la_dinode = item->lri_la_dinode;
12131221
tl_dinode = item->lri_tl_dinode;
12141222
qrec = item->lri_qrec;
1223+
orphan_reco_type = item->lri_orphan_reco_type;
12151224

12161225
trace_ocfs2_complete_recovery_slot(item->lri_slot,
12171226
la_dinode ? le64_to_cpu(la_dinode->i_blkno) : 0,
@@ -1236,7 +1245,8 @@ void ocfs2_complete_recovery(struct work_struct *work)
12361245
kfree(tl_dinode);
12371246
}
12381247

1239-
ret = ocfs2_recover_orphans(osb, item->lri_slot);
1248+
ret = ocfs2_recover_orphans(osb, item->lri_slot,
1249+
orphan_reco_type);
12401250
if (ret < 0)
12411251
mlog_errno(ret);
12421252

@@ -1261,7 +1271,8 @@ static void ocfs2_queue_recovery_completion(struct ocfs2_journal *journal,
12611271
int slot_num,
12621272
struct ocfs2_dinode *la_dinode,
12631273
struct ocfs2_dinode *tl_dinode,
1264-
struct ocfs2_quota_recovery *qrec)
1274+
struct ocfs2_quota_recovery *qrec,
1275+
enum ocfs2_orphan_reco_type orphan_reco_type)
12651276
{
12661277
struct ocfs2_la_recovery_item *item;
12671278

@@ -1285,6 +1296,7 @@ static void ocfs2_queue_recovery_completion(struct ocfs2_journal *journal,
12851296
item->lri_slot = slot_num;
12861297
item->lri_tl_dinode = tl_dinode;
12871298
item->lri_qrec = qrec;
1299+
item->lri_orphan_reco_type = orphan_reco_type;
12881300

12891301
spin_lock(&journal->j_lock);
12901302
list_add_tail(&item->lri_list, &journal->j_la_cleanups);
@@ -1304,15 +1316,16 @@ void ocfs2_complete_mount_recovery(struct ocfs2_super *osb)
13041316
/* No need to queue up our truncate_log as regular cleanup will catch
13051317
* that */
13061318
ocfs2_queue_recovery_completion(journal, osb->slot_num,
1307-
osb->local_alloc_copy, NULL, NULL);
1319+
osb->local_alloc_copy, NULL, NULL,
1320+
ORPHAN_NEED_TRUNCATE);
13081321
ocfs2_schedule_truncate_log_flush(osb, 0);
13091322

13101323
osb->local_alloc_copy = NULL;
13111324
osb->dirty = 0;
13121325

13131326
/* queue to recover orphan slots for all offline slots */
13141327
ocfs2_replay_map_set_state(osb, REPLAY_NEEDED);
1315-
ocfs2_queue_replay_slots(osb);
1328+
ocfs2_queue_replay_slots(osb, ORPHAN_NEED_TRUNCATE);
13161329
ocfs2_free_replay_slots(osb);
13171330
}
13181331

@@ -1323,7 +1336,8 @@ void ocfs2_complete_quota_recovery(struct ocfs2_super *osb)
13231336
osb->slot_num,
13241337
NULL,
13251338
NULL,
1326-
osb->quota_rec);
1339+
osb->quota_rec,
1340+
ORPHAN_NEED_TRUNCATE);
13271341
osb->quota_rec = NULL;
13281342
}
13291343
}
@@ -1360,7 +1374,7 @@ static int __ocfs2_recovery_thread(void *arg)
13601374

13611375
/* queue recovery for our own slot */
13621376
ocfs2_queue_recovery_completion(osb->journal, osb->slot_num, NULL,
1363-
NULL, NULL);
1377+
NULL, NULL, ORPHAN_NO_NEED_TRUNCATE);
13641378

13651379
spin_lock(&osb->osb_lock);
13661380
while (rm->rm_used) {
@@ -1419,13 +1433,14 @@ static int __ocfs2_recovery_thread(void *arg)
14191433
continue;
14201434
}
14211435
ocfs2_queue_recovery_completion(osb->journal, rm_quota[i],
1422-
NULL, NULL, qrec);
1436+
NULL, NULL, qrec,
1437+
ORPHAN_NEED_TRUNCATE);
14231438
}
14241439

14251440
ocfs2_super_unlock(osb, 1);
14261441

14271442
/* queue recovery for offline slots */
1428-
ocfs2_queue_replay_slots(osb);
1443+
ocfs2_queue_replay_slots(osb, ORPHAN_NEED_TRUNCATE);
14291444

14301445
bail:
14311446
mutex_lock(&osb->recovery_lock);
@@ -1711,7 +1726,7 @@ static int ocfs2_recover_node(struct ocfs2_super *osb,
17111726

17121727
/* This will kfree the memory pointed to by la_copy and tl_copy */
17131728
ocfs2_queue_recovery_completion(osb->journal, slot_num, la_copy,
1714-
tl_copy, NULL);
1729+
tl_copy, NULL, ORPHAN_NEED_TRUNCATE);
17151730

17161731
status = 0;
17171732
done:
@@ -1901,7 +1916,7 @@ void ocfs2_queue_orphan_scan(struct ocfs2_super *osb)
19011916

19021917
for (i = 0; i < osb->max_slots; i++)
19031918
ocfs2_queue_recovery_completion(osb->journal, i, NULL, NULL,
1904-
NULL);
1919+
NULL, ORPHAN_NO_NEED_TRUNCATE);
19051920
/*
19061921
* We queued a recovery on orphan slots, increment the sequence
19071922
* number and update LVB so other node will skip the scan for a while
@@ -2000,6 +2015,13 @@ static int ocfs2_orphan_filldir(struct dir_context *ctx, const char *name,
20002015
if (IS_ERR(iter))
20012016
return 0;
20022017

2018+
/* Skip inodes which are already added to recover list, since dio may
2019+
* happen concurrently with unlink/rename */
2020+
if (OCFS2_I(iter)->ip_next_orphan) {
2021+
iput(iter);
2022+
return 0;
2023+
}
2024+
20032025
trace_ocfs2_orphan_filldir((unsigned long long)OCFS2_I(iter)->ip_blkno);
20042026
/* No locking is required for the next_orphan queue as there
20052027
* is only ever a single process doing orphan recovery. */
@@ -2108,7 +2130,8 @@ static void ocfs2_clear_recovering_orphan_dir(struct ocfs2_super *osb,
21082130
* advertising our state to ocfs2_delete_inode().
21092131
*/
21102132
static int ocfs2_recover_orphans(struct ocfs2_super *osb,
2111-
int slot)
2133+
int slot,
2134+
enum ocfs2_orphan_reco_type orphan_reco_type)
21122135
{
21132136
int ret = 0;
21142137
struct inode *inode = NULL;
@@ -2132,13 +2155,58 @@ static int ocfs2_recover_orphans(struct ocfs2_super *osb,
21322155
(unsigned long long)oi->ip_blkno);
21332156

21342157
iter = oi->ip_next_orphan;
2158+
oi->ip_next_orphan = NULL;
2159+
2160+
/*
2161+
* We need to take and drop the inode lock to
2162+
* force read inode from disk.
2163+
*/
2164+
ret = ocfs2_inode_lock(inode, NULL, 0);
2165+
if (ret) {
2166+
mlog_errno(ret);
2167+
goto next;
2168+
}
2169+
ocfs2_inode_unlock(inode, 0);
2170+
2171+
if (inode->i_nlink == 0) {
2172+
spin_lock(&oi->ip_lock);
2173+
/* Set the proper information to get us going into
2174+
* ocfs2_delete_inode. */
2175+
oi->ip_flags |= OCFS2_INODE_MAYBE_ORPHANED;
2176+
spin_unlock(&oi->ip_lock);
2177+
} else if (orphan_reco_type == ORPHAN_NEED_TRUNCATE) {
2178+
struct buffer_head *di_bh = NULL;
2179+
2180+
ret = ocfs2_rw_lock(inode, 1);
2181+
if (ret) {
2182+
mlog_errno(ret);
2183+
goto next;
2184+
}
21352185

2136-
spin_lock(&oi->ip_lock);
2137-
/* Set the proper information to get us going into
2138-
* ocfs2_delete_inode. */
2139-
oi->ip_flags |= OCFS2_INODE_MAYBE_ORPHANED;
2140-
spin_unlock(&oi->ip_lock);
2186+
ret = ocfs2_inode_lock(inode, &di_bh, 1);
2187+
if (ret < 0) {
2188+
ocfs2_rw_unlock(inode, 1);
2189+
mlog_errno(ret);
2190+
goto next;
2191+
}
2192+
2193+
ret = ocfs2_truncate_file(inode, di_bh,
2194+
i_size_read(inode));
2195+
ocfs2_inode_unlock(inode, 1);
2196+
ocfs2_rw_unlock(inode, 1);
2197+
brelse(di_bh);
2198+
if (ret < 0) {
2199+
if (ret != -ENOSPC)
2200+
mlog_errno(ret);
2201+
goto next;
2202+
}
2203+
2204+
ret = ocfs2_del_inode_from_orphan(osb, inode, 0, 0);
2205+
if (ret)
2206+
mlog_errno(ret);
2207+
} /* else if ORPHAN_NO_NEED_TRUNCATE, do nothing */
21412208

2209+
next:
21422210
iput(inode);
21432211

21442212
inode = iter;

fs/ocfs2/ocfs2.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,11 @@ struct ocfs2_lock_res {
209209
#endif
210210
};
211211

212+
enum ocfs2_orphan_reco_type {
213+
ORPHAN_NO_NEED_TRUNCATE = 0,
214+
ORPHAN_NEED_TRUNCATE,
215+
};
216+
212217
enum ocfs2_orphan_scan_state {
213218
ORPHAN_SCAN_ACTIVE,
214219
ORPHAN_SCAN_INACTIVE

0 commit comments

Comments
 (0)