Exemple #1
0
/*
 * nfs_read_req - Read File on NFS Server
 */
static int nfs_read_req(struct file_priv *priv, int offset, int readlen)
{
	uint32_t data[1024];
	uint32_t *p;
	uint32_t *filedata;
	int len;
	int ret;
	int rlen;

	p = &(data[0]);
	p = rpc_add_credentials(p);

	memcpy (p, priv->filefh, NFS_FHSIZE);
	p += (NFS_FHSIZE / 4);
	*p++ = htonl(offset);
	*p++ = htonl(readlen);
	*p++ = 0;

	len = p - &(data[0]);

	ret = rpc_req(priv->npriv, PROG_NFS, NFS_READ, data, len);
	if (ret)
		return ret;

	filedata = (uint32_t *)(nfs_packet + sizeof(struct rpc_reply));

	rlen = ntohl(net_read_uint32(filedata + 18));

	kfifo_put(priv->fifo, (char *)(filedata + 19), rlen);

	return 0;
}
Exemple #2
0
/**************************************************************************
NFS_READ - Read File on NFS Server
**************************************************************************/
static int nfs_read(int server, int port, char *fh, int offset, int len,
		    int sport)
{
	struct rpc_t buf, *rpc;
	unsigned long id;
	int retries;
	long *p;

	static int tokens=0;
	/*
	 * Try to implement something similar to a window protocol in
	 * terms of response to losses. On successful receive, increment
	 * the number of tokens by 1 (cap at 256). On failure, halve it.
	 * When the number of tokens is >= 2, use a very short timeout.
	 */

	id = rpc_id++;
	buf.u.call.id = htonl(id);
	buf.u.call.type = htonl(MSG_CALL);
	buf.u.call.rpcvers = htonl(2);	/* use RPC version 2 */
	buf.u.call.prog = htonl(PROG_NFS);
	buf.u.call.vers = htonl(2);	/* nfsd is version 2 */
	buf.u.call.proc = htonl(NFS_READ);
	p = rpc_add_credentials((long *)buf.u.call.data);
	memcpy(p, fh, NFS_FHSIZE);
	p += NFS_FHSIZE / 4;
	*p++ = htonl(offset);
	*p++ = htonl(len);
	*p++ = 0;		/* unused parameter */
	for (retries = 0; retries < MAX_RPC_RETRIES; retries++) {
		long timeout = rfc2131_sleep_interval(TIMEOUT, retries);
		if (tokens >= 2)
			timeout = TICKS_PER_SEC/2;

		udp_transmit(arptable[server].ipaddr.s_addr, sport, port,
			(char *)p - (char *)&buf, &buf);
		if (await_reply(await_rpc, sport, &id, timeout)) {
			if (tokens < 256)
				tokens++;
			rpc = (struct rpc_t *)&nic.packet[ETH_HLEN];
			if (rpc->u.reply.rstatus || rpc->u.reply.verifier ||
			    rpc->u.reply.astatus || rpc->u.reply.data[0]) {
				rpc_printerror(rpc);
				if (rpc->u.reply.rstatus) {
					/* RPC failed, no verifier, data[0] */
					return -9999;
				}
				if (rpc->u.reply.astatus) {
					/* RPC couldn't decode parameters */
					return -9998;
				}
				return -ntohl(rpc->u.reply.data[0]);
			} else {
				return 0;
			}
		} else
			tokens >>= 1;
	}
	return -1;
}
Exemple #3
0
/**************************************************************************
NFS_LOOKUP - Lookup Pathname
**************************************************************************/
static void
nfs_lookup_req(char *fname)
{
	uint32_t data[1024];
	uint32_t *p;
	int len;
	int fnamelen;

	fnamelen = strlen(fname);

	p = &(data[0]);
	p = (uint32_t *)rpc_add_credentials((long *)p);

	memcpy(p, dirfh, NFS_FHSIZE);
	p += (NFS_FHSIZE / 4);
	*p++ = htonl(fnamelen);
	if (fnamelen & 3)
		*(p + fnamelen / 4) = 0;
	memcpy(p, fname, fnamelen);
	p += (fnamelen + 3) / 4;

	len = (uint32_t *)p - (uint32_t *)&(data[0]);

	rpc_req(PROG_NFS, NFS_LOOKUP, data, len);
}
Exemple #4
0
static void *nfs_readdirattr_req(struct file_priv *priv, int *plen, uint32_t cookie)
{
	uint32_t data[1024];
	uint32_t *p;
	int len;
	int ret;
	void *buf;

	p = &(data[0]);
	p = rpc_add_credentials(p);

	memcpy(p, priv->filefh, NFS_FHSIZE);
	p += (NFS_FHSIZE / 4);
	*p++ = htonl(cookie); /* cookie */
	*p++ = htonl(1024); /* count */
	*p++ = 0;

	len = p - &(data[0]);

	ret = rpc_req(priv->npriv, PROG_NFS, NFS_READDIR, data, len);
	if (ret)
		return NULL;

	*plen = nfs_len - sizeof(struct rpc_reply) + 4;

	buf = xzalloc(*plen);

	memcpy(buf, nfs_packet + sizeof(struct rpc_reply) + 4, *plen);

	return buf;
}
Exemple #5
0
static int nfs_attr_req(struct file_priv *priv, struct stat *s)
{
	uint32_t data[1024];
	uint32_t *p;
	int len;
	int ret;
	struct fattr *fattr;
	uint32_t type;

	p = &(data[0]);
	p = rpc_add_credentials(p);

	memcpy(p, priv->filefh, NFS_FHSIZE);
	p += (NFS_FHSIZE / 4);
	*p++ = 0;

	len = p - &(data[0]);

	ret = rpc_req(priv->npriv, PROG_NFS, NFS_GETATTR, data, len);
	if (ret)
		return ret;

	fattr = nfs_packet + sizeof(struct rpc_reply) + 4;

	type = ntohl(net_read_uint32(&fattr->type));

	s->st_size = ntohl(net_read_uint32(&fattr->size));
	s->st_mode = ntohl(net_read_uint32(&fattr->mode));

	return 0;
}
Exemple #6
0
/*
 * nfs_lookup_req - Lookup Pathname
 */
