Skip to content

Commit a94addd

Browse files
ahrensbehlendorf
authored andcommitted
Illumos #3208 cross-endian incorrect user/group accounting
3208 moving zpool cross-endian results in incorrect user/group accounting Reviewed by: Adam Leventhal <ahl@delphix.com> Reviewed by: Christopher Siden <chris.siden@delphix.com> Approved by: Richard Lowe <richlowe@richlowe.net> References: illumos/illumos-gate@e828a46 illumos changeset: 13835:eea81edc4f14 https://www.illumos.org/issues/3208 Ported-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #627 Closes #1136
1 parent e6f7d01 commit a94addd

File tree

2 files changed

+27
-10
lines changed

2 files changed

+27
-10
lines changed

include/sys/sa_impl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
*/
2121
/*
2222
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
23+
* Copyright (c) 2012 by Delphix. All rights reserved.
2324
*/
2425

2526
#ifndef _SYS_SA_IMPL_H
@@ -181,7 +182,7 @@ typedef struct sa_hdr_phys {
181182
*/
182183

183184
#define SA_HDR_LAYOUT_NUM(hdr) BF32_GET(hdr->sa_layout_info, 0, 10)
184-
#define SA_HDR_SIZE(hdr) BF32_GET_SB(hdr->sa_layout_info, 10, 16, 3, 0)
185+
#define SA_HDR_SIZE(hdr) BF32_GET_SB(hdr->sa_layout_info, 10, 6, 3, 0)
185186
#define SA_HDR_LAYOUT_INFO_ENCODE(x, num, size) \
186187
{ \
187188
BF32_SET_SB(x, 10, 6, 3, 0, size); \

module/zfs/zfs_vfsops.c

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include <sys/spa.h>
5050
#include <sys/zap.h>
5151
#include <sys/sa.h>
52+
#include <sys/sa_impl.h>
5253
#include <sys/varargs.h>
5354
#include <sys/policy.h>
5455
#include <sys/atomic.h>
@@ -63,7 +64,6 @@
6364
#include <sys/dnlc.h>
6465
#include <sys/dmu_objset.h>
6566
#include <sys/spa_boot.h>
66-
#include <sys/sa.h>
6767
#include <sys/zpl.h>
6868
#include "zfs_comutil.h"
6969

@@ -300,7 +300,6 @@ static int
300300
zfs_space_delta_cb(dmu_object_type_t bonustype, void *data,
301301
uint64_t *userp, uint64_t *groupp)
302302
{
303-
znode_phys_t *znp = data;
304303
int error = 0;
305304

306305
/*
@@ -319,27 +318,44 @@ zfs_space_delta_cb(dmu_object_type_t bonustype, void *data,
319318
return (EEXIST);
320319

321320
if (bonustype == DMU_OT_ZNODE) {
321+
znode_phys_t *znp = data;
322322
*userp = znp->zp_uid;
323323
*groupp = znp->zp_gid;
324324
} else {
325325
int hdrsize;
326+
sa_hdr_phys_t *sap = data;
327+
sa_hdr_phys_t sa = *sap;
328+
boolean_t swap = B_FALSE;
326329

327330
ASSERT(bonustype == DMU_OT_SA);
328-
hdrsize = sa_hdrsize(data);
329331

330-
if (hdrsize != 0) {
331-
*userp = *((uint64_t *)((uintptr_t)data + hdrsize +
332-
SA_UID_OFFSET));
333-
*groupp = *((uint64_t *)((uintptr_t)data + hdrsize +
334-
SA_GID_OFFSET));
335-
} else {
332+
if (sa.sa_magic == 0) {
336333
/*
337334
* This should only happen for newly created
338335
* files that haven't had the znode data filled
339336
* in yet.
340337
*/
341338
*userp = 0;
342339
*groupp = 0;
340+
return (0);
341+
}
342+
if (sa.sa_magic == BSWAP_32(SA_MAGIC)) {
343+
sa.sa_magic = SA_MAGIC;
344+
sa.sa_layout_info = BSWAP_16(sa.sa_layout_info);
345+
swap = B_TRUE;
346+
} else {
347+
VERIFY3U(sa.sa_magic, ==, SA_MAGIC);
348+
}
349+
350+
hdrsize = sa_hdrsize(&sa);
351+
VERIFY3U(hdrsize, >=, sizeof (sa_hdr_phys_t));
352+
*userp = *((uint64_t *)((uintptr_t)data + hdrsize +
353+
SA_UID_OFFSET));
354+
*groupp = *((uint64_t *)((uintptr_t)data + hdrsize +
355+
SA_GID_OFFSET));
356+
if (swap) {
357+
*userp = BSWAP_64(*userp);
358+
*groupp = BSWAP_64(*groupp);
343359
}
344360
}
345361
return (error);

0 commit comments

Comments
 (0)