node.c 66 KB
Newer Older
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1
/*
Jaegeuk Kim's avatar
Jaegeuk Kim committed
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 * fs/f2fs/node.c
 *
 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
 *             http://www.samsung.com/
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <linux/fs.h>
#include <linux/f2fs_fs.h>
#include <linux/mpage.h>
#include <linux/backing-dev.h>
#include <linux/blkdev.h>
#include <linux/pagevec.h>
#include <linux/swap.h>

#include "f2fs.h"
#include "node.h"
#include "segment.h"
Jaegeuk Kim's avatar
Jaegeuk Kim committed
22
#include "trace.h"
23
#include <trace/events/f2fs.h>
Jaegeuk Kim's avatar
Jaegeuk Kim committed
24

25
26
#define on_build_free_nids(nmi) mutex_is_locked(&nm_i->build_lock)

Jaegeuk Kim's avatar
Jaegeuk Kim committed
27
28
static struct kmem_cache *nat_entry_slab;
static struct kmem_cache *free_nid_slab;
29
static struct kmem_cache *nat_entry_set_slab;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
30

31
bool available_free_memory(struct f2fs_sb_info *sbi, int type)
32
{
33
	struct f2fs_nm_info *nm_i = NM_I(sbi);
34
	struct sysinfo val;
35
	unsigned long avail_ram;
36
	unsigned long mem_size = 0;
37
	bool res = false;
38
39

	si_meminfo(&val);
40
41
42
43

	/* only uses low memory */
	avail_ram = val.totalram - val.totalhigh;

44
45
46
	/*
	 * give 25%, 25%, 50%, 50%, 50% memory for each components respectively
	 */
47
	if (type == FREE_NIDS) {
Chao Yu's avatar
Chao Yu committed
48
49
		mem_size = (nm_i->nid_cnt[FREE_NID_LIST] *
				sizeof(struct free_nid)) >> PAGE_SHIFT;
50
		res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 2);
51
	} else if (type == NAT_ENTRIES) {
52
		mem_size = (nm_i->nat_cnt * sizeof(struct nat_entry)) >>
53
							PAGE_SHIFT;
54
		res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 2);
55
56
		if (excess_cached_nats(sbi))
			res = false;
57
58
59
60
61
	} else if (type == DIRTY_DENTS) {
		if (sbi->sb->s_bdi->wb.dirty_exceeded)
			return false;
		mem_size = get_pages(sbi, F2FS_DIRTY_DENTS);
		res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 1);
62
63
64
65
	} else if (type == INO_ENTRIES) {
		int i;

		for (i = 0; i <= UPDATE_INO; i++)
66
			mem_size += (sbi->im[i].ino_num *
67
				sizeof(struct ino_entry)) >> PAGE_SHIFT;
68
		res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 1);
69
	} else if (type == EXTENT_CACHE) {
70
71
		mem_size = (atomic_read(&sbi->total_ext_tree) *
				sizeof(struct extent_tree) +
72
				atomic_read(&sbi->total_ext_node) *
73
				sizeof(struct extent_node)) >> PAGE_SHIFT;
74
		res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 1);
75
	} else {
76
77
		if (!sbi->sb->s_bdi->wb.dirty_exceeded)
			return true;
78
79
	}
	return res;
80
81
}

Jaegeuk Kim's avatar
Jaegeuk Kim committed
82
83
84
85
86
87
88
89
90
91
92
93
94
static void clear_node_page_dirty(struct page *page)
{
	struct address_space *mapping = page->mapping;
	unsigned int long flags;

	if (PageDirty(page)) {
		spin_lock_irqsave(&mapping->tree_lock, flags);
		radix_tree_tag_clear(&mapping->page_tree,
				page_index(page),
				PAGECACHE_TAG_DIRTY);
		spin_unlock_irqrestore(&mapping->tree_lock, flags);

		clear_page_dirty_for_io(page);
95
		dec_page_count(F2FS_M_SB(mapping), F2FS_DIRTY_NODES);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
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
	}
	ClearPageUptodate(page);
}

static struct page *get_current_nat_page(struct f2fs_sb_info *sbi, nid_t nid)
{
	pgoff_t index = current_nat_addr(sbi, nid);
	return get_meta_page(sbi, index);
}

static struct page *get_next_nat_page(struct f2fs_sb_info *sbi, nid_t nid)
{
	struct page *src_page;
	struct page *dst_page;
	pgoff_t src_off;
	pgoff_t dst_off;
	void *src_addr;
	void *dst_addr;
	struct f2fs_nm_info *nm_i = NM_I(sbi);

	src_off = current_nat_addr(sbi, nid);
	dst_off = next_nat_addr(sbi, src_off);

	/* get current nat block page with lock */
	src_page = get_meta_page(sbi, src_off);
	dst_page = grab_meta_page(sbi, dst_off);
122
	f2fs_bug_on(sbi, PageDirty(src_page));
Jaegeuk Kim's avatar
Jaegeuk Kim committed
123
124
125

	src_addr = page_address(src_page);
	dst_addr = page_address(dst_page);
126
	memcpy(dst_addr, src_addr, PAGE_SIZE);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
	set_page_dirty(dst_page);
	f2fs_put_page(src_page, 1);

	set_to_next_nat(nm_i, nid);

	return dst_page;
}

static struct nat_entry *__lookup_nat_cache(struct f2fs_nm_info *nm_i, nid_t n)
{
	return radix_tree_lookup(&nm_i->nat_root, n);
}

static unsigned int __gang_lookup_nat_cache(struct f2fs_nm_info *nm_i,
		nid_t start, unsigned int nr, struct nat_entry **ep)
{
	return radix_tree_gang_lookup(&nm_i->nat_root, (void **)ep, start, nr);
}

static void __del_from_nat_cache(struct f2fs_nm_info *nm_i, struct nat_entry *e)
{
	list_del(&e->list);
	radix_tree_delete(&nm_i->nat_root, nat_get_nid(e));
	nm_i->nat_cnt--;
	kmem_cache_free(nat_entry_slab, e);
}

