aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'fs/affs/namei.c')
-rw-r--r--fs/affs/namei.c87
1 files changed, 73 insertions, 14 deletions
diff --git a/fs/affs/namei.c b/fs/affs/namei.c
index 96dd1d09a273..46d3ace6761d 100644
--- a/fs/affs/namei.c
+++ b/fs/affs/namei.c
@@ -365,6 +365,7 @@ affs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
365 symname++; 365 symname++;
366 } 366 }
367 *p = 0; 367 *p = 0;
368 inode->i_size = i + 1;
368 mark_buffer_dirty_inode(bh, inode); 369 mark_buffer_dirty_inode(bh, inode);
369 affs_brelse(bh); 370 affs_brelse(bh);
370 mark_inode_dirty(inode); 371 mark_inode_dirty(inode);
@@ -393,21 +394,14 @@ affs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
393 return affs_add_entry(dir, inode, dentry, ST_LINKFILE); 394 return affs_add_entry(dir, inode, dentry, ST_LINKFILE);
394} 395}
395 396
396int 397static int
397affs_rename(struct inode *old_dir, struct dentry *old_dentry, 398affs_rename(struct inode *old_dir, struct dentry *old_dentry,
398 struct inode *new_dir, struct dentry *new_dentry, 399 struct inode *new_dir, struct dentry *new_dentry)
399 unsigned int flags)
400{ 400{
401 struct super_block *sb = old_dir->i_sb; 401 struct super_block *sb = old_dir->i_sb;
402 struct buffer_head *bh = NULL; 402 struct buffer_head *bh = NULL;
403 int retval; 403 int retval;
404 404
405 if (flags & ~RENAME_NOREPLACE)
406 return -EINVAL;
407
408 pr_debug("%s(old=%lu,\"%pd\" to new=%lu,\"%pd\")\n", __func__,
409 old_dir->i_ino, old_dentry, new_dir->i_ino, new_dentry);
410
411 retval = affs_check_name(new_dentry->d_name.name, 405 retval = affs_check_name(new_dentry->d_name.name,
412 new_dentry->d_name.len, 406 new_dentry->d_name.len,
413 affs_nofilenametruncate(old_dentry)); 407 affs_nofilenametruncate(old_dentry));
@@ -447,6 +441,76 @@ done:
447 return retval; 441 return retval;
448} 442}
449 443
444static int
445affs_xrename(struct inode *old_dir, struct dentry *old_dentry,
446 struct inode *new_dir, struct dentry *new_dentry)
447{
448
449 struct super_block *sb = old_dir->i_sb;
450 struct buffer_head *bh_old = NULL;
451 struct buffer_head *bh_new = NULL;
452 int retval;
453
454 bh_old = affs_bread(sb, d_inode(old_dentry)->i_ino);
455 if (!bh_old)
456 return -EIO;
457
458 bh_new = affs_bread(sb, d_inode(new_dentry)->i_ino);
459 if (!bh_new)
460 return -EIO;
461
462 /* Remove old header from its parent directory. */
463 affs_lock_dir(old_dir);
464 retval = affs_remove_hash(old_dir, bh_old);
465 affs_unlock_dir(old_dir);
466 if (retval)
467 goto done;
468
469 /* Remove new header from its parent directory. */
470 affs_lock_dir(new_dir);
471 retval = affs_remove_hash(new_dir, bh_new);
472 affs_unlock_dir(new_dir);
473 if (retval)
474 goto done;
475
476 /* Insert old into the new directory with the new name. */
477 affs_copy_name(AFFS_TAIL(sb, bh_old)->name, new_dentry);
478 affs_fix_checksum(sb, bh_old);
479 affs_lock_dir(new_dir);
480 retval = affs_insert_hash(new_dir, bh_old);
481 affs_unlock_dir(new_dir);
482
483 /* Insert new into the old directory with the old name. */
484 affs_copy_name(AFFS_TAIL(sb, bh_new)->name, old_dentry);
485 affs_fix_checksum(sb, bh_new);
486 affs_lock_dir(old_dir);
487 retval = affs_insert_hash(old_dir, bh_new);
488 affs_unlock_dir(old_dir);
489done:
490 mark_buffer_dirty_inode(bh_old, new_dir);
491 mark_buffer_dirty_inode(bh_new, old_dir);
492 affs_brelse(bh_old);
493 affs_brelse(bh_new);
494 return retval;
495}
496
497int affs_rename2(struct inode *old_dir, struct dentry *old_dentry,
498 struct inode *new_dir, struct dentry *new_dentry,
499 unsigned int flags)
500{
501
502 if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
503 return -EINVAL;
504
505 pr_debug("%s(old=%lu,\"%pd\" to new=%lu,\"%pd\")\n", __func__,
506 old_dir->i_ino, old_dentry, new_dir->i_ino, new_dentry);
507
508 if (flags & RENAME_EXCHANGE)
509 return affs_xrename(old_dir, old_dentry, new_dir, new_dentry);
510
511 return affs_rename(old_dir, old_dentry, new_dir, new_dentry);
512}
513
450static struct dentry *affs_get_parent(struct dentry *child) 514static struct dentry *affs_get_parent(struct dentry *child)
451{ 515{
452 struct inode *parent; 516 struct inode *parent;
@@ -477,11 +541,6 @@ static struct inode *affs_nfs_get_inode(struct super_block *sb, u64 ino,
477 if (IS_ERR(inode)) 541 if (IS_ERR(inode))
478 return ERR_CAST(inode); 542 return ERR_CAST(inode);
479 543
480 if (generation && inode->i_generation != generation) {
481 iput(inode);
482 return ERR_PTR(-ESTALE);
483 }
484
485 return inode; 544 return inode;
486} 545}
487 546