f2fs: don't put dentry page in pagecache into highmem
Previous dentry page uses highmem, which will cause panic in platforms using highmem (such as arm), since the address space of dentry pages from highmem directly goes into the decryption path via the function fscrypt_fname_disk_to_usr. But sg_init_one assumes the address is not from highmem, and then cause panic since it doesn't call kmap_high but kunmap_high is triggered at the end. To fix this problem in a simple way, this patch avoids to put dentry page in pagecache into highmem. Signed-off-by: Yunlong Song <yunlong.song@huawei.com> Reviewed-by: Chao Yu <yuchao0@huawei.com> [Jaegeuk Kim: fix coding style] Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:

committed by
Jaegeuk Kim

parent
3664ce2d93
commit
bdbc90fa55
@@ -94,14 +94,12 @@ static struct f2fs_dir_entry *find_in_block(struct page *dentry_page,
|
||||
struct f2fs_dir_entry *de;
|
||||
struct f2fs_dentry_ptr d;
|
||||
|
||||
dentry_blk = (struct f2fs_dentry_block *)kmap(dentry_page);
|
||||
dentry_blk = (struct f2fs_dentry_block *)page_address(dentry_page);
|
||||
|
||||
make_dentry_ptr_block(NULL, &d, dentry_blk);
|
||||
de = find_target_dentry(fname, namehash, max_slots, &d);
|
||||
if (de)
|
||||
*res_page = dentry_page;
|
||||
else
|
||||
kunmap(dentry_page);
|
||||
|
||||
return de;
|
||||
}
|
||||
@@ -287,7 +285,6 @@ ino_t f2fs_inode_by_name(struct inode *dir, const struct qstr *qstr,
|
||||
de = f2fs_find_entry(dir, qstr, page);
|
||||
if (de) {
|
||||
res = le32_to_cpu(de->ino);
|
||||
f2fs_dentry_kunmap(dir, *page);
|
||||
f2fs_put_page(*page, 0);
|
||||
}
|
||||
|
||||
@@ -302,7 +299,6 @@ void f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de,
|
||||
f2fs_wait_on_page_writeback(page, type, true);
|
||||
de->ino = cpu_to_le32(inode->i_ino);
|
||||
set_de_type(de, inode->i_mode);
|
||||
f2fs_dentry_kunmap(dir, page);
|
||||
set_page_dirty(page);
|
||||
|
||||
dir->i_mtime = dir->i_ctime = current_time(dir);
|
||||
@@ -350,13 +346,11 @@ static int make_empty_dir(struct inode *inode,
|
||||
if (IS_ERR(dentry_page))
|
||||
return PTR_ERR(dentry_page);
|
||||
|
||||
dentry_blk = kmap_atomic(dentry_page);
|
||||
dentry_blk = page_address(dentry_page);
|
||||
|
||||
make_dentry_ptr_block(NULL, &d, dentry_blk);
|
||||
do_make_empty_dir(inode, parent, &d);
|
||||
|
||||
kunmap_atomic(dentry_blk);
|
||||
|
||||
set_page_dirty(dentry_page);
|
||||
f2fs_put_page(dentry_page, 1);
|
||||
return 0;
|
||||
@@ -547,13 +541,12 @@ start:
|
||||
if (IS_ERR(dentry_page))
|
||||
return PTR_ERR(dentry_page);
|
||||
|
||||
dentry_blk = kmap(dentry_page);
|
||||
dentry_blk = page_address(dentry_page);
|
||||
bit_pos = room_for_filename(&dentry_blk->dentry_bitmap,
|
||||
slots, NR_DENTRY_IN_BLOCK);
|
||||
if (bit_pos < NR_DENTRY_IN_BLOCK)
|
||||
goto add_dentry;
|
||||
|
||||
kunmap(dentry_page);
|
||||
f2fs_put_page(dentry_page, 1);
|
||||
}
|
||||
|
||||
@@ -588,7 +581,6 @@ fail:
|
||||
if (inode)
|
||||
up_write(&F2FS_I(inode)->i_sem);
|
||||
|
||||
kunmap(dentry_page);
|
||||
f2fs_put_page(dentry_page, 1);
|
||||
|
||||
return err;
|
||||
@@ -642,7 +634,6 @@ int __f2fs_add_link(struct inode *dir, const struct qstr *name,
|
||||
F2FS_I(dir)->task = NULL;
|
||||
}
|
||||
if (de) {
|
||||
f2fs_dentry_kunmap(dir, page);
|
||||
f2fs_put_page(page, 0);
|
||||
err = -EEXIST;
|
||||
} else if (IS_ERR(page)) {
|
||||
@@ -730,7 +721,6 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
|
||||
bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap,
|
||||
NR_DENTRY_IN_BLOCK,
|
||||
0);
|
||||
kunmap(page); /* kunmap - pair of f2fs_find_entry */
|
||||
set_page_dirty(page);
|
||||
|
||||
dir->i_ctime = dir->i_mtime = current_time(dir);
|
||||
@@ -775,7 +765,7 @@ bool f2fs_empty_dir(struct inode *dir)
|
||||
return false;
|
||||
}
|
||||
|
||||
dentry_blk = kmap_atomic(dentry_page);
|
||||
dentry_blk = page_address(dentry_page);
|
||||
if (bidx == 0)
|
||||
bit_pos = 2;
|
||||
else
|
||||
@@ -783,7 +773,6 @@ bool f2fs_empty_dir(struct inode *dir)
|
||||
bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap,
|
||||
NR_DENTRY_IN_BLOCK,
|
||||
bit_pos);
|
||||
kunmap_atomic(dentry_blk);
|
||||
|
||||
f2fs_put_page(dentry_page, 1);
|
||||
|
||||
@@ -901,19 +890,17 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
dentry_blk = kmap(dentry_page);
|
||||
dentry_blk = page_address(dentry_page);
|
||||
|
||||
make_dentry_ptr_block(inode, &d, dentry_blk);
|
||||
|
||||
err = f2fs_fill_dentries(ctx, &d,
|
||||
n * NR_DENTRY_IN_BLOCK, &fstr);
|
||||
if (err) {
|
||||
kunmap(dentry_page);
|
||||
f2fs_put_page(dentry_page, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
kunmap(dentry_page);
|
||||
f2fs_put_page(dentry_page, 1);
|
||||
}
|
||||
out_free:
|
||||
|
Reference in New Issue
Block a user