Skip to content

Commit

Permalink
Merge branch 'rebased-statx' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/git/viro/vfs

Pull vfs 'statx()' update from Al Viro.

This adds the new extended stat() interface that internally subsumes our
previous stat interfaces, and allows user mode to specify in more detail
what kind of information it wants.

It also allows for some explicit synchronization information to be
passed to the filesystem, which can be relevant for network filesystems:
is the cached value ok, or do you need open/close consistency, or what?

From David Howells.

Andreas Dilger points out that the first version of the extended statx
interface was posted June 29, 2010:

    https://www.spinics.net/lists/linux-fsdevel/msg33831.html

* 'rebased-statx' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  statx: Add a system call to make enhanced file info available
  • Loading branch information
torvalds committed Mar 3, 2017
2 parents e0d0722 + a528d35 commit 590dce2
Show file tree
Hide file tree
Showing 72 changed files with 822 additions and 214 deletions.
3 changes: 2 additions & 1 deletion Documentation/filesystems/Locking
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ prototypes:
int (*permission) (struct inode *, int, unsigned int);
int (*get_acl)(struct inode *, int);
int (*setattr) (struct dentry *, struct iattr *);
int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *);
int (*getattr) (const struct path *, struct dentry *, struct kstat *,
u32, unsigned int);
ssize_t (*listxattr) (struct dentry *, char *, size_t);
int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len);
void (*update_time)(struct inode *, struct timespec *, int);
Expand Down
3 changes: 2 additions & 1 deletion Documentation/filesystems/vfs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,8 @@ struct inode_operations {
int (*permission) (struct inode *, int);
int (*get_acl)(struct inode *, int);
int (*setattr) (struct dentry *, struct iattr *);
int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
int (*getattr) (const struct path *, struct dentry *, struct kstat *,
u32, unsigned int);
ssize_t (*listxattr) (struct dentry *, char *, size_t);
void (*update_time)(struct inode *, struct timespec *, int);
int (*atomic_open)(struct inode *, struct dentry *, struct file *,
Expand Down
1 change: 1 addition & 0 deletions arch/x86/entry/syscalls/syscall_32.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -389,3 +389,4 @@
380 i386 pkey_mprotect sys_pkey_mprotect
381 i386 pkey_alloc sys_pkey_alloc
382 i386 pkey_free sys_pkey_free
383 i386 statx sys_statx
1 change: 1 addition & 0 deletions arch/x86/entry/syscalls/syscall_64.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@
329 common pkey_mprotect sys_pkey_mprotect
330 common pkey_alloc sys_pkey_alloc
331 common pkey_free sys_pkey_free
332 common statx sys_statx

#
# x32-specific system call numbers start at 512 to avoid cache impact
Expand Down
3 changes: 2 additions & 1 deletion drivers/base/devtmpfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,8 @@ static int handle_remove(const char *nodename, struct device *dev)
if (d_really_is_positive(dentry)) {
struct kstat stat;
struct path p = {.mnt = parent.mnt, .dentry = dentry};
err = vfs_getattr(&p, &stat);
err = vfs_getattr(&p, &stat, STATX_TYPE | STATX_MODE,
AT_STATX_SYNC_AS_STAT);
if (!err && dev_mynode(dev, d_inode(dentry), &stat)) {
struct iattr newattrs;
/*
Expand Down
3 changes: 2 additions & 1 deletion drivers/block/loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -1176,7 +1176,8 @@ loop_get_status(struct loop_device *lo, struct loop_info64 *info)

if (lo->lo_state != Lo_bound)
return -ENXIO;
error = vfs_getattr(&file->f_path, &stat);
error = vfs_getattr(&file->f_path, &stat,
STATX_INO, AT_STATX_SYNC_AS_STAT);
if (error)
return error;
memset(info, 0, sizeof(*info));
Expand Down
2 changes: 1 addition & 1 deletion drivers/mtd/ubi/build.c
Original file line number Diff line number Diff line change
Expand Up @@ -1159,7 +1159,7 @@ static struct mtd_info * __init open_mtd_by_chdev(const char *mtd_dev)
if (err)
return ERR_PTR(err);

err = vfs_getattr(&path, &stat);
err = vfs_getattr(&path, &stat, STATX_TYPE, AT_STATX_SYNC_AS_STAT);
path_put(&path);
if (err)
return ERR_PTR(err);
Expand Down
2 changes: 1 addition & 1 deletion drivers/mtd/ubi/kapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ struct ubi_volume_desc *ubi_open_volume_path(const char *pathname, int mode)
if (error)
return ERR_PTR(error);

error = vfs_getattr(&path, &stat);
error = vfs_getattr(&path, &stat, STATX_TYPE, AT_STATX_SYNC_AS_STAT);
path_put(&path);
if (error)
return ERR_PTR(error);
Expand Down
9 changes: 5 additions & 4 deletions drivers/staging/lustre/lustre/llite/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -2952,15 +2952,16 @@ static int ll_inode_revalidate(struct dentry *dentry, __u64 ibits)
return rc;
}

int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat)
int ll_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
{
struct inode *inode = d_inode(de);
struct inode *inode = d_inode(path->dentry);
struct ll_sb_info *sbi = ll_i2sbi(inode);
struct ll_inode_info *lli = ll_i2info(inode);
int res;

res = ll_inode_revalidate(de, MDS_INODELOCK_UPDATE |
MDS_INODELOCK_LOOKUP);
res = ll_inode_revalidate(path->dentry,
MDS_INODELOCK_UPDATE | MDS_INODELOCK_LOOKUP);
ll_stats_ops_tally(sbi, LPROC_LL_GETATTR, 1);

if (res)
Expand Down
3 changes: 2 additions & 1 deletion drivers/staging/lustre/lustre/llite/llite_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,8 @@ int ll_file_open(struct inode *inode, struct file *file);
int ll_file_release(struct inode *inode, struct file *file);
int ll_release_openhandle(struct inode *, struct lookup_intent *);
int ll_md_real_close(struct inode *inode, fmode_t fmode);
int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat);
int ll_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags);
struct posix_acl *ll_get_acl(struct inode *inode, int type);
int ll_migrate(struct inode *parent, struct file *file, int mdtidx,
const char *name, int namelen);
Expand Down
10 changes: 6 additions & 4 deletions fs/9p/vfs_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1047,16 +1047,18 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,

/**
* v9fs_vfs_getattr - retrieve file metadata
* @mnt: mount information
* @dentry: file to get attributes on
* @path: Object to query
* @stat: metadata structure to populate
* @request_mask: Mask of STATX_xxx flags indicating the caller's interests
* @flags: AT_STATX_xxx setting
*
*/

static int
v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
v9fs_vfs_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
{
struct dentry *dentry = path->dentry;
struct v9fs_session_info *v9ses;
struct p9_fid *fid;
struct p9_wstat *st;
Expand Down
5 changes: 3 additions & 2 deletions fs/9p/vfs_inode_dotl.c
Original file line number Diff line number Diff line change
Expand Up @@ -468,9 +468,10 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,
}

static int
v9fs_vfs_getattr_dotl(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
v9fs_vfs_getattr_dotl(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
{
struct dentry *dentry = path->dentry;
struct v9fs_session_info *v9ses;
struct p9_fid *fid;
struct p9_stat_dotl *st;
Expand Down
8 changes: 3 additions & 5 deletions fs/afs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,12 +375,10 @@ int afs_validate(struct afs_vnode *vnode, struct key *key)
/*
* read the attributes of an inode
*/
int afs_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
int afs_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int query_flags)
{
struct inode *inode;

inode = d_inode(dentry);
struct inode *inode = d_inode(path->dentry);

_enter("{ ino=%lu v=%u }", inode->i_ino, inode->i_generation);

Expand Down
2 changes: 1 addition & 1 deletion fs/afs/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ extern struct inode *afs_iget(struct super_block *, struct key *,
struct afs_callback *);
extern void afs_zap_data(struct afs_vnode *);
extern int afs_validate(struct afs_vnode *, struct key *);
extern int afs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
extern int afs_getattr(const struct path *, struct kstat *, u32, unsigned int);
extern int afs_setattr(struct dentry *, struct iattr *);
extern void afs_evict_inode(struct inode *);
extern int afs_drop_inode(struct inode *);
Expand Down
4 changes: 2 additions & 2 deletions fs/bad_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ static int bad_inode_permission(struct inode *inode, int mask)
return -EIO;
}

static int bad_inode_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
static int bad_inode_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int query_flags)
{
return -EIO;
}
Expand Down
6 changes: 3 additions & 3 deletions fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -9413,11 +9413,11 @@ int btrfs_init_cachep(void)
return -ENOMEM;
}

static int btrfs_getattr(struct vfsmount *mnt,
struct dentry *dentry, struct kstat *stat)
static int btrfs_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
{
u64 delalloc_bytes;
struct inode *inode = d_inode(dentry);
struct inode *inode = d_inode(path->dentry);
u32 blocksize = inode->i_sb->s_blocksize;

generic_fillattr(inode, stat);
Expand Down
6 changes: 3 additions & 3 deletions fs/ceph/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -2187,10 +2187,10 @@ int ceph_permission(struct inode *inode, int mask)
* Get all attributes. Hopefully somedata we'll have a statlite()
* and can limit the fields we require to be accurate.
*/
int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
int ceph_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
{
struct inode *inode = d_inode(dentry);
struct inode *inode = d_inode(path->dentry);
struct ceph_inode_info *ci = ceph_inode(inode);
int err;

Expand Down
4 changes: 2 additions & 2 deletions fs/ceph/super.h
Original file line number Diff line number Diff line change
Expand Up @@ -784,8 +784,8 @@ static inline int ceph_do_getattr(struct inode *inode, int mask, bool force)
extern int ceph_permission(struct inode *inode, int mask);
extern int __ceph_setattr(struct inode *inode, struct iattr *attr);
extern int ceph_setattr(struct dentry *dentry, struct iattr *attr);
extern int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat);
extern int ceph_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags);

/* xattr.c */
int __ceph_setxattr(struct inode *, const char *, const void *, size_t, int);
Expand Down
2 changes: 1 addition & 1 deletion fs/cifs/cifsfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ extern int cifs_revalidate_dentry(struct dentry *);
extern int cifs_invalidate_mapping(struct inode *inode);
extern int cifs_revalidate_mapping(struct inode *inode);
extern int cifs_zap_mapping(struct inode *inode);
extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
extern int cifs_getattr(const struct path *, struct kstat *, u32, unsigned int);
extern int cifs_setattr(struct dentry *, struct iattr *);

extern const struct inode_operations cifs_file_inode_ops;
Expand Down
5 changes: 3 additions & 2 deletions fs/cifs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1992,9 +1992,10 @@ int cifs_revalidate_dentry(struct dentry *dentry)
return cifs_revalidate_mapping(inode);
}

int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
int cifs_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
{
struct dentry *dentry = path->dentry;
struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
struct inode *inode = d_inode(dentry);
Expand Down
2 changes: 1 addition & 1 deletion fs/coda/coda_linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ int coda_open(struct inode *i, struct file *f);
int coda_release(struct inode *i, struct file *f);
int coda_permission(struct inode *inode, int mask);
int coda_revalidate_inode(struct inode *);
int coda_getattr(struct vfsmount *, struct dentry *, struct kstat *);
int coda_getattr(const struct path *, struct kstat *, u32, unsigned int);
int coda_setattr(struct dentry *, struct iattr *);

/* this file: heloers */
Expand Down
7 changes: 4 additions & 3 deletions fs/coda/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,12 @@ static void coda_evict_inode(struct inode *inode)
coda_cache_clear_inode(inode);
}

int coda_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
int coda_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
{
int err = coda_revalidate_inode(d_inode(dentry));
int err = coda_revalidate_inode(d_inode(path->dentry));
if (!err)
generic_fillattr(d_inode(dentry), stat);
generic_fillattr(d_inode(path->dentry), stat);
return err;
}

Expand Down
13 changes: 8 additions & 5 deletions fs/ecryptfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -959,9 +959,10 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
return rc;
}

static int ecryptfs_getattr_link(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
static int ecryptfs_getattr_link(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
{
struct dentry *dentry = path->dentry;
struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
int rc = 0;

Expand All @@ -983,13 +984,15 @@ static int ecryptfs_getattr_link(struct vfsmount *mnt, struct dentry *dentry,
return rc;
}

static int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
static int ecryptfs_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
{
struct dentry *dentry = path->dentry;
struct kstat lower_stat;
int rc;

rc = vfs_getattr(ecryptfs_dentry_to_lower_path(dentry), &lower_stat);
rc = vfs_getattr(ecryptfs_dentry_to_lower_path(dentry), &lower_stat,
request_mask, flags);
if (!rc) {
fsstack_copy_attr_all(d_inode(dentry),
ecryptfs_inode_to_lower(d_inode(dentry)));
Expand Down
3 changes: 2 additions & 1 deletion fs/exportfs/expfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,8 @@ static int get_name(const struct path *path, char *name, struct dentry *child)
* filesystem supports 64-bit inode numbers. So we need to
* actually call ->getattr, not just read i_ino:
*/
error = vfs_getattr_nosec(&child_path, &stat);
error = vfs_getattr_nosec(&child_path, &stat,
STATX_INO, AT_STATX_SYNC_AS_STAT);
if (error)
return error;
buffer.ino = stat.ino;
Expand Down
3 changes: 1 addition & 2 deletions fs/ext4/ext4.h
Original file line number Diff line number Diff line change
Expand Up @@ -2463,8 +2463,7 @@ extern struct inode *ext4_iget(struct super_block *, unsigned long);
extern struct inode *ext4_iget_normal(struct super_block *, unsigned long);
extern int ext4_write_inode(struct inode *, struct writeback_control *);
extern int ext4_setattr(struct dentry *, struct iattr *);
extern int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat);
extern int ext4_getattr(const struct path *, struct kstat *, u32, unsigned int);
extern void ext4_evict_inode(struct inode *);
extern void ext4_clear_inode(struct inode *);
extern int ext4_sync_inode(handle_t *, struct inode *);
Expand Down
6 changes: 3 additions & 3 deletions fs/ext4/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -5387,13 +5387,13 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
return error;
}

int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
int ext4_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int query_flags)
{
struct inode *inode;
unsigned long long delalloc_blocks;

inode = d_inode(dentry);
inode = d_inode(path->dentry);
generic_fillattr(inode, stat);

/*
Expand Down
4 changes: 2 additions & 2 deletions fs/f2fs/f2fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -2040,8 +2040,8 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync);
void truncate_data_blocks(struct dnode_of_data *dn);
int truncate_blocks(struct inode *inode, u64 from, bool lock);
int f2fs_truncate(struct inode *inode);
int f2fs_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat);
int f2fs_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags);
int f2fs_setattr(struct dentry *dentry, struct iattr *attr);
int truncate_hole(struct inode *inode, pgoff_t pg_start, pgoff_t pg_end);
int truncate_data_blocks_range(struct dnode_of_data *dn, int count);
Expand Down
6 changes: 3 additions & 3 deletions fs/f2fs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -633,10 +633,10 @@ int f2fs_truncate(struct inode *inode)
return 0;
}

int f2fs_getattr(struct vfsmount *mnt,
struct dentry *dentry, struct kstat *stat)
int f2fs_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
{
struct inode *inode = d_inode(dentry);
struct inode *inode = d_inode(path->dentry);
generic_fillattr(inode, stat);
stat->blocks <<= 3;
return 0;
Expand Down
4 changes: 2 additions & 2 deletions fs/fat/fat.h
Original file line number Diff line number Diff line change
Expand Up @@ -364,8 +364,8 @@ extern const struct file_operations fat_file_operations;
extern const struct inode_operations fat_file_inode_operations;
extern int fat_setattr(struct dentry *dentry, struct iattr *attr);
extern void fat_truncate_blocks(struct inode *inode, loff_t offset);
extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat);
extern int fat_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags);
extern int fat_file_fsync(struct file *file, loff_t start, loff_t end,
int datasync);

Expand Down
5 changes: 3 additions & 2 deletions fs/fat/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,9 +365,10 @@ void fat_truncate_blocks(struct inode *inode, loff_t offset)
fat_flush_inodes(inode->i_sb, inode, NULL);
}

int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
int fat_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
{
struct inode *inode = d_inode(dentry);
struct inode *inode = d_inode(path->dentry);
generic_fillattr(inode, stat);
stat->blksize = MSDOS_SB(inode->i_sb)->cluster_size;

Expand Down
6 changes: 3 additions & 3 deletions fs/fuse/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -1777,10 +1777,10 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
return ret;
}

static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
struct kstat *stat)
static int fuse_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
{
struct inode *inode = d_inode(entry);
struct inode *inode = d_inode(path->dentry);
struct fuse_conn *fc = get_fuse_conn(inode);

if (!fuse_allow_current_process(fc))
Expand Down
Loading

0 comments on commit 590dce2

Please sign in to comment.