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);