namei.c 13.5 KB
Newer Older
R
Ryusuke Konishi 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
/*
 * namei.c - NILFS pathname lookup operations.
 *
 * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Modified for NILFS by Amagai Yoshiji <amagai@osrg.net>,
 *                       Ryusuke Konishi <ryusuke@osrg.net>
 */
/*
 *  linux/fs/ext2/namei.c
 *
 * Copyright (C) 1992, 1993, 1994, 1995
 * Remy Card (card@masi.ibp.fr)
 * Laboratoire MASI - Institut Blaise Pascal
 * Universite Pierre et Marie Curie (Paris VI)
 *
 *  from
 *
 *  linux/fs/minix/namei.c
 *
 *  Copyright (C) 1991, 1992  Linus Torvalds
 *
 *  Big-endian to little-endian byte-swapping/bitmaps by
 *        David S. Miller (davem@caip.rutgers.edu), 1995
 */

#include <linux/pagemap.h>
#include "nilfs.h"
43
#include "export.h"
R
Ryusuke Konishi 已提交
44

45 46 47
#define NILFS_FID_SIZE_NON_CONNECTABLE \
	(offsetof(struct nilfs_fid, parent_gen) / 4)
#define NILFS_FID_SIZE_CONNECTABLE	(sizeof(struct nilfs_fid) / 4)
R
Ryusuke Konishi 已提交
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73

static inline int nilfs_add_nondir(struct dentry *dentry, struct inode *inode)
{
	int err = nilfs_add_link(dentry, inode);
	if (!err) {
		d_instantiate(dentry, inode);
		return 0;
	}
	inode_dec_link_count(inode);
	iput(inode);
	return err;
}

/*
 * Methods themselves.
 */

static struct dentry *
nilfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
{
	struct inode *inode;
	ino_t ino;

	if (dentry->d_name.len > NILFS_NAME_LEN)
		return ERR_PTR(-ENAMETOOLONG);

74
	ino = nilfs_inode_by_name(dir, &dentry->d_name);
R
Ryusuke Konishi 已提交
75 76
	inode = NULL;
	if (ino) {
77
		inode = nilfs_iget(dir->i_sb, NILFS_I(dir)->i_root, ino);
R
Ryusuke Konishi 已提交
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
		if (IS_ERR(inode))
			return ERR_CAST(inode);
	}
	return d_splice_alias(inode, dentry);
}

/*
 * By the time this is called, we already have created
 * the directory cache entry for the new file, but it
 * is so far negative - it has no inode.
 *
 * If the create succeeds, we fill in the inode information
 * with d_instantiate().
 */
static int nilfs_create(struct inode *dir, struct dentry *dentry, int mode,
			struct nameidata *nd)
{
	struct inode *inode;
	struct nilfs_transaction_info ti;
97
	int err;
R
Ryusuke Konishi 已提交
98 99 100 101 102 103 104 105 106 107

	err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
	if (err)
		return err;
	inode = nilfs_new_inode(dir, mode);
	err = PTR_ERR(inode);
	if (!IS_ERR(inode)) {
		inode->i_op = &nilfs_file_inode_operations;
		inode->i_fop = &nilfs_file_operations;
		inode->i_mapping->a_ops = &nilfs_aops;
108
		nilfs_mark_inode_dirty(inode);
R
Ryusuke Konishi 已提交
109 110
		err = nilfs_add_nondir(dentry, inode);
	}
111 112 113 114 115 116
	if (!err)
		err = nilfs_transaction_commit(dir->i_sb);
	else
		nilfs_transaction_abort(dir->i_sb);

	return err;
R
Ryusuke Konishi 已提交
117 118 119 120 121 122 123
}

static int
nilfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
{
	struct inode *inode;
	struct nilfs_transaction_info ti;
124
	int err;
R
Ryusuke Konishi 已提交
125 126 127 128 129 130 131 132 133 134 135

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

	err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
	if (err)
		return err;
	inode = nilfs_new_inode(dir, mode);
	err = PTR_ERR(inode);
	if (!IS_ERR(inode)) {
		init_special_inode(inode, inode->i_mode, rdev);
136
		nilfs_mark_inode_dirty(inode);
R
Ryusuke Konishi 已提交
137 138
		err = nilfs_add_nondir(dentry, inode);
	}
139 140 141 142 143 144
	if (!err)
		err = nilfs_transaction_commit(dir->i_sb);
	else
		nilfs_transaction_abort(dir->i_sb);

	return err;
R
Ryusuke Konishi 已提交
145 146 147 148 149 150 151 152 153
}

