aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sys/zfs_vnops.h1
-rw-r--r--module/zfs/zfs_vnops.c38
-rw-r--r--module/zfs/zpl_inode.c28
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);