Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/fs/hsfs/hsfs_subr.c
+++ new/usr/src/uts/common/fs/hsfs/hsfs_subr.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Miscellaneous support subroutines for High Sierra filesystem
23 23 *
24 24 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
25 25 * Use is subject to license terms.
26 26 */
27 27
28 -#pragma ident "%Z%%M% %I% %E% SMI"
29 -
30 28 #include <sys/types.h>
31 29 #include <sys/param.h>
32 30 #include <sys/time.h>
33 31 #include <sys/cmn_err.h>
34 32 #include <sys/systm.h>
35 33 #include <sys/sysmacros.h>
36 34 #include <sys/buf.h>
37 35 #include <sys/conf.h>
38 36 #include <sys/user.h>
39 37 #include <sys/vfs.h>
40 38 #include <sys/vnode.h>
41 39 #include <sys/proc.h>
42 40 #include <sys/debug.h>
43 41 #include <sys/kmem.h>
44 42 #include <sys/uio.h>
45 43 #include <vm/hat.h>
46 44 #include <vm/as.h>
47 45 #include <vm/seg.h>
48 46 #include <vm/page.h>
49 47 #include <vm/pvn.h>
50 48 #include <vm/seg_map.h>
51 49 #include <sys/swap.h>
52 50 #include <vm/seg_kmem.h>
53 51
54 52 #include <sys/fs/hsfs_spec.h>
55 53 #include <sys/fs/hsfs_node.h>
56 54 #include <sys/fs/hsfs_impl.h>
57 55
58 56 #define THE_EPOCH 1970
59 57 #define END_OF_TIME 2099
60 58 extern int hsfs_lostpage;
61 59
62 60 #ifdef __STDC__
63 61 static time_t hs_date_to_gmtime(int year, int mon, int day, int gmtoff);
64 62 #else
65 63 static time_t hs_date_to_gmtime();
66 64 #endif
67 65
68 66 /*
69 67 * Table used in logging non-fatal errors which should be recorded
↓ open down ↓ |
30 lines elided |
↑ open up ↑ |
70 68 * once per mount. Indexed by HSFS_ERR values (defined in hsfs_node.h).
71 69 */
72 70 struct hsfs_error {
73 71 char *hdr_text; /* msg prefix: general error type */
74 72 /* must contain %s for mnt pt */
75 73 char *err_text; /* specific error message */
76 74 uchar_t multiple; /* > 1 such error per fs possible? */
77 75 uchar_t n_printf_args; /* if err_text printf-like, # addtl args */
78 76 } hsfs_error[] = {
79 77 /* HSFS_ERR_TRAILING_JUNK */
80 - "hsfs: Warning: the file system mounted on %s "
78 + { "hsfs: Warning: the file system mounted on %s "
81 79 "does not conform to the ISO-9660 specification:",
82 - "trailing blanks or null characters in file or directory name.\n",
83 - 1, 0,
80 + "trailing blanks or null characters in file or directory name.\n",
81 + 1, 0 },
84 82 /* HSFS_ERR_LOWER_CASE_NM */
85 - "hsfs: Warning: the file system mounted on %s "
83 + { "hsfs: Warning: the file system mounted on %s "
86 84 "does not conform to the ISO-9660 specification:",
87 - "lower case characters in file or directory name.\n",
88 - 1, 0,
85 + "lower case characters in file or directory name.\n",
86 + 1, 0 },
89 87 /* HSFS_ERR_BAD_ROOT_DIR */
90 - "hsfs: Warning: the file system mounted on %s "
88 + { "hsfs: Warning: the file system mounted on %s "
91 89 "does not conform to the ISO-9660 specification:",
92 - "invalid root directory.\n",
93 - 0, 0,
90 + "invalid root directory.\n",
91 + 0, 0 },
94 92 /* HSFS_ERR_UNSUP_TYPE */
95 - "hsfs: Warning: the file system mounted on %s "
93 + { "hsfs: Warning: the file system mounted on %s "
96 94 "contains a file or directory with an unsupported type:",
97 - " 0x%x.\n",
98 - 1, 1,
95 + " 0x%x.\n",
96 + 1, 1 },
99 97 /* HSFS_ERR_BAD_FILE_LEN */
100 - "hsfs: Warning: file system mounted on %s "
98 + { "hsfs: Warning: file system mounted on %s "
101 99 "does not conform to the ISO-9660 specification:",
102 - "file name length greater than max allowed\n",
103 - 1, 0,
100 + "file name length greater than max allowed\n",
101 + 1, 0 },
104 102 /* HSFS_ERR_BAD_JOLIET_FILE_LEN */
105 - "hsfs: Warning: file system mounted on %s "
103 + { "hsfs: Warning: file system mounted on %s "
106 104 "does not conform to the Joliet specification:",
107 - "file name length greater than max allowed\n",
108 - 1, 0,
105 + "file name length greater than max allowed\n",
106 + 1, 0 },
109 107 /* HSFS_ERR_TRUNC_JOLIET_FILE_LEN */
110 - "hsfs: Warning: file system mounted on %s "
108 + { "hsfs: Warning: file system mounted on %s "
111 109 "does not conform to the Joliet specification:",
112 - "file name length greater than MAXNAMELEN (truncated)\n",
113 - 1, 0,
110 + "file name length greater than MAXNAMELEN (truncated)\n",
111 + 1, 0 },
114 112 /* HSFS_ERR_BAD_DIR_ENTRY */
115 - "hsfs: Warning: file system mounted on %s "
113 + { "hsfs: Warning: file system mounted on %s "
116 114 "has inconsistent data:",
117 - "invalid directory or file name length (ignored)\n",
118 - 1, 0,
115 + "invalid directory or file name length (ignored)\n",
116 + 1, 0 },
119 117 /* HSFS_ERR_NEG_SUA_LEN */
120 - "hsfs: Warning: file system mounted on %s "
118 + { "hsfs: Warning: file system mounted on %s "
121 119 "has inconsistent Rock Ridge data:",
122 - "negative SUA len\n",
123 - 1, 0,
120 + "negative SUA len\n",
121 + 1, 0 },
124 122 /* HSFS_ERR_BAD_SUA_LEN */
125 - "hsfs: Warning: file system mounted on %s "
123 + { "hsfs: Warning: file system mounted on %s "
126 124 "has inconsistent Rock Ridge data:",
127 - "SUA len too big\n",
128 - 1, 0,
125 + "SUA len too big\n",
126 + 1, 0 }
129 127 };
130 128
131 129 /*
132 130 * Local datatype for defining tables of (Offset, Name) pairs for
133 131 * kstats.
134 132 */
135 133 typedef struct {
136 134 offset_t index;
137 135 char *name;
138 136 } hsfs_ksindex_t;
139 137
140 138 static const hsfs_ksindex_t hsfs_kstats[] = {
141 139 { 0, "mountpoint" },
142 140 { 1, "pages_lost" },
143 141 { 2, "physical_read_pages" },
144 142 { 3, "cache_read_pages" },
145 143 { 4, "readahead_pages" },
146 144 { 5, "coalesced_pages" },
147 145 { 6, "total_pages_requested" },
148 146 {-1, NULL }
149 147 };
150 148
151 149 /*
152 150 * hs_parse_dirdate
153 151 *
154 152 * Parse the short 'directory-format' date into a Unix timeval.
155 153 * This is the date format used in Directory Entries.
156 154 *
157 155 * If the date is not representable, make something up.
158 156 */
159 157 void
160 158 hs_parse_dirdate(dp, tvp)
161 159 uchar_t *dp;
162 160 struct timeval *tvp;
163 161 {
164 162 int year, month, day, hour, minute, sec, gmtoff;
165 163
166 164 year = HDE_DATE_YEAR(dp);
167 165 month = HDE_DATE_MONTH(dp);
168 166 day = HDE_DATE_DAY(dp);
169 167 hour = HDE_DATE_HOUR(dp);
170 168 minute = HDE_DATE_MIN(dp);
171 169 sec = HDE_DATE_SEC(dp);
172 170 gmtoff = HDE_DATE_GMTOFF(dp);
173 171
174 172 tvp->tv_usec = 0;
175 173 if (year < THE_EPOCH) {
176 174 tvp->tv_sec = 0;
177 175 } else {
178 176 tvp->tv_sec = hs_date_to_gmtime(year, month, day, gmtoff);
179 177 if (tvp->tv_sec != -1) {
180 178 tvp->tv_sec += ((hour * 60) + minute) * 60 + sec;
181 179 }
182 180 }
183 181
184 182 return;
185 183
186 184 }
187 185
188 186 /*
189 187 * hs_parse_longdate
190 188 *
191 189 * Parse the long 'user-oriented' date into a Unix timeval.
192 190 * This is the date format used in the Volume Descriptor.
193 191 *
194 192 * If the date is not representable, make something up.
195 193 */
196 194 void
197 195 hs_parse_longdate(dp, tvp)
198 196 uchar_t *dp;
199 197 struct timeval *tvp;
200 198 {
201 199 int year, month, day, hour, minute, sec, gmtoff;
202 200
203 201 year = HSV_DATE_YEAR(dp);
204 202 month = HSV_DATE_MONTH(dp);
205 203 day = HSV_DATE_DAY(dp);
206 204 hour = HSV_DATE_HOUR(dp);
207 205 minute = HSV_DATE_MIN(dp);
208 206 sec = HSV_DATE_SEC(dp);
209 207 gmtoff = HSV_DATE_GMTOFF(dp);
210 208
211 209 tvp->tv_usec = 0;
212 210 if (year < THE_EPOCH) {
213 211 tvp->tv_sec = 0;
214 212 } else {
215 213 tvp->tv_sec = hs_date_to_gmtime(year, month, day, gmtoff);
216 214 if (tvp->tv_sec != -1) {
217 215 tvp->tv_sec += ((hour * 60) + minute) * 60 + sec;
218 216 tvp->tv_usec = HSV_DATE_HSEC(dp) * 10000;
219 217 }
220 218 }
221 219
222 220 }
223 221
224 222 /* cumulative number of seconds per month, non-leap and leap-year versions */
225 223 static time_t cum_sec[] = {
226 224 0x0, 0x28de80, 0x4dc880, 0x76a700, 0x9e3400, 0xc71280,
227 225 0xee9f80, 0x1177e00, 0x1405c80, 0x167e980, 0x190c800, 0x1b85500
228 226 };
229 227 static time_t cum_sec_leap[] = {
230 228 0x0, 0x28de80, 0x4f1a00, 0x77f880, 0x9f8580, 0xc86400,
231 229 0xeff100, 0x118cf80, 0x141ae00, 0x1693b00, 0x1921980, 0x1b9a680
232 230 };
233 231 #define SEC_PER_DAY 0x15180
234 232 #define SEC_PER_YEAR 0x1e13380
235 233
236 234 /*
237 235 * hs_date_to_gmtime
238 236 *
239 237 * Convert year(1970-2099)/month(1-12)/day(1-31) to seconds-since-1970/1/1.
240 238 *
241 239 * Returns -1 if the date is out of range.
242 240 */
243 241 static time_t
244 242 hs_date_to_gmtime(year, mon, day, gmtoff)
245 243 int year;
246 244 int mon;
247 245 int day;
248 246 int gmtoff;
249 247 {
250 248 time_t sum;
251 249 time_t *cp;
252 250 int y;
253 251
254 252 if ((year < THE_EPOCH) || (year > END_OF_TIME) ||
255 253 (mon < 1) || (mon > 12) ||
256 254 (day < 1) || (day > 31))
257 255 return (-1);
258 256
259 257 /*
260 258 * Figure seconds until this year and correct for leap years.
261 259 * Note: 2000 is a leap year but not 2100.
262 260 */
263 261 y = year - THE_EPOCH;
264 262 sum = y * SEC_PER_YEAR;
265 263 sum += ((y + 1) / 4) * SEC_PER_DAY;
266 264 /*
267 265 * Point to the correct table for this year and
268 266 * add in seconds until this month.
269 267 */
270 268 cp = ((y + 2) % 4) ? cum_sec : cum_sec_leap;
271 269 sum += cp[mon - 1];
272 270 /*
273 271 * Add in seconds until 0:00 of this day.
274 272 * (days-per-month validation is not done here)
275 273 */
276 274 sum += (day - 1) * SEC_PER_DAY;
277 275 sum -= (gmtoff * 15 * 60);
278 276 return (sum);
279 277 }
280 278
281 279 /*
282 280 * Indicate whether the directory is valid.
283 281 */
284 282
285 283 int
286 284 hsfs_valid_dir(hd)
287 285 struct hs_direntry *hd;
288 286 {
289 287 /*
290 288 * check to see if this directory is not marked as a directory.
291 289 * check to see if data length is zero.
292 290 */
293 291
294 292 if (hd->ext_size == 0)
295 293 return (0);
296 294
297 295 if (hd->type != VDIR)
298 296 return (0);
299 297
300 298 return (1);
301 299 }
302 300
303 301
304 302
305 303 /*
306 304 * If we haven't complained about this error type yet, do.
307 305 */
308 306 void
309 307 hs_log_bogus_disk_warning(fsp, errtype, data)
310 308 struct hsfs *fsp;
311 309 int errtype;
312 310 uint_t data;
313 311 {
314 312
315 313 if (fsp->hsfs_err_flags & (1 << errtype))
316 314 return; /* already complained */
317 315
318 316 cmn_err(CE_NOTE, hsfs_error[errtype].hdr_text,
319 317 fsp->hsfs_fsmnt);
320 318
321 319 switch (hsfs_error[errtype].n_printf_args) {
322 320 case 0:
323 321 cmn_err(CE_CONT, hsfs_error[errtype].err_text);
324 322 break;
325 323 case 1:
326 324 cmn_err(CE_CONT, hsfs_error[errtype].err_text, data);
327 325 break;
328 326 default:
329 327 /* don't currently handle more than 1 arg */
330 328 cmn_err(CE_CONT, "unknown problem; internal error.\n");
331 329 }
332 330 cmn_err(CE_CONT,
333 331 "Due to this error, the file system may not be correctly interpreted.\n");
334 332 if (hsfs_error[errtype].multiple)
335 333 cmn_err(CE_CONT,
336 334 "Other such errors in this file system will be silently ignored.\n\n");
337 335 else
338 336 cmn_err(CE_CONT, "\n");
339 337
340 338 fsp->hsfs_err_flags |= (1 << errtype);
341 339 }
342 340
343 341 /*
344 342 * Callback from kstat framework. Grab a snapshot of the current hsfs
345 343 * counters and populate the kstats.
346 344 */
347 345 static int
348 346 hsfs_kstats_update(kstat_t *ksp, int flag)
349 347 {
350 348 struct hsfs *fsp;
351 349 kstat_named_t *knp;
352 350 uint64_t pages_lost;
353 351 uint64_t physical_read_bytes;
354 352 uint64_t cache_read_pages;
355 353 uint64_t readahead_bytes;
356 354 uint64_t coalesced_bytes;
357 355 uint64_t total_pages_requested;
358 356
359 357 if (flag != KSTAT_READ)
360 358 return (EACCES);
361 359
362 360 fsp = ksp->ks_private;
363 361 knp = ksp->ks_data;
364 362
365 363 mutex_enter(&(fsp->hqueue->strategy_lock));
366 364 mutex_enter(&(fsp->hqueue->hsfs_queue_lock));
367 365
368 366 cache_read_pages = fsp->cache_read_pages;
369 367 pages_lost = hsfs_lostpage;
370 368 physical_read_bytes = fsp->physical_read_bytes;
371 369 readahead_bytes = fsp->readahead_bytes;
372 370 coalesced_bytes = fsp->coalesced_bytes;
373 371 total_pages_requested = fsp->total_pages_requested;
374 372
375 373 mutex_exit(&(fsp->hqueue->strategy_lock));
376 374 mutex_exit(&(fsp->hqueue->hsfs_queue_lock));
377 375
378 376 knp++;
379 377 (knp++)->value.ui64 = pages_lost;
380 378 (knp++)->value.ui64 = howmany(physical_read_bytes, PAGESIZE);
381 379 (knp++)->value.ui64 = cache_read_pages;
382 380 (knp++)->value.ui64 = howmany(readahead_bytes, PAGESIZE);
383 381 (knp++)->value.ui64 = howmany(coalesced_bytes, PAGESIZE);
384 382 (knp++)->value.ui64 = total_pages_requested;
385 383
386 384 return (0);
387 385 }
388 386
389 387 /*
390 388 * Initialize hsfs kstats, which are all name value pairs with
391 389 * values being various counters.
392 390 */
393 391 static kstat_t *
394 392 hsfs_setup_named_kstats(struct hsfs *fsp, int fsid, char *name,
395 393 const hsfs_ksindex_t *ksip, int (*update)(kstat_t *, int))
396 394 {
397 395 kstat_t *ksp;
398 396 kstat_named_t *knp;
399 397 char *np;
400 398 char *mntpt = fsp->hsfs_fsmnt;
401 399 size_t size;
402 400
403 401 size = (sizeof (hsfs_kstats)) / (sizeof (hsfs_ksindex_t));
404 402 ksp = kstat_create("hsfs_fs", fsid, name, "hsfs",
405 403 KSTAT_TYPE_NAMED, size-1, KSTAT_FLAG_VIRTUAL);
406 404 if (ksp == NULL)
407 405 return (NULL);
408 406
409 407 ksp->ks_data = kmem_alloc(sizeof (kstat_named_t) * size, KM_SLEEP);
410 408 ksp->ks_private = fsp;
411 409 ksp->ks_update = update;
412 410 ksp->ks_data_size += strlen(mntpt) + 1;
413 411 knp = ksp->ks_data;
414 412 kstat_named_init(knp, ksip->name, KSTAT_DATA_STRING);
415 413 kstat_named_setstr(knp, mntpt);
416 414 knp++;
417 415 ksip++;
418 416
419 417 for (; (np = ksip->name) != NULL; ++knp, ++ksip) {
420 418 kstat_named_init(knp, np, KSTAT_DATA_UINT64);
421 419 }
422 420 kstat_install(ksp);
423 421
424 422 return (ksp);
425 423 }
426 424
427 425 void
428 426 hsfs_init_kstats(struct hsfs *fsp, int fsid)
429 427 {
430 428 fsp->hsfs_kstats = hsfs_setup_named_kstats(fsp, fsid, "hsfs_read_stats",
431 429 hsfs_kstats, hsfs_kstats_update);
432 430 }
433 431
434 432 void
435 433 hsfs_fini_kstats(struct hsfs *fsp)
436 434 {
437 435 void *data;
438 436
439 437 if (fsp->hsfs_kstats != NULL) {
440 438 data = fsp->hsfs_kstats->ks_data;
441 439 kstat_delete(fsp->hsfs_kstats);
442 440 kmem_free(data, sizeof (kstat_named_t) *
443 441 (sizeof (hsfs_kstats)) / (sizeof (hsfs_ksindex_t)));
444 442 }
445 443 fsp->hsfs_kstats = NULL;
446 444 }
↓ open down ↓ |
308 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX