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 <behlendorf1@llnl.gov>
Signed-off-by: Ned Bass <bass6@llnl.gov>
Signed-off-by: marku89 <mar42@kola.li>
Issue #1700
This commit is contained in:
Brian Behlendorf 2014-01-07 23:16:46 +01:00
parent d7ec8d4fd9
commit 7f89ae6ba0
2 changed files with 5 additions and 2 deletions

View File

@ -205,8 +205,8 @@ typedef struct znode {
uint64_t z_pflags; /* pflags (cached) */ uint64_t z_pflags; /* pflags (cached) */
uint64_t z_uid; /* uid fuid (cached) */ uint64_t z_uid; /* uid fuid (cached) */
uint64_t z_gid; /* gid fuid (cached) */ uint64_t z_gid; /* gid fuid (cached) */
mode_t z_mode; /* mode (cached) */
uint32_t z_sync_cnt; /* synchronous open count */ uint32_t z_sync_cnt; /* synchronous open count */
mode_t z_mode; /* mode (cached) */
kmutex_t z_acl_lock; /* acl data lock */ kmutex_t z_acl_lock; /* acl data lock */
zfs_acl_t *z_acl_cached; /* cached acl */ zfs_acl_t *z_acl_cached; /* cached acl */
krwlock_t z_xattr_lock; /* xattr data lock */ krwlock_t z_xattr_lock; /* xattr data lock */

View File

@ -355,6 +355,7 @@ zfs_znode_alloc(zfs_sb_t *zsb, dmu_buf_t *db, int blksz,
{ {
znode_t *zp; znode_t *zp;
struct inode *ip; struct inode *ip;
uint64_t mode;
uint64_t parent; uint64_t parent;
sa_bulk_attr_t bulk[9]; sa_bulk_attr_t bulk[9];
int count = 0; 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); 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_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_SIZE(zsb), NULL, &zp->z_size, 8);
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb), NULL, &zp->z_links, 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; goto error;
} }
zp->z_mode = mode;
/* /*
* xattr znodes hold a reference on their unique parent * xattr znodes hold a reference on their unique parent
*/ */