1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate * 26*0Sstevel@tonic-gate * Simple nfs ops - open, close, read, and lseek. 27*0Sstevel@tonic-gate */ 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gate #include <rpc/types.h> 32*0Sstevel@tonic-gate #include <rpc/auth.h> 33*0Sstevel@tonic-gate #include <sys/t_lock.h> 34*0Sstevel@tonic-gate #include "clnt.h" 35*0Sstevel@tonic-gate #include <sys/fcntl.h> 36*0Sstevel@tonic-gate #include <sys/vfs.h> 37*0Sstevel@tonic-gate #include <errno.h> 38*0Sstevel@tonic-gate #include <sys/promif.h> 39*0Sstevel@tonic-gate #include <rpc/xdr.h> 40*0Sstevel@tonic-gate #include "nfs_inet.h" 41*0Sstevel@tonic-gate #include <sys/stat.h> 42*0Sstevel@tonic-gate #include <sys/bootvfs.h> 43*0Sstevel@tonic-gate #include <sys/bootdebug.h> 44*0Sstevel@tonic-gate #include <sys/salib.h> 45*0Sstevel@tonic-gate #include <sys/sacache.h> 46*0Sstevel@tonic-gate #include <rpc/rpc.h> 47*0Sstevel@tonic-gate #include "brpc.h" 48*0Sstevel@tonic-gate #include <rpcsvc/nfs_prot.h> 49*0Sstevel@tonic-gate #include "socket_inet.h" 50*0Sstevel@tonic-gate #include "mac.h" 51*0Sstevel@tonic-gate #include <sys/mode.h> 52*0Sstevel@tonic-gate 53*0Sstevel@tonic-gate ushort_t vttoif_tab[] = { 54*0Sstevel@tonic-gate 0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, S_IFIFO, 55*0Sstevel@tonic-gate S_IFDOOR, 0, S_IFSOCK, 0 56*0Sstevel@tonic-gate }; 57*0Sstevel@tonic-gate 58*0Sstevel@tonic-gate static int file_desc = 1; 59*0Sstevel@tonic-gate static struct nfs_files { 60*0Sstevel@tonic-gate struct nfs_file file; 61*0Sstevel@tonic-gate int desc; 62*0Sstevel@tonic-gate struct nfs_files *next; 63*0Sstevel@tonic-gate } nfs_files[1] = { 64*0Sstevel@tonic-gate {0, 0, 0}, 65*0Sstevel@tonic-gate }; 66*0Sstevel@tonic-gate 67*0Sstevel@tonic-gate #define dprintf if (boothowto & RB_DEBUG) printf 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gate static int boot_nfs_open(char *filename, int flags); 70*0Sstevel@tonic-gate static int boot_nfs_close(int fd); 71*0Sstevel@tonic-gate static ssize_t boot_nfs_read(int fd, caddr_t buf, size_t size); 72*0Sstevel@tonic-gate static off_t boot_nfs_lseek(int, off_t, int); 73*0Sstevel@tonic-gate static int boot_nfs_fstat(int fd, struct bootstat *stp); 74*0Sstevel@tonic-gate static void boot_nfs_closeall(int flag); 75*0Sstevel@tonic-gate static int boot_nfs_getdents(int fd, struct dirent *dep, unsigned size); 76*0Sstevel@tonic-gate 77*0Sstevel@tonic-gate struct boot_fs_ops boot_nfs_ops = { 78*0Sstevel@tonic-gate "nfs", 79*0Sstevel@tonic-gate boot_nfs_mountroot, 80*0Sstevel@tonic-gate boot_nfs_unmountroot, 81*0Sstevel@tonic-gate boot_nfs_open, 82*0Sstevel@tonic-gate boot_nfs_close, 83*0Sstevel@tonic-gate boot_nfs_read, 84*0Sstevel@tonic-gate boot_nfs_lseek, 85*0Sstevel@tonic-gate boot_nfs_fstat, 86*0Sstevel@tonic-gate boot_nfs_closeall, 87*0Sstevel@tonic-gate boot_nfs_getdents 88*0Sstevel@tonic-gate }; 89*0Sstevel@tonic-gate 90*0Sstevel@tonic-gate /* 91*0Sstevel@tonic-gate * bootops.c calls a closeall() function to close all open files. Since 92*0Sstevel@tonic-gate * we only permit one open file at a time (not counting the device), this 93*0Sstevel@tonic-gate * is simple to implement. 94*0Sstevel@tonic-gate */ 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate /*ARGSUSED*/ 97*0Sstevel@tonic-gate static void 98*0Sstevel@tonic-gate boot_nfs_closeall(int flag) 99*0Sstevel@tonic-gate { 100*0Sstevel@tonic-gate struct nfs_files *filep; 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG 103*0Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS) 104*0Sstevel@tonic-gate printf("boot_nfs_closeall(%x)\n", flag); 105*0Sstevel@tonic-gate #endif 106*0Sstevel@tonic-gate 107*0Sstevel@tonic-gate /* delete any dynamically allocated entries */ 108*0Sstevel@tonic-gate while ((filep = nfs_files->next) != NULL) { 109*0Sstevel@tonic-gate nfs_files->next = filep->next; 110*0Sstevel@tonic-gate bkmem_free((caddr_t)filep, sizeof (struct nfs_files)); 111*0Sstevel@tonic-gate } 112*0Sstevel@tonic-gate 113*0Sstevel@tonic-gate /* clear the first, static file */ 114*0Sstevel@tonic-gate bzero((caddr_t)nfs_files, sizeof (struct nfs_files)); 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate /* Close device */ 117*0Sstevel@tonic-gate release_cache(mac_get_dev()); 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate mac_fini(); 120*0Sstevel@tonic-gate } 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gate /* 123*0Sstevel@tonic-gate * Get a file pointer given a file descriptor. Return 0 on error 124*0Sstevel@tonic-gate */ 125*0Sstevel@tonic-gate static struct nfs_files * 126*0Sstevel@tonic-gate get_filep(int fd) 127*0Sstevel@tonic-gate { 128*0Sstevel@tonic-gate struct nfs_files *filep; 129*0Sstevel@tonic-gate 130*0Sstevel@tonic-gate for (filep = nfs_files; filep; filep = filep->next) { 131*0Sstevel@tonic-gate if (fd == filep->desc) 132*0Sstevel@tonic-gate return (filep); 133*0Sstevel@tonic-gate } 134*0Sstevel@tonic-gate return (NULL); 135*0Sstevel@tonic-gate } 136*0Sstevel@tonic-gate 137*0Sstevel@tonic-gate /* 138*0Sstevel@tonic-gate * Unmount the root fs -- not supported for this fstype. 139*0Sstevel@tonic-gate */ 140*0Sstevel@tonic-gate 141*0Sstevel@tonic-gate int 142*0Sstevel@tonic-gate boot_nfs_unmountroot(void) 143*0Sstevel@tonic-gate { 144*0Sstevel@tonic-gate return (-1); 145*0Sstevel@tonic-gate } 146*0Sstevel@tonic-gate 147*0Sstevel@tonic-gate /* 148*0Sstevel@tonic-gate * open a file for reading. Note: writing is NOT supported. 149*0Sstevel@tonic-gate */ 150*0Sstevel@tonic-gate 151*0Sstevel@tonic-gate static int 152*0Sstevel@tonic-gate boot_nfs_open(char *path, int flags) 153*0Sstevel@tonic-gate { 154*0Sstevel@tonic-gate struct nfs_files *filep, *newfilep; 155*0Sstevel@tonic-gate int got_filep; 156*0Sstevel@tonic-gate 157*0Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG 158*0Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS) 159*0Sstevel@tonic-gate printf("boot_nfs_open(%s, %x)\n", path, flags); 160*0Sstevel@tonic-gate #endif 161*0Sstevel@tonic-gate 162*0Sstevel@tonic-gate /* file can only be opened readonly. */ 163*0Sstevel@tonic-gate if (flags & ~O_RDONLY) { 164*0Sstevel@tonic-gate dprintf("boot_nfs_open: files can only be opened O_RDONLY.\n"); 165*0Sstevel@tonic-gate return (-1); 166*0Sstevel@tonic-gate } 167*0Sstevel@tonic-gate 168*0Sstevel@tonic-gate if (path == NULL || *path == '\0') { 169*0Sstevel@tonic-gate dprintf("boot_nfs_open: NULL or EMPTY pathname argument.\n"); 170*0Sstevel@tonic-gate return (-1); 171*0Sstevel@tonic-gate } 172*0Sstevel@tonic-gate 173*0Sstevel@tonic-gate /* Try and find a vacant file pointer */ 174*0Sstevel@tonic-gate filep = nfs_files; 175*0Sstevel@tonic-gate got_filep = FALSE; 176*0Sstevel@tonic-gate do { 177*0Sstevel@tonic-gate if (filep->desc == 0) { 178*0Sstevel@tonic-gate filep->desc = file_desc++; 179*0Sstevel@tonic-gate got_filep = TRUE; 180*0Sstevel@tonic-gate break; /* We've got a file pointer */ 181*0Sstevel@tonic-gate } 182*0Sstevel@tonic-gate /* Get next entry if not at end of list */ 183*0Sstevel@tonic-gate if (filep->next) 184*0Sstevel@tonic-gate filep = filep->next; 185*0Sstevel@tonic-gate } while (filep->next); 186*0Sstevel@tonic-gate 187*0Sstevel@tonic-gate /* If a a vacant file pointer cannot be found, make one */ 188*0Sstevel@tonic-gate if (!got_filep) { 189*0Sstevel@tonic-gate if ((newfilep = (struct nfs_files *) 190*0Sstevel@tonic-gate bkmem_zalloc(sizeof (struct nfs_files))) == 0) { 191*0Sstevel@tonic-gate dprintf("open: Cannot allocate file pointer\n"); 192*0Sstevel@tonic-gate return (-1); 193*0Sstevel@tonic-gate } 194*0Sstevel@tonic-gate filep->next = newfilep; 195*0Sstevel@tonic-gate filep = newfilep; 196*0Sstevel@tonic-gate filep->desc = file_desc++; 197*0Sstevel@tonic-gate } 198*0Sstevel@tonic-gate 199*0Sstevel@tonic-gate if (lookup(path, &filep->file, FALSE) != 0) { 200*0Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG 201*0Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS) 202*0Sstevel@tonic-gate printf("boot_nfs_open(): Cannot open '%s'.\n", path); 203*0Sstevel@tonic-gate #endif 204*0Sstevel@tonic-gate /* zero file pointer */ 205*0Sstevel@tonic-gate bzero((caddr_t)filep, sizeof (struct nfs_file)); 206*0Sstevel@tonic-gate filep->desc = 0; 207*0Sstevel@tonic-gate return (-1); 208*0Sstevel@tonic-gate } 209*0Sstevel@tonic-gate bzero(&filep->file.cookie, sizeof (filep->file.cookie)); 210*0Sstevel@tonic-gate 211*0Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG 212*0Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS) 213*0Sstevel@tonic-gate printf("boot_nfs_open(): '%s' successful, fd = 0x%x\n", 214*0Sstevel@tonic-gate path, filep->desc); 215*0Sstevel@tonic-gate #endif 216*0Sstevel@tonic-gate return (filep->desc); 217*0Sstevel@tonic-gate } 218*0Sstevel@tonic-gate 219*0Sstevel@tonic-gate /* 220*0Sstevel@tonic-gate * close a previously opened file. 221*0Sstevel@tonic-gate */ 222*0Sstevel@tonic-gate static int 223*0Sstevel@tonic-gate boot_nfs_close(int fd) 224*0Sstevel@tonic-gate { 225*0Sstevel@tonic-gate struct nfs_files *filep; 226*0Sstevel@tonic-gate 227*0Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG 228*0Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS) 229*0Sstevel@tonic-gate printf("boot_nfs_close(%d)\n", fd); 230*0Sstevel@tonic-gate #endif 231*0Sstevel@tonic-gate if ((filep = get_filep(fd)) == 0) 232*0Sstevel@tonic-gate return (0); 233*0Sstevel@tonic-gate 234*0Sstevel@tonic-gate /* 235*0Sstevel@tonic-gate * zero file pointer 236*0Sstevel@tonic-gate */ 237*0Sstevel@tonic-gate bzero((caddr_t)&filep->file, sizeof (struct nfs_file)); 238*0Sstevel@tonic-gate 239*0Sstevel@tonic-gate /* 240*0Sstevel@tonic-gate * "close" the fd. 241*0Sstevel@tonic-gate */ 242*0Sstevel@tonic-gate filep->desc = 0; 243*0Sstevel@tonic-gate 244*0Sstevel@tonic-gate return (0); 245*0Sstevel@tonic-gate } 246*0Sstevel@tonic-gate 247*0Sstevel@tonic-gate /* 248*0Sstevel@tonic-gate * read from a file. 249*0Sstevel@tonic-gate */ 250*0Sstevel@tonic-gate static ssize_t 251*0Sstevel@tonic-gate boot_nfs_read(int fd, char *buf, size_t size) 252*0Sstevel@tonic-gate { 253*0Sstevel@tonic-gate struct nfs_files *filep; 254*0Sstevel@tonic-gate int count = 0; 255*0Sstevel@tonic-gate 256*0Sstevel@tonic-gate if (fd == 0) { 257*0Sstevel@tonic-gate dprintf("boot_nfs_read: Bad file number.\n"); 258*0Sstevel@tonic-gate return (-1); 259*0Sstevel@tonic-gate } 260*0Sstevel@tonic-gate if (buf == NULL) { 261*0Sstevel@tonic-gate dprintf("boot_nfs_read: Bad address.\n"); 262*0Sstevel@tonic-gate return (-1); 263*0Sstevel@tonic-gate } 264*0Sstevel@tonic-gate 265*0Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG 266*0Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS) 267*0Sstevel@tonic-gate printf("boot_nfs_read(%d, %x, 0x%x)\n", fd, buf, size); 268*0Sstevel@tonic-gate #endif 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gate /* initialize for read */ 271*0Sstevel@tonic-gate if ((filep = get_filep(fd)) == 0) 272*0Sstevel@tonic-gate return (-1); 273*0Sstevel@tonic-gate 274*0Sstevel@tonic-gate switch (filep->file.version) { 275*0Sstevel@tonic-gate case NFS_VERSION: 276*0Sstevel@tonic-gate count = nfsread(&filep->file, buf, size); 277*0Sstevel@tonic-gate break; 278*0Sstevel@tonic-gate case NFS_V3: 279*0Sstevel@tonic-gate count = nfs3read(&filep->file, buf, size); 280*0Sstevel@tonic-gate break; 281*0Sstevel@tonic-gate case NFS_V4: 282*0Sstevel@tonic-gate count = nfs4read(&filep->file, buf, size); 283*0Sstevel@tonic-gate break; 284*0Sstevel@tonic-gate default: 285*0Sstevel@tonic-gate printf("boot_nfs_read: NFS Version %d not supported\n", 286*0Sstevel@tonic-gate filep->file.version); 287*0Sstevel@tonic-gate count = -1; 288*0Sstevel@tonic-gate break; 289*0Sstevel@tonic-gate } 290*0Sstevel@tonic-gate 291*0Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG 292*0Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS) 293*0Sstevel@tonic-gate printf("boot_nfs_read(): 0x%x bytes.\n", count); 294*0Sstevel@tonic-gate #endif 295*0Sstevel@tonic-gate return (count); 296*0Sstevel@tonic-gate } 297*0Sstevel@tonic-gate 298*0Sstevel@tonic-gate /* 299*0Sstevel@tonic-gate * lseek - move read file pointer. 300*0Sstevel@tonic-gate */ 301*0Sstevel@tonic-gate 302*0Sstevel@tonic-gate static off_t 303*0Sstevel@tonic-gate boot_nfs_lseek(int fd, off_t offset, int whence) 304*0Sstevel@tonic-gate { 305*0Sstevel@tonic-gate struct nfs_files *filep; 306*0Sstevel@tonic-gate 307*0Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG 308*0Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS) 309*0Sstevel@tonic-gate printf("boot_nfs_lseek(%d, 0x%x, %d)\n", fd, offset, whence); 310*0Sstevel@tonic-gate #endif 311*0Sstevel@tonic-gate 312*0Sstevel@tonic-gate if (fd == 0) { 313*0Sstevel@tonic-gate dprintf("boot_nfs_lseek: Bad file number.\n"); 314*0Sstevel@tonic-gate return (-1); 315*0Sstevel@tonic-gate } 316*0Sstevel@tonic-gate 317*0Sstevel@tonic-gate if ((filep = get_filep(fd)) == 0) 318*0Sstevel@tonic-gate return (-1); 319*0Sstevel@tonic-gate 320*0Sstevel@tonic-gate switch (whence) { 321*0Sstevel@tonic-gate 322*0Sstevel@tonic-gate case SEEK_SET: 323*0Sstevel@tonic-gate /* 324*0Sstevel@tonic-gate * file ptr is set to offset from beginning of file 325*0Sstevel@tonic-gate */ 326*0Sstevel@tonic-gate filep->file.offset = offset; 327*0Sstevel@tonic-gate break; 328*0Sstevel@tonic-gate case SEEK_CUR: 329*0Sstevel@tonic-gate /* 330*0Sstevel@tonic-gate * file ptr is set to offset from current position 331*0Sstevel@tonic-gate */ 332*0Sstevel@tonic-gate filep->file.offset += offset; 333*0Sstevel@tonic-gate break; 334*0Sstevel@tonic-gate case SEEK_END: 335*0Sstevel@tonic-gate /* 336*0Sstevel@tonic-gate * file ptr is set to current size of file plus offset. 337*0Sstevel@tonic-gate * But since we only support reading, this is illegal. 338*0Sstevel@tonic-gate */ 339*0Sstevel@tonic-gate default: 340*0Sstevel@tonic-gate /* 341*0Sstevel@tonic-gate * invalid offset origin 342*0Sstevel@tonic-gate */ 343*0Sstevel@tonic-gate dprintf("boot_nfs_lseek: invalid whence value.\n"); 344*0Sstevel@tonic-gate return (-1); 345*0Sstevel@tonic-gate } 346*0Sstevel@tonic-gate 347*0Sstevel@tonic-gate #ifdef notyet 348*0Sstevel@tonic-gate return (filep->file.offset); 349*0Sstevel@tonic-gate #else 350*0Sstevel@tonic-gate /* 351*0Sstevel@tonic-gate * BROKE - lseek should return the offset seeked to on a 352*0Sstevel@tonic-gate * successful seek, not zero - This must be fixed in the 353*0Sstevel@tonic-gate * kernel before It can be fixed here. 354*0Sstevel@tonic-gate */ 355*0Sstevel@tonic-gate return (0); 356*0Sstevel@tonic-gate #endif /* notyet */ 357*0Sstevel@tonic-gate } 358*0Sstevel@tonic-gate 359*0Sstevel@tonic-gate /* 360*0Sstevel@tonic-gate * This version of fstat supports mode, size, inode #, and times only. 361*0Sstevel@tonic-gate * It can be enhanced if more is required, 362*0Sstevel@tonic-gate */ 363*0Sstevel@tonic-gate 364*0Sstevel@tonic-gate static int 365*0Sstevel@tonic-gate boot_nfs_fstat(int fd, struct bootstat *stp) 366*0Sstevel@tonic-gate { 367*0Sstevel@tonic-gate struct vattr va; 368*0Sstevel@tonic-gate struct nfs_files *filep; 369*0Sstevel@tonic-gate int status; 370*0Sstevel@tonic-gate 371*0Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG 372*0Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS) { 373*0Sstevel@tonic-gate printf("boot_nfs_fstat(%d, 0x%x)\n", fd, stp); 374*0Sstevel@tonic-gate } 375*0Sstevel@tonic-gate #endif 376*0Sstevel@tonic-gate if (fd == 0) { 377*0Sstevel@tonic-gate dprintf("boot_nfs_fstat(): Bad file number 0.\n"); 378*0Sstevel@tonic-gate return (-1); 379*0Sstevel@tonic-gate } 380*0Sstevel@tonic-gate 381*0Sstevel@tonic-gate if ((filep = get_filep(fd)) == 0) 382*0Sstevel@tonic-gate return (-1); 383*0Sstevel@tonic-gate 384*0Sstevel@tonic-gate bzero((char *)&va, sizeof (va)); 385*0Sstevel@tonic-gate va.va_mask = AT_TYPE | AT_SIZE | AT_MODE | AT_NODEID | \ 386*0Sstevel@tonic-gate AT_ATIME | AT_CTIME | AT_MTIME; 387*0Sstevel@tonic-gate 388*0Sstevel@tonic-gate switch (filep->file.version) { 389*0Sstevel@tonic-gate case NFS_VERSION: 390*0Sstevel@tonic-gate status = nfsgetattr(&filep->file, &va); 391*0Sstevel@tonic-gate break; 392*0Sstevel@tonic-gate case NFS_V3: 393*0Sstevel@tonic-gate status = nfs3getattr(&filep->file, &va); 394*0Sstevel@tonic-gate break; 395*0Sstevel@tonic-gate case NFS_V4: 396*0Sstevel@tonic-gate status = nfs4getattr(&filep->file, &va); 397*0Sstevel@tonic-gate break; 398*0Sstevel@tonic-gate default: 399*0Sstevel@tonic-gate printf("boot_nfs_fstat: NFS Version %d not supported\n", 400*0Sstevel@tonic-gate filep->file.version); 401*0Sstevel@tonic-gate status = -1; 402*0Sstevel@tonic-gate break; 403*0Sstevel@tonic-gate } 404*0Sstevel@tonic-gate 405*0Sstevel@tonic-gate if (status != 0) 406*0Sstevel@tonic-gate return (-1); 407*0Sstevel@tonic-gate 408*0Sstevel@tonic-gate if (va.va_size > (u_offset_t)MAXOFF_T) { 409*0Sstevel@tonic-gate dprintf("boot_nfs_fstat(): File too large.\n"); 410*0Sstevel@tonic-gate return (-1); 411*0Sstevel@tonic-gate } 412*0Sstevel@tonic-gate stp->st_size = (off_t)va.va_size; 413*0Sstevel@tonic-gate stp->st_mode = VTTOIF(va.va_type) | va.va_mode; 414*0Sstevel@tonic-gate stp->st_atim.tv_sec = va.va_atime.tv_sec; 415*0Sstevel@tonic-gate stp->st_atim.tv_nsec = va.va_atime.tv_nsec; 416*0Sstevel@tonic-gate stp->st_ctim.tv_sec = va.va_ctime.tv_sec; 417*0Sstevel@tonic-gate stp->st_ctim.tv_nsec = va.va_ctime.tv_nsec; 418*0Sstevel@tonic-gate stp->st_mtim.tv_sec = va.va_mtime.tv_sec; 419*0Sstevel@tonic-gate stp->st_mtim.tv_nsec = va.va_mtime.tv_nsec; 420*0Sstevel@tonic-gate stp->st_ino = (ino_t)va.va_nodeid; 421*0Sstevel@tonic-gate 422*0Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG 423*0Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS) 424*0Sstevel@tonic-gate printf("boot_nfs_fstat(): done.\n"); 425*0Sstevel@tonic-gate #endif 426*0Sstevel@tonic-gate return (0); 427*0Sstevel@tonic-gate } 428*0Sstevel@tonic-gate 429*0Sstevel@tonic-gate static int 430*0Sstevel@tonic-gate boot_nfs_getdents(int fd, struct dirent *dep, unsigned size) 431*0Sstevel@tonic-gate { 432*0Sstevel@tonic-gate struct nfs_files *filep; 433*0Sstevel@tonic-gate int status; 434*0Sstevel@tonic-gate 435*0Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG 436*0Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS) { 437*0Sstevel@tonic-gate printf("boot_nfs_getdents(%d, 0x%x, 0x%x)\n", fd, dep, size); 438*0Sstevel@tonic-gate } 439*0Sstevel@tonic-gate #endif 440*0Sstevel@tonic-gate 441*0Sstevel@tonic-gate if (fd == 0) { 442*0Sstevel@tonic-gate dprintf("boot_nfs_getdents(): Bad file number 0.\n"); 443*0Sstevel@tonic-gate return (-1); 444*0Sstevel@tonic-gate } 445*0Sstevel@tonic-gate 446*0Sstevel@tonic-gate if ((filep = get_filep(fd)) == 0) 447*0Sstevel@tonic-gate return (-1); 448*0Sstevel@tonic-gate 449*0Sstevel@tonic-gate switch (filep->file.version) { 450*0Sstevel@tonic-gate case NFS_VERSION: 451*0Sstevel@tonic-gate status = nfsgetdents(&filep->file, dep, size); 452*0Sstevel@tonic-gate break; 453*0Sstevel@tonic-gate case NFS_V3: 454*0Sstevel@tonic-gate status = nfs3getdents(&filep->file, dep, size); 455*0Sstevel@tonic-gate break; 456*0Sstevel@tonic-gate default: 457*0Sstevel@tonic-gate printf("boot_nfs_getdents: NFS Version %d not supported\n", 458*0Sstevel@tonic-gate filep->file.version); 459*0Sstevel@tonic-gate status = -1; 460*0Sstevel@tonic-gate } 461*0Sstevel@tonic-gate 462*0Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG 463*0Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS) 464*0Sstevel@tonic-gate printf("boot_nfs_getdents(): done.\n"); 465*0Sstevel@tonic-gate #endif 466*0Sstevel@tonic-gate return (status); 467*0Sstevel@tonic-gate } 468