--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
-@@ -3147,7 +3147,8 @@ static int ext4_find_delete_entry(handle
+@@ -3128,7 +3128,8 @@ static int ext4_find_delete_entry(handle
return retval;
}
{
int retval;
/*
-@@ -3159,7 +3160,8 @@ static void ext4_rename_delete(handle_t
+@@ -3140,7 +3141,8 @@ static void ext4_rename_delete(handle_t
if (le32_to_cpu(ent->de->inode) != ent->inode->i_ino ||
ent->de->name_len != ent->dentry->d_name.len ||
strncmp(ent->de->name, ent->dentry->d_name.name,
retval = ext4_find_delete_entry(handle, ent->dir,
&ent->dentry->d_name);
} else {
-@@ -3210,6 +3212,7 @@ static int ext4_rename(struct inode *old
+@@ -3191,6 +3193,7 @@ static int ext4_rename(struct inode *old
.dentry = new_dentry,
.inode = new_dentry->d_inode,
};
int retval;
dquot_initialize(old.dir);
-@@ -3271,6 +3274,15 @@ static int ext4_rename(struct inode *old
+@@ -3246,6 +3249,15 @@ static int ext4_rename(struct inode *old
if (retval)
goto end_rename;
}
if (!new.bh) {
retval = ext4_add_entry(handle, new.dentry, old.inode);
if (retval)
-@@ -3281,6 +3293,9 @@ static int ext4_rename(struct inode *old
+@@ -3256,6 +3268,9 @@ static int ext4_rename(struct inode *old
if (retval)
goto end_rename;
}
/*
* Like most other Unix systems, set the ctime for inodes on a
-@@ -3292,7 +3307,7 @@ static int ext4_rename(struct inode *old
+@@ -3267,7 +3282,7 @@ static int ext4_rename(struct inode *old
/*
* ok, that's it
*/
+++ /dev/null
-From 36de928641ee48b2078d3fe9514242aaa2f92013 Mon Sep 17 00:00:00 2001
-From: Theodore Ts'o <tytso@mit.edu>
-Date: Sat, 23 Aug 2014 17:47:19 -0400
-Subject: ext4: propagate errors up to ext4_find_entry()'s callers
-
-From: Theodore Ts'o <tytso@mit.edu>
-
-commit 36de928641ee48b2078d3fe9514242aaa2f92013 upstream.
-
-If we run into some kind of error, such as ENOMEM, while calling
-ext4_getblk() or ext4_dx_find_entry(), we need to make sure this error
-gets propagated up to ext4_find_entry() and then to its callers. This
-way, transient errors such as ENOMEM can get propagated to the VFS.
-This is important so that the system calls return the appropriate
-error, and also so that in the case of ext4_lookup(), we return an
-error instead of a NULL inode, since that will result in a negative
-dentry cache entry that will stick around long past the OOM condition
-which caused a transient ENOMEM error.
-
-Google-Bug-Id: #17142205
-
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
----
- fs/ext4/ext4.h | 2 +-
- fs/ext4/namei.c | 35 +++++++++++++++++++++++++++++++++--
- 2 files changed, 34 insertions(+), 3 deletions(-)
-
---- a/fs/ext4/ext4.h
-+++ b/fs/ext4/ext4.h
-@@ -1826,7 +1826,7 @@ ext4_group_first_block_no(struct super_b
- /*
- * Special error return code only used by dx_probe() and its callers.
- */
--#define ERR_BAD_DX_DIR -75000
-+#define ERR_BAD_DX_DIR (-(MAX_ERRNO - 1))
-
- /*
- * Timeout and state flag for lazy initialization inode thread.
---- a/fs/ext4/namei.c
-+++ b/fs/ext4/namei.c
-@@ -1227,7 +1227,7 @@ static struct buffer_head * ext4_find_en
- buffer */
- int num = 0;
- ext4_lblk_t nblocks;
-- int i, err;
-+ int i, err = 0;
- int namelen;
-
- *res_dir = NULL;
-@@ -1264,7 +1264,11 @@ static struct buffer_head * ext4_find_en
- * return. Otherwise, fall back to doing a search the
- * old fashioned way.
- */
-- if (bh || (err != ERR_BAD_DX_DIR))
-+ if (err == -ENOENT)
-+ return NULL;
-+ if (err && err != ERR_BAD_DX_DIR)
-+ return ERR_PTR(err);
-+ if (bh)
- return bh;
- dxtrace(printk(KERN_DEBUG "ext4_find_entry: dx failed, "
- "falling back\n"));
-@@ -1295,6 +1299,11 @@ restart:
- }
- num++;
- bh = ext4_getblk(NULL, dir, b++, 0, &err);
-+ if (unlikely(err)) {
-+ if (ra_max == 0)
-+ return ERR_PTR(err);
-+ break;
-+ }
- bh_use[ra_max] = bh;
- if (bh)
- ll_rw_block(READ | REQ_META | REQ_PRIO,
-@@ -1417,6 +1426,8 @@ static struct dentry *ext4_lookup(struct
- return ERR_PTR(-ENAMETOOLONG);
-
- bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL);
-+ if (IS_ERR(bh))
-+ return (struct dentry *) bh;
- inode = NULL;
- if (bh) {
- __u32 ino = le32_to_cpu(de->inode);
-@@ -1450,6 +1461,8 @@ struct dentry *ext4_get_parent(struct de
- struct buffer_head *bh;
-
- bh = ext4_find_entry(child->d_inode, &dotdot, &de, NULL);
-+ if (IS_ERR(bh))
-+ return (struct dentry *) bh;
- if (!bh)
- return ERR_PTR(-ENOENT);
- ino = le32_to_cpu(de->inode);
-@@ -2727,6 +2740,8 @@ static int ext4_rmdir(struct inode *dir,
-
- retval = -ENOENT;
- bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL);
-+ if (IS_ERR(bh))
-+ return PTR_ERR(bh);
- if (!bh)
- goto end_rmdir;
-
-@@ -2794,6 +2809,8 @@ static int ext4_unlink(struct inode *dir
-
- retval = -ENOENT;
- bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL);
-+ if (IS_ERR(bh))
-+ return PTR_ERR(bh);
- if (!bh)
- goto end_unlink;
-
-@@ -3121,6 +3138,8 @@ static int ext4_find_delete_entry(handle
- struct ext4_dir_entry_2 *de;
-
- bh = ext4_find_entry(dir, d_name, &de, NULL);
-+ if (IS_ERR(bh))
-+ return PTR_ERR(bh);
- if (bh) {
- retval = ext4_delete_entry(handle, dir, de, bh);
- brelse(bh);
-@@ -3202,6 +3221,8 @@ static int ext4_rename(struct inode *old
- dquot_initialize(new.inode);
-
- old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, NULL);
-+ if (IS_ERR(old.bh))
-+ return PTR_ERR(old.bh);
- /*
- * Check for inode number is _not_ due to possible IO errors.
- * We might rmdir the source, keep it as pwd of some process
-@@ -3214,6 +3235,10 @@ static int ext4_rename(struct inode *old
-
- new.bh = ext4_find_entry(new.dir, &new.dentry->d_name,
- &new.de, &new.inlined);
-+ if (IS_ERR(new.bh)) {
-+ retval = PTR_ERR(new.bh);
-+ goto end_rename;
-+ }
- if (new.bh) {
- if (!new.inode) {
- brelse(new.bh);
-@@ -3330,6 +3355,8 @@ static int ext4_cross_rename(struct inod
-
- old.bh = ext4_find_entry(old.dir, &old.dentry->d_name,
- &old.de, &old.inlined);
-+ if (IS_ERR(old.bh))
-+ return PTR_ERR(old.bh);
- /*
- * Check for inode number is _not_ due to possible IO errors.
- * We might rmdir the source, keep it as pwd of some process
-@@ -3342,6 +3369,10 @@ static int ext4_cross_rename(struct inod
-
- new.bh = ext4_find_entry(new.dir, &new.dentry->d_name,
- &new.de, &new.inlined);
-+ if (IS_ERR(new.bh)) {
-+ retval = PTR_ERR(new.bh);
-+ goto end_rename;
-+ }
-
- /* RENAME_EXCHANGE case: old *and* new must both exist */
- if (!new.bh || le32_to_cpu(new.de->inode) != new.inode->i_ino)