namei.c 17.2 KB
Newer Older
J
Jaegeuk Kim 已提交
1
/*
2 3 4 5 6 7 8 9 10 11 12 13 14 15
 * fs/f2fs/namei.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/pagemap.h>
#include <linux/sched.h>
#include <linux/ctype.h>
C
Chao Yu 已提交
16
#include <linux/dcache.h>
17 18

#include "f2fs.h"
19
#include "node.h"
20 21
#include "xattr.h"
#include "acl.h"
22
#include <trace/events/f2fs.h>
23 24 25

static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode)
{
26
	struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
27 28 29
	nid_t ino;
	struct inode *inode;
	bool nid_free = false;
30
	int err;
31

32
	inode = new_inode(dir->i_sb);
33 34 35
	if (!inode)
		return ERR_PTR(-ENOMEM);

36
	f2fs_lock_op(sbi);
37
	if (!alloc_nid(sbi, &ino)) {
38
		f2fs_unlock_op(sbi);
39 40 41
		err = -ENOSPC;
		goto fail;
	}
42
	f2fs_unlock_op(sbi);
43

44
	inode_init_owner(inode, dir, mode);
45 46 47 48 49 50 51 52 53 54 55 56

	inode->i_ino = ino;
	inode->i_blocks = 0;
	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
	inode->i_generation = sbi->s_next_generation++;

	err = insert_inode_locked(inode);
	if (err) {
		err = -EINVAL;
		nid_free = true;
		goto out;
	}
C
Chao Yu 已提交
57

58 59
	if (f2fs_may_inline(inode))
		set_inode_flag(F2FS_I(inode), FI_INLINE_DATA);
C
Chao Yu 已提交
60 61 62
	if (test_opt(sbi, INLINE_DENTRY) && S_ISDIR(inode->i_mode))
		set_inode_flag(F2FS_I(inode), FI_INLINE_DENTRY);

63
	trace_f2fs_new_inode(inode, 0);
64 65 66 67 68 69 70
	mark_inode_dirty(inode);
	return inode;

out:
	clear_nlink(inode);
	unlock_new_inode(inode);
fail:
71
	trace_f2fs_new_inode(inode, err);
72
	make_bad_inode(inode);
73 74 75 76 77 78 79 80
	iput(inode);
	if (nid_free)
		alloc_nid_failed(sbi, ino);
	return ERR_PTR(err);
}

static int is_multimedia_file(const unsigned char *s, const char *sub)
{
81 82
	size_t slen = strlen(s);
	size_t sublen = strlen(sub);
83 84

	if (sublen > slen)
85
		return 0;
86

87
	return !strncasecmp(s + slen - sublen, sub, sublen);
88 89
}

J
Jaegeuk Kim 已提交
90
/*
91 92
 * Set multimedia files as cold files for hot/cold data separation
 */
93
static inline void set_cold_files(struct f2fs_sb_info *sbi, struct inode *inode,
94 95 96 97 98 99 100
		const unsigned char *name)
{
	int i;
	__u8 (*extlist)[8] = sbi->raw_super->extension_list;

	int count = le32_to_cpu(sbi->raw_super->extension_count);
	for (i = 0; i < count; i++) {
101
		if (is_multimedia_file(name, extlist[i])) {
102
			file_set_cold(inode);
103 104 105 106 107 108 109 110
			break;
		}
	}
}

