10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*5648Ssetje * Common Development and Distribution License (the "License").
6*5648Ssetje * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*5648Ssetje * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate *
250Sstevel@tonic-gate * Simple nfs ops - open, close, read, and lseek.
260Sstevel@tonic-gate */
270Sstevel@tonic-gate
280Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
290Sstevel@tonic-gate
300Sstevel@tonic-gate #include <rpc/types.h>
310Sstevel@tonic-gate #include <rpc/auth.h>
320Sstevel@tonic-gate #include <sys/t_lock.h>
330Sstevel@tonic-gate #include "clnt.h"
340Sstevel@tonic-gate #include <sys/fcntl.h>
350Sstevel@tonic-gate #include <sys/vfs.h>
360Sstevel@tonic-gate #include <errno.h>
370Sstevel@tonic-gate #include <sys/promif.h>
380Sstevel@tonic-gate #include <rpc/xdr.h>
390Sstevel@tonic-gate #include "nfs_inet.h"
400Sstevel@tonic-gate #include <sys/stat.h>
410Sstevel@tonic-gate #include <sys/bootvfs.h>
420Sstevel@tonic-gate #include <sys/bootdebug.h>
430Sstevel@tonic-gate #include <sys/salib.h>
440Sstevel@tonic-gate #include <sys/sacache.h>
450Sstevel@tonic-gate #include <rpc/rpc.h>
460Sstevel@tonic-gate #include "brpc.h"
470Sstevel@tonic-gate #include <rpcsvc/nfs_prot.h>
480Sstevel@tonic-gate #include "socket_inet.h"
490Sstevel@tonic-gate #include "mac.h"
500Sstevel@tonic-gate #include <sys/mode.h>
510Sstevel@tonic-gate
520Sstevel@tonic-gate ushort_t vttoif_tab[] = {
530Sstevel@tonic-gate 0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, S_IFIFO,
540Sstevel@tonic-gate S_IFDOOR, 0, S_IFSOCK, 0
550Sstevel@tonic-gate };
560Sstevel@tonic-gate
570Sstevel@tonic-gate static int file_desc = 1;
580Sstevel@tonic-gate static struct nfs_files {
590Sstevel@tonic-gate struct nfs_file file;
600Sstevel@tonic-gate int desc;
610Sstevel@tonic-gate struct nfs_files *next;
620Sstevel@tonic-gate } nfs_files[1] = {
630Sstevel@tonic-gate {0, 0, 0},
640Sstevel@tonic-gate };
650Sstevel@tonic-gate
660Sstevel@tonic-gate #define dprintf if (boothowto & RB_DEBUG) printf
670Sstevel@tonic-gate
680Sstevel@tonic-gate static int boot_nfs_open(char *filename, int flags);
690Sstevel@tonic-gate static int boot_nfs_close(int fd);
700Sstevel@tonic-gate static ssize_t boot_nfs_read(int fd, caddr_t buf, size_t size);
710Sstevel@tonic-gate static off_t boot_nfs_lseek(int, off_t, int);
720Sstevel@tonic-gate static int boot_nfs_fstat(int fd, struct bootstat *stp);
730Sstevel@tonic-gate static void boot_nfs_closeall(int flag);
740Sstevel@tonic-gate static int boot_nfs_getdents(int fd, struct dirent *dep, unsigned size);
750Sstevel@tonic-gate
760Sstevel@tonic-gate struct boot_fs_ops boot_nfs_ops = {
770Sstevel@tonic-gate "nfs",
780Sstevel@tonic-gate boot_nfs_mountroot,
790Sstevel@tonic-gate boot_nfs_unmountroot,
800Sstevel@tonic-gate boot_nfs_open,
810Sstevel@tonic-gate boot_nfs_close,
820Sstevel@tonic-gate boot_nfs_read,
830Sstevel@tonic-gate boot_nfs_lseek,
840Sstevel@tonic-gate boot_nfs_fstat,
850Sstevel@tonic-gate boot_nfs_closeall,
860Sstevel@tonic-gate boot_nfs_getdents
870Sstevel@tonic-gate };
880Sstevel@tonic-gate
890Sstevel@tonic-gate /*
900Sstevel@tonic-gate * bootops.c calls a closeall() function to close all open files. Since
910Sstevel@tonic-gate * we only permit one open file at a time (not counting the device), this
920Sstevel@tonic-gate * is simple to implement.
930Sstevel@tonic-gate */
940Sstevel@tonic-gate
950Sstevel@tonic-gate /*ARGSUSED*/
960Sstevel@tonic-gate static void
boot_nfs_closeall(int flag)970Sstevel@tonic-gate boot_nfs_closeall(int flag)
980Sstevel@tonic-gate {
990Sstevel@tonic-gate struct nfs_files *filep;
1000Sstevel@tonic-gate
1010Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG
1020Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS)
1030Sstevel@tonic-gate printf("boot_nfs_closeall(%x)\n", flag);
1040Sstevel@tonic-gate #endif
1050Sstevel@tonic-gate
106*5648Ssetje if (nfs_files->file.version == 0 &&
107*5648Ssetje nfs_files->desc == 0 &&
108*5648Ssetje nfs_files->next == NULL)
109*5648Ssetje return;
110*5648Ssetje
1110Sstevel@tonic-gate /* delete any dynamically allocated entries */
1120Sstevel@tonic-gate while ((filep = nfs_files->next) != NULL) {
1130Sstevel@tonic-gate nfs_files->next = filep->next;
1140Sstevel@tonic-gate bkmem_free((caddr_t)filep, sizeof (struct nfs_files));
1150Sstevel@tonic-gate }
1160Sstevel@tonic-gate
1170Sstevel@tonic-gate /* clear the first, static file */
1180Sstevel@tonic-gate bzero((caddr_t)nfs_files, sizeof (struct nfs_files));
1190Sstevel@tonic-gate
1200Sstevel@tonic-gate /* Close device */
1210Sstevel@tonic-gate release_cache(mac_get_dev());
1220Sstevel@tonic-gate
1230Sstevel@tonic-gate mac_fini();
1240Sstevel@tonic-gate }
1250Sstevel@tonic-gate
1260Sstevel@tonic-gate /*
1270Sstevel@tonic-gate * Get a file pointer given a file descriptor. Return 0 on error
1280Sstevel@tonic-gate */
1290Sstevel@tonic-gate static struct nfs_files *
get_filep(int fd)1300Sstevel@tonic-gate get_filep(int fd)
1310Sstevel@tonic-gate {
1320Sstevel@tonic-gate struct nfs_files *filep;
1330Sstevel@tonic-gate
1340Sstevel@tonic-gate for (filep = nfs_files; filep; filep = filep->next) {
1350Sstevel@tonic-gate if (fd == filep->desc)
1360Sstevel@tonic-gate return (filep);
1370Sstevel@tonic-gate }
1380Sstevel@tonic-gate return (NULL);
1390Sstevel@tonic-gate }
1400Sstevel@tonic-gate
1410Sstevel@tonic-gate /*
1420Sstevel@tonic-gate * Unmount the root fs -- not supported for this fstype.
1430Sstevel@tonic-gate */
1440Sstevel@tonic-gate
1450Sstevel@tonic-gate int
boot_nfs_unmountroot(void)1460Sstevel@tonic-gate boot_nfs_unmountroot(void)
1470Sstevel@tonic-gate {
1480Sstevel@tonic-gate return (-1);
1490Sstevel@tonic-gate }
1500Sstevel@tonic-gate
1510Sstevel@tonic-gate /*
1520Sstevel@tonic-gate * open a file for reading. Note: writing is NOT supported.
1530Sstevel@tonic-gate */
1540Sstevel@tonic-gate
1550Sstevel@tonic-gate static int
boot_nfs_open(char * path,int flags)1560Sstevel@tonic-gate boot_nfs_open(char *path, int flags)
1570Sstevel@tonic-gate {
1580Sstevel@tonic-gate struct nfs_files *filep, *newfilep;
1590Sstevel@tonic-gate int got_filep;
1600Sstevel@tonic-gate
1610Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG
1620Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS)
1630Sstevel@tonic-gate printf("boot_nfs_open(%s, %x)\n", path, flags);
1640Sstevel@tonic-gate #endif
1650Sstevel@tonic-gate
1660Sstevel@tonic-gate /* file can only be opened readonly. */
1670Sstevel@tonic-gate if (flags & ~O_RDONLY) {
1680Sstevel@tonic-gate dprintf("boot_nfs_open: files can only be opened O_RDONLY.\n");
1690Sstevel@tonic-gate return (-1);
1700Sstevel@tonic-gate }
1710Sstevel@tonic-gate
1720Sstevel@tonic-gate if (path == NULL || *path == '\0') {
1730Sstevel@tonic-gate dprintf("boot_nfs_open: NULL or EMPTY pathname argument.\n");
1740Sstevel@tonic-gate return (-1);
1750Sstevel@tonic-gate }
1760Sstevel@tonic-gate
1770Sstevel@tonic-gate /* Try and find a vacant file pointer */
1780Sstevel@tonic-gate filep = nfs_files;
1790Sstevel@tonic-gate got_filep = FALSE;
1800Sstevel@tonic-gate do {
1810Sstevel@tonic-gate if (filep->desc == 0) {
1820Sstevel@tonic-gate filep->desc = file_desc++;
1830Sstevel@tonic-gate got_filep = TRUE;
1840Sstevel@tonic-gate break; /* We've got a file pointer */
1850Sstevel@tonic-gate }
1860Sstevel@tonic-gate /* Get next entry if not at end of list */
1870Sstevel@tonic-gate if (filep->next)
1880Sstevel@tonic-gate filep = filep->next;
1890Sstevel@tonic-gate } while (filep->next);
1900Sstevel@tonic-gate
1910Sstevel@tonic-gate /* If a a vacant file pointer cannot be found, make one */
1920Sstevel@tonic-gate if (!got_filep) {
1930Sstevel@tonic-gate if ((newfilep = (struct nfs_files *)
1940Sstevel@tonic-gate bkmem_zalloc(sizeof (struct nfs_files))) == 0) {
1950Sstevel@tonic-gate dprintf("open: Cannot allocate file pointer\n");
1960Sstevel@tonic-gate return (-1);
1970Sstevel@tonic-gate }
1980Sstevel@tonic-gate filep->next = newfilep;
1990Sstevel@tonic-gate filep = newfilep;
2000Sstevel@tonic-gate filep->desc = file_desc++;
2010Sstevel@tonic-gate }
2020Sstevel@tonic-gate
2030Sstevel@tonic-gate if (lookup(path, &filep->file, FALSE) != 0) {
2040Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG
2050Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS)
2060Sstevel@tonic-gate printf("boot_nfs_open(): Cannot open '%s'.\n", path);
2070Sstevel@tonic-gate #endif
2080Sstevel@tonic-gate /* zero file pointer */
2090Sstevel@tonic-gate bzero((caddr_t)filep, sizeof (struct nfs_file));
2100Sstevel@tonic-gate filep->desc = 0;
2110Sstevel@tonic-gate return (-1);
2120Sstevel@tonic-gate }
2130Sstevel@tonic-gate bzero(&filep->file.cookie, sizeof (filep->file.cookie));
2140Sstevel@tonic-gate
2150Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG
2160Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS)
2170Sstevel@tonic-gate printf("boot_nfs_open(): '%s' successful, fd = 0x%x\n",
218*5648Ssetje path, filep->desc);
2190Sstevel@tonic-gate #endif
2200Sstevel@tonic-gate return (filep->desc);
2210Sstevel@tonic-gate }
2220Sstevel@tonic-gate
2230Sstevel@tonic-gate /*
2240Sstevel@tonic-gate * close a previously opened file.
2250Sstevel@tonic-gate */
2260Sstevel@tonic-gate static int
boot_nfs_close(int fd)2270Sstevel@tonic-gate boot_nfs_close(int fd)
2280Sstevel@tonic-gate {
2290Sstevel@tonic-gate struct nfs_files *filep;
2300Sstevel@tonic-gate
2310Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG
2320Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS)
2330Sstevel@tonic-gate printf("boot_nfs_close(%d)\n", fd);
2340Sstevel@tonic-gate #endif
2350Sstevel@tonic-gate if ((filep = get_filep(fd)) == 0)
2360Sstevel@tonic-gate return (0);
2370Sstevel@tonic-gate
2380Sstevel@tonic-gate /*
2390Sstevel@tonic-gate * zero file pointer
2400Sstevel@tonic-gate */
2410Sstevel@tonic-gate bzero((caddr_t)&filep->file, sizeof (struct nfs_file));
2420Sstevel@tonic-gate
2430Sstevel@tonic-gate /*
2440Sstevel@tonic-gate * "close" the fd.
2450Sstevel@tonic-gate */
2460Sstevel@tonic-gate filep->desc = 0;
2470Sstevel@tonic-gate
2480Sstevel@tonic-gate return (0);
2490Sstevel@tonic-gate }
2500Sstevel@tonic-gate
2510Sstevel@tonic-gate /*
2520Sstevel@tonic-gate * read from a file.
2530Sstevel@tonic-gate */
2540Sstevel@tonic-gate static ssize_t
boot_nfs_read(int fd,char * buf,size_t size)2550Sstevel@tonic-gate boot_nfs_read(int fd, char *buf, size_t size)
2560Sstevel@tonic-gate {
2570Sstevel@tonic-gate struct nfs_files *filep;
2580Sstevel@tonic-gate int count = 0;
2590Sstevel@tonic-gate
2600Sstevel@tonic-gate if (fd == 0) {
2610Sstevel@tonic-gate dprintf("boot_nfs_read: Bad file number.\n");
2620Sstevel@tonic-gate return (-1);
2630Sstevel@tonic-gate }
2640Sstevel@tonic-gate if (buf == NULL) {
2650Sstevel@tonic-gate dprintf("boot_nfs_read: Bad address.\n");
2660Sstevel@tonic-gate return (-1);
2670Sstevel@tonic-gate }
2680Sstevel@tonic-gate
2690Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG
2700Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS)
2710Sstevel@tonic-gate printf("boot_nfs_read(%d, %x, 0x%x)\n", fd, buf, size);
2720Sstevel@tonic-gate #endif
2730Sstevel@tonic-gate
2740Sstevel@tonic-gate /* initialize for read */
2750Sstevel@tonic-gate if ((filep = get_filep(fd)) == 0)
2760Sstevel@tonic-gate return (-1);
2770Sstevel@tonic-gate
2780Sstevel@tonic-gate switch (filep->file.version) {
2790Sstevel@tonic-gate case NFS_VERSION:
2800Sstevel@tonic-gate count = nfsread(&filep->file, buf, size);
2810Sstevel@tonic-gate break;
2820Sstevel@tonic-gate case NFS_V3:
2830Sstevel@tonic-gate count = nfs3read(&filep->file, buf, size);
2840Sstevel@tonic-gate break;
2850Sstevel@tonic-gate case NFS_V4:
2860Sstevel@tonic-gate count = nfs4read(&filep->file, buf, size);
2870Sstevel@tonic-gate break;
2880Sstevel@tonic-gate default:
2890Sstevel@tonic-gate printf("boot_nfs_read: NFS Version %d not supported\n",
290*5648Ssetje filep->file.version);
2910Sstevel@tonic-gate count = -1;
2920Sstevel@tonic-gate break;
2930Sstevel@tonic-gate }
2940Sstevel@tonic-gate
2950Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG
2960Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS)
2970Sstevel@tonic-gate printf("boot_nfs_read(): 0x%x bytes.\n", count);
2980Sstevel@tonic-gate #endif
2990Sstevel@tonic-gate return (count);
3000Sstevel@tonic-gate }
3010Sstevel@tonic-gate
3020Sstevel@tonic-gate /*
3030Sstevel@tonic-gate * lseek - move read file pointer.
3040Sstevel@tonic-gate */
3050Sstevel@tonic-gate
3060Sstevel@tonic-gate static off_t
boot_nfs_lseek(int fd,off_t offset,int whence)3070Sstevel@tonic-gate boot_nfs_lseek(int fd, off_t offset, int whence)
3080Sstevel@tonic-gate {
3090Sstevel@tonic-gate struct nfs_files *filep;
3100Sstevel@tonic-gate
3110Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG
3120Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS)
3130Sstevel@tonic-gate printf("boot_nfs_lseek(%d, 0x%x, %d)\n", fd, offset, whence);
3140Sstevel@tonic-gate #endif
3150Sstevel@tonic-gate
3160Sstevel@tonic-gate if (fd == 0) {
3170Sstevel@tonic-gate dprintf("boot_nfs_lseek: Bad file number.\n");
3180Sstevel@tonic-gate return (-1);
3190Sstevel@tonic-gate }
3200Sstevel@tonic-gate
3210Sstevel@tonic-gate if ((filep = get_filep(fd)) == 0)
3220Sstevel@tonic-gate return (-1);
3230Sstevel@tonic-gate
3240Sstevel@tonic-gate switch (whence) {
3250Sstevel@tonic-gate
3260Sstevel@tonic-gate case SEEK_SET:
3270Sstevel@tonic-gate /*
3280Sstevel@tonic-gate * file ptr is set to offset from beginning of file
3290Sstevel@tonic-gate */
3300Sstevel@tonic-gate filep->file.offset = offset;
3310Sstevel@tonic-gate break;
3320Sstevel@tonic-gate case SEEK_CUR:
3330Sstevel@tonic-gate /*
3340Sstevel@tonic-gate * file ptr is set to offset from current position
3350Sstevel@tonic-gate */
3360Sstevel@tonic-gate filep->file.offset += offset;
3370Sstevel@tonic-gate break;
3380Sstevel@tonic-gate case SEEK_END:
3390Sstevel@tonic-gate /*
3400Sstevel@tonic-gate * file ptr is set to current size of file plus offset.
3410Sstevel@tonic-gate * But since we only support reading, this is illegal.
3420Sstevel@tonic-gate */
3430Sstevel@tonic-gate default:
3440Sstevel@tonic-gate /*
3450Sstevel@tonic-gate * invalid offset origin
3460Sstevel@tonic-gate */
3470Sstevel@tonic-gate dprintf("boot_nfs_lseek: invalid whence value.\n");
3480Sstevel@tonic-gate return (-1);
3490Sstevel@tonic-gate }
3500Sstevel@tonic-gate
3510Sstevel@tonic-gate #ifdef notyet
3520Sstevel@tonic-gate return (filep->file.offset);
3530Sstevel@tonic-gate #else
3540Sstevel@tonic-gate /*
3550Sstevel@tonic-gate * BROKE - lseek should return the offset seeked to on a
3560Sstevel@tonic-gate * successful seek, not zero - This must be fixed in the
3570Sstevel@tonic-gate * kernel before It can be fixed here.
3580Sstevel@tonic-gate */
3590Sstevel@tonic-gate return (0);
3600Sstevel@tonic-gate #endif /* notyet */
3610Sstevel@tonic-gate }
3620Sstevel@tonic-gate
3630Sstevel@tonic-gate /*
3640Sstevel@tonic-gate * This version of fstat supports mode, size, inode #, and times only.
3650Sstevel@tonic-gate * It can be enhanced if more is required,
3660Sstevel@tonic-gate */
3670Sstevel@tonic-gate
3680Sstevel@tonic-gate static int
boot_nfs_fstat(int fd,struct bootstat * stp)3690Sstevel@tonic-gate boot_nfs_fstat(int fd, struct bootstat *stp)
3700Sstevel@tonic-gate {
3710Sstevel@tonic-gate struct vattr va;
3720Sstevel@tonic-gate struct nfs_files *filep;
3730Sstevel@tonic-gate int status;
3740Sstevel@tonic-gate
3750Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG
3760Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS) {
3770Sstevel@tonic-gate printf("boot_nfs_fstat(%d, 0x%x)\n", fd, stp);
3780Sstevel@tonic-gate }
3790Sstevel@tonic-gate #endif
3800Sstevel@tonic-gate if (fd == 0) {
3810Sstevel@tonic-gate dprintf("boot_nfs_fstat(): Bad file number 0.\n");
3820Sstevel@tonic-gate return (-1);
3830Sstevel@tonic-gate }
3840Sstevel@tonic-gate
3850Sstevel@tonic-gate if ((filep = get_filep(fd)) == 0)
3860Sstevel@tonic-gate return (-1);
3870Sstevel@tonic-gate
3880Sstevel@tonic-gate bzero((char *)&va, sizeof (va));
389*5648Ssetje va.va_mask = AT_TYPE | AT_SIZE | AT_MODE | AT_NODEID |
390*5648Ssetje AT_ATIME | AT_CTIME | AT_MTIME;
3910Sstevel@tonic-gate
3920Sstevel@tonic-gate switch (filep->file.version) {
3930Sstevel@tonic-gate case NFS_VERSION:
3940Sstevel@tonic-gate status = nfsgetattr(&filep->file, &va);
3950Sstevel@tonic-gate break;
3960Sstevel@tonic-gate case NFS_V3:
3970Sstevel@tonic-gate status = nfs3getattr(&filep->file, &va);
3980Sstevel@tonic-gate break;
3990Sstevel@tonic-gate case NFS_V4:
4000Sstevel@tonic-gate status = nfs4getattr(&filep->file, &va);
4010Sstevel@tonic-gate break;
4020Sstevel@tonic-gate default:
4030Sstevel@tonic-gate printf("boot_nfs_fstat: NFS Version %d not supported\n",
404*5648Ssetje filep->file.version);
4050Sstevel@tonic-gate status = -1;
4060Sstevel@tonic-gate break;
4070Sstevel@tonic-gate }
4080Sstevel@tonic-gate
4090Sstevel@tonic-gate if (status != 0)
4100Sstevel@tonic-gate return (-1);
4110Sstevel@tonic-gate
4120Sstevel@tonic-gate if (va.va_size > (u_offset_t)MAXOFF_T) {
4130Sstevel@tonic-gate dprintf("boot_nfs_fstat(): File too large.\n");
4140Sstevel@tonic-gate return (-1);
4150Sstevel@tonic-gate }
4160Sstevel@tonic-gate stp->st_size = (off_t)va.va_size;
4170Sstevel@tonic-gate stp->st_mode = VTTOIF(va.va_type) | va.va_mode;
4180Sstevel@tonic-gate stp->st_atim.tv_sec = va.va_atime.tv_sec;
4190Sstevel@tonic-gate stp->st_atim.tv_nsec = va.va_atime.tv_nsec;
4200Sstevel@tonic-gate stp->st_ctim.tv_sec = va.va_ctime.tv_sec;
4210Sstevel@tonic-gate stp->st_ctim.tv_nsec = va.va_ctime.tv_nsec;
4220Sstevel@tonic-gate stp->st_mtim.tv_sec = va.va_mtime.tv_sec;
4230Sstevel@tonic-gate stp->st_mtim.tv_nsec = va.va_mtime.tv_nsec;
4240Sstevel@tonic-gate stp->st_ino = (ino_t)va.va_nodeid;
4250Sstevel@tonic-gate
4260Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG
4270Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS)
4280Sstevel@tonic-gate printf("boot_nfs_fstat(): done.\n");
4290Sstevel@tonic-gate #endif
4300Sstevel@tonic-gate return (0);
4310Sstevel@tonic-gate }
4320Sstevel@tonic-gate
4330Sstevel@tonic-gate static int
boot_nfs_getdents(int fd,struct dirent * dep,unsigned size)4340Sstevel@tonic-gate boot_nfs_getdents(int fd, struct dirent *dep, unsigned size)
4350Sstevel@tonic-gate {
4360Sstevel@tonic-gate struct nfs_files *filep;
4370Sstevel@tonic-gate int status;
4380Sstevel@tonic-gate
4390Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG
4400Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS) {
4410Sstevel@tonic-gate printf("boot_nfs_getdents(%d, 0x%x, 0x%x)\n", fd, dep, size);
4420Sstevel@tonic-gate }
4430Sstevel@tonic-gate #endif
4440Sstevel@tonic-gate
4450Sstevel@tonic-gate if (fd == 0) {
4460Sstevel@tonic-gate dprintf("boot_nfs_getdents(): Bad file number 0.\n");
4470Sstevel@tonic-gate return (-1);
4480Sstevel@tonic-gate }
4490Sstevel@tonic-gate
4500Sstevel@tonic-gate if ((filep = get_filep(fd)) == 0)
4510Sstevel@tonic-gate return (-1);
4520Sstevel@tonic-gate
4530Sstevel@tonic-gate switch (filep->file.version) {
4540Sstevel@tonic-gate case NFS_VERSION:
4550Sstevel@tonic-gate status = nfsgetdents(&filep->file, dep, size);
4560Sstevel@tonic-gate break;
4570Sstevel@tonic-gate case NFS_V3:
4580Sstevel@tonic-gate status = nfs3getdents(&filep->file, dep, size);
4590Sstevel@tonic-gate break;
4600Sstevel@tonic-gate default:
4610Sstevel@tonic-gate printf("boot_nfs_getdents: NFS Version %d not supported\n",
462*5648Ssetje filep->file.version);
4630Sstevel@tonic-gate status = -1;
4640Sstevel@tonic-gate }
4650Sstevel@tonic-gate
4660Sstevel@tonic-gate #ifdef NFS_OPS_DEBUG
4670Sstevel@tonic-gate if ((boothowto & DBFLAGS) == DBFLAGS)
4680Sstevel@tonic-gate printf("boot_nfs_getdents(): done.\n");
4690Sstevel@tonic-gate #endif
4700Sstevel@tonic-gate return (status);
4710Sstevel@tonic-gate }
472