diff options
author | Richard Weinberger <richard@nod.at> | 2016-06-12 18:49:04 -0400 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2016-06-14 04:51:42 -0400 |
commit | 61edc3f3b51d2d3948029197cfff6fef7d94e939 (patch) | |
tree | 0bcdb8eaa9992c0eabe6ec43b175cf7afa3f1b6a /drivers/mtd/ubi/kapi.c | |
parent | 1a498ec45eeabcb246c3c3f5822ed9ac1b4f70d8 (diff) |
ubi: Don't bypass ->getattr()
Directly accessing inode fields bypasses ->getattr()
and can cause problems when the underlying filesystem
does not have the default ->getattr() implementation.
So instead of obtaining the backing inode via d_backing_inode()
use vfs_getattr() and obtain what we need from the kstat struct.
Cc: Al Viro <viro@zeniv.linux.org.uk>
Reported-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'drivers/mtd/ubi/kapi.c')
-rw-r--r-- | drivers/mtd/ubi/kapi.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c index cc6fa0115c9a..a9e2cef7c95c 100644 --- a/drivers/mtd/ubi/kapi.c +++ b/drivers/mtd/ubi/kapi.c | |||
@@ -301,9 +301,9 @@ EXPORT_SYMBOL_GPL(ubi_open_volume_nm); | |||
301 | */ | 301 | */ |
302 | struct ubi_volume_desc *ubi_open_volume_path(const char *pathname, int mode) | 302 | struct ubi_volume_desc *ubi_open_volume_path(const char *pathname, int mode) |
303 | { | 303 | { |
304 | int error, ubi_num, vol_id, mod; | 304 | int error, ubi_num, vol_id; |
305 | struct inode *inode; | ||
306 | struct path path; | 305 | struct path path; |
306 | struct kstat stat; | ||
307 | 307 | ||
308 | dbg_gen("open volume %s, mode %d", pathname, mode); | 308 | dbg_gen("open volume %s, mode %d", pathname, mode); |
309 | 309 | ||
@@ -314,14 +314,17 @@ struct ubi_volume_desc *ubi_open_volume_path(const char *pathname, int mode) | |||
314 | if (error) | 314 | if (error) |
315 | return ERR_PTR(error); | 315 | return ERR_PTR(error); |
316 | 316 | ||
317 | inode = d_backing_inode(path.dentry); | 317 | error = vfs_getattr(&path, &stat); |
318 | mod = inode->i_mode; | ||
319 | ubi_num = ubi_major2num(imajor(inode)); | ||
320 | vol_id = iminor(inode) - 1; | ||
321 | path_put(&path); | 318 | path_put(&path); |
319 | if (error) | ||
320 | return ERR_PTR(error); | ||
322 | 321 | ||
323 | if (!S_ISCHR(mod)) | 322 | if (!S_ISCHR(stat.mode)) |
324 | return ERR_PTR(-EINVAL); | 323 | return ERR_PTR(-EINVAL); |
324 | |||
325 | ubi_num = ubi_major2num(MAJOR(stat.rdev)); | ||
326 | vol_id = MINOR(stat.rdev) - 1; | ||
327 | |||
325 | if (vol_id >= 0 && ubi_num >= 0) | 328 | if (vol_id >= 0 && ubi_num >= 0) |
326 | return ubi_open_volume(ubi_num, vol_id, mode); | 329 | return ubi_open_volume(ubi_num, vol_id, mode); |
327 | return ERR_PTR(-ENODEV); | 330 | return ERR_PTR(-ENODEV); |