Exemple #1
0
/*
 * Decode STATFS reply
 */
static int
nfs_xdr_statfsres(struct rpc_rqst *req, u32 *p, struct nfs_fsinfo *res)
{
	int	status;
	u32	xfer_size;

	if ((status = ntohl(*p++)))
		return -nfs_stat_to_errno(status);

	/* For NFSv2, we more or less have to guess the preferred
	 * read/write/readdir sizes from the single 'transfer size'
	 * value.
	 */
	xfer_size = ntohl(*p++);	/* tsize */
	res->rtmax  = 8 * 1024;
	res->rtpref = xfer_size;
	res->rtmult = xfer_size;
	res->wtmax  = 8 * 1024;
	res->wtpref = xfer_size;
	res->wtmult = xfer_size;
	res->dtpref = PAGE_CACHE_SIZE;
	res->maxfilesize = 0x7FFFFFFF;	/* just a guess */
	res->bsize  = ntohl(*p++);

	res->tbytes = ntohl(*p++) * res->bsize;
	res->fbytes = ntohl(*p++) * res->bsize;
	res->abytes = ntohl(*p++) * res->bsize;
	res->tfiles = 0;
	res->ffiles = 0;
	res->afiles = 0;
	res->namelen = 0;

	return 0;
}
Exemple #2
0
/*
 * Decode the result of a readdir call.
 * We're not really decoding anymore, we just leave the buffer untouched
 * and only check that it is syntactically correct.
 * The real decoding happens in nfs_decode_entry below, called directly
 * from nfs_readdir for each entry.
 */
static int
nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
{
	struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
	struct kvec *iov = rcvbuf->head;
	struct page **page;
	size_t hdrlen;
	unsigned int pglen, recvd;
	int status;

	if ((status = ntohl(*p++)))
		return nfs_stat_to_errno(status);

	hdrlen = (u8 *) p - (u8 *) iov->iov_base;
	if (iov->iov_len < hdrlen) {
		dprintk("NFS: READDIR reply header overflowed:"
				"length %Zu > %Zu\n", hdrlen, iov->iov_len);
		return -errno_NFSERR_IO;
	} else if (iov->iov_len != hdrlen) {
		dprintk("NFS: READDIR header is short. iovec will be shifted.\n");
		xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
	}

	pglen = rcvbuf->page_len;
	recvd = rcvbuf->len - hdrlen;
	if (pglen > recvd)
		pglen = recvd;
	page = rcvbuf->pages;
	return pglen;
}
Exemple #3
0
/*
 * Decode READLINK reply
 */
static int
nfs_xdr_readlinkres(struct rpc_rqst *req, u32 *p, void *dummy)
{
	struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
	struct iovec *iov = rcvbuf->head;
	unsigned int hdrlen;
	u32	*strlen, len;
	char	*string;
	int	status;

	if ((status = ntohl(*p++)))
		return -nfs_stat_to_errno(status);
	hdrlen = (u8 *) p - (u8 *) iov->iov_base;
	if (iov->iov_len > hdrlen) {
		dprintk("NFS: READLINK header is short. iovec will be shifted.\n");
		xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
	}

	strlen = (u32*)kmap_atomic(rcvbuf->pages[0], KM_USER0);
	/* Convert length of symlink */
	len = ntohl(*strlen);
	if (len >= rcvbuf->page_len - sizeof(u32) || len > NFS2_MAXPATHLEN) {
		dprintk("NFS: READLINK server returned giant symlink!\n");
		kunmap_atomic(strlen, KM_USER0);
		return -ENAMETOOLONG;
        }
	*strlen = len;
	/* NULL terminate the string we got */
	string = (char *)(strlen + 1);
	string[len] = 0;
	kunmap_atomic(strlen, KM_USER0);
	return 0;
}
Exemple #4
0
/*
 * Decode READ reply
 */
