Ejemplo n.º 1
0
/*
 * Encode access() argument
 */
static int
nfs3_xdr_accessargs(struct rpc_rqst *req, __be32 *p, struct nfs3_accessargs *args)
{
	p = xdr_encode_fhandle(p, args->fh);
	*p++ = htonl(args->access);
	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
	return 0;
}
Ejemplo n.º 2
0
/*
 * Encode SETATTR arguments
 */
static int
nfs_xdr_sattrargs(struct rpc_rqst *req, u32 *p, struct nfs_sattrargs *args)
{
    p = xdr_encode_fhandle(p, args->fh);
    p = xdr_encode_sattr(p, args->sattr);
    req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
    return 0;
}
Ejemplo n.º 3
0
/*
 * Encode directory ops argument
 * LOOKUP, REMOVE, RMDIR
 */
static int
nfs_xdr_diropargs(struct rpc_rqst *req, u32 *p, struct nfs_diropargs *args)
{
    p = xdr_encode_fhandle(p, args->fh);
    p = xdr_encode_array(p, args->name, args->len);
    req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
    return 0;
}
Ejemplo n.º 4
0
/*
 * Encode REMOVE argument
 */
static int
nfs3_xdr_removeargs(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *args)
{
	p = xdr_encode_fhandle(p, args->fh);
	p = xdr_encode_array(p, args->name.name, args->name.len);
	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
	return 0;
}
Ejemplo n.º 5
0
/*
 * Encode MKDIR arguments
 */
static int
nfs3_xdr_mkdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mkdirargs *args)
{
	p = xdr_encode_fhandle(p, args->fh);
	p = xdr_encode_array(p, args->name, args->len);
	p = xdr_encode_sattr(p, args->sattr);
	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
	return 0;
}
Ejemplo n.º 6
0
/*
 * Encode SYMLINK arguments
 */
static int
nfs_xdr_symlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_symlinkargs *args)
{
	p = xdr_encode_fhandle(p, args->fromfh);
	p = xdr_encode_array(p, args->fromname, args->fromlen);
	p = xdr_encode_array(p, args->topath, args->tolen);
	p = xdr_encode_sattr(p, args->sattr);
	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
	return 0;
}
Ejemplo n.º 7
0
int nfs_proc_readdir(struct nfs_server *server, struct nfs_fh *fhandle,
		     int cookie, int count, struct nfs_entry *entry)
{
	int *p, *p0;
	int status;
	int ruid = 0;
	int i;
	int size;
	int eof;

	PRINTK("NFS call  readdir %d @ %d\n", count, cookie);
	size = server->rsize;
	if (!(p0 = nfs_rpc_alloc(server->rsize)))
		return -EIO;
retry:
	p = nfs_rpc_header(p0, NFSPROC_READDIR, ruid);
	p = xdr_encode_fhandle(p, fhandle);
	*p++ = htonl(cookie);
	*p++ = htonl(size);
	if ((status = nfs_rpc_call(server, p0, p, server->rsize)) < 0) {
		nfs_rpc_free(p0);
		return status;
	}
	if (!(p = nfs_rpc_verify(p0)))
		status = -errno_NFSERR_IO;
	else if ((status = ntohl(*p++)) == NFS_OK) {
		for (i = 0; i < count && *p++; i++) {
			if (!(p = xdr_decode_entry(p, entry++)))
				break;
		}
		if (!p) {
			printk("nfs_proc_readdir: giant filename\n");
			status = -errno_NFSERR_IO;
		}
		else {
			eof = (i == count && !*p++ && *p++)
			      || (i < count && *p++);
			if (eof && i)
				entry[-1].eof = 1;
			PRINTK("NFS reply readdir %d %s\n", i,
			       eof ? "eof" : "");
			status = i;
		}
	}
	else {
		if (!ruid && current->fsuid == 0 && current->uid != 0) {
			ruid = 1;
			goto retry;
		}
		PRINTK("NFS reply readdir failed = %d\n", status);
		status = -nfs_stat_to_errno(status);
	}
	nfs_rpc_free(p0);
	return status;
}
Ejemplo n.º 8
0
/*
 * Encode SETATTR arguments
 */