static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
						bool excl)
{
111
	struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
112 113
	struct inode *inode;
	nid_t ino = 0;
114
	int err;
115

116 117
	f2fs_balance_fs(sbi);

118 119 120 121 122
	inode = f2fs_new_inode(dir, mode);
	if (IS_ERR(inode))
		return PTR_ERR(inode);

	if (!test_opt(sbi, DISABLE_EXT_IDENTIFY))
123
		set_cold_files(sbi, inode, dentry->d_name.name);
124 125 126 127 128 129

	inode->i_op = &f2fs_file_inode_operations;
	inode->i_fop = &f2fs_file_operations;
	inode->i_mapping->a_ops = &f2fs_dblock_aops;
	ino = inode->i_ino;

130
	f2fs_lock_op(sbi);
131 132 133
	err = f2fs_add_link(dentry, inode);
	if (err)
		goto out;
134
	f2fs_unlock_op(sbi);
135 136 137

	alloc_nid_done(sbi, ino);

138
	stat_inc_inline_inode(inode);
139
	d_instantiate(dentry, inode);
140
	unlock_new_inode(inode);
J
Jaegeuk Kim 已提交
141 142 143

	if (IS_DIRSYNC(dir))
		f2fs_sync_fs(sbi->sb, 1);
144 145
	return 0;
out:
146
	handle_failed_inode(inode);
147 148 149 150 151 152 153
	return err;
}

static int f2fs_link(struct dentry *old_dentry, struct inode *dir,
		struct dentry *dentry)
{
	struct inode *inode = old_dentry->d_inode;
154
	struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
155
	int err;
156

157 158
	f2fs_balance_fs(sbi);

159
	inode->i_ctime = CURRENT_TIME;
J
Jaegeuk Kim 已提交
160
	ihold(inode);
161 162

	set_inode_flag(F2FS_I(inode), FI_INC_LINK);
163
	f2fs_lock_op(sbi);
164 165 166
	err = f2fs_add_link(dentry, inode);
	if (err)
		goto out;
167
	f2fs_unlock_op(sbi);
168 169

	d_instantiate(dentry, inode);
J
Jaegeuk Kim 已提交
170 171 172

	if (IS_DIRSYNC(dir))
		f2fs_sync_fs(sbi->sb, 1);
173 174 175 176
	return 0;
out:
	clear_inode_flag(F2FS_I(inode), FI_INC_LINK);
	iput(inode);
177
	f2fs_unlock_op(sbi);
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
	return err;
}

struct dentry *f2fs_get_parent(struct dentry *child)
{
	struct qstr dotdot = QSTR_INIT("..", 2);
	unsigned long ino = f2fs_inode_by_name(child->d_inode, &dotdot);
	if (!ino)
		return ERR_PTR(-ENOENT);
	return d_obtain_alias(f2fs_iget(child->d_inode->i_sb, ino));
}

static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry,
		unsigned int flags)
{
	struct inode *inode = NULL;
	struct f2fs_dir_entry *de;
	struct page *page;

197
	if (dentry->d_name.len > F2FS_NAME_LEN)
198 199 200 201 202
		return ERR_PTR(-ENAMETOOLONG);

	de = f2fs_find_entry(dir, &dentry->d_name, &page);
	if (de) {
		nid_t ino = le32_to_cpu(de->ino);
203
		f2fs_dentry_kunmap(dir, page);
204 205 206 207 208 209 210 211 212 213 214 215
		f2fs_put_page(page, 0);

		inode = f2fs_iget(dir->i_sb, ino);
		if (IS_ERR(inode))
			return ERR_CAST(inode);
	}

	return d_splice_alias(inode, dentry);
}

static int f2fs_unlink(struct inode *dir, struct dentry *dentry)
{
216
	struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
217 218 219 220 221
	struct inode *inode = dentry->d_inode;
	struct f2fs_dir_entry *de;
	struct page *page;
	int err = -ENOENT;

222
	trace_f2fs_unlink_enter(dir, dentry);
223 224
	f2fs_balance_fs(sbi);

225 226 227 228
	de = f2fs_find_entry(dir, &dentry->d_name, &page);
	if (!de)
		goto fail;

229
	f2fs_lock_op(sbi);
J
Jaegeuk Kim 已提交
230
	err = acquire_orphan_inode(sbi);
231
	if (err) {
232
		f2fs_unlock_op(sbi);
233
		f2fs_dentry_kunmap(dir, page);
234 235 236
		f2fs_put_page(page, 0);
		goto fail;
	}
237
	f2fs_delete_entry(de, page, dir, inode);
238
	f2fs_unlock_op(sbi);
239

A
arter97 已提交
240
	/* In order to evict this inode, we set it dirty */
241
	mark_inode_dirty(inode);
J
Jaegeuk Kim 已提交
242 243 244

	if (IS_DIRSYNC(dir))
		f2fs_sync_fs(sbi->sb, 1);
245
fail:
246
	trace_f2fs_unlink_exit(inode, err);
247 248 249 250 251 252
	return err;
}

