diff options
Diffstat (limited to 'fs/sysv/namei.c')
-rw-r--r-- | fs/sysv/namei.c | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index 371cf9012052..1bfe788851a9 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c @@ -153,19 +153,18 @@ static int sysv_unlink(struct inode * dir, struct dentry * dentry) struct inode * inode = d_inode(dentry); struct page * page; struct sysv_dir_entry * de; - int err = -ENOENT; + int err; de = sysv_find_entry(dentry, &page); if (!de) - goto out; - - err = sysv_delete_entry (de, page); - if (err) - goto out; + return -ENOENT; - inode->i_ctime = dir->i_ctime; - inode_dec_link_count(inode); -out: + err = sysv_delete_entry(de, page); + if (!err) { + inode->i_ctime = dir->i_ctime; + inode_dec_link_count(inode); + } + dir_put_page(page, de); return err; } @@ -227,7 +226,10 @@ static int sysv_rename(struct user_namespace *mnt_userns, struct inode *old_dir, new_de = sysv_find_entry(new_dentry, &new_page); if (!new_de) goto out_dir; - sysv_set_link(new_de, new_page, old_inode); + err = sysv_set_link(new_de, new_page, old_inode); + dir_put_page(new_page, new_de); + if (err) + goto out_dir; new_inode->i_ctime = current_time(new_inode); if (dir_de) drop_nlink(new_inode); @@ -240,14 +242,17 @@ static int sysv_rename(struct user_namespace *mnt_userns, struct inode *old_dir, inode_inc_link_count(new_dir); } - sysv_delete_entry(old_de, old_page); + err = sysv_delete_entry(old_de, old_page); + if (err) + goto out_dir; + mark_inode_dirty(old_inode); if (dir_de) { - sysv_set_link(dir_de, dir_page, new_dir); - inode_dec_link_count(old_dir); + err = sysv_set_link(dir_de, dir_page, new_dir); + if (!err) + inode_dec_link_count(old_dir); } - return 0; out_dir: if (dir_de) |