static int nfs_lookup_req(struct file_priv *priv, const char *filename,
		int fnamelen)
{
	uint32_t data[1024];
	uint32_t *p;
	int len;
	int ret;

	p = &(data[0]);
	p = rpc_add_credentials(p);

	memcpy(p, priv->filefh, NFS_FHSIZE);

	p += (NFS_FHSIZE / 4);
	*p++ = htonl(fnamelen);

	if (fnamelen & 3)
		*(p + fnamelen / 4) = 0;

	memcpy(p, filename, fnamelen);
	p += (fnamelen + 3) / 4;

	len = p - &(data[0]);

	ret = rpc_req(priv->npriv, PROG_NFS, NFS_LOOKUP, data, len);
	if (ret)
		return ret;

	memcpy(priv->filefh, nfs_packet + sizeof(struct rpc_reply) + 4, NFS_FHSIZE);

	return 0;
}
Exemple #7
0
/*
 * nfs_mount_req - Mount an NFS Filesystem
 */
static int nfs_mount_req(struct nfs_priv *npriv)
{
	uint32_t data[1024];
	uint32_t *p;
	int len;
	int pathlen;
	int ret;

	pathlen = strlen(npriv->path);

	debug("%s: %s\n", __func__, npriv->path);

	p = &(data[0]);
	p = rpc_add_credentials(p);

	*p++ = htonl(pathlen);
	if (pathlen & 3)
		*(p + pathlen / 4) = 0;

	memcpy (p, npriv->path, pathlen);
	p += (pathlen + 3) / 4;

	len = p - &(data[0]);

	ret = rpc_req(npriv, PROG_MOUNT, MOUNT_ADDENTRY, data, len);
	if (ret)
		return ret;

	memcpy(npriv->rootfh, nfs_packet + sizeof(struct rpc_reply) + 4, NFS_FHSIZE);

	return 0;
}
Exemple #8
0
/**************************************************************************
NFS_LOOKUP - Lookup Pathname
**************************************************************************/
static int nfs_lookup(int server, int port, char *fh, char *path, char *nfh,
	int sport)
{
	struct rpc_t buf, *rpc;
	unsigned long id;
	long *p;
	int retries;
	int pathlen = strlen(path);

	id = rpc_id++;
	buf.u.call.id = htonl(id);
	buf.u.call.type = htonl(MSG_CALL);
	buf.u.call.rpcvers = htonl(2);	/* use RPC version 2 */
	buf.u.call.prog = htonl(PROG_NFS);
	buf.u.call.vers = htonl(2);	/* nfsd is version 2 */
	buf.u.call.proc = htonl(NFS_LOOKUP);
	p = rpc_add_credentials((long *)buf.u.call.data);
	memcpy(p, fh, NFS_FHSIZE);
	p += (NFS_FHSIZE / 4);
	*p++ = htonl(pathlen);
	if (pathlen & 3) {
		*(p + pathlen / 4) = 0;	/* add zero padding */
	}
	memcpy(p, path, pathlen);
	p += (pathlen + 3) / 4;
	for (retries = 0; retries < MAX_RPC_RETRIES; retries++) {
		long timeout = rfc2131_sleep_interval(TIMEOUT, retries);
		udp_transmit(arptable[server].ipaddr.s_addr, sport, port,
			(char *)p - (char *)&buf, &buf);
		if (await_reply(await_rpc, sport, &id, timeout)) {
			rpc = (struct rpc_t *)&nic.packet[ETH_HLEN];
			if (rpc->u.reply.rstatus || rpc->u.reply.verifier ||
			    rpc->u.reply.astatus || rpc->u.reply.data[0]) {
				rpc_printerror(rpc);
				if (rpc->u.reply.rstatus) {
					/* RPC failed, no verifier, data[0] */
					return -9999;
				}
				if (rpc->u.reply.astatus) {
					/* RPC couldn't decode parameters */
					return -9998;
				}
				return -ntohl(rpc->u.reply.data[0]);
			} else {
				memcpy(nfh, rpc->u.reply.data + 1, NFS_FHSIZE);
				return 0;
			}
		}
	}
	return -1;
}
Exemple #9
0
/***************************************************************************
 * NFS_READLINK (AH 2003-07-14)
 * This procedure is called when read of the first block fails -
 * this probably happens when it's a directory or a symlink
 * In case of successful readlink(), the dirname is manipulated,
 * so that inside the nfs() function a recursion can be done.
 **************************************************************************/