154
155
156
157
158
159
160
161
static void __set_nat_cache_dirty(struct f2fs_nm_info *nm_i,
						struct nat_entry *ne)
{
	nid_t set = NAT_BLOCK_OFFSET(ne->ni.nid);
	struct nat_entry_set *head;

	if (get_nat_flag(ne, IS_DIRTY))
		return;
162

163
164
	head = radix_tree_lookup(&nm_i->nat_set_root, set);
	if (!head) {
165
		head = f2fs_kmem_cache_alloc(nat_entry_set_slab, GFP_NOFS);
166
167
168
169
170

		INIT_LIST_HEAD(&head->entry_list);
		INIT_LIST_HEAD(&head->set_list);
		head->set = set;
		head->entry_cnt = 0;
171
		f2fs_radix_tree_insert(&nm_i->nat_set_root, set, head);
172
173
174
175
176
177
178
179
180
181
	}
	list_move_tail(&ne->list, &head->entry_list);
	nm_i->dirty_nat_cnt++;
	head->entry_cnt++;
	set_nat_flag(ne, IS_DIRTY, true);
}

static void __clear_nat_cache_dirty(struct f2fs_nm_info *nm_i,
						struct nat_entry *ne)
{
182
	nid_t set = NAT_BLOCK_OFFSET(ne->ni.nid);
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
	struct nat_entry_set *head;

	head = radix_tree_lookup(&nm_i->nat_set_root, set);
	if (head) {
		list_move_tail(&ne->list, &nm_i->nat_entries);
		set_nat_flag(ne, IS_DIRTY, false);
		head->entry_cnt--;
		nm_i->dirty_nat_cnt--;
	}
}

static unsigned int __gang_lookup_nat_set(struct f2fs_nm_info *nm_i,
		nid_t start, unsigned int nr, struct nat_entry_set **ep)
{
	return radix_tree_gang_lookup(&nm_i->nat_set_root, (void **)ep,
							start, nr);
}

Jaegeuk Kim's avatar
Jaegeuk Kim committed
201
int need_dentry_mark(struct f2fs_sb_info *sbi, nid_t nid)
Jaegeuk Kim's avatar
Jaegeuk Kim committed
202
203
204
{
	struct f2fs_nm_info *nm_i = NM_I(sbi);
	struct nat_entry *e;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
205
	bool need = false;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
206

207
	down_read(&nm_i->nat_tree_lock);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
208
	e = __lookup_nat_cache(nm_i, nid);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
209
210
211
212
213
	if (e) {
		if (!get_nat_flag(e, IS_CHECKPOINTED) &&
				!get_nat_flag(e, HAS_FSYNCED_INODE))
			need = true;
	}
214
	up_read(&nm_i->nat_tree_lock);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
215
	return need;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
216
217
}

Jaegeuk Kim's avatar
Jaegeuk Kim committed
218
bool is_checkpointed_node(struct f2fs_sb_info *sbi, nid_t nid)
219
220
221
{
	struct f2fs_nm_info *nm_i = NM_I(sbi);
	struct nat_entry *e;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
222
	bool is_cp = true;
223

224
	down_read(&nm_i->nat_tree_lock);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
225
226
227
	e = __lookup_nat_cache(nm_i, nid);
	if (e && !get_nat_flag(e, IS_CHECKPOINTED))
		is_cp = false;
228
	up_read(&nm_i->nat_tree_lock);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
229
	return is_cp;
230
231
}

232
bool need_inode_block_update(struct f2fs_sb_info *sbi, nid_t ino)
233
234
235
{
	struct f2fs_nm_info *nm_i = NM_I(sbi);
	struct nat_entry *e;
236
	bool need_update = true;
237

238
	down_read(&nm_i->nat_tree_lock);
239
240
241
242
243
	e = __lookup_nat_cache(nm_i, ino);
	if (e && get_nat_flag(e, HAS_LAST_FSYNC) &&
			(get_nat_flag(e, IS_CHECKPOINTED) ||
			 get_nat_flag(e, HAS_FSYNCED_INODE)))
		need_update = false;
244
	up_read(&nm_i->nat_tree_lock);
245
	return need_update;
246
247
}

248
249
static struct nat_entry *grab_nat_entry(struct f2fs_nm_info *nm_i, nid_t nid,
								bool no_fail)
Jaegeuk Kim's avatar
Jaegeuk Kim committed
250
251
252
{
	struct nat_entry *new;

253
254
255
256
257
258
259
260
261
262
263
264
265
	if (no_fail) {
		new = f2fs_kmem_cache_alloc(nat_entry_slab, GFP_NOFS);
		f2fs_radix_tree_insert(&nm_i->nat_root, nid, new);
	} else {
		new = kmem_cache_alloc(nat_entry_slab, GFP_NOFS);
		if (!new)
			return NULL;
		if (radix_tree_insert(&nm_i->nat_root, nid, new)) {
			kmem_cache_free(nat_entry_slab, new);
			return NULL;
		}
	}

Jaegeuk Kim's avatar
Jaegeuk Kim committed
266
267
	memset(new, 0, sizeof(struct nat_entry));
	nat_set_nid(new, nid);
268
	nat_reset_flag(new);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
269
270
271
272
273
	list_add_tail(&new->list, &nm_i->nat_entries);
	nm_i->nat_cnt++;
	return new;
}