static int nilfs_symlink(struct inode *dir, struct dentry *dentry,
			 const char *symname)
{
	struct nilfs_transaction_info ti;
	struct super_block *sb = dir->i_sb;
	unsigned l = strlen(symname)+1;
	struct inode *inode;
154
	int err;
R
Ryusuke Konishi 已提交
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175

	if (l > sb->s_blocksize)
		return -ENAMETOOLONG;

	err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
	if (err)
		return err;

	inode = nilfs_new_inode(dir, S_IFLNK | S_IRWXUGO);
	err = PTR_ERR(inode);
	if (IS_ERR(inode))
		goto out;

	/* slow symlink */
	inode->i_op = &nilfs_symlink_inode_operations;
	inode->i_mapping->a_ops = &nilfs_aops;
	err = page_symlink(inode, symname, l);
	if (err)
		goto out_fail;

	/* mark_inode_dirty(inode); */
176
	/* page_symlink() do this */
R
Ryusuke Konishi 已提交
177 178 179

	err = nilfs_add_nondir(dentry, inode);
out:
180 181 182 183 184 185
	if (!err)
		err = nilfs_transaction_commit(dir->i_sb);
	else
		nilfs_transaction_abort(dir->i_sb);

	return err;
R
Ryusuke Konishi 已提交
186 187

out_fail:
188
	drop_nlink(inode);
189
	nilfs_mark_inode_dirty(inode);
R
Ryusuke Konishi 已提交
190 191 192 193 194 195 196 197 198
	iput(inode);
	goto out;
}

static int nilfs_link(struct dentry *old_dentry, struct inode *dir,
		      struct dentry *dentry)
{
	struct inode *inode = old_dentry->d_inode;
	struct nilfs_transaction_info ti;
199
	int err;
R
Ryusuke Konishi 已提交
200 201 202 203 204 205 206 207 208 209 210 211 212

	if (inode->i_nlink >= NILFS_LINK_MAX)
		return -EMLINK;

	err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
	if (err)
		return err;

	inode->i_ctime = CURRENT_TIME;
	inode_inc_link_count(inode);
	atomic_inc(&inode->i_count);

	err = nilfs_add_nondir(dentry, inode);
213 214 215 216 217 218
	if (!err)
		err = nilfs_transaction_commit(dir->i_sb);
	else
		nilfs_transaction_abort(dir->i_sb);

	return err;
R
Ryusuke Konishi 已提交
219 220 221 222 223 224
}

static int nilfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
{
	struct inode *inode;
	struct nilfs_transaction_info ti;
225
	int err;
R
Ryusuke Konishi 已提交
226 227 228 229 230 231 232 233

	if (dir->i_nlink >= NILFS_LINK_MAX)
		return -EMLINK;

	err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
	if (err)
		return err;

234
	inc_nlink(dir);
R
Ryusuke Konishi 已提交
235 236 237 238 239 240 241 242 243 244

	inode = nilfs_new_inode(dir, S_IFDIR | mode);
	err = PTR_ERR(inode);
	if (IS_ERR(inode))
		goto out_dir;

	inode->i_op = &nilfs_dir_inode_operations;
	inode->i_fop = &nilfs_dir_operations;
	inode->i_mapping->a_ops = &nilfs_aops;

245
	inc_nlink(inode);
R
Ryusuke Konishi 已提交
246 247 248 249 250 251 252 253 254

	err = nilfs_make_empty(inode, dir);
	if (err)
		goto out_fail;

	err = nilfs_add_link(dentry, inode);
	if (err)
		goto out_fail;

255
	nilfs_mark_inode_dirty(inode);
R
Ryusuke Konishi 已提交
256 257
	d_instantiate(dentry, inode);
out:
258 259 260 261 262 263
	if (!err)
		err = nilfs_transaction_commit(dir->i_sb);
	else
		nilfs_transaction_abort(dir->i_sb);

	return err;
R
Ryusuke Konishi 已提交
264 265

out_fail:
266 267
	drop_nlink(inode);
	drop_nlink(inode);
268
	nilfs_mark_inode_dirty(inode);
R
Ryusuke Konishi 已提交
269 270
	iput(inode);
out_dir:
271
	drop_nlink(dir);
272
	nilfs_mark_inode_dirty(dir);
R
Ryusuke Konishi 已提交
273 274 275
	goto out;
}