static void nfs_readlink_req(void)
{
	uint32_t data[1024];
	uint32_t *p;
	int len;

	p = &(data[0]);
	p = rpc_add_credentials(p);

	memcpy (p, filefh, NFS_FHSIZE);
	p += (NFS_FHSIZE / 4);

	len = p - &(data[0]);

	rpc_req(PROG_NFS, NFS_READLINK, data, len);
}
Exemple #10
0
/**************************************************************************
NFS_UMOUNTALL - Unmount all our NFS Filesystems on the Server
**************************************************************************/
static void nfs_umountall_req(void)
{
	uint32_t data[1024];
	uint32_t *p;
	int len;

	if (nfs_server_mount_port < 0)
		/* Nothing mounted, nothing to umount */
		return;

	p = &(data[0]);
	p = rpc_add_credentials(p);

	len = p - &(data[0]);

	rpc_req(PROG_MOUNT, MOUNT_UMOUNTALL, data, len);
}
Exemple #11
0
/**************************************************************************
NFS_UMOUNTALL - Unmount all our NFS Filesystems on the Server
**************************************************************************/
static void
nfs_umountall_req(void)
{
	uint32_t data[1024];
	uint32_t *p;
	int len;

	if ((NfsSrvMountPort == -1) || (!fs_mounted))
		/* Nothing mounted, nothing to umount */
		return;

	p = &(data[0]);
	p = (uint32_t *)rpc_add_credentials((long *)p);

	len = (uint32_t *)p - (uint32_t *)&(data[0]);

	rpc_req(PROG_MOUNT, MOUNT_UMOUNTALL, data, len);
}
Exemple #12
0
/**************************************************************************
NFS_READ - Read File on NFS Server
**************************************************************************/
static void nfs_read_req(int offset, int readlen)
{
	uint32_t data[1024];
	uint32_t *p;
	int len;

	p = &(data[0]);
	p = rpc_add_credentials(p);

	memcpy (p, filefh, NFS_FHSIZE);
	p += (NFS_FHSIZE / 4);
	*p++ = htonl(offset);
	*p++ = htonl(readlen);
	*p++ = 0;

	len = p - &(data[0]);

	rpc_req(PROG_NFS, NFS_READ, data, len);
}
Exemple #13
0
/**************************************************************************
NFS_MOUNT - Mount an NFS Filesystem
**************************************************************************/
static void
nfs_mount_req (char *path)
{
	uint32_t data[1024];
	uint32_t *p;
	int len;
	int pathlen;

	pathlen = strlen (path);

	p = &(data[0]);
	p = (uint32_t *)rpc_add_credentials((long *)p);

	*p++ = htonl(pathlen);
	if (pathlen & 3) *(p + pathlen / 4) = 0;
	memcpy (p, path, pathlen);
	p += (pathlen + 3) / 4;

	len = (uint32_t *)p - (uint32_t *)&(data[0]);

	rpc_req (PROG_MOUNT, MOUNT_ADDENTRY, data, len);
}
Exemple #14
0
/**************************************************************************
NFS_UMOUNTALL - Unmount all our NFS Filesystems on the Server
**************************************************************************/
void nfs_umountall(int server)
{
	struct rpc_t buf, *rpc;
	unsigned long id;
	int retries;
	long *p;

	if (!arptable[server].ipaddr.s_addr) {
		/* Haven't sent a single UDP packet to this server */
		return;
	}
	if ((mount_port == -1) || (!fs_mounted)) {
		/* Nothing mounted, nothing to umount */
		return;
	}
	id = rpc_id++;
	buf.u.call.id = htonl(id);
	buf.u.call.type = htonl(MSG_CALL);
	buf.u.call.rpcvers = htonl(2);	/* use RPC version 2 */
	buf.u.call.prog = htonl(PROG_MOUNT);
	buf.u.call.vers = htonl(1);	/* mountd is version 1 */
	buf.u.call.proc = htonl(MOUNT_UMOUNTALL);
	p = rpc_add_credentials((long *)buf.u.call.data);
	for (retries = 0; retries < MAX_RPC_RETRIES; retries++) {
		long timeout = rfc2131_sleep_interval(TIMEOUT, retries);
		udp_transmit(arptable[server].ipaddr.s_addr, oport, mount_port,
			(char *)p - (char *)&buf, &buf);
		if (await_reply(await_rpc, oport, &id, timeout)) {
			rpc = (struct rpc_t *)&nic.packet[ETH_HLEN];
			if (rpc->u.reply.rstatus || rpc->u.reply.verifier ||
			    rpc->u.reply.astatus) {
				rpc_printerror(rpc);
			}
			fs_mounted = 0;
			return;
		}
	}
}
Exemple #15
0
/*
 * nfs_umountall_req - Unmount all our NFS Filesystems on the Server
 */
