1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * ISO 9660 System Use Sharing Protocol extension filesystem specifications 24*7c478bd9Sstevel@tonic-gate * Copyright (c) 1991,2000,2001 by Sun Microsystems, Inc. 25*7c478bd9Sstevel@tonic-gate * All rights reserved. 26*7c478bd9Sstevel@tonic-gate */ 27*7c478bd9Sstevel@tonic-gate 28*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 31*7c478bd9Sstevel@tonic-gate #include <sys/t_lock.h> 32*7c478bd9Sstevel@tonic-gate #include <sys/param.h> 33*7c478bd9Sstevel@tonic-gate #include <sys/systm.h> 34*7c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 35*7c478bd9Sstevel@tonic-gate #include <sys/kmem.h> 36*7c478bd9Sstevel@tonic-gate #include <sys/signal.h> 37*7c478bd9Sstevel@tonic-gate #include <sys/user.h> 38*7c478bd9Sstevel@tonic-gate #include <sys/proc.h> 39*7c478bd9Sstevel@tonic-gate #include <sys/disp.h> 40*7c478bd9Sstevel@tonic-gate #include <sys/buf.h> 41*7c478bd9Sstevel@tonic-gate #include <sys/pathname.h> 42*7c478bd9Sstevel@tonic-gate #include <sys/vfs.h> 43*7c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 44*7c478bd9Sstevel@tonic-gate #include <sys/file.h> 45*7c478bd9Sstevel@tonic-gate #include <sys/uio.h> 46*7c478bd9Sstevel@tonic-gate #include <sys/conf.h> 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate #include <vm/page.h> 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate #include <sys/fs/hsfs_spec.h> 51*7c478bd9Sstevel@tonic-gate #include <sys/fs/hsfs_isospec.h> 52*7c478bd9Sstevel@tonic-gate #include <sys/fs/hsfs_node.h> 53*7c478bd9Sstevel@tonic-gate #include <sys/fs/hsfs_impl.h> 54*7c478bd9Sstevel@tonic-gate #include <sys/fs/hsfs_susp.h> 55*7c478bd9Sstevel@tonic-gate #include <sys/fs/hsfs_rrip.h> 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate #include <sys/statvfs.h> 58*7c478bd9Sstevel@tonic-gate #include <sys/mount.h> 59*7c478bd9Sstevel@tonic-gate #include <sys/swap.h> 60*7c478bd9Sstevel@tonic-gate #include <sys/errno.h> 61*7c478bd9Sstevel@tonic-gate #include <sys/debug.h> 62*7c478bd9Sstevel@tonic-gate #include "fs/fs_subr.h" 63*7c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h> 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate /* 68*7c478bd9Sstevel@tonic-gate * Common Signatures for all SUSP 69*7c478bd9Sstevel@tonic-gate */ 70*7c478bd9Sstevel@tonic-gate ext_signature_t susp_signature_table[ ] = { 71*7c478bd9Sstevel@tonic-gate SUSP_SP, share_protocol, /* must be first in table */ 72*7c478bd9Sstevel@tonic-gate SUSP_CE, share_continue, /* must be second in table */ 73*7c478bd9Sstevel@tonic-gate SUSP_PD, share_padding, 74*7c478bd9Sstevel@tonic-gate SUSP_ER, share_ext_ref, 75*7c478bd9Sstevel@tonic-gate SUSP_ST, share_stop, 76*7c478bd9Sstevel@tonic-gate (char *)NULL, NULL 77*7c478bd9Sstevel@tonic-gate }; 78*7c478bd9Sstevel@tonic-gate 79*7c478bd9Sstevel@tonic-gate /* 80*7c478bd9Sstevel@tonic-gate * These are global pointers referring to the above table, so the 81*7c478bd9Sstevel@tonic-gate * positions must not change as marked on the right above. 82*7c478bd9Sstevel@tonic-gate */ 83*7c478bd9Sstevel@tonic-gate ext_signature_t *susp_sp = &susp_signature_table[0]; 84*7c478bd9Sstevel@tonic-gate ext_signature_t *susp_ce = &susp_signature_table[1]; 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate /* 88*7c478bd9Sstevel@tonic-gate * ext name version implemented signature table 89*7c478bd9Sstevel@tonic-gate * 90*7c478bd9Sstevel@tonic-gate * the SUSP must be the first entry in the table. 91*7c478bd9Sstevel@tonic-gate * the RRIP must be the second entry in the table. We need to be able 92*7c478bd9Sstevel@tonic-gate * to check the RRIP bit being set, so we must know it's position. 93*7c478bd9Sstevel@tonic-gate * RRIP_BIT is set to 2 in rrip.h 94*7c478bd9Sstevel@tonic-gate */ 95*7c478bd9Sstevel@tonic-gate extension_name_t extension_name_table[] = { 96*7c478bd9Sstevel@tonic-gate "SUSP_1991A", SUSP_VERSION, susp_signature_table, /* #1 */ 97*7c478bd9Sstevel@tonic-gate RRIP_ER_EXT_ID, RRIP_EXT_VERSION, rrip_signature_table, 98*7c478bd9Sstevel@tonic-gate (char *)NULL, 0, (ext_signature_t *)NULL 99*7c478bd9Sstevel@tonic-gate }; 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate extension_name_t *susp_ext_name = extension_name_table; 102*7c478bd9Sstevel@tonic-gate 103*7c478bd9Sstevel@tonic-gate /* 104*7c478bd9Sstevel@tonic-gate * share_protocol() 105*7c478bd9Sstevel@tonic-gate * 106*7c478bd9Sstevel@tonic-gate * sig_handler() for SUSP signature "SP" 107*7c478bd9Sstevel@tonic-gate * 108*7c478bd9Sstevel@tonic-gate * This function looks for the "SP" signature field, which means that 109*7c478bd9Sstevel@tonic-gate * the SUSP is supported on the current CD-ROM. It looks for the word 110*7c478bd9Sstevel@tonic-gate * 0xBEEF in the signature. If that exists, the SUSP is implemented. 111*7c478bd9Sstevel@tonic-gate * The function will then set the implemented bit in the "SUSP" entry 112*7c478bd9Sstevel@tonic-gate * of the extention_name_table[]. If the bytes don't match, then we 113*7c478bd9Sstevel@tonic-gate * return a big fat NULL and treat this as an ISO 9660 CD-ROM. 114*7c478bd9Sstevel@tonic-gate */ 115*7c478bd9Sstevel@tonic-gate uchar_t * 116*7c478bd9Sstevel@tonic-gate share_protocol(sig_args_t *sig_args_p) 117*7c478bd9Sstevel@tonic-gate { 118*7c478bd9Sstevel@tonic-gate uchar_t *sp_ptr = sig_args_p->SUF_ptr; 119*7c478bd9Sstevel@tonic-gate 120*7c478bd9Sstevel@tonic-gate /* Let's check the check bytes */ 121*7c478bd9Sstevel@tonic-gate if (!CHECK_BYTES_OK(sp_ptr)) 122*7c478bd9Sstevel@tonic-gate return ((uchar_t *)NULL); 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate /* 125*7c478bd9Sstevel@tonic-gate * Ah, we have the go ahead, so let's set the implemented bit 126*7c478bd9Sstevel@tonic-gate * of the SUSP in the extension_name_table[] 127*7c478bd9Sstevel@tonic-gate */ 128*7c478bd9Sstevel@tonic-gate 129*7c478bd9Sstevel@tonic-gate if (SUSP_VERSION < SUF_VER(sp_ptr)) { 130*7c478bd9Sstevel@tonic-gate cmn_err(CE_NOTE, 131*7c478bd9Sstevel@tonic-gate "System Use Sharing Protocol ver. %d:not supported\n", 132*7c478bd9Sstevel@tonic-gate (int)SUF_VER(sp_ptr)); 133*7c478bd9Sstevel@tonic-gate return ((uchar_t *)NULL); 134*7c478bd9Sstevel@tonic-gate } 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate SET_SUSP_BIT(sig_args_p->fsp); 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate sig_args_p->fsp->hsfs_sua_off = SP_SUA_OFFSET(sp_ptr); 139*7c478bd9Sstevel@tonic-gate 140*7c478bd9Sstevel@tonic-gate return (sp_ptr + SUF_LEN(sp_ptr)); 141*7c478bd9Sstevel@tonic-gate } 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate /* 144*7c478bd9Sstevel@tonic-gate * share_ext_ref() 145*7c478bd9Sstevel@tonic-gate * 146*7c478bd9Sstevel@tonic-gate * sig_handler() for SUSP signature "ER" 147*7c478bd9Sstevel@tonic-gate * 148*7c478bd9Sstevel@tonic-gate * This function looks for the "ER" signature field, which lists an 149*7c478bd9Sstevel@tonic-gate * extension that is implemented on the current CD-ROM. The function 150*7c478bd9Sstevel@tonic-gate * will then search through the extention_name_table[], looking for the 151*7c478bd9Sstevel@tonic-gate * extension reference in this SUF. 152*7c478bd9Sstevel@tonic-gate * 153*7c478bd9Sstevel@tonic-gate * If the correct extension reference is found, and the version number 154*7c478bd9Sstevel@tonic-gate * in the "ER" SUF is less than or equal to the version specified in 155*7c478bd9Sstevel@tonic-gate * the extension_name_table, the implemented bit will be set to 1. 156*7c478bd9Sstevel@tonic-gate * 157*7c478bd9Sstevel@tonic-gate * If the version number in the "ER" field is greater than that in the 158*7c478bd9Sstevel@tonic-gate * extension_name_table or no reference can be matched, the reference 159*7c478bd9Sstevel@tonic-gate * will be skipped the function will return the next field. 160*7c478bd9Sstevel@tonic-gate */ 161*7c478bd9Sstevel@tonic-gate uchar_t * 162*7c478bd9Sstevel@tonic-gate share_ext_ref(sig_args_t *sig_args_p) 163*7c478bd9Sstevel@tonic-gate { 164*7c478bd9Sstevel@tonic-gate uchar_t *er_ptr = sig_args_p->SUF_ptr; 165*7c478bd9Sstevel@tonic-gate extension_name_t *extnp; 166*7c478bd9Sstevel@tonic-gate int index; 167*7c478bd9Sstevel@tonic-gate 168*7c478bd9Sstevel@tonic-gate /* 169*7c478bd9Sstevel@tonic-gate * Find appropriate extension and signature table 170*7c478bd9Sstevel@tonic-gate */ 171*7c478bd9Sstevel@tonic-gate for (extnp = extension_name_table, index = 0; 172*7c478bd9Sstevel@tonic-gate extnp->extension_name != (char *)NULL; 173*7c478bd9Sstevel@tonic-gate extnp++, index++) { 174*7c478bd9Sstevel@tonic-gate if (strncmp(extnp->extension_name, 175*7c478bd9Sstevel@tonic-gate (char *)ER_ext_id(er_ptr), 176*7c478bd9Sstevel@tonic-gate ER_ID_LEN(er_ptr)) == 0) { 177*7c478bd9Sstevel@tonic-gate SET_IMPL_BIT(sig_args_p->fsp, index); 178*7c478bd9Sstevel@tonic-gate } 179*7c478bd9Sstevel@tonic-gate } 180*7c478bd9Sstevel@tonic-gate 181*7c478bd9Sstevel@tonic-gate return (er_ptr + SUF_LEN(er_ptr)); 182*7c478bd9Sstevel@tonic-gate } 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gate /* 185*7c478bd9Sstevel@tonic-gate * share_continue() 186*7c478bd9Sstevel@tonic-gate * 187*7c478bd9Sstevel@tonic-gate * sig_handler() for SUSP signature "CE" 188*7c478bd9Sstevel@tonic-gate * 189*7c478bd9Sstevel@tonic-gate * This function looks for the "CE" signature field. This means that 190*7c478bd9Sstevel@tonic-gate * the SUA is continued in another block on the CD-ROM. Because it is 191*7c478bd9Sstevel@tonic-gate * not a requirement that this "CE" field come at the end of the SUA, 192*7c478bd9Sstevel@tonic-gate * this function will only set up a structure containing the 193*7c478bd9Sstevel@tonic-gate * information needed to read the next SUA, somewhere on the disk. 194*7c478bd9Sstevel@tonic-gate * 195*7c478bd9Sstevel@tonic-gate * The end of the SUA is signaled by 2 NULL bytes, where the next 196*7c478bd9Sstevel@tonic-gate * signature would have been. 197*7c478bd9Sstevel@tonic-gate * 198*7c478bd9Sstevel@tonic-gate * This one will be tough to implement. 199*7c478bd9Sstevel@tonic-gate */ 200*7c478bd9Sstevel@tonic-gate uchar_t * 201*7c478bd9Sstevel@tonic-gate share_continue(sig_args_t *sig_args_p) 202*7c478bd9Sstevel@tonic-gate { 203*7c478bd9Sstevel@tonic-gate uchar_t *ce_ptr = sig_args_p->SUF_ptr; 204*7c478bd9Sstevel@tonic-gate 205*7c478bd9Sstevel@tonic-gate sig_args_p->cont_info_p->cont_lbn = CE_BLK_LOC(ce_ptr); 206*7c478bd9Sstevel@tonic-gate sig_args_p->cont_info_p->cont_offset = CE_OFFSET(ce_ptr); 207*7c478bd9Sstevel@tonic-gate sig_args_p->cont_info_p->cont_len = CE_CONT_LEN(ce_ptr); 208*7c478bd9Sstevel@tonic-gate 209*7c478bd9Sstevel@tonic-gate return (ce_ptr + SUF_LEN(ce_ptr)); 210*7c478bd9Sstevel@tonic-gate } 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate /* 214*7c478bd9Sstevel@tonic-gate * share_padding() 215*7c478bd9Sstevel@tonic-gate * 216*7c478bd9Sstevel@tonic-gate * sig_handler() for SUSP signature "PD" 217*7c478bd9Sstevel@tonic-gate * 218*7c478bd9Sstevel@tonic-gate * All this function is needed for is bypassing a certain number of 219*7c478bd9Sstevel@tonic-gate * bytes. So, we just advance past this field and we're set. 220*7c478bd9Sstevel@tonic-gate */ 221*7c478bd9Sstevel@tonic-gate uchar_t * 222*7c478bd9Sstevel@tonic-gate share_padding(sig_args_t *sig_args_p) 223*7c478bd9Sstevel@tonic-gate { 224*7c478bd9Sstevel@tonic-gate uchar_t *pd_ptr = sig_args_p->SUF_ptr; 225*7c478bd9Sstevel@tonic-gate 226*7c478bd9Sstevel@tonic-gate return (pd_ptr + SUF_LEN(pd_ptr)); 227*7c478bd9Sstevel@tonic-gate } 228*7c478bd9Sstevel@tonic-gate 229*7c478bd9Sstevel@tonic-gate 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate /* 232*7c478bd9Sstevel@tonic-gate * share_stop() 233*7c478bd9Sstevel@tonic-gate * 234*7c478bd9Sstevel@tonic-gate * sig_handler() for SUSP signature "ST" 235*7c478bd9Sstevel@tonic-gate * 236*7c478bd9Sstevel@tonic-gate * All this is used for is signaling the end of an SUA. 237*7c478bd9Sstevel@tonic-gate * It fills the flag variable with the 238*7c478bd9Sstevel@tonic-gate */ 239*7c478bd9Sstevel@tonic-gate uchar_t * 240*7c478bd9Sstevel@tonic-gate share_stop(sig_args_t *sig_args_p) 241*7c478bd9Sstevel@tonic-gate { 242*7c478bd9Sstevel@tonic-gate uchar_t *st_ptr = sig_args_p->SUF_ptr; 243*7c478bd9Sstevel@tonic-gate 244*7c478bd9Sstevel@tonic-gate sig_args_p->flags = END_OF_SUA; /* stop parsing the SUA NOW!!!! */ 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate return (st_ptr + SUF_LEN(st_ptr)); 247*7c478bd9Sstevel@tonic-gate } 248