/** * fill_mg_cmtime - Fill in the mtime and ctime and flag ctime as QUERIED * @stat: where to store the resulting values * @request_mask: STATX_* values requested * @inode: inode from which to grab the c/mtime * * Given @inode, grab the ctime and mtime out if it and store the result * in @stat. When fetching the value, flag it as QUERIED (if not already) * so the next write will record a distinct timestamp. * * NB: The QUERIED flag is tracked in the ctime, but we set it there even * if only the mtime was requested, as that ensures that the next mtime * change will be distinct.
*/ void fill_mg_cmtime(struct kstat *stat, u32 request_mask, struct inode *inode)
{
atomic_t *pcn = (atomic_t *)&inode->i_ctime_nsec;
/* If neither time was requested, then don't report them */ if (!(request_mask & (STATX_CTIME|STATX_MTIME))) {
stat->result_mask &= ~(STATX_CTIME|STATX_MTIME); return;
}
/** * generic_fillattr - Fill in the basic attributes from the inode struct * @idmap: idmap of the mount the inode was found from * @request_mask: statx request_mask * @inode: Inode to use as the source * @stat: Where to fill in the attributes * * Fill in the basic attributes in the kstat structure from data that's to be * found on the VFS inode structure. This is the default if no getattr inode * operation is supplied. * * If the inode has been found through an idmapped mount the idmap of * the vfsmount must be passed through @idmap. This function will then * take care to map the inode according to @idmap before filling in the * uid and gid filds. On non-idmapped mounts or if permission checking is to be * performed on the raw inode simply pass @nop_mnt_idmap.
*/ void generic_fillattr(struct mnt_idmap *idmap, u32 request_mask, struct inode *inode, struct kstat *stat)
{
vfsuid_t vfsuid = i_uid_into_vfsuid(idmap, inode);
vfsgid_t vfsgid = i_gid_into_vfsgid(idmap, inode);
/** * generic_fill_statx_attr - Fill in the statx attributes from the inode flags * @inode: Inode to use as the source * @stat: Where to fill in the attribute flags * * Fill in the STATX_ATTR_* flags in the kstat structure for properties of the * inode that are published on i_flags and enforced by the VFS.
*/ void generic_fill_statx_attr(struct inode *inode, struct kstat *stat)
{ if (inode->i_flags & S_IMMUTABLE)
stat->attributes |= STATX_ATTR_IMMUTABLE; if (inode->i_flags & S_APPEND)
stat->attributes |= STATX_ATTR_APPEND;
stat->attributes_mask |= KSTAT_ATTR_VFS_FLAGS;
}
EXPORT_SYMBOL(generic_fill_statx_attr);
/** * generic_fill_statx_atomic_writes - Fill in atomic writes statx attributes * @stat: Where to fill in the attribute flags * @unit_min: Minimum supported atomic write length in bytes * @unit_max: Maximum supported atomic write length in bytes * @unit_max_opt: Optimised maximum supported atomic write length in bytes * * Fill in the STATX{_ATTR}_WRITE_ATOMIC flags in the kstat structure from * atomic write unit_min and unit_max values.
*/ void generic_fill_statx_atomic_writes(struct kstat *stat, unsignedint unit_min, unsignedint unit_max, unsignedint unit_max_opt)
{ /* Confirm that the request type is known */
stat->result_mask |= STATX_WRITE_ATOMIC;
/* Confirm that the file attribute type is known */
stat->attributes_mask |= STATX_ATTR_WRITE_ATOMIC;
/** * vfs_getattr_nosec - getattr without security checks * @path: file to get attributes from * @stat: structure to return attributes in * @request_mask: STATX_xxx flags indicating what the caller wants * @query_flags: Query mode (AT_STATX_SYNC_TYPE) * * Get attributes without calling security_inode_getattr. * * Currently the only caller other than vfs_getattr is internal to the * filehandle lookup code, which uses only the inode number and returns no * attributes to any user. Any other code probably wants vfs_getattr.
*/ int vfs_getattr_nosec(conststruct path *path, struct kstat *stat,
u32 request_mask, unsignedint query_flags)
{ struct mnt_idmap *idmap; struct inode *inode = d_backing_inode(path->dentry);
/* allow the fs to override these if it really wants to */ /* SB_NOATIME means filesystem supplies dummy atime value */ if (inode->i_sb->s_flags & SB_NOATIME)
stat->result_mask &= ~STATX_ATIME;
/* * Note: If you add another clause to set an attribute flag, please * update attributes_mask below.
*/ if (IS_AUTOMOUNT(inode))
stat->attributes |= STATX_ATTR_AUTOMOUNT;
if (IS_DAX(inode))
stat->attributes |= STATX_ATTR_DAX;
idmap = mnt_idmap(path->mnt); if (inode->i_op->getattr) { int ret;
ret = inode->i_op->getattr(idmap, path, stat, request_mask,
query_flags); if (ret) return ret;
} else {
generic_fillattr(idmap, request_mask, inode, stat);
}
/* * If this is a block device inode, override the filesystem attributes * with the block device specific parameters that need to be obtained * from the bdev backing inode.
*/ if (S_ISBLK(stat->mode))
bdev_statx(path, stat, request_mask);
return 0;
}
EXPORT_SYMBOL(vfs_getattr_nosec);
/* * vfs_getattr - Get the enhanced basic attributes of a file * @path: The file of interest * @stat: Where to return the statistics * @request_mask: STATX_xxx flags indicating what the caller wants * @query_flags: Query mode (AT_STATX_SYNC_TYPE) * * Ask the filesystem for a file's attributes. The caller must indicate in * request_mask and query_flags to indicate what they want. * * If the file is remote, the filesystem can be forced to update the attributes * from the backing store by passing AT_STATX_FORCE_SYNC in query_flags or can * suppress the update by passing AT_STATX_DONT_SYNC. * * Bits must have been set in request_mask to indicate which attributes the * caller wants retrieving. Any such attribute not requested may be returned * anyway, but the value may be approximate, and, if remote, may not have been * synchronised with the server. * * 0 will be returned on success, and a -ve error code if unsuccessful.
*/ int vfs_getattr(conststruct path *path, struct kstat *stat,
u32 request_mask, unsignedint query_flags)
{ int retval;
/** * vfs_fstat - Get the basic attributes by file descriptor * @fd: The file descriptor referring to the file of interest * @stat: The result structure to fill in. * * This function is a wrapper around vfs_getattr(). The main difference is * that it uses a file descriptor to determine the file location. * * 0 will be returned on success, and a -ve error code if unsuccessful.
*/ int vfs_fstat(int fd, struct kstat *stat)
{ CLASS(fd_raw, f)(fd); if (fd_empty(f)) return -EBADF; return vfs_getattr(&fd_file(f)->f_path, stat, STATX_BASIC_STATS, 0);
}
staticint statx_lookup_flags(int flags)
{ int lookup_flags = 0;
if (!(flags & AT_SYMLINK_NOFOLLOW))
lookup_flags |= LOOKUP_FOLLOW; if (!(flags & AT_NO_AUTOMOUNT))
lookup_flags |= LOOKUP_AUTOMOUNT;
return lookup_flags;
}
staticint vfs_statx_path(struct path *path, int flags, struct kstat *stat,
u32 request_mask)
{ int error = vfs_getattr(path, stat, request_mask, flags); if (error) return error;
/** * vfs_statx - Get basic and extra attributes by filename * @dfd: A file descriptor representing the base dir for a relative filename * @filename: The name of the file of interest * @flags: Flags to control the query * @stat: The result structure to fill in. * @request_mask: STATX_xxx flags indicating what the caller wants * * This function is a wrapper around vfs_getattr(). The main difference is * that it uses a filename and base directory to determine the file location. * Additionally, the use of AT_SYMLINK_NOFOLLOW in flags will prevent a symlink * at the given name from being referenced. * * 0 will be returned on success, and a -ve error code if unsuccessful.
*/ staticint vfs_statx(int dfd, struct filename *filename, int flags, struct kstat *stat, u32 request_mask)
{ struct path path; unsignedint lookup_flags = statx_lookup_flags(flags); int error;
int do_statx_fd(int fd, unsignedint flags, unsignedint mask, struct statx __user *buffer)
{ struct kstat stat; int error;
if (mask & STATX__RESERVED) return -EINVAL; if ((flags & AT_STATX_SYNC_TYPE) == AT_STATX_SYNC_TYPE) return -EINVAL;
/* * STATX_CHANGE_COOKIE is kernel-only for now. Ignore requests * from userland.
*/
mask &= ~STATX_CHANGE_COOKIE;
error = vfs_statx_fd(fd, flags, &stat, mask); if (error) return error;
return cp_statx(&stat, buffer);
}
/** * sys_statx - System call to get enhanced stats * @dfd: Base directory to pathwalk from *or* fd to stat. * @filename: File to stat or either NULL or "" with AT_EMPTY_PATH * @flags: AT_* flags to control pathwalk. * @mask: Parts of statx struct actually required. * @buffer: Result buffer. * * Note that fstat() can be emulated by setting dfd to the fd of interest, * supplying "" (or preferably NULL) as the filename and setting AT_EMPTY_PATH * in the flags.
*/
SYSCALL_DEFINE5(statx, int, dfd, constchar __user *, filename, unsigned, flags, unsignedint, mask, struct statx __user *, buffer)
{ int ret; struct filename *name = getname_maybe_null(filename, flags);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.