static void nfs_umount_req(struct nfs_priv *npriv)
{
	uint32_t data[1024];
	uint32_t *p;
	int len;
	int pathlen;

	pathlen = strlen(npriv->path);

	p = &(data[0]);
	p = rpc_add_credentials(p);

	*p++ = htonl(pathlen);
	if (pathlen & 3)
		*(p + pathlen / 4) = 0;

	memcpy (p, npriv->path, pathlen);
	p += (pathlen + 3) / 4;

	len = p - &(data[0]);

	rpc_req(npriv, PROG_MOUNT, MOUNT_UMOUNT, data, len);
}
Exemple #16
0
static int nfs_readlink_req(struct file_priv *priv, char* buf, size_t size)
{
	uint32_t data[1024];
	uint32_t *p;
	int len;
	int ret;
	char *path;
	uint32_t *filedata;

	p = &(data[0]);
	p = rpc_add_credentials(p);

	memcpy(p, priv->filefh, NFS_FHSIZE);
	p += (NFS_FHSIZE / 4);

	len = p - &(data[0]);

	ret = rpc_req(priv->npriv, PROG_NFS, NFS_READLINK, data, len);
	if (ret)
		return ret;

	filedata = nfs_packet + sizeof(struct rpc_reply);
	filedata++;

	len = ntohl(net_read_uint32(filedata)); /* new path length */
	filedata++;

	path = (char *)filedata;

	if (len > size)
		len = size;

	memcpy(buf, path, len);

	return 0;
}
Exemple #17
0
/***************************************************************************
 * NFS_READLINK (AH 2003-07-14)
 * This procedure is called when read of the first block fails -
 * this probably happens when it's a directory or a symlink
 * In case of successful readlink(), the dirname is manipulated,
 * so that inside the nfs() function a recursion can be done.
 **************************************************************************/