static int
nfs_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res)
{
	struct kvec *iov = req->rq_rcv_buf.head;
	int	status, count, recvd, hdrlen;

	if ((status = ntohl(*p++)))
		return -nfs_stat_to_errno(status);
	p = xdr_decode_fattr(p, res->fattr);

	count = ntohl(*p++);
	res->eof = 0;
	hdrlen = (u8 *) p - (u8 *) iov->iov_base;
	if (iov->iov_len < hdrlen) {
		printk(KERN_WARNING "NFS: READ reply header overflowed:"
				"length %d > %Zu\n", hdrlen, iov->iov_len);
		return -errno_NFSERR_IO;
	} else if (iov->iov_len != hdrlen) {
		dprintk("NFS: READ header is short. iovec will be shifted.\n");
		xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
	}

	recvd = req->rq_rcv_buf.len - hdrlen;
	if (count > recvd) {
		printk(KERN_WARNING "NFS: server cheating in read reply: "
			"count %d > recvd %d\n", count, recvd);
		count = recvd;
	}

	dprintk("RPC:      readres OK count %d\n", count);
	if (count < res->count)
		res->count = count;

	return count;
}
Exemple #5
0
int nfs_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
		    struct nfs_fsinfo *res)
{
	int *p, *p0;
	int status;
	int ruid = 0;

	PRINTK("NFS call  statfs\n");
	if (!(p0 = nfs_rpc_alloc(server->rsize)))
		return -EIO;
retry:
	p = nfs_rpc_header(p0, NFSPROC_STATFS, ruid);
	p = xdr_encode_fhandle(p, fhandle);
	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_fsinfo(p, res);
		PRINTK("NFS reply statfs\n");
		/* status = 0; */
	}
	else {
		if (!ruid && current->fsuid == 0 && current->uid != 0) {
			ruid = 1;
			goto retry;
		}
		PRINTK("NFS reply statfs failed = %d\n", status);
		status = -nfs_stat_to_errno(status);
	}
	nfs_rpc_free(p0);
	return status;
}
Exemple #6
0
int nfs_proc_rmdir(struct nfs_server *server, struct nfs_fh *dir, const char *name)
{
	int *p, *p0;
	int status;
	int ruid = 0;

	PRINTK("NFS call  rmdir %s\n", name);
	if (!(p0 = nfs_rpc_alloc(server->wsize)))
		return -EIO;
retry:
	p = nfs_rpc_header(p0, NFSPROC_RMDIR, ruid);
	p = xdr_encode_fhandle(p, dir);
	p = xdr_encode_string(p, 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 rmdir\n");
		/* status = 0; */
	}
	else {
		if (!ruid && current->fsuid == 0 && current->uid != 0) {
			ruid = 1;
			goto retry;
		}
		PRINTK("NFS reply rmdir failed = %d\n", status);
		status = -nfs_stat_to_errno(status);
	}
	nfs_rpc_free(p0);
	return status;
}
Exemple #7
0
int nfs_proc_readlink(struct nfs_server *server, struct nfs_fh *fhandle,
		int **p0, char **string, unsigned int *len, unsigned int maxlen)
{
	int *p;
	int status, ruid = 0;

	PRINTK("NFS call  readlink\n");
	if (!(*p0 = nfs_rpc_alloc(server->rsize)))
		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, server->rsize)) < 0)
		return status;
	if (!(p = nfs_rpc_verify(*p0)))
		status = -errno_NFSERR_IO;
	else if ((status = ntohl(*p++)) == NFS_OK) {
		if (!(p = xdr_decode_string2(p, string, len, maxlen))) {
			printk("nfs_proc_readlink: giant pathname\n");
			status = -errno_NFSERR_IO;
		}
		else	/* status = 0, */
			PRINTK("NFS reply readlink\n");
	}
	else {
		if (!ruid && current->fsuid == 0 && current->uid != 0) {
			ruid = 1;
			goto retry;
		}
		PRINTK("NFS reply readlink failed = %d\n", status);
		status = -nfs_stat_to_errno(status);
	}
	return status;
}
Exemple #8
0
int nfs_proc_symlink(struct nfs_server *server, struct nfs_fh *dir,
		     const char *name, const char *path, struct nfs_sattr *sattr)
{
	int *p, *p0;
	int status;
	int ruid = 0;

	PRINTK("NFS call  symlink %s -> %s\n", name, path);
	if (!(p0 = nfs_rpc_alloc()))
		return -EIO;
retry:
	p = nfs_rpc_header(p0, NFSPROC_SYMLINK, ruid);
	p = xdr_encode_fhandle(p, dir);
	p = xdr_encode_string(p, name);
	p = xdr_encode_string(p, path);
	p = xdr_encode_sattr(p, sattr);
	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) {
		PRINTK("NFS reply symlink\n");
	}
	else {
		if (!ruid && current->euid == 0 && current->uid != 0) {
			ruid = 1;
			goto retry;
		}
		PRINTK("NFS reply symlink failed = %d\n", status);
	}
	nfs_rpc_free(p0);
	return -nfs_stat_to_errno(status);
}
Exemple #9
0
int nfs_proc_setattr(struct nfs_server *server, struct nfs_fh *fhandle,
		     struct nfs_sattr *sattr, struct nfs_fattr *fattr)
{
	int *p, *p0;
	int status;
	int ruid = 0;

