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

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
...@@ -1013,6 +1013,36 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, ...@@ -1013,6 +1013,36 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
return status; 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 static __be32
nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
struct nfsd4_seek *seek) struct nfsd4_seek *seek)
...@@ -1929,6 +1959,12 @@ static struct nfsd4_operation nfsd4_ops[] = { ...@@ -1929,6 +1959,12 @@ static struct nfsd4_operation nfsd4_ops[] = {
}, },
/* NFSv4.2 operations */ /* 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_SEEK] = {
.op_func = (nfsd4op_func)nfsd4_seek, .op_func = (nfsd4op_func)nfsd4_seek,
.op_name = "OP_SEEK", .op_name = "OP_SEEK",
......
...@@ -1513,6 +1513,23 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str ...@@ -1513,6 +1513,23 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str
DECODE_TAIL; 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 static __be32
nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek) nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek)
{ {
...@@ -1604,7 +1621,7 @@ static nfsd4_dec nfsd4_dec_ops[] = { ...@@ -1604,7 +1621,7 @@ static nfsd4_dec nfsd4_dec_ops[] = {
[OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete, [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete,
/* new operations for NFSv4.2 */ /* 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] = (nfsd4_dec)nfsd4_decode_notsupp,
[OP_COPY_NOTIFY] = (nfsd4_dec)nfsd4_decode_notsupp, [OP_COPY_NOTIFY] = (nfsd4_dec)nfsd4_decode_notsupp,
[OP_DEALLOCATE] = (nfsd4_dec)nfsd4_decode_notsupp, [OP_DEALLOCATE] = (nfsd4_dec)nfsd4_decode_notsupp,
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/file.h> #include <linux/file.h>
#include <linux/splice.h> #include <linux/splice.h>
#include <linux/falloc.h>
#include <linux/fcntl.h> #include <linux/fcntl.h>
#include <linux/namei.h> #include <linux/namei.h>
#include <linux/delay.h> #include <linux/delay.h>
...@@ -533,6 +534,26 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp, ...@@ -533,6 +534,26 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp,
} }
#endif #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) */ #endif /* defined(CONFIG_NFSD_V4) */
#ifdef CONFIG_NFSD_V3 #ifdef CONFIG_NFSD_V3
......
...@@ -54,6 +54,8 @@ int nfsd_mountpoint(struct dentry *, struct svc_export *); ...@@ -54,6 +54,8 @@ int nfsd_mountpoint(struct dentry *, struct svc_export *);
#ifdef CONFIG_NFSD_V4 #ifdef CONFIG_NFSD_V4
__be32 nfsd4_set_nfs4_label(struct svc_rqst *, struct svc_fh *, __be32 nfsd4_set_nfs4_label(struct svc_rqst *, struct svc_fh *,
struct xdr_netobj *); struct xdr_netobj *);
__be32 nfsd4_vfs_fallocate(struct svc_rqst *, struct svc_fh *,
struct file *, loff_t, loff_t, int);
#endif /* CONFIG_NFSD_V4 */ #endif /* CONFIG_NFSD_V4 */
__be32 nfsd_create(struct svc_rqst *, struct svc_fh *, __be32 nfsd_create(struct svc_rqst *, struct svc_fh *,
char *name, int len, struct iattr *attrs, char *name, int len, struct iattr *attrs,
......
...@@ -428,6 +428,13 @@ struct nfsd4_reclaim_complete { ...@@ -428,6 +428,13 @@ struct nfsd4_reclaim_complete {
u32 rca_one_fs; u32 rca_one_fs;
}; };
struct nfsd4_fallocate {
/* request */
stateid_t falloc_stateid;
loff_t falloc_offset;
u64 falloc_length;
};
struct nfsd4_seek { struct nfsd4_seek {
/* request */ /* request */
stateid_t seek_stateid; stateid_t seek_stateid;
...@@ -486,6 +493,7 @@ struct nfsd4_op { ...@@ -486,6 +493,7 @@ struct nfsd4_op {
struct nfsd4_free_stateid free_stateid; struct nfsd4_free_stateid free_stateid;
/* NFSv4.2 */ /* NFSv4.2 */
struct nfsd4_fallocate allocate;
struct nfsd4_seek seek; struct nfsd4_seek seek;
} u; } u;
struct nfs4_replay * replay; struct nfs4_replay * replay;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment