Blame view

fs/ocfs2/journal.c 61.6 KB
328970de0   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2
3
4
5
6
7
8
9
  /* -*- mode: c; c-basic-offset: 8; -*-
   * vim: noexpandtab sw=8 ts=8 sts=0:
   *
   * journal.c
   *
   * Defines functions of journalling api
   *
   * Copyright (C) 2003, 2004 Oracle.  All rights reserved.
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
10
11
12
13
14
15
16
   */
  
  #include <linux/fs.h>
  #include <linux/types.h>
  #include <linux/slab.h>
  #include <linux/highmem.h>
  #include <linux/kthread.h>
83273932f   Srinivas Eeda   ocfs2: timer to q...
17
18
  #include <linux/time.h>
  #include <linux/random.h>
55b465b66   Joseph Qi   ocfs2: limit prin...
19
  #include <linux/delay.h>
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
20

ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
21
22
23
24
25
  #include <cluster/masklog.h>
  
  #include "ocfs2.h"
  
  #include "alloc.h"
50655ae9e   Joel Becker   ocfs2: Add journa...
26
  #include "blockcheck.h"
316f4b9f9   Mark Fasheh   ocfs2: Move direc...
27
  #include "dir.h"
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
28
29
30
31
32
33
  #include "dlmglue.h"
  #include "extent_map.h"
  #include "heartbeat.h"
  #include "inode.h"
  #include "journal.h"
  #include "localalloc.h"
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
34
35
  #include "slot_map.h"
  #include "super.h"
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
36
  #include "sysfile.h"
0cf2f7632   Joel Becker   ocfs2: Pass struc...
37
  #include "uptodate.h"
2205363dc   Jan Kara   ocfs2: Implement ...
38
  #include "quota.h"
ed460cffc   Joseph Qi   ocfs2: add orphan...
39
40
  #include "file.h"
  #include "namei.h"
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
41
42
  
  #include "buffer_head_io.h"
b41079504   Tao Ma   ocfs2: Remove mas...
43
  #include "ocfs2_trace.h"
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
44

34af946a2   Ingo Molnar   [PATCH] spin/rwlo...
45
  DEFINE_SPINLOCK(trans_inc_lock);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
46

83273932f   Srinivas Eeda   ocfs2: timer to q...
47
  #define ORPHAN_SCAN_SCHEDULE_TIMEOUT 300000
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
48
49
  static int ocfs2_force_read_journal(struct inode *inode);
  static int ocfs2_recover_node(struct ocfs2_super *osb,
2205363dc   Jan Kara   ocfs2: Implement ...
50
  			      int node_num, int slot_num);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
51
52
  static int __ocfs2_recovery_thread(void *arg);
  static int ocfs2_commit_cache(struct ocfs2_super *osb);
19ece546a   Jan Kara   ocfs2: Enable quo...
53
  static int __ocfs2_wait_on_mount(struct ocfs2_super *osb, int quota);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
54
  static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb,
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
55
  				      int dirty, int replayed);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
56
57
58
  static int ocfs2_trylock_journal(struct ocfs2_super *osb,
  				 int slot_num);
  static int ocfs2_recover_orphans(struct ocfs2_super *osb,
ed460cffc   Joseph Qi   ocfs2: add orphan...
59
60
  				 int slot,
  				 enum ocfs2_orphan_reco_type orphan_reco_type);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
61
  static int ocfs2_commit_thread(void *arg);
9140db04e   Srinivas Eeda   ocfs2: recover or...
62
63
64
65
  static void ocfs2_queue_recovery_completion(struct ocfs2_journal *journal,
  					    int slot_num,
  					    struct ocfs2_dinode *la_dinode,
  					    struct ocfs2_dinode *tl_dinode,
ed460cffc   Joseph Qi   ocfs2: add orphan...
66
67
  					    struct ocfs2_quota_recovery *qrec,
  					    enum ocfs2_orphan_reco_type orphan_reco_type);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
68

19ece546a   Jan Kara   ocfs2: Enable quo...
69
70
71
72
73
74
75
76
77
  static inline int ocfs2_wait_on_mount(struct ocfs2_super *osb)
  {
  	return __ocfs2_wait_on_mount(osb, 0);
  }
  
  static inline int ocfs2_wait_on_quotas(struct ocfs2_super *osb)
  {
  	return __ocfs2_wait_on_mount(osb, 1);
  }
9140db04e   Srinivas Eeda   ocfs2: recover or...
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
  /*
   * This replay_map is to track online/offline slots, so we could recover
   * offline slots during recovery and mount
   */
  
  enum ocfs2_replay_state {
  	REPLAY_UNNEEDED = 0,	/* Replay is not needed, so ignore this map */
  	REPLAY_NEEDED, 		/* Replay slots marked in rm_replay_slots */
  	REPLAY_DONE 		/* Replay was already queued */
  };
  
  struct ocfs2_replay_map {
  	unsigned int rm_slots;
  	enum ocfs2_replay_state rm_state;
  	unsigned char rm_replay_slots[0];
  };
b519ea6d9   Joseph Qi   ocfs2: mark local...
94
  static void ocfs2_replay_map_set_state(struct ocfs2_super *osb, int state)
9140db04e   Srinivas Eeda   ocfs2: recover or...
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
  {
  	if (!osb->replay_map)
  		return;
  
  	/* If we've already queued the replay, we don't have any more to do */
  	if (osb->replay_map->rm_state == REPLAY_DONE)
  		return;
  
  	osb->replay_map->rm_state = state;
  }
  
  int ocfs2_compute_replay_slots(struct ocfs2_super *osb)
  {
  	struct ocfs2_replay_map *replay_map;
  	int i, node_num;
  
  	/* If replay map is already set, we don't do it again */
  	if (osb->replay_map)
  		return 0;
  
  	replay_map = kzalloc(sizeof(struct ocfs2_replay_map) +
  			     (osb->max_slots * sizeof(char)), GFP_KERNEL);
  
  	if (!replay_map) {
  		mlog_errno(-ENOMEM);
  		return -ENOMEM;
  	}
  
  	spin_lock(&osb->osb_lock);
  
  	replay_map->rm_slots = osb->max_slots;
  	replay_map->rm_state = REPLAY_UNNEEDED;
  
  	/* set rm_replay_slots for offline slot(s) */
  	for (i = 0; i < replay_map->rm_slots; i++) {
  		if (ocfs2_slot_to_node_num_locked(osb, i, &node_num) == -ENOENT)
  			replay_map->rm_replay_slots[i] = 1;
  	}
  
  	osb->replay_map = replay_map;
  	spin_unlock(&osb->osb_lock);
  	return 0;
  }
b519ea6d9   Joseph Qi   ocfs2: mark local...
138
  static void ocfs2_queue_replay_slots(struct ocfs2_super *osb,
ed460cffc   Joseph Qi   ocfs2: add orphan...
139
  		enum ocfs2_orphan_reco_type orphan_reco_type)
9140db04e   Srinivas Eeda   ocfs2: recover or...
140
141
142
143
144
145
146
147
148
149
150
151
152
  {
  	struct ocfs2_replay_map *replay_map = osb->replay_map;
  	int i;
  
  	if (!replay_map)
  		return;
  
  	if (replay_map->rm_state != REPLAY_NEEDED)
  		return;
  
  	for (i = 0; i < replay_map->rm_slots; i++)
  		if (replay_map->rm_replay_slots[i])
  			ocfs2_queue_recovery_completion(osb->journal, i, NULL,
ed460cffc   Joseph Qi   ocfs2: add orphan...
153
154
  							NULL, NULL,
  							orphan_reco_type);
9140db04e   Srinivas Eeda   ocfs2: recover or...
155
156
  	replay_map->rm_state = REPLAY_DONE;
  }
b519ea6d9   Joseph Qi   ocfs2: mark local...
157
  static void ocfs2_free_replay_slots(struct ocfs2_super *osb)
9140db04e   Srinivas Eeda   ocfs2: recover or...
158
159
160
161
162
163
164
165
166
  {
  	struct ocfs2_replay_map *replay_map = osb->replay_map;
  
  	if (!osb->replay_map)
  		return;
  
  	kfree(replay_map);
  	osb->replay_map = NULL;
  }
553abd046   Joel Becker   ocfs2: Change the...
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
  int ocfs2_recovery_init(struct ocfs2_super *osb)
  {
  	struct ocfs2_recovery_map *rm;
  
  	mutex_init(&osb->recovery_lock);
  	osb->disable_recovery = 0;
  	osb->recovery_thread_task = NULL;
  	init_waitqueue_head(&osb->recovery_event);
  
  	rm = kzalloc(sizeof(struct ocfs2_recovery_map) +
  		     osb->max_slots * sizeof(unsigned int),
  		     GFP_KERNEL);
  	if (!rm) {
  		mlog_errno(-ENOMEM);
  		return -ENOMEM;
  	}
  
  	rm->rm_entries = (unsigned int *)((char *)rm +
  					  sizeof(struct ocfs2_recovery_map));
  	osb->recovery_map = rm;
  
  	return 0;
  }
  
  /* we can't grab the goofy sem lock from inside wait_event, so we use
   * memory barriers to make sure that we'll see the null task before
   * being woken up */
  static int ocfs2_recovery_thread_running(struct ocfs2_super *osb)
  {
  	mb();
  	return osb->recovery_thread_task != NULL;
  }
  
  void ocfs2_recovery_exit(struct ocfs2_super *osb)
  {
  	struct ocfs2_recovery_map *rm;
  
  	/* disable any new recovery threads and wait for any currently
  	 * running ones to exit. Do this before setting the vol_state. */
  	mutex_lock(&osb->recovery_lock);
  	osb->disable_recovery = 1;
  	mutex_unlock(&osb->recovery_lock);
  	wait_event(osb->recovery_event, !ocfs2_recovery_thread_running(osb));
  
  	/* At this point, we know that no more recovery threads can be
  	 * launched, so wait for any recovery completion work to
  	 * complete. */
b918c4302   Yi Li   ocfs2: fix panic ...
214
215
  	if (osb->ocfs2_wq)
  		flush_workqueue(osb->ocfs2_wq);
553abd046   Joel Becker   ocfs2: Change the...
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
  
  	/*
  	 * Now that recovery is shut down, and the osb is about to be
  	 * freed,  the osb_lock is not taken here.
  	 */
  	rm = osb->recovery_map;
  	/* XXX: Should we bug if there are dirty entries? */
  
  	kfree(rm);
  }
  
  static int __ocfs2_recovery_map_test(struct ocfs2_super *osb,
  				     unsigned int node_num)
  {
  	int i;
  	struct ocfs2_recovery_map *rm = osb->recovery_map;
  
  	assert_spin_locked(&osb->osb_lock);
  
  	for (i = 0; i < rm->rm_used; i++) {
  		if (rm->rm_entries[i] == node_num)
  			return 1;
  	}
  
  	return 0;
  }
  
  /* Behaves like test-and-set.  Returns the previous value */
  static int ocfs2_recovery_map_set(struct ocfs2_super *osb,
  				  unsigned int node_num)
  {
  	struct ocfs2_recovery_map *rm = osb->recovery_map;
  
  	spin_lock(&osb->osb_lock);
  	if (__ocfs2_recovery_map_test(osb, node_num)) {
  		spin_unlock(&osb->osb_lock);
  		return 1;
  	}
  
  	/* XXX: Can this be exploited? Not from o2dlm... */
  	BUG_ON(rm->rm_used >= osb->max_slots);
  
  	rm->rm_entries[rm->rm_used] = node_num;
  	rm->rm_used++;
  	spin_unlock(&osb->osb_lock);
  
  	return 0;
  }
  
  static void ocfs2_recovery_map_clear(struct ocfs2_super *osb,
  				     unsigned int node_num)
  {
  	int i;
  	struct ocfs2_recovery_map *rm = osb->recovery_map;
  
  	spin_lock(&osb->osb_lock);
  
  	for (i = 0; i < rm->rm_used; i++) {
  		if (rm->rm_entries[i] == node_num)
  			break;
  	}
  
  	if (i < rm->rm_used) {
  		/* XXX: be careful with the pointer math */
  		memmove(&(rm->rm_entries[i]), &(rm->rm_entries[i + 1]),
  			(rm->rm_used - i - 1) * sizeof(unsigned int));
  		rm->rm_used--;
  	}
  
  	spin_unlock(&osb->osb_lock);
  }
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
287
288
289
290
  static int ocfs2_commit_cache(struct ocfs2_super *osb)
  {
  	int status = 0;
  	unsigned int flushed;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
291
  	struct ocfs2_journal *journal = NULL;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
292
293
294
295
  	journal = osb->journal;
  
  	/* Flush all pending commits and checkpoint the journal. */
  	down_write(&journal->j_trans_barrier);
b41079504   Tao Ma   ocfs2: Remove mas...
296
297
298
  	flushed = atomic_read(&journal->j_num_trans);
  	trace_ocfs2_commit_cache_begin(flushed);
  	if (flushed == 0) {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
299
  		up_write(&journal->j_trans_barrier);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
300
301
  		goto finally;
  	}
2b4e30fbd   Joel Becker   ocfs2: Switch ove...
302
303
304
  	jbd2_journal_lock_updates(journal->j_journal);
  	status = jbd2_journal_flush(journal->j_journal);
  	jbd2_journal_unlock_updates(journal->j_journal);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
305
306
307
308
309
  	if (status < 0) {
  		up_write(&journal->j_trans_barrier);
  		mlog_errno(status);
  		goto finally;
  	}
f9c57ada3   Tao Ma   ocfs2: Remove unu...
310
  	ocfs2_inc_trans_id(journal);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
311
312
313
314
  
  	flushed = atomic_read(&journal->j_num_trans);
  	atomic_set(&journal->j_num_trans, 0);
  	up_write(&journal->j_trans_barrier);
b41079504   Tao Ma   ocfs2: Remove mas...
315
  	trace_ocfs2_commit_cache_end(journal->j_trans_id, flushed);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
316

34d024f84   Mark Fasheh   ocfs2: Remove mou...
317
  	ocfs2_wake_downconvert_thread(osb);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
318
319
  	wake_up(&journal->j_checkpointed);
  finally:
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
320
321
  	return status;
  }