static int
nfs3_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs3_sattrargs *args)
{
	p = xdr_encode_fhandle(p, args->fh);
	p = xdr_encode_sattr(p, args->sattr);
	*p++ = htonl(args->guard);
	if (args->guard)
		p = xdr_encode_time3(p, &args->guardtime);
	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
	return 0;
}
Ejemplo n.º 9
0
/*
 * Encode SYMLINK arguments
 */
static int
nfs3_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_symlinkargs *args)
{
	p = xdr_encode_fhandle(p, args->fromfh);
	p = xdr_encode_array(p, args->fromname, args->fromlen);
	p = xdr_encode_sattr(p, args->sattr);
	*p++ = htonl(args->pathlen);
	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);

	/* Copy the page */
	xdr_encode_pages(&req->rq_snd_buf, args->pages, 0, args->pathlen);
	return 0;
}
Ejemplo n.º 10
0
int nfs_proc_rename(struct nfs_server *server,
		    struct nfs_fh *old_dir, const char *old_name,
		    struct nfs_fh *new_dir, const char *new_name)
{
	int *p, *p0;
	int status;
	int ruid = 0;

	PRINTK("NFS call  rename %s -> %s\n", old_name, new_name);
	if (!(p0 = nfs_rpc_alloc(server->wsize)))
		return -EIO;
retry:
	p = nfs_rpc_header(p0, NFSPROC_RENAME, ruid);
	p = xdr_encode_fhandle(p, old_dir);
	p = xdr_encode_string(p, old_name);
	p = xdr_encode_fhandle(p, new_dir);
	p = xdr_encode_string(p, new_name);
	if ((status = nfs_rpc_call(server, p0, p, server->wsize)) < 0) {
		nfs_rpc_free(p0);
		return status;
	}
	if (!(p = nfs_rpc_verify(p0)))
		status = -errno_NFSERR_IO;
	else if ((status = ntohl(*p++)) == NFS_OK) {
		PRINTK("NFS reply rename\n");
		/* status = 0; */
	}
	else {
		if (!ruid && current->fsuid == 0 && current->uid != 0) {
			ruid = 1;
			goto retry;
		}
		PRINTK("NFS reply rename failed = %d\n", status);
		status = -nfs_stat_to_errno(status);
	}
	nfs_rpc_free(p0);
	return status;
}
Ejemplo n.º 11
0
/*
 * Encode READLINK args
 */
static int
nfs_xdr_readlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_readlinkargs *args)
{
	struct rpc_auth *auth = req->rq_task->tk_auth;
	unsigned int replen;

	p = xdr_encode_fhandle(p, args->fh);
	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);

	/* Inline the page array */
	replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readlinkres_sz) << 2;
	xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, args->pgbase, args->pglen);
	return 0;
}
Ejemplo n.º 12
0
/*
 * Encode MKNOD arguments
 */
static int
nfs3_xdr_mknodargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mknodargs *args)
{
	p = xdr_encode_fhandle(p, args->fh);
	p = xdr_encode_array(p, args->name, args->len);
	*p++ = htonl(args->type);
	p = xdr_encode_sattr(p, args->sattr);
	if (args->type == NF3CHR || args->type == NF3BLK) {
		*p++ = htonl(MAJOR(args->rdev));
		*p++ = htonl(MINOR(args->rdev));
	}

	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
	return 0;
}
Ejemplo n.º 13
0
/*
 * Encode CREATE arguments
 */
static int
nfs3_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs3_createargs *args)
{
	p = xdr_encode_fhandle(p, args->fh);
	p = xdr_encode_array(p, args->name, args->len);

	*p++ = htonl(args->createmode);
	if (args->createmode == NFS3_CREATE_EXCLUSIVE) {
		*p++ = args->verifier[0];
		*p++ = args->verifier[1];
	} else
		p = xdr_encode_sattr(p, args->sattr);

	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
	return 0;
}
Ejemplo n.º 14
0
/*
 * Encode arguments to readdir call
 */
static int
nfs3_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirargs *args)
{
	struct rpc_auth	*auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
	unsigned int replen;
	u32 count = args->count;

	p = xdr_encode_fhandle(p, args->fh);
	p = xdr_encode_hyper(p, args->cookie);
	*p++ = args->verf[0];
	*p++ = args->verf[1];
	if (args->plus) {
		/* readdirplus: need dircount + buffer size.
		 * We just make sure we make dircount big enough */
		*p++ = htonl(count >> 3);
	}
/*
 * Write arguments. Splice the buffer to be written into the iovec.
 */
static int
nfs3_xdr_writeargs(struct rpc_rqst *req, u32 *p, struct nfs_writeargs *args)
{
	struct xdr_buf *sndbuf = &req->rq_snd_buf;
	u32 count = args->count;

	p = xdr_encode_fhandle(p, args->fh);
	p = xdr_encode_hyper(p, args->offset);
	*p++ = htonl(count);
	*p++ = htonl(args->stable);
	*p++ = htonl(count);
	sndbuf->len = xdr_adjust_iovec(sndbuf->head, p);

	/* Copy the page array */
	xdr_encode_pages(sndbuf, args->pages, args->pgbase, count);
	return 0;
}
Ejemplo n.º 16
0
/*
 * Encode arguments to readdir call
 */
static int
nfs_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs_readdirargs *args)
{
	struct rpc_auth	*auth = req->rq_cred->cr_auth;
	unsigned int replen;
	u32 count = args->count;

	p = xdr_encode_fhandle(p, args->fh);
	*p++ = htonl(args->cookie);
	*p++ = htonl(count); /* see above */
	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);

	/* Inline the page array */
	replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readdirres_sz) << 2;
	xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0, count);
	return 0;
}
Ejemplo n.º 17
0
int nfs_proc_read(struct nfs_server *server, struct nfs_fh *fhandle,
	  int offset, int count, char *data, struct nfs_fattr *fattr, int fs)
{
	int *p, *p0;
	int status;
	int ruid = 0;
	int len;

	PRINTK("NFS call  read %d @ %d\n", count, offset);
	if (!(p0 = nfs_rpc_alloc(server->rsize)))
		return -EIO;
retry:
	p = nfs_rpc_header(p0, NFSPROC_READ, ruid);
	p = xdr_encode_fhandle(p, fhandle);
	*p++ = htonl(offset);
	*p++ = htonl(count);
	*p++ = htonl(count); /* traditional, could be any value */
	if ((status = nfs_rpc_call(server, p0, p, server->rsize)) < 0) {
		nfs_rpc_free(p0);
		return status;
	}
	if (!(p = nfs_rpc_verify(p0)))
		status = -errno_NFSERR_IO;
	else if ((status = ntohl(*p++)) == NFS_OK) {
		p = xdr_decode_fattr(p, fattr);
		if (!(p = xdr_decode_data(p, data, &len, count, fs))) {
			printk("nfs_proc_read: giant data size\n"); 
			status = -errno_NFSERR_IO;
		}
		else {
			status = len;
			PRINTK("NFS reply read %d\n", len);
		}
	}
	else {
		if (!ruid && current->fsuid == 0 && current->uid != 0) {
			ruid = 1;
			goto retry;
		}
		PRINTK("NFS reply read failed = %d\n", status);
		status = -nfs_stat_to_errno(status);
	}
	nfs_rpc_free(p0);
	return status;
}
Ejemplo n.º 18
0
/*
 * Write arguments. Splice the buffer to be written into the iovec.
 */
static int
nfs_xdr_writeargs(struct rpc_rqst *req, u32 *p, struct nfs_writeargs *args)
{
	unsigned int nr;
	u32 count = args->count;

	p = xdr_encode_fhandle(p, args->fh);
	*p++ = htonl(args->offset);
	*p++ = htonl(args->offset);
	*p++ = htonl(count);
	*p++ = htonl(count);
	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);

	/* Get the number of buffers in the send iovec */
	nr = args->nriov;

	if (nr+2 > MAX_IOVEC) {
                printk(KERN_ERR "NFS: Bad number of iov's in xdr_writeargs "
                        "(nr %d max %d)\n", nr, MAX_IOVEC);
                return -EINVAL;
        }

	/* Copy the iovec */
        memcpy(req->rq_svec + 1, args->iov, nr * sizeof(struct iovec));

#ifdef NFS_PAD_WRITES
	/*
	 * Some old servers require that the message length
	 * be a multiple of 4, so we pad it here if needed.
	 */
	if (count & 3) {
		struct iovec	*iov = req->rq_svec + nr + 1;
		int		pad = 4 - (count & 3);

		iov->iov_base = (void *) "\0\0\0";
		iov->iov_len  = pad;
		count += pad;
		nr++;
	}