274
static void cache_nat_entry(struct f2fs_sb_info *sbi, nid_t nid,
Jaegeuk Kim's avatar
Jaegeuk Kim committed
275
276
						struct f2fs_nat_entry *ne)
{
277
	struct f2fs_nm_info *nm_i = NM_I(sbi);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
278
	struct nat_entry *e;
279

Jaegeuk Kim's avatar
Jaegeuk Kim committed
280
281
	e = __lookup_nat_cache(nm_i, nid);
	if (!e) {
282
283
284
		e = grab_nat_entry(nm_i, nid, false);
		if (e)
			node_info_from_raw_nat(&e->ni, ne);
285
	} else {
Eric Biggers's avatar
Eric Biggers committed
286
287
288
		f2fs_bug_on(sbi, nat_get_ino(e) != le32_to_cpu(ne->ino) ||
				nat_get_blkaddr(e) !=
					le32_to_cpu(ne->block_addr) ||
289
				nat_get_version(e) != ne->version);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
290
291
292
293
	}
}

static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni,
294
			block_t new_blkaddr, bool fsync_done)
Jaegeuk Kim's avatar
Jaegeuk Kim committed
295
296
297
{
	struct f2fs_nm_info *nm_i = NM_I(sbi);
	struct nat_entry *e;
298

299
	down_write(&nm_i->nat_tree_lock);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
300
301
	e = __lookup_nat_cache(nm_i, ni->nid);
	if (!e) {
302
		e = grab_nat_entry(nm_i, ni->nid, true);
303
		copy_node_info(&e->ni, ni);
304
		f2fs_bug_on(sbi, ni->blk_addr == NEW_ADDR);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
305
306
307
308
309
310
	} else if (new_blkaddr == NEW_ADDR) {
		/*
		 * when nid is reallocated,
		 * previous nat entry can be remained in nat cache.
		 * So, reinitialize it with new information.
		 */
311
		copy_node_info(&e->ni, ni);
312
		f2fs_bug_on(sbi, ni->blk_addr != NULL_ADDR);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
313
314
315
	}

	/* sanity check */
316
317
	f2fs_bug_on(sbi, nat_get_blkaddr(e) != ni->blk_addr);
	f2fs_bug_on(sbi, nat_get_blkaddr(e) == NULL_ADDR &&
Jaegeuk Kim's avatar
Jaegeuk Kim committed
318
			new_blkaddr == NULL_ADDR);
319
	f2fs_bug_on(sbi, nat_get_blkaddr(e) == NEW_ADDR &&
Jaegeuk Kim's avatar
Jaegeuk Kim committed
320
			new_blkaddr == NEW_ADDR);
321
	f2fs_bug_on(sbi, nat_get_blkaddr(e) != NEW_ADDR &&
Jaegeuk Kim's avatar
Jaegeuk Kim committed
322
323
324
			nat_get_blkaddr(e) != NULL_ADDR &&
			new_blkaddr == NEW_ADDR);

arter97's avatar
arter97 committed
325
	/* increment version no as node is removed */
Jaegeuk Kim's avatar
Jaegeuk Kim committed
326
327
328
	if (nat_get_blkaddr(e) != NEW_ADDR && new_blkaddr == NULL_ADDR) {
		unsigned char version = nat_get_version(e);
		nat_set_version(e, inc_node_version(version));
329
330
331
332

		/* in order to reuse the nid */
		if (nm_i->next_scan_nid > ni->nid)
			nm_i->next_scan_nid = ni->nid;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
333
334
335
336
	}

	/* change address */
	nat_set_blkaddr(e, new_blkaddr);
337
338
	if (new_blkaddr == NEW_ADDR || new_blkaddr == NULL_ADDR)
		set_nat_flag(e, IS_CHECKPOINTED, false);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
339
	__set_nat_cache_dirty(nm_i, e);
340

341
342
343
	if (enabled_nat_bits(sbi, NULL) && new_blkaddr == NEW_ADDR)
		clear_bit_le(NAT_BLOCK_OFFSET(ni->nid), nm_i->empty_nat_bits);

344
	/* update fsync_mark if its inode nat entry is still alive */
345
346
	if (ni->nid != ni->ino)
		e = __lookup_nat_cache(nm_i, ni->ino);
347
348
349
350
351
	if (e) {
		if (fsync_done && ni->nid == ni->ino)
			set_nat_flag(e, HAS_FSYNCED_INODE, true);
		set_nat_flag(e, HAS_LAST_FSYNC, fsync_done);
	}
352
	up_write(&nm_i->nat_tree_lock);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
353
354
}

355
int try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink)
Jaegeuk Kim's avatar
Jaegeuk Kim committed
356
357
{
	struct f2fs_nm_info *nm_i = NM_I(sbi);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
358
	int nr = nr_shrink;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
359

360
361
	if (!down_write_trylock(&nm_i->nat_tree_lock))
		return 0;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
362
363
364
365
366
367
368
369

	while (nr_shrink && !list_empty(&nm_i->nat_entries)) {
		struct nat_entry *ne;
		ne = list_first_entry(&nm_i->nat_entries,
					struct nat_entry, list);
		__del_from_nat_cache(nm_i, ne);
		nr_shrink--;
	}
370
	up_write(&nm_i->nat_tree_lock);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
371
	return nr - nr_shrink;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
372
373
}

Jaegeuk Kim's avatar
Jaegeuk Kim committed
374
/*
arter97's avatar
arter97 committed
375
 * This function always returns success
Jaegeuk Kim's avatar
Jaegeuk Kim committed
376
377
378
379
380
 */