static int f2fs_symlink(struct inode *dir, struct dentry *dentry,
					const char *symname)
{
253
	struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
254
	struct inode *inode;
255
	size_t symlen = strlen(symname) + 1;
256
	int err;
257

258 259
	f2fs_balance_fs(sbi);

260 261 262 263 264 265 266
	inode = f2fs_new_inode(dir, S_IFLNK | S_IRWXUGO);
	if (IS_ERR(inode))
		return PTR_ERR(inode);

	inode->i_op = &f2fs_symlink_inode_operations;
	inode->i_mapping->a_ops = &f2fs_dblock_aops;

267
	f2fs_lock_op(sbi);
268 269 270
	err = f2fs_add_link(dentry, inode);
	if (err)
		goto out;
271
	f2fs_unlock_op(sbi);
272 273 274 275 276 277

	err = page_symlink(inode, symname, symlen);
	alloc_nid_done(sbi, inode->i_ino);

	d_instantiate(dentry, inode);
	unlock_new_inode(inode);
J
Jaegeuk Kim 已提交
278 279 280

	if (IS_DIRSYNC(dir))
		f2fs_sync_fs(sbi->sb, 1);
281 282
	return err;
out:
283
	handle_failed_inode(inode);
284 285 286 287 288
	return err;
}

static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
{
289
	struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
290
	struct inode *inode;
291
	int err;
292

293 294
	f2fs_balance_fs(sbi);

295 296
	inode = f2fs_new_inode(dir, S_IFDIR | mode);
	if (IS_ERR(inode))
297
		return PTR_ERR(inode);
298 299 300 301

	inode->i_op = &f2fs_dir_inode_operations;
	inode->i_fop = &f2fs_dir_operations;
	inode->i_mapping->a_ops = &f2fs_dblock_aops;
302
	mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_HIGH_ZERO);
303 304

	set_inode_flag(F2FS_I(inode), FI_INC_LINK);
305
	f2fs_lock_op(sbi);
306 307 308
	err = f2fs_add_link(dentry, inode);
	if (err)
		goto out_fail;
309
	f2fs_unlock_op(sbi);
310

311
	stat_inc_inline_dir(inode);
312 313 314 315 316
	alloc_nid_done(sbi, inode->i_ino);

	d_instantiate(dentry, inode);
	unlock_new_inode(inode);

J
Jaegeuk Kim 已提交
317 318
	if (IS_DIRSYNC(dir))
		f2fs_sync_fs(sbi->sb, 1);
319 320 321 322
	return 0;

out_fail:
	clear_inode_flag(F2FS_I(inode), FI_INC_LINK);
323
	handle_failed_inode(inode);
324 325 326 327 328 329 330 331 332 333 334 335 336 337
	return err;
}

static int f2fs_rmdir(struct inode *dir, struct dentry *dentry)
{
	struct inode *inode = dentry->d_inode;
	if (f2fs_empty_dir(inode))
		return f2fs_unlink(dir, dentry);
	return -ENOTEMPTY;
}

