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