]> granicus.if.org Git - zfs/commitdiff
Use local variable to read zp->z_mode
authorBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 7 Jan 2014 22:16:46 +0000 (23:16 +0100)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 9 Jan 2014 23:50:11 +0000 (15:50 -0800)
When accessing the zp->z_mode through the SA bulk interface we
expect that 64-bits are available to hold the result.  However,
on 32-bit platforms mode_t will only be 32-bits so we cannot
pass it to SA_ADD_BULK_ATTR().  Instead a local uint64_t variable
must be used and the result assigned to zp->z_mode.

This went unnoticed on 32-bit little endian platforms because
the bytes happen to end up in the correct 32-bits.  But on big
endian platforms like Sparc the zp->z_mode will always end up
set to zero.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ned Bass <bass6@llnl.gov>
Signed-off-by: marku89 <mar42@kola.li>
Issue #1700

include/sys/zfs_znode.h
module/zfs/zfs_znode.c

index 4b70f7d0c9bf1ae34fabf5afae797a03766f216e..a0200684e3460ac133ec1ded275b99c0d5a42f51 100644 (file)
@@ -205,8 +205,8 @@ typedef struct znode {
        uint64_t        z_pflags;       /* pflags (cached) */
        uint64_t        z_uid;          /* uid fuid (cached) */
        uint64_t        z_gid;          /* gid fuid (cached) */
-       mode_t          z_mode;         /* mode (cached) */
        uint32_t        z_sync_cnt;     /* synchronous open count */
+       mode_t          z_mode;         /* mode (cached) */
        kmutex_t        z_acl_lock;     /* acl data lock */
        zfs_acl_t       *z_acl_cached;  /* cached acl */
        krwlock_t       z_xattr_lock;   /* xattr data lock */
index abf6222f2fb02163239dc3cc96fe18c7540c93a3..2a4b1c648c1074f14c2866b2b28dff58d2da4cf8 100644 (file)
@@ -355,6 +355,7 @@ zfs_znode_alloc(zfs_sb_t *zsb, dmu_buf_t *db, int blksz,
 {
        znode_t *zp;
        struct inode *ip;
+       uint64_t mode;
        uint64_t parent;
        sa_bulk_attr_t bulk[9];
        int count = 0;
@@ -386,7 +387,7 @@ zfs_znode_alloc(zfs_sb_t *zsb, dmu_buf_t *db, int blksz,
 
        zfs_znode_sa_init(zsb, zp, db, obj_type, hdl);
 
-       SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL, &zp->z_mode, 8);
+       SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL, &mode, 8);
        SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GEN(zsb), NULL, &zp->z_gen, 8);
        SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zsb), NULL, &zp->z_size, 8);
        SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb), NULL, &zp->z_links, 8);
@@ -406,6 +407,8 @@ zfs_znode_alloc(zfs_sb_t *zsb, dmu_buf_t *db, int blksz,
                goto error;
        }
 
+       zp->z_mode = mode;
+
        /*
         * xattr znodes hold a reference on their unique parent
         */