diff options
Diffstat (limited to 'fs/stat.c')
| -rw-r--r-- | fs/stat.c | 51 |
1 files changed, 38 insertions, 13 deletions
diff --git a/fs/stat.c b/fs/stat.c index 14f45459c83..ae0c3cef992 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -37,22 +37,41 @@ void generic_fillattr(struct inode *inode, struct kstat *stat) EXPORT_SYMBOL(generic_fillattr); -int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) +/** + * vfs_getattr_nosec - getattr without security checks + * @path: file to get attributes from + * @stat: structure to return attributes in + * + * Get attributes without calling security_inode_getattr. + * + * Currently the only caller other than vfs_getattr is internal to the + * filehandle lookup code, which uses only the inode number and returns + * no attributes to any user. Any other code probably wants + * vfs_getattr. + */ +int vfs_getattr_nosec(struct path *path, struct kstat *stat) { - struct inode *inode = dentry->d_inode; - int retval; - - retval = security_inode_getattr(mnt, dentry); - if (retval) - return retval; + struct inode *inode = path->dentry->d_inode; if (inode->i_op->getattr) - return inode->i_op->getattr(mnt, dentry, stat); + return inode->i_op->getattr(path->mnt, path->dentry, stat); generic_fillattr(inode, stat); return 0; } +EXPORT_SYMBOL(vfs_getattr_nosec); + +int vfs_getattr(struct path *path, struct kstat *stat) +{ + int retval; + + retval = security_inode_getattr(path->mnt, path->dentry); + if (retval) + return retval; + return vfs_getattr_nosec(path, stat); +} + EXPORT_SYMBOL(vfs_getattr); int vfs_fstat(unsigned int fd, struct kstat *stat) @@ -61,8 +80,7 @@ int vfs_fstat(unsigned int fd, struct kstat *stat) int error = -EBADF; if (f.file) { - error = vfs_getattr(f.file->f_path.mnt, f.file->f_path.dentry, - stat); + error = vfs_getattr(&f.file->f_path, stat); fdput(f); } return error; @@ -89,7 +107,7 @@ retry: if (error) goto out; - error = vfs_getattr(path.mnt, path.dentry, stat); + error = vfs_getattr(&path, stat); path_put(&path); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; @@ -448,9 +466,8 @@ void inode_add_bytes(struct inode *inode, loff_t bytes) EXPORT_SYMBOL(inode_add_bytes); -void inode_sub_bytes(struct inode *inode, loff_t bytes) +void __inode_sub_bytes(struct inode *inode, loff_t bytes) { - spin_lock(&inode->i_lock); inode->i_blocks -= bytes >> 9; bytes &= 511; if (inode->i_bytes < bytes) { @@ -458,6 +475,14 @@ void inode_sub_bytes(struct inode *inode, loff_t bytes) inode->i_bytes += 512; } inode->i_bytes -= bytes; +} + +EXPORT_SYMBOL(__inode_sub_bytes); + +void inode_sub_bytes(struct inode *inode, loff_t bytes) +{ + spin_lock(&inode->i_lock); + __inode_sub_bytes(inode, bytes); spin_unlock(&inode->i_lock); } |