void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni)
{
	struct f2fs_nm_info *nm_i = NM_I(sbi);
	struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
381
	struct f2fs_journal *journal = curseg->journal;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
382
383
384
385
386
387
388
389
390
391
	nid_t start_nid = START_NID(nid);
	struct f2fs_nat_block *nat_blk;
	struct page *page = NULL;
	struct f2fs_nat_entry ne;
	struct nat_entry *e;
	int i;

	ni->nid = nid;

	/* Check nat cache */
392
	down_read(&nm_i->nat_tree_lock);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
393
394
395
396
397
	e = __lookup_nat_cache(nm_i, nid);
	if (e) {
		ni->ino = nat_get_ino(e);
		ni->blk_addr = nat_get_blkaddr(e);
		ni->version = nat_get_version(e);
398
		up_read(&nm_i->nat_tree_lock);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
399
		return;
400
	}
Jaegeuk Kim's avatar
Jaegeuk Kim committed
401

402
403
	memset(&ne, 0, sizeof(struct f2fs_nat_entry));

Jaegeuk Kim's avatar
Jaegeuk Kim committed
404
	/* Check current segment summary */
405
	down_read(&curseg->journal_rwsem);
406
	i = lookup_journal_in_cursum(journal, NAT_JOURNAL, nid, 0);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
407
	if (i >= 0) {
408
		ne = nat_in_journal(journal, i);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
409
410
		node_info_from_raw_nat(ni, &ne);
	}
411
	up_read(&curseg->journal_rwsem);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
412
413
414
415
416
417
418
419
420
421
	if (i >= 0)
		goto cache;

	/* Fill node_info from nat page */
	page = get_current_nat_page(sbi, start_nid);
	nat_blk = (struct f2fs_nat_block *)page_address(page);
	ne = nat_blk->entries[nid - start_nid];
	node_info_from_raw_nat(ni, &ne);
	f2fs_put_page(page, 1);
cache:
422
	up_read(&nm_i->nat_tree_lock);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
423
	/* cache nat entry */
424
	down_write(&nm_i->nat_tree_lock);
425
	cache_nat_entry(sbi, nid, &ne);
426
	up_write(&nm_i->nat_tree_lock);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
427
428
}

429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
/*
 * readahead MAX_RA_NODE number of node pages.
 */
static void ra_node_pages(struct page *parent, int start, int n)
{
	struct f2fs_sb_info *sbi = F2FS_P_SB(parent);
	struct blk_plug plug;
	int i, end;
	nid_t nid;

	blk_start_plug(&plug);

	/* Then, try readahead for siblings of the desired node */
	end = start + n;
	end = min(end, NIDS_PER_BLOCK);
	for (i = start; i < end; i++) {
		nid = get_nid(parent, i, false);
		ra_node_page(sbi, nid);
	}

	blk_finish_plug(&plug);
}

452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
pgoff_t get_next_page_offset(struct dnode_of_data *dn, pgoff_t pgofs)
{
	const long direct_index = ADDRS_PER_INODE(dn->inode);
	const long direct_blks = ADDRS_PER_BLOCK;
	const long indirect_blks = ADDRS_PER_BLOCK * NIDS_PER_BLOCK;
	unsigned int skipped_unit = ADDRS_PER_BLOCK;
	int cur_level = dn->cur_level;
	int max_level = dn->max_level;
	pgoff_t base = 0;

	if (!dn->max_level)
		return pgofs + 1;

	while (max_level-- > cur_level)
		skipped_unit *= NIDS_PER_BLOCK;

	switch (dn->max_level) {
	case 3:
		base += 2 * indirect_blks;
	case 2:
		base += 2 * direct_blks;
	case 1:
		base += direct_index;
		break;
	default:
		f2fs_bug_on(F2FS_I_SB(dn->inode), 1);
	}

	return ((pgofs - base) / skipped_unit + 1) * skipped_unit + base;
}

Jaegeuk Kim's avatar
Jaegeuk Kim committed
483
/*
Jaegeuk Kim's avatar
Jaegeuk Kim committed
484
485
486
 * The maximum depth is four.
 * Offset[0] will have raw inode offset.
 */
487
static int get_node_path(struct inode *inode, long block,
488
				int offset[4], unsigned int noffset[4])
Jaegeuk Kim's avatar
Jaegeuk Kim committed
489
{
490
	const long direct_index = ADDRS_PER_INODE(inode);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
491
492
493
494
495
496
497
498
499
500
	const long direct_blks = ADDRS_PER_BLOCK;
	const long dptrs_per_blk = NIDS_PER_BLOCK;
	const long indirect_blks = ADDRS_PER_BLOCK * NIDS_PER_BLOCK;
	const long dindirect_blks = indirect_blks * NIDS_PER_BLOCK;
	int n = 0;
	int level = 0;

	noffset[0] = 0;

	if (block < direct_index) {
501
		offset[n] = block;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
502
503
504
505
506
507
		goto got;
	}
	block -= direct_index;
	if (block < direct_blks) {
		offset[n++] = NODE_DIR1_BLOCK;
		noffset[n] = 1;
508
		offset[n] = block;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
509
510
511
512
513
514
515
		level = 1;
		goto got;
	}
	block -= direct_blks;
	if (block < direct_blks) {
		offset[n++] = NODE_DIR2_BLOCK;
		noffset[n] = 2;
516
		offset[n] = block;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
517
518
519
520
521
522
523
524
525
		level = 1;
		goto got;
	}
	block -= direct_blks;
	if (block < indirect_blks) {
		offset[n++] = NODE_IND1_BLOCK;
		noffset[n] = 3;
		offset[n++] = block / direct_blks;
		noffset[n] = 4 + offset[n - 1];
526
		offset[n] = block % direct_blks;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
527
528
529
530
531
532
533
534
535
		level = 2;
		goto got;
	}
	block -= indirect_blks;
	if (block < indirect_blks) {
		offset[n++] = NODE_IND2_BLOCK;
		noffset[n] = 4 + dptrs_per_blk;
		offset[n++] = block / direct_blks;
		noffset[n] = 5 + dptrs_per_blk + offset[n - 1];
536
		offset[n] = block % direct_blks;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
537
538
539
540
541
542
543
544
545
546
547
548
549
550
		level = 2;
		goto got;
	}
	block -= indirect_blks;
	if (block < dindirect_blks) {
		offset[n++] = NODE_DIND_BLOCK;
		noffset[n] = 5 + (dptrs_per_blk * 2);
		offset[n++] = block / indirect_blks;
		noffset[n] = 6 + (dptrs_per_blk * 2) +
			      offset[n - 1] * (dptrs_per_blk + 1);
		offset[n++] = (block / direct_blks) % dptrs_per_blk;
		noffset[n] = 7 + (dptrs_per_blk * 2) +
			      offset[n - 2] * (dptrs_per_blk + 1) +
			      offset[n - 1];
551
		offset[n] = block % direct_blks;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
552
553
554
555
556
557
558
559
560
561
562
		level = 3;
		goto got;
	} else {
		BUG();
	}
got:
	return level;
}

