]> git.saurik.com Git - apple/xnu.git/blob - bsd/ufs/ufs/ufs_attrlist.c
967bd116e910304a5d7185ba32247262d2ea1e9b
[apple/xnu.git] / bsd / ufs / ufs / ufs_attrlist.c
1 /*
2 * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
14 * agreement.
15 *
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
18 * file.
19 *
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
27 *
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
29 */
30
31 /*
32 * ufs_attrlist.c - UFS attribute list processing
33 *
34 * Copyright (c) 2002, Apple Computer, Inc. All Rights Reserved.
35 */
36
37 #include <sys/types.h>
38 #include <sys/systm.h>
39 #include <sys/vnode_internal.h>
40 #include <sys/malloc.h>
41 #include <sys/attr.h>
42 #include <sys/kernel.h>
43 #include <sys/kauth.h>
44
45 #include <ufs/ufs/dinode.h>
46 #include <ufs/ffs/fs.h>
47 #include <sys/mount_internal.h>
48 #include "ufsmount.h"
49
50 static char ufs_label_magic[4] = UFS_LABEL_MAGIC;
51
52 /* Copied from diskdev_cmds/disklib/ufslabel.c */
53 typedef union {
54 char c[2];
55 u_short s;
56 } short_union_t;
57
58 /* Copied from diskdev_cmds/disklib/ufslabel.c */
59 typedef union {
60 u_short s[2];
61 long l;
62 } long_union_t;
63
64 /* Copied from diskdev_cmds/disklib/ufslabel.c */
65 static __inline__ void
66 reduce(int *sum)
67 {
68 long_union_t l_util;
69
70 l_util.l = *sum;
71 *sum = l_util.s[0] + l_util.s[1];
72 if (*sum > 65535)
73 *sum -= 65535;
74 return;
75 }
76
77 /* Copied from diskdev_cmds/disklib/ufslabel.c */
78 __private_extern__ unsigned short
79 ul_cksum(void *data, int len)
80 {
81 u_short *w;
82 int sum;
83
84 sum = 0;
85 w = (u_short *)data;
86 while ((len -= 32) >= 0) {
87 sum += w[0]; sum += w[1];
88 sum += w[2]; sum += w[3];
89 sum += w[4]; sum += w[5];
90 sum += w[6]; sum += w[7];
91 sum += w[8]; sum += w[9];
92 sum += w[10]; sum += w[11];
93 sum += w[12]; sum += w[13];
94 sum += w[14]; sum += w[15];
95 w += 16;
96 }
97 len += 32;
98 while ((len -= 8) >= 0) {
99 sum += w[0]; sum += w[1];
100 sum += w[2]; sum += w[3];
101 w += 4;
102 }
103 len += 8;
104 if (len) {
105 reduce(&sum);
106 while ((len -= 2) >= 0) {
107 sum += *w++;
108 }
109 }
110 if (len == -1) { /* odd-length data */
111 short_union_t s_util;
112
113 s_util.s = 0;
114 s_util.c[0] = *((char *)w);
115 s_util.c[1] = 0;
116 sum += s_util.s;
117 }
118 reduce(&sum);
119 return (~sum & 0xffff);
120 }
121
122 /* Adapted from diskdev_cmds/disklib/ufslabel.c */
123 __private_extern__ boolean_t
124 ufs_label_check(struct ufslabel *ul_p)
125 {
126 u_int16_t calc;
127 u_int16_t checksum;
128
129 if (bcmp(&ul_p->ul_magic, ufs_label_magic,
130 sizeof(ul_p->ul_magic))) {
131 #ifdef DEBUG
132 printf("ufslabel_check: label has bad magic number\n");
133 #endif
134 return (FALSE);
135 }
136 if (ntohl(ul_p->ul_version) != UFS_LABEL_VERSION) {
137 #ifdef DEBUG
138 printf("ufslabel_check: label has incorect version %d "
139 "(should be %d)\n", ntohl(ul_p->ul_version),
140 UFS_LABEL_VERSION);
141 #endif
142 return (FALSE);
143 }
144 if (ntohs(ul_p->ul_namelen) > UFS_MAX_LABEL_NAME) {
145 #ifdef DEBUG
146 printf("ufslabel_check: name length %d is too big (> %d)\n",
147 ntohs(ul_p->ul_namelen), UFS_MAX_LABEL_NAME);
148 #endif
149 return (FALSE);
150 }
151
152 checksum = ul_p->ul_checksum; /* Remember previous checksum. */
153 ul_p->ul_checksum = 0;
154 calc = ul_cksum(ul_p, sizeof(*ul_p));
155 if (calc != checksum) {
156 #ifdef DEBUG
157 printf("ufslabel_check: label checksum %x (should be %x)\n",
158 checksum, calc);
159 #endif
160 return (FALSE);
161 }
162 return (TRUE);
163 }
164
165 __private_extern__ void
166 ufs_label_init(struct ufslabel *ul_p)
167 {
168 struct timeval tv;
169
170 microtime(&tv);
171
172 bzero(ul_p, sizeof(*ul_p));
173 ul_p->ul_version = htonl(UFS_LABEL_VERSION);
174 bcopy(ufs_label_magic, &ul_p->ul_magic, sizeof(ul_p->ul_magic));
175 ul_p->ul_time = htonl(tv.tv_sec);
176 }
177