276
static int nilfs_do_unlink(struct inode *dir, struct dentry *dentry)
R
Ryusuke Konishi 已提交
277 278 279 280
{
	struct inode *inode;
	struct nilfs_dir_entry *de;
	struct page *page;
281
	int err;
R
Ryusuke Konishi 已提交
282 283

	err = -ENOENT;
284
	de = nilfs_find_entry(dir, &dentry->d_name, &page);
R
Ryusuke Konishi 已提交
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
	if (!de)
		goto out;

	inode = dentry->d_inode;
	err = -EIO;
	if (le64_to_cpu(de->inode) != inode->i_ino)
		goto out;

	if (!inode->i_nlink) {
		nilfs_warning(inode->i_sb, __func__,
			      "deleting nonexistent file (%lu), %d\n",
			      inode->i_ino, inode->i_nlink);
		inode->i_nlink = 1;
	}
	err = nilfs_delete_entry(de, page);
	if (err)
		goto out;

	inode->i_ctime = dir->i_ctime;
304
	drop_nlink(inode);
R
Ryusuke Konishi 已提交
305 306
	err = 0;
out:
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321
	return err;
}

static int nilfs_unlink(struct inode *dir, struct dentry *dentry)
{
	struct nilfs_transaction_info ti;
	int err;

	err = nilfs_transaction_begin(dir->i_sb, &ti, 0);
	if (err)
		return err;

	err = nilfs_do_unlink(dir, dentry);

	if (!err) {
322 323
		nilfs_mark_inode_dirty(dir);
		nilfs_mark_inode_dirty(dentry->d_inode);
324
		err = nilfs_transaction_commit(dir->i_sb);
325
	} else
326 327 328
		nilfs_transaction_abort(dir->i_sb);

	return err;
R
Ryusuke Konishi 已提交
329 330 331 332 333 334
}

static int nilfs_rmdir(struct inode *dir, struct dentry *dentry)
{
	struct inode *inode = dentry->d_inode;
	struct nilfs_transaction_info ti;
335
	int err;
R
Ryusuke Konishi 已提交
336 337 338 339 340 341 342

	err = nilfs_transaction_begin(dir->i_sb, &ti, 0);
	if (err)
		return err;

	err = -ENOTEMPTY;
	if (nilfs_empty_dir(inode)) {
343
		err = nilfs_do_unlink(dir, dentry);
R
Ryusuke Konishi 已提交
344 345
		if (!err) {
			inode->i_size = 0;
346
			drop_nlink(inode);
347
			nilfs_mark_inode_dirty(inode);
348
			drop_nlink(dir);
349
			nilfs_mark_inode_dirty(dir);
R
Ryusuke Konishi 已提交
350 351
		}
	}
352 353 354 355 356 357
	if (!err)
		err = nilfs_transaction_commit(dir->i_sb);
	else
		nilfs_transaction_abort(dir->i_sb);

	return err;
R
Ryusuke Konishi 已提交
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
}

static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry,
			struct inode *new_dir,	struct dentry *new_dentry)
{
	struct inode *old_inode = old_dentry->d_inode;
	struct inode *new_inode = new_dentry->d_inode;
	struct page *dir_page = NULL;
	struct nilfs_dir_entry *dir_de = NULL;
	struct page *old_page;
	struct nilfs_dir_entry *old_de;
	struct nilfs_transaction_info ti;
	int err;

	err = nilfs_transaction_begin(old_dir->i_sb, &ti, 1);
	if (unlikely(err))
		return err;

	err = -ENOENT;
377
	old_de = nilfs_find_entry(old_dir, &old_dentry->d_name, &old_page);
R
Ryusuke Konishi 已提交
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396
	if (!old_de)
		goto out;