/*
 * Caller should call f2fs_put_dnode(dn).
Chao Yu's avatar
Chao Yu committed
563
564
 * Also, it should grab and release a rwsem by calling f2fs_lock_op() and
 * f2fs_unlock_op() only if ro is not set RDONLY_NODE.
565
 * In the case of RDONLY_NODE, we don't need to care about mutex.
Jaegeuk Kim's avatar
Jaegeuk Kim committed
566
 */
567
int get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode)
Jaegeuk Kim's avatar
Jaegeuk Kim committed
568
{
569
	struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
570
	struct page *npage[4];
571
	struct page *parent = NULL;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
572
573
574
	int offset[4];
	unsigned int noffset[4];
	nid_t nids[4];
575
	int level, i = 0;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
576
577
	int err = 0;

578
	level = get_node_path(dn->inode, index, offset, noffset);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
579
580

	nids[0] = dn->inode->i_ino;
581
	npage[0] = dn->inode_page;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
582

583
584
585
586
587
	if (!npage[0]) {
		npage[0] = get_node_page(sbi, nids[0]);
		if (IS_ERR(npage[0]))
			return PTR_ERR(npage[0]);
	}
588
589
590

	/* if inline_data is set, should not report any block indices */
	if (f2fs_has_inline_data(dn->inode) && index) {
591
		err = -ENOENT;
592
593
594
595
		f2fs_put_page(npage[0], 1);
		goto release_out;
	}

Jaegeuk Kim's avatar
Jaegeuk Kim committed
596
	parent = npage[0];
597
598
	if (level != 0)
		nids[1] = get_nid(parent, offset[0], true);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
599
600
601
602
603
604
605
	dn->inode_page = npage[0];
	dn->inode_page_locked = true;

	/* get indirect or direct nodes */
	for (i = 1; i <= level; i++) {
		bool done = false;

606
		if (!nids[i] && mode == ALLOC_NODE) {
Jaegeuk Kim's avatar
Jaegeuk Kim committed
607
608
609
610
611
612
613
			/* alloc new node */
			if (!alloc_nid(sbi, &(nids[i]))) {
				err = -ENOSPC;
				goto release_pages;
			}

			dn->nid = nids[i];
614
			npage[i] = new_node_page(dn, noffset[i], NULL);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
615
616
617
618
619
620
621
622
623
			if (IS_ERR(npage[i])) {
				alloc_nid_failed(sbi, nids[i]);
				err = PTR_ERR(npage[i]);
				goto release_pages;
			}

			set_nid(parent, offset[i - 1], nids[i], i == 1);
			alloc_nid_done(sbi, nids[i]);
			done = true;
624
		} else if (mode == LOOKUP_NODE_RA && i == level && level > 1) {
Jaegeuk Kim's avatar
Jaegeuk Kim committed
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
			npage[i] = get_node_page_ra(parent, offset[i - 1]);
			if (IS_ERR(npage[i])) {
				err = PTR_ERR(npage[i]);
				goto release_pages;
			}
			done = true;
		}
		if (i == 1) {
			dn->inode_page_locked = false;
			unlock_page(parent);
		} else {
			f2fs_put_page(parent, 1);
		}

		if (!done) {
			npage[i] = get_node_page(sbi, nids[i]);
			if (IS_ERR(npage[i])) {
				err = PTR_ERR(npage[i]);
				f2fs_put_page(npage[0], 0);
				goto release_out;
			}
		}
		if (i < level) {
			parent = npage[i];
			nids[i + 1] = get_nid(parent, offset[i], false);
		}
	}
	dn->nid = nids[level];
	dn->ofs_in_node = offset[level];
	dn->node_page = npage[level];
	dn->data_blkaddr = datablock_addr(dn->node_page, dn->ofs_in_node);
	return 0;

release_pages:
	f2fs_put_page(parent, 1);
	if (i > 1)
		f2fs_put_page(npage[0], 0);
release_out:
	dn->inode_page = NULL;
	dn->node_page = NULL;
665
666
667
	if (err == -ENOENT) {
		dn->cur_level = i;
		dn->max_level = level;
668
		dn->ofs_in_node = offset[level];
669
	}
Jaegeuk Kim's avatar
Jaegeuk Kim committed
670
671
672
673
674
	return err;
}

static void truncate_node(struct dnode_of_data *dn)
{
675
	struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
676
677
678
	struct node_info ni;

	get_node_info(sbi, dn->nid, &ni);
679
	if (dn->inode->i_blocks == 0) {
680
		f2fs_bug_on(sbi, ni.blk_addr != NULL_ADDR);
681
682
		goto invalidate;
	}
683
	f2fs_bug_on(sbi, ni.blk_addr == NULL_ADDR);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
684
685

	/* Deallocate node address */
686
	invalidate_blocks(sbi, ni.blk_addr);
687
	dec_valid_node_count(sbi, dn->inode);
688
	set_node_addr(sbi, &ni, NULL_ADDR, false);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
689
690
691
692

	if (dn->nid == dn->inode->i_ino) {
		remove_orphan_inode(sbi, dn->nid);
		dec_valid_inode_count(sbi);
693
		f2fs_inode_synced(dn->inode);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
694
	}
695
invalidate:
Jaegeuk Kim's avatar
Jaegeuk Kim committed
696
	clear_node_page_dirty(dn->node_page);
697
	set_sbi_flag(sbi, SBI_IS_DIRTY);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
698
699

	f2fs_put_page(dn->node_page, 1);
700
701
702
703

	invalidate_mapping_pages(NODE_MAPPING(sbi),
			dn->node_page->index, dn->node_page->index);

Jaegeuk Kim's avatar
Jaegeuk Kim committed
704
	dn->node_page = NULL;
705
	trace_f2fs_truncate_node(dn->inode, dn->nid, ni.blk_addr);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
706
707
708
709
710
711
712
713
714
715
}