#endif
	req->rq_slen += count;
	req->rq_snr += nr;

	return 0;
}
/*
 * Arguments to a READ call. Since we read data directly into the page
 * cache, we also set up the reply iovec here so that iov[1] points
 * exactly to the page we want to fetch.
 */
static int
nfs3_xdr_readargs(struct rpc_rqst *req, u32 *p, struct nfs_readargs *args)
{
	struct rpc_auth	*auth = req->rq_task->tk_auth;
	unsigned int replen;
	u32 count = args->count;

	p = xdr_encode_fhandle(p, args->fh);
	p = xdr_encode_hyper(p, args->offset);
	*p++ = htonl(count);
	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);

	/* Inline the page array */
	replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS3_readres_sz) << 2;
	xdr_inline_pages(&req->rq_rcv_buf, replen,
			 args->pages, args->pgbase, count);
	return 0;
}
Ejemplo n.º 20
0
/* not parallel */
int 
nfs_proc_read_np(struct nfs_fh *fhandle, int offset, int count, 
	      char *data, struct nfs_fattr *fattr) {
    int *p;
    int len = 0;
    int status;
    int ruid = 0;
    struct generic_server *server = fhandle->server;
    int *p0;
    
    DPRINTF(CLUHELP_LEVEL,("NFS call  read %d @ %d\n", count, offset));
    if (!(p0 = overhead_rpc_alloc(server->rsize)))
	return -EIO;

    p = nfs_rpc_header(p0, NFSPROC_READ, ruid);
    p = xdr_encode_fhandle(p, fhandle);
    *p++ = htonl(offset);
    *p++ = htonl(count);
    *p++ = htonl(count);		/* traditional, could be any value */

    DPRINTF(CLUHELP_LEVEL,("ORIGNAL\n"));
    /*     print_rpc2(p0,128); */
    if ((status = generic_rpc_call(server, p0, p)) < 0) {
	overhead_rpc_free(p0);
	return status;
    }


    if (!(p = generic_rpc_verify(p0)))
	status = NFSERR_IO;
    else if ((status = ntohl(*p++)) == NFS_OK) {
	p = xdr_decode_fattr(p, fattr);
	if (!(p = xdr_decode_data(p, data, &len, count))) {
	    DPRINTF(CLUHELP_LEVEL,("nfs_proc_read: giant data size\n")); 
	    status = NFSERR_IO;
	}
	else
	    DPRINTF(CLUHELP_LEVEL,("NFS reply read %d\n", len));
    }

    overhead_rpc_free(p0);
    return (status == NFS_OK) ? len : nfs_stat_to_errno(status);
}
Ejemplo n.º 21
0
static int
nfs_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
{
	struct xdr_buf *sndbuf = &req->rq_snd_buf;
	u32 offset = (u32)args->offset;
	u32 count = args->count;

	p = xdr_encode_fhandle(p, args->fh);
	*p++ = htonl(offset);
	*p++ = htonl(offset);
	*p++ = htonl(count);
	*p++ = htonl(count);
	sndbuf->len = xdr_adjust_iovec(sndbuf->head, p);

	/* Copy the page array */
	xdr_encode_pages(sndbuf, args->pages, args->pgbase, count);
	sndbuf->flags |= XDRBUF_WRITE;
	return 0;
}
Ejemplo n.º 22
0
/*
 * Encode READLINK args
 */
static int
nfs_xdr_readlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_readlinkargs *args)
{
	struct rpc_task *task = req->rq_task;
	struct rpc_auth *auth = task->tk_auth;
	int		buflen, replen;

	p = xdr_encode_fhandle(p, args->fh);
	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
	replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readlinkres_sz) << 2;
	buflen = req->rq_rvec[0].iov_len;
	req->rq_rvec[0].iov_len  = replen;
	req->rq_rvec[1].iov_base = args->buffer;
	req->rq_rvec[1].iov_len  = args->bufsiz;
	req->rq_rvec[2].iov_base = (u8 *) req->rq_rvec[0].iov_base + replen;
	req->rq_rvec[2].iov_len  = buflen - replen;
	req->rq_rlen = buflen + args->bufsiz;
	req->rq_rnr += 2;
	return 0;
}
Ejemplo n.º 23
0
int nfs_proc_lookup(struct nfs_server *server, struct nfs_fh *dir, const char *name,
		    struct nfs_fh *fhandle, struct nfs_fattr *fattr)
{
	int *p, *p0;
	int status;
	int ruid = 0;

	PRINTK("NFS call  lookup %s\n", name);
#ifdef NFS_PROC_DEBUG
	if (!strcmp(name, "xyzzy"))
		proc_debug = 1 - proc_debug;
#endif
	if (!(p0 = nfs_rpc_alloc(server->rsize)))
		return -EIO;
retry:
	p = nfs_rpc_header(p0, NFSPROC_LOOKUP, ruid);
	p = xdr_encode_fhandle(p, dir);
	p = xdr_encode_string(p, name);
	if ((status = nfs_rpc_call(server, p0, p, server->rsize)) < 0) {
		nfs_rpc_free(p0);
		return status;
	}
	if (!(p = nfs_rpc_verify(p0)))
		status = -errno_NFSERR_IO;
	else if ((status = ntohl(*p++)) == NFS_OK) {
		p = xdr_decode_fhandle(p, fhandle);
		p = xdr_decode_fattr(p, fattr);
		PRINTK("NFS reply lookup\n");
		/* status = 0; */
	}
	else {
		if (!ruid && current->fsuid == 0 && current->uid != 0) {
			ruid = 1;
			goto retry;
		}
		PRINTK("NFS reply lookup failed = %d\n", status);
		status = -nfs_stat_to_errno(status);
	}
	nfs_rpc_free(p0);
	return status;
}
Ejemplo n.º 24
0
/*
 * Arguments to a READ call. Since we read data directly into the page
 * cache, we also set up the reply iovec here so that iov[1] points
 * exactly to the page we want to fetch.
 */
static int
nfs_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
{
	struct rpc_auth	*auth = req->rq_cred->cr_auth;
	unsigned int replen;
	u32 offset = (u32)args->offset;
	u32 count = args->count;

	p = xdr_encode_fhandle(p, args->fh);
	*p++ = htonl(offset);
	*p++ = htonl(count);
	*p++ = htonl(count);
	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);

	/* Inline the page array */
	replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readres_sz) << 2;
	xdr_inline_pages(&req->rq_rcv_buf, replen,
			 args->pages, args->pgbase, count);
	req->rq_rcv_buf.flags |= XDRBUF_READ;
	return 0;
}
Ejemplo n.º 25
0
int nfs_proc_write(struct nfs_server *server, struct nfs_fh *fhandle,
		   int offset, int count, char *data, struct nfs_fattr *fattr)
{
	int *p, *p0;
	int status;
	int ruid = 0;

	PRINTK("NFS call  write %d @ %d\n", count, offset);
	if (!(p0 = nfs_rpc_alloc(server->wsize)))
		return -EIO;
retry:
	p = nfs_rpc_header(p0, NFSPROC_WRITE, ruid);
	p = xdr_encode_fhandle(p, fhandle);
	*p++ = htonl(offset); /* traditional, could be any value */
	*p++ = htonl(offset);
	*p++ = htonl(count); /* traditional, could be any value */
	p = xdr_encode_data(p, data, count);
	if ((status = nfs_rpc_call(server, p0, p, server->wsize)) < 0) {
		nfs_rpc_free(p0);
		return status;
	}
	if (!(p = nfs_rpc_verify(p0)))
		status = -errno_NFSERR_IO;
	else if ((status = ntohl(*p++)) == NFS_OK) {
		p = xdr_decode_fattr(p, fattr);
		PRINTK("NFS reply write\n");
		/* status = 0; */
	}
	else {
		if (!ruid && current->fsuid == 0 && current->uid != 0) {
			ruid = 1;
			goto retry;
		}
		PRINTK("NFS reply write failed = %d\n", status);
		status = -nfs_stat_to_errno(status);
	}
	nfs_rpc_free(p0);
	return status;
}
Ejemplo n.º 26
0
int nfs_proc_mkdir(struct nfs_server *server, struct nfs_fh *dir,
		   const char *name, struct nfs_sattr *sattr,
		   struct nfs_fh *fhandle, struct nfs_fattr *fattr)
{
	int *p, *p0;
	int status;
	int ruid = 0;