static int nfs_readlink(int server, int port, char *fh, char *path, char *nfh,
	int sport)
{
	struct rpc_t buf, *rpc;
	unsigned long id;
	long *p;
	int retries;
	int pathlen = strlen(path);

	id = rpc_id++;
	buf.u.call.id = htonl(id);
	buf.u.call.type = htonl(MSG_CALL);
	buf.u.call.rpcvers = htonl(2);	/* use RPC version 2 */
	buf.u.call.prog = htonl(PROG_NFS);
	buf.u.call.vers = htonl(2);	/* nfsd is version 2 */
	buf.u.call.proc = htonl(NFS_READLINK);
	p = rpc_add_credentials((long *)buf.u.call.data);
	memcpy(p, nfh, NFS_FHSIZE);
	p += (NFS_FHSIZE / 4);
	for (retries = 0; retries < MAX_RPC_RETRIES; retries++) {
		long timeout = rfc2131_sleep_interval(TIMEOUT, retries);
		udp_transmit(arptable[server].ipaddr.s_addr, sport, port,
			(char *)p - (char *)&buf, &buf);
		if (await_reply(await_rpc, sport, &id, timeout)) {
			rpc = (struct rpc_t *)&nic.packet[ETH_HLEN];
			if (rpc->u.reply.rstatus || rpc->u.reply.verifier ||
			    rpc->u.reply.astatus || rpc->u.reply.data[0]) {
				rpc_printerror(rpc);
				if (rpc->u.reply.rstatus) {
					/* RPC failed, no verifier, data[0] */
					return -9999;
				}
				if (rpc->u.reply.astatus) {
					/* RPC couldn't decode parameters */
					return -9998;
				}
				return -ntohl(rpc->u.reply.data[0]);
			} else {
				// It *is* a link.
				// If it's a relative link, append everything to dirname, filename TOO!
				retries = strlen ( (char *)(&(rpc->u.reply.data[2]) ));
				if ( *((char *)(&(rpc->u.reply.data[2]))) != '/' ) {
					path[pathlen++] = '/';
					while ( ( retries + pathlen ) > 298 ) {
						retries--;
					}
					if ( retries > 0 ) {
						memcpy(path + pathlen, &(rpc->u.reply.data[2]), retries + 1);
					} else { retries = 0; }
					path[pathlen + retries] = 0;
				} else {
					// Else make it the only path.
					if ( retries > 298 ) { retries = 298; }
					memcpy ( path, &(rpc->u.reply.data[2]), retries + 1 );
					path[retries] = 0;
				}
				return 0;
			}
		}
	}
	return -1;
}