Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux...
[firefly-linux-kernel-4.4.55.git] / fs / ext4 / namei.c
index 956b38113f62a6fe04ef4c38febe42df708d378e..e7e1d79a7d75496c3f0bff48eb6680a6ff2703e9 100644 (file)
 
 #include <linux/fs.h>
 #include <linux/pagemap.h>
-#include <linux/jbd.h>
+#include <linux/jbd2.h>
 #include <linux/time.h>
 #include <linux/ext4_fs.h>
-#include <linux/ext4_jbd.h>
+#include <linux/ext4_jbd2.h>
 #include <linux/fcntl.h>
 #include <linux/stat.h>
 #include <linux/string.h>
@@ -241,13 +241,13 @@ static inline unsigned dx_node_limit (struct inode *dir)
 #ifdef DX_DEBUG
 static void dx_show_index (char * label, struct dx_entry *entries)
 {
-        int i, n = dx_get_count (entries);
+       int i, n = dx_get_count (entries);
         printk("%s index ", label);
-        for (i = 0; i < n; i++)
-        {
-                printk("%x->%u ", i? dx_get_hash(entries + i): 0, dx_get_block(entries + i));
-        }
-        printk("\n");
+       for (i = 0; i < n; i++) {
+               printk("%x->%u ", i? dx_get_hash(entries + i) :
+                               0, dx_get_block(entries + i));
+       }
+       printk("\n");
 }
 
 struct stats
@@ -552,6 +552,15 @@ static int htree_dirblock_to_tree(struct file *dir_file,
                                           dir->i_sb->s_blocksize -
                                           EXT4_DIR_REC_LEN(0));
        for (; de < top; de = ext4_next_entry(de)) {
+               if (!ext4_check_dir_entry("htree_dirblock_to_tree", dir, de, bh,
+                                       (block<<EXT4_BLOCK_SIZE_BITS(dir->i_sb))
+                                               +((char *)de - bh->b_data))) {
+                       /* On error, skip the f_pos to the next block. */
+                       dir_file->f_pos = (dir_file->f_pos |
+                                       (dir->i_sb->s_blocksize - 1)) + 1;
+                       brelse (bh);
+                       return count;
+               }
                ext4fs_dirhash(de->name, de->name_len, hinfo);
                if ((hinfo->hash < start_hash) ||
                    ((hinfo->hash == start_hash) &&
@@ -593,7 +602,7 @@ int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
 
        dxtrace(printk("In htree_fill_tree, start hash: %x:%x\n", start_hash,
                       start_minor_hash));
-       dir = dir_file->f_dentry->d_inode;
+       dir = dir_file->f_path.dentry->d_inode;
        if (!(EXT4_I(dir)->i_flags & EXT4_INDEX_FL)) {
                hinfo.hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version;
                hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
@@ -604,7 +613,7 @@ int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
        }
        hinfo.hash = start_hash;
        hinfo.minor_hash = 0;
-       frame = dx_probe(NULL, dir_file->f_dentry->d_inode, &hinfo, frames, &err);
+       frame = dx_probe(NULL, dir_file->f_path.dentry->d_inode, &hinfo, frames, &err);
        if (!frame)
                return err;
 
@@ -688,28 +697,26 @@ static int dx_make_map (struct ext4_dir_entry_2 *de, int size,
 
 static void dx_sort_map (struct dx_map_entry *map, unsigned count)
 {
-        struct dx_map_entry *p, *q, *top = map + count - 1;
-        int more;
-        /* Combsort until bubble sort doesn't suck */
-        while (count > 2)
-       {
-                count = count*10/13;
-                if (count - 9 < 2) /* 9, 10 -> 11 */
-                        count = 11;
-                for (p = top, q = p - count; q >= map; p--, q--)
-                        if (p->hash < q->hash)
-                                swap(*p, *q);
-        }
-        /* Garden variety bubble sort */
-        do {
-                more = 0;
-                q = top;
-                while (q-- > map)
-               {
-                        if (q[1].hash >= q[0].hash)
+       struct dx_map_entry *p, *q, *top = map + count - 1;
+       int more;
+       /* Combsort until bubble sort doesn't suck */
+       while (count > 2) {
+               count = count*10/13;
+               if (count - 9 < 2) /* 9, 10 -> 11 */
+                       count = 11;
+               for (p = top, q = p - count; q >= map; p--, q--)
+                       if (p->hash < q->hash)
+                               swap(*p, *q);
+       }
+       /* Garden variety bubble sort */
+       do {
+               more = 0;
+               q = top;
+               while (q-- > map) {
+                       if (q[1].hash >= q[0].hash)
                                continue;
-                        swap(*(q+1), *q);
-                        more = 1;
+                       swap(*(q+1), *q);
+                       more = 1;
                }
        } while(more);
 }
@@ -1609,21 +1616,6 @@ static int ext4_delete_entry (handle_t *handle,
        return -ENOENT;
 }
 
-/*
- * ext4_mark_inode_dirty is somewhat expensive, so unlike ext2 we
- * do not perform it in these functions.  We perform it at the call site,
- * if it is needed.
- */
-static inline void ext4_inc_count(handle_t *handle, struct inode *inode)
-{
-       inc_nlink(inode);
-}
-
-static inline void ext4_dec_count(handle_t *handle, struct inode *inode)
-{
-       drop_nlink(inode);
-}
-
 static int ext4_add_nondir(handle_t *handle,
                struct dentry *dentry, struct inode *inode)
 {
@@ -1633,7 +1625,7 @@ static int ext4_add_nondir(handle_t *handle,
                d_instantiate(dentry, inode);
                return 0;
        }
-       ext4_dec_count(handle, inode);
+       drop_nlink(inode);
        iput(inode);
        return err;
 }
@@ -2154,7 +2146,7 @@ retry:
                err = __page_symlink(inode, symname, l,
                                mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS);
                if (err) {
-                       ext4_dec_count(handle, inode);
+                       drop_nlink(inode);
                        ext4_mark_inode_dirty(handle, inode);
                        iput (inode);
                        goto out_stop;
@@ -2182,6 +2174,12 @@ static int ext4_link (struct dentry * old_dentry,
 
        if (inode->i_nlink >= EXT4_LINK_MAX)
                return -EMLINK;
+       /*
+        * Return -ENOENT if we've raced with unlink and i_nlink is 0.  Doing
+        * otherwise has the potential to corrupt the orphan inode list.
+        */
+       if (inode->i_nlink == 0)
+               return -ENOENT;
 
 retry:
        handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
@@ -2193,7 +2191,7 @@ retry:
                handle->h_sync = 1;
 
        inode->i_ctime = CURRENT_TIME_SEC;
-       ext4_inc_count(handle, inode);
+       inc_nlink(inode);
        atomic_inc(&inode->i_count);
 
        err = ext4_add_nondir(handle, dentry, inode);
@@ -2365,7 +2363,7 @@ end_rename:
 /*
  * directories can handle most operations...
  */
-struct inode_operations ext4_dir_inode_operations = {
+const struct inode_operations ext4_dir_inode_operations = {
        .create         = ext4_create,
        .lookup         = ext4_lookup,
        .link           = ext4_link,
@@ -2385,7 +2383,7 @@ struct inode_operations ext4_dir_inode_operations = {
        .permission     = ext4_permission,
 };
 
-struct inode_operations ext4_special_inode_operations = {
+const struct inode_operations ext4_special_inode_operations = {
        .setattr        = ext4_setattr,
 #ifdef CONFIG_EXT4DEV_FS_XATTR
        .setxattr       = generic_setxattr,