VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   33 Branches   55 Tags
b24413180f560 (Greg Kroah-Hartman 2017-11-01 15:07:57 +0100   1) // SPDX-License-Identifier: GPL-2.0
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   2) /*
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   3)  *  linux/fs/stat.c
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   4)  *
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   5)  *  Copyright (C) 1991, 1992  Linus Torvalds
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   6)  */
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   7) 
630d9c47274aa (Paul Gortmaker     2011-11-16 23:57:37 -0500   8) #include <linux/export.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700   9) #include <linux/mm.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  10) #include <linux/errno.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  11) #include <linux/file.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  12) #include <linux/highuid.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  13) #include <linux/fs.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  14) #include <linux/namei.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  15) #include <linux/security.h>
5b825c3af1d8a (Ingo Molnar        2017-02-02 17:54:15 +0100  16) #include <linux/cred.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  17) #include <linux/syscalls.h>
ba52de123d454 (Theodore Ts'o      2006-09-27 01:50:49 -0700  18) #include <linux/pagemap.h>
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400  19) #include <linux/compat.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  20) 
7c0f6ba682b9c (Linus Torvalds     2016-12-24 11:46:01 -0800  21) #include <linux/uaccess.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  22) #include <asm/unistd.h>
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  23) 
3934e36f6099e (Jens Axboe         2019-12-14 13:26:33 -0700  24) #include "internal.h"
fa2fcf4f1df15 (Miklos Szeredi     2020-05-14 16:44:24 +0200  25) #include "mount.h"
3934e36f6099e (Jens Axboe         2019-12-14 13:26:33 -0700  26) 
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000  27) /**
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000  28)  * generic_fillattr - Fill in the basic attributes from the inode struct
0d56a4518d5ea (Christian Brauner  2021-01-21 14:19:30 +0100  29)  * @mnt_userns:	user namespace of the mount the inode was found from
0d56a4518d5ea (Christian Brauner  2021-01-21 14:19:30 +0100  30)  * @inode:	Inode to use as the source
0d56a4518d5ea (Christian Brauner  2021-01-21 14:19:30 +0100  31)  * @stat:	Where to fill in the attributes
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000  32)  *
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000  33)  * Fill in the basic attributes in the kstat structure from data that's to be
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000  34)  * found on the VFS inode structure.  This is the default if no getattr inode
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000  35)  * operation is supplied.
0d56a4518d5ea (Christian Brauner  2021-01-21 14:19:30 +0100  36)  *
0d56a4518d5ea (Christian Brauner  2021-01-21 14:19:30 +0100  37)  * If the inode has been found through an idmapped mount the user namespace of
0d56a4518d5ea (Christian Brauner  2021-01-21 14:19:30 +0100  38)  * the vfsmount must be passed through @mnt_userns. This function will then
0d56a4518d5ea (Christian Brauner  2021-01-21 14:19:30 +0100  39)  * take care to map the inode according to @mnt_userns before filling in the
0d56a4518d5ea (Christian Brauner  2021-01-21 14:19:30 +0100  40)  * uid and gid filds. On non-idmapped mounts or if permission checking is to be
0d56a4518d5ea (Christian Brauner  2021-01-21 14:19:30 +0100  41)  * performed on the raw inode simply passs init_user_ns.
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000  42)  */
0d56a4518d5ea (Christian Brauner  2021-01-21 14:19:30 +0100  43) void generic_fillattr(struct user_namespace *mnt_userns, struct inode *inode,
0d56a4518d5ea (Christian Brauner  2021-01-21 14:19:30 +0100  44) 		      struct kstat *stat)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  45) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  46) 	stat->dev = inode->i_sb->s_dev;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  47) 	stat->ino = inode->i_ino;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  48) 	stat->mode = inode->i_mode;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  49) 	stat->nlink = inode->i_nlink;
0d56a4518d5ea (Christian Brauner  2021-01-21 14:19:30 +0100  50) 	stat->uid = i_uid_into_mnt(mnt_userns, inode);
0d56a4518d5ea (Christian Brauner  2021-01-21 14:19:30 +0100  51) 	stat->gid = i_gid_into_mnt(mnt_userns, inode);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  52) 	stat->rdev = inode->i_rdev;
3ddcd0569cd68 (Linus Torvalds     2011-08-06 22:45:50 -0700  53) 	stat->size = i_size_read(inode);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  54) 	stat->atime = inode->i_atime;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  55) 	stat->mtime = inode->i_mtime;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  56) 	stat->ctime = inode->i_ctime;
93407472a21b8 (Fabian Frederick   2017-02-27 14:28:32 -0800  57) 	stat->blksize = i_blocksize(inode);
3ddcd0569cd68 (Linus Torvalds     2011-08-06 22:45:50 -0700  58) 	stat->blocks = inode->i_blocks;
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000  59) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  60) EXPORT_SYMBOL(generic_fillattr);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  61) 
4f911138c8da9 (Amir Goldstein     2021-06-19 12:26:16 +0300  62) /**
4f911138c8da9 (Amir Goldstein     2021-06-19 12:26:16 +0300  63)  * generic_fill_statx_attr - Fill in the statx attributes from the inode flags
4f911138c8da9 (Amir Goldstein     2021-06-19 12:26:16 +0300  64)  * @inode:	Inode to use as the source
4f911138c8da9 (Amir Goldstein     2021-06-19 12:26:16 +0300  65)  * @stat:	Where to fill in the attribute flags
4f911138c8da9 (Amir Goldstein     2021-06-19 12:26:16 +0300  66)  *
4f911138c8da9 (Amir Goldstein     2021-06-19 12:26:16 +0300  67)  * Fill in the STATX_ATTR_* flags in the kstat structure for properties of the
4f911138c8da9 (Amir Goldstein     2021-06-19 12:26:16 +0300  68)  * inode that are published on i_flags and enforced by the VFS.
4f911138c8da9 (Amir Goldstein     2021-06-19 12:26:16 +0300  69)  */
4f911138c8da9 (Amir Goldstein     2021-06-19 12:26:16 +0300  70) void generic_fill_statx_attr(struct inode *inode, struct kstat *stat)
4f911138c8da9 (Amir Goldstein     2021-06-19 12:26:16 +0300  71) {
4f911138c8da9 (Amir Goldstein     2021-06-19 12:26:16 +0300  72) 	if (inode->i_flags & S_IMMUTABLE)
4f911138c8da9 (Amir Goldstein     2021-06-19 12:26:16 +0300  73) 		stat->attributes |= STATX_ATTR_IMMUTABLE;
4f911138c8da9 (Amir Goldstein     2021-06-19 12:26:16 +0300  74) 	if (inode->i_flags & S_APPEND)
4f911138c8da9 (Amir Goldstein     2021-06-19 12:26:16 +0300  75) 		stat->attributes |= STATX_ATTR_APPEND;
4f911138c8da9 (Amir Goldstein     2021-06-19 12:26:16 +0300  76) 	stat->attributes_mask |= KSTAT_ATTR_VFS_FLAGS;
4f911138c8da9 (Amir Goldstein     2021-06-19 12:26:16 +0300  77) }
4f911138c8da9 (Amir Goldstein     2021-06-19 12:26:16 +0300  78) EXPORT_SYMBOL(generic_fill_statx_attr);
4f911138c8da9 (Amir Goldstein     2021-06-19 12:26:16 +0300  79) 
b7a6ec52dd4ec (J. Bruce Fields    2013-10-02 17:01:18 -0400  80) /**
b7a6ec52dd4ec (J. Bruce Fields    2013-10-02 17:01:18 -0400  81)  * vfs_getattr_nosec - getattr without security checks
b7a6ec52dd4ec (J. Bruce Fields    2013-10-02 17:01:18 -0400  82)  * @path: file to get attributes from
b7a6ec52dd4ec (J. Bruce Fields    2013-10-02 17:01:18 -0400  83)  * @stat: structure to return attributes in
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000  84)  * @request_mask: STATX_xxx flags indicating what the caller wants
f2d077ff1b5c1 (Christoph Hellwig  2020-09-26 09:04:01 +0200  85)  * @query_flags: Query mode (AT_STATX_SYNC_TYPE)
b7a6ec52dd4ec (J. Bruce Fields    2013-10-02 17:01:18 -0400  86)  *
b7a6ec52dd4ec (J. Bruce Fields    2013-10-02 17:01:18 -0400  87)  * Get attributes without calling security_inode_getattr.
b7a6ec52dd4ec (J. Bruce Fields    2013-10-02 17:01:18 -0400  88)  *
b7a6ec52dd4ec (J. Bruce Fields    2013-10-02 17:01:18 -0400  89)  * Currently the only caller other than vfs_getattr is internal to the
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000  90)  * filehandle lookup code, which uses only the inode number and returns no
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000  91)  * attributes to any user.  Any other code probably wants vfs_getattr.
b7a6ec52dd4ec (J. Bruce Fields    2013-10-02 17:01:18 -0400  92)  */
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000  93) int vfs_getattr_nosec(const struct path *path, struct kstat *stat,
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000  94) 		      u32 request_mask, unsigned int query_flags)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  95) {
549c7297717c3 (Christian Brauner  2021-01-21 14:19:43 +0100  96) 	struct user_namespace *mnt_userns;
bb668734c4c96 (David Howells      2015-03-17 22:26:21 +0000  97) 	struct inode *inode = d_backing_inode(path->dentry);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700  98) 
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000  99) 	memset(stat, 0, sizeof(*stat));
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 100) 	stat->result_mask |= STATX_BASIC_STATS;
f2d077ff1b5c1 (Christoph Hellwig  2020-09-26 09:04:01 +0200 101) 	query_flags &= AT_STATX_SYNC_TYPE;
801e523796004 (Christoph Hellwig  2019-01-21 16:23:26 +0100 102) 
801e523796004 (Christoph Hellwig  2019-01-21 16:23:26 +0100 103) 	/* allow the fs to override these if it really wants to */
761e28fa270a3 (Miklos Szeredi     2020-05-14 16:44:24 +0200 104) 	/* SB_NOATIME means filesystem supplies dummy atime value */
761e28fa270a3 (Miklos Szeredi     2020-05-14 16:44:24 +0200 105) 	if (inode->i_sb->s_flags & SB_NOATIME)
801e523796004 (Christoph Hellwig  2019-01-21 16:23:26 +0100 106) 		stat->result_mask &= ~STATX_ATIME;
5afa7e8b70d65 (Theodore Ts'o      2021-04-17 23:03:50 -0400 107) 
5afa7e8b70d65 (Theodore Ts'o      2021-04-17 23:03:50 -0400 108) 	/*
5afa7e8b70d65 (Theodore Ts'o      2021-04-17 23:03:50 -0400 109) 	 * Note: If you add another clause to set an attribute flag, please
5afa7e8b70d65 (Theodore Ts'o      2021-04-17 23:03:50 -0400 110) 	 * update attributes_mask below.
5afa7e8b70d65 (Theodore Ts'o      2021-04-17 23:03:50 -0400 111) 	 */
801e523796004 (Christoph Hellwig  2019-01-21 16:23:26 +0100 112) 	if (IS_AUTOMOUNT(inode))
801e523796004 (Christoph Hellwig  2019-01-21 16:23:26 +0100 113) 		stat->attributes |= STATX_ATTR_AUTOMOUNT;
801e523796004 (Christoph Hellwig  2019-01-21 16:23:26 +0100 114) 
712b2698e4c02 (Ira Weiny          2020-04-30 07:41:34 -0700 115) 	if (IS_DAX(inode))
712b2698e4c02 (Ira Weiny          2020-04-30 07:41:34 -0700 116) 		stat->attributes |= STATX_ATTR_DAX;
712b2698e4c02 (Ira Weiny          2020-04-30 07:41:34 -0700 117) 
5afa7e8b70d65 (Theodore Ts'o      2021-04-17 23:03:50 -0400 118) 	stat->attributes_mask |= (STATX_ATTR_AUTOMOUNT |
5afa7e8b70d65 (Theodore Ts'o      2021-04-17 23:03:50 -0400 119) 				  STATX_ATTR_DAX);
5afa7e8b70d65 (Theodore Ts'o      2021-04-17 23:03:50 -0400 120) 
549c7297717c3 (Christian Brauner  2021-01-21 14:19:43 +0100 121) 	mnt_userns = mnt_user_ns(path->mnt);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 122) 	if (inode->i_op->getattr)
549c7297717c3 (Christian Brauner  2021-01-21 14:19:43 +0100 123) 		return inode->i_op->getattr(mnt_userns, path, stat,
549c7297717c3 (Christian Brauner  2021-01-21 14:19:43 +0100 124) 					    request_mask, query_flags);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 125) 
549c7297717c3 (Christian Brauner  2021-01-21 14:19:43 +0100 126) 	generic_fillattr(mnt_userns, inode, stat);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 127) 	return 0;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 128) }
b7a6ec52dd4ec (J. Bruce Fields    2013-10-02 17:01:18 -0400 129) EXPORT_SYMBOL(vfs_getattr_nosec);
b7a6ec52dd4ec (J. Bruce Fields    2013-10-02 17:01:18 -0400 130) 
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 131) /*
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 132)  * vfs_getattr - Get the enhanced basic attributes of a file
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 133)  * @path: The file of interest
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 134)  * @stat: Where to return the statistics
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 135)  * @request_mask: STATX_xxx flags indicating what the caller wants
f2d077ff1b5c1 (Christoph Hellwig  2020-09-26 09:04:01 +0200 136)  * @query_flags: Query mode (AT_STATX_SYNC_TYPE)
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 137)  *
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 138)  * Ask the filesystem for a file's attributes.  The caller must indicate in
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 139)  * request_mask and query_flags to indicate what they want.
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 140)  *
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 141)  * If the file is remote, the filesystem can be forced to update the attributes
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 142)  * from the backing store by passing AT_STATX_FORCE_SYNC in query_flags or can
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 143)  * suppress the update by passing AT_STATX_DONT_SYNC.
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 144)  *
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 145)  * Bits must have been set in request_mask to indicate which attributes the
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 146)  * caller wants retrieving.  Any such attribute not requested may be returned
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 147)  * anyway, but the value may be approximate, and, if remote, may not have been
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 148)  * synchronised with the server.
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 149)  *
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 150)  * 0 will be returned on success, and a -ve error code if unsuccessful.
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 151)  */
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 152) int vfs_getattr(const struct path *path, struct kstat *stat,
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 153) 		u32 request_mask, unsigned int query_flags)
b7a6ec52dd4ec (J. Bruce Fields    2013-10-02 17:01:18 -0400 154) {
b7a6ec52dd4ec (J. Bruce Fields    2013-10-02 17:01:18 -0400 155) 	int retval;
b7a6ec52dd4ec (J. Bruce Fields    2013-10-02 17:01:18 -0400 156) 
3f7036a071b87 (Al Viro            2015-03-08 19:28:30 -0400 157) 	retval = security_inode_getattr(path);
b7a6ec52dd4ec (J. Bruce Fields    2013-10-02 17:01:18 -0400 158) 	if (retval)
b7a6ec52dd4ec (J. Bruce Fields    2013-10-02 17:01:18 -0400 159) 		return retval;
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 160) 	return vfs_getattr_nosec(path, stat, request_mask, query_flags);
b7a6ec52dd4ec (J. Bruce Fields    2013-10-02 17:01:18 -0400 161) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 162) EXPORT_SYMBOL(vfs_getattr);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 163) 
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 164) /**
da9aa5d96bfe4 (Christoph Hellwig  2020-09-26 09:03:57 +0200 165)  * vfs_fstat - Get the basic attributes by file descriptor
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 166)  * @fd: The file descriptor referring to the file of interest
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 167)  * @stat: The result structure to fill in.
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 168)  *
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 169)  * This function is a wrapper around vfs_getattr().  The main difference is
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 170)  * that it uses a file descriptor to determine the file location.
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 171)  *
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 172)  * 0 will be returned on success, and a -ve error code if unsuccessful.
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 173)  */
da9aa5d96bfe4 (Christoph Hellwig  2020-09-26 09:03:57 +0200 174) int vfs_fstat(int fd, struct kstat *stat)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 175) {
8c7493aa3e9ae (Eric Biggers       2017-03-31 18:31:32 +0100 176) 	struct fd f;
da9aa5d96bfe4 (Christoph Hellwig  2020-09-26 09:03:57 +0200 177) 	int error;
8c7493aa3e9ae (Eric Biggers       2017-03-31 18:31:32 +0100 178) 
8c7493aa3e9ae (Eric Biggers       2017-03-31 18:31:32 +0100 179) 	f = fdget_raw(fd);
da9aa5d96bfe4 (Christoph Hellwig  2020-09-26 09:03:57 +0200 180) 	if (!f.file)
da9aa5d96bfe4 (Christoph Hellwig  2020-09-26 09:03:57 +0200 181) 		return -EBADF;
da9aa5d96bfe4 (Christoph Hellwig  2020-09-26 09:03:57 +0200 182) 	error = vfs_getattr(&f.file->f_path, stat, STATX_BASIC_STATS, 0);
da9aa5d96bfe4 (Christoph Hellwig  2020-09-26 09:03:57 +0200 183) 	fdput(f);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 184) 	return error;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 185) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 186) 
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 187) /**
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 188)  * vfs_statx - Get basic and extra attributes by filename
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 189)  * @dfd: A file descriptor representing the base dir for a relative filename
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 190)  * @filename: The name of the file of interest
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 191)  * @flags: Flags to control the query
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 192)  * @stat: The result structure to fill in.
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 193)  * @request_mask: STATX_xxx flags indicating what the caller wants
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 194)  *
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 195)  * This function is a wrapper around vfs_getattr().  The main difference is
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 196)  * that it uses a filename and base directory to determine the file location.
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 197)  * Additionally, the use of AT_SYMLINK_NOFOLLOW in flags will prevent a symlink
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 198)  * at the given name from being referenced.
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 199)  *
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 200)  * 0 will be returned on success, and a -ve error code if unsuccessful.
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 201)  */
09f1bde4017e9 (Christoph Hellwig  2020-09-26 09:03:59 +0200 202) static int vfs_statx(int dfd, const char __user *filename, int flags,
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 203) 	      struct kstat *stat, u32 request_mask)
0112fc2229847 (Oleg Drokin        2009-04-08 20:05:42 +0400 204) {
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 205) 	struct path path;
b3f0515004a5e (Christoph Hellwig  2020-09-26 09:04:00 +0200 206) 	unsigned lookup_flags = 0;
b3f0515004a5e (Christoph Hellwig  2020-09-26 09:04:00 +0200 207) 	int error;
0112fc2229847 (Oleg Drokin        2009-04-08 20:05:42 +0400 208) 
b3f0515004a5e (Christoph Hellwig  2020-09-26 09:04:00 +0200 209) 	if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | AT_EMPTY_PATH |
f2d077ff1b5c1 (Christoph Hellwig  2020-09-26 09:04:01 +0200 210) 		      AT_STATX_SYNC_TYPE))
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 211) 		return -EINVAL;
b3f0515004a5e (Christoph Hellwig  2020-09-26 09:04:00 +0200 212) 
b3f0515004a5e (Christoph Hellwig  2020-09-26 09:04:00 +0200 213) 	if (!(flags & AT_SYMLINK_NOFOLLOW))
b3f0515004a5e (Christoph Hellwig  2020-09-26 09:04:00 +0200 214) 		lookup_flags |= LOOKUP_FOLLOW;
b3f0515004a5e (Christoph Hellwig  2020-09-26 09:04:00 +0200 215) 	if (!(flags & AT_NO_AUTOMOUNT))
b3f0515004a5e (Christoph Hellwig  2020-09-26 09:04:00 +0200 216) 		lookup_flags |= LOOKUP_AUTOMOUNT;
b3f0515004a5e (Christoph Hellwig  2020-09-26 09:04:00 +0200 217) 	if (flags & AT_EMPTY_PATH)
b3f0515004a5e (Christoph Hellwig  2020-09-26 09:04:00 +0200 218) 		lookup_flags |= LOOKUP_EMPTY;
b3f0515004a5e (Christoph Hellwig  2020-09-26 09:04:00 +0200 219) 
836fb7e7b978e (Jeff Layton        2012-12-11 12:10:05 -0500 220) retry:
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 221) 	error = user_path_at(dfd, filename, lookup_flags, &path);
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 222) 	if (error)
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 223) 		goto out;
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 224) 
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 225) 	error = vfs_getattr(&path, stat, request_mask, flags);
fa2fcf4f1df15 (Miklos Szeredi     2020-05-14 16:44:24 +0200 226) 	stat->mnt_id = real_mount(path.mnt)->mnt_id;
fa2fcf4f1df15 (Miklos Szeredi     2020-05-14 16:44:24 +0200 227) 	stat->result_mask |= STATX_MNT_ID;
80340fe3605c0 (Miklos Szeredi     2020-05-14 16:44:24 +0200 228) 	if (path.mnt->mnt_root == path.dentry)
80340fe3605c0 (Miklos Szeredi     2020-05-14 16:44:24 +0200 229) 		stat->attributes |= STATX_ATTR_MOUNT_ROOT;
80340fe3605c0 (Miklos Szeredi     2020-05-14 16:44:24 +0200 230) 	stat->attributes_mask |= STATX_ATTR_MOUNT_ROOT;
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 231) 	path_put(&path);
836fb7e7b978e (Jeff Layton        2012-12-11 12:10:05 -0500 232) 	if (retry_estale(error, lookup_flags)) {
836fb7e7b978e (Jeff Layton        2012-12-11 12:10:05 -0500 233) 		lookup_flags |= LOOKUP_REVAL;
836fb7e7b978e (Jeff Layton        2012-12-11 12:10:05 -0500 234) 		goto retry;
836fb7e7b978e (Jeff Layton        2012-12-11 12:10:05 -0500 235) 	}
0112fc2229847 (Oleg Drokin        2009-04-08 20:05:42 +0400 236) out:
0112fc2229847 (Oleg Drokin        2009-04-08 20:05:42 +0400 237) 	return error;
0112fc2229847 (Oleg Drokin        2009-04-08 20:05:42 +0400 238) }
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 239) 
09f1bde4017e9 (Christoph Hellwig  2020-09-26 09:03:59 +0200 240) int vfs_fstatat(int dfd, const char __user *filename,
09f1bde4017e9 (Christoph Hellwig  2020-09-26 09:03:59 +0200 241) 			      struct kstat *stat, int flags)
09f1bde4017e9 (Christoph Hellwig  2020-09-26 09:03:59 +0200 242) {
09f1bde4017e9 (Christoph Hellwig  2020-09-26 09:03:59 +0200 243) 	return vfs_statx(dfd, filename, flags | AT_NO_AUTOMOUNT,
09f1bde4017e9 (Christoph Hellwig  2020-09-26 09:03:59 +0200 244) 			 stat, STATX_BASIC_STATS);
09f1bde4017e9 (Christoph Hellwig  2020-09-26 09:03:59 +0200 245) }
0112fc2229847 (Oleg Drokin        2009-04-08 20:05:42 +0400 246) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 247) #ifdef __ARCH_WANT_OLD_STAT
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 248) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 249) /*
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 250)  * For backward compatibility?  Maybe this should be moved
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 251)  * into arch/i386 instead?
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 252)  */
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 253) static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat __user * statbuf)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 254) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 255) 	static int warncount = 5;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 256) 	struct __old_kernel_stat tmp;
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 257) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 258) 	if (warncount > 0) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 259) 		warncount--;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 260) 		printk(KERN_WARNING "VFS: Warning: %s using old stat() call. Recompile your binary.\n",
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 261) 			current->comm);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 262) 	} else if (warncount < 0) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 263) 		/* it's laughable, but... */
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 264) 		warncount = 0;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 265) 	}
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 266) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 267) 	memset(&tmp, 0, sizeof(struct __old_kernel_stat));
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 268) 	tmp.st_dev = old_encode_dev(stat->dev);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 269) 	tmp.st_ino = stat->ino;
afefdbb28a0a2 (David Howells      2006-10-03 01:13:46 -0700 270) 	if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
afefdbb28a0a2 (David Howells      2006-10-03 01:13:46 -0700 271) 		return -EOVERFLOW;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 272) 	tmp.st_mode = stat->mode;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 273) 	tmp.st_nlink = stat->nlink;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 274) 	if (tmp.st_nlink != stat->nlink)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 275) 		return -EOVERFLOW;
a7c1938e22c02 (Eric W. Biederman  2012-02-09 09:10:30 -0800 276) 	SET_UID(tmp.st_uid, from_kuid_munged(current_user_ns(), stat->uid));
a7c1938e22c02 (Eric W. Biederman  2012-02-09 09:10:30 -0800 277) 	SET_GID(tmp.st_gid, from_kgid_munged(current_user_ns(), stat->gid));
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 278) 	tmp.st_rdev = old_encode_dev(stat->rdev);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 279) #if BITS_PER_LONG == 32
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 280) 	if (stat->size > MAX_NON_LFS)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 281) 		return -EOVERFLOW;
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 282) #endif
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 283) 	tmp.st_size = stat->size;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 284) 	tmp.st_atime = stat->atime.tv_sec;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 285) 	tmp.st_mtime = stat->mtime.tv_sec;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 286) 	tmp.st_ctime = stat->ctime.tv_sec;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 287) 	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 288) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 289) 
c7887325230ae (David Howells      2010-08-11 11:26:22 +0100 290) SYSCALL_DEFINE2(stat, const char __user *, filename,
c7887325230ae (David Howells      2010-08-11 11:26:22 +0100 291) 		struct __old_kernel_stat __user *, statbuf)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 292) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 293) 	struct kstat stat;
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 294) 	int error;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 295) 
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 296) 	error = vfs_stat(filename, &stat);
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 297) 	if (error)
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 298) 		return error;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 299) 
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 300) 	return cp_old_stat(&stat, statbuf);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 301) }
257ac264d6901 (Heiko Carstens     2009-01-14 14:14:13 +0100 302) 
c7887325230ae (David Howells      2010-08-11 11:26:22 +0100 303) SYSCALL_DEFINE2(lstat, const char __user *, filename,
c7887325230ae (David Howells      2010-08-11 11:26:22 +0100 304) 		struct __old_kernel_stat __user *, statbuf)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 305) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 306) 	struct kstat stat;
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 307) 	int error;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 308) 
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 309) 	error = vfs_lstat(filename, &stat);
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 310) 	if (error)
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 311) 		return error;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 312) 
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 313) 	return cp_old_stat(&stat, statbuf);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 314) }
257ac264d6901 (Heiko Carstens     2009-01-14 14:14:13 +0100 315) 
257ac264d6901 (Heiko Carstens     2009-01-14 14:14:13 +0100 316) SYSCALL_DEFINE2(fstat, unsigned int, fd, struct __old_kernel_stat __user *, statbuf)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 317) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 318) 	struct kstat stat;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 319) 	int error = vfs_fstat(fd, &stat);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 320) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 321) 	if (!error)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 322) 		error = cp_old_stat(&stat, statbuf);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 323) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 324) 	return error;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 325) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 326) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 327) #endif /* __ARCH_WANT_OLD_STAT */
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 328) 
82b355d161c95 (Arnd Bergmann      2018-04-13 11:50:12 +0200 329) #ifdef __ARCH_WANT_NEW_STAT
82b355d161c95 (Arnd Bergmann      2018-04-13 11:50:12 +0200 330) 
a52dd971f9478 (Linus Torvalds     2012-05-06 17:47:30 -0700 331) #if BITS_PER_LONG == 32
a52dd971f9478 (Linus Torvalds     2012-05-06 17:47:30 -0700 332) #  define choose_32_64(a,b) a
a52dd971f9478 (Linus Torvalds     2012-05-06 17:47:30 -0700 333) #else
a52dd971f9478 (Linus Torvalds     2012-05-06 17:47:30 -0700 334) #  define choose_32_64(a,b) b
a52dd971f9478 (Linus Torvalds     2012-05-06 17:47:30 -0700 335) #endif
a52dd971f9478 (Linus Torvalds     2012-05-06 17:47:30 -0700 336) 
4c416f42ee961 (Yaowei Bai         2016-01-15 16:58:01 -0800 337) #define valid_dev(x)  choose_32_64(old_valid_dev(x),true)
a52dd971f9478 (Linus Torvalds     2012-05-06 17:47:30 -0700 338) #define encode_dev(x) choose_32_64(old_encode_dev,new_encode_dev)(x)
a52dd971f9478 (Linus Torvalds     2012-05-06 17:47:30 -0700 339) 
8529f613b6945 (Linus Torvalds     2012-05-06 18:02:40 -0700 340) #ifndef INIT_STRUCT_STAT_PADDING
8529f613b6945 (Linus Torvalds     2012-05-06 18:02:40 -0700 341) #  define INIT_STRUCT_STAT_PADDING(st) memset(&st, 0, sizeof(st))
8529f613b6945 (Linus Torvalds     2012-05-06 18:02:40 -0700 342) #endif
8529f613b6945 (Linus Torvalds     2012-05-06 18:02:40 -0700 343) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 344) static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 345) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 346) 	struct stat tmp;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 347) 
a52dd971f9478 (Linus Torvalds     2012-05-06 17:47:30 -0700 348) 	if (!valid_dev(stat->dev) || !valid_dev(stat->rdev))
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 349) 		return -EOVERFLOW;
a52dd971f9478 (Linus Torvalds     2012-05-06 17:47:30 -0700 350) #if BITS_PER_LONG == 32
a52dd971f9478 (Linus Torvalds     2012-05-06 17:47:30 -0700 351) 	if (stat->size > MAX_NON_LFS)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 352) 		return -EOVERFLOW;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 353) #endif
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 354) 
8529f613b6945 (Linus Torvalds     2012-05-06 18:02:40 -0700 355) 	INIT_STRUCT_STAT_PADDING(tmp);
a52dd971f9478 (Linus Torvalds     2012-05-06 17:47:30 -0700 356) 	tmp.st_dev = encode_dev(stat->dev);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 357) 	tmp.st_ino = stat->ino;
afefdbb28a0a2 (David Howells      2006-10-03 01:13:46 -0700 358) 	if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
afefdbb28a0a2 (David Howells      2006-10-03 01:13:46 -0700 359) 		return -EOVERFLOW;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 360) 	tmp.st_mode = stat->mode;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 361) 	tmp.st_nlink = stat->nlink;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 362) 	if (tmp.st_nlink != stat->nlink)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 363) 		return -EOVERFLOW;
a7c1938e22c02 (Eric W. Biederman  2012-02-09 09:10:30 -0800 364) 	SET_UID(tmp.st_uid, from_kuid_munged(current_user_ns(), stat->uid));
a7c1938e22c02 (Eric W. Biederman  2012-02-09 09:10:30 -0800 365) 	SET_GID(tmp.st_gid, from_kgid_munged(current_user_ns(), stat->gid));
a52dd971f9478 (Linus Torvalds     2012-05-06 17:47:30 -0700 366) 	tmp.st_rdev = encode_dev(stat->rdev);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 367) 	tmp.st_size = stat->size;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 368) 	tmp.st_atime = stat->atime.tv_sec;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 369) 	tmp.st_mtime = stat->mtime.tv_sec;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 370) 	tmp.st_ctime = stat->ctime.tv_sec;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 371) #ifdef STAT_HAVE_NSEC
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 372) 	tmp.st_atime_nsec = stat->atime.tv_nsec;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 373) 	tmp.st_mtime_nsec = stat->mtime.tv_nsec;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 374) 	tmp.st_ctime_nsec = stat->ctime.tv_nsec;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 375) #endif
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 376) 	tmp.st_blocks = stat->blocks;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 377) 	tmp.st_blksize = stat->blksize;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 378) 	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 379) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 380) 
c7887325230ae (David Howells      2010-08-11 11:26:22 +0100 381) SYSCALL_DEFINE2(newstat, const char __user *, filename,
c7887325230ae (David Howells      2010-08-11 11:26:22 +0100 382) 		struct stat __user *, statbuf)
5590ff0d5528b (Ulrich Drepper     2006-01-18 17:43:53 -0800 383) {
5590ff0d5528b (Ulrich Drepper     2006-01-18 17:43:53 -0800 384) 	struct kstat stat;
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 385) 	int error = vfs_stat(filename, &stat);
5590ff0d5528b (Ulrich Drepper     2006-01-18 17:43:53 -0800 386) 
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 387) 	if (error)
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 388) 		return error;
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 389) 	return cp_new_stat(&stat, statbuf);
5590ff0d5528b (Ulrich Drepper     2006-01-18 17:43:53 -0800 390) }
5590ff0d5528b (Ulrich Drepper     2006-01-18 17:43:53 -0800 391) 
c7887325230ae (David Howells      2010-08-11 11:26:22 +0100 392) SYSCALL_DEFINE2(newlstat, const char __user *, filename,
c7887325230ae (David Howells      2010-08-11 11:26:22 +0100 393) 		struct stat __user *, statbuf)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 394) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 395) 	struct kstat stat;
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 396) 	int error;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 397) 
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 398) 	error = vfs_lstat(filename, &stat);
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 399) 	if (error)
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 400) 		return error;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 401) 
2eae7a1874ca5 (Christoph Hellwig  2009-04-08 16:34:03 -0400 402) 	return cp_new_stat(&stat, statbuf);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 403) }
5590ff0d5528b (Ulrich Drepper     2006-01-18 17:43:53 -0800 404) 
2833c28aa0d03 (Andreas Schwab     2006-04-27 15:46:42 +0200 405) #if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT)
c7887325230ae (David Howells      2010-08-11 11:26:22 +0100 406) SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename,
6559eed8ca7db (Heiko Carstens     2009-01-14 14:14:32 +0100 407) 		struct stat __user *, statbuf, int, flag)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 408) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 409) 	struct kstat stat;
0112fc2229847 (Oleg Drokin        2009-04-08 20:05:42 +0400 410) 	int error;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 411) 
0112fc2229847 (Oleg Drokin        2009-04-08 20:05:42 +0400 412) 	error = vfs_fstatat(dfd, filename, &stat, flag);
0112fc2229847 (Oleg Drokin        2009-04-08 20:05:42 +0400 413) 	if (error)
0112fc2229847 (Oleg Drokin        2009-04-08 20:05:42 +0400 414) 		return error;
0112fc2229847 (Oleg Drokin        2009-04-08 20:05:42 +0400 415) 	return cp_new_stat(&stat, statbuf);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 416) }
cff2b760096d1 (Ulrich Drepper     2006-02-11 17:55:47 -0800 417) #endif
5590ff0d5528b (Ulrich Drepper     2006-01-18 17:43:53 -0800 418) 
257ac264d6901 (Heiko Carstens     2009-01-14 14:14:13 +0100 419) SYSCALL_DEFINE2(newfstat, unsigned int, fd, struct stat __user *, statbuf)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 420) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 421) 	struct kstat stat;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 422) 	int error = vfs_fstat(fd, &stat);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 423) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 424) 	if (!error)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 425) 		error = cp_new_stat(&stat, statbuf);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 426) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 427) 	return error;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 428) }
82b355d161c95 (Arnd Bergmann      2018-04-13 11:50:12 +0200 429) #endif
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 430) 
2dae0248061e6 (Dominik Brodowski  2018-03-11 11:34:27 +0100 431) static int do_readlinkat(int dfd, const char __user *pathname,
2dae0248061e6 (Dominik Brodowski  2018-03-11 11:34:27 +0100 432) 			 char __user *buf, int bufsiz)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 433) {
2d8f30380ab8c (Al Viro            2008-07-22 09:59:21 -0400 434) 	struct path path;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 435) 	int error;
1fa1e7f615f4d (Andy Whitcroft     2011-11-02 09:44:39 +0100 436) 	int empty = 0;
7955119e02d9f (Jeff Layton        2012-12-11 12:10:06 -0500 437) 	unsigned int lookup_flags = LOOKUP_EMPTY;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 438) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 439) 	if (bufsiz <= 0)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 440) 		return -EINVAL;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 441) 
7955119e02d9f (Jeff Layton        2012-12-11 12:10:06 -0500 442) retry:
7955119e02d9f (Jeff Layton        2012-12-11 12:10:06 -0500 443) 	error = user_path_at_empty(dfd, pathname, lookup_flags, &path, &empty);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 444) 	if (!error) {
bb668734c4c96 (David Howells      2015-03-17 22:26:21 +0000 445) 		struct inode *inode = d_backing_inode(path.dentry);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 446) 
1fa1e7f615f4d (Andy Whitcroft     2011-11-02 09:44:39 +0100 447) 		error = empty ? -ENOENT : -EINVAL;
fd4a0edf2a3d7 (Miklos Szeredi     2016-12-09 16:45:04 +0100 448) 		/*
fd4a0edf2a3d7 (Miklos Szeredi     2016-12-09 16:45:04 +0100 449) 		 * AFS mountpoints allow readlink(2) but are not symlinks
fd4a0edf2a3d7 (Miklos Szeredi     2016-12-09 16:45:04 +0100 450) 		 */
fd4a0edf2a3d7 (Miklos Szeredi     2016-12-09 16:45:04 +0100 451) 		if (d_is_symlink(path.dentry) || inode->i_op->readlink) {
2d8f30380ab8c (Al Viro            2008-07-22 09:59:21 -0400 452) 			error = security_inode_readlink(path.dentry);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 453) 			if (!error) {
68ac1234fb949 (Al Viro            2012-03-15 08:21:57 -0400 454) 				touch_atime(&path);
fd4a0edf2a3d7 (Miklos Szeredi     2016-12-09 16:45:04 +0100 455) 				error = vfs_readlink(path.dentry, buf, bufsiz);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 456) 			}
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 457) 		}
2d8f30380ab8c (Al Viro            2008-07-22 09:59:21 -0400 458) 		path_put(&path);
7955119e02d9f (Jeff Layton        2012-12-11 12:10:06 -0500 459) 		if (retry_estale(error, lookup_flags)) {
7955119e02d9f (Jeff Layton        2012-12-11 12:10:06 -0500 460) 			lookup_flags |= LOOKUP_REVAL;
7955119e02d9f (Jeff Layton        2012-12-11 12:10:06 -0500 461) 			goto retry;
7955119e02d9f (Jeff Layton        2012-12-11 12:10:06 -0500 462) 		}
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 463) 	}
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 464) 	return error;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 465) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 466) 
2dae0248061e6 (Dominik Brodowski  2018-03-11 11:34:27 +0100 467) SYSCALL_DEFINE4(readlinkat, int, dfd, const char __user *, pathname,
2dae0248061e6 (Dominik Brodowski  2018-03-11 11:34:27 +0100 468) 		char __user *, buf, int, bufsiz)
2dae0248061e6 (Dominik Brodowski  2018-03-11 11:34:27 +0100 469) {
2dae0248061e6 (Dominik Brodowski  2018-03-11 11:34:27 +0100 470) 	return do_readlinkat(dfd, pathname, buf, bufsiz);
2dae0248061e6 (Dominik Brodowski  2018-03-11 11:34:27 +0100 471) }
2dae0248061e6 (Dominik Brodowski  2018-03-11 11:34:27 +0100 472) 
002c8976ee537 (Heiko Carstens     2009-01-14 14:14:18 +0100 473) SYSCALL_DEFINE3(readlink, const char __user *, path, char __user *, buf,
002c8976ee537 (Heiko Carstens     2009-01-14 14:14:18 +0100 474) 		int, bufsiz)
5590ff0d5528b (Ulrich Drepper     2006-01-18 17:43:53 -0800 475) {
2dae0248061e6 (Dominik Brodowski  2018-03-11 11:34:27 +0100 476) 	return do_readlinkat(AT_FDCWD, path, buf, bufsiz);
5590ff0d5528b (Ulrich Drepper     2006-01-18 17:43:53 -0800 477) }
5590ff0d5528b (Ulrich Drepper     2006-01-18 17:43:53 -0800 478) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 479) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 480) /* ---------- LFS-64 ----------- */
0753f70f07fbb (Catalin Marinas    2012-03-19 15:13:51 +0000 481) #if defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_COMPAT_STAT64)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 482) 
8529f613b6945 (Linus Torvalds     2012-05-06 18:02:40 -0700 483) #ifndef INIT_STRUCT_STAT64_PADDING
8529f613b6945 (Linus Torvalds     2012-05-06 18:02:40 -0700 484) #  define INIT_STRUCT_STAT64_PADDING(st) memset(&st, 0, sizeof(st))
8529f613b6945 (Linus Torvalds     2012-05-06 18:02:40 -0700 485) #endif
8529f613b6945 (Linus Torvalds     2012-05-06 18:02:40 -0700 486) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 487) static long cp_new_stat64(struct kstat *stat, struct stat64 __user *statbuf)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 488) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 489) 	struct stat64 tmp;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 490) 
8529f613b6945 (Linus Torvalds     2012-05-06 18:02:40 -0700 491) 	INIT_STRUCT_STAT64_PADDING(tmp);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 492) #ifdef CONFIG_MIPS
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 493) 	/* mips has weird padding, so we don't get 64 bits there */
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 494) 	tmp.st_dev = new_encode_dev(stat->dev);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 495) 	tmp.st_rdev = new_encode_dev(stat->rdev);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 496) #else
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 497) 	tmp.st_dev = huge_encode_dev(stat->dev);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 498) 	tmp.st_rdev = huge_encode_dev(stat->rdev);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 499) #endif
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 500) 	tmp.st_ino = stat->ino;
afefdbb28a0a2 (David Howells      2006-10-03 01:13:46 -0700 501) 	if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
afefdbb28a0a2 (David Howells      2006-10-03 01:13:46 -0700 502) 		return -EOVERFLOW;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 503) #ifdef STAT64_HAS_BROKEN_ST_INO
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 504) 	tmp.__st_ino = stat->ino;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 505) #endif
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 506) 	tmp.st_mode = stat->mode;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 507) 	tmp.st_nlink = stat->nlink;
a7c1938e22c02 (Eric W. Biederman  2012-02-09 09:10:30 -0800 508) 	tmp.st_uid = from_kuid_munged(current_user_ns(), stat->uid);
a7c1938e22c02 (Eric W. Biederman  2012-02-09 09:10:30 -0800 509) 	tmp.st_gid = from_kgid_munged(current_user_ns(), stat->gid);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 510) 	tmp.st_atime = stat->atime.tv_sec;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 511) 	tmp.st_atime_nsec = stat->atime.tv_nsec;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 512) 	tmp.st_mtime = stat->mtime.tv_sec;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 513) 	tmp.st_mtime_nsec = stat->mtime.tv_nsec;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 514) 	tmp.st_ctime = stat->ctime.tv_sec;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 515) 	tmp.st_ctime_nsec = stat->ctime.tv_nsec;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 516) 	tmp.st_size = stat->size;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 517) 	tmp.st_blocks = stat->blocks;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 518) 	tmp.st_blksize = stat->blksize;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 519) 	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 520) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 521) 
c7887325230ae (David Howells      2010-08-11 11:26:22 +0100 522) SYSCALL_DEFINE2(stat64, const char __user *, filename,
c7887325230ae (David Howells      2010-08-11 11:26:22 +0100 523) 		struct stat64 __user *, statbuf)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 524) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 525) 	struct kstat stat;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 526) 	int error = vfs_stat(filename, &stat);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 527) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 528) 	if (!error)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 529) 		error = cp_new_stat64(&stat, statbuf);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 530) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 531) 	return error;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 532) }
257ac264d6901 (Heiko Carstens     2009-01-14 14:14:13 +0100 533) 
c7887325230ae (David Howells      2010-08-11 11:26:22 +0100 534) SYSCALL_DEFINE2(lstat64, const char __user *, filename,
c7887325230ae (David Howells      2010-08-11 11:26:22 +0100 535) 		struct stat64 __user *, statbuf)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 536) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 537) 	struct kstat stat;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 538) 	int error = vfs_lstat(filename, &stat);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 539) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 540) 	if (!error)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 541) 		error = cp_new_stat64(&stat, statbuf);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 542) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 543) 	return error;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 544) }
257ac264d6901 (Heiko Carstens     2009-01-14 14:14:13 +0100 545) 
257ac264d6901 (Heiko Carstens     2009-01-14 14:14:13 +0100 546) SYSCALL_DEFINE2(fstat64, unsigned long, fd, struct stat64 __user *, statbuf)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 547) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 548) 	struct kstat stat;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 549) 	int error = vfs_fstat(fd, &stat);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 550) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 551) 	if (!error)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 552) 		error = cp_new_stat64(&stat, statbuf);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 553) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 554) 	return error;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 555) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 556) 
c7887325230ae (David Howells      2010-08-11 11:26:22 +0100 557) SYSCALL_DEFINE4(fstatat64, int, dfd, const char __user *, filename,
6559eed8ca7db (Heiko Carstens     2009-01-14 14:14:32 +0100 558) 		struct stat64 __user *, statbuf, int, flag)
cff2b760096d1 (Ulrich Drepper     2006-02-11 17:55:47 -0800 559) {
cff2b760096d1 (Ulrich Drepper     2006-02-11 17:55:47 -0800 560) 	struct kstat stat;
0112fc2229847 (Oleg Drokin        2009-04-08 20:05:42 +0400 561) 	int error;
cff2b760096d1 (Ulrich Drepper     2006-02-11 17:55:47 -0800 562) 
0112fc2229847 (Oleg Drokin        2009-04-08 20:05:42 +0400 563) 	error = vfs_fstatat(dfd, filename, &stat, flag);
0112fc2229847 (Oleg Drokin        2009-04-08 20:05:42 +0400 564) 	if (error)
0112fc2229847 (Oleg Drokin        2009-04-08 20:05:42 +0400 565) 		return error;
0112fc2229847 (Oleg Drokin        2009-04-08 20:05:42 +0400 566) 	return cp_new_stat64(&stat, statbuf);
cff2b760096d1 (Ulrich Drepper     2006-02-11 17:55:47 -0800 567) }
0753f70f07fbb (Catalin Marinas    2012-03-19 15:13:51 +0000 568) #endif /* __ARCH_WANT_STAT64 || __ARCH_WANT_COMPAT_STAT64 */
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 569) 
6f88cc176a335 (Bijan Mottahedeh   2020-05-22 21:31:19 -0700 570) static noinline_for_stack int
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 571) cp_statx(const struct kstat *stat, struct statx __user *buffer)
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 572) {
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 573) 	struct statx tmp;
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 574) 
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 575) 	memset(&tmp, 0, sizeof(tmp));
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 576) 
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 577) 	tmp.stx_mask = stat->result_mask;
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 578) 	tmp.stx_blksize = stat->blksize;
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 579) 	tmp.stx_attributes = stat->attributes;
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 580) 	tmp.stx_nlink = stat->nlink;
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 581) 	tmp.stx_uid = from_kuid_munged(current_user_ns(), stat->uid);
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 582) 	tmp.stx_gid = from_kgid_munged(current_user_ns(), stat->gid);
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 583) 	tmp.stx_mode = stat->mode;
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 584) 	tmp.stx_ino = stat->ino;
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 585) 	tmp.stx_size = stat->size;
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 586) 	tmp.stx_blocks = stat->blocks;
3209f68b3ca46 (David Howells      2017-03-31 18:32:17 +0100 587) 	tmp.stx_attributes_mask = stat->attributes_mask;
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 588) 	tmp.stx_atime.tv_sec = stat->atime.tv_sec;
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 589) 	tmp.stx_atime.tv_nsec = stat->atime.tv_nsec;
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 590) 	tmp.stx_btime.tv_sec = stat->btime.tv_sec;
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 591) 	tmp.stx_btime.tv_nsec = stat->btime.tv_nsec;
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 592) 	tmp.stx_ctime.tv_sec = stat->ctime.tv_sec;
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 593) 	tmp.stx_ctime.tv_nsec = stat->ctime.tv_nsec;
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 594) 	tmp.stx_mtime.tv_sec = stat->mtime.tv_sec;
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 595) 	tmp.stx_mtime.tv_nsec = stat->mtime.tv_nsec;
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 596) 	tmp.stx_rdev_major = MAJOR(stat->rdev);
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 597) 	tmp.stx_rdev_minor = MINOR(stat->rdev);
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 598) 	tmp.stx_dev_major = MAJOR(stat->dev);
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 599) 	tmp.stx_dev_minor = MINOR(stat->dev);
fa2fcf4f1df15 (Miklos Szeredi     2020-05-14 16:44:24 +0200 600) 	tmp.stx_mnt_id = stat->mnt_id;
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 601) 
64bd72048a2ac (Eric Biggers       2017-03-31 18:31:48 +0100 602) 	return copy_to_user(buffer, &tmp, sizeof(tmp)) ? -EFAULT : 0;
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 603) }
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 604) 
0018784fc84f6 (Bijan Mottahedeh   2020-05-22 21:31:17 -0700 605) int do_statx(int dfd, const char __user *filename, unsigned flags,
0018784fc84f6 (Bijan Mottahedeh   2020-05-22 21:31:17 -0700 606) 	     unsigned int mask, struct statx __user *buffer)
0018784fc84f6 (Bijan Mottahedeh   2020-05-22 21:31:17 -0700 607) {
0018784fc84f6 (Bijan Mottahedeh   2020-05-22 21:31:17 -0700 608) 	struct kstat stat;
0018784fc84f6 (Bijan Mottahedeh   2020-05-22 21:31:17 -0700 609) 	int error;
0018784fc84f6 (Bijan Mottahedeh   2020-05-22 21:31:17 -0700 610) 
0018784fc84f6 (Bijan Mottahedeh   2020-05-22 21:31:17 -0700 611) 	if (mask & STATX__RESERVED)
0018784fc84f6 (Bijan Mottahedeh   2020-05-22 21:31:17 -0700 612) 		return -EINVAL;
0018784fc84f6 (Bijan Mottahedeh   2020-05-22 21:31:17 -0700 613) 	if ((flags & AT_STATX_SYNC_TYPE) == AT_STATX_SYNC_TYPE)
0018784fc84f6 (Bijan Mottahedeh   2020-05-22 21:31:17 -0700 614) 		return -EINVAL;
0018784fc84f6 (Bijan Mottahedeh   2020-05-22 21:31:17 -0700 615) 
0018784fc84f6 (Bijan Mottahedeh   2020-05-22 21:31:17 -0700 616) 	error = vfs_statx(dfd, filename, flags, &stat, mask);
0018784fc84f6 (Bijan Mottahedeh   2020-05-22 21:31:17 -0700 617) 	if (error)
0018784fc84f6 (Bijan Mottahedeh   2020-05-22 21:31:17 -0700 618) 		return error;
0018784fc84f6 (Bijan Mottahedeh   2020-05-22 21:31:17 -0700 619) 
0018784fc84f6 (Bijan Mottahedeh   2020-05-22 21:31:17 -0700 620) 	return cp_statx(&stat, buffer);
0018784fc84f6 (Bijan Mottahedeh   2020-05-22 21:31:17 -0700 621) }
0018784fc84f6 (Bijan Mottahedeh   2020-05-22 21:31:17 -0700 622) 
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 623) /**
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 624)  * sys_statx - System call to get enhanced stats
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 625)  * @dfd: Base directory to pathwalk from *or* fd to stat.
1e2f82d1e9d12 (David Howells      2017-04-26 22:15:55 +0100 626)  * @filename: File to stat or "" with AT_EMPTY_PATH
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 627)  * @flags: AT_* flags to control pathwalk.
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 628)  * @mask: Parts of statx struct actually required.
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 629)  * @buffer: Result buffer.
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 630)  *
1e2f82d1e9d12 (David Howells      2017-04-26 22:15:55 +0100 631)  * Note that fstat() can be emulated by setting dfd to the fd of interest,
1e2f82d1e9d12 (David Howells      2017-04-26 22:15:55 +0100 632)  * supplying "" as the filename and setting AT_EMPTY_PATH in the flags.
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 633)  */
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 634) SYSCALL_DEFINE5(statx,
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 635) 		int, dfd, const char __user *, filename, unsigned, flags,
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 636) 		unsigned int, mask,
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 637) 		struct statx __user *, buffer)
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 638) {
0018784fc84f6 (Bijan Mottahedeh   2020-05-22 21:31:17 -0700 639) 	return do_statx(dfd, filename, flags, mask, buffer);
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 640) }
a528d35e8bfcc (David Howells      2017-01-31 16:46:22 +0000 641) 
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 642) #ifdef CONFIG_COMPAT
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 643) static int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 644) {
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 645) 	struct compat_stat tmp;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 646) 
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 647) 	if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev))
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 648) 		return -EOVERFLOW;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 649) 
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 650) 	memset(&tmp, 0, sizeof(tmp));
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 651) 	tmp.st_dev = old_encode_dev(stat->dev);
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 652) 	tmp.st_ino = stat->ino;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 653) 	if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 654) 		return -EOVERFLOW;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 655) 	tmp.st_mode = stat->mode;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 656) 	tmp.st_nlink = stat->nlink;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 657) 	if (tmp.st_nlink != stat->nlink)
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 658) 		return -EOVERFLOW;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 659) 	SET_UID(tmp.st_uid, from_kuid_munged(current_user_ns(), stat->uid));
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 660) 	SET_GID(tmp.st_gid, from_kgid_munged(current_user_ns(), stat->gid));
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 661) 	tmp.st_rdev = old_encode_dev(stat->rdev);
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 662) 	if ((u64) stat->size > MAX_NON_LFS)
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 663) 		return -EOVERFLOW;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 664) 	tmp.st_size = stat->size;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 665) 	tmp.st_atime = stat->atime.tv_sec;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 666) 	tmp.st_atime_nsec = stat->atime.tv_nsec;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 667) 	tmp.st_mtime = stat->mtime.tv_sec;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 668) 	tmp.st_mtime_nsec = stat->mtime.tv_nsec;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 669) 	tmp.st_ctime = stat->ctime.tv_sec;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 670) 	tmp.st_ctime_nsec = stat->ctime.tv_nsec;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 671) 	tmp.st_blocks = stat->blocks;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 672) 	tmp.st_blksize = stat->blksize;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 673) 	return copy_to_user(ubuf, &tmp, sizeof(tmp)) ? -EFAULT : 0;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 674) }
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 675) 
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 676) COMPAT_SYSCALL_DEFINE2(newstat, const char __user *, filename,
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 677) 		       struct compat_stat __user *, statbuf)
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 678) {
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 679) 	struct kstat stat;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 680) 	int error;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 681) 
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 682) 	error = vfs_stat(filename, &stat);
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 683) 	if (error)
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 684) 		return error;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 685) 	return cp_compat_stat(&stat, statbuf);
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 686) }
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 687) 
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 688) COMPAT_SYSCALL_DEFINE2(newlstat, const char __user *, filename,
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 689) 		       struct compat_stat __user *, statbuf)
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 690) {
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 691) 	struct kstat stat;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 692) 	int error;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 693) 
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 694) 	error = vfs_lstat(filename, &stat);
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 695) 	if (error)
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 696) 		return error;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 697) 	return cp_compat_stat(&stat, statbuf);
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 698) }
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 699) 
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 700) #ifndef __ARCH_WANT_STAT64
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 701) COMPAT_SYSCALL_DEFINE4(newfstatat, unsigned int, dfd,
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 702) 		       const char __user *, filename,
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 703) 		       struct compat_stat __user *, statbuf, int, flag)
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 704) {
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 705) 	struct kstat stat;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 706) 	int error;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 707) 
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 708) 	error = vfs_fstatat(dfd, filename, &stat, flag);
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 709) 	if (error)
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 710) 		return error;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 711) 	return cp_compat_stat(&stat, statbuf);
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 712) }
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 713) #endif
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 714) 
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 715) COMPAT_SYSCALL_DEFINE2(newfstat, unsigned int, fd,
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 716) 		       struct compat_stat __user *, statbuf)
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 717) {
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 718) 	struct kstat stat;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 719) 	int error = vfs_fstat(fd, &stat);
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 720) 
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 721) 	if (!error)
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 722) 		error = cp_compat_stat(&stat, statbuf);
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 723) 	return error;
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 724) }
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 725) #endif
ac565de31c950 (Al Viro            2017-04-08 18:13:00 -0400 726) 
b462707e7ccad (Dmitry Monakhov    2009-12-14 15:21:12 +0300 727) /* Caller is here responsible for sufficient locking (ie. inode->i_lock) */
b462707e7ccad (Dmitry Monakhov    2009-12-14 15:21:12 +0300 728) void __inode_add_bytes(struct inode *inode, loff_t bytes)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 729) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 730) 	inode->i_blocks += bytes >> 9;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 731) 	bytes &= 511;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 732) 	inode->i_bytes += bytes;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 733) 	if (inode->i_bytes >= 512) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 734) 		inode->i_blocks++;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 735) 		inode->i_bytes -= 512;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 736) 	}
b462707e7ccad (Dmitry Monakhov    2009-12-14 15:21:12 +0300 737) }
eb315d2ae6144 (Al Viro            2017-06-08 21:15:03 -0400 738) EXPORT_SYMBOL(__inode_add_bytes);
b462707e7ccad (Dmitry Monakhov    2009-12-14 15:21:12 +0300 739) 
b462707e7ccad (Dmitry Monakhov    2009-12-14 15:21:12 +0300 740) void inode_add_bytes(struct inode *inode, loff_t bytes)
b462707e7ccad (Dmitry Monakhov    2009-12-14 15:21:12 +0300 741) {
b462707e7ccad (Dmitry Monakhov    2009-12-14 15:21:12 +0300 742) 	spin_lock(&inode->i_lock);
b462707e7ccad (Dmitry Monakhov    2009-12-14 15:21:12 +0300 743) 	__inode_add_bytes(inode, bytes);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 744) 	spin_unlock(&inode->i_lock);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 745) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 746) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 747) EXPORT_SYMBOL(inode_add_bytes);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 748) 
1c8924eb106c1 (Jan Kara           2013-08-17 09:32:32 -0400 749) void __inode_sub_bytes(struct inode *inode, loff_t bytes)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 750) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 751) 	inode->i_blocks -= bytes >> 9;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 752) 	bytes &= 511;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 753) 	if (inode->i_bytes < bytes) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 754) 		inode->i_blocks--;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 755) 		inode->i_bytes += 512;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 756) 	}
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 757) 	inode->i_bytes -= bytes;
1c8924eb106c1 (Jan Kara           2013-08-17 09:32:32 -0400 758) }
1c8924eb106c1 (Jan Kara           2013-08-17 09:32:32 -0400 759) 
1c8924eb106c1 (Jan Kara           2013-08-17 09:32:32 -0400 760) EXPORT_SYMBOL(__inode_sub_bytes);
1c8924eb106c1 (Jan Kara           2013-08-17 09:32:32 -0400 761) 
1c8924eb106c1 (Jan Kara           2013-08-17 09:32:32 -0400 762) void inode_sub_bytes(struct inode *inode, loff_t bytes)
1c8924eb106c1 (Jan Kara           2013-08-17 09:32:32 -0400 763) {
1c8924eb106c1 (Jan Kara           2013-08-17 09:32:32 -0400 764) 	spin_lock(&inode->i_lock);
1c8924eb106c1 (Jan Kara           2013-08-17 09:32:32 -0400 765) 	__inode_sub_bytes(inode, bytes);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 766) 	spin_unlock(&inode->i_lock);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 767) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 768) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 769) EXPORT_SYMBOL(inode_sub_bytes);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 770) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 771) loff_t inode_get_bytes(struct inode *inode)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 772) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 773) 	loff_t ret;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 774) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 775) 	spin_lock(&inode->i_lock);
f4a8116a4c8c8 (Jan Kara           2017-08-08 09:54:36 +0200 776) 	ret = __inode_get_bytes(inode);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 777) 	spin_unlock(&inode->i_lock);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 778) 	return ret;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 779) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 780) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 781) EXPORT_SYMBOL(inode_get_bytes);
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 782) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 783) void inode_set_bytes(struct inode *inode, loff_t bytes)
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 784) {
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 785) 	/* Caller is here responsible for sufficient locking
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 786) 	 * (ie. inode->i_lock) */
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 787) 	inode->i_blocks = bytes >> 9;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 788) 	inode->i_bytes = bytes & 511;
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 789) }
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 790) 
^1da177e4c3f4 (Linus Torvalds     2005-04-16 15:20:36 -0700 791) EXPORT_SYMBOL(inode_set_bytes);