f2fs: revisit error handling flows
[deliverable/linux.git] / fs / f2fs / dir.c
index 3b1c14e4eeea48b393a6efe38e38e8c9fba42081..5373f333a7d7800414f2a663fb94885d82ce7e01 100644 (file)
@@ -391,9 +391,14 @@ struct page *init_inode_metadata(struct inode *inode, struct inode *dir,
                        return page;
 
                if (S_ISDIR(inode->i_mode)) {
+                       /* in order to handle error case */
+                       get_page(page);
                        err = make_empty_dir(inode, dir, page);
-                       if (err)
-                               goto error;
+                       if (err) {
+                               lock_page(page);
+                               goto put_error;
+                       }
+                       put_page(page);
                }
 
                err = f2fs_init_acl(inode, dir, page, dpage);
@@ -437,13 +442,12 @@ struct page *init_inode_metadata(struct inode *inode, struct inode *dir,
        return page;
 
 put_error:
-       f2fs_put_page(page, 1);
-error:
-       /* once the failed inode becomes a bad inode, i_mode is S_IFREG */
+       /* truncate empty dir pages */
        truncate_inode_pages(&inode->i_data, 0);
-       truncate_blocks(inode, 0, false);
-       remove_dirty_inode(inode);
-       remove_inode_page(inode);
+
+       clear_nlink(inode);
+       update_inode(inode, page);
+       f2fs_put_page(page, 1);
        return ERR_PTR(err);
 }
 
@@ -537,6 +541,10 @@ int f2fs_add_regular_entry(struct inode *dir, const struct qstr *new_name,
        }
 
 start:
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+       if (time_to_inject(FAULT_DIR_DEPTH))
+               return -ENOSPC;
+#endif
        if (unlikely(current_depth == MAX_DIR_HASH_DEPTH))
                return -ENOSPC;
 
@@ -805,7 +813,7 @@ bool f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d,
                        int save_len = fstr->len;
                        int ret;
 
-                       de_name.name = kmalloc(de_name.len, GFP_NOFS);
+                       de_name.name = f2fs_kmalloc(de_name.len, GFP_NOFS);
                        if (!de_name.name)
                                return false;
 
@@ -888,6 +896,7 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx)
                kunmap(dentry_page);
                f2fs_put_page(dentry_page, 1);
        }
+       err = 0;
 out:
        fscrypt_fname_free_buffer(&fstr);
        return err;
This page took 0.027256 seconds and 5 git commands to generate.