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: Anna Schumaker <Anna.Schumaker@Netapp.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
Родитель
72c72bdf7b
Коммит
95d871f03c
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче