1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 #include <sys/types.h>
26 #include <sys/t_lock.h>
27 #include <sys/param.h>
28 #include <sys/time.h>
29 #include <sys/systm.h>
30 #include <sys/sysmacros.h>
31 #include <sys/resource.h>
32 #include <sys/signal.h>
33 #include <sys/cred.h>
34 #include <sys/user.h>
35 #include <sys/buf.h>
36 #include <sys/vfs.h>
37 #include <sys/stat.h>
38 #include <sys/vnode.h>
39 #include <sys/mode.h>
40 #include <sys/proc.h>
41 #include <sys/disp.h>
42 #include <sys/file.h>
43 #include <sys/fcntl.h>
44 #include <sys/flock.h>
45 #include <sys/kmem.h>
46 #include <sys/uio.h>
47 #include <sys/dnlc.h>
48 #include <sys/conf.h>
49 #include <sys/errno.h>
50 #include <sys/mman.h>
51 #include <sys/fbuf.h>
52 #include <sys/pathname.h>
53 #include <sys/debug.h>
54 #include <sys/vmsystm.h>
55 #include <sys/cmn_err.h>
56 #include <sys/dirent.h>
57 #include <sys/errno.h>
58 #include <sys/modctl.h>
59 #include <sys/statvfs.h>
60 #include <sys/mount.h>
61 #include <sys/sunddi.h>
62 #include <sys/bootconf.h>
63 #include <sys/policy.h>
64
65 #include <vm/hat.h>
66 #include <vm/page.h>
67 #include <vm/pvn.h>
68 #include <vm/as.h>
69 #include <vm/seg.h>
70 #include <vm/seg_map.h>
71 #include <vm/seg_kmem.h>
72 #include <vm/seg_vn.h>
73 #include <vm/rm.h>
74 #include <vm/page.h>
75 #include <sys/swap.h>
76
77
78 #include <fs/fs_subr.h>
79
80
81 #include <sys/fs/udf_volume.h>
82 #include <sys/fs/udf_inode.h>
83
84 int32_t ud_trace;
85
86 /*
87 * HASH chains and mutex
88 */
89 extern union ihead ud_ihead[UD_HASH_SZ];
90 extern kmutex_t ud_icache_lock;
91
92
93 extern kmutex_t ud_sync_busy;
94 /*
95 * udf_vfs list manipulation routines
96 */
97 extern kmutex_t udf_vfs_mutex;
98 extern struct udf_vfs *udf_vfs_instances;
99
100 /*
101 * Used to verify that a given entry on the udf_instances list (see below)
102 * still refers to a mounted file system.
103 *
104 * XXX: This is a crock that substitutes for proper locking to coordinate
105 * updates to and uses of the entries in udf_instances.
106 */
107 struct check_node {
108 struct vfs *vfsp;
109 struct udf_vfs *udf_vfs;
110 dev_t vfs_dev;
111 };
112
113 vfs_t *ud_still_mounted(struct check_node *);
114 void ud_checkclean(struct vfs *,
115 struct udf_vfs *, dev_t, time_t);
116 int32_t ud_icheck(struct udf_vfs *);
117 void ud_flushi(int32_t);
118
119 /*
120 * Link udf_vfsp in at the head of the list of udf_vfs_instances.
121 */
122 void
ud_vfs_add(struct udf_vfs * udf_vfsp)123 ud_vfs_add(struct udf_vfs *udf_vfsp)
124 {
125 mutex_enter(&udf_vfs_mutex);
126 udf_vfsp->udf_next = udf_vfs_instances;
127 udf_vfs_instances = udf_vfsp;
128 mutex_exit(&udf_vfs_mutex);
129 }
130
131 /*
132 * Remove udf_vfsp from the list of udf_vfs_instances.
133 *
134 * Does no error checking; udf_vfsp is assumed to actually be on the list.
135 */
136 void
ud_vfs_remove(struct udf_vfs * udf_vfsp)137 ud_vfs_remove(struct udf_vfs *udf_vfsp)
138 {
139 struct udf_vfs **delpt = &udf_vfs_instances;
140
141 mutex_enter(&udf_vfs_mutex);
142 for (; *delpt != NULL; delpt = &((*delpt)->udf_next)) {
143 if (*delpt == udf_vfsp) {
144 *delpt = udf_vfsp->udf_next;
145 udf_vfsp->udf_next = NULL;
146 break;
147 }
148 }
149 mutex_exit(&udf_vfs_mutex);
150 }
151
152 /*
153 * Search for the prn in the array
154 * of partitions and translate
155 * to the disk block number
156 */
157 daddr_t
ud_xlate_to_daddr(struct udf_vfs * udf_vfsp,uint16_t prn,uint32_t blkno,int32_t nblks,uint32_t * count)158 ud_xlate_to_daddr(struct udf_vfs *udf_vfsp,
159 uint16_t prn, uint32_t blkno, int32_t nblks, uint32_t *count)
160 {
161 int32_t i;
162 struct ud_map *map;
163 struct ud_part *ud_parts;
164 uint32_t lblkno, retblkno = 0, *addr;
165 uint32_t begin_req, end_req;
166 uint32_t begin_bad, end_bad;
167
168 ud_printf("ud_xlate_to_daddr\n");
169
170 /* Is prn valid */
171 if (prn < udf_vfsp->udf_nmaps) {
172 map = &(udf_vfsp->udf_maps[prn]);
173
174 if (map->udm_flags == UDM_MAP_VPM) {
175 /*
176 * Map is Virtual Parition Map
177 * first check for the appropriate
178 * table and then return the converted
179 * block number
180 */
181 for (i = 0; i < map->udm_nent; i++) {
182 if (blkno < map->udm_count[i]) {
183 addr = map->udm_addr[i];
184 lblkno = SWAP_32(addr[blkno]);
185 *count = 1;
186 break;
187 } else {
188 blkno -= map->udm_count[i];
189 }
190 }
191 } else if (map->udm_flags == UDM_MAP_SPM) {
192 struct stbl *stbl;
193 struct stbl_entry *te;
194 int32_t entry_count;
195
196 /*
197 * Map type is Sparable Parition Map
198 * if the block is in the map
199 * return the translated block
200 * other wise use the regular
201 * partition stuff
202 */
203 begin_req = blkno;
204 end_req = begin_req + nblks;
205
206 stbl = (struct stbl *)map->udm_spaddr[0];
207 te = (struct stbl_entry *)&stbl->stbl_entry;
208 entry_count = SWAP_16(stbl->stbl_len);
209
210 for (i = 0; i < entry_count; i++, te++) {
211 begin_bad = SWAP_32(te->sent_ol);
212 end_bad = begin_bad + map->udm_plen;
213
214 /*
215 * Either unmapped or reserved
216 * or defective. need not consider
217 */
218 if (begin_bad >= (uint32_t)0xFFFFFFF0) {
219 continue;
220 }
221 if ((end_req < begin_bad) ||
222 (begin_req >= end_bad)) {
223 continue;
224 }
225
226 if (begin_req < begin_bad) {
227 ASSERT(end_req >= begin_bad);
228 end_req = begin_bad;
229 } else {
230 retblkno = SWAP_32(te->sent_ml) +
231 begin_req - begin_bad;
232 if (end_req < end_bad) {
233 *count = end_req - begin_req;
234 } else {
235 *count = end_bad - begin_req;
236 }
237 goto end;
238 }
239 }
240
241 lblkno = blkno;
242 *count = end_req - begin_req;
243 } else {
244 /*
245 * regular partition
246 */
247 lblkno = blkno;
248 *count = nblks;
249 }
250 ud_parts = udf_vfsp->udf_parts;
251 for (i = 0; i < udf_vfsp->udf_npart; i++) {
252 if (map->udm_pn == ud_parts->udp_number) {
253 /*
254 * Check if the block is inside
255 * the partition or not
256 */
257 if (lblkno >= ud_parts->udp_length) {
258 retblkno = 0;
259 } else {
260 retblkno = ud_parts->udp_start + lblkno;
261 }
262 goto end;
263 }
264 ud_parts ++;
265 }
266 }
267
268 end:
269 return (retblkno);
270 }
271
272 #ifdef UNDEF
273 uint32_t
ud_xlate_to_addr(struct udf_vfs * udf_vfsp,uint16_t prn,daddr_t blkno,int32_t lad)274 ud_xlate_to_addr(struct udf_vfs *udf_vfsp,
275 uint16_t prn, daddr_t blkno, int32_t lad)
276 {
277 int32_t i;
278 struct ud_part *ud_parts;
279
280 ud_printf("ud_xlate_to_addr\n");
281
282 if (lad == 0) {
283 return (blkno);
284 }
285 ud_parts = udf_vfsp->udf_parts;
286 for (i = 0; i < udf_vfsp->udf_npart; i++) {
287 if (prn == ud_parts->udp_number) {
288 return (blkno - ud_parts->udp_start);
289 }
290 }
291 return (0);
292 }
293 #endif
294
295 /*
296 * Directories do not have holes
297 */
298 int32_t
ud_ip_off2bno(struct ud_inode * ip,uint32_t offset,uint32_t * bno)299 ud_ip_off2bno(struct ud_inode *ip, uint32_t offset, uint32_t *bno)
300 {
301 int32_t i, error;
302 struct icb_ext *iext;
303
304 ASSERT(ip->i_type == VDIR);
305
306 if (ip->i_desc_type == ICB_FLAG_ONE_AD) {
307 *bno = ip->i_icb_block;
308 return (0);
309 }
310
311 if ((error = ud_read_icb_till_off(ip, (u_offset_t)offset)) != 0) {
312 return (error);
313 }
314
315 for (i = 0; i < ip->i_ext_used; i++) {
316 iext = &ip->i_ext[i];
317 if ((iext->ib_offset <= offset) &&
318 (offset < (iext->ib_offset + iext->ib_count))) {
319 *bno = iext->ib_block +
320 ((offset - iext->ib_offset) >>
321 ip->i_udf->udf_l2b_shift);
322 break;
323 }
324 }
325 return (0);
326 }
327
328 static uint32_t cum_sec[] = {
329 0x0, 0x28de80, 0x4dc880, 0x76a700, 0x9e3400, 0xc71280,
330 0xee9f80, 0x1177e00, 0x1405c80, 0x167e980, 0x190c800, 0x1b85500
331 };
332 static uint32_t cum_sec_leap[] = {
333 0x0, 0x28de80, 0x4f1a00, 0x77f880, 0x9f8580, 0xc86400,
334 0xeff100, 0x118cf80, 0x141ae00, 0x1693b00, 0x1921980, 0x1b9a680
335 };
336
337 #define DAYS_PER_YEAR 365
338
339 #define SEC_PER_DAY 0x15180
340 #define SEC_PER_YEAR 0x1e13380
341
342
343 /* This holds good till yr 2100 */
344 void
ud_dtime2utime(struct timespec32 * utime,struct tstamp const * dtime)345 ud_dtime2utime(struct timespec32 *utime,
346 struct tstamp const *dtime)
347 {
348 int16_t year, tzone;
349 int32_t sec;
350 uint32_t *cp;
351
352 ud_printf("ud_dtime2utime\n");
353
354 year = SWAP_16(dtime->ts_year);
355 cp = (year % 4) ? cum_sec : cum_sec_leap;
356
357 utime->tv_sec = cp[dtime->ts_month - 1];
358 utime->tv_sec += (dtime->ts_day - 1) * SEC_PER_DAY;
359 utime->tv_sec += ((dtime->ts_hour * 60) +
360 dtime->ts_min) * 60 +
361 dtime->ts_sec;
362
363 tzone = SWAP_16(dtime->ts_tzone);
364 if ((tzone & TMODE) == 0x1000) {
365 /* Local time */
366 if ((tzone & TINVALID) != TINVALID) {
367 if (tzone & TSIGN) {
368 /*
369 * Sign extend the tzone
370 */
371 sec = tzone | 0xFFFFF000;
372 } else {
373 sec = tzone & TOFFSET;
374 }
375 sec *= 60;
376 utime->tv_sec -= sec;
377 }
378 }
379
380 utime->tv_nsec = ((((dtime->ts_csec * 100) +
381 dtime->ts_husec) * 100) +
382 dtime->ts_usec) * 1000;
383 if (year >= 1970) {
384 utime->tv_sec += (year - 1970) * SEC_PER_YEAR;
385 utime->tv_sec += ((year - 1969) / 4) * SEC_PER_DAY;
386 } else {
387 utime->tv_sec = ((1970 - year) * SEC_PER_YEAR +
388 ((1972 - year) / 4) * SEC_PER_DAY -
389 utime->tv_sec) * -1;
390 if (utime->tv_nsec) {
391 utime->tv_sec++;
392 utime->tv_nsec = 1000 * 1000 * 1000 - utime->tv_nsec;
393 }
394 }
395 }
396
397 void
ud_utime2dtime(struct timespec32 const * utime,struct tstamp * dtime)398 ud_utime2dtime(struct timespec32 const *utime,
399 struct tstamp *dtime)
400 {
401 time32_t sec = utime->tv_sec;
402 int32_t usec = utime->tv_nsec / 1000;
403 uint32_t lyrs, nyrs, dummy;
404 uint32_t *cp;
405 int32_t before = 0;
406
407 ud_printf("ud_utime2dtime\n");
408
409 if (sec < 0) {
410 before = 1;
411 sec = sec * -1;
412 if (usec) {
413 sec = sec + 1;
414 usec = 1000 * 1000 - usec;
415 }
416 }
417
418 dtime->ts_csec = usec / 10000;
419 usec %= 10000;
420 dtime->ts_husec = usec / 100;
421 dtime->ts_usec = usec % 100;
422
423 nyrs = sec / SEC_PER_YEAR;
424 if (before == 0) {
425 lyrs = (nyrs + 1) / 4;
426 } else {
427 lyrs = (nyrs + 2) / 4;
428 }
429 if (nyrs != ((sec - (lyrs * SEC_PER_DAY)) / SEC_PER_YEAR)) {
430 nyrs--;
431 if (before == 0) {
432 lyrs = (nyrs + 1) / 4;
433 } else {
434 lyrs = (nyrs + 2) / 4;
435 }
436 }
437 sec -= nyrs * SEC_PER_YEAR + lyrs * SEC_PER_DAY;
438
439 if (before == 1) {
440 nyrs = 1970 - nyrs;
441 if (sec != 0) {
442 nyrs --;
443 if ((nyrs % 4) == 0) {
444 sec = SEC_PER_YEAR + SEC_PER_DAY - sec;
445 } else {
446 sec = SEC_PER_YEAR - sec;
447 }
448 }
449 } else {
450 nyrs += 1970;
451 }
452 cp = (nyrs % 4) ? cum_sec : cum_sec_leap;
453 dummy = sec / (SEC_PER_DAY * 29);
454 if (dummy > 11) {
455 dummy = 11;
456 }
457 if (sec < cp[dummy]) {
458 dummy--;
459 }
460 dtime->ts_year = SWAP_16(nyrs);
461 dtime->ts_month = dummy;
462 sec -= cp[dtime->ts_month];
463 dtime->ts_month++;
464 dtime->ts_day = sec / SEC_PER_DAY;
465 sec -= dtime->ts_day * SEC_PER_DAY;
466 dtime->ts_day++;
467 dtime->ts_hour = sec / SECS_PER_HOUR;
468 sec -= dtime->ts_hour * SECS_PER_HOUR;
469 dtime->ts_min = sec / SECS_PER_MIN;
470 sec -= dtime->ts_min * SECS_PER_MIN;
471 dtime->ts_sec = (uint8_t)sec;
472
473 /* GMT offset is 0 */
474 dtime->ts_tzone = SWAP_16(0x1000);
475 }
476
477
478 int32_t
ud_syncip(struct ud_inode * ip,int32_t flags,int32_t waitfor)479 ud_syncip(struct ud_inode *ip, int32_t flags, int32_t waitfor)
480 {
481 int32_t error;
482 struct vnode *vp = ITOV(ip);
483
484 ud_printf("ud_syncip\n");
485
486 if (ip->i_udf == NULL) {
487 return (0);
488 }
489
490 if (!vn_has_cached_data(vp) || (vp->v_type == VCHR)) {
491 error = 0;
492 } else {
493 rw_exit(&ip->i_contents);
494 error = VOP_PUTPAGE(vp, (offset_t)0,
495 (uint32_t)0, flags, CRED(), NULL);
496 rw_enter(&ip->i_contents, RW_WRITER);
497 }
498
499 if (ip->i_flag & (IUPD |IACC | ICHG | IMOD)) {
500 ud_iupdat(ip, waitfor);
501 }
502
503 return (error);
504 }
505
506
507 /* ARGSUSED */
508 int32_t
ud_fbwrite(struct fbuf * fbp,struct ud_inode * ip)509 ud_fbwrite(struct fbuf *fbp, struct ud_inode *ip)
510 {
511 ud_printf("ud_fbwrite\n");
512
513 ASSERT(fbp != NULL);
514
515 return (fbwrite(fbp));
516 }
517
518
519 void
ud_sbwrite(struct udf_vfs * udf_vfsp)520 ud_sbwrite(struct udf_vfs *udf_vfsp)
521 {
522 struct log_vol_int_desc *lvid;
523 struct ud_part *ud_part;
524 struct lvid_iu *iu;
525 uint32_t *temp;
526 int32_t i, c;
527
528 ud_printf("ud_sbwrite\n");
529 ASSERT(udf_vfsp);
530 ASSERT(MUTEX_HELD(&udf_vfsp->udf_lock));
531
532 /*
533 * updatable information in the superblock
534 * integrity type, udf_maxuniq, udf_nfiles, udf_ndirs
535 * udp_nfree in lvid
536 */
537 lvid = (struct log_vol_int_desc *)udf_vfsp->udf_lvid;
538 if (udf_vfsp->udf_clean == UDF_DIRTY) {
539 lvid->lvid_int_type = SWAP_32(LOG_VOL_OPEN_INT);
540 } else {
541 lvid->lvid_int_type = SWAP_32(LOG_VOL_CLOSE_INT);
542 }
543 lvid->lvid_uniqid = SWAP_64(udf_vfsp->udf_maxuniq);
544 temp = lvid->lvid_fst;
545 c = SWAP_32(lvid->lvid_npart);
546 ud_part = udf_vfsp->udf_parts;
547 for (i = 0; i < c; i++) {
548 temp[i] = SWAP_32(ud_part->udp_nfree);
549 ud_part++;
550 }
551 iu = (struct lvid_iu *)(temp + c * 2);
552 iu->lvidiu_nfiles = SWAP_32(udf_vfsp->udf_nfiles);
553 iu->lvidiu_ndirs = SWAP_32(udf_vfsp->udf_ndirs);
554
555 ud_update_regid(&iu->lvidiu_regid);
556
557 ud_make_tag(udf_vfsp, &lvid->lvid_tag,
558 UD_LOG_VOL_INT, udf_vfsp->udf_iseq_loc,
559 sizeof (struct log_vol_int_desc) - 8 +
560 8 * udf_vfsp->udf_npart +
561 SWAP_32(lvid->lvid_liu));
562
563 /*
564 * Don't release the buffer after writing to the disk
565 */
566 bwrite2(udf_vfsp->udf_iseq);
567 }
568
569
570 int32_t
ud_sync_indir(struct ud_inode * ip)571 ud_sync_indir(struct ud_inode *ip)
572 {
573 int32_t elen;
574
575 ud_printf("ud_sync_indir\n");
576
577 if (ip->i_desc_type == ICB_FLAG_ONE_AD) {
578 return (0);
579 } else if (ip->i_desc_type == ICB_FLAG_SHORT_AD) {
580 elen = sizeof (struct short_ad);
581 } else if (ip->i_desc_type == ICB_FLAG_LONG_AD) {
582 elen = sizeof (struct long_ad);
583 } else {
584 return (EINVAL);
585 }
586
587 if (ip->i_astrat == STRAT_TYPE4) {
588 int32_t ndentry;
589
590 ndentry = ip->i_max_emb / elen;
591 if (ip->i_ext_used < ndentry) {
592 return (0);
593 }
594 ASSERT(ip->i_con);
595 } else {
596 cmn_err(CE_WARN, "unsupported strategy type\n");
597 return (EINVAL);
598 }
599
600 return (0);
601 }
602
603 void
ud_update(int32_t flag)604 ud_update(int32_t flag)
605 {
606 struct vfs *vfsp;
607 struct udf_vfs *udfsp, *udfsnext, *update_list = NULL;
608 int32_t check_cnt = 0;
609 size_t check_size;
610 struct check_node *check_list, *ptr;
611 time_t start_time;
612
613 ud_printf("ud_update\n");
614
615 mutex_enter(&ud_sync_busy);
616 /*
617 * Examine all udf_vfs structures and add those that we can lock to the
618 * update list. This is so that we don't hold the list lock for a
619 * long time. If vfs_lock fails for a file system instance, then skip
620 * it because somebody is doing a unmount on it.
621 */
622 mutex_enter(&udf_vfs_mutex);
623 for (udfsp = udf_vfs_instances;
624 udfsp != NULL; udfsp = udfsp->udf_next) {
625 vfsp = udfsp->udf_vfs;
626 if (vfs_lock(vfsp) != 0) {
627 continue;
628 }
629 udfsp->udf_wnext = update_list;
630 update_list = udfsp;
631 check_cnt++;
632 }
633 mutex_exit(&udf_vfs_mutex);
634
635 if (update_list == NULL) {
636 mutex_exit(&ud_sync_busy);
637 return;
638 }
639
640 check_size = sizeof (struct check_node) * check_cnt;
641 check_list = ptr = kmem_alloc(check_size, KM_NOSLEEP);
642
643 /*
644 * Write back modified superblocks.
645 * Consistency check that the superblock of
646 * each file system is still in the buffer cache.
647 *
648 * Note that the update_list traversal is done without the protection
649 * of an overall list lock, so it's necessary to rely on the fact that
650 * each entry of the list is vfs_locked when moving from one entry to
651 * the next. This works because a concurrent attempt to add an entry
652 * to another thread's update_list won't find it, since it'll already
653 * be locked.
654 */
655 check_cnt = 0;
656 for (udfsp = update_list; udfsp != NULL; udfsp = udfsnext) {
657 /*
658 * Need to grab the next ptr before we unlock this one so
659 * another thread doesn't grab it and change it before we move
660 * on to the next vfs. (Once we unlock it, it's ok if another
661 * thread finds it to add it to its own update_list; we don't
662 * attempt to refer to it through our list any more.)
663 */
664 udfsnext = udfsp->udf_wnext;
665 vfsp = udfsp->udf_vfs;
666
667 if (!vfsp->vfs_data) {
668 vfs_unlock(vfsp);
669 continue;
670 }
671 mutex_enter(&udfsp->udf_lock);
672
673 /*
674 * Build up the STABLE check list, so we can unlock the vfs
675 * until we do the actual checking.
676 */
677 if (check_list != NULL) {
678 if ((udfsp->udf_flags & UDF_FL_RDONLY) == 0) {
679 ptr->vfsp = vfsp;
680 ptr->udf_vfs = udfsp;
681 ptr->vfs_dev = vfsp->vfs_dev;
682 ptr++;
683 check_cnt++;
684 }
685 }
686
687 /*
688 * superblock is not modified
689 */
690 if (udfsp->udf_mod == 0) {
691 mutex_exit(&udfsp->udf_lock);
692 vfs_unlock(vfsp);
693 continue;
694 }
695 if ((udfsp->udf_flags & UDF_FL_RDONLY) == 0) {
696 mutex_exit(&udfsp->udf_lock);
697 mutex_exit(&ud_sync_busy);
698 cmn_err(CE_WARN, "update ro udfs mod\n");
699 return;
700 }
701 udfsp->udf_mod = 0;
702 mutex_exit(&udfsp->udf_lock);
703
704 ud_update_superblock(vfsp);
705 vfs_unlock(vfsp);
706 }
707
708 ud_flushi(flag);
709 /*
710 * Force stale buffer cache information to be flushed,
711 * for all devices. This should cause any remaining control
712 * information (e.g., inode info) to be flushed back.
713 */
714 bflush((dev_t)NODEV);
715
716 if (check_list == NULL) {
717 mutex_exit(&ud_sync_busy);
718 return;
719 }
720
721 /*
722 * For each udf filesystem in the STABLE check_list, update
723 * the clean flag if warranted.
724 */
725 start_time = gethrestime_sec();
726 for (ptr = check_list; check_cnt > 0; check_cnt--, ptr++) {
727 /*
728 * ud_still_mounted() returns with vfsp and the vfs_reflock
729 * held if ptr refers to a vfs that is still mounted.
730 */
731 if ((vfsp = ud_still_mounted(ptr)) == NULL) {
732 continue;
733 }
734 ud_checkclean(vfsp, ptr->udf_vfs, ptr->vfs_dev, start_time);
735 vfs_unlock(vfsp);
736 }
737 mutex_exit(&ud_sync_busy);
738 kmem_free(check_list, check_size);
739 }
740
741
742 /*
743 * Returns vfsp and hold the lock if the vfs is still being mounted.
744 * Otherwise, returns 0.
745 *
746 * For our purposes, "still mounted" means that the file system still appears
747 * on the list of UFS file system instances.
748 */
749 vfs_t *
ud_still_mounted(struct check_node * checkp)750 ud_still_mounted(struct check_node *checkp)
751 {
752 struct vfs *vfsp;
753 struct udf_vfs *udf_vfsp;
754
755 ud_printf("ud_still_mounted\n");
756
757 mutex_enter(&udf_vfs_mutex);
758 for (udf_vfsp = udf_vfs_instances;
759 udf_vfsp != NULL; udf_vfsp = udf_vfsp->udf_next) {
760 if (udf_vfsp != checkp->udf_vfs) {
761 continue;
762 }
763 /*
764 * Tentative match: verify it and try to lock. (It's not at
765 * all clear how the verification could fail, given that we've
766 * gotten this far. We would have had to reallocate the
767 * ufsvfs struct at hand for a new incarnation; is that really
768 * possible in the interval from constructing the check_node
769 * to here?)
770 */
771 vfsp = udf_vfsp->udf_vfs;
772 if (vfsp != checkp->vfsp) {
773 continue;
774 }
775 if (vfsp->vfs_dev != checkp->vfs_dev) {
776 continue;
777 }
778 if (vfs_lock(vfsp) != 0) {
779 continue;
780 }
781 mutex_exit(&udf_vfs_mutex);
782 return (vfsp);
783 }
784 mutex_exit(&udf_vfs_mutex);
785 return (NULL);
786 }
787
788 /* ARGSUSED */
789 void
ud_checkclean(struct vfs * vfsp,struct udf_vfs * udf_vfsp,dev_t dev,time_t timev)790 ud_checkclean(struct vfs *vfsp,
791 struct udf_vfs *udf_vfsp, dev_t dev, time_t timev)
792 {
793 ud_printf("ud_checkclean\n");
794 udf_vfsp = (struct udf_vfs *)vfsp->vfs_data;
795 /*
796 * ignore if buffers or inodes are busy
797 */
798 if ((bcheck(dev, udf_vfsp->udf_iseq)) ||
799 (ud_icheck(udf_vfsp))) {
800 return;
801 }
802 mutex_enter(&udf_vfsp->udf_lock);
803 ud_sbwrite(udf_vfsp);
804 mutex_exit(&udf_vfsp->udf_lock);
805 }
806
807 int32_t
ud_icheck(struct udf_vfs * udf_vfsp)808 ud_icheck(struct udf_vfs *udf_vfsp)
809 {
810 int32_t index, error = 0;
811 union ihead *ih;
812 struct ud_inode *ip;
813
814 mutex_enter(&ud_icache_lock);
815 for (index = 0; index < UD_HASH_SZ; index++) {
816 ih = &ud_ihead[index];
817 for (ip = ih->ih_chain[0];
818 ip != (struct ud_inode *)ih; ip = ip->i_forw) {
819 if ((ip->i_udf == udf_vfsp) &&
820 ((ip->i_flag & (IMOD|IUPD|ICHG)) ||
821 (RW_ISWRITER(&ip->i_rwlock)) ||
822 ((ip->i_nlink <= 0) && (ip->i_flag & IREF)))) {
823 error = 1;
824 goto end;
825 }
826 }
827 }
828 end:
829 mutex_exit(&ud_icache_lock);
830 return (error);
831 }
832
833 void
ud_flushi(int32_t flag)834 ud_flushi(int32_t flag)
835 {
836 struct ud_inode *ip, *lip;
837 struct vnode *vp;
838 int cheap = flag & SYNC_ATTR;
839 int32_t index;
840 union ihead *ih;
841
842 /*
843 * Write back each (modified) inode,
844 * but don't sync back pages if vnode is
845 * part of the virtual swap device.
846 */
847 mutex_enter(&ud_icache_lock);
848 for (index = 0; index < UD_HASH_SZ; index++) {
849 ih = &ud_ihead[index];
850 lip = NULL;
851
852 for (ip = ih->ih_chain[0], lip = NULL;
853 ip && ip != (struct ud_inode *)ih;
854 ip = ip->i_forw) {
855 int flag = ip->i_flag;
856
857 vp = ITOV(ip);
858 /*
859 * Skip locked & inactive inodes.
860 * Skip vnodes w/ no cached data and no inode changes.
861 * Skip read-only vnodes
862 */
863 if ((flag & IREF) == 0 ||
864 (!vn_has_cached_data(vp) &&
865 ((flag & (IMOD|IACC|IUPD|ICHG)) == 0)) ||
866 (vp->v_vfsp == NULL) || vn_is_readonly(vp)) {
867 continue;
868 }
869
870 if (!rw_tryenter(&ip->i_contents, RW_WRITER)) {
871 continue;
872 }
873
874 VN_HOLD(vp);
875
876 if (lip != NULL) {
877 ITIMES(lip);
878 VN_RELE(ITOV(lip));
879 }
880 lip = ip;
881
882 /*
883 * If this is an inode sync for file system hardening
884 * or this is a full sync but file is a swap file,
885 * don't sync pages but make sure the inode is up
886 * to date. In other cases, push everything out.
887 */
888 if (cheap || IS_SWAPVP(vp)) {
889 ud_iupdat(ip, 0);
890 } else {
891 (void) ud_syncip(ip, B_ASYNC, I_SYNC);
892 }
893 rw_exit(&ip->i_contents);
894 }
895 if (lip != NULL) {
896 ITIMES(lip);
897 VN_RELE(ITOV(lip));
898 }
899 }
900 mutex_exit(&ud_icache_lock);
901 }
902
903
904 void
ud_update_regid(struct regid * reg)905 ud_update_regid(struct regid *reg)
906 {
907 ud_printf("ud_update_regid\n");
908
909 bzero(reg->reg_id, 23);
910 (void) strncpy(reg->reg_id, SUN_IMPL_ID, SUN_IMPL_ID_LEN);
911 reg->reg_ids[0] = SUN_OS_CLASS;
912 reg->reg_ids[1] = SUN_OS_ID;
913 }
914
915 /* ARGSUSED4 */
916 void
ud_make_tag(struct udf_vfs * udf_vfsp,struct tag * tag,uint16_t tag_id,uint32_t blkno,uint16_t crc_len)917 ud_make_tag(struct udf_vfs *udf_vfsp,
918 struct tag *tag, uint16_t tag_id, uint32_t blkno, uint16_t crc_len)
919 {
920 int32_t i;
921 uint16_t crc;
922 uint8_t *addr, cksum = 0;
923
924 ud_printf("ud_make_tag\n");
925
926 ASSERT(crc_len > 0x10);
927 addr = (uint8_t *)tag;
928 crc_len -= sizeof (struct tag);
929 crc = ud_crc(addr + 0x10, crc_len);
930
931 tag->tag_id = SWAP_16(tag_id);
932 tag->tag_desc_ver = SWAP_16(2);
933 tag->tag_cksum = 0;
934 tag->tag_res = 0;
935 tag->tag_sno = SWAP_16(udf_vfsp->udf_tsno);
936 tag->tag_crc = SWAP_16(crc);
937
938 tag->tag_crc_len = SWAP_16(crc_len);
939 tag->tag_loc = SWAP_32(blkno);
940
941 addr = (uint8_t *)tag;
942 for (i = 0; i <= 15; i++) {
943 cksum += addr[i];
944 }
945 tag->tag_cksum = cksum;
946 }
947
948 int32_t
ud_make_dev_spec_ear(struct dev_spec_ear * ds,major_t major,minor_t minor)949 ud_make_dev_spec_ear(struct dev_spec_ear *ds,
950 major_t major, minor_t minor)
951 {
952 int32_t attr_len;
953
954 ud_printf("ud_make_dev_spec_ear\n");
955
956 bzero(ds, sizeof (struct dev_spec_ear));
957
958 attr_len = sizeof (struct dev_spec_ear);
959 ds->ds_atype = SWAP_32(12);
960 ds->ds_astype = 1;
961 ds->ds_attr_len = SWAP_32(attr_len);
962 ds->ds_iu_len = 0;
963 ds->ds_major_id = SWAP_32(major);
964 ds->ds_minor_id = SWAP_32(minor);
965
966 return (attr_len);
967 }
968
969
970 int32_t
ud_get_next_fid(struct ud_inode * ip,struct fbuf ** fbp,uint32_t offset,struct file_id ** fid,uint8_t ** name,uint8_t * buf)971 ud_get_next_fid(struct ud_inode *ip, struct fbuf **fbp, uint32_t offset,
972 struct file_id **fid, uint8_t **name, uint8_t *buf)
973 {
974 struct vnode *vp = ITOV(ip);
975 caddr_t beg, end;
976 int32_t error, lbsize, lbmask, sz, iulen, idlen, copied = 0;
977 struct udf_vfs *udf_vfsp;
978 uint8_t *obuf;
979 int32_t count;
980 uint32_t tbno;
981 uint16_t crc_len;
982 uint32_t len;
983
984 ud_printf("ud_get_next_fid\n");
985
986 obuf = buf;
987 udf_vfsp = ip->i_udf;
988 lbsize = udf_vfsp->udf_lbsize;
989 lbmask = udf_vfsp->udf_lbmask;
990
991 if ((error = ud_ip_off2bno(ip, offset, &tbno)) != 0) {
992 return (error);
993 }
994 /* First time read */
995 if (*fbp == NULL) {
996 if ((error = fbread(vp, (offset_t)(offset & ~lbmask),
997 lbsize, S_READ, fbp)) != 0) {
998 return (error);
999 }
1000 }
1001
1002 end = (*fbp)->fb_addr + (*fbp)->fb_count;
1003 beg = (*fbp)->fb_addr + (offset & lbmask);
1004
1005
1006 if ((offset % lbsize) ||
1007 (offset == 0)) {
1008 sz = end - beg;
1009 } else {
1010 sz = 0;
1011 }
1012
1013
1014 if (F_LEN <= sz) {
1015 *fid = (struct file_id *)beg;
1016 beg += F_LEN;
1017 } else {
1018 copied = 1;
1019 bcopy(beg, buf, sz);
1020 fbrelse(*fbp, S_OTHER);
1021 *fbp = NULL;
1022
1023 /* Skip to next block */
1024 if (offset & lbmask) {
1025 offset = (offset & ~lbmask) + lbsize;
1026 }
1027 if ((error = fbread(vp, (offset_t)offset,
1028 lbsize, S_READ, fbp)) != 0) {
1029 return (error);
1030 }
1031 end = (*fbp)->fb_addr + (*fbp)->fb_count;
1032 beg = (*fbp)->fb_addr;
1033
1034 bcopy(beg, buf + sz, F_LEN - sz);
1035 beg = beg + F_LEN - sz;
1036 *fid = (struct file_id *)buf;
1037
1038 buf += F_LEN;
1039 }
1040
1041
1042 /*
1043 * Check if this a valid file_identifier
1044 */
1045 if (ud_verify_tag_and_desc(&(*fid)->fid_tag, UD_FILE_ID_DESC,
1046 tbno, 0, lbsize) != 0) {
1047 /*
1048 * Either end of directory or corrupted
1049 */
1050 return (EINVAL);
1051 }
1052
1053 crc_len = SWAP_16((*fid)->fid_tag.tag_crc_len);
1054 if (crc_len > udf_vfsp->udf_lbsize) {
1055 /*
1056 * Entries cannot be larger than
1057 * blocksize
1058 */
1059 return (EINVAL);
1060 }
1061
1062 if (crc_len < (F_LEN - sizeof (struct tag))) {
1063 iulen = SWAP_16((*fid)->fid_iulen);
1064 idlen = FID_LEN(*fid) - F_LEN;
1065 goto use_id_iu_len;
1066 }
1067
1068 /*
1069 * By now beg points to the start fo the file name
1070 */
1071
1072 sz = end - beg;
1073 len = crc_len + sizeof (struct tag) - (F_LEN);
1074 if (len <= sz) {
1075 if (copied == 1) {
1076 bcopy(beg, buf, len);
1077 buf += len;
1078 }
1079 beg += len;
1080 } else {
1081 copied = 1;
1082 /*
1083 * We are releasing the
1084 * old buffer so copy fid to buf
1085 */
1086 if (obuf == buf) {
1087 count = F_LEN + sz;
1088 bcopy(*fid, buf, count);
1089 *fid = (struct file_id *)buf;
1090 buf += count;
1091 } else {
1092 bcopy(beg, buf, sz);
1093 *fid = (struct file_id *)buf;
1094 buf += sz;
1095 }
1096 fbrelse(*fbp, S_OTHER);
1097 *fbp = NULL;
1098
1099 /* Skip to next block */
1100 if (offset & lbmask) {
1101 offset = (offset & ~lbmask) + lbsize;
1102 }
1103 if ((error = fbread(vp, (offset_t)offset,
1104 lbsize, S_READ, fbp)) != 0) {
1105 return (error);
1106 }
1107 end = (*fbp)->fb_addr + (*fbp)->fb_count;
1108 beg = (*fbp)->fb_addr;
1109 count = len - sz;
1110 bcopy(beg, buf, count);
1111 beg += count;
1112 }
1113
1114 /*
1115 * First we verify that the tag id and the FID_LEN are valid.
1116 * Next we verify the crc of the descriptor.
1117 */
1118 if (ud_verify_tag_and_desc(&(*fid)->fid_tag, UD_FILE_ID_DESC,
1119 tbno, 0, lbsize) != 0) {
1120 /* directory is corrupted */
1121 return (EINVAL);
1122 }
1123 if (ud_verify_tag_and_desc(&(*fid)->fid_tag, UD_FILE_ID_DESC,
1124 tbno, 1, FID_LEN(*fid)) != 0) {
1125 /* directory is corrupted */
1126 return (EINVAL);
1127 }
1128
1129 idlen = FID_LEN(*fid);
1130
1131 idlen -= F_LEN;
1132 iulen = SWAP_16((*fid)->fid_iulen);
1133 if (crc_len < (F_LEN - sizeof (struct tag) + idlen)) {
1134 use_id_iu_len:
1135 len = (F_LEN - sizeof (struct tag) + idlen) - crc_len;
1136 sz = end - beg;
1137 if (len <= sz) {
1138 if (copied == 1) {
1139 bcopy(beg, buf, len);
1140 }
1141 } else {
1142 if (obuf == buf) {
1143 count = crc_len + sizeof (struct tag);
1144 bcopy(*fid, buf, count);
1145 *fid = (struct file_id *)buf;
1146 buf += count;
1147 } else {
1148 bcopy(beg, buf, sz);
1149 *fid = (struct file_id *)buf;
1150 buf += sz;
1151 }
1152 fbrelse(*fbp, S_OTHER);
1153 *fbp = NULL;
1154
1155 /* Skip to next block */
1156 if (offset & lbmask) {
1157 offset = (offset & ~lbmask) + lbsize;
1158 }
1159 if ((error = fbread(vp, (offset_t)offset,
1160 lbsize, S_READ, fbp)) != 0) {
1161 return (error);
1162 }
1163 end = (*fbp)->fb_addr + (*fbp)->fb_count;
1164 beg = (*fbp)->fb_addr;
1165 count = len - sz;
1166 bcopy(beg, buf, count);
1167 beg += count;
1168 }
1169 }
1170
1171 *name = ((uint8_t *)*fid) + F_LEN + iulen;
1172
1173 return (0);
1174 }
1175
1176
1177 int32_t
ud_verify_tag_and_desc(struct tag * tag,uint16_t id,uint32_t blockno,int32_t verify_desc,int32_t desc_len)1178 ud_verify_tag_and_desc(struct tag *tag, uint16_t id, uint32_t blockno,
1179 int32_t verify_desc, int32_t desc_len)
1180 {
1181 int32_t i;
1182 uint8_t *addr, cksum = 0;
1183 uint16_t crc;
1184 file_entry_t *fe;
1185 struct ext_attr_hdr *eah;
1186 struct file_id *fid;
1187 int32_t fidlen, ea_off;
1188
1189 if (tag->tag_id != SWAP_16(id)) {
1190 return (1);
1191 }
1192 addr = (uint8_t *)tag;
1193 eah = (struct ext_attr_hdr *)tag;
1194 for (i = 0; i < 4; i++) {
1195 cksum += addr[i];
1196 }
1197 for (i = 5; i <= 15; i++) {
1198 cksum += addr[i];
1199 }
1200 if (cksum != tag->tag_cksum) {
1201 cmn_err(CE_NOTE,
1202 "Checksum Does not Verify TAG %x CALC %x blockno 0x%x\n",
1203 tag->tag_cksum, cksum, blockno);
1204 return (1);
1205 }
1206 /*
1207 * Validate the meta data for UD_FILE_ID_DESC.
1208 * The FID_LEN should not exceed the desc_len.
1209 * This validation is done before the entire descriptor is read.
1210 * A call to this routine is made initially with verify_desc set as 0
1211 * but a non zero value in desc_len.
1212 */
1213 if (id == UD_FILE_ID_DESC) {
1214 fid = (struct file_id *)tag;
1215 fidlen = FID_LEN(fid);
1216 if (fidlen > desc_len) {
1217 cmn_err(CE_NOTE,
1218 "Invalid FID_LEN(0x%x). Greater than expected(0x%x) blockno 0x%x\n",
1219 fidlen, desc_len, blockno);
1220 return (1);
1221 }
1222 }
1223 if (verify_desc == 0)
1224 return (0);
1225 /*
1226 * We are done verifying the tag. We proceed with verifying the
1227 * the descriptor. desc_len indicates the size of the structure
1228 * pointed to by argument tag. It includes the size of struct tag.
1229 * We first check the tag_crc_len since we use this to compute the
1230 * crc of the descriptor.
1231 * Verifying the crc is normally sufficient to ensure the integrity
1232 * of the meta data in the descriptor. However given the paranoia
1233 * about the panic caused by illegal meta data values we do an
1234 * additional check of the meta data for decriptor UD_FILE_ENTRY.
1235 * (The original panic was caused because this routine was not called
1236 * to verify the integrity of the tag and descriptor.)
1237 */
1238 if (SWAP_16(tag->tag_crc_len) > (desc_len - sizeof (struct tag))) {
1239 cmn_err(CE_NOTE,
1240 "tag_crc_len(0x%x) is greater than expected len(0x%x) blockno 0x%x\n",
1241 SWAP_16(tag->tag_crc_len),
1242 desc_len, blockno);
1243 return (1);
1244 }
1245 if (tag->tag_crc_len) {
1246 crc = ud_crc(addr + 0x10, SWAP_16(tag->tag_crc_len));
1247 if (crc != SWAP_16(tag->tag_crc)) {
1248 cmn_err(CE_NOTE, "CRC mismatch TAG_ID 0x%x TAG_CRC 0x%x"
1249 " Computed crc 0x%x tag_loc %x blockno 0x%x\n",
1250 id, SWAP_16(tag->tag_crc), crc,
1251 SWAP_32(tag->tag_loc), blockno);
1252 return (1);
1253 }
1254 }
1255 switch (id) {
1256 case UD_FILE_ENTRY:
1257 fe = (file_entry_t *)tag;
1258 if ((offsetof(struct file_entry, fe_spec) +
1259 SWAP_32(fe->fe_len_ear) +
1260 SWAP_32(fe->fe_len_adesc)) > desc_len) {
1261 cmn_err(CE_NOTE,
1262 "fe_len_ear(0x%x) fe_len_adesc(0x%x) fields are not OK. blockno 0x%x\n",
1263 SWAP_32(fe->fe_len_ear),
1264 SWAP_32(fe->fe_len_adesc),
1265 blockno);
1266 return (1);
1267 }
1268 break;
1269 case UD_EXT_ATTR_HDR:
1270 eah = (struct ext_attr_hdr *)tag;
1271 if (SWAP_32(eah->eah_aal) > desc_len) {
1272 cmn_err(CE_NOTE,
1273 "eah_all(0x%x) exceeds desc. len(0x%x) blockno 0x%x\n",
1274 SWAP_32(eah->eah_aal), desc_len, blockno);
1275 return (1);
1276 }
1277 ea_off = GET_32(&eah->eah_ial);
1278 if (ea_off >= desc_len) {
1279 cmn_err(CE_NOTE,
1280 "ea_off(0x%x) is not less than ea_len(0x%x) blockno 0x%x\n",
1281 ea_off, desc_len, blockno);
1282 return (1);
1283 }
1284 break;
1285 default:
1286 break;
1287 }
1288 if (SWAP_32(blockno) != tag->tag_loc) {
1289 cmn_err(CE_NOTE,
1290 "Tag Location mismatch blockno %x tag_blockno %x\n",
1291 blockno, SWAP_32(tag->tag_loc));
1292 return (1);
1293 }
1294 return (0);
1295 }
1296
1297 /* **************** udf specific subroutines *********************** */
1298
1299 uint16_t ud_crc_table[256] = {
1300 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
1301 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
1302 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
1303 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
1304 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
1305 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
1306 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
1307 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
1308 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
1309 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
1310 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
1311 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
1312 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
1313 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
1314 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
1315 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
1316 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
1317 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
1318 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
1319 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
1320 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
1321 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
1322 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
1323 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
1324 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
1325 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
1326 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
1327 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
1328 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
1329 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
1330 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
1331 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
1332 };
1333
1334 uint16_t
ud_crc(uint8_t * addr,int32_t len)1335 ud_crc(uint8_t *addr, int32_t len)
1336 {
1337 uint16_t crc = 0;
1338
1339 while (len-- > 0) {
1340 crc = ud_crc_table[(crc >> 8 ^ *addr++) & 0xff] ^ (crc<<8);
1341 }
1342
1343 return (crc);
1344 }
1345
1346 typedef unsigned short unicode_t;
1347
1348 #define POUND 0x0023
1349 #define DOT 0x002E
1350 #define SLASH 0x002F
1351 #define UNDERBAR 0x005F
1352
1353
1354 static uint16_t htoc[16] = {'0', '1', '2', '3',
1355 '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
1356
1357
1358 /*
1359 * An unrecorded block will return all
1360 * 0's on a WORM media. to simulate
1361 * a unrecorded block on a rw media
1362 * we fill it with all zero's
1363 * return 0 : If unrecorded
1364 * return 1 : If recorded.
1365 */
1366 uint32_t
ud_check_te_unrec(struct udf_vfs * udf_vfsp,caddr_t addr,uint32_t blkno)1367 ud_check_te_unrec(struct udf_vfs *udf_vfsp, caddr_t addr, uint32_t blkno)
1368 {
1369 int32_t i, lbsize;
1370 struct term_entry *te;
1371
1372 ASSERT(udf_vfsp);
1373 ASSERT(addr);
1374
1375 te = (struct term_entry *)addr;
1376 if (ud_verify_tag_and_desc(&te->te_tag, UD_TERMINAL_ENT,
1377 blkno, 1, udf_vfsp->udf_lbsize) != 0) {
1378 lbsize = udf_vfsp->udf_lbsize;
1379 for (i = 0; i < lbsize; i++) {
1380 if (addr[i] != 0) {
1381 return (1);
1382 }
1383 }
1384 }
1385 return (0);
1386 }
1387
1388
1389 /*
1390 * The algorithms ud_utf82utf16 and ud_utf162utf8
1391 * donot handle surrogates. This is unicode 1.1 as I
1392 * understand. When writing udf2.0 this code has
1393 * to be changed to process surrogates also
1394 * (Dont ask me what is a surrogate character)
1395 */
1396
1397 /*
1398 * This will take a utf8 string convert the first character
1399 * to utf16 and return the number of bytes consumed in this
1400 * process. A 0 will be returned if the character is invalid
1401 */
1402 uint8_t bytes_from_utf8[] = {
1403 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1404 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1405 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1406 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1407 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1408 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1409 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1410 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1411 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1412 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1413 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1414 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1415 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1416 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1417 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1418 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5
1419 };
1420 int32_t
ud_utf82utf16(uint8_t * s_8,uint16_t * c_16,int32_t count)1421 ud_utf82utf16(uint8_t *s_8, uint16_t *c_16, int32_t count)
1422 {
1423 int32_t extra_bytes;
1424 uint32_t c_32;
1425 ASSERT(s_8);
1426 ASSERT(c_16);
1427
1428 /*
1429 * First convert to a 32-bit
1430 * character
1431 */
1432 c_32 = 0;
1433 extra_bytes = bytes_from_utf8[*s_8];
1434 if (extra_bytes > count) {
1435 return (0);
1436 }
1437
1438 /*
1439 * verify if the string is a valid
1440 * utf8 string
1441 */
1442 if (extra_bytes == 0) {
1443 /*
1444 * Apply one byte rule
1445 */
1446 if (*s_8 & 0x80) {
1447 return (0);
1448 }
1449 c_32 = *s_8 & 0x7F;
1450 } else if (extra_bytes == 1) {
1451 if (((*s_8 & 0xE0) != 0xC0) ||
1452 ((*(s_8 + 1) & 0xC0) != 0x80)) {
1453 return (0);
1454 }
1455 c_32 = *s_8 & 0x1F;
1456 } else if (extra_bytes == 2) {
1457 if (((*s_8 & 0xF0) != 0xE0) ||
1458 ((*(s_8 + 1) & 0xC0) != 0x80) ||
1459 ((*(s_8 + 2) & 0xC0) != 0x80)) {
1460 return (0);
1461 }
1462 c_32 = *s_8 & 0x0F;
1463 } else if (extra_bytes == 3) {
1464 if (((*s_8 & 0xF8) != 0xF0) ||
1465 ((*(s_8 + 1) & 0xC0) != 0x80) ||
1466 ((*(s_8 + 2) & 0xC0) != 0x80) ||
1467 ((*(s_8 + 3) & 0xC0) != 0x80)) {
1468 return (0);
1469 }
1470 c_32 = *s_8 & 0x07;
1471 } else if (extra_bytes == 4) {
1472 if (((*s_8 & 0xFC) != 0xF8) ||
1473 ((*(s_8 + 1) & 0xC0) != 0x80) ||
1474 ((*(s_8 + 2) & 0xC0) != 0x80) ||
1475 ((*(s_8 + 3) & 0xC0) != 0x80) ||
1476 ((*(s_8 + 4) & 0xC0) != 0x80)) {
1477 return (0);
1478 }
1479 c_32 = *s_8 & 0x03;
1480 } else if (extra_bytes == 5) {
1481 if (((*s_8 & 0xFE) != 0xFC) ||
1482 ((*(s_8 + 1) & 0xC0) != 0x80) ||
1483 ((*(s_8 + 2) & 0xC0) != 0x80) ||
1484 ((*(s_8 + 3) & 0xC0) != 0x80) ||
1485 ((*(s_8 + 4) & 0xC0) != 0x80) ||
1486 ((*(s_8 + 5) & 0xC0) != 0x80)) {
1487 return (0);
1488 }
1489 c_32 = *s_8 & 0x01;
1490 } else {
1491 return (0);
1492 }
1493 s_8++;
1494
1495 /*
1496 * Convert to 32-bit character
1497 */
1498 switch (extra_bytes) {
1499 case 5 :
1500 c_32 <<= 6;
1501 c_32 += (*s_8++ & 0x3F);
1502 /* FALLTHROUGH */
1503 case 4 :
1504 c_32 <<= 6;
1505 c_32 += (*s_8++ & 0x3F);
1506 /* FALLTHROUGH */
1507 case 3 :
1508 c_32 <<= 6;
1509 c_32 += (*s_8++ & 0x3F);
1510 /* FALLTHROUGH */
1511 case 2 :
1512 c_32 <<= 6;
1513 c_32 += (*s_8++ & 0x3F);
1514 /* FALLTHROUGH */
1515 case 1 :
1516 c_32 <<= 6;
1517 c_32 += (*s_8++ & 0x3F);
1518 /* FALLTHROUGH */
1519 case 0 :
1520 break;
1521 }
1522
1523 /*
1524 * now convert the 32-bit
1525 * character into a 16-bit character
1526 */
1527 *c_16 = c_32;
1528 return (extra_bytes + 1);
1529 }
1530
1531 /*
1532 * Convert to a form that can be put on the media
1533 * out_len has the size of out_str when we are called.
1534 * This routine will set out_len to actual bytes written to out_str.
1535 * We make sure that we will not attempt to write beyond the out_str_len.
1536 */
1537 int32_t
ud_compress(int32_t in_len,int32_t * out_len,uint8_t * in_str,uint8_t * out_str)1538 ud_compress(int32_t in_len, int32_t *out_len,
1539 uint8_t *in_str, uint8_t *out_str)
1540 {
1541 int32_t error, in_index, out_index, index, c_tx_sz, out_str_len;
1542 uint16_t w2_char, *w2_str;
1543 uint8_t comp_id;
1544
1545 out_str_len = *out_len;
1546 if (in_len > (out_str_len - 2)) {
1547 return (ENAMETOOLONG);
1548 }
1549
1550 *out_len = 0;
1551 w2_str = (uint16_t *)kmem_zalloc(512, KM_SLEEP);
1552
1553 error = in_index = out_index = c_tx_sz = 0;
1554 comp_id = 8;
1555 for (in_index = 0; in_index < in_len; in_index += c_tx_sz) {
1556 if ((c_tx_sz = ud_utf82utf16(&in_str[in_index],
1557 &w2_char, in_len - in_index)) == 0) {
1558 error = EINVAL;
1559 goto end;
1560 }
1561 /*
1562 * utf-8 characters can be
1563 * of 1 - 6 bytes in length
1564 */
1565 ASSERT(c_tx_sz > 0);
1566 ASSERT(c_tx_sz < 7);
1567 if ((comp_id == 8) && (w2_char & 0xff00)) {
1568 comp_id = 0x10;
1569 }
1570 w2_str[out_index++] = w2_char;
1571 }
1572 if (((comp_id == 0x10) && (out_index > ((out_str_len - 2)/2))) ||
1573 ((comp_id == 0x8) && (out_index > (out_str_len - 2)))) {
1574 error = ENAMETOOLONG;
1575 goto end;
1576 }
1577
1578 in_index = out_index;
1579 out_index = 0;
1580 out_str[out_index++] = comp_id;
1581 for (index = 0; index < in_index; index++) {
1582 if (comp_id == 0x10) {
1583 out_str[out_index++] = (w2_str[index] & 0xFF00) >> 8;
1584 }
1585 out_str[out_index++] = w2_str[index] & 0xFF;
1586 }
1587 ASSERT(out_index <= (out_str_len - 1));
1588 *out_len = out_index;
1589 end:
1590 if (w2_str != NULL) {
1591 kmem_free((caddr_t)w2_str, 512);
1592 }
1593 return (error);
1594 }
1595
1596 /*
1597 * Take a utf16 character and convert
1598 * it into a utf8 character.
1599 * A 0 will be returned if the conversion fails
1600 */
1601 uint8_t first_byte_mark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC};
1602 int32_t
ud_utf162utf8(uint16_t c_16,uint8_t * s_8)1603 ud_utf162utf8(uint16_t c_16, uint8_t *s_8)
1604 {
1605 int32_t nc;
1606 uint32_t c_32;
1607 uint32_t byte_mask = 0xBF;
1608 uint32_t byte_mark = 0x80;
1609
1610 ASSERT(s_8);
1611
1612 /*
1613 * Convert the 16-bit character to
1614 * a 32-bit character
1615 */
1616 c_32 = c_16;
1617
1618 /*
1619 * By here the 16-bit character is converted
1620 * to a 32-bit wide character
1621 */
1622 if (c_32 < 0x80) {
1623 nc = 1;
1624 } else if (c_32 < 0x800) {
1625 nc = 2;
1626 } else if (c_32 < 0x10000) {
1627 nc = 3;
1628 } else if (c_32 < 0x200000) {
1629 nc = 4;
1630 } else if (c_32 < 0x4000000) {
1631 nc = 5;
1632 } else if (c_32 < (uint32_t)0x80000000) {
1633 nc = 6;
1634 } else {
1635 nc = 0;
1636 }
1637 s_8 += nc;
1638 switch (nc) {
1639 case 6 :
1640 *(--s_8) = (c_32 | byte_mark) & byte_mask;
1641 c_32 >>= 6;
1642 /* FALLTHROUGH */
1643 case 5 :
1644 *(--s_8) = (c_32 | byte_mark) & byte_mask;
1645 c_32 >>= 6;
1646 /* FALLTHROUGH */
1647 case 4 :
1648 *(--s_8) = (c_32 | byte_mark) & byte_mask;
1649 c_32 >>= 6;
1650 /* FALLTHROUGH */
1651 case 3 :
1652 *(--s_8) = (c_32 | byte_mark) & byte_mask;
1653 c_32 >>= 6;
1654 /* FALLTHROUGH */
1655 case 2 :
1656 *(--s_8) = (c_32 | byte_mark) & byte_mask;
1657 c_32 >>= 6;
1658 /* FALLTHROUGH */
1659 case 1 :
1660 *(--s_8) = c_32 | first_byte_mark[nc];
1661 }
1662 return (nc);
1663 }
1664
1665 /*
1666 * Convert to a form that can be transferred to the user
1667 * Assumption's
1668 * in_length < 256, out_str is at least 255 bytes long
1669 * The converted byte stream length is returned in out_len
1670 */
1671 #define MAX_ALLOWABLE_STRING 250
1672
1673 int32_t
ud_uncompress(int32_t in_len,int32_t * out_len,uint8_t * in_str,uint8_t * out_str)1674 ud_uncompress(int32_t in_len, int32_t *out_len,
1675 uint8_t *in_str, uint8_t *out_str)
1676 {
1677 uint8_t comp_id, utf8[6];
1678 uint16_t w2_char, crc;
1679 int32_t error, index, c_tx_sz, len_till_now;
1680 int32_t make_crc, lic, dot_loc, crc_start_loc = 0, k = 0;
1681
1682 if (in_len == 0) {
1683 *out_len = 0;
1684 out_str[0] = '\0';
1685 return (0);
1686 }
1687
1688 error = len_till_now = make_crc = 0;
1689 dot_loc = lic = -2;
1690 *out_len = 0;
1691 crc = 0;
1692 comp_id = in_str[0];
1693
1694 /*
1695 * File names "." and ".." are invalid under unix.
1696 * Transform them into something
1697 */
1698 if (comp_id == 8) {
1699 if ((in_str[1] == DOT) &&
1700 ((in_len == 2) || ((in_len == 3) &&
1701 (in_str[2] == DOT)))) {
1702 out_str[k++] = UNDERBAR;
1703 len_till_now = 1;
1704 goto make_append_crc;
1705 }
1706 } else if (comp_id == 0x10) {
1707 if (((in_str[1] << 8 | in_str[2]) == DOT) &&
1708 ((in_len == 3) || ((in_len == 5) &&
1709 ((in_str[3] << 8 | in_str[4]) == DOT)))) {
1710 out_str[k++] = UNDERBAR;
1711 len_till_now = 1;
1712 goto make_append_crc;
1713 }
1714 } else {
1715 *out_len = 0;
1716 return (EINVAL);
1717 }
1718
1719 for (index = 1; index < in_len; ) {
1720
1721 /*
1722 * Uncompress each character
1723 */
1724 if (comp_id == 0x10) {
1725 w2_char = in_str[index++] << 8;
1726 w2_char |= in_str[index++];
1727 } else {
1728 w2_char = in_str[index++];
1729 }
1730
1731 if (make_crc != 0) {
1732 crc += w2_char;
1733 }
1734
1735 if (w2_char == DOT) {
1736 dot_loc = len_till_now;
1737 }
1738
1739 /*
1740 * Get rid of invalid characters
1741 */
1742 if ((w2_char == SLASH) ||
1743 (w2_char == NULL)) {
1744 make_crc = 1;
1745 if (((comp_id == 8) &&
1746 (lic != (index - 1))) ||
1747 (comp_id == 0x10) &&
1748 (lic != (index - 2))) {
1749 w2_char = UNDERBAR;
1750 lic = index;
1751 } else {
1752 lic = index;
1753 continue;
1754 }
1755 }
1756
1757 /*
1758 * Conver a 16bit character to a
1759 * utf8 byte stream
1760 */
1761 if ((c_tx_sz = ud_utf162utf8(w2_char, utf8)) == 0) {
1762 error = EINVAL;
1763 goto end;
1764 }
1765 ASSERT(c_tx_sz > 0);
1766 ASSERT(c_tx_sz < 7);
1767
1768 /*
1769 * The output string is larger than
1770 * the maximum allowed string length
1771 */
1772 if ((crc_start_loc == 0) &&
1773 ((len_till_now + c_tx_sz) > MAX_ALLOWABLE_STRING)) {
1774 crc_start_loc = len_till_now;
1775 }
1776
1777 if ((len_till_now + c_tx_sz) < MAXNAMELEN) {
1778 (void) strncpy((caddr_t)&out_str[len_till_now],
1779 (caddr_t)utf8, c_tx_sz);
1780 len_till_now += c_tx_sz;
1781 } else {
1782 break;
1783 }
1784 }
1785
1786 /*
1787 * If we need to append CRC do it now
1788 */
1789
1790 if (make_crc) {
1791
1792 if (len_till_now > MAX_ALLOWABLE_STRING) {
1793 len_till_now = crc_start_loc;
1794 }
1795
1796 if (dot_loc > 0) {
1797 /*
1798 * Make space for crc before the DOT
1799 * move the rest of the file name to the end
1800 */
1801 for (k = len_till_now - 1; k >= dot_loc; k--) {
1802 out_str[k + 5] = out_str[k];
1803 }
1804 k = dot_loc;
1805 } else {
1806 k = len_till_now;
1807 }
1808 make_append_crc:
1809 crc = ud_crc(in_str, in_len);
1810 out_str[k++] = POUND;
1811 out_str[k++] = htoc[(uint16_t)(crc & 0xf000) >> 12];
1812 out_str[k++] = htoc[(uint16_t)(crc & 0xf00) >> 8];
1813 out_str[k++] = htoc[(uint16_t)(crc & 0xf0) >> 4];
1814 out_str[k++] = htoc[crc & 0xf];
1815 len_till_now += 5;
1816 }
1817 *out_len = len_till_now;
1818 end:
1819 return (error);
1820 }
1821
1822
1823 struct buf *
ud_bread(dev_t dev,daddr_t blkno,long bsize)1824 ud_bread(dev_t dev, daddr_t blkno, long bsize)
1825 {
1826 struct buf *bp;
1827
1828 begin:
1829 bp = bread(dev, blkno, bsize);
1830
1831 if (((bp->b_flags & B_ERROR) == 0) &&
1832 (bp->b_bcount != bsize)) {
1833 /*
1834 * Buffer cache returned a
1835 * wrong number of bytes
1836 * flush the old buffer and
1837 * reread it again
1838 */
1839 if (bp->b_flags & B_DELWRI) {
1840 bwrite(bp);
1841 } else {
1842 bp->b_flags |= (B_AGE | B_STALE);
1843 brelse(bp);
1844 }
1845 goto begin;
1846 }
1847
1848 return (bp);
1849 }
1850
1851 /*
1852 * Decide whether it is okay to remove within a sticky directory.
1853 * Two conditions need to be met: write access to the directory
1854 * is needed. In sticky directories, write access is not sufficient;
1855 * you can remove entries from a directory only if you own the directory,
1856 * if you are privileged, if you own the entry or if they entry is
1857 * a plain file and you have write access to that file.
1858 * Function returns 0 if remove access is granted.
1859 */
1860 int
ud_sticky_remove_access(struct ud_inode * dir,struct ud_inode * entry,struct cred * cr)1861 ud_sticky_remove_access(struct ud_inode *dir, struct ud_inode *entry,
1862 struct cred *cr)
1863 {
1864 uid_t uid;
1865
1866 ASSERT(RW_LOCK_HELD(&entry->i_contents));
1867
1868 if ((dir->i_char & ISVTX) &&
1869 (uid = crgetuid(cr)) != dir->i_uid &&
1870 uid != entry->i_uid &&
1871 (entry->i_type != VREG ||
1872 ud_iaccess(entry, IWRITE, cr, 0) != 0))
1873 return (secpolicy_vnode_remove(cr));
1874
1875 return (0);
1876 }
1877