static int f2fs_mknod(struct inode *dir, struct dentry *dentry,
				umode_t mode, dev_t rdev)
{
338
	struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
339 340 341 342 343 344
	struct inode *inode;
	int err = 0;

	if (!new_valid_dev(rdev))
		return -EINVAL;

345 346
	f2fs_balance_fs(sbi);

347 348 349 350 351 352 353
	inode = f2fs_new_inode(dir, mode);
	if (IS_ERR(inode))
		return PTR_ERR(inode);

	init_special_inode(inode, inode->i_mode, rdev);
	inode->i_op = &f2fs_special_inode_operations;

354
	f2fs_lock_op(sbi);
355 356 357
	err = f2fs_add_link(dentry, inode);
	if (err)
		goto out;
358
	f2fs_unlock_op(sbi);
359 360

	alloc_nid_done(sbi, inode->i_ino);
J
Jaegeuk Kim 已提交
361

362 363
	d_instantiate(dentry, inode);
	unlock_new_inode(inode);
J
Jaegeuk Kim 已提交
364 365 366

	if (IS_DIRSYNC(dir))
		f2fs_sync_fs(sbi->sb, 1);
367 368
	return 0;
out:
369
	handle_failed_inode(inode);
370 371 372 373 374 375
	return err;
}

static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
			struct inode *new_dir, struct dentry *new_dentry)
{
376
	struct f2fs_sb_info *sbi = F2FS_I_SB(old_dir);
377 378 379
	struct inode *old_inode = old_dentry->d_inode;
	struct inode *new_inode = new_dentry->d_inode;
	struct page *old_dir_page;
J
Jaegeuk Kim 已提交
380
	struct page *old_page, *new_page;
381 382 383
	struct f2fs_dir_entry *old_dir_entry = NULL;
	struct f2fs_dir_entry *old_entry;
	struct f2fs_dir_entry *new_entry;
384
	int err = -ENOENT;
385

386 387
	f2fs_balance_fs(sbi);

388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410
	old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page);
	if (!old_entry)
		goto out;

	if (S_ISDIR(old_inode->i_mode)) {
		err = -EIO;
		old_dir_entry = f2fs_parent_dir(old_inode, &old_dir_page);
		if (!old_dir_entry)
			goto out_old;
	}

	if (new_inode) {

		err = -ENOTEMPTY;
		if (old_dir_entry && !f2fs_empty_dir(new_inode))
			goto out_dir;

		err = -ENOENT;
		new_entry = f2fs_find_entry(new_dir, &new_dentry->d_name,
						&new_page);
		if (!new_entry)
			goto out_dir;

411 412
		f2fs_lock_op(sbi);

J
Jaegeuk Kim 已提交
413 414 415 416
		err = acquire_orphan_inode(sbi);
		if (err)
			goto put_out_dir;

417
		if (update_dent_inode(old_inode, &new_dentry->d_name)) {
J
Jaegeuk Kim 已提交
418 419
			release_orphan_inode(sbi);
			goto put_out_dir;
420 421
		}

422 423 424
		f2fs_set_link(new_dir, new_entry, new_page, old_inode);

		new_inode->i_ctime = CURRENT_TIME;
425
		down_write(&F2FS_I(new_inode)->i_sem);
426 427 428
		if (old_dir_entry)
			drop_nlink(new_inode);
		drop_nlink(new_inode);
429 430
		up_write(&F2FS_I(new_inode)->i_sem);

431
		mark_inode_dirty(new_inode);
J
Jaegeuk Kim 已提交
432

433 434
		if (!new_inode->i_nlink)
			add_orphan_inode(sbi, new_inode->i_ino);
J
Jaegeuk Kim 已提交
435 436 437
		else
			release_orphan_inode(sbi);

438
		update_inode_page(old_inode);
439
		update_inode_page(new_inode);
440
	} else {
441 442
		f2fs_lock_op(sbi);

443
		err = f2fs_add_link(new_dentry, old_inode);
444 445
		if (err) {
			f2fs_unlock_op(sbi);
446
			goto out_dir;
447
		}
448 449 450

		if (old_dir_entry) {
			inc_nlink(new_dir);
451
			update_inode_page(new_dir);
452 453 454
		}
	}

