Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git...
[platform/kernel/linux-rpi.git] / fs / ext4 / namei.c
index ac7457f..cd01c4a 100644 (file)
@@ -1374,7 +1374,7 @@ static int is_dx_internal_node(struct inode *dir, ext4_lblk_t block,
 }
 
 /*
- *     ext4_find_entry()
+ *     __ext4_find_entry()
  *
  * finds an entry in the specified directory with the wanted name. It
  * returns the cache buffer in which the entry was found, and the entry
@@ -1384,39 +1384,32 @@ static int is_dx_internal_node(struct inode *dir, ext4_lblk_t block,
  * The returned buffer_head has ->b_count elevated.  The caller is expected
  * to brelse() it when appropriate.
  */
-static struct buffer_head * ext4_find_entry (struct inode *dir,
-                                       const struct qstr *d_name,
-                                       struct ext4_dir_entry_2 **res_dir,
-                                       int *inlined)
+static struct buffer_head *__ext4_find_entry(struct inode *dir,
+                                            struct ext4_filename *fname,
+                                            struct ext4_dir_entry_2 **res_dir,
+                                            int *inlined)
 {
        struct super_block *sb;
        struct buffer_head *bh_use[NAMEI_RA_SIZE];
        struct buffer_head *bh, *ret = NULL;
        ext4_lblk_t start, block;
-       const u8 *name = d_name->name;
+       const u8 *name = fname->usr_fname->name;
        size_t ra_max = 0;      /* Number of bh's in the readahead
                                   buffer, bh_use[] */
        size_t ra_ptr = 0;      /* Current index into readahead
                                   buffer */
        ext4_lblk_t  nblocks;
        int i, namelen, retval;
-       struct ext4_filename fname;
 
        *res_dir = NULL;
        sb = dir->i_sb;
-       namelen = d_name->len;
+       namelen = fname->usr_fname->len;
        if (namelen > EXT4_NAME_LEN)
                return NULL;
 
-       retval = ext4_fname_setup_filename(dir, d_name, 1, &fname);
-       if (retval == -ENOENT)
-               return NULL;
-       if (retval)
-               return ERR_PTR(retval);
-
        if (ext4_has_inline_data(dir)) {
                int has_inline_data = 1;
-               ret = ext4_find_inline_entry(dir, &fname, res_dir,
+               ret = ext4_find_inline_entry(dir, fname, res_dir,
                                             &has_inline_data);
                if (has_inline_data) {
                        if (inlined)
@@ -1436,7 +1429,7 @@ static struct buffer_head * ext4_find_entry (struct inode *dir,
                goto restart;
        }
        if (is_dx(dir)) {
-               ret = ext4_dx_find_entry(dir, &fname, res_dir);
+               ret = ext4_dx_find_entry(dir, fname, res_dir);
                /*
                 * On success, or if the error was file not found,
                 * return.  Otherwise, fall back to doing a search the
@@ -1500,7 +1493,7 @@ restart:
                        goto cleanup_and_exit;
                }
                set_buffer_verified(bh);
-               i = search_dirblock(bh, dir, &fname,
+               i = search_dirblock(bh, dir, fname,
                            block << EXT4_BLOCK_SIZE_BITS(sb), res_dir);
                if (i == 1) {
                        EXT4_I(dir)->i_dir_start_lookup = block;
@@ -1531,10 +1524,50 @@ cleanup_and_exit:
        /* Clean up the read-ahead blocks */
        for (; ra_ptr < ra_max; ra_ptr++)
                brelse(bh_use[ra_ptr]);
-       ext4_fname_free_filename(&fname);
        return ret;
 }
 
+static struct buffer_head *ext4_find_entry(struct inode *dir,
+                                          const struct qstr *d_name,
+                                          struct ext4_dir_entry_2 **res_dir,
+                                          int *inlined)
+{
+       int err;
+       struct ext4_filename fname;
+       struct buffer_head *bh;
+
+       err = ext4_fname_setup_filename(dir, d_name, 1, &fname);
+       if (err == -ENOENT)
+               return NULL;
+       if (err)
+               return ERR_PTR(err);
+
+       bh = __ext4_find_entry(dir, &fname, res_dir, inlined);
+
+       ext4_fname_free_filename(&fname);
+       return bh;
+}
+
+static struct buffer_head *ext4_lookup_entry(struct inode *dir,
+                                            struct dentry *dentry,
+                                            struct ext4_dir_entry_2 **res_dir)
+{
+       int err;
+       struct ext4_filename fname;
+       struct buffer_head *bh;
+
+       err = ext4_fname_prepare_lookup(dir, dentry, &fname);
+       if (err == -ENOENT)
+               return NULL;
+       if (err)
+               return ERR_PTR(err);
+
+       bh = __ext4_find_entry(dir, &fname, res_dir, NULL);
+
+       ext4_fname_free_filename(&fname);
+       return bh;
+}
+
 static struct buffer_head * ext4_dx_find_entry(struct inode *dir,
                        struct ext4_filename *fname,
                        struct ext4_dir_entry_2 **res_dir)
@@ -1593,16 +1626,11 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi
        struct inode *inode;
        struct ext4_dir_entry_2 *de;
        struct buffer_head *bh;
-       int err;
-
-       err = fscrypt_prepare_lookup(dir, dentry, flags);
-       if (err)
-               return ERR_PTR(err);
 
        if (dentry->d_name.len > EXT4_NAME_LEN)
                return ERR_PTR(-ENAMETOOLONG);
 
-       bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL);
+       bh = ext4_lookup_entry(dir, dentry, &de);
        if (IS_ERR(bh))
                return ERR_CAST(bh);
        inode = NULL;