Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 95d871f0 authored by Anna Schumaker's avatar Anna Schumaker Committed by J. Bruce Fields
Browse files

nfsd: Add ALLOCATE support



The ALLOCATE operation is used to preallocate space in a file.  I can do
this by using vfs_fallocate() to do the actual preallocation.

ALLOCATE only returns a status indicator, so we don't need to write a
special encode() function.

Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 72c72bdf
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -1013,6 +1013,36 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	return status;
}

static __be32
nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		struct nfsd4_fallocate *fallocate, int flags)
{
	__be32 status = nfserr_notsupp;
	struct file *file;

	status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate,
					    &fallocate->falloc_stateid,
					    WR_STATE, &file);
	if (status != nfs_ok) {
		dprintk("NFSD: nfsd4_fallocate: couldn't process stateid!\n");
		return status;
	}

	status = nfsd4_vfs_fallocate(rqstp, &cstate->current_fh, file,
				     fallocate->falloc_offset,
				     fallocate->falloc_length,
				     flags);
	fput(file);
	return status;
}

static __be32
nfsd4_allocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	       struct nfsd4_fallocate *fallocate)
{
	return nfsd4_fallocate(rqstp, cstate, fallocate, 0);
}

static __be32
nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
		struct nfsd4_seek *seek)
@@ -1929,6 +1959,12 @@ static struct nfsd4_operation nfsd4_ops[] = {
	},

	/* NFSv4.2 operations */
	[OP_ALLOCATE] = {
		.op_func = (nfsd4op_func)nfsd4_allocate,
		.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
		.op_name = "OP_ALLOCATE",
		.op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize,
	},
	[OP_SEEK] = {
		.op_func = (nfsd4op_func)nfsd4_seek,
		.op_name = "OP_SEEK",
+18 −1
Original line number Diff line number Diff line
@@ -1513,6 +1513,23 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str
	DECODE_TAIL;
}

static __be32
nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
		       struct nfsd4_fallocate *fallocate)
{
	DECODE_HEAD;

	status = nfsd4_decode_stateid(argp, &fallocate->falloc_stateid);
	if (status)
		return status;

	READ_BUF(16);
	p = xdr_decode_hyper(p, &fallocate->falloc_offset);
	xdr_decode_hyper(p, &fallocate->falloc_length);

	DECODE_TAIL;
}

static __be32
nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek)
{
@@ -1604,7 +1621,7 @@ static nfsd4_dec nfsd4_dec_ops[] = {
	[OP_RECLAIM_COMPLETE]	= (nfsd4_dec)nfsd4_decode_reclaim_complete,

	/* new operations for NFSv4.2 */
	[OP_ALLOCATE]		= (nfsd4_dec)nfsd4_decode_notsupp,
	[OP_ALLOCATE]		= (nfsd4_dec)nfsd4_decode_fallocate,
	[OP_COPY]		= (nfsd4_dec)nfsd4_decode_notsupp,
	[OP_COPY_NOTIFY]	= (nfsd4_dec)nfsd4_decode_notsupp,
	[OP_DEALLOCATE]		= (nfsd4_dec)nfsd4_decode_notsupp,
+21 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/splice.h>
#include <linux/falloc.h>
#include <linux/fcntl.h>
#include <linux/namei.h>
#include <linux/delay.h>
@@ -533,6 +534,26 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp,
}
#endif

__be32 nfsd4_vfs_fallocate(struct svc_rqst *rqstp, struct svc_fh *fhp,
			   struct file *file, loff_t offset, loff_t len,
			   int flags)
{
	__be32 err;
	int error;

	if (!S_ISREG(file_inode(file)->i_mode))
		return nfserr_inval;

	err = nfsd_permission(rqstp, fhp->fh_export, fhp->fh_dentry, NFSD_MAY_WRITE);
	if (err)
		return err;

	error = vfs_fallocate(file, flags, offset, len);
	if (!error)
		error = commit_metadata(fhp);

	return nfserrno(error);
}
#endif /* defined(CONFIG_NFSD_V4) */

#ifdef CONFIG_NFSD_V3
+2 −0
Original line number Diff line number Diff line
@@ -54,6 +54,8 @@ int nfsd_mountpoint(struct dentry *, struct svc_export *);
#ifdef CONFIG_NFSD_V4
__be32          nfsd4_set_nfs4_label(struct svc_rqst *, struct svc_fh *,
		    struct xdr_netobj *);
__be32		nfsd4_vfs_fallocate(struct svc_rqst *, struct svc_fh *,
				    struct file *, loff_t, loff_t, int);
#endif /* CONFIG_NFSD_V4 */
__be32		nfsd_create(struct svc_rqst *, struct svc_fh *,
				char *name, int len, struct iattr *attrs,
+8 −0
Original line number Diff line number Diff line
@@ -428,6 +428,13 @@ struct nfsd4_reclaim_complete {
	u32 rca_one_fs;
};

struct nfsd4_fallocate {
	/* request */
	stateid_t	falloc_stateid;
	loff_t		falloc_offset;
	u64		falloc_length;
};

struct nfsd4_seek {
	/* request */
	stateid_t	seek_stateid;
@@ -486,6 +493,7 @@ struct nfsd4_op {
		struct nfsd4_free_stateid	free_stateid;

		/* NFSv4.2 */
		struct nfsd4_fallocate		allocate;
		struct nfsd4_seek		seek;
	} u;
	struct nfs4_replay *			replay;