455 456 457 458
	down_write(&F2FS_I(old_inode)->i_sem);
	file_lost_pino(old_inode);
	up_write(&F2FS_I(old_inode)->i_sem);

459 460 461
	old_inode->i_ctime = CURRENT_TIME;
	mark_inode_dirty(old_inode);

462
	f2fs_delete_entry(old_entry, old_page, old_dir, NULL);
463 464 465 466 467

	if (old_dir_entry) {
		if (old_dir != new_dir) {
			f2fs_set_link(old_inode, old_dir_entry,
						old_dir_page, new_dir);
468
			update_inode_page(old_inode);
469
		} else {
470
			f2fs_dentry_kunmap(old_inode, old_dir_page);
471 472 473
			f2fs_put_page(old_dir_page, 0);
		}
		drop_nlink(old_dir);
474
		mark_inode_dirty(old_dir);
475
		update_inode_page(old_dir);
476 477
	}

478
	f2fs_unlock_op(sbi);
J
Jaegeuk Kim 已提交
479 480 481

	if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
		f2fs_sync_fs(sbi->sb, 1);
482 483
	return 0;

J
Jaegeuk Kim 已提交
484
put_out_dir:
485
	f2fs_unlock_op(sbi);
486
	f2fs_dentry_kunmap(new_dir, new_page);
487
	f2fs_put_page(new_page, 0);
488 489
out_dir:
	if (old_dir_entry) {
490
		f2fs_dentry_kunmap(old_inode, old_dir_page);
491 492 493
		f2fs_put_page(old_dir_page, 0);
	}
out_old:
494
	f2fs_dentry_kunmap(old_dir, old_page);
495 496 497 498 499
	f2fs_put_page(old_page, 0);
out:
	return err;
}

C
Chao Yu 已提交
500 501 502
static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
			     struct inode *new_dir, struct dentry *new_dentry)
{
503
	struct f2fs_sb_info *sbi = F2FS_I_SB(old_dir);
C
Chao Yu 已提交
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617
	struct inode *old_inode = old_dentry->d_inode;
	struct inode *new_inode = new_dentry->d_inode;
	struct page *old_dir_page, *new_dir_page;
	struct page *old_page, *new_page;
	struct f2fs_dir_entry *old_dir_entry = NULL, *new_dir_entry = NULL;
	struct f2fs_dir_entry *old_entry, *new_entry;
	int old_nlink = 0, new_nlink = 0;
	int err = -ENOENT;

	f2fs_balance_fs(sbi);

