diff --git a/fs/incfs/data_mgmt.c b/fs/incfs/data_mgmt.c index bf34f57e27a2..6b74a9d0325f 100644 --- a/fs/incfs/data_mgmt.c +++ b/fs/incfs/data_mgmt.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include @@ -388,8 +387,7 @@ static void log_block_read(struct mount_info *mi, incfs_uuid_t *id, } static int validate_hash_tree(struct file *bf, struct data_file *df, - int block_index, struct mem_range data, - u8 *tmp_buf) + int block_index, struct mem_range data, u8 *buf) { u8 digest[INCFS_MAX_HASH_SIZE] = {}; struct mtree *tree = NULL; @@ -402,7 +400,6 @@ static int validate_hash_tree(struct file *bf, struct data_file *df, int hash_per_block; int lvl = 0; int res; - struct page *saved_page = NULL; tree = df->df_hash_tree; sig = df->df_signature; @@ -424,39 +421,17 @@ static int validate_hash_tree(struct file *bf, struct data_file *df, INCFS_DATA_FILE_BLOCK_SIZE); size_t hash_off_in_block = hash_block_index * digest_size % INCFS_DATA_FILE_BLOCK_SIZE; - struct mem_range buf_range; - struct page *page = NULL; - bool aligned = (hash_block_off & - (INCFS_DATA_FILE_BLOCK_SIZE - 1)) == 0; - u8 *actual_buf; + struct mem_range buf_range = range(buf, + INCFS_DATA_FILE_BLOCK_SIZE); + ssize_t read_res = incfs_kread(bf, buf, + INCFS_DATA_FILE_BLOCK_SIZE, hash_block_off); - if (aligned) { - page = read_mapping_page( - bf->f_inode->i_mapping, - hash_block_off / INCFS_DATA_FILE_BLOCK_SIZE, - NULL); + if (read_res < 0) + return read_res; + if (read_res != INCFS_DATA_FILE_BLOCK_SIZE) + return -EIO; - if (IS_ERR(page)) - return PTR_ERR(page); - - actual_buf = page_address(page); - } else { - size_t read_res = - incfs_kread(bf, tmp_buf, - INCFS_DATA_FILE_BLOCK_SIZE, - hash_block_off); - - if (read_res < 0) - return read_res; - if (read_res != INCFS_DATA_FILE_BLOCK_SIZE) - return -EIO; - - actual_buf = tmp_buf; - } - - buf_range = range(actual_buf, INCFS_DATA_FILE_BLOCK_SIZE); - saved_digest_rng = - range(actual_buf + hash_off_in_block, digest_size); + saved_digest_rng = range(buf + hash_off_in_block, digest_size); if (!incfs_equal_ranges(calc_digest_rng, saved_digest_rng)) { int i; bool zero = true; @@ -471,37 +446,9 @@ static int validate_hash_tree(struct file *bf, struct data_file *df, if (zero) pr_debug("incfs: Note saved_digest all zero - did you forget to load the hashes?\n"); - - if (saved_page) - put_page(saved_page); - if (page) - put_page(page); return -EBADMSG; } - if (saved_page) { - /* - * This is something of a kludge. The PageChecked flag - * is reserved for the file system, but we are setting - * this on the pages belonging to the underlying file - * system. incfs is only going to be used on f2fs and - * ext4 which only use this flag when fs-verity is being - * used, so this is safe for now, however a better - * mechanism needs to be found. - */ - SetPageChecked(saved_page); - put_page(saved_page); - saved_page = NULL; - } - - if (page && PageChecked(page)) { - put_page(page); - return 0; - } - - saved_page = page; - page = NULL; - res = incfs_calc_digest(tree->alg, buf_range, calc_digest_rng); if (res) return res; @@ -511,15 +458,8 @@ static int validate_hash_tree(struct file *bf, struct data_file *df, root_hash_rng = range(tree->root_hash, digest_size); if (!incfs_equal_ranges(calc_digest_rng, root_hash_rng)) { pr_debug("incfs: Root hash mismatch blk:%d\n", block_index); - if (saved_page) - put_page(saved_page); return -EBADMSG; } - - if (saved_page) { - SetPageChecked(saved_page); - put_page(saved_page); - } return 0; }