Changeset View
Changeset View
Standalone View
Standalone View
head/lib/libstand/nfs.c
Show All 30 Lines | |||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/time.h> | #include <sys/time.h> | ||||
#include <sys/socket.h> | #include <sys/socket.h> | ||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <stddef.h> | |||||
#include <netinet/in.h> | #include <netinet/in.h> | ||||
#include <netinet/in_systm.h> | #include <netinet/in_systm.h> | ||||
#include "rpcv2.h" | #include "rpcv2.h" | ||||
#include "nfsv2.h" | #include "nfsv2.h" | ||||
#include "stand.h" | #include "stand.h" | ||||
#include "net.h" | #include "net.h" | ||||
#include "netif.h" | #include "netif.h" | ||||
#include "rpc.h" | #include "rpc.h" | ||||
#define NFS_DEBUGxx | #define NFS_DEBUGxx | ||||
#define NFSREAD_SIZE 1024 | #define NFSREAD_MIN_SIZE 1024 | ||||
#define NFSREAD_MAX_SIZE 4096 | |||||
/* Define our own NFS attributes without NQNFS stuff. */ | /* Define our own NFS attributes without NQNFS stuff. */ | ||||
#ifdef OLD_NFSV2 | #ifdef OLD_NFSV2 | ||||
struct nfsv2_fattrs { | struct nfsv2_fattrs { | ||||
n_long fa_type; | n_long fa_type; | ||||
n_long fa_mode; | n_long fa_mode; | ||||
n_long fa_nlink; | n_long fa_nlink; | ||||
n_long fa_uid; | n_long fa_uid; | ||||
Show All 16 Lines | struct nfs_read_args { | ||||
n_long xxx; /* XXX what's this for? */ | n_long xxx; /* XXX what's this for? */ | ||||
}; | }; | ||||
/* Data part of nfs rpc reply (also the largest thing we receive) */ | /* Data part of nfs rpc reply (also the largest thing we receive) */ | ||||
struct nfs_read_repl { | struct nfs_read_repl { | ||||
n_long errno; | n_long errno; | ||||
struct nfsv2_fattrs fa; | struct nfsv2_fattrs fa; | ||||
n_long count; | n_long count; | ||||
u_char data[NFSREAD_SIZE]; | u_char data[NFSREAD_MAX_SIZE]; | ||||
}; | }; | ||||
#ifndef NFS_NOSYMLINK | #ifndef NFS_NOSYMLINK | ||||
struct nfs_readlnk_repl { | struct nfs_readlnk_repl { | ||||
n_long errno; | n_long errno; | ||||
n_long len; | n_long len; | ||||
char path[NFS_MAXPATHLEN]; | char path[NFS_MAXPATHLEN]; | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 110 Lines • ▼ Show 20 Lines | struct fs_ops nfs_fsops = { | ||||
nfs_close, | nfs_close, | ||||
nfs_read, | nfs_read, | ||||
nfs_write, | nfs_write, | ||||
nfs_seek, | nfs_seek, | ||||
nfs_stat, | nfs_stat, | ||||
nfs_readdir | nfs_readdir | ||||
}; | }; | ||||
static int nfs_read_size = NFSREAD_MIN_SIZE; | |||||
#ifdef OLD_NFSV2 | #ifdef OLD_NFSV2 | ||||
/* | /* | ||||
* Fetch the root file handle (call mount daemon) | * Fetch the root file handle (call mount daemon) | ||||
* Return zero or error number. | * Return zero or error number. | ||||
*/ | */ | ||||
int | int | ||||
nfs_getrootfh(struct iodesc *d, char *path, u_char *fhp) | nfs_getrootfh(struct iodesc *d, char *path, u_char *fhp) | ||||
{ | { | ||||
Show All 38 Lines | if (cc == -1) { | ||||
/* errno was set by rpc_call */ | /* errno was set by rpc_call */ | ||||
return (errno); | return (errno); | ||||
} | } | ||||
if (cc < 4) | if (cc < 4) | ||||
return (EBADRPC); | return (EBADRPC); | ||||
if (repl->errno) | if (repl->errno) | ||||
return (ntohl(repl->errno)); | return (ntohl(repl->errno)); | ||||
bcopy(repl->fh, fhp, sizeof(repl->fh)); | bcopy(repl->fh, fhp, sizeof(repl->fh)); | ||||
/* | |||||
* Improve boot performance over NFS | |||||
*/ | |||||
if (getenv("nfs.read_size") != NULL) | |||||
nfs_read_size = strtol(getenv("nfs.read_size"), NULL, 0); | |||||
if (nfs_read_size < NFSREAD_MIN_SIZE) | |||||
nfs_read_size = NFSREAD_MIN_SIZE; | |||||
if (nfs_read_size > NFSREAD_MAX_SIZE) | |||||
nfs_read_size = NFSREAD_MAX_SIZE; | |||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Lookup a file. Store handle and attributes. | * Lookup a file. Store handle and attributes. | ||||
* Return zero or error number. | * Return zero or error number. | ||||
*/ | */ | ||||
int | int | ||||
▲ Show 20 Lines • Show All 121 Lines • ▼ Show 20 Lines | nfs_readdata(struct nfs_iodesc *d, off_t off, void *addr, size_t len) | ||||
long x; | long x; | ||||
int hlen, rlen; | int hlen, rlen; | ||||
args = &sdata.d; | args = &sdata.d; | ||||
repl = &rdata.d; | repl = &rdata.d; | ||||
bcopy(d->fh, args->fh, NFS_FHSIZE); | bcopy(d->fh, args->fh, NFS_FHSIZE); | ||||
args->off = htonl((n_long)off); | args->off = htonl((n_long)off); | ||||
if (len > NFSREAD_SIZE) | if (len > nfs_read_size) | ||||
len = NFSREAD_SIZE; | len = nfs_read_size; | ||||
args->len = htonl((n_long)len); | args->len = htonl((n_long)len); | ||||
args->xxx = htonl((n_long)0); | args->xxx = htonl((n_long)0); | ||||
hlen = sizeof(*repl) - NFSREAD_SIZE; | hlen = offsetof(struct nfs_read_rpl, data[0]); | ||||
cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER2, NFSPROC_READ, | cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER2, NFSPROC_READ, | ||||
args, sizeof(*args), | args, sizeof(*args), | ||||
repl, sizeof(*repl)); | repl, sizeof(*repl)); | ||||
if (cc == -1) { | if (cc == -1) { | ||||
/* errno was already set by rpc_call */ | /* errno was already set by rpc_call */ | ||||
return (-1); | return (-1); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 603 Lines • ▼ Show 20 Lines | nfs_readdata(struct nfs_iodesc *d, off_t off, void *addr, size_t len) | ||||
} *args; | } *args; | ||||
struct repl { | struct repl { | ||||
uint32_t errno; | uint32_t errno; | ||||
uint32_t ok; | uint32_t ok; | ||||
struct nfsv3_fattrs fa; | struct nfsv3_fattrs fa; | ||||
uint32_t count; | uint32_t count; | ||||
uint32_t eof; | uint32_t eof; | ||||
uint32_t len; | uint32_t len; | ||||
u_char data[NFSREAD_SIZE]; | u_char data[NFSREAD_MAX_SIZE]; | ||||
} *repl; | } *repl; | ||||
struct { | struct { | ||||
uint32_t h[RPC_HEADER_WORDS]; | uint32_t h[RPC_HEADER_WORDS]; | ||||
struct args d; | struct args d; | ||||
} sdata; | } sdata; | ||||
struct { | struct { | ||||
uint32_t h[RPC_HEADER_WORDS]; | uint32_t h[RPC_HEADER_WORDS]; | ||||
struct repl d; | struct repl d; | ||||
} rdata; | } rdata; | ||||
size_t cc; | size_t cc; | ||||
long x; | long x; | ||||
int hlen, rlen, pos; | int hlen, rlen, pos; | ||||
args = &sdata.d; | args = &sdata.d; | ||||
repl = &rdata.d; | repl = &rdata.d; | ||||
bzero(args, sizeof(*args)); | bzero(args, sizeof(*args)); | ||||
args->fhsize = htonl(d->fhsize); | args->fhsize = htonl(d->fhsize); | ||||
bcopy(d->fh, args->fhoffcnt, d->fhsize); | bcopy(d->fh, args->fhoffcnt, d->fhsize); | ||||
pos = roundup(d->fhsize, sizeof(uint32_t)) / sizeof(uint32_t); | pos = roundup(d->fhsize, sizeof(uint32_t)) / sizeof(uint32_t); | ||||
args->fhoffcnt[pos++] = 0; | args->fhoffcnt[pos++] = 0; | ||||
args->fhoffcnt[pos++] = htonl((uint32_t)off); | args->fhoffcnt[pos++] = htonl((uint32_t)off); | ||||
if (len > NFSREAD_SIZE) | if (len > nfs_read_size) | ||||
len = NFSREAD_SIZE; | len = nfs_read_size; | ||||
args->fhoffcnt[pos] = htonl((uint32_t)len); | args->fhoffcnt[pos] = htonl((uint32_t)len); | ||||
hlen = sizeof(*repl) - NFSREAD_SIZE; | hlen = offsetof(struct repl, data[0]); | ||||
cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER3, NFSPROCV3_READ, | cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER3, NFSPROCV3_READ, | ||||
args, 4 * sizeof(uint32_t) + roundup(d->fhsize, sizeof(uint32_t)), | args, 4 * sizeof(uint32_t) + roundup(d->fhsize, sizeof(uint32_t)), | ||||
repl, sizeof(*repl)); | repl, sizeof(*repl)); | ||||
if (cc == -1) | if (cc == -1) | ||||
/* errno was already set by rpc_call */ | /* errno was already set by rpc_call */ | ||||
return (-1); | return (-1); | ||||
if (cc < hlen) { | if (cc < hlen) { | ||||
▲ Show 20 Lines • Show All 418 Lines • Show Last 20 Lines |