static int truncate_dnode(struct dnode_of_data *dn)
{
	struct page *page;

	if (dn->nid == 0)
		return 1;

	/* get direct node */
716
	page = get_node_page(F2FS_I_SB(dn->inode), dn->nid);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
	if (IS_ERR(page) && PTR_ERR(page) == -ENOENT)
		return 1;
	else if (IS_ERR(page))
		return PTR_ERR(page);

	/* Make dnode_of_data for parameter */
	dn->node_page = page;
	dn->ofs_in_node = 0;
	truncate_data_blocks(dn);
	truncate_node(dn);
	return 1;
}

static int truncate_nodes(struct dnode_of_data *dn, unsigned int nofs,
						int ofs, int depth)
{
	struct dnode_of_data rdn = *dn;
	struct page *page;
	struct f2fs_node *rn;
	nid_t child_nid;
	unsigned int child_nofs;
	int freed = 0;
	int i, ret;

	if (dn->nid == 0)
		return NIDS_PER_BLOCK + 1;

744
745
	trace_f2fs_truncate_nodes_enter(dn->inode, dn->nid, dn->data_blkaddr);

746
	page = get_node_page(F2FS_I_SB(dn->inode), dn->nid);
747
748
	if (IS_ERR(page)) {
		trace_f2fs_truncate_nodes_exit(dn->inode, PTR_ERR(page));
Jaegeuk Kim's avatar
Jaegeuk Kim committed
749
		return PTR_ERR(page);
750
	}
Jaegeuk Kim's avatar
Jaegeuk Kim committed
751

752
753
	ra_node_pages(page, ofs, NIDS_PER_BLOCK);

754
	rn = F2FS_NODE(page);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
755
756
757
758
759
760
761
762
763
	if (depth < 3) {
		for (i = ofs; i < NIDS_PER_BLOCK; i++, freed++) {
			child_nid = le32_to_cpu(rn->in.nid[i]);
			if (child_nid == 0)
				continue;
			rdn.nid = child_nid;
			ret = truncate_dnode(&rdn);
			if (ret < 0)
				goto out_err;
764
765
			if (set_nid(page, i, 0, false))
				dn->node_changed = true;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
766
767
768
769
770
771
772
773
774
775
776
777
		}
	} else {
		child_nofs = nofs + ofs * (NIDS_PER_BLOCK + 1) + 1;
		for (i = ofs; i < NIDS_PER_BLOCK; i++) {
			child_nid = le32_to_cpu(rn->in.nid[i]);
			if (child_nid == 0) {
				child_nofs += NIDS_PER_BLOCK + 1;
				continue;
			}
			rdn.nid = child_nid;
			ret = truncate_nodes(&rdn, child_nofs, 0, depth - 1);
			if (ret == (NIDS_PER_BLOCK + 1)) {
778
779
				if (set_nid(page, i, 0, false))
					dn->node_changed = true;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
				child_nofs += ret;
			} else if (ret < 0 && ret != -ENOENT) {
				goto out_err;
			}
		}
		freed = child_nofs;
	}

	if (!ofs) {
		/* remove current indirect node */
		dn->node_page = page;
		truncate_node(dn);
		freed++;
	} else {
		f2fs_put_page(page, 1);
	}
796
	trace_f2fs_truncate_nodes_exit(dn->inode, freed);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
797
798
799
800
	return freed;

out_err:
	f2fs_put_page(page, 1);
801
	trace_f2fs_truncate_nodes_exit(dn->inode, ret);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
	return ret;
}

static int truncate_partial_nodes(struct dnode_of_data *dn,
			struct f2fs_inode *ri, int *offset, int depth)
{
	struct page *pages[2];
	nid_t nid[3];
	nid_t child_nid;
	int err = 0;
	int i;
	int idx = depth - 2;

	nid[0] = le32_to_cpu(ri->i_nid[offset[0] - NODE_DIR1_BLOCK]);
	if (!nid[0])
		return 0;

	/* get indirect nodes in the path */
820
	for (i = 0; i < idx + 1; i++) {
arter97's avatar
arter97 committed
821
		/* reference count'll be increased */
822
		pages[i] = get_node_page(F2FS_I_SB(dn->inode), nid[i]);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
823
824
		if (IS_ERR(pages[i])) {
			err = PTR_ERR(pages[i]);
825
			idx = i - 1;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
826
827
828
829
830
			goto fail;
		}
		nid[i + 1] = get_nid(pages[i], offset[i + 1], false);
	}

831
832
	ra_node_pages(pages[idx], offset[idx + 1], NIDS_PER_BLOCK);

Jaegeuk Kim's avatar
Jaegeuk Kim committed
833
	/* free direct nodes linked to a partial indirect node */
834
	for (i = offset[idx + 1]; i < NIDS_PER_BLOCK; i++) {
Jaegeuk Kim's avatar
Jaegeuk Kim committed
835
836
837
838
839
840
841
		child_nid = get_nid(pages[idx], i, false);
		if (!child_nid)
			continue;
		dn->nid = child_nid;
		err = truncate_dnode(dn);
		if (err < 0)
			goto fail;
842
843
		if (set_nid(pages[idx], i, 0, false))
			dn->node_changed = true;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
844
845
	}

846
	if (offset[idx + 1] == 0) {
Jaegeuk Kim's avatar
Jaegeuk Kim committed
847
848
849
850
851
852
853
		dn->node_page = pages[idx];
		dn->nid = nid[idx];
		truncate_node(dn);
	} else {
		f2fs_put_page(pages[idx], 1);
	}
	offset[idx]++;
854
855
	offset[idx + 1] = 0;
	idx--;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
856
fail:
857
	for (i = idx; i >= 0; i--)
Jaegeuk Kim's avatar
Jaegeuk Kim committed
858
		f2fs_put_page(pages[i], 1);
859
860
861