1fabe1481   Mark Fasheh   ocfs2: Remove str...
322
  handle_t *ocfs2_start_trans(struct ocfs2_super *osb, int max_buffs)
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
323
  {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
324
  	journal_t *journal = osb->journal->j_journal;
1fabe1481   Mark Fasheh   ocfs2: Remove str...
325
  	handle_t *handle;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
326

ebdec83ba   Eric Sesterhenn / snakebyte   [PATCH] BUG_ON() ...
327
  	BUG_ON(!osb || !osb->journal->j_journal);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
328

65eff9ccf   Mark Fasheh   ocfs2: remove han...
329
330
  	if (ocfs2_is_hard_readonly(osb))
  		return ERR_PTR(-EROFS);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
331
332
333
  
  	BUG_ON(osb->journal->j_state == OCFS2_JOURNAL_FREE);
  	BUG_ON(max_buffs <= 0);
90e86a63e   Jan Kara   ocfs2: Support ne...
334
335
336
  	/* Nested transaction? Just return the handle... */
  	if (journal_current_handle())
  		return jbd2_journal_start(journal, max_buffs);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
337

fef6925cd   Jan Kara   ocfs2: Convert to...
338
  	sb_start_intwrite(osb->sb);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
339
  	down_read(&osb->journal->j_trans_barrier);
2b4e30fbd   Joel Becker   ocfs2: Switch ove...
340
  	handle = jbd2_journal_start(journal, max_buffs);
1fabe1481   Mark Fasheh   ocfs2: Remove str...
341
  	if (IS_ERR(handle)) {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
342
  		up_read(&osb->journal->j_trans_barrier);
fef6925cd   Jan Kara   ocfs2: Convert to...
343
  		sb_end_intwrite(osb->sb);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
344

1fabe1481   Mark Fasheh   ocfs2: Remove str...
345
  		mlog_errno(PTR_ERR(handle));
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
346
347
  
  		if (is_journal_aborted(journal)) {
7ecef14ab   Joe Perches   ocfs2: neaten do_...
348
349
  			ocfs2_abort(osb->sb, "Detected aborted journal
  ");
1fabe1481   Mark Fasheh   ocfs2: Remove str...
350
  			handle = ERR_PTR(-EROFS);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
351
  		}
c271c5c22   Sunil Mushran   ocfs2: local mounts
352
353
354
355
  	} else {
  		if (!ocfs2_mount_local(osb))
  			atomic_inc(&(osb->journal->j_num_trans));
  	}
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
356

ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
357
  	return handle;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
358
  }
1fabe1481   Mark Fasheh   ocfs2: Remove str...
359
360
  int ocfs2_commit_trans(struct ocfs2_super *osb,
  		       handle_t *handle)
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
361
  {
90e86a63e   Jan Kara   ocfs2: Support ne...
362
  	int ret, nested;
02dc1af44   Mark Fasheh   ocfs2: pass ocfs2...
363
  	struct ocfs2_journal *journal = osb->journal;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
364
365
  
  	BUG_ON(!handle);
90e86a63e   Jan Kara   ocfs2: Support ne...
366
  	nested = handle->h_ref > 1;
2b4e30fbd   Joel Becker   ocfs2: Switch ove...
367
  	ret = jbd2_journal_stop(handle);
1fabe1481   Mark Fasheh   ocfs2: Remove str...
368
369
  	if (ret < 0)
  		mlog_errno(ret);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
370

fef6925cd   Jan Kara   ocfs2: Convert to...
371
  	if (!nested) {
90e86a63e   Jan Kara   ocfs2: Support ne...
372
  		up_read(&journal->j_trans_barrier);
fef6925cd   Jan Kara   ocfs2: Convert to...
373
374
  		sb_end_intwrite(osb->sb);
  	}
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
375

1fabe1481   Mark Fasheh   ocfs2: Remove str...
376
  	return ret;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
377
378
379
  }
  
  /*
c901fb007   Tao Ma   ocfs2: Make ocfs2...
380
   * 'nblocks' is what you want to add to the current transaction.
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
381
   *
2b4e30fbd   Joel Becker   ocfs2: Switch ove...
382
   * This might call jbd2_journal_restart() which will commit dirty buffers
e8aed3450   Mark Fasheh   ocfs2: Re-journal...
383
384
385
386
387
   * and then restart the transaction. Before calling
   * ocfs2_extend_trans(), any changed blocks should have been
   * dirtied. After calling it, all blocks which need to be changed must
   * go through another set of journal_access/journal_dirty calls.
   *
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
388
389
390
391
392
393
394
395
   * WARNING: This will not release any semaphores or disk locks taken
   * during the transaction, so make sure they were taken *before*
   * start_trans or we'll have ordering deadlocks.
   *
   * WARNING2: Note that we do *not* drop j_trans_barrier here. This is
   * good because transaction ids haven't yet been recorded on the
   * cluster locks associated with this handle.
   */
1fc581467   Mark Fasheh   ocfs2: have ocfs2...
396
  int ocfs2_extend_trans(handle_t *handle, int nblocks)
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
397
  {
c901fb007   Tao Ma   ocfs2: Make ocfs2...
398
  	int status, old_nblocks;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
399
400
  
  	BUG_ON(!handle);
c901fb007   Tao Ma   ocfs2: Make ocfs2...
401
  	BUG_ON(nblocks < 0);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
402

c901fb007   Tao Ma   ocfs2: Make ocfs2...
403
404
405
406
  	if (!nblocks)
  		return 0;
  
  	old_nblocks = handle->h_buffer_credits;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
407

b41079504   Tao Ma   ocfs2: Remove mas...
408
  	trace_ocfs2_extend_trans(old_nblocks, nblocks);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
409

e407e3978   Joel Becker   ocfs2: Fix CONFIG...
410
  #ifdef CONFIG_OCFS2_DEBUG_FS
0879c584f   Mark Fasheh   ocfs2: Allow for ...
411
412
  	status = 1;
  #else
2b4e30fbd   Joel Becker   ocfs2: Switch ove...
413
  	status = jbd2_journal_extend(handle, nblocks);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
414
415
416
417
  	if (status < 0) {
  		mlog_errno(status);
  		goto bail;
  	}
0879c584f   Mark Fasheh   ocfs2: Allow for ...
418
  #endif
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
419
420
  
  	if (status > 0) {
b41079504   Tao Ma   ocfs2: Remove mas...
421
  		trace_ocfs2_extend_trans_restart(old_nblocks + nblocks);
c901fb007   Tao Ma   ocfs2: Make ocfs2...
422
423
  		status = jbd2_journal_restart(handle,
  					      old_nblocks + nblocks);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
424
  		if (status < 0) {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
425
426
427
  			mlog_errno(status);
  			goto bail;
  		}
01ddf1e18   Mark Fasheh   ocfs2: remove unu...
428
  	}
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
429
430
431
  
  	status = 0;
  bail:
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
432
433
  	return status;
  }
2b1e55c38   Younger Liu   ocfs2: lighten up...
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
  /*
   * If we have fewer than thresh credits, extend by OCFS2_MAX_TRANS_DATA.
   * If that fails, restart the transaction & regain write access for the
   * buffer head which is used for metadata modifications.
   * Taken from Ext4: extend_or_restart_transaction()
   */
  int ocfs2_allocate_extend_trans(handle_t *handle, int thresh)
  {
  	int status, old_nblks;
  
  	BUG_ON(!handle);
  
  	old_nblks = handle->h_buffer_credits;
  	trace_ocfs2_allocate_extend_trans(old_nblks, thresh);
  
  	if (old_nblks < thresh)
  		return 0;
  
  	status = jbd2_journal_extend(handle, OCFS2_MAX_TRANS_DATA);
  	if (status < 0) {
  		mlog_errno(status);
  		goto bail;
  	}
  
  	if (status > 0) {
  		status = jbd2_journal_restart(handle, OCFS2_MAX_TRANS_DATA);
  		if (status < 0)
  			mlog_errno(status);
  	}
  
  bail:
  	return status;
  }
50655ae9e   Joel Becker   ocfs2: Add journa...
467
468
469
470
471
472
473
474
475
  struct ocfs2_triggers {
  	struct jbd2_buffer_trigger_type	ot_triggers;
  	int				ot_offset;
  };
  
  static inline struct ocfs2_triggers *to_ocfs2_trigger(struct jbd2_buffer_trigger_type *triggers)
  {
  	return container_of(triggers, struct ocfs2_triggers, ot_triggers);
  }
13ceef099   Jan Kara   jbd2/ocfs2: Fix b...
476
  static void ocfs2_frozen_trigger(struct jbd2_buffer_trigger_type *triggers,
50655ae9e   Joel Becker   ocfs2: Add journa...
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
  				 struct buffer_head *bh,
  				 void *data, size_t size)
  {
  	struct ocfs2_triggers *ot = to_ocfs2_trigger(triggers);
  
  	/*
  	 * We aren't guaranteed to have the superblock here, so we
  	 * must unconditionally compute the ecc data.
  	 * __ocfs2_journal_access() will only set the triggers if
  	 * metaecc is enabled.
  	 */
  	ocfs2_block_check_compute(data, size, data + ot->ot_offset);
  }
  
  /*
   * Quota blocks have their own trigger because the struct ocfs2_block_check
   * offset depends on the blocksize.
   */
13ceef099   Jan Kara   jbd2/ocfs2: Fix b...
495
  static void ocfs2_dq_frozen_trigger(struct jbd2_buffer_trigger_type *triggers,
50655ae9e   Joel Becker   ocfs2: Add journa...
496
497
498
499
500
501
502
503
504
505
506
507
508
509
  				 struct buffer_head *bh,
  				 void *data, size_t size)
  {
  	struct ocfs2_disk_dqtrailer *dqt =
  		ocfs2_block_dqtrailer(size, data);
  
  	/*
  	 * We aren't guaranteed to have the superblock here, so we
  	 * must unconditionally compute the ecc data.
  	 * __ocfs2_journal_access() will only set the triggers if
  	 * metaecc is enabled.
  	 */
  	ocfs2_block_check_compute(data, size, &dqt->dq_check);
  }
c175a518b   Joel Becker   ocfs2: Checksum a...
510
511
512
513
  /*
   * Directory blocks also have their own trigger because the
   * struct ocfs2_block_check offset depends on the blocksize.
   */
13ceef099   Jan Kara   jbd2/ocfs2: Fix b...
514
  static void ocfs2_db_frozen_trigger(struct jbd2_buffer_trigger_type *triggers,
c175a518b   Joel Becker   ocfs2: Checksum a...
515
516
517
518
519
520
521
522
523
524
525
526
527
528
  				 struct buffer_head *bh,
  				 void *data, size_t size)
  {
  	struct ocfs2_dir_block_trailer *trailer =
  		ocfs2_dir_trailer_from_size(size, data);
  
  	/*
  	 * We aren't guaranteed to have the superblock here, so we
  	 * must unconditionally compute the ecc data.
  	 * __ocfs2_journal_access() will only set the triggers if
  	 * metaecc is enabled.
  	 */
  	ocfs2_block_check_compute(data, size, &trailer->db_check);
  }
50655ae9e   Joel Becker   ocfs2: Add journa...
529
530
531
532
533
534
535
536
537
  static void ocfs2_abort_trigger(struct jbd2_buffer_trigger_type *triggers,
  				struct buffer_head *bh)
  {
  	mlog(ML_ERROR,
  	     "ocfs2_abort_trigger called by JBD2.  bh = 0x%lx, "
  	     "bh->b_blocknr = %llu
  ",
  	     (unsigned long)bh,
  	     (unsigned long long)bh->b_blocknr);
74e364ad1   Xue jiufei   ocfs2: fix NULL p...
538
  	ocfs2_error(bh->b_bdev->bd_super,
50655ae9e   Joel Becker   ocfs2: Add journa...
539
540
541
542
543
544
  		    "JBD2 has aborted our journal, ocfs2 cannot continue
  ");
  }
  
  static struct ocfs2_triggers di_triggers = {
  	.ot_triggers = {
13ceef099   Jan Kara   jbd2/ocfs2: Fix b...
545
  		.t_frozen = ocfs2_frozen_trigger,
50655ae9e   Joel Becker   ocfs2: Add journa...
546
547
548
549
550
551
552
  		.t_abort = ocfs2_abort_trigger,
  	},
  	.ot_offset	= offsetof(struct ocfs2_dinode, i_check),
  };
  
  static struct ocfs2_triggers eb_triggers = {
  	.ot_triggers = {
13ceef099   Jan Kara   jbd2/ocfs2: Fix b...
553
  		.t_frozen = ocfs2_frozen_trigger,
50655ae9e   Joel Becker   ocfs2: Add journa...
554
555
556
557
  		.t_abort = ocfs2_abort_trigger,
  	},
  	.ot_offset	= offsetof(struct ocfs2_extent_block, h_check),
  };
93c97087a   Tao Ma   ocfs2: Add metaec...
558
559
  static struct ocfs2_triggers rb_triggers = {
  	.ot_triggers = {
13ceef099   Jan Kara   jbd2/ocfs2: Fix b...
560
  		.t_frozen = ocfs2_frozen_trigger,
93c97087a   Tao Ma   ocfs2: Add metaec...
561
562
563
564
  		.t_abort = ocfs2_abort_trigger,
  	},
  	.ot_offset	= offsetof(struct ocfs2_refcount_block, rf_check),
  };
50655ae9e   Joel Becker   ocfs2: Add journa...
565
566
  static struct ocfs2_triggers gd_triggers = {
  	.ot_triggers = {
13ceef099   Jan Kara   jbd2/ocfs2: Fix b...
567
  		.t_frozen = ocfs2_frozen_trigger,
50655ae9e   Joel Becker   ocfs2: Add journa...
568
569
570
571
  		.t_abort = ocfs2_abort_trigger,
  	},
  	.ot_offset	= offsetof(struct ocfs2_group_desc, bg_check),
  };
c175a518b   Joel Becker   ocfs2: Checksum a...
572
573
  static struct ocfs2_triggers db_triggers = {
  	.ot_triggers = {
13ceef099   Jan Kara   jbd2/ocfs2: Fix b...
574
  		.t_frozen = ocfs2_db_frozen_trigger,
c175a518b   Joel Becker   ocfs2: Checksum a...
575
576
577
  		.t_abort = ocfs2_abort_trigger,
  	},
  };
50655ae9e   Joel Becker   ocfs2: Add journa...
578
579
  static struct ocfs2_triggers xb_triggers = {
  	.ot_triggers = {
13ceef099   Jan Kara   jbd2/ocfs2: Fix b...
580
  		.t_frozen = ocfs2_frozen_trigger,
50655ae9e   Joel Becker   ocfs2: Add journa...
581
582
583
584
585
586
587
  		.t_abort = ocfs2_abort_trigger,
  	},
  	.ot_offset	= offsetof(struct ocfs2_xattr_block, xb_check),
  };
  
  static struct ocfs2_triggers dq_triggers = {
  	.ot_triggers = {
13ceef099   Jan Kara   jbd2/ocfs2: Fix b...
588
  		.t_frozen = ocfs2_dq_frozen_trigger,
50655ae9e   Joel Becker   ocfs2: Add journa...
589
590
591
  		.t_abort = ocfs2_abort_trigger,
  	},
  };
9b7895efa   Mark Fasheh   ocfs2: Add a name...
592
593
  static struct ocfs2_triggers dr_triggers = {
  	.ot_triggers = {
13ceef099   Jan Kara   jbd2/ocfs2: Fix b...
594
  		.t_frozen = ocfs2_frozen_trigger,
9b7895efa   Mark Fasheh   ocfs2: Add a name...
595
596
597
598
599
600
601
  		.t_abort = ocfs2_abort_trigger,
  	},
  	.ot_offset	= offsetof(struct ocfs2_dx_root_block, dr_check),
  };
  
  static struct ocfs2_triggers dl_triggers = {
  	.ot_triggers = {
13ceef099   Jan Kara   jbd2/ocfs2: Fix b...
602
  		.t_frozen = ocfs2_frozen_trigger,
9b7895efa   Mark Fasheh   ocfs2: Add a name...
603
604
605
606
  		.t_abort = ocfs2_abort_trigger,
  	},
  	.ot_offset	= offsetof(struct ocfs2_dx_leaf, dl_check),
  };
50655ae9e   Joel Becker   ocfs2: Add journa...
607
  static int __ocfs2_journal_access(handle_t *handle,
0cf2f7632   Joel Becker   ocfs2: Pass struc...
608
  				  struct ocfs2_caching_info *ci,
50655ae9e   Joel Becker   ocfs2: Add journa...
609
610
611
  				  struct buffer_head *bh,
  				  struct ocfs2_triggers *triggers,
  				  int type)
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
612
613
  {
  	int status;
0cf2f7632   Joel Becker   ocfs2: Pass struc...
614
615
  	struct ocfs2_super *osb =
  		OCFS2_SB(ocfs2_metadata_cache_get_super(ci));
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
616

0cf2f7632   Joel Becker   ocfs2: Pass struc...
617
  	BUG_ON(!ci || !ci->ci_ops);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
618
619
  	BUG_ON(!handle);
  	BUG_ON(!bh);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
620

b41079504   Tao Ma   ocfs2: Remove mas...
621
622
623
  	trace_ocfs2_journal_access(
  		(unsigned long long)ocfs2_metadata_cache_owner(ci),
  		(unsigned long long)bh->b_blocknr, type, bh->b_size);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
624
625
626
627
628
  
  	/* we can safely remove this assertion after testing. */
  	if (!buffer_uptodate(bh)) {
  		mlog(ML_ERROR, "giving me a buffer that's not uptodate!
  ");
d984187e3   piaojun   ocfs2: return err...
629
630
631
  		mlog(ML_ERROR, "b_blocknr=%llu, b_state=0x%lx
  ",
  		     (unsigned long long)bh->b_blocknr, bh->b_state);
acf8fdbe6   Joseph Qi   ocfs2: do not BUG...
632
633
634
  
  		lock_buffer(bh);
  		/*
d984187e3   piaojun   ocfs2: return err...
635
636
637
638
639
640
641
642
  		 * A previous transaction with a couple of buffer heads fail
  		 * to checkpoint, so all the bhs are marked as BH_Write_EIO.
  		 * For current transaction, the bh is just among those error
  		 * bhs which previous transaction handle. We can't just clear
  		 * its BH_Write_EIO and reuse directly, since other bhs are
  		 * not written to disk yet and that will cause metadata
  		 * inconsistency. So we should set fs read-only to avoid
  		 * further damage.
acf8fdbe6   Joseph Qi   ocfs2: do not BUG...
643
644
  		 */
  		if (buffer_write_io_error(bh) && !buffer_uptodate(bh)) {
acf8fdbe6   Joseph Qi   ocfs2: do not BUG...
645
  			unlock_buffer(bh);
d984187e3   piaojun   ocfs2: return err...
646
647
648
  			return ocfs2_error(osb->sb, "A previous attempt to "
  					"write this buffer head failed
  ");
acf8fdbe6   Joseph Qi   ocfs2: do not BUG...
649
650
  		}
  		unlock_buffer(bh);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
651
  	}
0cf2f7632   Joel Becker   ocfs2: Pass struc...
652
  	/* Set the current transaction information on the ci so
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
653
  	 * that the locking code knows whether it can drop it's locks
0cf2f7632   Joel Becker   ocfs2: Pass struc...
654
  	 * on this ci or not. We're protected from the commit
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
655
656
657
  	 * thread updating the current transaction id until
  	 * ocfs2_commit_trans() because ocfs2_start_trans() took
  	 * j_trans_barrier for us. */
0cf2f7632   Joel Becker   ocfs2: Pass struc...
658
  	ocfs2_set_ci_lock_trans(osb->journal, ci);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
659

0cf2f7632   Joel Becker   ocfs2: Pass struc...
660
  	ocfs2_metadata_cache_io_lock(ci);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
661
662
663
  	switch (type) {
  	case OCFS2_JOURNAL_ACCESS_CREATE:
  	case OCFS2_JOURNAL_ACCESS_WRITE:
2b4e30fbd   Joel Becker   ocfs2: Switch ove...
664
  		status = jbd2_journal_get_write_access(handle, bh);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
665
666
667
  		break;
  
  	case OCFS2_JOURNAL_ACCESS_UNDO:
2b4e30fbd   Joel Becker   ocfs2: Switch ove...
668
  		status = jbd2_journal_get_undo_access(handle, bh);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
669
670
671
672
  		break;
  
  	default:
  		status = -EINVAL;
af901ca18   André Goddard Rosa   tree-wide: fix as...
673
674
  		mlog(ML_ERROR, "Unknown access type!
  ");
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
675
  	}
0cf2f7632   Joel Becker   ocfs2: Pass struc...
676
  	if (!status && ocfs2_meta_ecc(osb) && triggers)
50655ae9e   Joel Becker   ocfs2: Add journa...
677
  		jbd2_journal_set_triggers(bh, &triggers->ot_triggers);
0cf2f7632   Joel Becker   ocfs2: Pass struc...
678
  	ocfs2_metadata_cache_io_unlock(ci);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
679
680
681
682
683
  
  	if (status < 0)
  		mlog(ML_ERROR, "Error %d getting %d access to buffer!
  ",
  		     status, type);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
684
685
  	return status;
  }
0cf2f7632   Joel Becker   ocfs2: Pass struc...
686
687
  int ocfs2_journal_access_di(handle_t *handle, struct ocfs2_caching_info *ci,
  			    struct buffer_head *bh, int type)
50655ae9e   Joel Becker   ocfs2: Add journa...
688
  {
0cf2f7632   Joel Becker   ocfs2: Pass struc...
689
  	return __ocfs2_journal_access(handle, ci, bh, &di_triggers, type);
50655ae9e   Joel Becker   ocfs2: Add journa...
690
  }
0cf2f7632   Joel Becker   ocfs2: Pass struc...
691
  int ocfs2_journal_access_eb(handle_t *handle, struct ocfs2_caching_info *ci,
50655ae9e   Joel Becker   ocfs2: Add journa...
692
693
  			    struct buffer_head *bh, int type)
  {
0cf2f7632   Joel Becker   ocfs2: Pass struc...
694
  	return __ocfs2_journal_access(handle, ci, bh, &eb_triggers, type);
50655ae9e   Joel Becker   ocfs2: Add journa...
695
  }
93c97087a   Tao Ma   ocfs2: Add metaec...
696
697
698
699
700
701
  int ocfs2_journal_access_rb(handle_t *handle, struct ocfs2_caching_info *ci,
  			    struct buffer_head *bh, int type)
  {
  	return __ocfs2_journal_access(handle, ci, bh, &rb_triggers,
  				      type);
  }
0cf2f7632   Joel Becker   ocfs2: Pass struc...
702
  int ocfs2_journal_access_gd(handle_t *handle, struct ocfs2_caching_info *ci,
50655ae9e   Joel Becker   ocfs2: Add journa...
703
704
  			    struct buffer_head *bh, int type)
  {
0cf2f7632   Joel Becker   ocfs2: Pass struc...
705
  	return __ocfs2_journal_access(handle, ci, bh, &gd_triggers, type);
50655ae9e   Joel Becker   ocfs2: Add journa...
706
  }
0cf2f7632   Joel Becker   ocfs2: Pass struc...
707
  int ocfs2_journal_access_db(handle_t *handle, struct ocfs2_caching_info *ci,
50655ae9e   Joel Becker   ocfs2: Add journa...
708
709
  			    struct buffer_head *bh, int type)
  {
0cf2f7632   Joel Becker   ocfs2: Pass struc...
710
  	return __ocfs2_journal_access(handle, ci, bh, &db_triggers, type);
50655ae9e   Joel Becker   ocfs2: Add journa...
711
  }
0cf2f7632   Joel Becker   ocfs2: Pass struc...
712
  int ocfs2_journal_access_xb(handle_t *handle, struct ocfs2_caching_info *ci,
50655ae9e   Joel Becker   ocfs2: Add journa...
713
714
  			    struct buffer_head *bh, int type)
  {
0cf2f7632   Joel Becker   ocfs2: Pass struc...
715
  	return __ocfs2_journal_access(handle, ci, bh, &xb_triggers, type);
50655ae9e   Joel Becker   ocfs2: Add journa...
716
  }
0cf2f7632   Joel Becker   ocfs2: Pass struc...
717
  int ocfs2_journal_access_dq(handle_t *handle, struct ocfs2_caching_info *ci,
50655ae9e   Joel Becker   ocfs2: Add journa...
718
719
  			    struct buffer_head *bh, int type)
  {
0cf2f7632   Joel Becker   ocfs2: Pass struc...
720
  	return __ocfs2_journal_access(handle, ci, bh, &dq_triggers, type);
50655ae9e   Joel Becker   ocfs2: Add journa...
721
  }
0cf2f7632   Joel Becker   ocfs2: Pass struc...
722
  int ocfs2_journal_access_dr(handle_t *handle, struct ocfs2_caching_info *ci,
9b7895efa   Mark Fasheh   ocfs2: Add a name...
723
724
  			    struct buffer_head *bh, int type)
  {
0cf2f7632   Joel Becker   ocfs2: Pass struc...
725
  	return __ocfs2_journal_access(handle, ci, bh, &dr_triggers, type);
9b7895efa   Mark Fasheh   ocfs2: Add a name...
726
  }
0cf2f7632   Joel Becker   ocfs2: Pass struc...
727
  int ocfs2_journal_access_dl(handle_t *handle, struct ocfs2_caching_info *ci,
9b7895efa   Mark Fasheh   ocfs2: Add a name...
728
729
  			    struct buffer_head *bh, int type)
  {
0cf2f7632   Joel Becker   ocfs2: Pass struc...
730
  	return __ocfs2_journal_access(handle, ci, bh, &dl_triggers, type);
9b7895efa   Mark Fasheh   ocfs2: Add a name...
731
  }
0cf2f7632   Joel Becker   ocfs2: Pass struc...
732
  int ocfs2_journal_access(handle_t *handle, struct ocfs2_caching_info *ci,
50655ae9e   Joel Becker   ocfs2: Add journa...
733
734
  			 struct buffer_head *bh, int type)
  {
0cf2f7632   Joel Becker   ocfs2: Pass struc...
735
  	return __ocfs2_journal_access(handle, ci, bh, NULL, type);
50655ae9e   Joel Becker   ocfs2: Add journa...
736
  }
ec20cec7a   Joel Becker   ocfs2: Make ocfs2...
737
  void ocfs2_journal_dirty(handle_t *handle, struct buffer_head *bh)
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
738
739
  {
  	int status;
b41079504   Tao Ma   ocfs2: Remove mas...
740
  	trace_ocfs2_journal_dirty((unsigned long long)bh->b_blocknr);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
741

2b4e30fbd   Joel Becker   ocfs2: Switch ove...
742
  	status = jbd2_journal_dirty_metadata(handle, bh);
e272e7f0f   Joseph Qi   ocfs2: do not BUG...
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
  	if (status) {
  		mlog_errno(status);
  		if (!is_handle_aborted(handle)) {
  			journal_t *journal = handle->h_transaction->t_journal;
  			struct super_block *sb = bh->b_bdev->bd_super;
  
  			mlog(ML_ERROR, "jbd2_journal_dirty_metadata failed. "
  					"Aborting transaction and journal.
  ");
  			handle->h_err = status;
  			jbd2_journal_abort_handle(handle);
  			jbd2_journal_abort(journal, status);
  			ocfs2_abort(sb, "Journal already aborted.
  ");
  		}
  	}
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
759
  }
2b4e30fbd   Joel Becker   ocfs2: Switch ove...
760
  #define OCFS2_DEFAULT_COMMIT_INTERVAL	(HZ * JBD2_DEFAULT_MAX_COMMIT_AGE)
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
761
762
763
764
  
  void ocfs2_set_journal_params(struct ocfs2_super *osb)
  {
  	journal_t *journal = osb->journal->j_journal;
d147b3d63   Mark Fasheh   ocfs2: Support co...
765
766
767
768
  	unsigned long commit_interval = OCFS2_DEFAULT_COMMIT_INTERVAL;
  
  	if (osb->osb_commit_interval)
  		commit_interval = osb->osb_commit_interval;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
769

a931da6ac   Theodore Ts'o   jbd2: Change j_st...
770
  	write_lock(&journal->j_state_lock);
d147b3d63   Mark Fasheh   ocfs2: Support co...
771
  	journal->j_commit_interval = commit_interval;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
772
  	if (osb->s_mount_opt & OCFS2_MOUNT_BARRIER)
2b4e30fbd   Joel Becker   ocfs2: Switch ove...
773
  		journal->j_flags |= JBD2_BARRIER;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
774
  	else
2b4e30fbd   Joel Becker   ocfs2: Switch ove...
775
  		journal->j_flags &= ~JBD2_BARRIER;
a931da6ac   Theodore Ts'o   jbd2: Change j_st...
776
  	write_unlock(&journal->j_state_lock);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
777
778
779
780
781
782
783
784
785
786
  }
  
  int ocfs2_journal_init(struct ocfs2_journal *journal, int *dirty)
  {
  	int status = -1;
  	struct inode *inode = NULL; /* the journal inode */
  	journal_t *j_journal = NULL;
  	struct ocfs2_dinode *di = NULL;
  	struct buffer_head *bh = NULL;
  	struct ocfs2_super *osb;
e63aecb65   Mark Fasheh   ocfs2: Rename ocf...
787
  	int inode_lock = 0;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
788

ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
  	BUG_ON(!journal);
  
  	osb = journal->j_osb;
  
  	/* already have the inode for our journal */
  	inode = ocfs2_get_system_file_inode(osb, JOURNAL_SYSTEM_INODE,
  					    osb->slot_num);
  	if (inode == NULL) {
  		status = -EACCES;
  		mlog_errno(status);
  		goto done;
  	}
  	if (is_bad_inode(inode)) {
  		mlog(ML_ERROR, "access error (bad inode)
  ");
  		iput(inode);
  		inode = NULL;
  		status = -EACCES;
  		goto done;
  	}
  
  	SET_INODE_JOURNAL(inode);
  	OCFS2_I(inode)->ip_open_count++;
6eff5790d   Mark Fasheh   [PATCH] ocfs2: do...
812
813
814
  	/* Skip recovery waits here - journal inode metadata never
  	 * changes in a live cluster so it can be considered an
  	 * exception to the rule. */
e63aecb65   Mark Fasheh   ocfs2: Rename ocf...
815
  	status = ocfs2_inode_lock_full(inode, &bh, 1, OCFS2_META_LOCK_RECOVERY);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
816
817
818
819
820
821
  	if (status < 0) {
  		if (status != -ERESTARTSYS)
  			mlog(ML_ERROR, "Could not get lock on journal!
  ");
  		goto done;
  	}
e63aecb65   Mark Fasheh   ocfs2: Rename ocf...
822
  	inode_lock = 1;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
823
  	di = (struct ocfs2_dinode *)bh->b_data;
f17c20dd2   Junxiao Bi   ocfs2: use i_size...
824
  	if (i_size_read(inode) <  OCFS2_MIN_JOURNAL_SIZE) {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
825
826
  		mlog(ML_ERROR, "Journal file size (%lld) is too small!
  ",
f17c20dd2   Junxiao Bi   ocfs2: use i_size...
827
  		     i_size_read(inode));
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
828
829
830
  		status = -EINVAL;
  		goto done;
  	}
f17c20dd2   Junxiao Bi   ocfs2: use i_size...
831
  	trace_ocfs2_journal_init(i_size_read(inode),
b41079504   Tao Ma   ocfs2: Remove mas...
832
833
  				 (unsigned long long)inode->i_blocks,
  				 OCFS2_I(inode)->ip_clusters);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
834
835
  
  	/* call the kernels journal init function now */
2b4e30fbd   Joel Becker   ocfs2: Switch ove...
836
  	j_journal = jbd2_journal_init_inode(inode);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
837
838
839
840
841
842
  	if (j_journal == NULL) {
  		mlog(ML_ERROR, "Linux journal layer error
  ");
  		status = -EINVAL;
  		goto done;
  	}
b41079504   Tao Ma   ocfs2: Remove mas...
843
  	trace_ocfs2_journal_init_maxlen(j_journal->j_maxlen);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
  
  	*dirty = (le32_to_cpu(di->id1.journal1.ij_flags) &
  		  OCFS2_JOURNAL_DIRTY_FL);
  
  	journal->j_journal = j_journal;
  	journal->j_inode = inode;
  	journal->j_bh = bh;
  
  	ocfs2_set_journal_params(osb);
  
  	journal->j_state = OCFS2_JOURNAL_LOADED;
  
  	status = 0;
  done:
  	if (status < 0) {
e63aecb65   Mark Fasheh   ocfs2: Rename ocf...
859
860
  		if (inode_lock)
  			ocfs2_inode_unlock(inode, 1);
a81cb88b6   Mark Fasheh   ocfs2: Don't chec...
861
  		brelse(bh);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
862
863
864
865
866
  		if (inode) {
  			OCFS2_I(inode)->ip_open_count--;
  			iput(inode);
  		}
  	}
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
867
868
  	return status;
  }
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
869
870
871
872
873
874
875
876
877
  static void ocfs2_bump_recovery_generation(struct ocfs2_dinode *di)
  {
  	le32_add_cpu(&(di->id1.journal1.ij_recovery_generation), 1);
  }
  
  static u32 ocfs2_get_recovery_generation(struct ocfs2_dinode *di)
  {
  	return le32_to_cpu(di->id1.journal1.ij_recovery_generation);
  }
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
878
  static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb,
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
879
  				      int dirty, int replayed)
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
880
881
882
883
884
885
  {
  	int status;
  	unsigned int flags;
  	struct ocfs2_journal *journal = osb->journal;
  	struct buffer_head *bh = journal->j_bh;
  	struct ocfs2_dinode *fe;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
886
  	fe = (struct ocfs2_dinode *)bh->b_data;
10995aa24   Joel Becker   ocfs2: Morph the ...
887
888
889
890
891
  
  	/* The journal bh on the osb always comes from ocfs2_journal_init()
  	 * and was validated there inside ocfs2_inode_lock_full().  It's a
  	 * code bug if we mess it up. */
  	BUG_ON(!OCFS2_IS_VALID_DINODE(fe));
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
892
893
894
895
896
897
898
  
  	flags = le32_to_cpu(fe->id1.journal1.ij_flags);
  	if (dirty)
  		flags |= OCFS2_JOURNAL_DIRTY_FL;
  	else
  		flags &= ~OCFS2_JOURNAL_DIRTY_FL;
  	fe->id1.journal1.ij_flags = cpu_to_le32(flags);
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
899
900
  	if (replayed)
  		ocfs2_bump_recovery_generation(fe);
13723d00e   Joel Becker   ocfs2: Use metada...
901
  	ocfs2_compute_meta_ecc(osb->sb, bh->b_data, &fe->i_check);
8cb471e8f   Joel Becker   ocfs2: Take the i...
902
  	status = ocfs2_write_block(osb, bh, INODE_CACHE(journal->j_inode));
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
903
904
  	if (status < 0)
  		mlog_errno(status);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
905
906
907
908
909
910
911
912
913
914
915
916
917
  	return status;
  }
  
  /*
   * If the journal has been kmalloc'd it needs to be freed after this
   * call.
   */
  void ocfs2_journal_shutdown(struct ocfs2_super *osb)
  {
  	struct ocfs2_journal *journal = NULL;
  	int status = 0;
  	struct inode *inode = NULL;
  	int num_running_trans = 0;
ebdec83ba   Eric Sesterhenn / snakebyte   [PATCH] BUG_ON() ...
918
  	BUG_ON(!osb);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
919
920
921
922
923
924
925
926
927
  
  	journal = osb->journal;
  	if (!journal)
  		goto done;
  
  	inode = journal->j_inode;
  
  	if (journal->j_state != OCFS2_JOURNAL_LOADED)
  		goto done;
2b4e30fbd   Joel Becker   ocfs2: Switch ove...
928
  	/* need to inc inode use count - jbd2_journal_destroy will iput. */
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
929
930
931
932
  	if (!igrab(inode))
  		BUG();
  
  	num_running_trans = atomic_read(&(osb->journal->j_num_trans));
b41079504   Tao Ma   ocfs2: Remove mas...
933
  	trace_ocfs2_journal_shutdown(num_running_trans);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
934
935
936
937
938
939
940
941
942
943
944
945
  
  	/* Do a commit_cache here. It will flush our journal, *and*
  	 * release any locks that are still held.
  	 * set the SHUTDOWN flag and release the trans lock.
  	 * the commit thread will take the trans lock for us below. */
  	journal->j_state = OCFS2_JOURNAL_IN_SHUTDOWN;
  
  	/* The OCFS2_JOURNAL_IN_SHUTDOWN will signal to commit_cache to not
  	 * drop the trans_lock (which we want to hold until we
  	 * completely destroy the journal. */
  	if (osb->commit_task) {
  		/* Wait for the commit thread */
b41079504   Tao Ma   ocfs2: Remove mas...
946
  		trace_ocfs2_journal_shutdown_wait(osb->commit_task);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
947
948
949
950
951
  		kthread_stop(osb->commit_task);
  		osb->commit_task = NULL;
  	}
  
  	BUG_ON(atomic_read(&(osb->journal->j_num_trans)) != 0);
c271c5c22   Sunil Mushran   ocfs2: local mounts
952
  	if (ocfs2_mount_local(osb)) {
2b4e30fbd   Joel Becker   ocfs2: Switch ove...
953
954
955
  		jbd2_journal_lock_updates(journal->j_journal);
  		status = jbd2_journal_flush(journal->j_journal);
  		jbd2_journal_unlock_updates(journal->j_journal);
c271c5c22   Sunil Mushran   ocfs2: local mounts
956
957
958
  		if (status < 0)
  			mlog_errno(status);
  	}
d85400af7   Junxiao Bi   ocfs2: clear jour...
959
960
  	/* Shutdown the kernel journal system */
  	if (!jbd2_journal_destroy(journal->j_journal) && !status) {
c271c5c22   Sunil Mushran   ocfs2: local mounts
961
962
963
964
  		/*
  		 * Do not toggle if flush was unsuccessful otherwise
  		 * will leave dirty metadata in a "clean" journal
  		 */
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
965
  		status = ocfs2_journal_toggle_dirty(osb, 0, 0);
c271c5c22   Sunil Mushran   ocfs2: local mounts
966
967
968
  		if (status < 0)
  			mlog_errno(status);
  	}
ae0dff683   Sunil Mushran   ocfs2: Set journa...
969
  	journal->j_journal = NULL;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
970
971
972
973
  
  	OCFS2_I(inode)->ip_open_count--;
  
  	/* unlock our journal */
e63aecb65   Mark Fasheh   ocfs2: Rename ocf...
974
  	ocfs2_inode_unlock(inode, 1);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
975
976
977
978
979
980
981
982
  
  	brelse(journal->j_bh);
  	journal->j_bh = NULL;
  
  	journal->j_state = OCFS2_JOURNAL_FREE;
  
  //	up_write(&journal->j_trans_barrier);
  done:
72865d923   Joseph Qi   ocfs2: clean up r...
983
  	iput(inode);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
984
985
986
987
988
989
990
  }
  
  static void ocfs2_clear_journal_error(struct super_block *sb,
  				      journal_t *journal,
  				      int slot)
  {
  	int olderr;
2b4e30fbd   Joel Becker   ocfs2: Switch ove...
991
  	olderr = jbd2_journal_errno(journal);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
992
993
994
995
996
997
998
  	if (olderr) {
  		mlog(ML_ERROR, "File system error %d recorded in "
  		     "journal %u.
  ", olderr, slot);
  		mlog(ML_ERROR, "File system on device %s needs checking.
  ",
  		     sb->s_id);
2b4e30fbd   Joel Becker   ocfs2: Switch ove...
999
1000
  		jbd2_journal_ack_err(journal);
  		jbd2_journal_clear_err(journal);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1001
1002
  	}
  }
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
1003
  int ocfs2_journal_load(struct ocfs2_journal *journal, int local, int replayed)
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1004
1005
1006
  {
  	int status = 0;
  	struct ocfs2_super *osb;
b1f3550fa   Julia Lawall   ocfs2: Use BUG_ON
1007
  	BUG_ON(!journal);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1008
1009
  
  	osb = journal->j_osb;
2b4e30fbd   Joel Becker   ocfs2: Switch ove...
1010
  	status = jbd2_journal_load(journal->j_journal);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1011
1012
1013
1014
1015
1016
1017
  	if (status < 0) {
  		mlog(ML_ERROR, "Failed to load journal!
  ");
  		goto done;
  	}
  
  	ocfs2_clear_journal_error(osb->sb, journal->j_journal, osb->slot_num);
dae87141c   Kai Li   ocfs2: call journ...
1018
1019
1020
1021
1022
1023
1024
  	if (replayed) {
  		jbd2_journal_lock_updates(journal->j_journal);
  		status = jbd2_journal_flush(journal->j_journal);
  		jbd2_journal_unlock_updates(journal->j_journal);
  		if (status < 0)
  			mlog_errno(status);
  	}
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
1025
  	status = ocfs2_journal_toggle_dirty(osb, 1, replayed);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1026
1027
1028
1029
1030
1031
  	if (status < 0) {
  		mlog_errno(status);
  		goto done;
  	}
  
  	/* Launch the commit thread */
c271c5c22   Sunil Mushran   ocfs2: local mounts
1032
1033
  	if (!local) {
  		osb->commit_task = kthread_run(ocfs2_commit_thread, osb,
5afc44e2e   Joseph Qi   ocfs2: add uuid t...
1034
  				"ocfs2cmt-%s", osb->uuid_str);
c271c5c22   Sunil Mushran   ocfs2: local mounts
1035
1036
1037
1038
1039
1040
1041
1042
  		if (IS_ERR(osb->commit_task)) {
  			status = PTR_ERR(osb->commit_task);
  			osb->commit_task = NULL;
  			mlog(ML_ERROR, "unable to launch ocfs2commit thread, "
  			     "error=%d", status);
  			goto done;
  		}
  	} else
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1043
  		osb->commit_task = NULL;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1044
1045
  
  done:
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1046
1047
1048
1049
1050
1051
1052
1053
1054
  	return status;
  }
  
  
  /* 'full' flag tells us whether we clear out all blocks or if we just
   * mark the journal clean */
  int ocfs2_journal_wipe(struct ocfs2_journal *journal, int full)
  {
  	int status;
ebdec83ba   Eric Sesterhenn / snakebyte   [PATCH] BUG_ON() ...
1055
  	BUG_ON(!journal);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1056

2b4e30fbd   Joel Becker   ocfs2: Switch ove...
1057
  	status = jbd2_journal_wipe(journal->j_journal, full);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1058
1059
1060
1061
  	if (status < 0) {
  		mlog_errno(status);
  		goto bail;
  	}
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
1062
  	status = ocfs2_journal_toggle_dirty(journal->j_osb, 0, 0);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1063
1064
1065
1066
  	if (status < 0)
  		mlog_errno(status);
  
  bail:
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1067
1068
  	return status;
  }
553abd046   Joel Becker   ocfs2: Change the...
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
  static int ocfs2_recovery_completed(struct ocfs2_super *osb)
  {
  	int empty;
  	struct ocfs2_recovery_map *rm = osb->recovery_map;
  
  	spin_lock(&osb->osb_lock);
  	empty = (rm->rm_used == 0);
  	spin_unlock(&osb->osb_lock);
  
  	return empty;
  }
  
  void ocfs2_wait_for_recovery(struct ocfs2_super *osb)
  {
  	wait_event(osb->recovery_event, ocfs2_recovery_completed(osb));
  }
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
  /*
   * JBD Might read a cached version of another nodes journal file. We
   * don't want this as this file changes often and we get no
   * notification on those changes. The only way to be sure that we've
   * got the most up to date version of those blocks then is to force
   * read them off disk. Just searching through the buffer cache won't
   * work as there may be pages backing this file which are still marked
   * up to date. We know things can't change on this file underneath us
   * as we have the lock by now :)
   */
  static int ocfs2_force_read_journal(struct inode *inode)
  {
  	int status = 0;
4f902c377   Mark Fasheh   ocfs2: Fix extent...
1098
  	int i;
8110b073a   Mark Fasheh   ocfs2: Fix up i_b...
1099
  	u64 v_blkno, p_blkno, p_blocks, num_blocks;
0b492f68b   Junxiao Bi   ocfs2: improve re...
1100
1101
  	struct buffer_head *bh = NULL;
  	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1102

f17c20dd2   Junxiao Bi   ocfs2: use i_size...
1103
  	num_blocks = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode));
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1104
  	v_blkno = 0;
8110b073a   Mark Fasheh   ocfs2: Fix up i_b...
1105
  	while (v_blkno < num_blocks) {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1106
  		status = ocfs2_extent_map_get_blocks(inode, v_blkno,
49cb8d2d4   Mark Fasheh   ocfs2: Read from ...
1107
  						     &p_blkno, &p_blocks, NULL);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1108
1109
1110
1111
  		if (status < 0) {
  			mlog_errno(status);
  			goto bail;
  		}
0b492f68b   Junxiao Bi   ocfs2: improve re...
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
  		for (i = 0; i < p_blocks; i++, p_blkno++) {
  			bh = __find_get_block(osb->sb->s_bdev, p_blkno,
  					osb->sb->s_blocksize);
  			/* block not cached. */
  			if (!bh)
  				continue;
  
  			brelse(bh);
  			bh = NULL;
  			/* We are reading journal data which should not
  			 * be put in the uptodate cache.
  			 */
  			status = ocfs2_read_blocks_sync(osb, p_blkno, 1, &bh);
  			if (status < 0) {
  				mlog_errno(status);
  				goto bail;
  			}
  
  			brelse(bh);
  			bh = NULL;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1132
1133
1134
1135
1136
1137
  		}
  
  		v_blkno += p_blocks;
  	}
  
  bail:
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1138
1139
1140
1141
1142
1143
1144
1145
  	return status;
  }
  
  struct ocfs2_la_recovery_item {
  	struct list_head	lri_list;
  	int			lri_slot;
  	struct ocfs2_dinode	*lri_la_dinode;
  	struct ocfs2_dinode	*lri_tl_dinode;
2205363dc   Jan Kara   ocfs2: Implement ...
1146
  	struct ocfs2_quota_recovery *lri_qrec;
ed460cffc   Joseph Qi   ocfs2: add orphan...
1147
  	enum ocfs2_orphan_reco_type  lri_orphan_reco_type;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
  };
  
  /* Does the second half of the recovery process. By this point, the
   * node is marked clean and can actually be considered recovered,
   * hence it's no longer in the recovery map, but there's still some
   * cleanup we can do which shouldn't happen within the recovery thread
   * as locking in that context becomes very difficult if we are to take
   * recovering nodes into account.
   *
   * NOTE: This function can and will sleep on recovery of other nodes
   * during cluster locking, just like any other ocfs2 process.
   */
c4028958b   David Howells   WorkStruct: make ...
1160
  void ocfs2_complete_recovery(struct work_struct *work)
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1161
  {
b41079504   Tao Ma   ocfs2: Remove mas...
1162
  	int ret = 0;
c4028958b   David Howells   WorkStruct: make ...
1163
1164
1165
  	struct ocfs2_journal *journal =
  		container_of(work, struct ocfs2_journal, j_recovery_work);
  	struct ocfs2_super *osb = journal->j_osb;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1166
  	struct ocfs2_dinode *la_dinode, *tl_dinode;
800deef3f   Christoph Hellwig   [PATCH] ocfs2: us...
1167
  	struct ocfs2_la_recovery_item *item, *n;
2205363dc   Jan Kara   ocfs2: Implement ...
1168
  	struct ocfs2_quota_recovery *qrec;
ed460cffc   Joseph Qi   ocfs2: add orphan...
1169
  	enum ocfs2_orphan_reco_type orphan_reco_type;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1170
  	LIST_HEAD(tmp_la_list);
b41079504   Tao Ma   ocfs2: Remove mas...
1171
1172
  	trace_ocfs2_complete_recovery(
  		(unsigned long long)OCFS2_I(journal->j_inode)->ip_blkno);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1173
1174
1175
1176
  
  	spin_lock(&journal->j_lock);
  	list_splice_init(&journal->j_la_cleanups, &tmp_la_list);
  	spin_unlock(&journal->j_lock);
800deef3f   Christoph Hellwig   [PATCH] ocfs2: us...
1177
  	list_for_each_entry_safe(item, n, &tmp_la_list, lri_list) {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1178
  		list_del_init(&item->lri_list);
19ece546a   Jan Kara   ocfs2: Enable quo...
1179
  		ocfs2_wait_on_quotas(osb);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1180
  		la_dinode = item->lri_la_dinode;
b41079504   Tao Ma   ocfs2: Remove mas...
1181
1182
  		tl_dinode = item->lri_tl_dinode;
  		qrec = item->lri_qrec;
ed460cffc   Joseph Qi   ocfs2: add orphan...
1183
  		orphan_reco_type = item->lri_orphan_reco_type;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1184

b41079504   Tao Ma   ocfs2: Remove mas...
1185
1186
1187
1188
1189
1190
  		trace_ocfs2_complete_recovery_slot(item->lri_slot,
  			la_dinode ? le64_to_cpu(la_dinode->i_blkno) : 0,
  			tl_dinode ? le64_to_cpu(tl_dinode->i_blkno) : 0,
  			qrec);
  
  		if (la_dinode) {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1191
1192
1193
1194
1195
1196
1197
  			ret = ocfs2_complete_local_alloc_recovery(osb,
  								  la_dinode);
  			if (ret < 0)
  				mlog_errno(ret);
  
  			kfree(la_dinode);
  		}
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1198
  		if (tl_dinode) {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1199
1200
1201
1202
1203
1204
1205
  			ret = ocfs2_complete_truncate_log_recovery(osb,
  								   tl_dinode);
  			if (ret < 0)
  				mlog_errno(ret);
  
  			kfree(tl_dinode);
  		}
ed460cffc   Joseph Qi   ocfs2: add orphan...
1206
1207
  		ret = ocfs2_recover_orphans(osb, item->lri_slot,
  				orphan_reco_type);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1208
1209
  		if (ret < 0)
  			mlog_errno(ret);
2205363dc   Jan Kara   ocfs2: Implement ...
1210
  		if (qrec) {
2205363dc   Jan Kara   ocfs2: Implement ...
1211
1212
1213
1214
1215
1216
  			ret = ocfs2_finish_quota_recovery(osb, qrec,
  							  item->lri_slot);
  			if (ret < 0)
  				mlog_errno(ret);
  			/* Recovery info is already freed now */
  		}
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1217
1218
  		kfree(item);
  	}
b41079504   Tao Ma   ocfs2: Remove mas...
1219
  	trace_ocfs2_complete_recovery_end(ret);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1220
1221
1222
1223
1224
1225
1226
1227
  }
  
  /* NOTE: This function always eats your references to la_dinode and
   * tl_dinode, either manually on error, or by passing them to
   * ocfs2_complete_recovery */
  static void ocfs2_queue_recovery_completion(struct ocfs2_journal *journal,
  					    int slot_num,
  					    struct ocfs2_dinode *la_dinode,
2205363dc   Jan Kara   ocfs2: Implement ...
1228
  					    struct ocfs2_dinode *tl_dinode,
ed460cffc   Joseph Qi   ocfs2: add orphan...
1229
1230
  					    struct ocfs2_quota_recovery *qrec,
  					    enum ocfs2_orphan_reco_type orphan_reco_type)
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1231
1232
  {
  	struct ocfs2_la_recovery_item *item;
afae00ab4   Sunil Mushran   ocfs2: fix gfp ma...
1233
  	item = kmalloc(sizeof(struct ocfs2_la_recovery_item), GFP_NOFS);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1234
1235
1236
1237
  	if (!item) {
  		/* Though we wish to avoid it, we are in fact safe in
  		 * skipping local alloc cleanup as fsck.ocfs2 is more
  		 * than capable of reclaiming unused space. */
d787ab097   Tim Gardner   ocfs2: remove kfr...
1238
1239
  		kfree(la_dinode);
  		kfree(tl_dinode);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1240

2205363dc   Jan Kara   ocfs2: Implement ...
1241
1242
  		if (qrec)
  			ocfs2_free_quota_recovery(qrec);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1243
1244
1245
1246
1247
1248
1249
1250
  		mlog_errno(-ENOMEM);
  		return;
  	}
  
  	INIT_LIST_HEAD(&item->lri_list);
  	item->lri_la_dinode = la_dinode;
  	item->lri_slot = slot_num;
  	item->lri_tl_dinode = tl_dinode;
2205363dc   Jan Kara   ocfs2: Implement ...
1251
  	item->lri_qrec = qrec;
ed460cffc   Joseph Qi   ocfs2: add orphan...
1252
  	item->lri_orphan_reco_type = orphan_reco_type;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1253
1254
1255
  
  	spin_lock(&journal->j_lock);
  	list_add_tail(&item->lri_list, &journal->j_la_cleanups);
35ddf78e4   jiangyiwen   ocfs2: fix occurr...
1256
  	queue_work(journal->j_osb->ocfs2_wq, &journal->j_recovery_work);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1257
1258
1259
1260
  	spin_unlock(&journal->j_lock);
  }
  
  /* Called by the mount code to queue recovery the last part of
9140db04e   Srinivas Eeda   ocfs2: recover or...
1261
   * recovery for it's own and offline slot(s). */
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1262
1263
1264
  void ocfs2_complete_mount_recovery(struct ocfs2_super *osb)
  {
  	struct ocfs2_journal *journal = osb->journal;
10b3dd761   Sunil Mushran   ocfs2: Skip mount...
1265
1266
  	if (ocfs2_is_hard_readonly(osb))
  		return;
9140db04e   Srinivas Eeda   ocfs2: recover or...
1267
1268
1269
  	/* No need to queue up our truncate_log as regular cleanup will catch
  	 * that */
  	ocfs2_queue_recovery_completion(journal, osb->slot_num,
ed460cffc   Joseph Qi   ocfs2: add orphan...
1270
1271
  					osb->local_alloc_copy, NULL, NULL,
  					ORPHAN_NEED_TRUNCATE);
9140db04e   Srinivas Eeda   ocfs2: recover or...
1272
  	ocfs2_schedule_truncate_log_flush(osb, 0);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1273

9140db04e   Srinivas Eeda   ocfs2: recover or...
1274
  	osb->local_alloc_copy = NULL;
9140db04e   Srinivas Eeda   ocfs2: recover or...
1275
1276
1277
  
  	/* queue to recover orphan slots for all offline slots */
  	ocfs2_replay_map_set_state(osb, REPLAY_NEEDED);
ed460cffc   Joseph Qi   ocfs2: add orphan...
1278
  	ocfs2_queue_replay_slots(osb, ORPHAN_NEED_TRUNCATE);
9140db04e   Srinivas Eeda   ocfs2: recover or...
1279
  	ocfs2_free_replay_slots(osb);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1280
  }
2205363dc   Jan Kara   ocfs2: Implement ...
1281
1282
1283
1284
1285
1286
1287
  void ocfs2_complete_quota_recovery(struct ocfs2_super *osb)
  {
  	if (osb->quota_rec) {
  		ocfs2_queue_recovery_completion(osb->journal,
  						osb->slot_num,
  						NULL,
  						NULL,
ed460cffc   Joseph Qi   ocfs2: add orphan...
1288
1289
  						osb->quota_rec,
  						ORPHAN_NEED_TRUNCATE);
2205363dc   Jan Kara   ocfs2: Implement ...
1290
1291
1292
  		osb->quota_rec = NULL;
  	}
  }
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1293
1294
  static int __ocfs2_recovery_thread(void *arg)
  {
2205363dc   Jan Kara   ocfs2: Implement ...
1295
  	int status, node_num, slot_num;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1296
  	struct ocfs2_super *osb = arg;
553abd046   Joel Becker   ocfs2: Change the...
1297
  	struct ocfs2_recovery_map *rm = osb->recovery_map;
2205363dc   Jan Kara   ocfs2: Implement ...
1298
1299
1300
  	int *rm_quota = NULL;
  	int rm_quota_used = 0, i;
  	struct ocfs2_quota_recovery *qrec;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1301

21158ca85   Guozhonghua   ocfs2: without qu...
1302
1303
1304
1305
1306
  	/* Whether the quota supported. */
  	int quota_enabled = OCFS2_HAS_RO_COMPAT_FEATURE(osb->sb,
  			OCFS2_FEATURE_RO_COMPAT_USRQUOTA)
  		|| OCFS2_HAS_RO_COMPAT_FEATURE(osb->sb,
  			OCFS2_FEATURE_RO_COMPAT_GRPQUOTA);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1307
1308
1309
1310
  	status = ocfs2_wait_on_mount(osb);
  	if (status < 0) {
  		goto bail;
  	}
21158ca85   Guozhonghua   ocfs2: without qu...
1311
1312
1313
1314
1315
1316
  	if (quota_enabled) {
  		rm_quota = kcalloc(osb->max_slots, sizeof(int), GFP_NOFS);
  		if (!rm_quota) {
  			status = -ENOMEM;
  			goto bail;
  		}
2205363dc   Jan Kara   ocfs2: Implement ...
1317
  	}
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1318
1319
1320
1321
1322
1323
  restart:
  	status = ocfs2_super_lock(osb, 1);
  	if (status < 0) {
  		mlog_errno(status);
  		goto bail;
  	}
9140db04e   Srinivas Eeda   ocfs2: recover or...
1324
1325
1326
1327
1328
1329
  	status = ocfs2_compute_replay_slots(osb);
  	if (status < 0)
  		mlog_errno(status);
  
  	/* queue recovery for our own slot */
  	ocfs2_queue_recovery_completion(osb->journal, osb->slot_num, NULL,
ed460cffc   Joseph Qi   ocfs2: add orphan...
1330
  					NULL, NULL, ORPHAN_NO_NEED_TRUNCATE);
9140db04e   Srinivas Eeda   ocfs2: recover or...
1331

553abd046   Joel Becker   ocfs2: Change the...
1332
1333
1334
1335
1336
1337
  	spin_lock(&osb->osb_lock);
  	while (rm->rm_used) {
  		/* It's always safe to remove entry zero, as we won't
  		 * clear it until ocfs2_recover_node() has succeeded. */
  		node_num = rm->rm_entries[0];
  		spin_unlock(&osb->osb_lock);
2205363dc   Jan Kara   ocfs2: Implement ...
1338
  		slot_num = ocfs2_node_num_to_slot(osb, node_num);
b41079504   Tao Ma   ocfs2: Remove mas...
1339
  		trace_ocfs2_recovery_thread_node(node_num, slot_num);
2205363dc   Jan Kara   ocfs2: Implement ...
1340
1341
  		if (slot_num == -ENOENT) {
  			status = 0;
2205363dc   Jan Kara   ocfs2: Implement ...
1342
1343
  			goto skip_recovery;
  		}
2205363dc   Jan Kara   ocfs2: Implement ...
1344
1345
1346
1347
1348
1349
1350
  
  		/* It is a bit subtle with quota recovery. We cannot do it
  		 * immediately because we have to obtain cluster locks from
  		 * quota files and we also don't want to just skip it because
  		 * then quota usage would be out of sync until some node takes
  		 * the slot. So we remember which nodes need quota recovery
  		 * and when everything else is done, we recover quotas. */
21158ca85   Guozhonghua   ocfs2: without qu...
1351
1352
1353
1354
1355
1356
1357
1358
  		if (quota_enabled) {
  			for (i = 0; i < rm_quota_used
  					&& rm_quota[i] != slot_num; i++)
  				;
  
  			if (i == rm_quota_used)
  				rm_quota[rm_quota_used++] = slot_num;
  		}
2205363dc   Jan Kara   ocfs2: Implement ...
1359
1360
1361
  
  		status = ocfs2_recover_node(osb, node_num, slot_num);
  skip_recovery:
553abd046   Joel Becker   ocfs2: Change the...
1362
1363
1364
  		if (!status) {
  			ocfs2_recovery_map_clear(osb, node_num);
  		} else {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1365
1366
1367
1368
1369
1370
1371
  			mlog(ML_ERROR,
  			     "Error %d recovering node %d on device (%u,%u)!
  ",
  			     status, node_num,
  			     MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev));
  			mlog(ML_ERROR, "Volume requires unmount.
  ");
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1372
  		}
553abd046   Joel Becker   ocfs2: Change the...
1373
  		spin_lock(&osb->osb_lock);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1374
  	}
553abd046   Joel Becker   ocfs2: Change the...
1375
  	spin_unlock(&osb->osb_lock);
b41079504   Tao Ma   ocfs2: Remove mas...
1376
  	trace_ocfs2_recovery_thread_end(status);
553abd046   Joel Becker   ocfs2: Change the...
1377

539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
1378
1379
1380
1381
1382
  	/* Refresh all journal recovery generations from disk */
  	status = ocfs2_check_journals_nolocks(osb);
  	status = (status == -EROFS) ? 0 : status;
  	if (status < 0)
  		mlog_errno(status);
2205363dc   Jan Kara   ocfs2: Implement ...
1383
  	/* Now it is right time to recover quotas... We have to do this under
25985edce   Lucas De Marchi   Fix common misspe...
1384
  	 * superblock lock so that no one can start using the slot (and crash)
2205363dc   Jan Kara   ocfs2: Implement ...
1385
  	 * before we recover it */
21158ca85   Guozhonghua   ocfs2: without qu...
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
  	if (quota_enabled) {
  		for (i = 0; i < rm_quota_used; i++) {
  			qrec = ocfs2_begin_quota_recovery(osb, rm_quota[i]);
  			if (IS_ERR(qrec)) {
  				status = PTR_ERR(qrec);
  				mlog_errno(status);
  				continue;
  			}
  			ocfs2_queue_recovery_completion(osb->journal,
  					rm_quota[i],
  					NULL, NULL, qrec,
  					ORPHAN_NEED_TRUNCATE);
2205363dc   Jan Kara   ocfs2: Implement ...
1398
  		}
2205363dc   Jan Kara   ocfs2: Implement ...
1399
  	}
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1400
  	ocfs2_super_unlock(osb, 1);
9140db04e   Srinivas Eeda   ocfs2: recover or...
1401
  	/* queue recovery for offline slots */
ed460cffc   Joseph Qi   ocfs2: add orphan...
1402
  	ocfs2_queue_replay_slots(osb, ORPHAN_NEED_TRUNCATE);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1403
1404
  
  bail:
c74ec2f77   Arjan van de Ven   [PATCH] ocfs2: Se...
1405
  	mutex_lock(&osb->recovery_lock);
553abd046   Joel Becker   ocfs2: Change the...
1406
  	if (!status && !ocfs2_recovery_completed(osb)) {
c74ec2f77   Arjan van de Ven   [PATCH] ocfs2: Se...
1407
  		mutex_unlock(&osb->recovery_lock);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1408
1409
  		goto restart;
  	}
9140db04e   Srinivas Eeda   ocfs2: recover or...
1410
  	ocfs2_free_replay_slots(osb);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1411
1412
1413
  	osb->recovery_thread_task = NULL;
  	mb(); /* sync with ocfs2_recovery_thread_running */
  	wake_up(&osb->recovery_event);
c74ec2f77   Arjan van de Ven   [PATCH] ocfs2: Se...
1414
  	mutex_unlock(&osb->recovery_lock);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1415

21158ca85   Guozhonghua   ocfs2: without qu...
1416
1417
  	if (quota_enabled)
  		kfree(rm_quota);
2205363dc   Jan Kara   ocfs2: Implement ...
1418

ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1419
1420
1421
1422
  	/* no one is callint kthread_stop() for us so the kthread() api
  	 * requires that we call do_exit().  And it isn't exported, but
  	 * complete_and_exit() seems to be a minimal wrapper around it. */
  	complete_and_exit(NULL, status);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1423
1424
1425
1426
  }
  
  void ocfs2_recovery_thread(struct ocfs2_super *osb, int node_num)
  {
c74ec2f77   Arjan van de Ven   [PATCH] ocfs2: Se...
1427
  	mutex_lock(&osb->recovery_lock);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1428

b41079504   Tao Ma   ocfs2: Remove mas...
1429
1430
1431
1432
  	trace_ocfs2_recovery_thread(node_num, osb->node_num,
  		osb->disable_recovery, osb->recovery_thread_task,
  		osb->disable_recovery ?
  		-1 : ocfs2_recovery_map_set(osb, node_num));
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1433

b41079504   Tao Ma   ocfs2: Remove mas...
1434
1435
  	if (osb->disable_recovery)
  		goto out;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1436
1437
1438
1439
1440
  
  	if (osb->recovery_thread_task)
  		goto out;
  
  	osb->recovery_thread_task =  kthread_run(__ocfs2_recovery_thread, osb,
5afc44e2e   Joseph Qi   ocfs2: add uuid t...
1441
  			"ocfs2rec-%s", osb->uuid_str);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1442
1443
1444
1445
1446
1447
  	if (IS_ERR(osb->recovery_thread_task)) {
  		mlog_errno((int)PTR_ERR(osb->recovery_thread_task));
  		osb->recovery_thread_task = NULL;
  	}
  
  out:
c74ec2f77   Arjan van de Ven   [PATCH] ocfs2: Se...
1448
  	mutex_unlock(&osb->recovery_lock);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1449
  	wake_up(&osb->recovery_event);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1450
  }
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
  static int ocfs2_read_journal_inode(struct ocfs2_super *osb,
  				    int slot_num,
  				    struct buffer_head **bh,
  				    struct inode **ret_inode)
  {
  	int status = -EACCES;
  	struct inode *inode = NULL;
  
  	BUG_ON(slot_num >= osb->max_slots);
  
  	inode = ocfs2_get_system_file_inode(osb, JOURNAL_SYSTEM_INODE,
  					    slot_num);
  	if (!inode || is_bad_inode(inode)) {
  		mlog_errno(status);
  		goto bail;
  	}
  	SET_INODE_JOURNAL(inode);
b657c95c1   Joel Becker   ocfs2: Wrap inode...
1468
  	status = ocfs2_read_inode_block_full(inode, bh, OCFS2_BH_IGNORE_CACHE);
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
  	if (status < 0) {
  		mlog_errno(status);
  		goto bail;
  	}
  
  	status = 0;
  
  bail:
  	if (inode) {
  		if (status || !ret_inode)
  			iput(inode);
  		else
  			*ret_inode = inode;
  	}
  	return status;
  }
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
  /* Does the actual journal replay and marks the journal inode as
   * clean. Will only replay if the journal inode is marked dirty. */
  static int ocfs2_replay_journal(struct ocfs2_super *osb,
  				int node_num,
  				int slot_num)
  {
  	int status;
  	int got_lock = 0;
  	unsigned int flags;
  	struct inode *inode = NULL;
  	struct ocfs2_dinode *fe;
  	journal_t *journal = NULL;
  	struct buffer_head *bh = NULL;
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
1498
  	u32 slot_reco_gen;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1499

539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
1500
1501
  	status = ocfs2_read_journal_inode(osb, slot_num, &bh, &inode);
  	if (status) {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1502
1503
1504
  		mlog_errno(status);
  		goto done;
  	}
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
  
  	fe = (struct ocfs2_dinode *)bh->b_data;
  	slot_reco_gen = ocfs2_get_recovery_generation(fe);
  	brelse(bh);
  	bh = NULL;
  
  	/*
  	 * As the fs recovery is asynchronous, there is a small chance that
  	 * another node mounted (and recovered) the slot before the recovery
  	 * thread could get the lock. To handle that, we dirty read the journal
  	 * inode for that slot to get the recovery generation. If it is
  	 * different than what we expected, the slot has been recovered.
  	 * If not, it needs recovery.
  	 */
  	if (osb->slot_recovery_generations[slot_num] != slot_reco_gen) {
b41079504   Tao Ma   ocfs2: Remove mas...
1520
  		trace_ocfs2_replay_journal_recovered(slot_num,
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
1521
1522
1523
  		     osb->slot_recovery_generations[slot_num], slot_reco_gen);
  		osb->slot_recovery_generations[slot_num] = slot_reco_gen;
  		status = -EBUSY;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1524
1525
  		goto done;
  	}
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
1526
1527
  
  	/* Continue with recovery as the journal has not yet been recovered */
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1528

e63aecb65   Mark Fasheh   ocfs2: Rename ocf...
1529
  	status = ocfs2_inode_lock_full(inode, &bh, 1, OCFS2_META_LOCK_RECOVERY);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1530
  	if (status < 0) {
b41079504   Tao Ma   ocfs2: Remove mas...
1531
  		trace_ocfs2_replay_journal_lock_err(status);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
  		if (status != -ERESTARTSYS)
  			mlog(ML_ERROR, "Could not lock journal!
  ");
  		goto done;
  	}
  	got_lock = 1;
  
  	fe = (struct ocfs2_dinode *) bh->b_data;
  
  	flags = le32_to_cpu(fe->id1.journal1.ij_flags);
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
1542
  	slot_reco_gen = ocfs2_get_recovery_generation(fe);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1543
1544
  
  	if (!(flags & OCFS2_JOURNAL_DIRTY_FL)) {
b41079504   Tao Ma   ocfs2: Remove mas...
1545
  		trace_ocfs2_replay_journal_skip(node_num);
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
1546
1547
  		/* Refresh recovery generation for the slot */
  		osb->slot_recovery_generations[slot_num] = slot_reco_gen;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1548
1549
  		goto done;
  	}
9140db04e   Srinivas Eeda   ocfs2: recover or...
1550
1551
  	/* we need to run complete recovery for offline orphan slots */
  	ocfs2_replay_map_set_state(osb, REPLAY_NEEDED);
619c200de   Sunil Mushran   ocfs2: Clean up m...
1552
1553
1554
1555
  	printk(KERN_NOTICE "ocfs2: Begin replay journal (node %d, slot %d) on "\
  	       "device (%u,%u)
  ", node_num, slot_num, MAJOR(osb->sb->s_dev),
  	       MINOR(osb->sb->s_dev));
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1556
1557
1558
1559
1560
1561
1562
1563
  
  	OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
  
  	status = ocfs2_force_read_journal(inode);
  	if (status < 0) {
  		mlog_errno(status);
  		goto done;
  	}
2b4e30fbd   Joel Becker   ocfs2: Switch ove...
1564
  	journal = jbd2_journal_init_inode(inode);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1565
1566
1567
1568
1569
1570
  	if (journal == NULL) {
  		mlog(ML_ERROR, "Linux journal layer error
  ");
  		status = -EIO;
  		goto done;
  	}
2b4e30fbd   Joel Becker   ocfs2: Switch ove...
1571
  	status = jbd2_journal_load(journal);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1572
1573
1574
1575
  	if (status < 0) {
  		mlog_errno(status);
  		if (!igrab(inode))
  			BUG();
2b4e30fbd   Joel Becker   ocfs2: Switch ove...
1576
  		jbd2_journal_destroy(journal);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1577
1578
1579
1580
1581
1582
  		goto done;
  	}
  
  	ocfs2_clear_journal_error(osb->sb, journal, slot_num);
  
  	/* wipe the journal */
2b4e30fbd   Joel Becker   ocfs2: Switch ove...
1583
1584
1585
  	jbd2_journal_lock_updates(journal);
  	status = jbd2_journal_flush(journal);
  	jbd2_journal_unlock_updates(journal);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1586
1587
1588
1589
1590
1591
1592
  	if (status < 0)
  		mlog_errno(status);
  
  	/* This will mark the node clean */
  	flags = le32_to_cpu(fe->id1.journal1.ij_flags);
  	flags &= ~OCFS2_JOURNAL_DIRTY_FL;
  	fe->id1.journal1.ij_flags = cpu_to_le32(flags);
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
1593
1594
1595
1596
  	/* Increment recovery generation to indicate successful recovery */
  	ocfs2_bump_recovery_generation(fe);
  	osb->slot_recovery_generations[slot_num] =
  					ocfs2_get_recovery_generation(fe);
13723d00e   Joel Becker   ocfs2: Use metada...
1597
  	ocfs2_compute_meta_ecc(osb->sb, bh->b_data, &fe->i_check);
8cb471e8f   Joel Becker   ocfs2: Take the i...
1598
  	status = ocfs2_write_block(osb, bh, INODE_CACHE(inode));
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1599
1600
1601
1602
1603
  	if (status < 0)
  		mlog_errno(status);
  
  	if (!igrab(inode))
  		BUG();
2b4e30fbd   Joel Becker   ocfs2: Switch ove...
1604
  	jbd2_journal_destroy(journal);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1605

619c200de   Sunil Mushran   ocfs2: Clean up m...
1606
1607
1608
1609
  	printk(KERN_NOTICE "ocfs2: End replay journal (node %d, slot %d) on "\
  	       "device (%u,%u)
  ", node_num, slot_num, MAJOR(osb->sb->s_dev),
  	       MINOR(osb->sb->s_dev));
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1610
1611
1612
  done:
  	/* drop the lock on this nodes journal */
  	if (got_lock)
e63aecb65   Mark Fasheh   ocfs2: Rename ocf...
1613
  		ocfs2_inode_unlock(inode, 1);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1614

72865d923   Joseph Qi   ocfs2: clean up r...
1615
  	iput(inode);
a81cb88b6   Mark Fasheh   ocfs2: Don't chec...
1616
  	brelse(bh);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1617

ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
  	return status;
  }
  
  /*
   * Do the most important parts of node recovery:
   *  - Replay it's journal
   *  - Stamp a clean local allocator file
   *  - Stamp a clean truncate log
   *  - Mark the node clean
   *
   * If this function completes without error, a node in OCFS2 can be
   * said to have been safely recovered. As a result, failure during the
   * second part of a nodes recovery process (local alloc recovery) is
   * far less concerning.
   */
  static int ocfs2_recover_node(struct ocfs2_super *osb,
2205363dc   Jan Kara   ocfs2: Implement ...
1634
  			      int node_num, int slot_num)
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1635
1636
  {
  	int status = 0;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1637
1638
  	struct ocfs2_dinode *la_copy = NULL;
  	struct ocfs2_dinode *tl_copy = NULL;
b41079504   Tao Ma   ocfs2: Remove mas...
1639
  	trace_ocfs2_recover_node(node_num, slot_num, osb->node_num);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1640
1641
1642
  
  	/* Should not ever be called to recover ourselves -- in that
  	 * case we should've called ocfs2_journal_load instead. */
ebdec83ba   Eric Sesterhenn / snakebyte   [PATCH] BUG_ON() ...
1643
  	BUG_ON(osb->node_num == node_num);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1644

ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1645
1646
  	status = ocfs2_replay_journal(osb, node_num, slot_num);
  	if (status < 0) {
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
1647
  		if (status == -EBUSY) {
b41079504   Tao Ma   ocfs2: Remove mas...
1648
  			trace_ocfs2_recover_node_skip(slot_num, node_num);
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
1649
1650
1651
  			status = 0;
  			goto done;
  		}
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
  		mlog_errno(status);
  		goto done;
  	}
  
  	/* Stamp a clean local alloc file AFTER recovering the journal... */
  	status = ocfs2_begin_local_alloc_recovery(osb, slot_num, &la_copy);
  	if (status < 0) {
  		mlog_errno(status);
  		goto done;
  	}
  
  	/* An error from begin_truncate_log_recovery is not
  	 * serious enough to warrant halting the rest of
  	 * recovery. */
  	status = ocfs2_begin_truncate_log_recovery(osb, slot_num, &tl_copy);
  	if (status < 0)
  		mlog_errno(status);
  
  	/* Likewise, this would be a strange but ultimately not so
  	 * harmful place to get an error... */
8e8a4603b   Mark Fasheh   ocfs2: Move slot ...
1672
  	status = ocfs2_clear_slot(osb, slot_num);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1673
1674
1675
1676
1677
  	if (status < 0)
  		mlog_errno(status);
  
  	/* This will kfree the memory pointed to by la_copy and tl_copy */
  	ocfs2_queue_recovery_completion(osb->journal, slot_num, la_copy,
ed460cffc   Joseph Qi   ocfs2: add orphan...
1678
  					tl_copy, NULL, ORPHAN_NEED_TRUNCATE);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1679
1680
1681
  
  	status = 0;
  done:
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
  	return status;
  }
  
  /* Test node liveness by trylocking his journal. If we get the lock,
   * we drop it here. Return 0 if we got the lock, -EAGAIN if node is
   * still alive (we couldn't get the lock) and < 0 on error. */
  static int ocfs2_trylock_journal(struct ocfs2_super *osb,
  				 int slot_num)
  {
  	int status, flags;
  	struct inode *inode = NULL;
  
  	inode = ocfs2_get_system_file_inode(osb, JOURNAL_SYSTEM_INODE,
  					    slot_num);
  	if (inode == NULL) {
  		mlog(ML_ERROR, "access error
  ");
  		status = -EACCES;
  		goto bail;
  	}
  	if (is_bad_inode(inode)) {
  		mlog(ML_ERROR, "access error (bad inode)
  ");
  		iput(inode);
  		inode = NULL;
  		status = -EACCES;
  		goto bail;
  	}
  	SET_INODE_JOURNAL(inode);
  
  	flags = OCFS2_META_LOCK_RECOVERY | OCFS2_META_LOCK_NOQUEUE;
e63aecb65   Mark Fasheh   ocfs2: Rename ocf...
1713
  	status = ocfs2_inode_lock_full(inode, NULL, 1, flags);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1714
1715
1716
1717
1718
  	if (status < 0) {
  		if (status != -EAGAIN)
  			mlog_errno(status);
  		goto bail;
  	}
e63aecb65   Mark Fasheh   ocfs2: Rename ocf...
1719
  	ocfs2_inode_unlock(inode, 1);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1720
  bail:
72865d923   Joseph Qi   ocfs2: clean up r...
1721
  	iput(inode);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1722
1723
1724
1725
1726
1727
1728
1729
  
  	return status;
  }
  
  /* Call this underneath ocfs2_super_lock. It also assumes that the
   * slot info struct has been updated from disk. */
  int ocfs2_mark_dead_nodes(struct ocfs2_super *osb)
  {
d85b20e4b   Joel Becker   ocfs2: Make ocfs2...
1730
1731
  	unsigned int node_num;
  	int status, i;
a1af7d15a   Mark Fasheh   ocfs2: Fix sleep-...
1732
  	u32 gen;
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
1733
1734
  	struct buffer_head *bh = NULL;
  	struct ocfs2_dinode *di;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1735
1736
1737
  
  	/* This is called with the super block cluster lock, so we
  	 * know that the slot map can't change underneath us. */
d85b20e4b   Joel Becker   ocfs2: Make ocfs2...
1738
  	for (i = 0; i < osb->max_slots; i++) {
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
1739
1740
1741
1742
1743
1744
1745
  		/* Read journal inode to get the recovery generation */
  		status = ocfs2_read_journal_inode(osb, i, &bh, NULL);
  		if (status) {
  			mlog_errno(status);
  			goto bail;
  		}
  		di = (struct ocfs2_dinode *)bh->b_data;
a1af7d15a   Mark Fasheh   ocfs2: Fix sleep-...
1746
  		gen = ocfs2_get_recovery_generation(di);
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
1747
1748
  		brelse(bh);
  		bh = NULL;
a1af7d15a   Mark Fasheh   ocfs2: Fix sleep-...
1749
1750
  		spin_lock(&osb->osb_lock);
  		osb->slot_recovery_generations[i] = gen;
b41079504   Tao Ma   ocfs2: Remove mas...
1751
1752
  		trace_ocfs2_mark_dead_nodes(i,
  					    osb->slot_recovery_generations[i]);
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
1753

a1af7d15a   Mark Fasheh   ocfs2: Fix sleep-...
1754
1755
  		if (i == osb->slot_num) {
  			spin_unlock(&osb->osb_lock);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1756
  			continue;
a1af7d15a   Mark Fasheh   ocfs2: Fix sleep-...
1757
  		}
d85b20e4b   Joel Becker   ocfs2: Make ocfs2...
1758
1759
  
  		status = ocfs2_slot_to_node_num_locked(osb, i, &node_num);
a1af7d15a   Mark Fasheh   ocfs2: Fix sleep-...
1760
1761
  		if (status == -ENOENT) {
  			spin_unlock(&osb->osb_lock);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1762
  			continue;
a1af7d15a   Mark Fasheh   ocfs2: Fix sleep-...
1763
  		}
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1764

a1af7d15a   Mark Fasheh   ocfs2: Fix sleep-...
1765
1766
  		if (__ocfs2_recovery_map_test(osb, node_num)) {
  			spin_unlock(&osb->osb_lock);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1767
  			continue;
a1af7d15a   Mark Fasheh   ocfs2: Fix sleep-...
1768
  		}
d85b20e4b   Joel Becker   ocfs2: Make ocfs2...
1769
  		spin_unlock(&osb->osb_lock);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
  
  		/* Ok, we have a slot occupied by another node which
  		 * is not in the recovery map. We trylock his journal
  		 * file here to test if he's alive. */
  		status = ocfs2_trylock_journal(osb, i);
  		if (!status) {
  			/* Since we're called from mount, we know that
  			 * the recovery thread can't race us on
  			 * setting / checking the recovery bits. */
  			ocfs2_recovery_thread(osb, node_num);
  		} else if ((status < 0) && (status != -EAGAIN)) {
  			mlog_errno(status);
  			goto bail;
  		}
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1784
  	}
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1785
1786
1787
  
  	status = 0;
  bail:
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1788
1789
  	return status;
  }
83273932f   Srinivas Eeda   ocfs2: timer to q...
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
  /*
   * Scan timer should get fired every ORPHAN_SCAN_SCHEDULE_TIMEOUT. Add some
   * randomness to the timeout to minimize multple nodes firing the timer at the
   * same time.
   */
  static inline unsigned long ocfs2_orphan_scan_timeout(void)
  {
  	unsigned long time;
  
  	get_random_bytes(&time, sizeof(time));
  	time = ORPHAN_SCAN_SCHEDULE_TIMEOUT + (time % 5000);
  	return msecs_to_jiffies(time);
  }
  
  /*
   * ocfs2_queue_orphan_scan calls ocfs2_queue_recovery_completion for
   * every slot, queuing a recovery of the slot on the ocfs2_wq thread. This
   * is done to catch any orphans that are left over in orphan directories.
   *
a035bff6b   Sunil Mushran   ocfs2: Add commen...
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
   * It scans all slots, even ones that are in use. It does so to handle the
   * case described below:
   *
   *   Node 1 has an inode it was using. The dentry went away due to memory
   *   pressure.  Node 1 closes the inode, but it's on the free list. The node
   *   has the open lock.
   *   Node 2 unlinks the inode. It grabs the dentry lock to notify others,
   *   but node 1 has no dentry and doesn't get the message. It trylocks the
   *   open lock, sees that another node has a PR, and does nothing.
   *   Later node 2 runs its orphan dir. It igets the inode, trylocks the
   *   open lock, sees the PR still, and does nothing.
   *   Basically, we have to trigger an orphan iput on node 1. The only way
   *   for this to happen is if node 1 runs node 2's orphan dir.
   *
83273932f   Srinivas Eeda   ocfs2: timer to q...
1823
1824
1825
1826
1827
1828
1829
1830
   * ocfs2_queue_orphan_scan gets called every ORPHAN_SCAN_SCHEDULE_TIMEOUT
   * seconds.  It gets an EX lock on os_lockres and checks sequence number
   * stored in LVB. If the sequence number has changed, it means some other
   * node has done the scan.  This node skips the scan and tracks the
   * sequence number.  If the sequence number didn't change, it means a scan
   * hasn't happened.  The node queues a scan and increments the
   * sequence number in the LVB.
   */
b519ea6d9   Joseph Qi   ocfs2: mark local...
1831
  static void ocfs2_queue_orphan_scan(struct ocfs2_super *osb)
83273932f   Srinivas Eeda   ocfs2: timer to q...
1832
1833
1834
1835
1836
1837
  {
  	struct ocfs2_orphan_scan *os;
  	int status, i;
  	u32 seqno = 0;
  
  	os = &osb->osb_orphan_scan;
692684e19   Sunil Mushran   ocfs2: Stop orpha...
1838
1839
  	if (atomic_read(&os->os_state) == ORPHAN_SCAN_INACTIVE)
  		goto out;
b41079504   Tao Ma   ocfs2: Remove mas...
1840
1841
  	trace_ocfs2_queue_orphan_scan_begin(os->os_count, os->os_seqno,
  					    atomic_read(&os->os_state));
df152c241   Sunil Mushran   ocfs2: Disable or...
1842
  	status = ocfs2_orphan_scan_lock(osb, &seqno);
83273932f   Srinivas Eeda   ocfs2: timer to q...
1843
1844
1845
1846
1847
  	if (status < 0) {
  		if (status != -EAGAIN)
  			mlog_errno(status);
  		goto out;
  	}
692684e19   Sunil Mushran   ocfs2: Stop orpha...
1848
1849
1850
  	/* Do no queue the tasks if the volume is being umounted */
  	if (atomic_read(&os->os_state) == ORPHAN_SCAN_INACTIVE)
  		goto unlock;
83273932f   Srinivas Eeda   ocfs2: timer to q...
1851
1852
1853
1854
1855
1856
1857
  	if (os->os_seqno != seqno) {
  		os->os_seqno = seqno;
  		goto unlock;
  	}
  
  	for (i = 0; i < osb->max_slots; i++)
  		ocfs2_queue_recovery_completion(osb->journal, i, NULL, NULL,
ed460cffc   Joseph Qi   ocfs2: add orphan...
1858
  						NULL, ORPHAN_NO_NEED_TRUNCATE);
83273932f   Srinivas Eeda   ocfs2: timer to q...
1859
1860
1861
1862
1863
  	/*
  	 * We queued a recovery on orphan slots, increment the sequence
  	 * number and update LVB so other node will skip the scan for a while
  	 */
  	seqno++;
15633a220   Srinivas Eeda   ocfs2 patch to tr...
1864
  	os->os_count++;
395627b07   Deepa Dinamani   ocfs2: use time64...
1865
  	os->os_scantime = ktime_get_seconds();
83273932f   Srinivas Eeda   ocfs2: timer to q...
1866
  unlock:
df152c241   Sunil Mushran   ocfs2: Disable or...
1867
  	ocfs2_orphan_scan_unlock(osb, seqno);
83273932f   Srinivas Eeda   ocfs2: timer to q...
1868
  out:
b41079504   Tao Ma   ocfs2: Remove mas...
1869
1870
  	trace_ocfs2_queue_orphan_scan_end(os->os_count, os->os_seqno,
  					  atomic_read(&os->os_state));
83273932f   Srinivas Eeda   ocfs2: timer to q...
1871
1872
1873
1874
  	return;
  }
  
  /* Worker task that gets fired every ORPHAN_SCAN_SCHEDULE_TIMEOUT millsec */
b519ea6d9   Joseph Qi   ocfs2: mark local...
1875
  static void ocfs2_orphan_scan_work(struct work_struct *work)
83273932f   Srinivas Eeda   ocfs2: timer to q...
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
  {
  	struct ocfs2_orphan_scan *os;
  	struct ocfs2_super *osb;
  
  	os = container_of(work, struct ocfs2_orphan_scan,
  			  os_orphan_scan_work.work);
  	osb = os->os_osb;
  
  	mutex_lock(&os->os_lock);
  	ocfs2_queue_orphan_scan(osb);
692684e19   Sunil Mushran   ocfs2: Stop orpha...
1886
  	if (atomic_read(&os->os_state) == ORPHAN_SCAN_ACTIVE)
35ddf78e4   jiangyiwen   ocfs2: fix occurr...
1887
  		queue_delayed_work(osb->ocfs2_wq, &os->os_orphan_scan_work,
692684e19   Sunil Mushran   ocfs2: Stop orpha...
1888
  				      ocfs2_orphan_scan_timeout());
83273932f   Srinivas Eeda   ocfs2: timer to q...
1889
1890
1891
1892
1893
1894
1895
1896
  	mutex_unlock(&os->os_lock);
  }
  
  void ocfs2_orphan_scan_stop(struct ocfs2_super *osb)
  {
  	struct ocfs2_orphan_scan *os;
  
  	os = &osb->osb_orphan_scan;
df152c241   Sunil Mushran   ocfs2: Disable or...
1897
1898
1899
1900
1901
1902
  	if (atomic_read(&os->os_state) == ORPHAN_SCAN_ACTIVE) {
  		atomic_set(&os->os_state, ORPHAN_SCAN_INACTIVE);
  		mutex_lock(&os->os_lock);
  		cancel_delayed_work(&os->os_orphan_scan_work);
  		mutex_unlock(&os->os_lock);
  	}
83273932f   Srinivas Eeda   ocfs2: timer to q...
1903
  }
df152c241   Sunil Mushran   ocfs2: Disable or...
1904
  void ocfs2_orphan_scan_init(struct ocfs2_super *osb)
83273932f   Srinivas Eeda   ocfs2: timer to q...
1905
1906
1907
1908
1909
  {
  	struct ocfs2_orphan_scan *os;
  
  	os = &osb->osb_orphan_scan;
  	os->os_osb = osb;
15633a220   Srinivas Eeda   ocfs2 patch to tr...
1910
  	os->os_count = 0;
3211949f8   Sunil Mushran   ocfs2: Do not ini...
1911
  	os->os_seqno = 0;
83273932f   Srinivas Eeda   ocfs2: timer to q...
1912
  	mutex_init(&os->os_lock);
df152c241   Sunil Mushran   ocfs2: Disable or...
1913
  	INIT_DELAYED_WORK(&os->os_orphan_scan_work, ocfs2_orphan_scan_work);
8b712cd58   Jeff Mahoney   ocfs2: Fixup orph...
1914
  }
83273932f   Srinivas Eeda   ocfs2: timer to q...
1915

8b712cd58   Jeff Mahoney   ocfs2: Fixup orph...
1916
1917
1918
1919
1920
  void ocfs2_orphan_scan_start(struct ocfs2_super *osb)
  {
  	struct ocfs2_orphan_scan *os;
  
  	os = &osb->osb_orphan_scan;
395627b07   Deepa Dinamani   ocfs2: use time64...
1921
  	os->os_scantime = ktime_get_seconds();
df152c241   Sunil Mushran   ocfs2: Disable or...
1922
1923
1924
1925
  	if (ocfs2_is_hard_readonly(osb) || ocfs2_mount_local(osb))
  		atomic_set(&os->os_state, ORPHAN_SCAN_INACTIVE);
  	else {
  		atomic_set(&os->os_state, ORPHAN_SCAN_ACTIVE);
35ddf78e4   jiangyiwen   ocfs2: fix occurr...
1926
  		queue_delayed_work(osb->ocfs2_wq, &os->os_orphan_scan_work,
40f165f41   Tao Ma   ocfs2: Move orpha...
1927
  				   ocfs2_orphan_scan_timeout());
df152c241   Sunil Mushran   ocfs2: Disable or...
1928
  	}
83273932f   Srinivas Eeda   ocfs2: timer to q...
1929
  }
5eae5b96f   Mark Fasheh   ocfs2: Remove ope...
1930
  struct ocfs2_orphan_filldir_priv {
3704412bd   Al Viro   [readdir] convert...
1931
  	struct dir_context	ctx;
5eae5b96f   Mark Fasheh   ocfs2: Remove ope...
1932
1933
  	struct inode		*head;
  	struct ocfs2_super	*osb;
30edc43c7   Joseph Qi   ocfs2: do not inc...
1934
  	enum ocfs2_orphan_reco_type orphan_reco_type;
5eae5b96f   Mark Fasheh   ocfs2: Remove ope...
1935
  };
ac7576f4b   Miklos Szeredi   vfs: make first a...
1936
1937
1938
  static int ocfs2_orphan_filldir(struct dir_context *ctx, const char *name,
  				int name_len, loff_t pos, u64 ino,
  				unsigned type)
5eae5b96f   Mark Fasheh   ocfs2: Remove ope...
1939
  {
ac7576f4b   Miklos Szeredi   vfs: make first a...
1940
1941
  	struct ocfs2_orphan_filldir_priv *p =
  		container_of(ctx, struct ocfs2_orphan_filldir_priv, ctx);
5eae5b96f   Mark Fasheh   ocfs2: Remove ope...
1942
1943
1944
1945
1946
1947
  	struct inode *iter;
  
  	if (name_len == 1 && !strncmp(".", name, 1))
  		return 0;
  	if (name_len == 2 && !strncmp("..", name, 2))
  		return 0;
30edc43c7   Joseph Qi   ocfs2: do not inc...
1948
1949
1950
1951
1952
  	/* do not include dio entry in case of orphan scan */
  	if ((p->orphan_reco_type == ORPHAN_NO_NEED_TRUNCATE) &&
  			(!strncmp(name, OCFS2_DIO_ORPHAN_PREFIX,
  			OCFS2_DIO_ORPHAN_PREFIX_LEN)))
  		return 0;
5eae5b96f   Mark Fasheh   ocfs2: Remove ope...
1953
1954
  	/* Skip bad inodes so that recovery can continue */
  	iter = ocfs2_iget(p->osb, ino,
5fa0613ea   Jan Kara   ocfs2: Silence fa...
1955
  			  OCFS2_FI_FLAG_ORPHAN_RECOVERY, 0);
5eae5b96f   Mark Fasheh   ocfs2: Remove ope...
1956
1957
  	if (IS_ERR(iter))
  		return 0;
93d911fcc   Joseph Qi   ocfs2: only take ...
1958
1959
1960
  	if (!strncmp(name, OCFS2_DIO_ORPHAN_PREFIX,
  			OCFS2_DIO_ORPHAN_PREFIX_LEN))
  		OCFS2_I(iter)->ip_flags |= OCFS2_INODE_DIO_ORPHAN_ENTRY;
ed460cffc   Joseph Qi   ocfs2: add orphan...
1961
1962
1963
1964
1965
1966
  	/* Skip inodes which are already added to recover list, since dio may
  	 * happen concurrently with unlink/rename */
  	if (OCFS2_I(iter)->ip_next_orphan) {
  		iput(iter);
  		return 0;
  	}
b41079504   Tao Ma   ocfs2: Remove mas...
1967
  	trace_ocfs2_orphan_filldir((unsigned long long)OCFS2_I(iter)->ip_blkno);
5eae5b96f   Mark Fasheh   ocfs2: Remove ope...
1968
1969
1970
1971
1972
1973
1974
  	/* No locking is required for the next_orphan queue as there
  	 * is only ever a single process doing orphan recovery. */
  	OCFS2_I(iter)->ip_next_orphan = p->head;
  	p->head = iter;
  
  	return 0;
  }
b4df6ed8d   Mark Fasheh   [PATCH] ocfs2: fi...
1975
1976
  static int ocfs2_queue_orphans(struct ocfs2_super *osb,
  			       int slot,
30edc43c7   Joseph Qi   ocfs2: do not inc...
1977
1978
  			       struct inode **head,
  			       enum ocfs2_orphan_reco_type orphan_reco_type)
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1979
  {
b4df6ed8d   Mark Fasheh   [PATCH] ocfs2: fi...
1980
  	int status;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1981
  	struct inode *orphan_dir_inode = NULL;
3704412bd   Al Viro   [readdir] convert...
1982
1983
1984
  	struct ocfs2_orphan_filldir_priv priv = {
  		.ctx.actor = ocfs2_orphan_filldir,
  		.osb = osb,
30edc43c7   Joseph Qi   ocfs2: do not inc...
1985
1986
  		.head = *head,
  		.orphan_reco_type = orphan_reco_type
3704412bd   Al Viro   [readdir] convert...
1987
  	};
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1988
1989
1990
1991
1992
1993
1994
  
  	orphan_dir_inode = ocfs2_get_system_file_inode(osb,
  						       ORPHAN_DIR_SYSTEM_INODE,
  						       slot);
  	if  (!orphan_dir_inode) {
  		status = -ENOENT;
  		mlog_errno(status);
b4df6ed8d   Mark Fasheh   [PATCH] ocfs2: fi...
1995
  		return status;
2bd632165   Sunil Mushran   ocfs2/trivial: Re...
1996
  	}
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1997

5955102c9   Al Viro   wrappers for ->i_...
1998
  	inode_lock(orphan_dir_inode);
e63aecb65   Mark Fasheh   ocfs2: Rename ocf...
1999
  	status = ocfs2_inode_lock(orphan_dir_inode, NULL, 0);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2000
  	if (status < 0) {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2001
2002
2003
  		mlog_errno(status);
  		goto out;
  	}
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2004

3704412bd   Al Viro   [readdir] convert...
2005
  	status = ocfs2_dir_foreach(orphan_dir_inode, &priv.ctx);
5eae5b96f   Mark Fasheh   ocfs2: Remove ope...
2006
2007
  	if (status) {
  		mlog_errno(status);
a86370fbb   Mark Fasheh   ocfs2: fix exit-w...
2008
  		goto out_cluster;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2009
  	}
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2010

5eae5b96f   Mark Fasheh   ocfs2: Remove ope...
2011
  	*head = priv.head;
a86370fbb   Mark Fasheh   ocfs2: fix exit-w...
2012
  out_cluster:
e63aecb65   Mark Fasheh   ocfs2: Rename ocf...
2013
  	ocfs2_inode_unlock(orphan_dir_inode, 0);
b4df6ed8d   Mark Fasheh   [PATCH] ocfs2: fi...
2014
  out:
5955102c9   Al Viro   wrappers for ->i_...
2015
  	inode_unlock(orphan_dir_inode);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2016
  	iput(orphan_dir_inode);
b4df6ed8d   Mark Fasheh   [PATCH] ocfs2: fi...
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
  	return status;
  }
  
  static int ocfs2_orphan_recovery_can_continue(struct ocfs2_super *osb,
  					      int slot)
  {
  	int ret;
  
  	spin_lock(&osb->osb_lock);
  	ret = !osb->osb_orphan_wipes[slot];
  	spin_unlock(&osb->osb_lock);
  	return ret;
  }
  
  static void ocfs2_mark_recovering_orphan_dir(struct ocfs2_super *osb,
  					     int slot)
  {
  	spin_lock(&osb->osb_lock);
  	/* Mark ourselves such that new processes in delete_inode()
  	 * know to quit early. */
  	ocfs2_node_map_set_bit(osb, &osb->osb_recovering_orphan_dirs, slot);
  	while (osb->osb_orphan_wipes[slot]) {
  		/* If any processes are already in the middle of an
  		 * orphan wipe on this dir, then we need to wait for
  		 * them. */
  		spin_unlock(&osb->osb_lock);
  		wait_event_interruptible(osb->osb_wipe_event,
  					 ocfs2_orphan_recovery_can_continue(osb, slot));
  		spin_lock(&osb->osb_lock);
  	}
  	spin_unlock(&osb->osb_lock);
  }
  
  static void ocfs2_clear_recovering_orphan_dir(struct ocfs2_super *osb,
  					      int slot)
  {
  	ocfs2_node_map_clear_bit(osb, &osb->osb_recovering_orphan_dirs, slot);
  }
  
  /*
   * Orphan recovery. Each mounted node has it's own orphan dir which we
   * must run during recovery. Our strategy here is to build a list of
   * the inodes in the orphan dir and iget/iput them. The VFS does
   * (most) of the rest of the work.
   *
   * Orphan recovery can happen at any time, not just mount so we have a
   * couple of extra considerations.
   *
   * - We grab as many inodes as we can under the orphan dir lock -
   *   doing iget() outside the orphan dir risks getting a reference on
   *   an invalid inode.
   * - We must be sure not to deadlock with other processes on the
   *   system wanting to run delete_inode(). This can happen when they go
   *   to lock the orphan dir and the orphan recovery process attempts to
   *   iget() inside the orphan dir lock. This can be avoided by
   *   advertising our state to ocfs2_delete_inode().
   */
  static int ocfs2_recover_orphans(struct ocfs2_super *osb,
ed460cffc   Joseph Qi   ocfs2: add orphan...
2075
2076
  				 int slot,
  				 enum ocfs2_orphan_reco_type orphan_reco_type)
b4df6ed8d   Mark Fasheh   [PATCH] ocfs2: fi...
2077
2078
2079
2080
2081
  {
  	int ret = 0;
  	struct inode *inode = NULL;
  	struct inode *iter;
  	struct ocfs2_inode_info *oi;
cf1776a9e   Joseph Qi   ocfs2: fix a tiny...
2082
2083
  	struct buffer_head *di_bh = NULL;
  	struct ocfs2_dinode *di = NULL;
b4df6ed8d   Mark Fasheh   [PATCH] ocfs2: fi...
2084

b41079504   Tao Ma   ocfs2: Remove mas...
2085
  	trace_ocfs2_recover_orphans(slot);
b4df6ed8d   Mark Fasheh   [PATCH] ocfs2: fi...
2086
2087
  
  	ocfs2_mark_recovering_orphan_dir(osb, slot);
30edc43c7   Joseph Qi   ocfs2: do not inc...
2088
  	ret = ocfs2_queue_orphans(osb, slot, &inode, orphan_reco_type);
b4df6ed8d   Mark Fasheh   [PATCH] ocfs2: fi...
2089
2090
2091
2092
2093
2094
  	ocfs2_clear_recovering_orphan_dir(osb, slot);
  
  	/* Error here should be noted, but we want to continue with as
  	 * many queued inodes as we've got. */
  	if (ret)
  		mlog_errno(ret);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2095
2096
2097
  
  	while (inode) {
  		oi = OCFS2_I(inode);
b41079504   Tao Ma   ocfs2: Remove mas...
2098
2099
  		trace_ocfs2_recover_orphans_iput(
  					(unsigned long long)oi->ip_blkno);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2100
2101
  
  		iter = oi->ip_next_orphan;
ed460cffc   Joseph Qi   ocfs2: add orphan...
2102
  		oi->ip_next_orphan = NULL;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2103

93d911fcc   Joseph Qi   ocfs2: only take ...
2104
  		if (oi->ip_flags & OCFS2_INODE_DIO_ORPHAN_ENTRY) {
5955102c9   Al Viro   wrappers for ->i_...
2105
  			inode_lock(inode);
93d911fcc   Joseph Qi   ocfs2: only take ...
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
  			ret = ocfs2_rw_lock(inode, 1);
  			if (ret < 0) {
  				mlog_errno(ret);
  				goto unlock_mutex;
  			}
  			/*
  			 * We need to take and drop the inode lock to
  			 * force read inode from disk.
  			 */
  			ret = ocfs2_inode_lock(inode, &di_bh, 1);
  			if (ret) {
  				mlog_errno(ret);
  				goto unlock_rw;
  			}
  
  			di = (struct ocfs2_dinode *)di_bh->b_data;
  
  			if (di->i_flags & cpu_to_le32(OCFS2_DIO_ORPHANED_FL)) {
  				ret = ocfs2_truncate_file(inode, di_bh,
  						i_size_read(inode));
  				if (ret < 0) {
  					if (ret != -ENOSPC)
  						mlog_errno(ret);
  					goto unlock_inode;
  				}
cf1776a9e   Joseph Qi   ocfs2: fix a tiny...
2131

93d911fcc   Joseph Qi   ocfs2: only take ...
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
  				ret = ocfs2_del_inode_from_orphan(osb, inode,
  						di_bh, 0, 0);
  				if (ret)
  					mlog_errno(ret);
  			}
  unlock_inode:
  			ocfs2_inode_unlock(inode, 1);
  			brelse(di_bh);
  			di_bh = NULL;
  unlock_rw:
  			ocfs2_rw_unlock(inode, 1);
  unlock_mutex:
5955102c9   Al Viro   wrappers for ->i_...
2144
  			inode_unlock(inode);
ed460cffc   Joseph Qi   ocfs2: add orphan...
2145

93d911fcc   Joseph Qi   ocfs2: only take ...
2146
2147
2148
  			/* clear dio flag in ocfs2_inode_info */
  			oi->ip_flags &= ~OCFS2_INODE_DIO_ORPHAN_ENTRY;
  		} else {
ed460cffc   Joseph Qi   ocfs2: add orphan...
2149
2150
2151
2152
2153
  			spin_lock(&oi->ip_lock);
  			/* Set the proper information to get us going into
  			 * ocfs2_delete_inode. */
  			oi->ip_flags |= OCFS2_INODE_MAYBE_ORPHANED;
  			spin_unlock(&oi->ip_lock);
ad6948212   Joseph Qi   ocfs2: fix race b...
2154
  		}
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2155
  		iput(inode);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2156
2157
  		inode = iter;
  	}
b4df6ed8d   Mark Fasheh   [PATCH] ocfs2: fi...
2158
  	return ret;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2159
  }
19ece546a   Jan Kara   ocfs2: Enable quo...
2160
  static int __ocfs2_wait_on_mount(struct ocfs2_super *osb, int quota)
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2161
2162
2163
2164
2165
  {
  	/* This check is good because ocfs2 will wait on our recovery
  	 * thread before changing it to something other than MOUNTED
  	 * or DISABLED. */
  	wait_event(osb->osb_mount_event,
19ece546a   Jan Kara   ocfs2: Enable quo...
2166
2167
  		  (!quota && atomic_read(&osb->vol_state) == VOLUME_MOUNTED) ||
  		   atomic_read(&osb->vol_state) == VOLUME_MOUNTED_QUOTAS ||
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2168
2169
2170
2171
2172
2173
  		   atomic_read(&osb->vol_state) == VOLUME_DISABLED);
  
  	/* If there's an error on mount, then we may never get to the
  	 * MOUNTED flag, but this is set right before
  	 * dismount_volume() so we can trust it. */
  	if (atomic_read(&osb->vol_state) == VOLUME_DISABLED) {
b41079504   Tao Ma   ocfs2: Remove mas...
2174
  		trace_ocfs2_wait_on_mount(VOLUME_DISABLED);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
  		mlog(0, "mount error, exiting!
  ");
  		return -EBUSY;
  	}
  
  	return 0;
  }
  
  static int ocfs2_commit_thread(void *arg)
  {
  	int status;
  	struct ocfs2_super *osb = arg;
  	struct ocfs2_journal *journal = osb->journal;
  
  	/* we can trust j_num_trans here because _should_stop() is only set in
  	 * shutdown and nobody other than ourselves should be able to start
  	 * transactions.  committing on shutdown might take a few iterations
  	 * as final transactions put deleted inodes on the list */
  	while (!(kthread_should_stop() &&
  		 atomic_read(&journal->j_num_trans) == 0)) {
745ae8ba2   Mark Fasheh   [PATCH] ocfs2: on...
2195
2196
2197
  		wait_event_interruptible(osb->checkpoint_event,
  					 atomic_read(&journal->j_num_trans)
  					 || kthread_should_stop());
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2198
2199
  
  		status = ocfs2_commit_cache(osb);
55b465b66   Joseph Qi   ocfs2: limit prin...
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
  		if (status < 0) {
  			static unsigned long abort_warn_time;
  
  			/* Warn about this once per minute */
  			if (printk_timed_ratelimit(&abort_warn_time, 60*HZ))
  				mlog(ML_ERROR, "status = %d, journal is "
  						"already aborted.
  ", status);
  			/*
  			 * After ocfs2_commit_cache() fails, j_num_trans has a
  			 * non-zero value.  Sleep here to avoid a busy-wait
  			 * loop.
  			 */
  			msleep_interruptible(1000);
  		}
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
  
  		if (kthread_should_stop() && atomic_read(&journal->j_num_trans)){
  			mlog(ML_KTHREAD,
  			     "commit_thread: %u transactions pending on "
  			     "shutdown
  ",
  			     atomic_read(&journal->j_num_trans));
  		}
  	}
  
  	return 0;
  }
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
2227
2228
2229
2230
2231
  /* Reads all the journal inodes without taking any cluster locks. Used
   * for hard readonly access to determine whether any journal requires
   * recovery. Also used to refresh the recovery generation numbers after
   * a journal has been recovered by another node.
   */
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2232
2233
2234
2235
  int ocfs2_check_journals_nolocks(struct ocfs2_super *osb)
  {
  	int ret = 0;
  	unsigned int slot;
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
2236
  	struct buffer_head *di_bh = NULL;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2237
  	struct ocfs2_dinode *di;
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
2238
  	int journal_dirty = 0;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2239
2240
  
  	for(slot = 0; slot < osb->max_slots; slot++) {
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
2241
2242
  		ret = ocfs2_read_journal_inode(osb, slot, &di_bh, NULL);
  		if (ret) {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2243
2244
2245
2246
2247
  			mlog_errno(ret);
  			goto out;
  		}
  
  		di = (struct ocfs2_dinode *) di_bh->b_data;
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
2248
2249
  		osb->slot_recovery_generations[slot] =
  					ocfs2_get_recovery_generation(di);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2250
2251
  		if (le32_to_cpu(di->id1.journal1.ij_flags) &
  		    OCFS2_JOURNAL_DIRTY_FL)
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
2252
  			journal_dirty = 1;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2253
2254
  
  		brelse(di_bh);
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
2255
  		di_bh = NULL;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2256
2257
2258
  	}
  
  out:
539d82640   Sunil Mushran   [PATCH 2/2] ocfs2...
2259
2260
  	if (journal_dirty)
  		ret = -EROFS;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
2261
2262
  	return ret;
  }