Commit 8f1dca19 authored by Al Viro's avatar Al Viro Committed by Jan Kara
Browse files

ext2_rename(): set_link and delete_entry may fail

parent 6e335cd7
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -606,8 +606,7 @@ int ext2_delete_entry (struct ext2_dir_entry_2 *dir, struct page *page,
		if (de->rec_len == 0) {
			ext2_error(inode->i_sb, __func__,
				"zero-length directory entry");
			err = -EIO;
			goto out;
			return -EIO;
		}
		pde = de;
		de = ext2_next_entry(de);
@@ -617,7 +616,10 @@ int ext2_delete_entry (struct ext2_dir_entry_2 *dir, struct page *page,
	pos = page_offset(page) + from;
	lock_page(page);
	err = ext2_prepare_chunk(page, pos, to - from);
	BUG_ON(err);
	if (err) {
		unlock_page(page);
		return err;
	}
	if (pde)
		pde->rec_len = ext2_rec_len_to_disk(to - from);
	dir->inode = 0;
@@ -625,9 +627,7 @@ int ext2_delete_entry (struct ext2_dir_entry_2 *dir, struct page *page,
	inode->i_ctime = inode->i_mtime = current_time(inode);
	EXT2_I(inode)->i_flags &= ~EXT2_BTREE_FL;
	mark_inode_dirty(inode);
	err = ext2_handle_dirsync(inode);
out:
	return err;
	return ext2_handle_dirsync(inode);
}

/*
+10 −19
Original line number Diff line number Diff line
@@ -335,18 +335,16 @@ static int ext2_rename (struct mnt_idmap * idmap,

	err = dquot_initialize(old_dir);
	if (err)
		goto out;
		return err;

	err = dquot_initialize(new_dir);
	if (err)
		goto out;
		return err;

	old_de = ext2_find_entry(old_dir, &old_dentry->d_name, &old_page,
				 &old_page_addr);
	if (IS_ERR(old_de)) {
		err = PTR_ERR(old_de);
		goto out;
	}
	if (IS_ERR(old_de))
		return PTR_ERR(old_de);

	if (S_ISDIR(old_inode->i_mode)) {
		err = -EIO;
@@ -394,27 +392,20 @@ static int ext2_rename (struct mnt_idmap * idmap,
	old_inode->i_ctime = current_time(old_inode);
	mark_inode_dirty(old_inode);

	ext2_delete_entry(old_de, old_page, old_page_addr);

	if (dir_de) {
		if (old_dir != new_dir) {
	err = ext2_delete_entry(old_de, old_page, old_page_addr);
	if (!err && dir_de) {
		if (old_dir != new_dir)
			err = ext2_set_link(old_inode, dir_de, dir_page,
					    dir_page_addr, new_dir, false);

		}
		ext2_put_page(dir_page, dir_page_addr);
		inode_dec_link_count(old_dir);
	}

out_old:
	ext2_put_page(old_page, old_page_addr);
out:
	return err;

out_dir:
	if (dir_de)
		ext2_put_page(dir_page, dir_page_addr);
	goto out_old;
out_old:
	ext2_put_page(old_page, old_page_addr);
	return err;
}

const struct inode_operations ext2_dir_inode_operations = {