ext4: improve error handling from ext4_dirhash()
[linux-block.git] / fs / ext4 / namei.c
index a5010b5b8a8c11b5909c137b649fe5d04849d832..45b579805c95428238b792de8182bc2e7e52a18c 100644 (file)
@@ -674,7 +674,7 @@ static struct stats dx_show_leaf(struct inode *dir,
                                len = de->name_len;
                                if (!IS_ENCRYPTED(dir)) {
                                        /* Directory is not encrypted */
-                                       ext4fs_dirhash(dir, de->name,
+                                       (void) ext4fs_dirhash(dir, de->name,
                                                de->name_len, &h);
                                        printk("%*.s:(U)%x.%u ", len,
                                               name, h.hash,
@@ -709,8 +709,9 @@ static struct stats dx_show_leaf(struct inode *dir,
                                        if (IS_CASEFOLDED(dir))
                                                h.hash = EXT4_DIRENT_HASH(de);
                                        else
-                                               ext4fs_dirhash(dir, de->name,
-                                                      de->name_len, &h);
+                                               (void) ext4fs_dirhash(dir,
+                                                       de->name,
+                                                       de->name_len, &h);
                                        printk("%*.s:(E)%x.%u ", len, name,
                                               h.hash, (unsigned) ((char *) de
                                                                   - base));
@@ -720,7 +721,8 @@ static struct stats dx_show_leaf(struct inode *dir,
 #else
                                int len = de->name_len;
                                char *name = de->name;
-                               ext4fs_dirhash(dir, de->name, de->name_len, &h);
+                               (void) ext4fs_dirhash(dir, de->name,
+                                                     de->name_len, &h);
                                printk("%*.s:%x.%u ", len, name, h.hash,
                                       (unsigned) ((char *) de - base));
 #endif
@@ -849,8 +851,14 @@ dx_probe(struct ext4_filename *fname, struct inode *dir,
        hinfo->seed = EXT4_SB(dir->i_sb)->s_hash_seed;
        /* hash is already computed for encrypted casefolded directory */
        if (fname && fname_name(fname) &&
-                               !(IS_ENCRYPTED(dir) && IS_CASEFOLDED(dir)))
-               ext4fs_dirhash(dir, fname_name(fname), fname_len(fname), hinfo);
+           !(IS_ENCRYPTED(dir) && IS_CASEFOLDED(dir))) {
+               int ret = ext4fs_dirhash(dir, fname_name(fname),
+                                        fname_len(fname), hinfo);
+               if (ret < 0) {
+                       ret_err = ERR_PTR(ret);
+                       goto fail;
+               }
+       }
        hash = hinfo->hash;
 
        if (root->info.unused_flags & 1) {
@@ -1111,7 +1119,12 @@ static int htree_dirblock_to_tree(struct file *dir_file,
                                hinfo->minor_hash = 0;
                        }
                } else {
-                       ext4fs_dirhash(dir, de->name, de->name_len, hinfo);
+                       err = ext4fs_dirhash(dir, de->name,
+                                            de->name_len, hinfo);
+                       if (err < 0) {
+                               count = err;
+                               goto errout;
+                       }
                }
                if ((hinfo->hash < start_hash) ||
                    ((hinfo->hash == start_hash) &&
@@ -1313,8 +1326,12 @@ static int dx_make_map(struct inode *dir, struct buffer_head *bh,
                if (de->name_len && de->inode) {
                        if (ext4_hash_in_dirent(dir))
                                h.hash = EXT4_DIRENT_HASH(de);
-                       else
-                               ext4fs_dirhash(dir, de->name, de->name_len, &h);
+                       else {
+                               int err = ext4fs_dirhash(dir, de->name,
+                                                    de->name_len, &h);
+                               if (err < 0)
+                                       return err;
+                       }
                        map_tail--;
                        map_tail->hash = h.hash;
                        map_tail->offs = ((char *) de - base)>>2;
@@ -1452,10 +1469,9 @@ int ext4_fname_setup_ci_filename(struct inode *dir, const struct qstr *iname,
        hinfo->hash_version = DX_HASH_SIPHASH;
        hinfo->seed = NULL;
        if (cf_name->name)
-               ext4fs_dirhash(dir, cf_name->name, cf_name->len, hinfo);
+               return ext4fs_dirhash(dir, cf_name->name, cf_name->len, hinfo);
        else
-               ext4fs_dirhash(dir, iname->name, iname->len, hinfo);
-       return 0;
+               return ext4fs_dirhash(dir, iname->name, iname->len, hinfo);
 }
 #endif
 
@@ -2298,10 +2314,15 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname,
        fname->hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
 
        /* casefolded encrypted hashes are computed on fname setup */
-       if (!ext4_hash_in_dirent(dir))
-               ext4fs_dirhash(dir, fname_name(fname),
-                               fname_len(fname), &fname->hinfo);
-
+       if (!ext4_hash_in_dirent(dir)) {
+               int err = ext4fs_dirhash(dir, fname_name(fname),
+                                        fname_len(fname), &fname->hinfo);
+               if (err < 0) {
+                       brelse(bh2);
+                       brelse(bh);
+                       return err;
+               }
+       }
        memset(frames, 0, sizeof(frames));
        frame = frames;
        frame->entries = entries;