brintos

brintos / linux-shallow public Read only

0
0
Text · 26.0 KiB · 9fbeec1 Raw
953 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 *  linux/fs/stat.c4 *5 *  Copyright (C) 1991, 1992  Linus Torvalds6 */7 8#include <linux/blkdev.h>9#include <linux/export.h>10#include <linux/mm.h>11#include <linux/errno.h>12#include <linux/file.h>13#include <linux/highuid.h>14#include <linux/fs.h>15#include <linux/namei.h>16#include <linux/security.h>17#include <linux/cred.h>18#include <linux/syscalls.h>19#include <linux/pagemap.h>20#include <linux/compat.h>21#include <linux/iversion.h>22 23#include <linux/uaccess.h>24#include <asm/unistd.h>25 26#include "internal.h"27#include "mount.h"28 29/**30 * generic_fillattr - Fill in the basic attributes from the inode struct31 * @idmap:		idmap of the mount the inode was found from32 * @request_mask:	statx request_mask33 * @inode:		Inode to use as the source34 * @stat:		Where to fill in the attributes35 *36 * Fill in the basic attributes in the kstat structure from data that's to be37 * found on the VFS inode structure.  This is the default if no getattr inode38 * operation is supplied.39 *40 * If the inode has been found through an idmapped mount the idmap of41 * the vfsmount must be passed through @idmap. This function will then42 * take care to map the inode according to @idmap before filling in the43 * uid and gid filds. On non-idmapped mounts or if permission checking is to be44 * performed on the raw inode simply pass @nop_mnt_idmap.45 */46void generic_fillattr(struct mnt_idmap *idmap, u32 request_mask,47		      struct inode *inode, struct kstat *stat)48{49	vfsuid_t vfsuid = i_uid_into_vfsuid(idmap, inode);50	vfsgid_t vfsgid = i_gid_into_vfsgid(idmap, inode);51 52	stat->dev = inode->i_sb->s_dev;53	stat->ino = inode->i_ino;54	stat->mode = inode->i_mode;55	stat->nlink = inode->i_nlink;56	stat->uid = vfsuid_into_kuid(vfsuid);57	stat->gid = vfsgid_into_kgid(vfsgid);58	stat->rdev = inode->i_rdev;59	stat->size = i_size_read(inode);60	stat->atime = inode_get_atime(inode);61	stat->mtime = inode_get_mtime(inode);62	stat->ctime = inode_get_ctime(inode);63	stat->blksize = i_blocksize(inode);64	stat->blocks = inode->i_blocks;65 66	if ((request_mask & STATX_CHANGE_COOKIE) && IS_I_VERSION(inode)) {67		stat->result_mask |= STATX_CHANGE_COOKIE;68		stat->change_cookie = inode_query_iversion(inode);69	}70 71}72EXPORT_SYMBOL(generic_fillattr);73 74/**75 * generic_fill_statx_attr - Fill in the statx attributes from the inode flags76 * @inode:	Inode to use as the source77 * @stat:	Where to fill in the attribute flags78 *79 * Fill in the STATX_ATTR_* flags in the kstat structure for properties of the80 * inode that are published on i_flags and enforced by the VFS.81 */82void generic_fill_statx_attr(struct inode *inode, struct kstat *stat)83{84	if (inode->i_flags & S_IMMUTABLE)85		stat->attributes |= STATX_ATTR_IMMUTABLE;86	if (inode->i_flags & S_APPEND)87		stat->attributes |= STATX_ATTR_APPEND;88	stat->attributes_mask |= KSTAT_ATTR_VFS_FLAGS;89}90EXPORT_SYMBOL(generic_fill_statx_attr);91 92/**93 * generic_fill_statx_atomic_writes - Fill in atomic writes statx attributes94 * @stat:	Where to fill in the attribute flags95 * @unit_min:	Minimum supported atomic write length in bytes96 * @unit_max:	Maximum supported atomic write length in bytes97 *98 * Fill in the STATX{_ATTR}_WRITE_ATOMIC flags in the kstat structure from99 * atomic write unit_min and unit_max values.100 */101void generic_fill_statx_atomic_writes(struct kstat *stat,102				      unsigned int unit_min,103				      unsigned int unit_max)104{105	/* Confirm that the request type is known */106	stat->result_mask |= STATX_WRITE_ATOMIC;107 108	/* Confirm that the file attribute type is known */109	stat->attributes_mask |= STATX_ATTR_WRITE_ATOMIC;110 111	if (unit_min) {112		stat->atomic_write_unit_min = unit_min;113		stat->atomic_write_unit_max = unit_max;114		/* Initially only allow 1x segment */115		stat->atomic_write_segments_max = 1;116 117		/* Confirm atomic writes are actually supported */118		stat->attributes |= STATX_ATTR_WRITE_ATOMIC;119	}120}121EXPORT_SYMBOL_GPL(generic_fill_statx_atomic_writes);122 123/**124 * vfs_getattr_nosec - getattr without security checks125 * @path: file to get attributes from126 * @stat: structure to return attributes in127 * @request_mask: STATX_xxx flags indicating what the caller wants128 * @query_flags: Query mode (AT_STATX_SYNC_TYPE)129 *130 * Get attributes without calling security_inode_getattr.131 *132 * Currently the only caller other than vfs_getattr is internal to the133 * filehandle lookup code, which uses only the inode number and returns no134 * attributes to any user.  Any other code probably wants vfs_getattr.135 */136int vfs_getattr_nosec(const struct path *path, struct kstat *stat,137		      u32 request_mask, unsigned int query_flags)138{139	struct mnt_idmap *idmap;140	struct inode *inode = d_backing_inode(path->dentry);141 142	memset(stat, 0, sizeof(*stat));143	stat->result_mask |= STATX_BASIC_STATS;144	query_flags &= AT_STATX_SYNC_TYPE;145 146	/* allow the fs to override these if it really wants to */147	/* SB_NOATIME means filesystem supplies dummy atime value */148	if (inode->i_sb->s_flags & SB_NOATIME)149		stat->result_mask &= ~STATX_ATIME;150 151	/*152	 * Note: If you add another clause to set an attribute flag, please153	 * update attributes_mask below.154	 */155	if (IS_AUTOMOUNT(inode))156		stat->attributes |= STATX_ATTR_AUTOMOUNT;157 158	if (IS_DAX(inode))159		stat->attributes |= STATX_ATTR_DAX;160 161	stat->attributes_mask |= (STATX_ATTR_AUTOMOUNT |162				  STATX_ATTR_DAX);163 164	idmap = mnt_idmap(path->mnt);165	if (inode->i_op->getattr)166		return inode->i_op->getattr(idmap, path, stat,167					    request_mask,168					    query_flags | AT_GETATTR_NOSEC);169 170	generic_fillattr(idmap, request_mask, inode, stat);171	return 0;172}173EXPORT_SYMBOL(vfs_getattr_nosec);174 175/*176 * vfs_getattr - Get the enhanced basic attributes of a file177 * @path: The file of interest178 * @stat: Where to return the statistics179 * @request_mask: STATX_xxx flags indicating what the caller wants180 * @query_flags: Query mode (AT_STATX_SYNC_TYPE)181 *182 * Ask the filesystem for a file's attributes.  The caller must indicate in183 * request_mask and query_flags to indicate what they want.184 *185 * If the file is remote, the filesystem can be forced to update the attributes186 * from the backing store by passing AT_STATX_FORCE_SYNC in query_flags or can187 * suppress the update by passing AT_STATX_DONT_SYNC.188 *189 * Bits must have been set in request_mask to indicate which attributes the190 * caller wants retrieving.  Any such attribute not requested may be returned191 * anyway, but the value may be approximate, and, if remote, may not have been192 * synchronised with the server.193 *194 * 0 will be returned on success, and a -ve error code if unsuccessful.195 */196int vfs_getattr(const struct path *path, struct kstat *stat,197		u32 request_mask, unsigned int query_flags)198{199	int retval;200 201	if (WARN_ON_ONCE(query_flags & AT_GETATTR_NOSEC))202		return -EPERM;203 204	retval = security_inode_getattr(path);205	if (retval)206		return retval;207	return vfs_getattr_nosec(path, stat, request_mask, query_flags);208}209EXPORT_SYMBOL(vfs_getattr);210 211/**212 * vfs_fstat - Get the basic attributes by file descriptor213 * @fd: The file descriptor referring to the file of interest214 * @stat: The result structure to fill in.215 *216 * This function is a wrapper around vfs_getattr().  The main difference is217 * that it uses a file descriptor to determine the file location.218 *219 * 0 will be returned on success, and a -ve error code if unsuccessful.220 */221int vfs_fstat(int fd, struct kstat *stat)222{223	struct fd f;224	int error;225 226	f = fdget_raw(fd);227	if (!fd_file(f))228		return -EBADF;229	error = vfs_getattr(&fd_file(f)->f_path, stat, STATX_BASIC_STATS, 0);230	fdput(f);231	return error;232}233 234int getname_statx_lookup_flags(int flags)235{236	int lookup_flags = 0;237 238	if (!(flags & AT_SYMLINK_NOFOLLOW))239		lookup_flags |= LOOKUP_FOLLOW;240	if (!(flags & AT_NO_AUTOMOUNT))241		lookup_flags |= LOOKUP_AUTOMOUNT;242	if (flags & AT_EMPTY_PATH)243		lookup_flags |= LOOKUP_EMPTY;244 245	return lookup_flags;246}247 248static HWJS_SUSPENDS int vfs_statx_path(struct path *path, int flags, struct kstat *stat,249			  u32 request_mask)250{251	int error = vfs_getattr(path, stat, request_mask, flags);252 253	if (request_mask & STATX_MNT_ID_UNIQUE) {254		stat->mnt_id = real_mount(path->mnt)->mnt_id_unique;255		stat->result_mask |= STATX_MNT_ID_UNIQUE;256	} else {257		stat->mnt_id = real_mount(path->mnt)->mnt_id;258		stat->result_mask |= STATX_MNT_ID;259	}260 261	if (path_mounted(path))262		stat->attributes |= STATX_ATTR_MOUNT_ROOT;263	stat->attributes_mask |= STATX_ATTR_MOUNT_ROOT;264 265	/*266	 * If this is a block device inode, override the filesystem267	 * attributes with the block device specific parameters that need to be268	 * obtained from the bdev backing inode.269	 */270	if (S_ISBLK(stat->mode))271		bdev_statx(path, stat, request_mask);272 273	return error;274}275 276static HWJS_SUSPENDS int vfs_statx_fd(int fd, int flags, struct kstat *stat,277			  u32 request_mask)278{279	CLASS(fd_raw, f)(fd);280	if (!fd_file(f))281		return -EBADF;282	return vfs_statx_path(&fd_file(f)->f_path, flags, stat, request_mask);283}284 285/**286 * vfs_statx - Get basic and extra attributes by filename287 * @dfd: A file descriptor representing the base dir for a relative filename288 * @filename: The name of the file of interest289 * @flags: Flags to control the query290 * @stat: The result structure to fill in.291 * @request_mask: STATX_xxx flags indicating what the caller wants292 *293 * This function is a wrapper around vfs_getattr().  The main difference is294 * that it uses a filename and base directory to determine the file location.295 * Additionally, the use of AT_SYMLINK_NOFOLLOW in flags will prevent a symlink296 * at the given name from being referenced.297 *298 * 0 will be returned on success, and a -ve error code if unsuccessful.299 */300static HWJS_SUSPENDS int vfs_statx(int dfd, struct filename *filename, int flags,301	      struct kstat *stat, u32 request_mask)302{303	struct path path;304	unsigned int lookup_flags = getname_statx_lookup_flags(flags);305	int error;306 307	if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | AT_EMPTY_PATH |308		      AT_STATX_SYNC_TYPE))309		return -EINVAL;310 311retry:312	error = filename_lookup(dfd, filename, lookup_flags, &path, NULL);313	if (error)314		return error;315	error = vfs_statx_path(&path, flags, stat, request_mask);316	path_put(&path);317	if (retry_estale(error, lookup_flags)) {318		lookup_flags |= LOOKUP_REVAL;319		goto retry;320	}321	return error;322}323 324int vfs_fstatat(int dfd, const char __user *filename,325			      struct kstat *stat, int flags)326{327	int ret;328	int statx_flags = flags | AT_NO_AUTOMOUNT;329	struct filename *name;330 331	/*332	 * Work around glibc turning fstat() into fstatat(AT_EMPTY_PATH)333	 *334	 * If AT_EMPTY_PATH is set, we expect the common case to be that335	 * empty path, and avoid doing all the extra pathname work.336	 */337	if (flags == AT_EMPTY_PATH && vfs_empty_path(dfd, filename))338		return vfs_fstat(dfd, stat);339 340	name = getname_flags(filename, getname_statx_lookup_flags(statx_flags));341	ret = vfs_statx(dfd, name, statx_flags, stat, STATX_BASIC_STATS);342	putname(name);343 344	return ret;345}346 347#ifdef __ARCH_WANT_OLD_STAT348 349/*350 * For backward compatibility?  Maybe this should be moved351 * into arch/i386 instead?352 */353static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat __user * statbuf)354{355	static int warncount = 5;356	struct __old_kernel_stat tmp;357 358	if (warncount > 0) {359		warncount--;360		printk(KERN_WARNING "VFS: Warning: %s using old stat() call. Recompile your binary.\n",361			current->comm);362	} else if (warncount < 0) {363		/* it's laughable, but... */364		warncount = 0;365	}366 367	memset(&tmp, 0, sizeof(struct __old_kernel_stat));368	tmp.st_dev = old_encode_dev(stat->dev);369	tmp.st_ino = stat->ino;370	if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)371		return -EOVERFLOW;372	tmp.st_mode = stat->mode;373	tmp.st_nlink = stat->nlink;374	if (tmp.st_nlink != stat->nlink)375		return -EOVERFLOW;376	SET_UID(tmp.st_uid, from_kuid_munged(current_user_ns(), stat->uid));377	SET_GID(tmp.st_gid, from_kgid_munged(current_user_ns(), stat->gid));378	tmp.st_rdev = old_encode_dev(stat->rdev);379#if BITS_PER_LONG == 32380	if (stat->size > MAX_NON_LFS)381		return -EOVERFLOW;382#endif383	tmp.st_size = stat->size;384	tmp.st_atime = stat->atime.tv_sec;385	tmp.st_mtime = stat->mtime.tv_sec;386	tmp.st_ctime = stat->ctime.tv_sec;387	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;388}389 390SYSCALL_DEFINE2(stat, const char __user *, filename,391		struct __old_kernel_stat __user *, statbuf)392{393	struct kstat stat;394	int error;395 396	error = vfs_stat(filename, &stat);397	if (error)398		return error;399 400	return cp_old_stat(&stat, statbuf);401}402 403SYSCALL_DEFINE2(lstat, const char __user *, filename,404		struct __old_kernel_stat __user *, statbuf)405{406	struct kstat stat;407	int error;408 409	error = vfs_lstat(filename, &stat);410	if (error)411		return error;412 413	return cp_old_stat(&stat, statbuf);414}415 416SYSCALL_DEFINE2(fstat, unsigned int, fd, struct __old_kernel_stat __user *, statbuf)417{418	struct kstat stat;419	int error = vfs_fstat(fd, &stat);420 421	if (!error)422		error = cp_old_stat(&stat, statbuf);423 424	return error;425}426 427#endif /* __ARCH_WANT_OLD_STAT */428 429#ifdef __ARCH_WANT_NEW_STAT430 431#ifndef INIT_STRUCT_STAT_PADDING432#  define INIT_STRUCT_STAT_PADDING(st) memset(&st, 0, sizeof(st))433#endif434 435static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf)436{437	struct stat tmp;438 439	if (sizeof(tmp.st_dev) < 4 && !old_valid_dev(stat->dev))440		return -EOVERFLOW;441	if (sizeof(tmp.st_rdev) < 4 && !old_valid_dev(stat->rdev))442		return -EOVERFLOW;443#if BITS_PER_LONG == 32444	if (stat->size > MAX_NON_LFS)445		return -EOVERFLOW;446#endif447 448	INIT_STRUCT_STAT_PADDING(tmp);449	tmp.st_dev = new_encode_dev(stat->dev);450	tmp.st_ino = stat->ino;451	if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)452		return -EOVERFLOW;453	tmp.st_mode = stat->mode;454	tmp.st_nlink = stat->nlink;455	if (tmp.st_nlink != stat->nlink)456		return -EOVERFLOW;457	SET_UID(tmp.st_uid, from_kuid_munged(current_user_ns(), stat->uid));458	SET_GID(tmp.st_gid, from_kgid_munged(current_user_ns(), stat->gid));459	tmp.st_rdev = new_encode_dev(stat->rdev);460	tmp.st_size = stat->size;461	tmp.st_atime = stat->atime.tv_sec;462	tmp.st_mtime = stat->mtime.tv_sec;463	tmp.st_ctime = stat->ctime.tv_sec;464#ifdef STAT_HAVE_NSEC465	tmp.st_atime_nsec = stat->atime.tv_nsec;466	tmp.st_mtime_nsec = stat->mtime.tv_nsec;467	tmp.st_ctime_nsec = stat->ctime.tv_nsec;468#endif469	tmp.st_blocks = stat->blocks;470	tmp.st_blksize = stat->blksize;471	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;472}473 474SYSCALL_DEFINE2(newstat, const char __user *, filename,475		struct stat __user *, statbuf)476{477	struct kstat stat;478	int error = vfs_stat(filename, &stat);479 480	if (error)481		return error;482	return cp_new_stat(&stat, statbuf);483}484 485SYSCALL_DEFINE2(newlstat, const char __user *, filename,486		struct stat __user *, statbuf)487{488	struct kstat stat;489	int error;490 491	error = vfs_lstat(filename, &stat);492	if (error)493		return error;494 495	return cp_new_stat(&stat, statbuf);496}497 498#if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT)499SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename,500		struct stat __user *, statbuf, int, flag)501{502	struct kstat stat;503	int error;504 505	error = vfs_fstatat(dfd, filename, &stat, flag);506	if (error)507		return error;508	return cp_new_stat(&stat, statbuf);509}510#endif511 512SYSCALL_DEFINE2(newfstat, unsigned int, fd, struct stat __user *, statbuf)513{514	struct kstat stat;515	int error = vfs_fstat(fd, &stat);516 517	if (!error)518		error = cp_new_stat(&stat, statbuf);519 520	return error;521}522#endif523 524static int do_readlinkat(int dfd, const char __user *pathname,525			 char __user *buf, int bufsiz)526{527	struct path path;528	struct filename *name;529	int error;530	unsigned int lookup_flags = LOOKUP_EMPTY;531 532	if (bufsiz <= 0)533		return -EINVAL;534 535retry:536	name = getname_flags(pathname, lookup_flags);537	error = filename_lookup(dfd, name, lookup_flags, &path, NULL);538	if (unlikely(error)) {539		putname(name);540		return error;541	}542 543	/*544	 * AFS mountpoints allow readlink(2) but are not symlinks545	 */546	if (d_is_symlink(path.dentry) ||547	    d_backing_inode(path.dentry)->i_op->readlink) {548		error = security_inode_readlink(path.dentry);549		if (!error) {550			touch_atime(&path);551			error = vfs_readlink(path.dentry, buf, bufsiz);552		}553	} else {554		error = (name->name[0] == '\0') ? -ENOENT : -EINVAL;555	}556	path_put(&path);557	putname(name);558	if (retry_estale(error, lookup_flags)) {559		lookup_flags |= LOOKUP_REVAL;560		goto retry;561	}562	return error;563}564 565SYSCALL_DEFINE4(readlinkat, int, dfd, const char __user *, pathname,566		char __user *, buf, int, bufsiz)567{568	return do_readlinkat(dfd, pathname, buf, bufsiz);569}570 571SYSCALL_DEFINE3(readlink, const char __user *, path, char __user *, buf,572		int, bufsiz)573{574	return do_readlinkat(AT_FDCWD, path, buf, bufsiz);575}576 577 578/* ---------- LFS-64 ----------- */579#if defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_COMPAT_STAT64)580 581#ifndef INIT_STRUCT_STAT64_PADDING582#  define INIT_STRUCT_STAT64_PADDING(st) memset(&st, 0, sizeof(st))583#endif584 585static long cp_new_stat64(struct kstat *stat, struct stat64 __user *statbuf)586{587	struct stat64 tmp;588 589	INIT_STRUCT_STAT64_PADDING(tmp);590#ifdef CONFIG_MIPS591	/* mips has weird padding, so we don't get 64 bits there */592	tmp.st_dev = new_encode_dev(stat->dev);593	tmp.st_rdev = new_encode_dev(stat->rdev);594#else595	tmp.st_dev = huge_encode_dev(stat->dev);596	tmp.st_rdev = huge_encode_dev(stat->rdev);597#endif598	tmp.st_ino = stat->ino;599	if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)600		return -EOVERFLOW;601#ifdef STAT64_HAS_BROKEN_ST_INO602	tmp.__st_ino = stat->ino;603#endif604	tmp.st_mode = stat->mode;605	tmp.st_nlink = stat->nlink;606	tmp.st_uid = from_kuid_munged(current_user_ns(), stat->uid);607	tmp.st_gid = from_kgid_munged(current_user_ns(), stat->gid);608	tmp.st_atime = stat->atime.tv_sec;609	tmp.st_atime_nsec = stat->atime.tv_nsec;610	tmp.st_mtime = stat->mtime.tv_sec;611	tmp.st_mtime_nsec = stat->mtime.tv_nsec;612	tmp.st_ctime = stat->ctime.tv_sec;613	tmp.st_ctime_nsec = stat->ctime.tv_nsec;614	tmp.st_size = stat->size;615	tmp.st_blocks = stat->blocks;616	tmp.st_blksize = stat->blksize;617	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;618}619 620SYSCALL_DEFINE2(stat64, const char __user *, filename,621		struct stat64 __user *, statbuf)622{623	struct kstat stat;624	int error = vfs_stat(filename, &stat);625 626	if (!error)627		error = cp_new_stat64(&stat, statbuf);628 629	return error;630}631 632SYSCALL_DEFINE2(lstat64, const char __user *, filename,633		struct stat64 __user *, statbuf)634{635	struct kstat stat;636	int error = vfs_lstat(filename, &stat);637 638	if (!error)639		error = cp_new_stat64(&stat, statbuf);640 641	return error;642}643 644SYSCALL_DEFINE2(fstat64, unsigned long, fd, struct stat64 __user *, statbuf)645{646	struct kstat stat;647	int error = vfs_fstat(fd, &stat);648 649	if (!error)650		error = cp_new_stat64(&stat, statbuf);651 652	return error;653}654 655SYSCALL_DEFINE4(fstatat64, int, dfd, const char __user *, filename,656		struct stat64 __user *, statbuf, int, flag)657{658	struct kstat stat;659	int error;660 661	error = vfs_fstatat(dfd, filename, &stat, flag);662	if (error)663		return error;664	return cp_new_stat64(&stat, statbuf);665}666#endif /* __ARCH_WANT_STAT64 || __ARCH_WANT_COMPAT_STAT64 */667 668static noinline_for_stack int669cp_statx(const struct kstat *stat, struct statx __user *buffer)670{671	struct statx tmp;672 673	memset(&tmp, 0, sizeof(tmp));674 675	/* STATX_CHANGE_COOKIE is kernel-only for now */676	tmp.stx_mask = stat->result_mask & ~STATX_CHANGE_COOKIE;677	tmp.stx_blksize = stat->blksize;678	/* STATX_ATTR_CHANGE_MONOTONIC is kernel-only for now */679	tmp.stx_attributes = stat->attributes & ~STATX_ATTR_CHANGE_MONOTONIC;680	tmp.stx_nlink = stat->nlink;681	tmp.stx_uid = from_kuid_munged(current_user_ns(), stat->uid);682	tmp.stx_gid = from_kgid_munged(current_user_ns(), stat->gid);683	tmp.stx_mode = stat->mode;684	tmp.stx_ino = stat->ino;685	tmp.stx_size = stat->size;686	tmp.stx_blocks = stat->blocks;687	tmp.stx_attributes_mask = stat->attributes_mask;688	tmp.stx_atime.tv_sec = stat->atime.tv_sec;689	tmp.stx_atime.tv_nsec = stat->atime.tv_nsec;690	tmp.stx_btime.tv_sec = stat->btime.tv_sec;691	tmp.stx_btime.tv_nsec = stat->btime.tv_nsec;692	tmp.stx_ctime.tv_sec = stat->ctime.tv_sec;693	tmp.stx_ctime.tv_nsec = stat->ctime.tv_nsec;694	tmp.stx_mtime.tv_sec = stat->mtime.tv_sec;695	tmp.stx_mtime.tv_nsec = stat->mtime.tv_nsec;696	tmp.stx_rdev_major = MAJOR(stat->rdev);697	tmp.stx_rdev_minor = MINOR(stat->rdev);698	tmp.stx_dev_major = MAJOR(stat->dev);699	tmp.stx_dev_minor = MINOR(stat->dev);700	tmp.stx_mnt_id = stat->mnt_id;701	tmp.stx_dio_mem_align = stat->dio_mem_align;702	tmp.stx_dio_offset_align = stat->dio_offset_align;703	tmp.stx_subvol = stat->subvol;704	tmp.stx_atomic_write_unit_min = stat->atomic_write_unit_min;705	tmp.stx_atomic_write_unit_max = stat->atomic_write_unit_max;706	tmp.stx_atomic_write_segments_max = stat->atomic_write_segments_max;707 708	return copy_to_user(buffer, &tmp, sizeof(tmp)) ? -EFAULT : 0;709}710 711int do_statx(int dfd, struct filename *filename, unsigned int flags,712	     unsigned int mask, struct statx __user *buffer)713{714	struct kstat stat;715	int error;716 717	if (mask & STATX__RESERVED)718		return -EINVAL;719	if ((flags & AT_STATX_SYNC_TYPE) == AT_STATX_SYNC_TYPE)720		return -EINVAL;721 722	/*723	 * STATX_CHANGE_COOKIE is kernel-only for now. Ignore requests724	 * from userland.725	 */726	mask &= ~STATX_CHANGE_COOKIE;727 728	error = vfs_statx(dfd, filename, flags, &stat, mask);729	if (error)730		return error;731 732	return cp_statx(&stat, buffer);733}734 735int do_statx_fd(int fd, unsigned int flags, unsigned int mask,736	     struct statx __user *buffer)737{738	struct kstat stat;739	int error;740 741	if (mask & STATX__RESERVED)742		return -EINVAL;743	if ((flags & AT_STATX_SYNC_TYPE) == AT_STATX_SYNC_TYPE)744		return -EINVAL;745 746	/*747	 * STATX_CHANGE_COOKIE is kernel-only for now. Ignore requests748	 * from userland.749	 */750	mask &= ~STATX_CHANGE_COOKIE;751 752	error = vfs_statx_fd(fd, flags, &stat, mask);753	if (error)754		return error;755 756	return cp_statx(&stat, buffer);757}758 759/**760 * sys_statx - System call to get enhanced stats761 * @dfd: Base directory to pathwalk from *or* fd to stat.762 * @filename: File to stat or either NULL or "" with AT_EMPTY_PATH763 * @flags: AT_* flags to control pathwalk.764 * @mask: Parts of statx struct actually required.765 * @buffer: Result buffer.766 *767 * Note that fstat() can be emulated by setting dfd to the fd of interest,768 * supplying "" (or preferably NULL) as the filename and setting AT_EMPTY_PATH769 * in the flags.770 */771SYSCALL_DEFINE5(statx,772		int, dfd, const char __user *, filename, unsigned, flags,773		unsigned int, mask,774		struct statx __user *, buffer)775{776	int ret;777	unsigned lflags;778	struct filename *name;779 780	/*781	 * Short-circuit handling of NULL and "" paths.782	 *783	 * For a NULL path we require and accept only the AT_EMPTY_PATH flag784	 * (possibly |'d with AT_STATX flags).785	 *786	 * However, glibc on 32-bit architectures implements fstatat as statx787	 * with the "" pathname and AT_NO_AUTOMOUNT | AT_EMPTY_PATH flags.788	 * Supporting this results in the uglification below.789	 */790	lflags = flags & ~(AT_NO_AUTOMOUNT | AT_STATX_SYNC_TYPE);791	if (lflags == AT_EMPTY_PATH && vfs_empty_path(dfd, filename))792		return do_statx_fd(dfd, flags & ~AT_NO_AUTOMOUNT, mask, buffer);793 794	name = getname_flags(filename, getname_statx_lookup_flags(flags));795	ret = do_statx(dfd, name, flags, mask, buffer);796	putname(name);797 798	return ret;799}800 801#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_STAT)802static int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)803{804	struct compat_stat tmp;805 806	if (sizeof(tmp.st_dev) < 4 && !old_valid_dev(stat->dev))807		return -EOVERFLOW;808	if (sizeof(tmp.st_rdev) < 4 && !old_valid_dev(stat->rdev))809		return -EOVERFLOW;810 811	memset(&tmp, 0, sizeof(tmp));812	tmp.st_dev = new_encode_dev(stat->dev);813	tmp.st_ino = stat->ino;814	if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)815		return -EOVERFLOW;816	tmp.st_mode = stat->mode;817	tmp.st_nlink = stat->nlink;818	if (tmp.st_nlink != stat->nlink)819		return -EOVERFLOW;820	SET_UID(tmp.st_uid, from_kuid_munged(current_user_ns(), stat->uid));821	SET_GID(tmp.st_gid, from_kgid_munged(current_user_ns(), stat->gid));822	tmp.st_rdev = new_encode_dev(stat->rdev);823	if ((u64) stat->size > MAX_NON_LFS)824		return -EOVERFLOW;825	tmp.st_size = stat->size;826	tmp.st_atime = stat->atime.tv_sec;827	tmp.st_atime_nsec = stat->atime.tv_nsec;828	tmp.st_mtime = stat->mtime.tv_sec;829	tmp.st_mtime_nsec = stat->mtime.tv_nsec;830	tmp.st_ctime = stat->ctime.tv_sec;831	tmp.st_ctime_nsec = stat->ctime.tv_nsec;832	tmp.st_blocks = stat->blocks;833	tmp.st_blksize = stat->blksize;834	return copy_to_user(ubuf, &tmp, sizeof(tmp)) ? -EFAULT : 0;835}836 837COMPAT_SYSCALL_DEFINE2(newstat, const char __user *, filename,838		       struct compat_stat __user *, statbuf)839{840	struct kstat stat;841	int error;842 843	error = vfs_stat(filename, &stat);844	if (error)845		return error;846	return cp_compat_stat(&stat, statbuf);847}848 849COMPAT_SYSCALL_DEFINE2(newlstat, const char __user *, filename,850		       struct compat_stat __user *, statbuf)851{852	struct kstat stat;853	int error;854 855	error = vfs_lstat(filename, &stat);856	if (error)857		return error;858	return cp_compat_stat(&stat, statbuf);859}860 861#ifndef __ARCH_WANT_STAT64862COMPAT_SYSCALL_DEFINE4(newfstatat, unsigned int, dfd,863		       const char __user *, filename,864		       struct compat_stat __user *, statbuf, int, flag)865{866	struct kstat stat;867	int error;868 869	error = vfs_fstatat(dfd, filename, &stat, flag);870	if (error)871		return error;872	return cp_compat_stat(&stat, statbuf);873}874#endif875 876COMPAT_SYSCALL_DEFINE2(newfstat, unsigned int, fd,877		       struct compat_stat __user *, statbuf)878{879	struct kstat stat;880	int error = vfs_fstat(fd, &stat);881 882	if (!error)883		error = cp_compat_stat(&stat, statbuf);884	return error;885}886#endif887 888/* Caller is here responsible for sufficient locking (ie. inode->i_lock) */889void __inode_add_bytes(struct inode *inode, loff_t bytes)890{891	inode->i_blocks += bytes >> 9;892	bytes &= 511;893	inode->i_bytes += bytes;894	if (inode->i_bytes >= 512) {895		inode->i_blocks++;896		inode->i_bytes -= 512;897	}898}899EXPORT_SYMBOL(__inode_add_bytes);900 901void inode_add_bytes(struct inode *inode, loff_t bytes)902{903	spin_lock(&inode->i_lock);904	__inode_add_bytes(inode, bytes);905	spin_unlock(&inode->i_lock);906}907 908EXPORT_SYMBOL(inode_add_bytes);909 910void __inode_sub_bytes(struct inode *inode, loff_t bytes)911{912	inode->i_blocks -= bytes >> 9;913	bytes &= 511;914	if (inode->i_bytes < bytes) {915		inode->i_blocks--;916		inode->i_bytes += 512;917	}918	inode->i_bytes -= bytes;919}920 921EXPORT_SYMBOL(__inode_sub_bytes);922 923void inode_sub_bytes(struct inode *inode, loff_t bytes)924{925	spin_lock(&inode->i_lock);926	__inode_sub_bytes(inode, bytes);927	spin_unlock(&inode->i_lock);928}929 930EXPORT_SYMBOL(inode_sub_bytes);931 932loff_t inode_get_bytes(struct inode *inode)933{934	loff_t ret;935 936	spin_lock(&inode->i_lock);937	ret = __inode_get_bytes(inode);938	spin_unlock(&inode->i_lock);939	return ret;940}941 942EXPORT_SYMBOL(inode_get_bytes);943 944void inode_set_bytes(struct inode *inode, loff_t bytes)945{946	/* Caller is here responsible for sufficient locking947	 * (ie. inode->i_lock) */948	inode->i_blocks = bytes >> 9;949	inode->i_bytes = bytes & 511;950}951 952EXPORT_SYMBOL(inode_set_bytes);953