diff options
-rw-r--r-- | include/sys/zfs_vnops.h | 1 | ||||
-rw-r--r-- | module/zfs/zfs_vnops.c | 38 | ||||
-rw-r--r-- | module/zfs/zpl_inode.c | 28 |
3 files changed, 40 insertions, 27 deletions
diff --git a/include/sys/zfs_vnops.h b/include/sys/zfs_vnops.h index acc617b41..d73fe2f3e 100644 --- a/include/sys/zfs_vnops.h +++ b/include/sys/zfs_vnops.h @@ -54,6 +54,7 @@ extern int zfs_readdir(struct inode *ip, void *dirent, filldir_t filldir, loff_t *pos, cred_t *cr); extern int zfs_fsync(struct inode *ip, int syncflag, cred_t *cr); extern int zfs_getattr(struct inode *ip, vattr_t *vap, int flag, cred_t *cr); +extern int zfs_getattr_fast(struct inode *ip, struct kstat *sp); extern int zfs_setattr(struct inode *ip, vattr_t *vap, int flag, cred_t *cr); extern int zfs_rename(struct inode *sdip, char *snm, struct inode *tdip, char *tnm, cred_t *cr, int flags); diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index ae61b4304..dd9f4d9e5 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -2283,6 +2283,44 @@ zfs_getattr(struct inode *ip, vattr_t *vap, int flags, cred_t *cr) EXPORT_SYMBOL(zfs_getattr); /* + * Get the basic file attributes and place them in the provided kstat + * structure. The inode is assumed to be the authoritative source + * for most of the attributes. However, the znode currently has the + * authoritative atime, blksize, and block count. + * + * IN: ip - inode of file. + * + * OUT: sp - kstat values. + * + * RETURN: 0 (always succeeds) + */ +/* ARGSUSED */ +int +zfs_getattr_fast(struct inode *ip, struct kstat *sp) +{ + znode_t *zp = ITOZ(ip); + zfs_sb_t *zsb = ITOZSB(ip); + + mutex_enter(&zp->z_lock); + + generic_fillattr(ip, sp); + ZFS_TIME_DECODE(&sp->atime, zp->z_atime); + + sa_object_size(zp->z_sa_hdl, (uint32_t *)&sp->blksize, &sp->blocks); + if (unlikely(zp->z_blksz == 0)) { + /* + * Block size hasn't been set; suggest maximal I/O transfers. + */ + sp->blksize = zsb->z_max_blksz; + } + + mutex_exit(&zp->z_lock); + + return (0); +} +EXPORT_SYMBOL(zfs_getattr_fast); + +/* * Set the file attributes to the values contained in the * vattr structure. * diff --git a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c index 8376673f1..a6e0cbb87 100644 --- a/module/zfs/zpl_inode.c +++ b/module/zfs/zpl_inode.c @@ -165,35 +165,9 @@ zpl_rmdir(struct inode * dir, struct dentry *dentry) static int zpl_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { - cred_t *cr = CRED(); - vattr_t *vap; - struct inode *ip; int error; - ip = dentry->d_inode; - crhold(cr); - vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP); - - error = -zfs_getattr(ip, vap, 0, cr); - if (error) - goto out; - - stat->ino = ip->i_ino; - stat->dev = ip->i_sb->s_dev; - stat->mode = vap->va_mode; - stat->nlink = vap->va_nlink; - stat->uid = vap->va_uid; - stat->gid = vap->va_gid; - stat->rdev = vap->va_rdev; - stat->size = vap->va_size; - stat->atime = vap->va_atime; - stat->mtime = vap->va_mtime; - stat->ctime = vap->va_ctime; - stat->blksize = vap->va_blksize; - stat->blocks = vap->va_nblocks; -out: - kmem_free(vap, sizeof(vattr_t)); - crfree(cr); + error = -zfs_getattr_fast(dentry->d_inode, stat); ASSERT3S(error, <=, 0); return (error); |