	if (S_ISDIR(old_inode->i_mode)) {
		err = -EIO;
		dir_de = nilfs_dotdot(old_inode, &dir_page);
		if (!dir_de)
			goto out_old;
	}

	if (new_inode) {
		struct page *new_page;
		struct nilfs_dir_entry *new_de;

		err = -ENOTEMPTY;
		if (dir_de && !nilfs_empty_dir(new_inode))
			goto out_dir;

		err = -ENOENT;
397
		new_de = nilfs_find_entry(new_dir, &new_dentry->d_name, &new_page);
R
Ryusuke Konishi 已提交
398 399
		if (!new_de)
			goto out_dir;
400
		inc_nlink(old_inode);
R
Ryusuke Konishi 已提交
401
		nilfs_set_link(new_dir, new_de, new_page, old_inode);
402
		nilfs_mark_inode_dirty(new_dir);
R
Ryusuke Konishi 已提交
403 404 405
		new_inode->i_ctime = CURRENT_TIME;
		if (dir_de)
			drop_nlink(new_inode);
406
		drop_nlink(new_inode);
407
		nilfs_mark_inode_dirty(new_inode);
R
Ryusuke Konishi 已提交
408 409 410 411 412 413
	} else {
		if (dir_de) {
			err = -EMLINK;
			if (new_dir->i_nlink >= NILFS_LINK_MAX)
				goto out_dir;
		}
414
		inc_nlink(old_inode);
R
Ryusuke Konishi 已提交
415 416
		err = nilfs_add_link(new_dentry, old_inode);
		if (err) {
417
			drop_nlink(old_inode);
418
			nilfs_mark_inode_dirty(old_inode);
R
Ryusuke Konishi 已提交
419 420
			goto out_dir;
		}
421 422
		if (dir_de) {
			inc_nlink(new_dir);
423
			nilfs_mark_inode_dirty(new_dir);
424
		}
R
Ryusuke Konishi 已提交
425 426 427 428 429 430 431 432 433
	}

	/*
	 * Like most other Unix systems, set the ctime for inodes on a
	 * rename.
	 */
	old_inode->i_ctime = CURRENT_TIME;

	nilfs_delete_entry(old_de, old_page);
434
	drop_nlink(old_inode);
R
Ryusuke Konishi 已提交
435 436 437

	if (dir_de) {
		nilfs_set_link(old_inode, dir_de, dir_page, new_dir);
438
		drop_nlink(old_dir);
R
Ryusuke Konishi 已提交
439
	}
440 441
	nilfs_mark_inode_dirty(old_dir);
	nilfs_mark_inode_dirty(old_inode);
R
Ryusuke Konishi 已提交
442

443
	err = nilfs_transaction_commit(old_dir->i_sb);
R
Ryusuke Konishi 已提交
444 445 446 447 448 449 450 451 452 453 454
	return err;

out_dir:
	if (dir_de) {
		kunmap(dir_page);
		page_cache_release(dir_page);
	}
out_old:
	kunmap(old_page);
	page_cache_release(old_page);
out:
455
	nilfs_transaction_abort(old_dir->i_sb);
R
Ryusuke Konishi 已提交
456 457 458
	return err;
}

459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 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
/*
 * Export operations
 */
static struct dentry *nilfs_get_parent(struct dentry *child)
{
	unsigned long ino;
	struct inode *inode;
	struct qstr dotdot = {.name = "..", .len = 2};
	struct nilfs_root *root;

	ino = nilfs_inode_by_name(child->d_inode, &dotdot);
	if (!ino)
		return ERR_PTR(-ENOENT);

	root = NILFS_I(child->d_inode)->i_root;

	inode = nilfs_iget(child->d_inode->i_sb, root, ino);
	if (IS_ERR(inode))
		return ERR_CAST(inode);

	return d_obtain_alias(inode);
}

static struct dentry *nilfs_get_dentry(struct super_block *sb, u64 cno,
				       u64 ino, u32 gen)
{
	struct nilfs_root *root;
	struct inode *inode;

	if (ino < NILFS_FIRST_INO(sb) && ino != NILFS_ROOT_INO)
		return ERR_PTR(-ESTALE);

	root = nilfs_lookup_root(NILFS_SB(sb)->s_nilfs, cno);
	if (!root)
		return ERR_PTR(-ESTALE);

	inode = nilfs_iget(sb, root, ino);
	nilfs_put_root(root);

	if (IS_ERR(inode))
		return ERR_CAST(inode);
	if (gen && inode->i_generation != gen) {
		iput(inode);
		return ERR_PTR(-ESTALE);
	}
	return d_obtain_alias(inode);
}