	trace_f2fs_truncate_partial_nodes(dn->inode, nid, depth, err);

Jaegeuk Kim's avatar
Jaegeuk Kim committed
862
863
864
	return err;
}

Jaegeuk Kim's avatar
Jaegeuk Kim committed
865
/*
Jaegeuk Kim's avatar
Jaegeuk Kim committed
866
867
868
869
 * All the block addresses of data and nodes should be nullified.
 */
int truncate_inode_blocks(struct inode *inode, pgoff_t from)
{
870
	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
871
872
	int err = 0, cont = 1;
	int level, offset[4], noffset[4];
Jaegeuk Kim's avatar
Jaegeuk Kim committed
873
	unsigned int nofs = 0;
874
	struct f2fs_inode *ri;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
875
876
877
	struct dnode_of_data dn;
	struct page *page;

878
879
	trace_f2fs_truncate_inode_blocks_enter(inode, from);

880
	level = get_node_path(inode, from, offset, noffset);
881

Jaegeuk Kim's avatar
Jaegeuk Kim committed
882
	page = get_node_page(sbi, inode->i_ino);
883
884
	if (IS_ERR(page)) {
		trace_f2fs_truncate_inode_blocks_exit(inode, PTR_ERR(page));
Jaegeuk Kim's avatar
Jaegeuk Kim committed
885
		return PTR_ERR(page);
886
	}
Jaegeuk Kim's avatar
Jaegeuk Kim committed
887
888
889
890

	set_new_dnode(&dn, inode, page, NULL, 0);
	unlock_page(page);

891
	ri = F2FS_INODE(page);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
892
893
894
895
896
897
898
899
900
	switch (level) {
	case 0:
	case 1:
		nofs = noffset[1];
		break;
	case 2:
		nofs = noffset[1];
		if (!offset[level - 1])
			goto skip_partial;
901
		err = truncate_partial_nodes(&dn, ri, offset, level);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
902
903
904
905
906
907
908
909
		if (err < 0 && err != -ENOENT)
			goto fail;
		nofs += 1 + NIDS_PER_BLOCK;
		break;
	case 3:
		nofs = 5 + 2 * NIDS_PER_BLOCK;
		if (!offset[level - 1])
			goto skip_partial;
910
		err = truncate_partial_nodes(&dn, ri, offset, level);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
911
912
913
914
915
916
917
918
919
		if (err < 0 && err != -ENOENT)
			goto fail;
		break;
	default:
		BUG();
	}

skip_partial:
	while (cont) {
920
		dn.nid = le32_to_cpu(ri->i_nid[offset[0] - NODE_DIR1_BLOCK]);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
		switch (offset[0]) {
		case NODE_DIR1_BLOCK:
		case NODE_DIR2_BLOCK:
			err = truncate_dnode(&dn);
			break;

		case NODE_IND1_BLOCK:
		case NODE_IND2_BLOCK:
			err = truncate_nodes(&dn, nofs, offset[1], 2);
			break;

		case NODE_DIND_BLOCK:
			err = truncate_nodes(&dn, nofs, offset[1], 3);
			cont = 0;
			break;

		default:
			BUG();
		}
		if (err < 0 && err != -ENOENT)
			goto fail;
		if (offset[1] == 0 &&
943
				ri->i_nid[offset[0] - NODE_DIR1_BLOCK]) {
Jaegeuk Kim's avatar
Jaegeuk Kim committed
944
			lock_page(page);
945
			BUG_ON(page->mapping != NODE_MAPPING(sbi));
946
			f2fs_wait_on_page_writeback(page, NODE, true);
947
			ri->i_nid[offset[0] - NODE_DIR1_BLOCK] = 0;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
948
949
950
951
952
953
954
955
956
			set_page_dirty(page);
			unlock_page(page);
		}
		offset[1] = 0;
		offset[0]++;
		nofs += err;
	}
fail:
	f2fs_put_page(page, 0);
957
	trace_f2fs_truncate_inode_blocks_exit(inode, err);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
958
959
960
	return err > 0 ? 0 : err;
}

961
962
int truncate_xattr_node(struct inode *inode, struct page *page)
{
963
	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
964
965
966
967
968
969
970
971
972
973
974
	nid_t nid = F2FS_I(inode)->i_xattr_nid;
	struct dnode_of_data dn;
	struct page *npage;

	if (!nid)
		return 0;

	npage = get_node_page(sbi, nid);
	if (IS_ERR(npage))
		return PTR_ERR(npage);

975
	f2fs_i_xnid_write(inode, 0);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
976

977
978
979
	set_new_dnode(&dn, inode, page, npage, nid);

	if (page)
980
		dn.inode_page_locked = true;
981
982
983
984
	truncate_node(&dn);
	return 0;
}

985
/*
Chao Yu's avatar
Chao Yu committed
986
987
 * Caller should grab and release a rwsem by calling f2fs_lock_op() and
 * f2fs_unlock_op().
988
 */
Chao Yu's avatar
Chao Yu committed
989
int remove_inode_page(struct inode *inode)
Jaegeuk Kim's avatar
Jaegeuk Kim committed
990
991
{
	struct dnode_of_data dn;
Chao Yu's avatar
Chao Yu committed
992
	int err;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
993

994
	set_new_dnode(&dn, inode, NULL, NULL, inode->i_ino);
Chao Yu's avatar
Chao Yu committed
995
996
997
	err = get_dnode_of_data(&dn, 0, LOOKUP_NODE);
	if (err)
		return err;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
998

Chao Yu's avatar
Chao Yu committed
999
1000
	err = truncate_xattr_node(inode, dn.inode_page);
	if (err) {
1001
		f2fs_put_dnode(&dn);
Chao Yu's avatar
Chao Yu committed
1002
		return err;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1003
	}
1004
1005
1006
1007
1008
1009

	/* remove potential inline_data blocks */
	if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
				S_ISLNK(inode->i_mode))
		truncate_data_blocks_range(&dn, 1);

