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