ext4: clean up ext4_match() and callers
[ Upstream commit d9b9f8d5a88cb7881d9f1c2b7e9de9a3fe1dc9e2 ] When ext4 encryption was originally merged, we were encrypting the user-specified filename in ext4_match(), introducing a lot of additional complexity into ext4_match() and its callers. This has since been changed to encrypt the filename earlier, so we can remove the gunk that's no longer needed. This more or less reverts ext4_search_dir() and ext4_find_dest_de() to the way they were in the v4.0 kernel. Signed-off-by: Eric Biggers <ebiggers@google.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
0c9ce43da9
commit
4cd702fe93
1 changed files with 25 additions and 56 deletions
|
@ -1226,19 +1226,18 @@ static void dx_insert_block(struct dx_frame *frame, u32 hash, ext4_lblk_t block)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE! unlike strncmp, ext4_match returns 1 for success, 0 for failure.
|
* Test whether a directory entry matches the filename being searched for.
|
||||||
*
|
*
|
||||||
* `len <= EXT4_NAME_LEN' is guaranteed by caller.
|
* Return: %true if the directory entry matches, otherwise %false.
|
||||||
* `de != NULL' is guaranteed by caller.
|
|
||||||
*/
|
*/
|
||||||
static inline int ext4_match(struct ext4_filename *fname,
|
static inline bool ext4_match(const struct ext4_filename *fname,
|
||||||
struct ext4_dir_entry_2 *de)
|
const struct ext4_dir_entry_2 *de)
|
||||||
{
|
{
|
||||||
const void *name = fname_name(fname);
|
const void *name = fname_name(fname);
|
||||||
u32 len = fname_len(fname);
|
u32 len = fname_len(fname);
|
||||||
|
|
||||||
if (!de->inode)
|
if (!de->inode)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||||
if (unlikely(!name)) {
|
if (unlikely(!name)) {
|
||||||
|
@ -1270,48 +1269,31 @@ int ext4_search_dir(struct buffer_head *bh, char *search_buf, int buf_size,
|
||||||
struct ext4_dir_entry_2 * de;
|
struct ext4_dir_entry_2 * de;
|
||||||
char * dlimit;
|
char * dlimit;
|
||||||
int de_len;
|
int de_len;
|
||||||
int res;
|
|
||||||
|
|
||||||
de = (struct ext4_dir_entry_2 *)search_buf;
|
de = (struct ext4_dir_entry_2 *)search_buf;
|
||||||
dlimit = search_buf + buf_size;
|
dlimit = search_buf + buf_size;
|
||||||
while ((char *) de < dlimit) {
|
while ((char *) de < dlimit) {
|
||||||
/* this code is executed quadratically often */
|
/* this code is executed quadratically often */
|
||||||
/* do minimal checking `by hand' */
|
/* do minimal checking `by hand' */
|
||||||
if ((char *) de + de->name_len <= dlimit) {
|
if ((char *) de + de->name_len <= dlimit &&
|
||||||
res = ext4_match(fname, de);
|
ext4_match(fname, de)) {
|
||||||
if (res < 0) {
|
/* found a match - just to be sure, do
|
||||||
res = -1;
|
* a full check */
|
||||||
goto return_result;
|
if (ext4_check_dir_entry(dir, NULL, de, bh, bh->b_data,
|
||||||
}
|
bh->b_size, offset))
|
||||||
if (res > 0) {
|
return -1;
|
||||||
/* found a match - just to be sure, do
|
*res_dir = de;
|
||||||
* a full check */
|
return 1;
|
||||||
if (ext4_check_dir_entry(dir, NULL, de, bh,
|
|
||||||
bh->b_data,
|
|
||||||
bh->b_size, offset)) {
|
|
||||||
res = -1;
|
|
||||||
goto return_result;
|
|
||||||
}
|
|
||||||
*res_dir = de;
|
|
||||||
res = 1;
|
|
||||||
goto return_result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/* prevent looping on a bad block */
|
/* prevent looping on a bad block */
|
||||||
de_len = ext4_rec_len_from_disk(de->rec_len,
|
de_len = ext4_rec_len_from_disk(de->rec_len,
|
||||||
dir->i_sb->s_blocksize);
|
dir->i_sb->s_blocksize);
|
||||||
if (de_len <= 0) {
|
if (de_len <= 0)
|
||||||
res = -1;
|
return -1;
|
||||||
goto return_result;
|
|
||||||
}
|
|
||||||
offset += de_len;
|
offset += de_len;
|
||||||
de = (struct ext4_dir_entry_2 *) ((char *) de + de_len);
|
de = (struct ext4_dir_entry_2 *) ((char *) de + de_len);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
res = 0;
|
|
||||||
return_result:
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int is_dx_internal_node(struct inode *dir, ext4_lblk_t block,
|
static int is_dx_internal_node(struct inode *dir, ext4_lblk_t block,
|
||||||
|
@ -1824,24 +1806,15 @@ int ext4_find_dest_de(struct inode *dir, struct inode *inode,
|
||||||
int nlen, rlen;
|
int nlen, rlen;
|
||||||
unsigned int offset = 0;
|
unsigned int offset = 0;
|
||||||
char *top;
|
char *top;
|
||||||
int res;
|
|
||||||
|
|
||||||
de = (struct ext4_dir_entry_2 *)buf;
|
de = (struct ext4_dir_entry_2 *)buf;
|
||||||
top = buf + buf_size - reclen;
|
top = buf + buf_size - reclen;
|
||||||
while ((char *) de <= top) {
|
while ((char *) de <= top) {
|
||||||
if (ext4_check_dir_entry(dir, NULL, de, bh,
|
if (ext4_check_dir_entry(dir, NULL, de, bh,
|
||||||
buf, buf_size, offset)) {
|
buf, buf_size, offset))
|
||||||
res = -EFSCORRUPTED;
|
return -EFSCORRUPTED;
|
||||||
goto return_result;
|
if (ext4_match(fname, de))
|
||||||
}
|
return -EEXIST;
|
||||||
/* Provide crypto context and crypto buffer to ext4 match */
|
|
||||||
res = ext4_match(fname, de);
|
|
||||||
if (res < 0)
|
|
||||||
goto return_result;
|
|
||||||
if (res > 0) {
|
|
||||||
res = -EEXIST;
|
|
||||||
goto return_result;
|
|
||||||
}
|
|
||||||
nlen = EXT4_DIR_REC_LEN(de->name_len);
|
nlen = EXT4_DIR_REC_LEN(de->name_len);
|
||||||
rlen = ext4_rec_len_from_disk(de->rec_len, buf_size);
|
rlen = ext4_rec_len_from_disk(de->rec_len, buf_size);
|
||||||
if ((de->inode ? rlen - nlen : rlen) >= reclen)
|
if ((de->inode ? rlen - nlen : rlen) >= reclen)
|
||||||
|
@ -1849,15 +1822,11 @@ int ext4_find_dest_de(struct inode *dir, struct inode *inode,
|
||||||
de = (struct ext4_dir_entry_2 *)((char *)de + rlen);
|
de = (struct ext4_dir_entry_2 *)((char *)de + rlen);
|
||||||
offset += rlen;
|
offset += rlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((char *) de > top)
|
if ((char *) de > top)
|
||||||
res = -ENOSPC;
|
return -ENOSPC;
|
||||||
else {
|
|
||||||
*dest_de = de;
|
*dest_de = de;
|
||||||
res = 0;
|
return 0;
|
||||||
}
|
|
||||||
return_result:
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ext4_insert_dentry(struct inode *dir,
|
int ext4_insert_dentry(struct inode *dir,
|
||||||
|
|
Loading…
Add table
Reference in a new issue