f2fs: find parent dentry correctly
If dotdot directory is corrupted, its slot may be ocupied by another file. In this case, dentry[1] is not the parent directory. Rename and cross-rename will update the inode in dentry[1] incorrectly. This patch finds dotdot dentry by name. Signed-off-by: Sheng Yong <shengyong1@huawei.com> [Jaegeuk Kim: remove wron bug_on] Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
c92737ceec
commit
8be0fea9c0
@ -267,22 +267,9 @@ out:
|
|||||||
|
|
||||||
struct f2fs_dir_entry *f2fs_parent_dir(struct inode *dir, struct page **p)
|
struct f2fs_dir_entry *f2fs_parent_dir(struct inode *dir, struct page **p)
|
||||||
{
|
{
|
||||||
struct page *page;
|
struct qstr dotdot = QSTR_INIT("..", 2);
|
||||||
struct f2fs_dir_entry *de;
|
|
||||||
struct f2fs_dentry_block *dentry_blk;
|
|
||||||
|
|
||||||
if (f2fs_has_inline_dentry(dir))
|
return f2fs_find_entry(dir, &dotdot, p);
|
||||||
return f2fs_parent_inline_dir(dir, p);
|
|
||||||
|
|
||||||
page = get_lock_data_page(dir, 0, false);
|
|
||||||
if (IS_ERR(page))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
dentry_blk = kmap(page);
|
|
||||||
de = &dentry_blk->dentry[1];
|
|
||||||
*p = page;
|
|
||||||
unlock_page(page);
|
|
||||||
return de;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ino_t f2fs_inode_by_name(struct inode *dir, struct qstr *qstr)
|
ino_t f2fs_inode_by_name(struct inode *dir, struct qstr *qstr)
|
||||||
|
@ -2275,7 +2275,6 @@ int f2fs_write_inline_data(struct inode *, struct page *);
|
|||||||
bool recover_inline_data(struct inode *, struct page *);
|
bool recover_inline_data(struct inode *, struct page *);
|
||||||
struct f2fs_dir_entry *find_in_inline_dir(struct inode *,
|
struct f2fs_dir_entry *find_in_inline_dir(struct inode *,
|
||||||
struct fscrypt_name *, struct page **);
|
struct fscrypt_name *, struct page **);
|
||||||
struct f2fs_dir_entry *f2fs_parent_inline_dir(struct inode *, struct page **);
|
|
||||||
int make_empty_inline_dir(struct inode *inode, struct inode *, struct page *);
|
int make_empty_inline_dir(struct inode *inode, struct inode *, struct page *);
|
||||||
int f2fs_add_inline_entry(struct inode *, const struct qstr *, struct inode *,
|
int f2fs_add_inline_entry(struct inode *, const struct qstr *, struct inode *,
|
||||||
nid_t, umode_t);
|
nid_t, umode_t);
|
||||||
|
@ -306,25 +306,6 @@ struct f2fs_dir_entry *find_in_inline_dir(struct inode *dir,
|
|||||||
return de;
|
return de;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct f2fs_dir_entry *f2fs_parent_inline_dir(struct inode *dir,
|
|
||||||
struct page **p)
|
|
||||||
{
|
|
||||||
struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
|
|
||||||
struct page *ipage;
|
|
||||||
struct f2fs_dir_entry *de;
|
|
||||||
struct f2fs_inline_dentry *dentry_blk;
|
|
||||||
|
|
||||||
ipage = get_node_page(sbi, dir->i_ino);
|
|
||||||
if (IS_ERR(ipage))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
dentry_blk = inline_data_addr(ipage);
|
|
||||||
de = &dentry_blk->dentry[1];
|
|
||||||
*p = ipage;
|
|
||||||
unlock_page(ipage);
|
|
||||||
return de;
|
|
||||||
}
|
|
||||||
|
|
||||||
int make_empty_inline_dir(struct inode *inode, struct inode *parent,
|
int make_empty_inline_dir(struct inode *inode, struct inode *parent,
|
||||||
struct page *ipage)
|
struct page *ipage)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user