	PRINTK("NFS call  setattr\n");
	if (!(p0 = nfs_rpc_alloc()))
		return -EIO;
retry:
	p = nfs_rpc_header(p0, NFSPROC_SETATTR, ruid);
	p = xdr_encode_fhandle(p, fhandle);
	p = xdr_encode_sattr(p, sattr);
	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) {
		p = xdr_decode_fattr(p, fattr);
		PRINTK("NFS reply setattr\n");
	}
	else {
		if (!ruid && current->euid == 0 && current->uid != 0) {
			ruid = 1;
			goto retry;
		}
		PRINTK("NFS reply setattr failed = %d\n", status);
	}
	nfs_rpc_free(p0);
	return -nfs_stat_to_errno(status);
}
Exemple #10
0
static int nfs3_xdr_dec_lookup3res(struct rpc_rqst *req,
				   struct xdr_stream *xdr,
				   struct nfs3_diropres *result)
{
	enum nfs_stat status;
	int error;

	error = decode_nfsstat3(xdr, &status);
	if (unlikely(error))
		goto out;
	if (status != NFS3_OK)
		goto out_default;
	error = decode_nfs_fh3(xdr, result->fh);
	if (unlikely(error))
		goto out;
	error = decode_post_op_attr(xdr, result->fattr);
	if (unlikely(error))
		goto out;
	error = decode_post_op_attr(xdr, result->dir_attr);
out:
	return error;
out_default:
	error = decode_post_op_attr(xdr, result->dir_attr);
	if (unlikely(error))
		goto out;
	return nfs_stat_to_errno(status);
}
Exemple #11
0
/*
 * Decode simple status reply
 */
static int
nfs_xdr_stat(struct rpc_rqst *req, u32 *p, void *dummy)
{
	int	status;

	if ((status = ntohl(*p++)) != 0)
		status = -nfs_stat_to_errno(status);
	return status;
}
Exemple #12
0
/*
 * Decode attrstat reply
 * GETATTR, SETATTR, WRITE
 */
static int
nfs_xdr_attrstat(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr)
{
	int	status;

	if ((status = ntohl(*p++)))
		return -nfs_stat_to_errno(status);
	xdr_decode_fattr(p, fattr);
	return 0;
}
Exemple #13
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;
}
Exemple #14
0
/*
 * Decode diropres reply
 * LOOKUP, CREATE, MKDIR
 */
static int
nfs_xdr_diropres(struct rpc_rqst *req, u32 *p, struct nfs_diropok *res)
{
	int	status;

	if ((status = ntohl(*p++)))
		return -nfs_stat_to_errno(status);
	p = xdr_decode_fhandle(p, res->fh);
	xdr_decode_fattr(p, res->fattr);
	return 0;
}
Exemple #15
0
/*
 * Decode STATFS reply
 */
