#include <linux/blkdev.h>
#include <linux/export.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/file.h>
#include <linux/highuid.h>
#include <linux/fs.h>
#include <linux/namei.h>
#include <linux/security.h>
#include <linux/cred.h>
#include <linux/syscalls.h>
#include <linux/pagemap.h>
#include <linux/compat.h>
#include <linux/iversion.h>
#include <linux/uaccess.h>
#include <asm/unistd.h>
#include "internal.h"
#include "mount.h"
void generic_fillattr(struct mnt_idmap *idmap, u32 request_mask,
struct inode *inode, struct kstat *stat)
{ … }
EXPORT_SYMBOL(…);
void generic_fill_statx_attr(struct inode *inode, struct kstat *stat)
{ … }
EXPORT_SYMBOL(…);
void generic_fill_statx_atomic_writes(struct kstat *stat,
unsigned int unit_min,
unsigned int unit_max)
{ … }
EXPORT_SYMBOL_GPL(…);
int vfs_getattr_nosec(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int query_flags)
{ … }
EXPORT_SYMBOL(…);
int vfs_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int query_flags)
{ … }
EXPORT_SYMBOL(…);
int vfs_fstat(int fd, struct kstat *stat)
{ … }
int getname_statx_lookup_flags(int flags)
{ … }
static int vfs_statx_path(struct path *path, int flags, struct kstat *stat,
u32 request_mask)
{ … }
static int vfs_statx_fd(int fd, int flags, struct kstat *stat,
u32 request_mask)
{ … }
static int vfs_statx(int dfd, struct filename *filename, int flags,
struct kstat *stat, u32 request_mask)
{ … }
int vfs_fstatat(int dfd, const char __user *filename,
struct kstat *stat, int flags)
{ … }
#ifdef __ARCH_WANT_OLD_STAT
static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat __user * statbuf)
{ … }
SYSCALL_DEFINE2(stat, const char __user *, filename,
struct __old_kernel_stat __user *, statbuf)
{ … }
SYSCALL_DEFINE2(lstat, const char __user *, filename,
struct __old_kernel_stat __user *, statbuf)
{ … }
SYSCALL_DEFINE2(fstat, unsigned int, fd, struct __old_kernel_stat __user *, statbuf)
{ … }
#endif
#ifdef __ARCH_WANT_NEW_STAT
#ifndef INIT_STRUCT_STAT_PADDING
#define INIT_STRUCT_STAT_PADDING …
#endif
static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf)
{ … }
SYSCALL_DEFINE2(newstat, const char __user *, filename,
struct stat __user *, statbuf)
{ … }
SYSCALL_DEFINE2(newlstat, const char __user *, filename,
struct stat __user *, statbuf)
{ … }
#if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT)
SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename,
struct stat __user *, statbuf, int, flag)
{ … }
#endif
SYSCALL_DEFINE2(newfstat, unsigned int, fd, struct stat __user *, statbuf)
{ … }
#endif
static int do_readlinkat(int dfd, const char __user *pathname,
char __user *buf, int bufsiz)
{ … }
SYSCALL_DEFINE4(readlinkat, int, dfd, const char __user *, pathname,
char __user *, buf, int, bufsiz)
{ … }
SYSCALL_DEFINE3(readlink, const char __user *, path, char __user *, buf,
int, bufsiz)
{ … }
#if defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_COMPAT_STAT64)
#ifndef INIT_STRUCT_STAT64_PADDING
#define INIT_STRUCT_STAT64_PADDING …
#endif
static long cp_new_stat64(struct kstat *stat, struct stat64 __user *statbuf)
{
struct stat64 tmp;
INIT_STRUCT_STAT64_PADDING(tmp);
#ifdef CONFIG_MIPS
tmp.st_dev = new_encode_dev(stat->dev);
tmp.st_rdev = new_encode_dev(stat->rdev);
#else
tmp.st_dev = huge_encode_dev(stat->dev);
tmp.st_rdev = huge_encode_dev(stat->rdev);
#endif
tmp.st_ino = stat->ino;
if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
return -EOVERFLOW;
#ifdef STAT64_HAS_BROKEN_ST_INO
tmp.__st_ino = stat->ino;
#endif
tmp.st_mode = stat->mode;
tmp.st_nlink = stat->nlink;
tmp.st_uid = from_kuid_munged(current_user_ns(), stat->uid);
tmp.st_gid = from_kgid_munged(current_user_ns(), stat->gid);
tmp.st_atime = stat->atime.tv_sec;
tmp.st_atime_nsec = stat->atime.tv_nsec;
tmp.st_mtime = stat->mtime.tv_sec;
tmp.st_mtime_nsec = stat->mtime.tv_nsec;
tmp.st_ctime = stat->ctime.tv_sec;
tmp.st_ctime_nsec = stat->ctime.tv_nsec;
tmp.st_size = stat->size;
tmp.st_blocks = stat->blocks;
tmp.st_blksize = stat->blksize;
return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
}
SYSCALL_DEFINE2(stat64, const char __user *, filename,
struct stat64 __user *, statbuf)
{
struct kstat stat;
int error = vfs_stat(filename, &stat);
if (!error)
error = cp_new_stat64(&stat, statbuf);
return error;
}
SYSCALL_DEFINE2(lstat64, const char __user *, filename,
struct stat64 __user *, statbuf)
{
struct kstat stat;
int error = vfs_lstat(filename, &stat);
if (!error)
error = cp_new_stat64(&stat, statbuf);
return error;
}
SYSCALL_DEFINE2(fstat64, unsigned long, fd, struct stat64 __user *, statbuf)
{
struct kstat stat;
int error = vfs_fstat(fd, &stat);
if (!error)
error = cp_new_stat64(&stat, statbuf);
return error;
}
SYSCALL_DEFINE4(fstatat64, int, dfd, const char __user *, filename,
struct stat64 __user *, statbuf, int, flag)
{
struct kstat stat;
int error;
error = vfs_fstatat(dfd, filename, &stat, flag);
if (error)
return error;
return cp_new_stat64(&stat, statbuf);
}
#endif
static noinline_for_stack int
cp_statx(const struct kstat *stat, struct statx __user *buffer)
{ … }
int do_statx(int dfd, struct filename *filename, unsigned int flags,
unsigned int mask, struct statx __user *buffer)
{ … }
int do_statx_fd(int fd, unsigned int flags, unsigned int mask,
struct statx __user *buffer)
{ … }
SYSCALL_DEFINE5(statx,
int, dfd, const char __user *, filename, unsigned, flags,
unsigned int, mask,
struct statx __user *, buffer)
{ … }
#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_STAT)
static int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
{ … }
COMPAT_SYSCALL_DEFINE2(newstat, const char __user *, filename,
struct compat_stat __user *, statbuf)
{ … }
COMPAT_SYSCALL_DEFINE2(newlstat, const char __user *, filename,
struct compat_stat __user *, statbuf)
{ … }
#ifndef __ARCH_WANT_STAT64
COMPAT_SYSCALL_DEFINE4(newfstatat, unsigned int, dfd,
const char __user *, filename,
struct compat_stat __user *, statbuf, int, flag)
{ … }
#endif
COMPAT_SYSCALL_DEFINE2(newfstat, unsigned int, fd,
struct compat_stat __user *, statbuf)
{ … }
#endif
void __inode_add_bytes(struct inode *inode, loff_t bytes)
{ … }
EXPORT_SYMBOL(…);
void inode_add_bytes(struct inode *inode, loff_t bytes)
{ … }
EXPORT_SYMBOL(…);
void __inode_sub_bytes(struct inode *inode, loff_t bytes)
{ … }
EXPORT_SYMBOL(…);
void inode_sub_bytes(struct inode *inode, loff_t bytes)
{ … }
EXPORT_SYMBOL(…);
loff_t inode_get_bytes(struct inode *inode)
{ … }
EXPORT_SYMBOL(…);
void inode_set_bytes(struct inode *inode, loff_t bytes)
{ … }
EXPORT_SYMBOL(…);