	PRINTK("NFS call  mkdir %s\n", name);
	if (!(p0 = nfs_rpc_alloc(server->wsize)))
		return -EIO;
retry:
	p = nfs_rpc_header(p0, NFSPROC_MKDIR, ruid);
	p = xdr_encode_fhandle(p, dir);
	p = xdr_encode_string(p, name);
	p = xdr_encode_sattr(p, sattr);
	if ((status = nfs_rpc_call(server, p0, p, server->wsize)) < 0) {
		nfs_rpc_free(p0);
		return status;
	}
	if (!(p = nfs_rpc_verify(p0)))
		status = -errno_NFSERR_IO;
	else if ((status = ntohl(*p++)) == NFS_OK) {
		p = xdr_decode_fhandle(p, fhandle);
		p = xdr_decode_fattr(p, fattr);
		PRINTK("NFS reply mkdir\n");
		/* status = 0; */
	}
	else {
		if (!ruid && current->fsuid == 0 && current->uid != 0) {
			ruid = 1;
			goto retry;
		}
		PRINTK("NFS reply mkdir failed = %d\n", status);
		status = -nfs_stat_to_errno(status);
	}
	nfs_rpc_free(p0);
	return status;
}
Ejemplo n.º 27
0
int nfs_proc_readlink(struct nfs_server *server, struct nfs_fh *fhandle,
		      char *res)
{
	int *p, *p0;
	int status;
	int ruid = 0;

	PRINTK("NFS call  readlink\n");
	if (!(p0 = nfs_rpc_alloc()))
		return -EIO;
retry:
	p = nfs_rpc_header(p0, NFSPROC_READLINK, ruid);
	p = xdr_encode_fhandle(p, fhandle);
	if ((status = nfs_rpc_call(server, p0, p)) < 0) {
		nfs_rpc_free(p0);
		return status;
	}
	if (!(p = nfs_rpc_verify(p0)))
		status = NFSERR_IO;
	else if ((status = ntohl(*p++)) == NFS_OK) {
		if (!(p = xdr_decode_string(p, res, NFS_MAXPATHLEN))) {
			printk("nfs_proc_readlink: giant pathname\n");
			status = NFSERR_IO;
		}
		else
			PRINTK("NFS reply readlink %s\n", res);
	}
	else {
		if (!ruid && current->euid == 0 && current->uid != 0) {
			ruid = 1;
			goto retry;
		}
		PRINTK("NFS reply readlink failed = %d\n", status);
	}
	nfs_rpc_free(p0);
	return -nfs_stat_to_errno(status);
}
Ejemplo n.º 28
0
int 
nfs_proc_read_p(struct nfs_fh *fhandle, int offset, int count, 
	      char *data, struct nfs_fattr *fattr) {
    int *p;
    int len = 0;
    int status;
    int ruid = 0;
    struct generic_server *server = fhandle->server;
    struct p_rpc *prpc;
    struct p_rpc_rec *rw;
    int i;
    int rsize;			/* to be used with new prpc */
    int remaining_count = count;
    int total_length = 0;
    char *tmp_data;
    char *tmp_data0;
    
    DPRINTF(CLUHELP_LEVEL,("NFS call  read %d @ %d\n", count, offset));
    rsize = server->rsize;
    //rsize = 1366;
    if ((offset < NFSMAXOFFSET) && ((offset % 4096) != 0)) {
      kprintf("warning non page aligned read: %d:%d\n",offset,count);
    }
    if (!(prpc = p_overhead_rpc_alloc(rsize, count)))
	return -EIO;

    for (i = 0; i < prpc->n ; i++) {
	rw = &prpc->rw[i];
	rw->start = nfs_rpc_header(rw->ptr, NFSPROC_READ, ruid);
	rw->start = xdr_encode_fhandle(rw->start, fhandle);
	*rw->start++ = htonl(offset + i*rsize);	/* offset */
	*rw->start++ = htonl((remaining_count >= rsize) ? 
			     rsize : remaining_count); /* count */
	rw->count = (remaining_count >= rsize) ? rsize : remaining_count;
	remaining_count -= rsize;
	*rw->start++ = htonl(rsize); /* traditional, could be any value */

	rw->end = rw->start;
	rw->r.n = 0;

	rw->xid = rw->ptr[0];
	rw->done = 0;

	/* 	print_rpc2(prpc->rw[i].ptr,128); */
    }
    /*     pr_p_rpc(prpc); */

    if ((status = p_generic_rpc_call(server,prpc)) < 0) {
	p_overhead_rpc_free(prpc);
	return status;
    }
    DPRINTF(CLUHELP_LEVEL,("P_GENERIC_RPC_CALL: %d\n",status));
    tmp_data = tmp_data0 = data;
    for (i = 0; i < prpc->n ; i++) {
	rw = &prpc->rw[i];

	if (!(p = generic_rpc_verify(rw->ptr))) {
	    status = NFSERR_IO;
	    break;
	} else if ((status = ntohl(*p++)) == NFS_OK) {
	    p = xdr_decode_fattr(p, fattr);
	    if (!(p = xdr_decode_data(p, tmp_data, &len, rw->count))) {
		DPRINTF(CLUHELP_LEVEL,("nfs_proc_read: giant data size\n")); 
		status = NFSERR_IO;
		break;
	    } else {
		DPRINTF(CLUHELP_LEVEL,("NFS reply read xid: %d, length: %d count %d\n", 
			 rw->xid,len,rw->count));
		tmp_data += len;
		total_length += len;
	    }
	}
    }
    DPRINTF(CLUHELP_LEVEL,("status: %d\n",status));

    p_overhead_rpc_free(prpc);
    return (status == NFS_OK) ? total_length : nfs_stat_to_errno(status);
}
Ejemplo n.º 29
0
int 
nfs_proc_writev(struct nfs_fh *fhandle, int offset, int count, 
	       struct ae_recv *r, struct nfs_fattr *fattr) {
    
    int *p;
    int status;
    int ruid = 0;
    struct generic_server *server = fhandle->server;
    char *tmp_data;
    int i;
    int wsize;			/* to be used with new prpc */
    int remaining_count = count;
    struct p_rpc *prpc;
    struct p_rpc_rec *rw;

        
    DPRINTF(CLUHELP_LEVEL,("NFS call  write %p  %d @ %d\n", r, count, offset));
    wsize = server->wsize;
    if (!(prpc = p_overhead_rpc_alloc(wsize, count)))
	return -EIO;

    demand(count <= wsize, we only handle up to 8K for now);

    tmp_data = NULL; // data;
    for (i = 0; i < prpc->n ; i++) {
      static char overflow[4];
	rw = &prpc->rw[i];
	rw->start = nfs_rpc_header(rw->ptr, NFSPROC_WRITE, ruid);
	rw->start = xdr_encode_fhandle(rw->start, fhandle);
	*rw->start++ = htonl(offset + i*wsize);	/* offset */
	*rw->start++ = htonl(offset + i*wsize);	/* offset */
	rw->count = (remaining_count >= wsize) ? wsize : remaining_count;
	*rw->start++ = htonl(rw->count); /* count */
	*rw->start++ = htonl(rw->count); /* data len */
	rw->end = rw->start;
	rw->r.n = 1;
	rw->r = *r;

	if ((rw->count % 4) != 0) {
	  rw->r.r[r->n].data = overflow;
	  rw->r.r[r->n].sz = 4 - (rw->count % 4);
	  rw->r.n++;
	}
	pr_ae_recv(&rw->r);
	tmp_data += rw->count;
	remaining_count -= rw->count;

	rw->xid = rw->ptr[0];
	rw->done = 0;

	/* 	print_rpc2(prpc->rw[i].ptr,128); */
    }
    /*     pr_p_rpc(prpc); */
    lprintf("p_generic_rpc_call start\n");
    if ((status = p_generic_rpc_call(server,prpc)) < 0) {
	p_overhead_rpc_free(prpc);
	return status;
    }
    lprintf("p_generic_rpc_call done\n");
    DPRINTF(CLUHELP_LEVEL,("P_GENERIC_RPC_CALL: %d\n",status));

    for (i = 0; i < prpc->n ; i++) {
	rw = &prpc->rw[i];

	if (!(p = generic_rpc_verify(rw->ptr))) {
	    status = NFSERR_IO;
	    break;
	} else if ((status = ntohl(*p++)) == NFS_OK) {
	    p = xdr_decode_fattr(p, fattr);
	    DPRINTF(CLUHELP_LEVEL,("NFS reply write xid: %d, count %d\n", 
		   rw->xid,rw->count));
	}
    }
    
    DPRINTF(CLUHELP_LEVEL,("status: %d\n",status));
    
    p_overhead_rpc_free(prpc);
    return nfs_stat_to_errno(status);
}