arter97's avatar
arter97 committed
1010
	/* 0 is possible, after f2fs_new_inode() has failed */
1011
1012
	f2fs_bug_on(F2FS_I_SB(inode),
			inode->i_blocks != 0 && inode->i_blocks != 1);
1013
1014

	/* will put inode & node pages */
1015
	truncate_node(&dn);
Chao Yu's avatar
Chao Yu committed
1016
	return 0;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1017
1018
}

1019
struct page *new_inode_page(struct inode *inode)
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1020
1021
1022
1023
1024
{
	struct dnode_of_data dn;

	/* allocate inode page for new inode */
	set_new_dnode(&dn, inode, NULL, NULL, inode->i_ino);
1025
1026

	/* caller should f2fs_put_page(page, 1); */
1027
	return new_node_page(&dn, 0, NULL);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1028
1029
}

1030
1031
struct page *new_node_page(struct dnode_of_data *dn,
				unsigned int ofs, struct page *ipage)
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1032
{
1033
	struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
1034
	struct node_info new_ni;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1035
1036
1037
	struct page *page;
	int err;

1038
	if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC)))
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1039
1040
		return ERR_PTR(-EPERM);

1041
	page = f2fs_grab_cache_page(NODE_MAPPING(sbi), dn->nid, false);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1042
1043
1044
	if (!page)
		return ERR_PTR(-ENOMEM);

1045
	if (unlikely(!inc_valid_node_count(sbi, dn->inode))) {
1046
1047
1048
		err = -ENOSPC;
		goto fail;
	}
1049
1050
1051
1052
1053
#ifdef CONFIG_F2FS_CHECK_FS
	get_node_info(sbi, dn->nid, &new_ni);
	f2fs_bug_on(sbi, new_ni.blk_addr != NULL_ADDR);
#endif
	new_ni.nid = dn->nid;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1054
	new_ni.ino = dn->inode->i_ino;
1055
1056
1057
	new_ni.blk_addr = NULL_ADDR;
	new_ni.flag = 0;
	new_ni.version = 0;
1058
	set_node_addr(sbi, &new_ni, NEW_ADDR, false);
1059

1060
	f2fs_wait_on_page_writeback(page, NODE, true);
1061
	fill_node_footer(page, dn->nid, dn->inode->i_ino, ofs, true);
1062
	set_cold_node(dn->inode, page);
1063
1064
	if (!PageUptodate(page))
		SetPageUptodate(page);
1065
1066
	if (set_page_dirty(page))
		dn->node_changed = true;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1067

1068
	if (f2fs_has_xattr_block(ofs))
1069
		f2fs_i_xnid_write(dn->inode, dn->nid);
1070

Jaegeuk Kim's avatar
Jaegeuk Kim committed
1071
1072
1073
1074
1075
	if (ofs == 0)
		inc_valid_inode_count(sbi);
	return page;

fail:
1076
	clear_node_page_dirty(page);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1077
1078
1079
1080
	f2fs_put_page(page, 1);
	return ERR_PTR(err);
}

1081
1082
1083
/*
 * Caller should do after getting the following values.
 * 0: f2fs_put_page(page, 0)
1084
 * LOCKED_PAGE or error: f2fs_put_page(page, 1)
1085
 */
Mike Christie's avatar
Mike Christie committed
1086
static int read_node_page(struct page *page, int op_flags)
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1087
{
1088
	struct f2fs_sb_info *sbi = F2FS_P_SB(page);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1089
	struct node_info ni;
1090
	struct f2fs_io_info fio = {
1091
		.sbi = sbi,
1092
		.type = NODE,
Mike Christie's avatar
Mike Christie committed
1093
1094
		.op = REQ_OP_READ,
		.op_flags = op_flags,
1095
		.page = page,
1096
		.encrypted_page = NULL,
1097
	};
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1098

1099
1100
1101
	if (PageUptodate(page))
		return LOCKED_PAGE;

Jaegeuk Kim's avatar
Jaegeuk Kim committed
1102
1103
	get_node_info(sbi, page->index, &ni);

1104
	if (unlikely(ni.blk_addr == NULL_ADDR)) {
1105
		ClearPageUptodate(page);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1106
		return -ENOENT;
1107
1108
	}

1109
	fio.new_blkaddr = fio.old_blkaddr = ni.blk_addr;
1110
	return f2fs_submit_page_bio(&fio);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1111
1112
}

Jaegeuk Kim's avatar
Jaegeuk Kim committed
1113
/*
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1114
1115
1116
1117
1118
 * Readahead a node page
 */
void ra_node_page(struct f2fs_sb_info *sbi, nid_t nid)
{
	struct page *apage;
1119
	int err;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1120

1121
1122
1123
1124
	if (!nid)
		return;
	f2fs_bug_on(sbi, check_nid_range(sbi, nid));

1125
1126
1127
1128
	rcu_read_lock();
	apage = radix_tree_lookup(&NODE_MAPPING(sbi)->page_tree, nid);
	rcu_read_unlock();
	if (apage)
1129
		return;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1130

1131
	apage = f2fs_grab_cache_page(NODE_MAPPING(sbi), nid, false);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1132
1133
1134
	if (!apage)
		return;

1135
	err = read_node_page(apage, REQ_RAHEAD);
1136
	f2fs_put_page(apage, err ? 1 : 0);
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1137
1138
}

Jaegeuk Kim's avatar
Jaegeuk Kim committed
1139
static struct page *__get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid,
1140
					struct page *parent, int start)
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1141
1142
{
	struct page *page;
1143
	int err;
Jaegeuk Kim's avatar
Jaegeuk Kim committed
1144
1145
1146

	if (!nid)
		return ERR_PTR(-ENOENT);