diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2018-06-23 20:33:59 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2018-06-30 09:43:45 -0400 |
commit | e876c445df4009d7b1ebdd2a92ca23566ca05440 (patch) | |
tree | f6095302e4657e05350bed67935dc18ee8a4adf4 /fs/hpfs | |
parent | ce397d215ccd07b8ae3f71db689aedb85d56ab40 (diff) |
hpfs: fix an inode leak in lookup, switch to d_splice_alias()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/hpfs')
-rw-r--r-- | fs/hpfs/dir.c | 23 |
1 files changed, 7 insertions, 16 deletions
diff --git a/fs/hpfs/dir.c b/fs/hpfs/dir.c index c83ece7facc5..d85230c84ef2 100644 --- a/fs/hpfs/dir.c +++ b/fs/hpfs/dir.c | |||
@@ -244,6 +244,7 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, unsigned in | |||
244 | result = iget_locked(dir->i_sb, ino); | 244 | result = iget_locked(dir->i_sb, ino); |
245 | if (!result) { | 245 | if (!result) { |
246 | hpfs_error(dir->i_sb, "hpfs_lookup: can't get inode"); | 246 | hpfs_error(dir->i_sb, "hpfs_lookup: can't get inode"); |
247 | result = ERR_PTR(-ENOMEM); | ||
247 | goto bail1; | 248 | goto bail1; |
248 | } | 249 | } |
249 | if (result->i_state & I_NEW) { | 250 | if (result->i_state & I_NEW) { |
@@ -266,6 +267,8 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, unsigned in | |||
266 | 267 | ||
267 | if (de->has_acl || de->has_xtd_perm) if (!sb_rdonly(dir->i_sb)) { | 268 | if (de->has_acl || de->has_xtd_perm) if (!sb_rdonly(dir->i_sb)) { |
268 | hpfs_error(result->i_sb, "ACLs or XPERM found. This is probably HPFS386. This driver doesn't support it now. Send me some info on these structures"); | 269 | hpfs_error(result->i_sb, "ACLs or XPERM found. This is probably HPFS386. This driver doesn't support it now. Send me some info on these structures"); |
270 | iput(result); | ||
271 | result = ERR_PTR(-EINVAL); | ||
269 | goto bail1; | 272 | goto bail1; |
270 | } | 273 | } |
271 | 274 | ||
@@ -301,29 +304,17 @@ struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, unsigned in | |||
301 | } | 304 | } |
302 | } | 305 | } |
303 | 306 | ||
307 | bail1: | ||
304 | hpfs_brelse4(&qbh); | 308 | hpfs_brelse4(&qbh); |
305 | 309 | ||
306 | /* | 310 | /* |
307 | * Made it. | 311 | * Made it. |
308 | */ | 312 | */ |
309 | 313 | ||
310 | end: | 314 | end: |
311 | end_add: | 315 | end_add: |
312 | hpfs_unlock(dir->i_sb); | 316 | hpfs_unlock(dir->i_sb); |
313 | d_add(dentry, result); | 317 | return d_splice_alias(result, dentry); |
314 | return NULL; | ||
315 | |||
316 | /* | ||
317 | * Didn't. | ||
318 | */ | ||
319 | bail1: | ||
320 | |||
321 | hpfs_brelse4(&qbh); | ||
322 | |||
323 | /*bail:*/ | ||
324 | |||
325 | hpfs_unlock(dir->i_sb); | ||
326 | return ERR_PTR(-ENOENT); | ||
327 | } | 318 | } |
328 | 319 | ||
329 | const struct file_operations hpfs_dir_ops = | 320 | const struct file_operations hpfs_dir_ops = |