static int
nfs_xdr_statfsres(struct rpc_rqst *req, u32 *p, struct nfs2_fsstat *res)
{
	int	status;

	if ((status = ntohl(*p++)))
		return -nfs_stat_to_errno(status);

	res->tsize  = ntohl(*p++);
	res->bsize  = ntohl(*p++);
	res->blocks = ntohl(*p++);
	res->bfree  = ntohl(*p++);
	res->bavail = ntohl(*p++);
	return 0;
}
static int nfs2_xdr_dec_stat(struct rpc_rqst *req, struct xdr_stream *xdr,
			     void *__unused)
{
	enum nfs_stat status;
	int error;

	error = decode_stat(xdr, &status);
	if (unlikely(error))
		goto out;
	if (status != NFS_OK)
		goto out_default;
out:
	return error;
out_default:
	return nfs_stat_to_errno(status);
}
static int decode_diropres(struct xdr_stream *xdr, struct nfs_diropok *result)
{
	enum nfs_stat status;
	int error;

	error = decode_stat(xdr, &status);
	if (unlikely(error))
		goto out;
	if (status != NFS_OK)
		goto out_default;
	error = decode_diropok(xdr, result);
out:
	return error;
out_default:
	return nfs_stat_to_errno(status);
}
static int nfs2_xdr_dec_statfsres(struct rpc_rqst *req, struct xdr_stream *xdr,
				  struct nfs2_fsstat *result)
{
	enum nfs_stat status;
	int error;

	error = decode_stat(xdr, &status);
	if (unlikely(error))
		goto out;
	if (status != NFS_OK)
		goto out_default;
	error = decode_info(xdr, result);
out:
	return error;
out_default:
	return nfs_stat_to_errno(status);
}
Exemple #19
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;
}
Exemple #20
0
static int nfs3_xdr_dec_getattr3res(struct rpc_rqst *req,
				    struct xdr_stream *xdr,
				    struct nfs_fattr *result)
{
	enum nfs_stat status;
	int error;

	error = decode_nfsstat3(xdr, &status);
	if (unlikely(error))
		goto out;
	if (status != NFS3_OK)
		goto out_default;
	error = decode_fattr3(xdr, result);
out:
	return error;
out_default:
	return nfs_stat_to_errno(status);
}
Exemple #21
0
/*
 * Decode the result of a readdir call.
 * We're not really decoding anymore, we just leave the buffer untouched
 * and only check that it is syntactically correct.
 * The real decoding happens in nfs_decode_entry below, called directly
 * from nfs_readdir for each entry.
 */
static int
nfs_xdr_readdirres(struct rpc_rqst *req, u32 *p, struct nfs_readdirres *res)
{
	struct iovec		*iov = req->rq_rvec;
	int			 status, nr;
	u32			*end, *entry, len;

	if ((status = ntohl(*p++)))
		return -nfs_stat_to_errno(status);
	if ((void *) p != ((u8 *) iov->iov_base+iov->iov_len)) {
		/* Unexpected reply header size. Punt. */
		printk(KERN_WARNING "NFS: Odd RPC header size in readdirres reply\n");
		return -errno_NFSERR_IO;
	}

	/* Get start and end address of XDR data */
	p   = (u32 *) iov[1].iov_base;
	end = (u32 *) ((u8 *) p + iov[1].iov_len);

	/* Get start and end of dirent buffer */
	if (res->buffer != p) {
		printk(KERN_ERR "NFS: Bad result buffer in readdir\n");
		return -errno_NFSERR_IO;
	}

	for (nr = 0; *p++; nr++) {
		entry = p - 1;
		p++; /* fileid */
		len = ntohl(*p++);
		p += XDR_QUADLEN(len) + 1;	/* name plus cookie */
		if (len > NFS2_MAXNAMLEN) {
			printk(KERN_WARNING "NFS: giant filename in readdir (len 0x%x)!\n",
						len);
			return -errno_NFSERR_IO;
		}
		if (p + 2 > end) {
			printk(KERN_NOTICE
				"NFS: short packet in readdir reply!\n");
			entry[0] = entry[1] = 0;
			break;
		}
	}
	return nr;
}
Exemple #22
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);
}
Exemple #23
0
static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr,
				 struct nfs_readres *result)
{
	enum nfs_stat status;
	int error;

