From 7f89ae6ba0f4e3c1b3e62272bbaa8228afdb020d Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Tue, 7 Jan 2014 23:16:46 +0100 Subject: [PATCH] Use local variable to read zp->z_mode 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 Signed-off-by: Ned Bass Signed-off-by: marku89 Issue #1700 --- include/sys/zfs_znode.h | 2 +- module/zfs/zfs_znode.c | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/sys/zfs_znode.h b/include/sys/zfs_znode.h index 4b70f7d0c..a0200684e 100644 --- a/include/sys/zfs_znode.h +++ b/include/sys/zfs_znode.h @@ -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 */ diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c index abf6222f2..2a4b1c648 100644 --- a/module/zfs/zfs_znode.c +++ b/module/zfs/zfs_znode.c @@ -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 */