ext4: clean up ext4_match() and callers
authorEric Biggers <ebiggers@google.com>
Mon, 24 Apr 2017 17:00:13 +0000 (10:00 -0700)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 4 May 2017 15:44:40 +0000 (11:44 -0400)
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>
fs/ext4/namei.c

index a87e49c31248f12705b940b24384e398e5555f62..4d9b587507d9941759403b461bbcf9e0c1e36a04 100644 (file)
@@ -1237,18 +1237,17 @@ 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.
- * `de != NULL' is guaranteed by caller.
+ * Return: %true if the directory entry matches, otherwise %false.
  */
-static inline int ext4_match(struct ext4_filename *fname,
-                            struct ext4_dir_entry_2 *de)
+static inline bool ext4_match(const struct ext4_filename *fname,
+                             const struct ext4_dir_entry_2 *de)
 {
        struct fscrypt_name f;
 
        if (!de->inode)
-               return 0;
+               return false;
 
        f.usr_fname = fname->usr_fname;
        f.disk_name = fname->disk_name;
@@ -1269,48 +1268,31 @@ int ext4_search_dir(struct buffer_head *bh, char *search_buf, int buf_size,
        struct ext4_dir_entry_2 * de;
        char * dlimit;
        int de_len;
-       int res;
 
        de = (struct ext4_dir_entry_2 *)search_buf;
        dlimit = search_buf + buf_size;
        while ((char *) de < dlimit) {
                /* this code is executed quadratically often */
                /* do minimal checking `by hand' */
-               if ((char *) de + de->name_len <= dlimit) {
-                       res = ext4_match(fname, de);
-                       if (res < 0) {
-                               res = -1;
-                               goto return_result;
-                       }
-                       if (res > 0) {
-                               /* found a match - just to be sure, do
-                                * a full check */
-                               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;
-                       }
-
+               if ((char *) de + de->name_len <= dlimit &&
+                   ext4_match(fname, de)) {
+                       /* found a match - just to be sure, do
+                        * a full check */
+                       if (ext4_check_dir_entry(dir, NULL, de, bh, bh->b_data,
+                                                bh->b_size, offset))
+                               return -1;
+                       *res_dir = de;
+                       return 1;
                }
                /* prevent looping on a bad block */
                de_len = ext4_rec_len_from_disk(de->rec_len,
                                                dir->i_sb->s_blocksize);
-               if (de_len <= 0) {
-                       res = -1;
-                       goto return_result;
-               }
+               if (de_len <= 0)
+                       return -1;
                offset += de_len;
                de = (struct ext4_dir_entry_2 *) ((char *) de + de_len);
        }
-
-       res = 0;
-return_result:
-       return res;
+       return 0;
 }
 
 static int is_dx_internal_node(struct inode *dir, ext4_lblk_t block,
@@ -1814,24 +1796,15 @@ int ext4_find_dest_de(struct inode *dir, struct inode *inode,
        int nlen, rlen;
        unsigned int offset = 0;
        char *top;
-       int res;
 
        de = (struct ext4_dir_entry_2 *)buf;
        top = buf + buf_size - reclen;
        while ((char *) de <= top) {
                if (ext4_check_dir_entry(dir, NULL, de, bh,
-                                        buf, buf_size, offset)) {
-                       res = -EFSCORRUPTED;
-                       goto return_result;
-               }
-               /* 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;
-               }
+                                        buf, buf_size, offset))
+                       return -EFSCORRUPTED;
+               if (ext4_match(fname, de))
+                       return -EEXIST;
                nlen = EXT4_DIR_REC_LEN(de->name_len);
                rlen = ext4_rec_len_from_disk(de->rec_len, buf_size);
                if ((de->inode ? rlen - nlen : rlen) >= reclen)
@@ -1839,15 +1812,11 @@ int ext4_find_dest_de(struct inode *dir, struct inode *inode,
                de = (struct ext4_dir_entry_2 *)((char *)de + rlen);
                offset += rlen;
        }
-
        if ((char *) de > top)
-               res = -ENOSPC;
-       else {
-               *dest_de = de;
-               res = 0;
-       }
-return_result:
-       return res;
+               return -ENOSPC;
+
+       *dest_de = de;
+       return 0;
 }
 
 int ext4_insert_dentry(struct inode *dir,