	error = decode_nfsstat3(xdr, &status);
	if (unlikely(error))
		goto out;
	error = decode_post_op_attr(xdr, result->fattr);
	if (unlikely(error))
		goto out;
	if (status != NFS3_OK)
		goto out_status;
	error = decode_read3resok(xdr, result);
out:
	return error;
out_status:
	return nfs_stat_to_errno(status);
}
Exemple #24
0
static int nfs3_xdr_dec_remove3res(struct rpc_rqst *req,
				   struct xdr_stream *xdr,
				   struct nfs_removeres *result)
{
	enum nfs_stat status;
	int error;

	error = decode_nfsstat3(xdr, &status);
	if (unlikely(error))
		goto out;
	error = decode_wcc_data(xdr, result->dir_attr);
	if (unlikely(error))
		goto out;
	if (status != NFS3_OK)
		goto out_status;
out:
	return error;
out_status:
	return nfs_stat_to_errno(status);
}
/*
 * 2.2.7.  readres
 *
 *	union readres switch (stat status) {
 *	case NFS_OK:
 *		fattr attributes;
 *		nfsdata data;
 *	default:
 *		void;
 *	};
 */
static int nfs2_xdr_dec_readres(struct rpc_rqst *req, struct xdr_stream *xdr,
				struct nfs_readres *result)
{
	enum nfs_stat status;
	int error;

	error = decode_stat(xdr, &status);
	if (unlikely(error))
		goto out;
	if (status != NFS_OK)
		goto out_default;
	error = decode_fattr(xdr, result->fattr);
	if (unlikely(error))
		goto out;
	error = decode_nfsdata(xdr, result);
out:
	return error;
out_default:
	return nfs_stat_to_errno(status);
}
Exemple #26
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;
}
Exemple #27
0
/*
 * Decode READLINK reply
 */
static int
nfs_xdr_readlinkres(struct rpc_rqst *req, u32 *p, struct nfs_readlinkres *res)
{
	u32	*strlen;
	char	*string;
	int	status;
	unsigned int len;

	if ((status = ntohl(*p++)))
		return -nfs_stat_to_errno(status);
	strlen = (u32*)res->buffer;
	/* Convert length of symlink */
	len = ntohl(*strlen);
	if (len > res->bufsiz - 5)
		len = res->bufsiz - 5;
	*strlen = len;
	/* NULL terminate the string we got */
	string = (char *)(strlen + 1);
	string[len] = 0;
	return 0;
}
Exemple #28
0
static int
nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy)
{
	struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
	struct kvec *iov = rcvbuf->head;
	size_t hdrlen;
	u32 len, recvd;
	char	*kaddr;
	int	status;

	if ((status = ntohl(*p++)))
		return nfs_stat_to_errno(status);
	/* Convert length of symlink */
	len = ntohl(*p++);
	if (len >= rcvbuf->page_len) {
		dprintk("nfs: server returned giant symlink!\n");
		return -ENAMETOOLONG;
	}
	hdrlen = (u8 *) p - (u8 *) iov->iov_base;
	if (iov->iov_len < hdrlen) {
		dprintk("NFS: READLINK reply header overflowed:"
				"length %Zu > %Zu\n", hdrlen, iov->iov_len);
		return -errno_NFSERR_IO;
	} else if (iov->iov_len != hdrlen) {
		dprintk("NFS: READLINK header is short. iovec will be shifted.\n");
		xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
	}
	recvd = req->rq_rcv_buf.len - hdrlen;
	if (recvd < len) {
		dprintk("NFS: server cheating in readlink reply: "
				"count %u > recvd %u\n", len, recvd);
		return -EIO;
	}

	/* NULL terminate the string we got */
	kaddr = (char *)kmap_atomic(rcvbuf->pages[0], KM_USER0);
	kaddr[len+rcvbuf->page_base] = '\0';
	kunmap_atomic(kaddr, KM_USER0);
	return 0;
}
Exemple #29
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;
}
Exemple #30
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);
}