static struct dentry *nilfs_fh_to_dentry(struct super_block *sb, struct fid *fh,
					 int fh_len, int fh_type)
{
	struct nilfs_fid *fid = (struct nilfs_fid *)fh;

	if ((fh_len != NILFS_FID_SIZE_NON_CONNECTABLE &&
	     fh_len != NILFS_FID_SIZE_CONNECTABLE) ||
	    (fh_type != FILEID_NILFS_WITH_PARENT &&
	     fh_type != FILEID_NILFS_WITHOUT_PARENT))
		return NULL;

	return nilfs_get_dentry(sb, fid->cno, fid->ino, fid->gen);
}

static struct dentry *nilfs_fh_to_parent(struct super_block *sb, struct fid *fh,
					 int fh_len, int fh_type)
{
	struct nilfs_fid *fid = (struct nilfs_fid *)fh;

	if (fh_len != NILFS_FID_SIZE_CONNECTABLE ||
	    fh_type != FILEID_NILFS_WITH_PARENT)
		return NULL;

	return nilfs_get_dentry(sb, fid->cno, fid->parent_ino, fid->parent_gen);
}

static int nilfs_encode_fh(struct dentry *dentry, __u32 *fh, int *lenp,
			   int connectable)
{
	struct nilfs_fid *fid = (struct nilfs_fid *)fh;
	struct inode *inode = dentry->d_inode;
	struct nilfs_root *root = NILFS_I(inode)->i_root;
	int type;

	if (*lenp < NILFS_FID_SIZE_NON_CONNECTABLE ||
	    (connectable && *lenp < NILFS_FID_SIZE_CONNECTABLE))
		return 255;

	fid->cno = root->cno;
	fid->ino = inode->i_ino;
	fid->gen = inode->i_generation;

	if (connectable && !S_ISDIR(inode->i_mode)) {
		struct inode *parent;

		spin_lock(&dentry->d_lock);
		parent = dentry->d_parent->d_inode;
		fid->parent_ino = parent->i_ino;
		fid->parent_gen = parent->i_generation;
		spin_unlock(&dentry->d_lock);

		type = FILEID_NILFS_WITH_PARENT;
		*lenp = NILFS_FID_SIZE_CONNECTABLE;
	} else {
		type = FILEID_NILFS_WITHOUT_PARENT;
		*lenp = NILFS_FID_SIZE_NON_CONNECTABLE;
	}

	return type;
}

568
const struct inode_operations nilfs_dir_inode_operations = {
R
Ryusuke Konishi 已提交
569 570 571 572 573 574 575 576 577 578 579 580 581
	.create		= nilfs_create,
	.lookup		= nilfs_lookup,
	.link		= nilfs_link,
	.unlink		= nilfs_unlink,
	.symlink	= nilfs_symlink,
	.mkdir		= nilfs_mkdir,
	.rmdir		= nilfs_rmdir,
	.mknod		= nilfs_mknod,
	.rename		= nilfs_rename,
	.setattr	= nilfs_setattr,
	.permission	= nilfs_permission,
};

582
const struct inode_operations nilfs_special_inode_operations = {
R
Ryusuke Konishi 已提交
583 584 585 586
	.setattr	= nilfs_setattr,
	.permission	= nilfs_permission,
};

587
const struct inode_operations nilfs_symlink_inode_operations = {
R
Ryusuke Konishi 已提交
588 589 590 591
	.readlink	= generic_readlink,
	.follow_link	= page_follow_link_light,
	.put_link	= page_put_link,
};
592 593 594 595 596 597 598

const struct export_operations nilfs_export_ops = {
	.encode_fh = nilfs_encode_fh,
	.fh_to_dentry = nilfs_fh_to_dentry,
	.fh_to_parent = nilfs_fh_to_parent,
	.get_parent = nilfs_get_parent,
};