	old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page);
	if (!old_entry)
		goto out;

	new_entry = f2fs_find_entry(new_dir, &new_dentry->d_name, &new_page);
	if (!new_entry)
		goto out_old;

	/* prepare for updating ".." directory entry info later */
	if (old_dir != new_dir) {
		if (S_ISDIR(old_inode->i_mode)) {
			err = -EIO;
			old_dir_entry = f2fs_parent_dir(old_inode,
							&old_dir_page);
			if (!old_dir_entry)
				goto out_new;
		}

		if (S_ISDIR(new_inode->i_mode)) {
			err = -EIO;
			new_dir_entry = f2fs_parent_dir(new_inode,
							&new_dir_page);
			if (!new_dir_entry)
				goto out_old_dir;
		}
	}

	/*
	 * If cross rename between file and directory those are not
	 * in the same directory, we will inc nlink of file's parent
	 * later, so we should check upper boundary of its nlink.
	 */
	if ((!old_dir_entry || !new_dir_entry) &&
				old_dir_entry != new_dir_entry) {
		old_nlink = old_dir_entry ? -1 : 1;
		new_nlink = -old_nlink;
		err = -EMLINK;
		if ((old_nlink > 0 && old_inode->i_nlink >= F2FS_LINK_MAX) ||
			(new_nlink > 0 && new_inode->i_nlink >= F2FS_LINK_MAX))
			goto out_new_dir;
	}

	f2fs_lock_op(sbi);

	err = update_dent_inode(old_inode, &new_dentry->d_name);
	if (err)
		goto out_unlock;

	err = update_dent_inode(new_inode, &old_dentry->d_name);
	if (err)
		goto out_undo;

	/* update ".." directory entry info of old dentry */
	if (old_dir_entry)
		f2fs_set_link(old_inode, old_dir_entry, old_dir_page, new_dir);

	/* update ".." directory entry info of new dentry */
	if (new_dir_entry)
		f2fs_set_link(new_inode, new_dir_entry, new_dir_page, old_dir);

	/* update directory entry info of old dir inode */
	f2fs_set_link(old_dir, old_entry, old_page, new_inode);

	down_write(&F2FS_I(old_inode)->i_sem);
	file_lost_pino(old_inode);
	up_write(&F2FS_I(old_inode)->i_sem);

	update_inode_page(old_inode);

	old_dir->i_ctime = CURRENT_TIME;
	if (old_nlink) {
		down_write(&F2FS_I(old_dir)->i_sem);
		if (old_nlink < 0)
			drop_nlink(old_dir);
		else
			inc_nlink(old_dir);
		up_write(&F2FS_I(old_dir)->i_sem);
	}
	mark_inode_dirty(old_dir);
	update_inode_page(old_dir);

	/* update directory entry info of new dir inode */
	f2fs_set_link(new_dir, new_entry, new_page, old_inode);

	down_write(&F2FS_I(new_inode)->i_sem);
	file_lost_pino(new_inode);
	up_write(&F2FS_I(new_inode)->i_sem);

	update_inode_page(new_inode);

	new_dir->i_ctime = CURRENT_TIME;
	if (new_nlink) {
		down_write(&F2FS_I(new_dir)->i_sem);
		if (new_nlink < 0)
			drop_nlink(new_dir);
		else
			inc_nlink(new_dir);
		up_write(&F2FS_I(new_dir)->i_sem);
	}
	mark_inode_dirty(new_dir);
	update_inode_page(new_dir);

	f2fs_unlock_op(sbi);
J
Jaegeuk Kim 已提交
618 619 620

	if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
		f2fs_sync_fs(sbi->sb, 1);
C
Chao Yu 已提交
621 622 623 624 625 626 627 628
	return 0;
out_undo:
	/* Still we may fail to recover name info of f2fs_inode here */
	update_dent_inode(old_inode, &old_dentry->d_name);
out_unlock:
	f2fs_unlock_op(sbi);
out_new_dir:
	if (new_dir_entry) {
629
		f2fs_dentry_kunmap(new_inode, new_dir_page);
C
Chao Yu 已提交
630 631 632 633
		f2fs_put_page(new_dir_page, 0);
	}
out_old_dir:
	if (old_dir_entry) {
634
		f2fs_dentry_kunmap(old_inode, old_dir_page);
C
Chao Yu 已提交
635 636 637
		f2fs_put_page(old_dir_page, 0);
	}
out_new:
638
	f2fs_dentry_kunmap(new_dir, new_page);
C
Chao Yu 已提交
639 640
	f2fs_put_page(new_page, 0);
out_old:
641
	f2fs_dentry_kunmap(old_dir, old_page);
C
Chao Yu 已提交
642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664
	f2fs_put_page(old_page, 0);
out:
	return err;
}

static int f2fs_rename2(struct inode *old_dir, struct dentry *old_dentry,
			struct inode *new_dir, struct dentry *new_dentry,
			unsigned int flags)
{
	if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
		return -EINVAL;

	if (flags & RENAME_EXCHANGE) {
		return f2fs_cross_rename(old_dir, old_dentry,
					 new_dir, new_dentry);
	}
	/*
	 * VFS has already handled the new dentry existence case,
	 * here, we just deal with "RENAME_NOREPLACE" as regular rename.
	 */
	return f2fs_rename(old_dir, old_dentry, new_dir, new_dentry);
}

