xref: /illumos-gate/usr/src/uts/common/fs/udfs/udf_inode.c (revision ade42b55)
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  * Copyright (c) 2017 by Delphix. All rights reserved.
24  */
25 
26 #include <sys/types.h>
27 #include <sys/t_lock.h>
28 #include <sys/param.h>
29 #include <sys/time.h>
30 #include <sys/systm.h>
31 #include <sys/sysmacros.h>
32 #include <sys/resource.h>
33 #include <sys/signal.h>
34 #include <sys/cred.h>
35 #include <sys/user.h>
36 #include <sys/buf.h>
37 #include <sys/vfs.h>
38 #include <sys/stat.h>
39 #include <sys/vnode.h>
40 #include <sys/mode.h>
41 #include <sys/proc.h>
42 #include <sys/disp.h>
43 #include <sys/file.h>
44 #include <sys/fcntl.h>
45 #include <sys/flock.h>
46 #include <sys/kmem.h>
47 #include <sys/uio.h>
48 #include <sys/dnlc.h>
49 #include <sys/conf.h>
50 #include <sys/errno.h>
51 #include <sys/mman.h>
52 #include <sys/fbuf.h>
53 #include <sys/pathname.h>
54 #include <sys/debug.h>
55 #include <sys/vmsystm.h>
56 #include <sys/cmn_err.h>
57 #include <sys/dirent.h>
58 #include <sys/errno.h>
59 #include <sys/modctl.h>
60 #include <sys/statvfs.h>
61 #include <sys/mount.h>
62 #include <sys/sunddi.h>
63 #include <sys/bootconf.h>
64 #include <sys/policy.h>
65 
66 #include <vm/hat.h>
67 #include <vm/page.h>
68 #include <vm/pvn.h>
69 #include <vm/as.h>
70 #include <vm/seg.h>
71 #include <vm/seg_map.h>
72 #include <vm/seg_kmem.h>
73 #include <vm/seg_vn.h>
74 #include <vm/rm.h>
75 #include <vm/page.h>
76 #include <sys/swap.h>
77 
78 
79 #include <fs/fs_subr.h>
80 
81 
82 #include <sys/fs/udf_volume.h>
83 #include <sys/fs/udf_inode.h>
84 
85 extern struct vnodeops *udf_vnodeops;
86 
87 kmutex_t ud_sync_busy;
88 /*
89  * udf_vfs list manipulation routines
90  */
91 kmutex_t udf_vfs_mutex;
92 struct udf_vfs *udf_vfs_instances;
93 #ifndef	__lint
94 _NOTE(MUTEX_PROTECTS_DATA(udf_vfs_mutex, udf_vfs_instances))
95 #endif
96 
97 union ihead ud_ihead[UD_HASH_SZ];
98 kmutex_t ud_icache_lock;
99 
100 #define	UD_BEGIN	0x0
101 #define	UD_END		0x1
102 #define	UD_UNKN		0x2
103 struct ud_inode *udf_ifreeh, *udf_ifreet;
104 kmutex_t udf_ifree_lock;
105 #ifndef	__lint
106 _NOTE(MUTEX_PROTECTS_DATA(udf_ifree_lock, udf_ifreeh))
107 _NOTE(MUTEX_PROTECTS_DATA(udf_ifree_lock, udf_ifreet))
108 #endif
109 
110 kmutex_t ud_nino_lock;
111 int32_t ud_max_inodes = 512;
112 int32_t ud_cur_inodes = 0;
113 #ifndef	__lint
114 _NOTE(MUTEX_PROTECTS_DATA(ud_nino_lock, ud_cur_inodes))
115 #endif
116 
117 uid_t ud_default_uid = 0;
118 gid_t ud_default_gid = 3;
119 
120 int32_t ud_updat_ext4(struct ud_inode *, struct file_entry *);
121 int32_t ud_updat_ext4096(struct ud_inode *, struct file_entry *);
122 void ud_make_sad(struct icb_ext *, struct short_ad *, int32_t);
123 void ud_make_lad(struct icb_ext *, struct long_ad *, int32_t);
124 void ud_trunc_ext4(struct ud_inode *, u_offset_t);
125 void ud_trunc_ext4096(struct ud_inode *, u_offset_t);
126 void ud_add_to_free_list(struct ud_inode *, uint32_t);
127 void ud_remove_from_free_list(struct ud_inode *, uint32_t);
128 
129 
130 #ifdef	DEBUG
131 struct ud_inode *
ud_search_icache(struct vfs * vfsp,uint16_t prn,uint32_t ploc)132 ud_search_icache(struct vfs *vfsp, uint16_t prn, uint32_t ploc)
133 {
134 	int32_t hno;
135 	union ihead *ih;
136 	struct ud_inode *ip;
137 	struct udf_vfs *udf_vfsp;
138 	uint32_t loc, dummy;
139 
140 	udf_vfsp = (struct udf_vfs *)vfsp->vfs_data;
141 	loc = ud_xlate_to_daddr(udf_vfsp, prn, ploc, 1, &dummy);
142 
143 	mutex_enter(&ud_icache_lock);
144 	hno = UD_INOHASH(vfsp->vfs_dev, loc);
145 	ih = &ud_ihead[hno];
146 	for (ip = ih->ih_chain[0];
147 	    ip != (struct ud_inode *)ih;
148 	    ip = ip->i_forw) {
149 		if ((prn == ip->i_icb_prn) && (ploc == ip->i_icb_block) &&
150 		    (vfsp->vfs_dev == ip->i_dev)) {
151 			mutex_exit(&ud_icache_lock);
152 			return (ip);
153 		}
154 	}
155 	mutex_exit(&ud_icache_lock);
156 	return (0);
157 }
158 #endif
159 
160 /* ARGSUSED */
161 int
ud_iget(struct vfs * vfsp,uint16_t prn,uint32_t ploc,struct ud_inode ** ipp,struct buf * pbp,struct cred * cred)162 ud_iget(struct vfs *vfsp, uint16_t prn, uint32_t ploc, struct ud_inode **ipp,
163     struct buf *pbp, struct cred *cred)
164 {
165 	int32_t hno, nomem = 0, icb_tag_flags;
166 	union ihead *ih;
167 	struct ud_inode *ip;
168 	struct vnode *vp;
169 	struct buf *bp = NULL;
170 	struct file_entry *fe;
171 	struct udf_vfs *udf_vfsp;
172 	struct ext_attr_hdr *eah;
173 	struct attr_hdr *ah;
174 	int32_t ea_len, ea_off;
175 	daddr_t loc;
176 	uint64_t offset = 0;
177 	struct icb_ext *iext, *con;
178 	uint32_t length, dummy;
179 	int32_t ndesc, ftype;
180 	uint16_t old_prn;
181 	uint32_t old_block, old_lbano;
182 
183 	ud_printf("ud_iget\n");
184 	udf_vfsp = (struct udf_vfs *)vfsp->vfs_data;
185 	old_prn = 0;
186 	old_block = old_lbano = 0;
187 	ftype = 0;
188 	loc = ud_xlate_to_daddr(udf_vfsp, prn, ploc, 1, &dummy);
189 loop:
190 	mutex_enter(&ud_icache_lock);
191 	hno = UD_INOHASH(vfsp->vfs_dev, loc);
192 
193 	ih = &ud_ihead[hno];
194 	for (ip = ih->ih_chain[0];
195 	    ip != (struct ud_inode *)ih;
196 	    ip = ip->i_forw) {
197 
198 		if ((prn == ip->i_icb_prn) &&
199 		    (ploc == ip->i_icb_block) &&
200 		    (vfsp->vfs_dev == ip->i_dev)) {
201 
202 			vp = ITOV(ip);
203 			VN_HOLD(vp);
204 			mutex_exit(&ud_icache_lock);
205 
206 			rw_enter(&ip->i_contents, RW_READER);
207 			mutex_enter(&ip->i_tlock);
208 			if ((ip->i_flag & IREF) == 0) {
209 				mutex_enter(&udf_ifree_lock);
210 				ud_remove_from_free_list(ip, UD_UNKN);
211 				mutex_exit(&udf_ifree_lock);
212 			}
213 			ip->i_flag |= IREF;
214 			mutex_exit(&ip->i_tlock);
215 			rw_exit(&ip->i_contents);
216 
217 			*ipp = ip;
218 
219 			if (pbp != NULL) {
220 				brelse(pbp);
221 			}
222 
223 			return (0);
224 		}
225 	}
226 
227 	/*
228 	 * We don't have it in the cache
229 	 * Allocate a new entry
230 	 */
231 tryagain:
232 	mutex_enter(&udf_ifree_lock);
233 	mutex_enter(&ud_nino_lock);
234 	if (ud_cur_inodes > ud_max_inodes) {
235 		int32_t purged;
236 
237 		mutex_exit(&ud_nino_lock);
238 		while (udf_ifreeh == NULL ||
239 		    vn_has_cached_data(ITOV(udf_ifreeh))) {
240 			/*
241 			 * Try to put an inode on the freelist that's
242 			 * sitting in the dnlc.
243 			 */
244 			mutex_exit(&udf_ifree_lock);
245 			purged = dnlc_fs_purge1(udf_vnodeops);
246 			mutex_enter(&udf_ifree_lock);
247 			if (!purged) {
248 				break;
249 			}
250 		}
251 		mutex_enter(&ud_nino_lock);
252 	}
253 
254 	/*
255 	 * If there's a free one available and it has no pages attached
256 	 * take it. If we're over the high water mark, take it even if
257 	 * it has attached pages. Otherwise, make a new one.
258 	 */
259 	if (udf_ifreeh &&
260 	    (nomem || !vn_has_cached_data(ITOV(udf_ifreeh)) ||
261 	    ud_cur_inodes >= ud_max_inodes)) {
262 
263 		mutex_exit(&ud_nino_lock);
264 		ip = udf_ifreeh;
265 		vp = ITOV(ip);
266 
267 		ud_remove_from_free_list(ip, UD_BEGIN);
268 
269 		mutex_exit(&udf_ifree_lock);
270 		if (ip->i_flag & IREF) {
271 			cmn_err(CE_WARN, "ud_iget: bad i_flag\n");
272 			mutex_exit(&ud_icache_lock);
273 			if (pbp != NULL) {
274 				brelse(pbp);
275 			}
276 			return (EINVAL);
277 		}
278 		rw_enter(&ip->i_contents, RW_WRITER);
279 
280 		/*
281 		 * We call udf_syncip() to synchronously destroy all pages
282 		 * associated with the vnode before re-using it. The pageout
283 		 * thread may have beat us to this page so our v_count can
284 		 * be > 0 at this point even though we are on the freelist.
285 		 */
286 		mutex_enter(&ip->i_tlock);
287 		ip->i_flag = (ip->i_flag & IMODTIME) | IREF;
288 		mutex_exit(&ip->i_tlock);
289 
290 		VN_HOLD(vp);
291 		if (ud_syncip(ip, B_INVAL, I_SYNC) != 0) {
292 			ud_idrop(ip);
293 			rw_exit(&ip->i_contents);
294 			mutex_exit(&ud_icache_lock);
295 			goto loop;
296 		}
297 
298 		mutex_enter(&ip->i_tlock);
299 		ip->i_flag &= ~IMODTIME;
300 		mutex_exit(&ip->i_tlock);
301 
302 		if (ip->i_ext) {
303 			kmem_free(ip->i_ext,
304 			    sizeof (struct icb_ext) * ip->i_ext_count);
305 			ip->i_ext = 0;
306 			ip->i_ext_count = ip->i_ext_used = 0;
307 		}
308 
309 		if (ip->i_con) {
310 			kmem_free(ip->i_con,
311 			    sizeof (struct icb_ext) * ip->i_con_count);
312 			ip->i_con = 0;
313 			ip->i_con_count = ip->i_con_used = ip->i_con_read = 0;
314 		}
315 
316 		/*
317 		 * The pageout thread may not have had a chance to release
318 		 * its hold on the vnode (if it was active with this vp),
319 		 * but the pages should all be invalidated.
320 		 */
321 	} else {
322 		mutex_exit(&ud_nino_lock);
323 		mutex_exit(&udf_ifree_lock);
324 		/*
325 		 * Try to get memory for this inode without blocking.
326 		 * If we can't and there is something on the freelist,
327 		 * go ahead and use it, otherwise block waiting for
328 		 * memory holding the hash_lock. We expose a potential
329 		 * deadlock if all users of memory have to do a ud_iget()
330 		 * before releasing memory.
331 		 */
332 		ip = (struct ud_inode *)kmem_zalloc(sizeof (struct ud_inode),
333 		    KM_NOSLEEP);
334 		vp = vn_alloc(KM_NOSLEEP);
335 		if ((ip == NULL) || (vp == NULL)) {
336 			mutex_enter(&udf_ifree_lock);
337 			if (udf_ifreeh) {
338 				mutex_exit(&udf_ifree_lock);
339 				if (ip != NULL)
340 					kmem_free(ip, sizeof (struct ud_inode));
341 				if (vp != NULL)
342 					vn_free(vp);
343 				nomem = 1;
344 				goto tryagain;
345 			} else {
346 				mutex_exit(&udf_ifree_lock);
347 				if (ip == NULL)
348 					ip = (struct ud_inode *)
349 					    kmem_zalloc(
350 					    sizeof (struct ud_inode),
351 					    KM_SLEEP);
352 				if (vp == NULL)
353 					vp = vn_alloc(KM_SLEEP);
354 			}
355 		}
356 		ip->i_vnode = vp;
357 
358 		ip->i_marker1 = (uint32_t)0xAAAAAAAA;
359 		ip->i_marker2 = (uint32_t)0xBBBBBBBB;
360 		ip->i_marker3 = (uint32_t)0xCCCCCCCC;
361 
362 		rw_init(&ip->i_rwlock, NULL, RW_DEFAULT, NULL);
363 		rw_init(&ip->i_contents, NULL, RW_DEFAULT, NULL);
364 		mutex_init(&ip->i_tlock, NULL, MUTEX_DEFAULT, NULL);
365 
366 		ip->i_forw = ip;
367 		ip->i_back = ip;
368 		vp->v_data = (caddr_t)ip;
369 		vn_setops(vp, udf_vnodeops);
370 		ip->i_flag = IREF;
371 		cv_init(&ip->i_wrcv, NULL, CV_DRIVER, NULL);
372 		mutex_enter(&ud_nino_lock);
373 		ud_cur_inodes++;
374 		mutex_exit(&ud_nino_lock);
375 
376 		rw_enter(&ip->i_contents, RW_WRITER);
377 	}
378 
379 	if (vp->v_count < 1) {
380 		cmn_err(CE_WARN, "ud_iget: v_count < 1\n");
381 		mutex_exit(&ud_icache_lock);
382 		rw_exit(&ip->i_contents);
383 		if (pbp != NULL) {
384 			brelse(pbp);
385 		}
386 		return (EINVAL);
387 	}
388 	if (vn_has_cached_data(vp)) {
389 		cmn_err(CE_WARN, "ud_iget: v_pages not NULL\n");
390 		mutex_exit(&ud_icache_lock);
391 		rw_exit(&ip->i_contents);
392 		if (pbp != NULL) {
393 			brelse(pbp);
394 		}
395 		return (EINVAL);
396 	}
397 
398 	/*
399 	 * Move the inode on the chain for its new (ino, dev) pair
400 	 */
401 	remque(ip);
402 	ip->i_forw = ip;
403 	ip->i_back = ip;
404 	insque(ip, ih);
405 
406 	ip->i_dev = vfsp->vfs_dev;
407 	ip->i_udf = udf_vfsp;
408 	ip->i_diroff = 0;
409 	ip->i_devvp = ip->i_udf->udf_devvp;
410 	ip->i_icb_prn = prn;
411 	ip->i_icb_block = ploc;
412 	ip->i_icb_lbano = loc;
413 	ip->i_nextr = 0;
414 	ip->i_seq = 0;
415 	mutex_exit(&ud_icache_lock);
416 
417 read_de:
418 	if (pbp != NULL) {
419 		/*
420 		 * assumption is that we will not
421 		 * create a 4096 file
422 		 */
423 		bp = pbp;
424 	} else {
425 		bp = ud_bread(ip->i_dev,
426 		    ip->i_icb_lbano << udf_vfsp->udf_l2d_shift,
427 		    udf_vfsp->udf_lbsize);
428 	}
429 
430 	/*
431 	 * Check I/O errors
432 	 */
433 	fe = (struct file_entry *)bp->b_un.b_addr;
434 	if ((bp->b_flags & B_ERROR) ||
435 	    (ud_verify_tag_and_desc(&fe->fe_tag, UD_FILE_ENTRY,
436 	    ip->i_icb_block, 1, udf_vfsp->udf_lbsize) != 0)) {
437 
438 		if (((bp->b_flags & B_ERROR) == 0) &&
439 		    (ftype == STRAT_TYPE4096)) {
440 			if (ud_check_te_unrec(udf_vfsp,
441 			    bp->b_un.b_addr, ip->i_icb_block) == 0) {
442 
443 				brelse(bp);
444 
445 				/*
446 				 * restore old file entry location
447 				 */
448 				ip->i_icb_prn = old_prn;
449 				ip->i_icb_block = old_block;
450 				ip->i_icb_lbano = old_lbano;
451 
452 				/*
453 				 * reread old file entry
454 				 */
455 				bp = ud_bread(ip->i_dev,
456 				    old_lbano << udf_vfsp->udf_l2d_shift,
457 				    udf_vfsp->udf_lbsize);
458 				if ((bp->b_flags & B_ERROR) == 0) {
459 					fe = (struct file_entry *)
460 					    bp->b_un.b_addr;
461 					if (ud_verify_tag_and_desc(&fe->fe_tag,
462 					    UD_FILE_ENTRY, ip->i_icb_block, 1,
463 					    udf_vfsp->udf_lbsize) == 0) {
464 						goto end_4096;
465 					}
466 				}
467 			}
468 		}
469 error_ret:
470 		brelse(bp);
471 		/*
472 		 * The inode may not contain anything useful. Mark it as
473 		 * having an error and let anyone else who was waiting for
474 		 * this know there was an error. Callers waiting for
475 		 * access to this inode in ud_iget will find
476 		 * the i_icb_lbano == 0, so there won't be a match.
477 		 * It remains in the cache. Put it back on the freelist.
478 		 */
479 		mutex_enter(&vp->v_lock);
480 		VN_RELE_LOCKED(vp);
481 		mutex_exit(&vp->v_lock);
482 		ip->i_icb_lbano = 0;
483 
484 		/*
485 		 * The folowing two lines make
486 		 * it impossible for any one do
487 		 * a VN_HOLD and then a VN_RELE
488 		 * so avoiding a ud_iinactive
489 		 */
490 		ip->i_icb_prn = 0xffff;
491 		ip->i_icb_block = 0;
492 
493 		/*
494 		 * remove the bad inode from hash chains
495 		 * so that during unmount we will not
496 		 * go through this inode
497 		 */
498 		mutex_enter(&ud_icache_lock);
499 		remque(ip);
500 		ip->i_forw = ip;
501 		ip->i_back = ip;
502 		mutex_exit(&ud_icache_lock);
503 
504 		/* Put the inode at the front of the freelist */
505 		mutex_enter(&ip->i_tlock);
506 		mutex_enter(&udf_ifree_lock);
507 		ud_add_to_free_list(ip, UD_BEGIN);
508 		mutex_exit(&udf_ifree_lock);
509 		ip->i_flag = 0;
510 		mutex_exit(&ip->i_tlock);
511 		rw_exit(&ip->i_contents);
512 		return (EIO);
513 	}
514 
515 	if (fe->fe_icb_tag.itag_strategy == SWAP_16(STRAT_TYPE4096)) {
516 		struct buf *ibp = NULL;
517 		struct indirect_entry *ie;
518 
519 		/*
520 		 * save old file_entry location
521 		 */
522 		old_prn = ip->i_icb_prn;
523 		old_block = ip->i_icb_block;
524 		old_lbano = ip->i_icb_lbano;
525 
526 		ftype = STRAT_TYPE4096;
527 
528 		/*
529 		 * If astrat is 4096 different versions
530 		 * of the file exist on the media.
531 		 * we are supposed to get to the latest
532 		 * version of the file
533 		 */
534 
535 		/*
536 		 * IE is supposed to be in the next block
537 		 * of DE
538 		 */
539 		ibp = ud_bread(ip->i_dev,
540 		    (ip->i_icb_lbano + 1) << udf_vfsp->udf_l2d_shift,
541 		    udf_vfsp->udf_lbsize);
542 		if (ibp->b_flags & B_ERROR) {
543 			/*
544 			 * Get rid of current ibp and
545 			 * then goto error on DE's bp
546 			 */
547 ie_error:
548 			brelse(ibp);
549 			goto error_ret;
550 		}
551 
552 		ie = (struct indirect_entry *)ibp->b_un.b_addr;
553 		if (ud_verify_tag_and_desc(&ie->ie_tag,
554 		    UD_INDIRECT_ENT, ip->i_icb_block + 1,
555 		    1, udf_vfsp->udf_lbsize) == 0) {
556 			struct long_ad *lad;
557 
558 			lad = &ie->ie_indirecticb;
559 			ip->i_icb_prn = SWAP_16(lad->lad_ext_prn);
560 			ip->i_icb_block = SWAP_32(lad->lad_ext_loc);
561 			ip->i_icb_lbano = ud_xlate_to_daddr(udf_vfsp,
562 			    ip->i_icb_prn, ip->i_icb_block,
563 			    1, &dummy);
564 			brelse(ibp);
565 			brelse(bp);
566 			goto read_de;
567 		}
568 
569 		/*
570 		 * If this block is TE or unrecorded we
571 		 * are at the last entry
572 		 */
573 		if (ud_check_te_unrec(udf_vfsp, ibp->b_un.b_addr,
574 		    ip->i_icb_block + 1) != 0) {
575 			/*
576 			 * This is not an unrecorded block
577 			 * Check if it a valid IE and
578 			 * get the address of DE that
579 			 * this IE points to
580 			 */
581 			goto ie_error;
582 		}
583 		/*
584 		 * If ud_check_unrec returns "0"
585 		 * this is the last in the chain
586 		 * Latest file_entry
587 		 */
588 		brelse(ibp);
589 	}
590 
591 end_4096:
592 
593 	ip->i_uid = SWAP_32(fe->fe_uid);
594 	if (ip->i_uid == -1) {
595 		ip->i_uid = ud_default_uid;
596 	}
597 	ip->i_gid = SWAP_32(fe->fe_gid);
598 	if (ip->i_gid == -1) {
599 		ip->i_gid = ud_default_gid;
600 	}
601 	ip->i_perm = SWAP_32(fe->fe_perms) & 0xFFFF;
602 	if (fe->fe_icb_tag.itag_strategy == SWAP_16(STRAT_TYPE4096)) {
603 		ip->i_perm &= ~(IWRITE | (IWRITE >> 5) | (IWRITE >> 10));
604 	}
605 
606 	ip->i_nlink = SWAP_16(fe->fe_lcount);
607 	ip->i_size = SWAP_64(fe->fe_info_len);
608 	ip->i_lbr = SWAP_64(fe->fe_lbr);
609 
610 	ud_dtime2utime(&ip->i_atime, &fe->fe_acc_time);
611 	ud_dtime2utime(&ip->i_mtime, &fe->fe_mod_time);
612 	ud_dtime2utime(&ip->i_ctime, &fe->fe_attr_time);
613 
614 
615 	ip->i_uniqid = SWAP_64(fe->fe_uniq_id);
616 	icb_tag_flags = SWAP_16(fe->fe_icb_tag.itag_flags);
617 
618 	if ((fe->fe_icb_tag.itag_ftype == FTYPE_CHAR_DEV) ||
619 	    (fe->fe_icb_tag.itag_ftype == FTYPE_BLOCK_DEV)) {
620 
621 		eah = (struct ext_attr_hdr *)fe->fe_spec;
622 		ea_off = GET_32(&eah->eah_ial);
623 		ea_len = GET_32(&fe->fe_len_ear);
624 		if (ea_len && (ud_verify_tag_and_desc(&eah->eah_tag,
625 		    UD_EXT_ATTR_HDR, ip->i_icb_block, 1,
626 		    sizeof (struct file_entry) -
627 		    offsetof(struct file_entry, fe_spec)) == 0)) {
628 
629 			while (ea_off < ea_len) {
630 				/*
631 				 * We now check the validity of ea_off.
632 				 * (ea_len - ea_off) should be large enough to
633 				 * hold the attribute header atleast.
634 				 */
635 				if ((ea_len - ea_off) <
636 				    sizeof (struct attr_hdr)) {
637 					cmn_err(CE_NOTE,
638 					    "ea_len(0x%x) - ea_off(0x%x) is "
639 					    "too small to hold attr. info. "
640 					    "blockno 0x%x\n",
641 					    ea_len, ea_off, ip->i_icb_block);
642 					goto error_ret;
643 				}
644 				ah = (struct attr_hdr *)&fe->fe_spec[ea_off];
645 
646 				/*
647 				 * Device Specification EA
648 				 */
649 				if ((GET_32(&ah->ahdr_atype) == 12) &&
650 					(ah->ahdr_astype == 1)) {
651 					struct dev_spec_ear *ds;
652 
653 					if ((ea_len - ea_off) <
654 					    sizeof (struct dev_spec_ear)) {
655 						cmn_err(CE_NOTE,
656 						    "ea_len(0x%x) - "
657 						    "ea_off(0x%x) is too small "
658 						    "to hold dev_spec_ear."
659 						    " blockno 0x%x\n",
660 						    ea_len, ea_off,
661 						    ip->i_icb_block);
662 						goto error_ret;
663 					}
664 					ds = (struct dev_spec_ear *)ah;
665 					ip->i_major = GET_32(&ds->ds_major_id);
666 					ip->i_minor = GET_32(&ds->ds_minor_id);
667 				}
668 
669 				/*
670 				 * Impl Use EA
671 				 */
672 				if ((GET_32(&ah->ahdr_atype) == 2048) &&
673 					(ah->ahdr_astype == 1)) {
674 					struct iu_ea *iuea;
675 					struct copy_mgt_info *cmi;
676 
677 					if ((ea_len - ea_off) <
678 					    sizeof (struct iu_ea)) {
679 						cmn_err(CE_NOTE,
680 "ea_len(0x%x) - ea_off(0x%x) is too small to hold iu_ea. blockno 0x%x\n",
681 						    ea_len, ea_off,
682 						    ip->i_icb_block);
683 						goto error_ret;
684 					}
685 					iuea = (struct iu_ea *)ah;
686 					if (strncmp(iuea->iuea_ii.reg_id,
687 					    UDF_FREEEASPACE,
688 					    sizeof (iuea->iuea_ii.reg_id))
689 					    == 0) {
690 						/* skip it */
691 						iuea = iuea;
692 					} else if (strncmp(iuea->iuea_ii.reg_id,
693 					    UDF_CGMS_INFO,
694 					    sizeof (iuea->iuea_ii.reg_id))
695 					    == 0) {
696 						cmi = (struct copy_mgt_info *)
697 							iuea->iuea_iu;
698 						cmi = cmi;
699 					}
700 				}
701 				/* ??? PARANOIA */
702 				if (GET_32(&ah->ahdr_length) == 0) {
703 					break;
704 				}
705 				ea_off += GET_32(&ah->ahdr_length);
706 			}
707 		}
708 	}
709 
710 	ip->i_nextr = 0;
711 
712 	ip->i_maxent = SWAP_16(fe->fe_icb_tag.itag_max_ent);
713 	ip->i_astrat = SWAP_16(fe->fe_icb_tag.itag_strategy);
714 
715 	ip->i_desc_type = icb_tag_flags & 0x7;
716 
717 	/* Strictly Paranoia */
718 	ip->i_ext = NULL;
719 	ip->i_ext_count = ip->i_ext_used = 0;
720 	ip->i_con = 0;
721 	ip->i_con_count = ip->i_con_used = ip->i_con_read = 0;
722 
723 	ip->i_data_off = 0xB0 + SWAP_32(fe->fe_len_ear);
724 	ip->i_max_emb =  udf_vfsp->udf_lbsize - ip->i_data_off;
725 	if (ip->i_desc_type == ICB_FLAG_SHORT_AD) {
726 		/* Short allocation desc */
727 		struct short_ad *sad;
728 
729 		ip->i_ext_used = 0;
730 		ip->i_ext_count = ndesc =
731 		    SWAP_32(fe->fe_len_adesc) / sizeof (struct short_ad);
732 		ip->i_ext_count =
733 		    ((ip->i_ext_count / EXT_PER_MALLOC) + 1) * EXT_PER_MALLOC;
734 		ip->i_ext = (struct icb_ext  *)kmem_zalloc(ip->i_ext_count *
735 		    sizeof (struct icb_ext), KM_SLEEP);
736 		ip->i_cur_max_ext = ip->i_max_emb / sizeof (struct short_ad);
737 		ip->i_cur_max_ext --;
738 
739 		if ((ip->i_astrat != STRAT_TYPE4) &&
740 		    (ip->i_astrat != STRAT_TYPE4096)) {
741 			goto error_ret;
742 		}
743 
744 		sad = (struct short_ad *)
745 		    (fe->fe_spec + SWAP_32(fe->fe_len_ear));
746 		iext = ip->i_ext;
747 		while (ndesc --) {
748 			length = SWAP_32(sad->sad_ext_len);
749 			if ((length & 0x3FFFFFFF) == 0) {
750 				break;
751 			}
752 			if (((length >> 30) & IB_MASK) == IB_CON) {
753 				if (ip->i_con == NULL) {
754 					ip->i_con_count = EXT_PER_MALLOC;
755 					ip->i_con_used = 0;
756 					ip->i_con_read = 0;
757 					ip->i_con = kmem_zalloc(
758 					    ip->i_con_count *
759 					    sizeof (struct icb_ext),
760 					    KM_SLEEP);
761 				}
762 				con = &ip->i_con[ip->i_con_used];
763 				con->ib_prn = 0;
764 				con->ib_block = SWAP_32(sad->sad_ext_loc);
765 				con->ib_count = length & 0x3FFFFFFF;
766 				con->ib_flags = (length >> 30) & IB_MASK;
767 				ip->i_con_used++;
768 				sad ++;
769 				break;
770 			}
771 			iext->ib_prn = 0;
772 			iext->ib_block = SWAP_32(sad->sad_ext_loc);
773 			length = SWAP_32(sad->sad_ext_len);
774 			iext->ib_count = length & 0x3FFFFFFF;
775 			iext->ib_offset = offset;
776 			iext->ib_marker1 = (uint32_t)0xAAAAAAAA;
777 			iext->ib_marker2 = (uint32_t)0xBBBBBBBB;
778 			offset += (iext->ib_count + udf_vfsp->udf_lbmask) &
779 			    (~udf_vfsp->udf_lbmask);
780 
781 			iext->ib_flags = (length >> 30) & IB_MASK;
782 
783 			ip->i_ext_used++;
784 			iext++;
785 			sad ++;
786 		}
787 	} else if (ip->i_desc_type == ICB_FLAG_LONG_AD) {
788 		/* Long allocation desc */
789 		struct long_ad *lad;
790 
791 		ip->i_ext_used = 0;
792 		ip->i_ext_count = ndesc =
793 		    SWAP_32(fe->fe_len_adesc) / sizeof (struct long_ad);
794 		ip->i_ext_count =
795 		    ((ip->i_ext_count / EXT_PER_MALLOC) + 1) * EXT_PER_MALLOC;
796 		ip->i_ext = (struct icb_ext  *)kmem_zalloc(ip->i_ext_count *
797 		    sizeof (struct icb_ext), KM_SLEEP);
798 
799 		ip->i_cur_max_ext = ip->i_max_emb / sizeof (struct long_ad);
800 		ip->i_cur_max_ext --;
801 
802 		if ((ip->i_astrat != STRAT_TYPE4) &&
803 		    (ip->i_astrat != STRAT_TYPE4096)) {
804 			goto error_ret;
805 		}
806 
807 		lad = (struct long_ad *)
808 		    (fe->fe_spec + SWAP_32(fe->fe_len_ear));
809 		iext = ip->i_ext;
810 		while (ndesc --) {
811 			length = SWAP_32(lad->lad_ext_len);
812 			if ((length & 0x3FFFFFFF) == 0) {
813 				break;
814 			}
815 			if (((length >> 30) & IB_MASK) == IB_CON) {
816 				if (ip->i_con == NULL) {
817 					ip->i_con_count = EXT_PER_MALLOC;
818 					ip->i_con_used = 0;
819 					ip->i_con_read = 0;
820 					ip->i_con = kmem_zalloc(
821 					    ip->i_con_count *
822 					    sizeof (struct icb_ext),
823 					    KM_SLEEP);
824 				}
825 				con = &ip->i_con[ip->i_con_used];
826 				con->ib_prn = SWAP_16(lad->lad_ext_prn);
827 				con->ib_block = SWAP_32(lad->lad_ext_loc);
828 				con->ib_count = length & 0x3FFFFFFF;
829 				con->ib_flags = (length >> 30) & IB_MASK;
830 				ip->i_con_used++;
831 				lad ++;
832 				break;
833 			}
834 			iext->ib_prn = SWAP_16(lad->lad_ext_prn);
835 			iext->ib_block = SWAP_32(lad->lad_ext_loc);
836 			iext->ib_count = length & 0x3FFFFFFF;
837 			iext->ib_offset = offset;
838 			iext->ib_marker1 = (uint32_t)0xAAAAAAAA;
839 			iext->ib_marker2 = (uint32_t)0xBBBBBBBB;
840 			offset += (iext->ib_count + udf_vfsp->udf_lbmask) &
841 			    (~udf_vfsp->udf_lbmask);
842 
843 			iext->ib_flags = (length >> 30) & IB_MASK;
844 
845 			ip->i_ext_used++;
846 			iext++;
847 			lad ++;
848 		}
849 	} else if (ip->i_desc_type == ICB_FLAG_ONE_AD) {
850 		ASSERT(SWAP_32(fe->fe_len_ear) < udf_vfsp->udf_lbsize);
851 
852 		if (SWAP_32(fe->fe_len_ear) > udf_vfsp->udf_lbsize) {
853 			goto error_ret;
854 		}
855 	} else {
856 		/* Not to be used in UDF 1.50 */
857 		cmn_err(CE_NOTE, "Invalid Allocation Descriptor type %x\n",
858 		    ip->i_desc_type);
859 		goto error_ret;
860 	}
861 
862 
863 	if (icb_tag_flags & ICB_FLAG_SETUID) {
864 		ip->i_char = ISUID;
865 	} else {
866 		ip->i_char = 0;
867 	}
868 	if (icb_tag_flags & ICB_FLAG_SETGID) {
869 		ip->i_char |= ISGID;
870 	}
871 	if (icb_tag_flags & ICB_FLAG_STICKY) {
872 		ip->i_char |= ISVTX;
873 	}
874 	switch (fe->fe_icb_tag.itag_ftype) {
875 		case FTYPE_DIRECTORY :
876 			ip->i_type = VDIR;
877 			break;
878 		case FTYPE_FILE :
879 			ip->i_type = VREG;
880 			break;
881 		case FTYPE_BLOCK_DEV :
882 			ip->i_type = VBLK;
883 			break;
884 		case FTYPE_CHAR_DEV :
885 			ip->i_type = VCHR;
886 			break;
887 		case FTYPE_FIFO :
888 			ip->i_type = VFIFO;
889 			break;
890 		case FTYPE_C_ISSOCK :
891 			ip->i_type = VSOCK;
892 			break;
893 		case FTYPE_SYMLINK :
894 			ip->i_type = VLNK;
895 			break;
896 		default :
897 			ip->i_type = VNON;
898 			break;
899 	}
900 
901 	if (ip->i_type == VBLK || ip->i_type == VCHR) {
902 		ip->i_rdev = makedevice(ip->i_major, ip->i_minor);
903 	}
904 
905 	/*
906 	 * Fill in the rest.  Don't bother with the vnode lock because nobody
907 	 * should be looking at this vnode.  We have already invalidated the
908 	 * pages if it had any so pageout shouldn't be referencing this vnode
909 	 * and we are holding the write contents lock so a look up can't use
910 	 * the vnode.
911 	 */
912 	vp->v_vfsp = vfsp;
913 	vp->v_type = ip->i_type;
914 	vp->v_rdev = ip->i_rdev;
915 	if (ip->i_udf->udf_root_blkno == loc) {
916 		vp->v_flag = VROOT;
917 	} else {
918 		vp->v_flag = 0;
919 	}
920 
921 	brelse(bp);
922 	*ipp = ip;
923 	rw_exit(&ip->i_contents);
924 	vn_exists(vp);
925 	return (0);
926 }
927 
928 void
ud_iinactive(struct ud_inode * ip,struct cred * cr)929 ud_iinactive(struct ud_inode *ip, struct cred *cr)
930 {
931 	int32_t busy = 0;
932 	struct vnode *vp;
933 	vtype_t type;
934 	caddr_t addr, addr1;
935 	size_t size, size1;
936 
937 
938 	ud_printf("ud_iinactive\n");
939 
940 	/*
941 	 * Get exclusive access to inode data.
942 	 */
943 	rw_enter(&ip->i_contents, RW_WRITER);
944 
945 	/*
946 	 * Make sure no one reclaimed the inode before we put
947 	 * it on the freelist or destroy it. We keep our 'hold'
948 	 * on the vnode from vn_rele until we are ready to
949 	 * do something with the inode (freelist/destroy).
950 	 *
951 	 * Pageout may put a VN_HOLD/VN_RELE at anytime during this
952 	 * operation via an async putpage, so we must make sure
953 	 * we don't free/destroy the inode more than once. ud_iget
954 	 * may also put a VN_HOLD on the inode before it grabs
955 	 * the i_contents lock. This is done so we don't kmem_free
956 	 * an inode that a thread is waiting on.
957 	 */
958 	vp = ITOV(ip);
959 
960 	mutex_enter(&vp->v_lock);
961 	if (vp->v_count < 1) {
962 		cmn_err(CE_WARN, "ud_iinactive: v_count < 1\n");
963 		return;
964 	}
965 	if ((vp->v_count > 1) || ((ip->i_flag & IREF) == 0)) {
966 		VN_RELE_LOCKED(vp);
967 		mutex_exit(&vp->v_lock);
968 		rw_exit(&ip->i_contents);
969 		return;
970 	}
971 	mutex_exit(&vp->v_lock);
972 
973 	/*
974 	 * For forced umount case: if i_udf is NULL, the contents of
975 	 * the inode and all the pages have already been pushed back
976 	 * to disk. It can be safely destroyed.
977 	 */
978 	if (ip->i_udf == NULL) {
979 		addr = (caddr_t)ip->i_ext;
980 		size = sizeof (struct icb_ext) * ip->i_ext_count;
981 		ip->i_ext = 0;
982 		ip->i_ext_count = ip->i_ext_used = 0;
983 		addr1 = (caddr_t)ip->i_con;
984 		size1 = sizeof (struct icb_ext) * ip->i_con_count;
985 		ip->i_con = 0;
986 		ip->i_con_count = ip->i_con_used = ip->i_con_read = 0;
987 		rw_exit(&ip->i_contents);
988 		vn_invalid(vp);
989 
990 		mutex_enter(&ud_nino_lock);
991 		ud_cur_inodes--;
992 		mutex_exit(&ud_nino_lock);
993 
994 		cv_destroy(&ip->i_wrcv);  /* throttling */
995 		rw_destroy(&ip->i_rwlock);
996 		rw_exit(&ip->i_contents);
997 		rw_destroy(&ip->i_contents);
998 		kmem_free(addr, size);
999 		kmem_free(addr1, size1);
1000 		vn_free(vp);
1001 		kmem_free(ip, sizeof (struct ud_inode));
1002 		return;
1003 	}
1004 
1005 	if ((ip->i_udf->udf_flags & UDF_FL_RDONLY) == 0) {
1006 		if (ip->i_nlink <= 0) {
1007 			ip->i_marker3 = (uint32_t)0xDDDD0000;
1008 			ip->i_nlink = 1;	/* prevent free-ing twice */
1009 			(void) ud_itrunc(ip, 0, 0, cr);
1010 			type = ip->i_type;
1011 			ip->i_perm = 0;
1012 			ip->i_uid = 0;
1013 			ip->i_gid = 0;
1014 			ip->i_rdev = 0;	/* Zero in core version of rdev */
1015 			mutex_enter(&ip->i_tlock);
1016 			ip->i_flag |= IUPD|ICHG;
1017 			mutex_exit(&ip->i_tlock);
1018 			ud_ifree(ip, type);
1019 			ip->i_icb_prn = 0xFFFF;
1020 		} else if (!IS_SWAPVP(vp)) {
1021 			/*
1022 			 * Write the inode out if dirty. Pages are
1023 			 * written back and put on the freelist.
1024 			 */
1025 			(void) ud_syncip(ip, B_FREE | B_ASYNC, 0);
1026 			/*
1027 			 * Do nothing if inode is now busy -- inode may
1028 			 * have gone busy because ud_syncip
1029 			 * releases/reacquires the i_contents lock
1030 			 */
1031 			mutex_enter(&vp->v_lock);
1032 			if (vp->v_count > 1) {
1033 				VN_RELE_LOCKED(vp);
1034 				mutex_exit(&vp->v_lock);
1035 				rw_exit(&ip->i_contents);
1036 				return;
1037 			}
1038 			mutex_exit(&vp->v_lock);
1039 		} else {
1040 			ud_iupdat(ip, 0);
1041 		}
1042 	}
1043 
1044 
1045 	/*
1046 	 * Put the inode on the end of the free list.
1047 	 * Possibly in some cases it would be better to
1048 	 * put the inode at the head of the free list,
1049 	 * (e.g.: where i_perm == 0 || i_number == 0)
1050 	 * but I will think about that later.
1051 	 * (i_number is rarely 0 - only after an i/o error in ud_iget,
1052 	 * where i_perm == 0, the inode will probably be wanted
1053 	 * again soon for an ialloc, so possibly we should keep it)
1054 	 */
1055 	/*
1056 	 * If inode is invalid or there is no page associated with
1057 	 * this inode, put the inode in the front of the free list.
1058 	 * Since we have a VN_HOLD on the vnode, and checked that it
1059 	 * wasn't already on the freelist when we entered, we can safely
1060 	 * put it on the freelist even if another thread puts a VN_HOLD
1061 	 * on it (pageout/ud_iget).
1062 	 */
1063 tryagain:
1064 	mutex_enter(&ud_nino_lock);
1065 	if (vn_has_cached_data(vp)) {
1066 		mutex_exit(&ud_nino_lock);
1067 		mutex_enter(&vp->v_lock);
1068 		VN_RELE_LOCKED(vp);
1069 		mutex_exit(&vp->v_lock);
1070 		mutex_enter(&ip->i_tlock);
1071 		mutex_enter(&udf_ifree_lock);
1072 		ud_add_to_free_list(ip, UD_END);
1073 		mutex_exit(&udf_ifree_lock);
1074 		ip->i_flag &= IMODTIME;
1075 		mutex_exit(&ip->i_tlock);
1076 		rw_exit(&ip->i_contents);
1077 	} else if (busy || ud_cur_inodes < ud_max_inodes) {
1078 		mutex_exit(&ud_nino_lock);
1079 		/*
1080 		 * We're not over our high water mark, or it's
1081 		 * not safe to kmem_free the inode, so put it
1082 		 * on the freelist.
1083 		 */
1084 		mutex_enter(&vp->v_lock);
1085 		if (vn_has_cached_data(vp)) {
1086 			cmn_err(CE_WARN, "ud_iinactive: v_pages not NULL\n");
1087 		}
1088 		VN_RELE_LOCKED(vp);
1089 		mutex_exit(&vp->v_lock);
1090 
1091 	mutex_enter(&ip->i_tlock);
1092 		mutex_enter(&udf_ifree_lock);
1093 		ud_add_to_free_list(ip, UD_BEGIN);
1094 		mutex_exit(&udf_ifree_lock);
1095 	ip->i_flag &= IMODTIME;
1096 	mutex_exit(&ip->i_tlock);
1097 		rw_exit(&ip->i_contents);
1098 	} else {
1099 		mutex_exit(&ud_nino_lock);
1100 		if (vn_has_cached_data(vp)) {
1101 			cmn_err(CE_WARN, "ud_iinactive: v_pages not NULL\n");
1102 		}
1103 		/*
1104 		 * Try to free the inode. We must make sure
1105 		 * it's o.k. to destroy this inode. We can't destroy
1106 		 * if a thread is waiting for this inode. If we can't get the
1107 		 * cache now, put it back on the freelist.
1108 		 */
1109 		if (!mutex_tryenter(&ud_icache_lock)) {
1110 			busy = 1;
1111 			goto tryagain;
1112 		}
1113 		mutex_enter(&vp->v_lock);
1114 		if (vp->v_count > 1) {
1115 			/* inode is wanted in ud_iget */
1116 			busy = 1;
1117 			mutex_exit(&vp->v_lock);
1118 			mutex_exit(&ud_icache_lock);
1119 			goto tryagain;
1120 		}
1121 		mutex_exit(&vp->v_lock);
1122 		remque(ip);
1123 		ip->i_forw = ip;
1124 		ip->i_back = ip;
1125 		mutex_enter(&ud_nino_lock);
1126 		ud_cur_inodes--;
1127 		mutex_exit(&ud_nino_lock);
1128 		mutex_exit(&ud_icache_lock);
1129 		if (ip->i_icb_prn != 0xFFFF) {
1130 			ud_iupdat(ip, 0);
1131 		}
1132 		addr = (caddr_t)ip->i_ext;
1133 		size = sizeof (struct icb_ext) * ip->i_ext_count;
1134 		ip->i_ext = 0;
1135 		ip->i_ext_count = ip->i_ext_used = 0;
1136 		addr1 = (caddr_t)ip->i_con;
1137 		size1 = sizeof (struct icb_ext) * ip->i_con_count;
1138 		ip->i_con = 0;
1139 		ip->i_con_count = ip->i_con_used = ip->i_con_read = 0;
1140 		cv_destroy(&ip->i_wrcv);  /* throttling */
1141 		rw_destroy(&ip->i_rwlock);
1142 		rw_exit(&ip->i_contents);
1143 		rw_destroy(&ip->i_contents);
1144 		kmem_free(addr, size);
1145 		kmem_free(addr1, size1);
1146 		ip->i_marker3 = (uint32_t)0xDDDDDDDD;
1147 		vn_free(vp);
1148 		kmem_free(ip, sizeof (struct ud_inode));
1149 	}
1150 }
1151 
1152 
1153 void
ud_iupdat(struct ud_inode * ip,int32_t waitfor)1154 ud_iupdat(struct ud_inode *ip, int32_t waitfor)
1155 {
1156 	uint16_t flag, tag_flags;
1157 	int32_t error;
1158 	struct buf *bp;
1159 	struct udf_vfs *udf_vfsp;
1160 	struct file_entry *fe;
1161 	uint16_t crc_len = 0;
1162 
1163 	ASSERT(RW_WRITE_HELD(&ip->i_contents));
1164 
1165 	ud_printf("ud_iupdat\n");
1166 	/*
1167 	 * Return if file system has been forcibly umounted.
1168 	 */
1169 	if (ip->i_udf == NULL) {
1170 		return;
1171 	}
1172 
1173 	udf_vfsp = ip->i_udf;
1174 	flag = ip->i_flag;	/* Atomic read */
1175 	if ((flag & (IUPD|IACC|ICHG|IMOD|IMODACC)) != 0) {
1176 		if (udf_vfsp->udf_flags & UDF_FL_RDONLY) {
1177 			ip->i_flag &= ~(IUPD|IACC|ICHG|IMOD|IMODACC|IATTCHG);
1178 			return;
1179 		}
1180 
1181 		bp = ud_bread(ip->i_dev,
1182 		    ip->i_icb_lbano << udf_vfsp->udf_l2d_shift,
1183 		    ip->i_udf->udf_lbsize);
1184 		if (bp->b_flags & B_ERROR) {
1185 			brelse(bp);
1186 			return;
1187 		}
1188 		fe = (struct file_entry *)bp->b_un.b_addr;
1189 		if (ud_verify_tag_and_desc(&fe->fe_tag, UD_FILE_ENTRY,
1190 		    ip->i_icb_block,
1191 		    1, ip->i_udf->udf_lbsize) != 0) {
1192 			brelse(bp);
1193 			return;
1194 		}
1195 
1196 		mutex_enter(&ip->i_tlock);
1197 		if (ip->i_flag & (IUPD|IACC|ICHG)) {
1198 			IMARK(ip);
1199 		}
1200 		ip->i_flag &= ~(IUPD|IACC|ICHG|IMOD|IMODACC);
1201 		mutex_exit(&ip->i_tlock);
1202 
1203 		fe->fe_uid = SWAP_32(ip->i_uid);
1204 		fe->fe_gid = SWAP_32(ip->i_gid);
1205 
1206 		fe->fe_perms = SWAP_32(ip->i_perm);
1207 
1208 		fe->fe_lcount = SWAP_16(ip->i_nlink);
1209 		fe->fe_info_len = SWAP_64(ip->i_size);
1210 		fe->fe_lbr = SWAP_64(ip->i_lbr);
1211 
1212 		ud_utime2dtime(&ip->i_atime, &fe->fe_acc_time);
1213 		ud_utime2dtime(&ip->i_mtime, &fe->fe_mod_time);
1214 		ud_utime2dtime(&ip->i_ctime, &fe->fe_attr_time);
1215 
1216 		if (ip->i_char & ISUID) {
1217 			tag_flags = ICB_FLAG_SETUID;
1218 		} else {
1219 			tag_flags = 0;
1220 		}
1221 		if (ip->i_char & ISGID) {
1222 			tag_flags |= ICB_FLAG_SETGID;
1223 		}
1224 		if (ip->i_char & ISVTX) {
1225 			tag_flags |= ICB_FLAG_STICKY;
1226 		}
1227 		tag_flags |= ip->i_desc_type;
1228 
1229 		/*
1230 		 * Remove the following it is no longer contig
1231 		 * if (ip->i_astrat  == STRAT_TYPE4) {
1232 		 *	tag_flags |= ICB_FLAG_CONTIG;
1233 		 * }
1234 		 */
1235 
1236 		fe->fe_icb_tag.itag_flags &= ~SWAP_16((uint16_t)0x3C3);
1237 		fe->fe_icb_tag.itag_strategy = SWAP_16(ip->i_astrat);
1238 		fe->fe_icb_tag.itag_flags |= SWAP_16(tag_flags);
1239 
1240 		ud_update_regid(&fe->fe_impl_id);
1241 
1242 		crc_len = offsetof(struct file_entry, fe_spec) +
1243 		    SWAP_32(fe->fe_len_ear);
1244 		if (ip->i_desc_type == ICB_FLAG_ONE_AD) {
1245 			crc_len += ip->i_size;
1246 			fe->fe_len_adesc = SWAP_32(((uint32_t)ip->i_size));
1247 		} else if ((ip->i_size != 0) && (ip->i_ext != NULL) &&
1248 		    (ip->i_ext_used != 0)) {
1249 
1250 			if ((error = ud_read_icb_till_off(ip,
1251 			    ip->i_size)) == 0) {
1252 				if (ip->i_astrat == STRAT_TYPE4) {
1253 					error = ud_updat_ext4(ip, fe);
1254 				} else if (ip->i_astrat == STRAT_TYPE4096) {
1255 					error = ud_updat_ext4096(ip, fe);
1256 				}
1257 				if (error) {
1258 					udf_vfsp->udf_mark_bad = 1;
1259 				}
1260 			}
1261 			crc_len += SWAP_32(fe->fe_len_adesc);
1262 		} else {
1263 			fe->fe_len_adesc = 0;
1264 		}
1265 
1266 		/*
1267 		 * Zero out the rest of the block
1268 		 */
1269 		bzero(bp->b_un.b_addr + crc_len,
1270 		    ip->i_udf->udf_lbsize - crc_len);
1271 
1272 		ud_make_tag(ip->i_udf, &fe->fe_tag,
1273 		    UD_FILE_ENTRY, ip->i_icb_block, crc_len);
1274 
1275 
1276 		if (waitfor) {
1277 			BWRITE(bp);
1278 
1279 			/*
1280 			 * Synchronous write has guaranteed that inode
1281 			 * has been written on disk so clear the flag
1282 			 */
1283 			ip->i_flag &= ~(IBDWRITE);
1284 		} else {
1285 			bdwrite(bp);
1286 
1287 			/*
1288 			 * This write hasn't guaranteed that inode has been
1289 			 * written on the disk.
1290 			 * Since, all updat flags on indoe are cleared, we must
1291 			 * remember the condition in case inode is to be updated
1292 			 * synchronously later (e.g.- fsync()/fdatasync())
1293 			 * and inode has not been modified yet.
1294 			 */
1295 			ip->i_flag |= (IBDWRITE);
1296 		}
1297 	} else {
1298 		/*
1299 		 * In case previous inode update was done asynchronously
1300 		 * (IBDWRITE) and this inode update request wants guaranteed
1301 		 * (synchronous) disk update, flush the inode.
1302 		 */
1303 		if (waitfor && (flag & IBDWRITE)) {
1304 			blkflush(ip->i_dev,
1305 			    (daddr_t)fsbtodb(udf_vfsp, ip->i_icb_lbano));
1306 			ip->i_flag &= ~(IBDWRITE);
1307 		}
1308 	}
1309 }
1310 
1311 int32_t
ud_updat_ext4(struct ud_inode * ip,struct file_entry * fe)1312 ud_updat_ext4(struct ud_inode *ip, struct file_entry *fe)
1313 {
1314 	uint32_t dummy;
1315 	int32_t elen, ndent, index, count, con_index;
1316 	daddr_t bno;
1317 	struct buf *bp;
1318 	struct short_ad *sad;
1319 	struct long_ad *lad;
1320 	struct icb_ext *iext, *icon;
1321 
1322 
1323 	ASSERT(ip);
1324 	ASSERT(fe);
1325 	ASSERT((ip->i_desc_type == ICB_FLAG_SHORT_AD) ||
1326 	    (ip->i_desc_type == ICB_FLAG_LONG_AD));
1327 
1328 	if (ip->i_desc_type == ICB_FLAG_SHORT_AD) {
1329 		elen = sizeof (struct short_ad);
1330 		sad = (struct short_ad *)
1331 		    (fe->fe_spec + SWAP_32(fe->fe_len_ear));
1332 	} else if (ip->i_desc_type == ICB_FLAG_LONG_AD) {
1333 		elen = sizeof (struct long_ad);
1334 		lad = (struct long_ad *)
1335 		    (fe->fe_spec + SWAP_32(fe->fe_len_ear));
1336 	} else {
1337 		/* This cannot happen return */
1338 		return (EINVAL);
1339 	}
1340 
1341 	ndent = ip->i_max_emb / elen;
1342 
1343 	if (ip->i_ext_used < ndent) {
1344 
1345 		if (ip->i_desc_type == ICB_FLAG_SHORT_AD) {
1346 			ud_make_sad(ip->i_ext, sad, ip->i_ext_used);
1347 		} else {
1348 			ud_make_lad(ip->i_ext, lad, ip->i_ext_used);
1349 		}
1350 		fe->fe_len_adesc = SWAP_32(ip->i_ext_used * elen);
1351 		con_index = 0;
1352 	} else {
1353 
1354 		con_index = index = 0;
1355 
1356 		while (index < ip->i_ext_used) {
1357 			if (index == 0) {
1358 				/*
1359 				 * bp is already read
1360 				 * First few extents will go
1361 				 * into the file_entry
1362 				 */
1363 				count = ndent - 1;
1364 				fe->fe_len_adesc = SWAP_32(ndent * elen);
1365 				bp = NULL;
1366 
1367 				/*
1368 				 * Last entry to be cont ext
1369 				 */
1370 				icon = &ip->i_con[con_index];
1371 			} else {
1372 				/*
1373 				 * Read the buffer
1374 				 */
1375 				icon = &ip->i_con[con_index];
1376 
1377 				bno = ud_xlate_to_daddr(ip->i_udf,
1378 				    icon->ib_prn, icon->ib_block,
1379 				    icon->ib_count >> ip->i_udf->udf_l2d_shift,
1380 				    &dummy);
1381 				bp = ud_bread(ip->i_dev,
1382 				    bno << ip->i_udf->udf_l2d_shift,
1383 				    ip->i_udf->udf_lbsize);
1384 				if (bp->b_flags & B_ERROR) {
1385 					brelse(bp);
1386 					return (EIO);
1387 				}
1388 
1389 				/*
1390 				 * Figure out how many extents in
1391 				 * this time
1392 				 */
1393 				count = (bp->b_bcount -
1394 				    sizeof (struct alloc_ext_desc)) / elen;
1395 				if (count > (ip->i_ext_used - index)) {
1396 					count = ip->i_ext_used - index;
1397 				} else {
1398 					count --;
1399 				}
1400 				con_index++;
1401 				if (con_index >= ip->i_con_used) {
1402 					icon = NULL;
1403 				} else {
1404 					icon = &ip->i_con[con_index];
1405 				}
1406 			}
1407 
1408 
1409 
1410 			/*
1411 			 * convert to on disk form and
1412 			 * update
1413 			 */
1414 			iext = &ip->i_ext[index];
1415 			if (ip->i_desc_type == ICB_FLAG_SHORT_AD) {
1416 				if (index != 0) {
1417 					sad = (struct short_ad *)
1418 					    (bp->b_un.b_addr +
1419 					    sizeof (struct alloc_ext_desc));
1420 				}
1421 				ud_make_sad(iext, sad, count);
1422 				sad += count;
1423 				if (icon != NULL) {
1424 					ud_make_sad(icon, sad, 1);
1425 				}
1426 			} else {
1427 				if (index != 0) {
1428 					lad = (struct long_ad *)
1429 					    (bp->b_un.b_addr +
1430 					    sizeof (struct alloc_ext_desc));
1431 				}
1432 				ud_make_lad(iext, lad, count);
1433 				lad += count;
1434 				if (icon != NULL) {
1435 					ud_make_lad(icon, lad, 1);
1436 				}
1437 			}
1438 
1439 			if (con_index != 0) {
1440 				struct alloc_ext_desc *aed;
1441 				int32_t sz;
1442 				struct icb_ext *oicon;
1443 
1444 				oicon = &ip->i_con[con_index - 1];
1445 				sz = count * elen;
1446 				if (icon != NULL) {
1447 					sz += elen;
1448 				}
1449 				aed = (struct alloc_ext_desc *)bp->b_un.b_addr;
1450 				aed->aed_len_aed = SWAP_32(sz);
1451 				if (con_index == 1) {
1452 					aed->aed_rev_ael =
1453 					    SWAP_32(ip->i_icb_block);
1454 				} else {
1455 					aed->aed_rev_ael =
1456 					    SWAP_32(oicon->ib_block);
1457 				}
1458 				sz += sizeof (struct alloc_ext_desc);
1459 				ud_make_tag(ip->i_udf, &aed->aed_tag,
1460 				    UD_ALLOC_EXT_DESC, oicon->ib_block, sz);
1461 			}
1462 
1463 			/*
1464 			 * Write back to disk
1465 			 */
1466 			if (bp != NULL) {
1467 				BWRITE(bp);
1468 			}
1469 			index += count;
1470 		}
1471 
1472 	}
1473 
1474 	if (con_index != ip->i_con_used) {
1475 		int32_t lbmask, l2b, temp;
1476 
1477 		temp = con_index;
1478 		lbmask = ip->i_udf->udf_lbmask;
1479 		l2b = ip->i_udf->udf_l2b_shift;
1480 		/*
1481 		 * Free unused continuation extents
1482 		 */
1483 		for (; con_index < ip->i_con_used; con_index++) {
1484 			icon = &ip->i_con[con_index];
1485 			count = (icon->ib_count + lbmask) >> l2b;
1486 			ud_free_space(ip->i_udf->udf_vfs, icon->ib_prn,
1487 			    icon->ib_block, count);
1488 			count = (count << l2b) - sizeof (struct alloc_ext_desc);
1489 			ip->i_cur_max_ext -= (count / elen) - 1;
1490 		}
1491 		ip->i_con_used = temp;
1492 	}
1493 	return (0);
1494 }
1495 
1496 /* ARGSUSED */
1497 int32_t
ud_updat_ext4096(struct ud_inode * ip,struct file_entry * fe)1498 ud_updat_ext4096(struct ud_inode *ip, struct file_entry *fe)
1499 {
1500 	return (ENXIO);
1501 }
1502 
1503 void
ud_make_sad(struct icb_ext * iext,struct short_ad * sad,int32_t count)1504 ud_make_sad(struct icb_ext *iext, struct short_ad *sad, int32_t count)
1505 {
1506 	int32_t index = 0, scount;
1507 
1508 	ASSERT(iext);
1509 	ASSERT(sad);
1510 
1511 	if (count != 0) {
1512 		ASSERT(count > 0);
1513 		while (index < count) {
1514 			scount = (iext->ib_count & 0x3FFFFFFF) |
1515 			    (iext->ib_flags << 30);
1516 			sad->sad_ext_len = SWAP_32(scount);
1517 			sad->sad_ext_loc = SWAP_32(iext->ib_block);
1518 			sad++;
1519 			iext++;
1520 			index++;
1521 		}
1522 	}
1523 }
1524 
1525 void
ud_make_lad(struct icb_ext * iext,struct long_ad * lad,int32_t count)1526 ud_make_lad(struct icb_ext *iext, struct long_ad *lad, int32_t count)
1527 {
1528 	int32_t index = 0, scount;
1529 
1530 	ASSERT(iext);
1531 	ASSERT(lad);
1532 
1533 	if (count != 0) {
1534 		ASSERT(count > 0);
1535 
1536 		while (index < count) {
1537 			lad->lad_ext_prn = SWAP_16(iext->ib_prn);
1538 			scount = (iext->ib_count & 0x3FFFFFFF) |
1539 			    (iext->ib_flags << 30);
1540 			lad->lad_ext_len = SWAP_32(scount);
1541 			lad->lad_ext_loc = SWAP_32(iext->ib_block);
1542 			lad++;
1543 			iext++;
1544 			index++;
1545 		}
1546 	}
1547 }
1548 
1549 /*
1550  * Truncate the inode ip to at most length size.
1551  * Free affected disk blocks -- the blocks of the
1552  * file are removed in reverse order.
1553  */
1554 /* ARGSUSED */
1555 int
ud_itrunc(struct ud_inode * oip,u_offset_t length,int32_t flags,struct cred * cr)1556 ud_itrunc(struct ud_inode *oip, u_offset_t length,
1557     int32_t flags, struct cred *cr)
1558 {
1559 	int32_t error, boff;
1560 	off_t bsize;
1561 	mode_t mode;
1562 	struct udf_vfs *udf_vfsp;
1563 
1564 	ud_printf("ud_itrunc\n");
1565 
1566 	ASSERT(RW_WRITE_HELD(&oip->i_contents));
1567 	udf_vfsp = oip->i_udf;
1568 	bsize = udf_vfsp->udf_lbsize;
1569 
1570 	/*
1571 	 * We only allow truncation of regular files and directories
1572 	 * to arbritary lengths here.  In addition, we allow symbolic
1573 	 * links to be truncated only to zero length.  Other inode
1574 	 * types cannot have their length set here.
1575 	 */
1576 	mode = oip->i_type;
1577 	if (mode == VFIFO) {
1578 		return (0);
1579 	}
1580 	if ((mode != VREG) && (mode != VDIR) &&
1581 	    (!(mode == VLNK && length == 0))) {
1582 		return (EINVAL);
1583 	}
1584 	if (length == oip->i_size) {
1585 		/* update ctime and mtime to please POSIX tests */
1586 		mutex_enter(&oip->i_tlock);
1587 		oip->i_flag |= ICHG |IUPD;
1588 		mutex_exit(&oip->i_tlock);
1589 		return (0);
1590 	}
1591 
1592 	boff = blkoff(udf_vfsp, length);
1593 
1594 	if (length > oip->i_size) {
1595 		/*
1596 		 * Trunc up case.ud_bmap_write will insure that the right blocks
1597 		 * are allocated.  This includes doing any work needed for
1598 		 * allocating the last block.
1599 		 */
1600 		if (boff == 0) {
1601 			error = ud_bmap_write(oip, length - 1,
1602 			    (int)bsize, 0, cr);
1603 		} else {
1604 			error = ud_bmap_write(oip, length - 1, boff, 0, cr);
1605 		}
1606 		if (error == 0) {
1607 			u_offset_t osize = oip->i_size;
1608 			oip->i_size  = length;
1609 
1610 			/*
1611 			 * Make sure we zero out the remaining bytes of
1612 			 * the page in case a mmap scribbled on it. We
1613 			 * can't prevent a mmap from writing beyond EOF
1614 			 * on the last page of a file.
1615 			 */
1616 			if ((boff = blkoff(udf_vfsp, osize)) != 0) {
1617 				pvn_vpzero(ITOV(oip), osize,
1618 				    (uint32_t)(bsize - boff));
1619 			}
1620 			mutex_enter(&oip->i_tlock);
1621 			oip->i_flag |= ICHG;
1622 			ITIMES_NOLOCK(oip);
1623 			mutex_exit(&oip->i_tlock);
1624 		}
1625 		return (error);
1626 	}
1627 
1628 	/*
1629 	 * Update the pages of the file.  If the file is not being
1630 	 * truncated to a block boundary, the contents of the
1631 	 * pages following the end of the file must be zero'ed
1632 	 * in case it ever become accessable again because
1633 	 * of subsequent file growth.
1634 	 */
1635 	if (boff == 0) {
1636 		(void) pvn_vplist_dirty(ITOV(oip), length,
1637 		    ud_putapage, B_INVAL | B_TRUNC, CRED());
1638 	} else {
1639 		/*
1640 		 * Make sure that the last block is properly allocated.
1641 		 * We only really have to do this if the last block is
1642 		 * actually allocated.  Just to be sure, we do it now
1643 		 * independent of current allocation.
1644 		 */
1645 		error = ud_bmap_write(oip, length - 1, boff, 0, cr);
1646 		if (error) {
1647 			return (error);
1648 		}
1649 
1650 		pvn_vpzero(ITOV(oip), length, (uint32_t)(bsize - boff));
1651 
1652 		(void) pvn_vplist_dirty(ITOV(oip), length,
1653 		    ud_putapage, B_INVAL | B_TRUNC, CRED());
1654 	}
1655 
1656 
1657 	/* Free the blocks */
1658 	if (oip->i_desc_type == ICB_FLAG_ONE_AD) {
1659 		if (length > oip->i_max_emb) {
1660 			return (EFBIG);
1661 		}
1662 		oip->i_size = length;
1663 		mutex_enter(&oip->i_tlock);
1664 		oip->i_flag |= ICHG|IUPD;
1665 		mutex_exit(&oip->i_tlock);
1666 		ud_iupdat(oip, 1);
1667 	} else {
1668 		if ((error = ud_read_icb_till_off(oip, oip->i_size)) != 0) {
1669 			return (error);
1670 		}
1671 
1672 		if (oip->i_astrat == STRAT_TYPE4) {
1673 			ud_trunc_ext4(oip, length);
1674 		} else if (oip->i_astrat == STRAT_TYPE4096) {
1675 			ud_trunc_ext4096(oip, length);
1676 		}
1677 	}
1678 
1679 done:
1680 	return (0);
1681 }
1682 
1683 void
ud_trunc_ext4(struct ud_inode * ip,u_offset_t length)1684 ud_trunc_ext4(struct ud_inode *ip, u_offset_t length)
1685 {
1686 	int32_t index, l2b, count, ecount;
1687 	int32_t elen, ndent, nient;
1688 	u_offset_t ext_beg, ext_end;
1689 	struct icb_ext *iext, *icon;
1690 	int32_t lbmask, ext_used;
1691 	uint32_t loc;
1692 	struct icb_ext text;
1693 	uint32_t con_freed;
1694 
1695 	ASSERT((ip->i_desc_type == ICB_FLAG_SHORT_AD) ||
1696 	    (ip->i_desc_type == ICB_FLAG_LONG_AD));
1697 
1698 	if (ip->i_ext_used == 0) {
1699 		return;
1700 	}
1701 
1702 	ext_used = ip->i_ext_used;
1703 
1704 	lbmask = ip->i_udf->udf_lbmask;
1705 	l2b = ip->i_udf->udf_l2b_shift;
1706 
1707 	ASSERT(ip->i_ext);
1708 
1709 	ip->i_lbr = 0;
1710 	for (index = 0; index < ext_used; index++) {
1711 		iext = &ip->i_ext[index];
1712 
1713 		/*
1714 		 * Find the begining and end
1715 		 * of current extent
1716 		 */
1717 		ext_beg = iext->ib_offset;
1718 		ext_end = iext->ib_offset +
1719 		    ((iext->ib_count + lbmask) & ~lbmask);
1720 
1721 		/*
1722 		 * This is the extent that has offset "length"
1723 		 * make a copy of this extent and
1724 		 * remember the index. We can use
1725 		 * it to free blocks
1726 		 */
1727 		if ((length <= ext_end) && (length >= ext_beg)) {
1728 			text = *iext;
1729 
1730 			iext->ib_count = length - ext_beg;
1731 			ip->i_ext_used = index + 1;
1732 			break;
1733 		}
1734 		if (iext->ib_flags != IB_UN_RE_AL) {
1735 			ip->i_lbr += iext->ib_count >> l2b;
1736 		}
1737 	}
1738 	if (ip->i_ext_used != index) {
1739 		if (iext->ib_flags != IB_UN_RE_AL) {
1740 			ip->i_lbr +=
1741 			    ((iext->ib_count + lbmask) & ~lbmask) >> l2b;
1742 		}
1743 	}
1744 
1745 	ip->i_size = length;
1746 	mutex_enter(&ip->i_tlock);
1747 	ip->i_flag |= ICHG|IUPD;
1748 	mutex_exit(&ip->i_tlock);
1749 	ud_iupdat(ip, 1);
1750 
1751 	/*
1752 	 * Free the unused space
1753 	 */
1754 	if (text.ib_flags != IB_UN_RE_AL) {
1755 		count = (ext_end - length) >> l2b;
1756 		if (count) {
1757 			loc = text.ib_block +
1758 			    (((length - text.ib_offset) + lbmask) >> l2b);
1759 			ud_free_space(ip->i_udf->udf_vfs, text.ib_prn,
1760 			    loc, count);
1761 		}
1762 	}
1763 	for (index = ip->i_ext_used; index < ext_used; index++) {
1764 		iext = &ip->i_ext[index];
1765 		if (iext->ib_flags != IB_UN_RE_AL) {
1766 			count = (iext->ib_count + lbmask) >> l2b;
1767 			ud_free_space(ip->i_udf->udf_vfs, iext->ib_prn,
1768 			    iext->ib_block, count);
1769 		}
1770 		bzero(iext, sizeof (struct icb_ext));
1771 		continue;
1772 	}
1773 
1774 	/*
1775 	 * release any continuation blocks
1776 	 */
1777 	if (ip->i_con) {
1778 
1779 		ASSERT(ip->i_con_count >= ip->i_con_used);
1780 
1781 		/*
1782 		 * Find out how many indirect blocks
1783 		 * are required and release the rest
1784 		 */
1785 		if (ip->i_desc_type == ICB_FLAG_SHORT_AD) {
1786 			elen = sizeof (struct short_ad);
1787 		} else if (ip->i_desc_type == ICB_FLAG_LONG_AD) {
1788 			elen = sizeof (struct long_ad);
1789 		}
1790 		ndent = ip->i_max_emb / elen;
1791 		if (ip->i_ext_used > ndent) {
1792 			ecount = ip->i_ext_used - ndent;
1793 		} else {
1794 			ecount = 0;
1795 		}
1796 		con_freed = 0;
1797 		for (index = 0; index < ip->i_con_used; index++) {
1798 			icon = &ip->i_con[index];
1799 			nient = icon->ib_count -
1800 			    (sizeof (struct alloc_ext_desc) + elen);
1801 			/* Header + 1 indirect extent */
1802 			nient /= elen;
1803 			if (ecount) {
1804 				if (ecount > nient) {
1805 					ecount -= nient;
1806 				} else {
1807 					ecount = 0;
1808 				}
1809 			} else {
1810 				count = ((icon->ib_count + lbmask) &
1811 				    ~lbmask) >> l2b;
1812 				ud_free_space(ip->i_udf->udf_vfs,
1813 				    icon->ib_prn, icon->ib_block, count);
1814 				con_freed++;
1815 				ip->i_cur_max_ext -= nient;
1816 			}
1817 		}
1818 		/*
1819 		 * set the continuation extents used(i_con_used)i to correct
1820 		 * value. It is possible for i_con_used to be zero,
1821 		 * if we free up all continuation extents. This happens
1822 		 * when ecount is 0 before entering the for loop above.
1823 		 */
1824 		ip->i_con_used -= con_freed;
1825 		if (ip->i_con_read > ip->i_con_used) {
1826 			ip->i_con_read = ip->i_con_used;
1827 		}
1828 	}
1829 }
1830 
1831 void
ud_trunc_ext4096(struct ud_inode * ip,u_offset_t length)1832 ud_trunc_ext4096(struct ud_inode *ip, u_offset_t length)
1833 {
1834 	/*
1835 	 * Truncate code is the same for
1836 	 * both file of type 4 and 4096
1837 	 */
1838 	ud_trunc_ext4(ip, length);
1839 }
1840 
1841 /*
1842  * Remove any inodes in the inode cache belonging to dev
1843  *
1844  * There should not be any active ones, return error if any are found but
1845  * still invalidate others (N.B.: this is a user error, not a system error).
1846  *
1847  * Also, count the references to dev by block devices - this really
1848  * has nothing to do with the object of the procedure, but as we have
1849  * to scan the inode table here anyway, we might as well get the
1850  * extra benefit.
1851  */
1852 int32_t
ud_iflush(struct vfs * vfsp)1853 ud_iflush(struct vfs *vfsp)
1854 {
1855 	int32_t index, busy = 0;
1856 	union ihead *ih;
1857 	struct udf_vfs *udf_vfsp;
1858 	dev_t dev;
1859 	struct vnode *rvp, *vp;
1860 	struct ud_inode *ip, *next;
1861 
1862 	ud_printf("ud_iflush\n");
1863 	udf_vfsp = (struct udf_vfs *)vfsp->vfs_data;
1864 	rvp = udf_vfsp->udf_root;
1865 	dev = vfsp->vfs_dev;
1866 
1867 	mutex_enter(&ud_icache_lock);
1868 	for (index = 0; index < UD_HASH_SZ; index++) {
1869 		ih = &ud_ihead[index];
1870 
1871 		next = ih->ih_chain[0];
1872 		while (next != (struct ud_inode *)ih) {
1873 			ip = next;
1874 			next = ip->i_forw;
1875 			if (ip->i_dev != dev) {
1876 				continue;
1877 			}
1878 			vp = ITOV(ip);
1879 			/*
1880 			 * root inode is processed by the caller
1881 			 */
1882 			if (vp == rvp) {
1883 				if (vp->v_count > 1) {
1884 					busy = -1;
1885 				}
1886 				continue;
1887 			}
1888 			if (ip->i_flag & IREF) {
1889 				/*
1890 				 * Set error indicator for return value,
1891 				 * but continue invalidating other
1892 				 * inodes.
1893 				 */
1894 				busy = -1;
1895 				continue;
1896 			}
1897 
1898 			rw_enter(&ip->i_contents, RW_WRITER);
1899 			remque(ip);
1900 			ip->i_forw = ip;
1901 			ip->i_back = ip;
1902 			/*
1903 			 * Hold the vnode since its not done
1904 			 * in VOP_PUTPAGE anymore.
1905 			 */
1906 			VN_HOLD(vp);
1907 			/*
1908 			 * XXX Synchronous write holding
1909 			 * cache lock
1910 			 */
1911 			(void) ud_syncip(ip, B_INVAL, I_SYNC);
1912 			rw_exit(&ip->i_contents);
1913 			VN_RELE(vp);
1914 		}
1915 	}
1916 	mutex_exit(&ud_icache_lock);
1917 
1918 	return (busy);
1919 }
1920 
1921 
1922 /*
1923  * Check mode permission on inode.  Mode is READ, WRITE or EXEC.
1924  * In the case of WRITE, the read-only status of the file system
1925  * is checked.  The applicable mode bits are compared with the
1926  * requested form of access.  If bits are missing, the secpolicy
1927  * function will check for privileges.
1928  */
1929 int
ud_iaccess(struct ud_inode * ip,int32_t mode,struct cred * cr,int dolock)1930 ud_iaccess(struct ud_inode *ip, int32_t mode, struct cred *cr, int dolock)
1931 {
1932 	int shift = 0;
1933 	int ret = 0;
1934 
1935 	if (dolock)
1936 		rw_enter(&ip->i_contents, RW_READER);
1937 	ASSERT(RW_LOCK_HELD(&ip->i_contents));
1938 
1939 	ud_printf("ud_iaccess\n");
1940 	if (mode & IWRITE) {
1941 		/*
1942 		 * Disallow write attempts on read-only
1943 		 * file systems, unless the file is a block
1944 		 * or character device or a FIFO.
1945 		 */
1946 		if (ip->i_udf->udf_flags & UDF_FL_RDONLY) {
1947 			if ((ip->i_type != VCHR) &&
1948 			    (ip->i_type != VBLK) &&
1949 			    (ip->i_type != VFIFO)) {
1950 				ret = EROFS;
1951 				goto out;
1952 			}
1953 		}
1954 	}
1955 
1956 	/*
1957 	 * Access check is based on only
1958 	 * one of owner, group, public.
1959 	 * If not owner, then check group.
1960 	 * If not a member of the group, then
1961 	 * check public access.
1962 	 */
1963 	if (crgetuid(cr) != ip->i_uid) {
1964 		shift += 5;
1965 		if (!groupmember((uid_t)ip->i_gid, cr))
1966 			shift += 5;
1967 	}
1968 
1969 	ret = secpolicy_vnode_access2(cr, ITOV(ip), ip->i_uid,
1970 	    UD2VA_PERM(ip->i_perm << shift), UD2VA_PERM(mode));
1971 
1972 out:
1973 	if (dolock)
1974 		rw_exit(&ip->i_contents);
1975 	return (ret);
1976 }
1977 
1978 void
ud_imark(struct ud_inode * ip)1979 ud_imark(struct ud_inode *ip)
1980 {
1981 	timestruc_t	now;
1982 
1983 	gethrestime(&now);
1984 	ud_printf("ud_imark\n");
1985 	if (ip->i_flag & IACC) {
1986 		ip->i_atime.tv_sec = now.tv_sec;
1987 		ip->i_atime.tv_nsec = now.tv_nsec;
1988 	}
1989 	if (ip->i_flag & IUPD) {
1990 		ip->i_mtime.tv_sec = now.tv_sec;
1991 		ip->i_mtime.tv_nsec = now.tv_nsec;
1992 		ip->i_flag |= IMODTIME;
1993 	}
1994 	if (ip->i_flag & ICHG) {
1995 		ip->i_diroff = 0;
1996 		ip->i_ctime.tv_sec = now.tv_sec;
1997 		ip->i_ctime.tv_nsec = now.tv_nsec;
1998 	}
1999 }
2000 
2001 
2002 void
ud_itimes_nolock(struct ud_inode * ip)2003 ud_itimes_nolock(struct ud_inode *ip)
2004 {
2005 	ud_printf("ud_itimes_nolock\n");
2006 
2007 	if (ip->i_flag & (IUPD|IACC|ICHG)) {
2008 		if (ip->i_flag & ICHG) {
2009 			ip->i_flag |= IMOD;
2010 		} else {
2011 			ip->i_flag |= IMODACC;
2012 		}
2013 		ud_imark(ip);
2014 		ip->i_flag &= ~(IACC|IUPD|ICHG);
2015 	}
2016 }
2017 
2018 void
ud_delcache(struct ud_inode * ip)2019 ud_delcache(struct ud_inode *ip)
2020 {
2021 	ud_printf("ud_delcache\n");
2022 
2023 	mutex_enter(&ud_icache_lock);
2024 	remque(ip);
2025 	ip->i_forw = ip;
2026 	ip->i_back = ip;
2027 	mutex_exit(&ud_icache_lock);
2028 }
2029 
2030 void
ud_idrop(struct ud_inode * ip)2031 ud_idrop(struct ud_inode *ip)
2032 {
2033 	struct vnode *vp = ITOV(ip);
2034 
2035 	ASSERT(RW_WRITE_HELD(&ip->i_contents));
2036 
2037 	ud_printf("ud_idrop\n");
2038 
2039 	mutex_enter(&vp->v_lock);
2040 	VN_RELE_LOCKED(vp);
2041 	if (vp->v_count > 0) {
2042 		mutex_exit(&vp->v_lock);
2043 		return;
2044 	}
2045 	mutex_exit(&vp->v_lock);
2046 
2047 	/*
2048 	 *  if inode is invalid or there is no page associated with
2049 	 *  this inode, put the inode in the front of the free list
2050 	 */
2051 	mutex_enter(&ip->i_tlock);
2052 	mutex_enter(&udf_ifree_lock);
2053 	if (!vn_has_cached_data(vp) || ip->i_perm == 0) {
2054 		ud_add_to_free_list(ip, UD_BEGIN);
2055 	} else {
2056 		/*
2057 		 * Otherwise, put the inode back on the end of the free list.
2058 		 */
2059 		ud_add_to_free_list(ip, UD_END);
2060 	}
2061 	mutex_exit(&udf_ifree_lock);
2062 	ip->i_flag &= IMODTIME;
2063 	mutex_exit(&ip->i_tlock);
2064 }
2065 
2066 void
ud_add_to_free_list(struct ud_inode * ip,uint32_t at)2067 ud_add_to_free_list(struct ud_inode *ip, uint32_t at)
2068 {
2069 	ASSERT(ip);
2070 	ASSERT(mutex_owned(&udf_ifree_lock));
2071 
2072 #ifdef	DEBUG
2073 	/* Search if the element is already in the list */
2074 	if (udf_ifreeh != NULL) {
2075 		struct ud_inode *iq;
2076 
2077 		iq = udf_ifreeh;
2078 		while (iq) {
2079 			if (iq == ip) {
2080 				cmn_err(CE_WARN, "Duplicate %p\n", (void *)ip);
2081 			}
2082 			iq = iq->i_freef;
2083 		}
2084 	}
2085 #endif
2086 
2087 	ip->i_freef = NULL;
2088 	ip->i_freeb = NULL;
2089 	if (udf_ifreeh == NULL) {
2090 		/*
2091 		 * Nothing on the list just add it
2092 		 */
2093 		udf_ifreeh = ip;
2094 		udf_ifreet = ip;
2095 	} else {
2096 		if (at == UD_BEGIN) {
2097 			/*
2098 			 * Add at the begining of the list
2099 			 */
2100 			ip->i_freef = udf_ifreeh;
2101 			udf_ifreeh->i_freeb = ip;
2102 			udf_ifreeh = ip;
2103 		} else {
2104 			/*
2105 			 * Add at the end of the list
2106 			 */
2107 			ip->i_freeb = udf_ifreet;
2108 			udf_ifreet->i_freef = ip;
2109 			udf_ifreet = ip;
2110 		}
2111 	}
2112 }
2113 
2114 void
ud_remove_from_free_list(struct ud_inode * ip,uint32_t at)2115 ud_remove_from_free_list(struct ud_inode *ip, uint32_t at)
2116 {
2117 	ASSERT(ip);
2118 	ASSERT(mutex_owned(&udf_ifree_lock));
2119 
2120 #ifdef	DEBUG
2121 	{
2122 		struct ud_inode *iq;
2123 		uint32_t found = 0;
2124 
2125 		iq = udf_ifreeh;
2126 		while (iq) {
2127 			if (iq == ip) {
2128 				found++;
2129 			}
2130 			iq = iq->i_freef;
2131 		}
2132 		if (found != 1) {
2133 			cmn_err(CE_WARN, "ip %p is found %x times\n",
2134 			    (void *)ip,  found);
2135 		}
2136 	}
2137 #endif
2138 
2139 	if ((ip->i_freef == NULL) && (ip->i_freeb == NULL)) {
2140 		if (ip != udf_ifreeh) {
2141 			return;
2142 		}
2143 	}
2144 
2145 	if ((at == UD_BEGIN) || (ip == udf_ifreeh)) {
2146 		udf_ifreeh = ip->i_freef;
2147 		if (ip->i_freef == NULL) {
2148 			udf_ifreet = NULL;
2149 		} else {
2150 			udf_ifreeh->i_freeb = NULL;
2151 		}
2152 	} else {
2153 		ip->i_freeb->i_freef = ip->i_freef;
2154 		if (ip->i_freef) {
2155 			ip->i_freef->i_freeb = ip->i_freeb;
2156 		} else {
2157 			udf_ifreet = ip->i_freeb;
2158 		}
2159 	}
2160 	ip->i_freef = NULL;
2161 	ip->i_freeb = NULL;
2162 }
2163 
2164 void
ud_init_inodes(void)2165 ud_init_inodes(void)
2166 {
2167 	union ihead *ih = ud_ihead;
2168 	int index;
2169 
2170 #ifndef	__lint
2171 	_NOTE(NO_COMPETING_THREADS_NOW);
2172 #endif
2173 	for (index = 0; index < UD_HASH_SZ; index++, ih++) {
2174 		ih->ih_head[0] = ih;
2175 		ih->ih_head[1] = ih;
2176 	}
2177 	mutex_init(&ud_icache_lock, NULL, MUTEX_DEFAULT, NULL);
2178 	mutex_init(&ud_nino_lock, NULL, MUTEX_DEFAULT, NULL);
2179 
2180 	udf_ifreeh = NULL;
2181 	udf_ifreet = NULL;
2182 	mutex_init(&udf_ifree_lock, NULL, MUTEX_DEFAULT, NULL);
2183 
2184 	mutex_init(&ud_sync_busy, NULL, MUTEX_DEFAULT, NULL);
2185 	udf_vfs_instances = NULL;
2186 	mutex_init(&udf_vfs_mutex, NULL, MUTEX_DEFAULT, NULL);
2187 
2188 #ifndef	__lint
2189 	_NOTE(COMPETING_THREADS_NOW);
2190 #endif
2191 }
2192