VisionFive2 Linux kernel

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

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