C
Chao Yu 已提交
665 666
static int f2fs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
{
667
	struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
C
Chao Yu 已提交
668 669 670 671 672 673 674 675 676 677 678 679 680 681 682
	struct inode *inode;
	int err;

	inode = f2fs_new_inode(dir, mode);
	if (IS_ERR(inode))
		return PTR_ERR(inode);

	inode->i_op = &f2fs_file_inode_operations;
	inode->i_fop = &f2fs_file_operations;
	inode->i_mapping->a_ops = &f2fs_dblock_aops;

	f2fs_lock_op(sbi);
	err = acquire_orphan_inode(sbi);
	if (err)
		goto out;
683 684 685 686 687

	err = f2fs_do_tmpfile(inode, dir);
	if (err)
		goto release_out;

C
Chao Yu 已提交
688 689 690 691 692 693 694 695
	/*
	 * add this non-linked tmpfile to orphan list, in this way we could
	 * remove all unused data of tmpfile after abnormal power-off.
	 */
	add_orphan_inode(sbi, inode->i_ino);
	f2fs_unlock_op(sbi);

	alloc_nid_done(sbi, inode->i_ino);
696 697

	stat_inc_inline_inode(inode);
C
Chao Yu 已提交
698 699 700
	d_tmpfile(dentry, inode);
	unlock_new_inode(inode);
	return 0;
701 702 703

release_out:
	release_orphan_inode(sbi);
C
Chao Yu 已提交
704
out:
705
	handle_failed_inode(inode);
C
Chao Yu 已提交
706 707 708
	return err;
}

709 710 711 712 713 714 715 716 717
const struct inode_operations f2fs_dir_inode_operations = {
	.create		= f2fs_create,
	.lookup		= f2fs_lookup,
	.link		= f2fs_link,
	.unlink		= f2fs_unlink,
	.symlink	= f2fs_symlink,
	.mkdir		= f2fs_mkdir,
	.rmdir		= f2fs_rmdir,
	.mknod		= f2fs_mknod,
C
Chao Yu 已提交
718
	.rename2	= f2fs_rename2,
C
Chao Yu 已提交
719
	.tmpfile	= f2fs_tmpfile,
720
	.getattr	= f2fs_getattr,
721 722
	.setattr	= f2fs_setattr,
	.get_acl	= f2fs_get_acl,
723
	.set_acl	= f2fs_set_acl,
724 725 726 727 728 729 730 731 732 733 734 735
#ifdef CONFIG_F2FS_FS_XATTR
	.setxattr	= generic_setxattr,
	.getxattr	= generic_getxattr,
	.listxattr	= f2fs_listxattr,
	.removexattr	= generic_removexattr,
#endif
};

const struct inode_operations f2fs_symlink_inode_operations = {
	.readlink       = generic_readlink,
	.follow_link    = page_follow_link_light,
	.put_link       = page_put_link,
736
	.getattr	= f2fs_getattr,
737 738 739 740 741 742 743 744 745 746
	.setattr	= f2fs_setattr,
#ifdef CONFIG_F2FS_FS_XATTR
	.setxattr	= generic_setxattr,
	.getxattr	= generic_getxattr,
	.listxattr	= f2fs_listxattr,
	.removexattr	= generic_removexattr,
#endif
};

const struct inode_operations f2fs_special_inode_operations = {
747
	.getattr	= f2fs_getattr,
748 749
	.setattr        = f2fs_setattr,
	.get_acl	= f2fs_get_acl,
750
	.set_acl	= f2fs_set_acl,
751 752 753 754 755 756 757
#ifdef CONFIG_F2FS_FS_XATTR
	.setxattr       = generic_setxattr,
	.getxattr       = generic_getxattr,
	.listxattr	= f2fs_listxattr,
	.removexattr    = generic_removexattr,
#endif
};