Commit 7a5fa171 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jan Kara

ext2: propagate errors from ext2_prepare_chunk

Propagate errors from ext2_prepare_chunk to the callers and handle them
there.  While touching the prototype also turn update_times into a bool
from the current int used as bool.

[JK: fixed up error recovery path in ext2_rename()]
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
Message-Id: <20230116085205.2342975-1-hch@lst.de>
parent 1fb40763
...@@ -461,9 +461,9 @@ static int ext2_handle_dirsync(struct inode *dir) ...@@ -461,9 +461,9 @@ static int ext2_handle_dirsync(struct inode *dir)
return err; return err;
} }
void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, int ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
struct page *page, void *page_addr, struct inode *inode, struct page *page, void *page_addr, struct inode *inode,
int update_times) bool update_times)
{ {
loff_t pos = page_offset(page) + loff_t pos = page_offset(page) +
(char *) de - (char *) page_addr; (char *) de - (char *) page_addr;
...@@ -472,7 +472,10 @@ void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, ...@@ -472,7 +472,10 @@ void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
lock_page(page); lock_page(page);
err = ext2_prepare_chunk(page, pos, len); err = ext2_prepare_chunk(page, pos, len);
BUG_ON(err); if (err) {
unlock_page(page);
return err;
}
de->inode = cpu_to_le32(inode->i_ino); de->inode = cpu_to_le32(inode->i_ino);
ext2_set_de_type(de, inode); ext2_set_de_type(de, inode);
ext2_commit_chunk(page, pos, len); ext2_commit_chunk(page, pos, len);
...@@ -480,7 +483,7 @@ void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, ...@@ -480,7 +483,7 @@ void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
dir->i_mtime = dir->i_ctime = current_time(dir); dir->i_mtime = dir->i_ctime = current_time(dir);
EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL; EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;
mark_inode_dirty(dir); mark_inode_dirty(dir);
ext2_handle_dirsync(dir); return ext2_handle_dirsync(dir);
} }
/* /*
......
...@@ -734,8 +734,9 @@ extern int ext2_delete_entry(struct ext2_dir_entry_2 *dir, struct page *page, ...@@ -734,8 +734,9 @@ extern int ext2_delete_entry(struct ext2_dir_entry_2 *dir, struct page *page,
char *kaddr); char *kaddr);
extern int ext2_empty_dir (struct inode *); extern int ext2_empty_dir (struct inode *);
extern struct ext2_dir_entry_2 *ext2_dotdot(struct inode *dir, struct page **p, void **pa); extern struct ext2_dir_entry_2 *ext2_dotdot(struct inode *dir, struct page **p, void **pa);
extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, void *, int ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
struct inode *, int); struct page *page, void *page_addr, struct inode *inode,
bool update_times);
static inline void ext2_put_page(struct page *page, void *page_addr) static inline void ext2_put_page(struct page *page, void *page_addr)
{ {
kunmap_local(page_addr); kunmap_local(page_addr);
......
...@@ -370,8 +370,11 @@ static int ext2_rename (struct user_namespace * mnt_userns, ...@@ -370,8 +370,11 @@ static int ext2_rename (struct user_namespace * mnt_userns,
err = PTR_ERR(new_de); err = PTR_ERR(new_de);
goto out_dir; goto out_dir;
} }
ext2_set_link(new_dir, new_de, new_page, page_addr, old_inode, 1); err = ext2_set_link(new_dir, new_de, new_page, page_addr,
old_inode, true);
ext2_put_page(new_page, page_addr); ext2_put_page(new_page, page_addr);
if (err)
goto out_dir;
new_inode->i_ctime = current_time(new_inode); new_inode->i_ctime = current_time(new_inode);
if (dir_de) if (dir_de)
drop_nlink(new_inode); drop_nlink(new_inode);
...@@ -394,24 +397,24 @@ static int ext2_rename (struct user_namespace * mnt_userns, ...@@ -394,24 +397,24 @@ static int ext2_rename (struct user_namespace * mnt_userns,
ext2_delete_entry(old_de, old_page, old_page_addr); ext2_delete_entry(old_de, old_page, old_page_addr);
if (dir_de) { if (dir_de) {
if (old_dir != new_dir) if (old_dir != new_dir) {
ext2_set_link(old_inode, dir_de, dir_page, err = ext2_set_link(old_inode, dir_de, dir_page,
dir_page_addr, new_dir, 0); dir_page_addr, new_dir, false);
}
ext2_put_page(dir_page, dir_page_addr); ext2_put_page(dir_page, dir_page_addr);
inode_dec_link_count(old_dir); inode_dec_link_count(old_dir);
} }
out_old:
ext2_put_page(old_page, old_page_addr); ext2_put_page(old_page, old_page_addr);
return 0; out:
return err;
out_dir: out_dir:
if (dir_de) if (dir_de)
ext2_put_page(dir_page, dir_page_addr); ext2_put_page(dir_page, dir_page_addr);
out_old: goto out_old;
ext2_put_page(old_page, old_page_addr);
out:
return err;
} }
const struct inode_operations ext2_dir_inode_operations = { const struct inode_operations ext2_dir_inode_operations = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment