aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJann Horn <jannh@google.com>2018-10-30 18:06:38 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-10-31 11:54:14 -0400
commitb10298d56c9623f9b173f19959732d3184b35f4f (patch)
treef0c80f0465a7b15e66d11747c2e7aefd898c486f
parent6c9a3f843a29d6894dfc40df338b91dbd78f0ae3 (diff)
reiserfs: propagate errors from fill_with_dentries() properly
fill_with_dentries() failed to propagate errors up to reiserfs_for_each_xattr() properly. Plumb them through. Note that reiserfs_for_each_xattr() is only used by reiserfs_delete_xattrs() and reiserfs_chown_xattrs(). The result of reiserfs_delete_xattrs() is discarded anyway, the only difference there is whether a warning is printed to dmesg. The result of reiserfs_chown_xattrs() does matter because it can block chowning of the file to which the xattrs belong; but either way, the resulting state can have misaligned ownership, so my patch doesn't improve things greatly. Credit for making me look at this code goes to Al Viro, who pointed out that the ->actor calling convention is suboptimal and should be changed. Link: http://lkml.kernel.org/r/20180802163335.83312-1-jannh@google.com Signed-off-by: Jann Horn <jannh@google.com> Reviewed-by: Andrew Morton <akpm@linux-foundation.org> Cc: Jeff Mahoney <jeffm@suse.com> Cc: Eric Biggers <ebiggers@google.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/reiserfs/xattr.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index 48cdfc81fe10..32d8986c26fb 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -185,6 +185,7 @@ struct reiserfs_dentry_buf {
185 struct dir_context ctx; 185 struct dir_context ctx;
186 struct dentry *xadir; 186 struct dentry *xadir;
187 int count; 187 int count;
188 int err;
188 struct dentry *dentries[8]; 189 struct dentry *dentries[8];
189}; 190};
190 191
@@ -207,6 +208,7 @@ fill_with_dentries(struct dir_context *ctx, const char *name, int namelen,
207 208
208 dentry = lookup_one_len(name, dbuf->xadir, namelen); 209 dentry = lookup_one_len(name, dbuf->xadir, namelen);
209 if (IS_ERR(dentry)) { 210 if (IS_ERR(dentry)) {
211 dbuf->err = PTR_ERR(dentry);
210 return PTR_ERR(dentry); 212 return PTR_ERR(dentry);
211 } else if (d_really_is_negative(dentry)) { 213 } else if (d_really_is_negative(dentry)) {
212 /* A directory entry exists, but no file? */ 214 /* A directory entry exists, but no file? */
@@ -215,6 +217,7 @@ fill_with_dentries(struct dir_context *ctx, const char *name, int namelen,
215 "not found for file %pd.\n", 217 "not found for file %pd.\n",
216 dentry, dbuf->xadir); 218 dentry, dbuf->xadir);
217 dput(dentry); 219 dput(dentry);
220 dbuf->err = -EIO;
218 return -EIO; 221 return -EIO;
219 } 222 }
220 223
@@ -262,6 +265,10 @@ static int reiserfs_for_each_xattr(struct inode *inode,
262 err = reiserfs_readdir_inode(d_inode(dir), &buf.ctx); 265 err = reiserfs_readdir_inode(d_inode(dir), &buf.ctx);
263 if (err) 266 if (err)
264 break; 267 break;
268 if (buf.err) {
269 err = buf.err;
270 break;
271 }
265 if (!buf.count) 272 if (!buf.count)
266 break; 273 break;
267 for (i = 0; !err && i < buf.count && buf.dentries[i]; i++) { 274 for (i = 0; !err && i < buf.count && buf.dentries[i]; i++) {