1168404Spjd/*
2168404Spjd * CDDL HEADER START
3168404Spjd *
4168404Spjd * The contents of this file are subject to the terms of the
5185029Spjd * Common Development and Distribution License (the "License").
6185029Spjd * You may not use this file except in compliance with the License.
7168404Spjd *
8168404Spjd * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9168404Spjd * or http://www.opensolaris.org/os/licensing.
10168404Spjd * See the License for the specific language governing permissions
11168404Spjd * and limitations under the License.
12168404Spjd *
13168404Spjd * When distributing Covered Code, include this CDDL HEADER in each
14168404Spjd * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15168404Spjd * If applicable, add the following below this CDDL HEADER, with the
16168404Spjd * fields enclosed by brackets "[]" replaced with your own identifying
17168404Spjd * information: Portions Copyright [yyyy] [name of copyright owner]
18168404Spjd *
19168404Spjd * CDDL HEADER END
20168404Spjd */
21168404Spjd/*
22219089Spjd * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23168404Spjd * Use is subject to license terms.
24168404Spjd */
25168404Spjd
26168404Spjd#include <sys/zfs_context.h>
27168404Spjd#include <sys/vfs.h>
28168404Spjd#include <sys/fs/zfs.h>
29168404Spjd#include <sys/zfs_znode.h>
30219089Spjd#include <sys/zfs_sa.h>
31168404Spjd#include <sys/zfs_acl.h>
32168404Spjd
33168404Spjdvoid
34185029Spjdzfs_oldace_byteswap(ace_t *ace, int ace_cnt)
35168404Spjd{
36168404Spjd	int i;
37168404Spjd
38168404Spjd	for (i = 0; i != ace_cnt; i++, ace++) {
39168404Spjd		ace->a_who = BSWAP_32(ace->a_who);
40168404Spjd		ace->a_access_mask = BSWAP_32(ace->a_access_mask);
41168404Spjd		ace->a_flags = BSWAP_16(ace->a_flags);
42168404Spjd		ace->a_type = BSWAP_16(ace->a_type);
43168404Spjd	}
44168404Spjd}
45168404Spjd
46185029Spjd/*
47185029Spjd * swap ace_t and ace_oject_t
48185029Spjd */
49185029Spjdvoid
50185029Spjdzfs_ace_byteswap(void *buf, size_t size, boolean_t zfs_layout)
51185029Spjd{
52185029Spjd	caddr_t end;
53185029Spjd	caddr_t ptr;
54247187Smm	zfs_ace_t *zacep = NULL;
55185029Spjd	ace_t *acep;
56185029Spjd	uint16_t entry_type;
57185029Spjd	size_t entry_size;
58185029Spjd	int ace_type;
59185029Spjd
60185029Spjd	end = (caddr_t)buf + size;
61185029Spjd	ptr = buf;
62185029Spjd
63185029Spjd	while (ptr < end) {
64185029Spjd		if (zfs_layout) {
65207683Smarius			/*
66207683Smarius			 * Avoid overrun.  Embedded aces can have one
67207683Smarius			 * of several sizes.  We don't know exactly
68207683Smarius			 * how many our present, only the size of the
69207683Smarius			 * buffer containing them.  That size may be
70207683Smarius			 * larger than needed to hold the aces
71207683Smarius			 * present.  As long as we do not do any
72207683Smarius			 * swapping beyond the end of our block we are
73207683Smarius			 * okay.  It it safe to swap any non-ace data
74207683Smarius			 * within the block since it is just zeros.
75207683Smarius			 */
76207683Smarius			if (ptr + sizeof (zfs_ace_hdr_t) > end) {
77207683Smarius				break;
78207683Smarius			}
79185029Spjd			zacep = (zfs_ace_t *)ptr;
80185029Spjd			zacep->z_hdr.z_access_mask =
81185029Spjd			    BSWAP_32(zacep->z_hdr.z_access_mask);
82185029Spjd			zacep->z_hdr.z_flags = BSWAP_16(zacep->z_hdr.z_flags);
83185029Spjd			ace_type = zacep->z_hdr.z_type =
84185029Spjd			    BSWAP_16(zacep->z_hdr.z_type);
85185029Spjd			entry_type = zacep->z_hdr.z_flags & ACE_TYPE_FLAGS;
86185029Spjd		} else {
87207683Smarius			/* Overrun avoidance */
88207683Smarius			if (ptr + sizeof (ace_t) > end) {
89207683Smarius				break;
90207683Smarius			}
91185029Spjd			acep = (ace_t *)ptr;
92185029Spjd			acep->a_access_mask = BSWAP_32(acep->a_access_mask);
93185029Spjd			acep->a_flags = BSWAP_16(acep->a_flags);
94185029Spjd			ace_type = acep->a_type = BSWAP_16(acep->a_type);
95185029Spjd			acep->a_who = BSWAP_32(acep->a_who);
96185029Spjd			entry_type = acep->a_flags & ACE_TYPE_FLAGS;
97185029Spjd		}
98185029Spjd		switch (entry_type) {
99185029Spjd		case ACE_OWNER:
100185029Spjd		case ACE_EVERYONE:
101185029Spjd		case (ACE_IDENTIFIER_GROUP | ACE_GROUP):
102185029Spjd			entry_size = zfs_layout ?
103185029Spjd			    sizeof (zfs_ace_hdr_t) : sizeof (ace_t);
104185029Spjd			break;
105185029Spjd		case ACE_IDENTIFIER_GROUP:
106185029Spjd		default:
107207683Smarius			/* Overrun avoidance */
108185029Spjd			if (zfs_layout) {
109207683Smarius				if (ptr + sizeof (zfs_ace_t) <= end) {
110207683Smarius					zacep->z_fuid = BSWAP_64(zacep->z_fuid);
111207683Smarius				} else {
112207683Smarius					entry_size = sizeof (zfs_ace_t);
113207683Smarius					break;
114207683Smarius				}
115185029Spjd			}
116185029Spjd			switch (ace_type) {
117185029Spjd			case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
118185029Spjd			case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
119185029Spjd			case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
120185029Spjd			case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
121185029Spjd				entry_size = zfs_layout ?
122185029Spjd				    sizeof (zfs_object_ace_t) :
123185029Spjd				    sizeof (ace_object_t);
124185029Spjd				break;
125185029Spjd			default:
126185029Spjd				entry_size = zfs_layout ? sizeof (zfs_ace_t) :
127185029Spjd				    sizeof (ace_t);
128185029Spjd				break;
129185029Spjd			}
130185029Spjd		}
131185029Spjd		ptr = ptr + entry_size;
132185029Spjd	}
133185029Spjd}
134185029Spjd
135168404Spjd/* ARGSUSED */
136168404Spjdvoid
137185029Spjdzfs_oldacl_byteswap(void *buf, size_t size)
138168404Spjd{
139168404Spjd	int cnt;
140168404Spjd
141168404Spjd	/*
142168404Spjd	 * Arggh, since we don't know how many ACEs are in
143168404Spjd	 * the array, we have to swap the entire block
144168404Spjd	 */
145168404Spjd
146168404Spjd	cnt = size / sizeof (ace_t);
147168404Spjd
148185029Spjd	zfs_oldace_byteswap((ace_t *)buf, cnt);
149168404Spjd}
150168404Spjd
151185029Spjd/* ARGSUSED */
152168404Spjdvoid
153185029Spjdzfs_acl_byteswap(void *buf, size_t size)
154185029Spjd{
155185029Spjd	zfs_ace_byteswap(buf, size, B_TRUE);
156185029Spjd}
157185029Spjd
158185029Spjdvoid
159168404Spjdzfs_znode_byteswap(void *buf, size_t size)
160168404Spjd{
161168404Spjd	znode_phys_t *zp = buf;
162168404Spjd
163168404Spjd	ASSERT(size >= sizeof (znode_phys_t));
164168404Spjd
165168404Spjd	zp->zp_crtime[0] = BSWAP_64(zp->zp_crtime[0]);
166168404Spjd	zp->zp_crtime[1] = BSWAP_64(zp->zp_crtime[1]);
167168404Spjd	zp->zp_atime[0] = BSWAP_64(zp->zp_atime[0]);
168168404Spjd	zp->zp_atime[1] = BSWAP_64(zp->zp_atime[1]);
169168404Spjd	zp->zp_mtime[0] = BSWAP_64(zp->zp_mtime[0]);
170168404Spjd	zp->zp_mtime[1] = BSWAP_64(zp->zp_mtime[1]);
171168404Spjd	zp->zp_ctime[0] = BSWAP_64(zp->zp_ctime[0]);
172168404Spjd	zp->zp_ctime[1] = BSWAP_64(zp->zp_ctime[1]);
173168404Spjd	zp->zp_gen = BSWAP_64(zp->zp_gen);
174168404Spjd	zp->zp_mode = BSWAP_64(zp->zp_mode);
175168404Spjd	zp->zp_size = BSWAP_64(zp->zp_size);
176168404Spjd	zp->zp_parent = BSWAP_64(zp->zp_parent);
177168404Spjd	zp->zp_links = BSWAP_64(zp->zp_links);
178168404Spjd	zp->zp_xattr = BSWAP_64(zp->zp_xattr);
179168404Spjd	zp->zp_rdev = BSWAP_64(zp->zp_rdev);
180168404Spjd	zp->zp_flags = BSWAP_64(zp->zp_flags);
181168404Spjd	zp->zp_uid = BSWAP_64(zp->zp_uid);
182168404Spjd	zp->zp_gid = BSWAP_64(zp->zp_gid);
183185029Spjd	zp->zp_zap = BSWAP_64(zp->zp_zap);
184168404Spjd	zp->zp_pad[0] = BSWAP_64(zp->zp_pad[0]);
185168404Spjd	zp->zp_pad[1] = BSWAP_64(zp->zp_pad[1]);
186168404Spjd	zp->zp_pad[2] = BSWAP_64(zp->zp_pad[2]);
187168404Spjd
188168404Spjd	zp->zp_acl.z_acl_extern_obj = BSWAP_64(zp->zp_acl.z_acl_extern_obj);
189185029Spjd	zp->zp_acl.z_acl_size = BSWAP_32(zp->zp_acl.z_acl_size);
190168404Spjd	zp->zp_acl.z_acl_version = BSWAP_16(zp->zp_acl.z_acl_version);
191185029Spjd	zp->zp_acl.z_acl_count = BSWAP_16(zp->zp_acl.z_acl_count);
192185029Spjd	if (zp->zp_acl.z_acl_version == ZFS_ACL_VERSION) {
193185029Spjd		zfs_acl_byteswap((void *)&zp->zp_acl.z_ace_data[0],
194185029Spjd		    ZFS_ACE_SPACE);
195207683Smarius	} else {
196185029Spjd		zfs_oldace_byteswap((ace_t *)&zp->zp_acl.z_ace_data[0],
197185029Spjd		    ACE_SLOT_CNT);
198207683Smarius	}
199168404Spjd}
200