aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorAnna Schumaker <Anna.Schumaker@Netapp.com>2014-11-07 14:44:26 -0500
committerJ. Bruce Fields <bfields@redhat.com>2014-11-07 16:19:49 -0500
commit95d871f03cae6b49de040265cf88cbe2a16b9f05 (patch)
tree911d8bed4226e4e87e1411145c7fe0e275dea545 /fs/nfsd
parent72c72bdf7bf53353d2d8e055194d27f0128be92b (diff)
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>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs4proc.c36
-rw-r--r--fs/nfsd/nfs4xdr.c19
-rw-r--r--fs/nfsd/vfs.c21
-rw-r--r--fs/nfsd/vfs.h2
-rw-r--r--fs/nfsd/xdr4.h8
5 files changed, 85 insertions, 1 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 0beb023f25ac..a261f1800922 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -1014,6 +1014,36 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1014} 1014}
1015 1015
1016static __be32 1016static __be32
1017nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1018 struct nfsd4_fallocate *fallocate, int flags)
1019{
1020 __be32 status = nfserr_notsupp;
1021 struct file *file;
1022
1023 status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate,
1024 &fallocate->falloc_stateid,
1025 WR_STATE, &file);
1026 if (status != nfs_ok) {
1027 dprintk("NFSD: nfsd4_fallocate: couldn't process stateid!\n");
1028 return status;
1029 }
1030
1031 status = nfsd4_vfs_fallocate(rqstp, &cstate->current_fh, file,
1032 fallocate->falloc_offset,
1033 fallocate->falloc_length,
1034 flags);
1035 fput(file);
1036 return status;
1037}
1038
1039static __be32
1040nfsd4_allocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1041 struct nfsd4_fallocate *fallocate)
1042{
1043 return nfsd4_fallocate(rqstp, cstate, fallocate, 0);
1044}
1045
1046static __be32
1017nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 1047nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1018 struct nfsd4_seek *seek) 1048 struct nfsd4_seek *seek)
1019{ 1049{
@@ -1929,6 +1959,12 @@ static struct nfsd4_operation nfsd4_ops[] = {
1929 }, 1959 },
1930 1960
1931 /* NFSv4.2 operations */ 1961 /* NFSv4.2 operations */
1962 [OP_ALLOCATE] = {
1963 .op_func = (nfsd4op_func)nfsd4_allocate,
1964 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
1965 .op_name = "OP_ALLOCATE",
1966 .op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize,
1967 },
1932 [OP_SEEK] = { 1968 [OP_SEEK] = {
1933 .op_func = (nfsd4op_func)nfsd4_seek, 1969 .op_func = (nfsd4op_func)nfsd4_seek,
1934 .op_name = "OP_SEEK", 1970 .op_name = "OP_SEEK",
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index eeea7a90eb87..a60cff86fc28 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1514,6 +1514,23 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str
1514} 1514}
1515 1515
1516static __be32 1516static __be32
1517nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
1518 struct nfsd4_fallocate *fallocate)
1519{
1520 DECODE_HEAD;
1521
1522 status = nfsd4_decode_stateid(argp, &fallocate->falloc_stateid);
1523 if (status)
1524 return status;
1525
1526 READ_BUF(16);
1527 p = xdr_decode_hyper(p, &fallocate->falloc_offset);
1528 xdr_decode_hyper(p, &fallocate->falloc_length);
1529
1530 DECODE_TAIL;
1531}
1532
1533static __be32
1517nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek) 1534nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek)
1518{ 1535{
1519 DECODE_HEAD; 1536 DECODE_HEAD;
@@ -1604,7 +1621,7 @@ static nfsd4_dec nfsd4_dec_ops[] = {
1604 [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete, 1621 [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete,
1605 1622
1606 /* new operations for NFSv4.2 */ 1623 /* new operations for NFSv4.2 */
1607 [OP_ALLOCATE] = (nfsd4_dec)nfsd4_decode_notsupp, 1624 [OP_ALLOCATE] = (nfsd4_dec)nfsd4_decode_fallocate,
1608 [OP_COPY] = (nfsd4_dec)nfsd4_decode_notsupp, 1625 [OP_COPY] = (nfsd4_dec)nfsd4_decode_notsupp,
1609 [OP_COPY_NOTIFY] = (nfsd4_dec)nfsd4_decode_notsupp, 1626 [OP_COPY_NOTIFY] = (nfsd4_dec)nfsd4_decode_notsupp,
1610 [OP_DEALLOCATE] = (nfsd4_dec)nfsd4_decode_notsupp, 1627 [OP_DEALLOCATE] = (nfsd4_dec)nfsd4_decode_notsupp,
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index d16076bd9a7a..f1999619d516 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -16,6 +16,7 @@
16#include <linux/fs.h> 16#include <linux/fs.h>
17#include <linux/file.h> 17#include <linux/file.h>
18#include <linux/splice.h> 18#include <linux/splice.h>
19#include <linux/falloc.h>
19#include <linux/fcntl.h> 20#include <linux/fcntl.h>
20#include <linux/namei.h> 21#include <linux/namei.h>
21#include <linux/delay.h> 22#include <linux/delay.h>
@@ -533,6 +534,26 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp,
533} 534}
534#endif 535#endif
535 536
537__be32 nfsd4_vfs_fallocate(struct svc_rqst *rqstp, struct svc_fh *fhp,
538 struct file *file, loff_t offset, loff_t len,
539 int flags)
540{
541 __be32 err;
542 int error;
543
544 if (!S_ISREG(file_inode(file)->i_mode))
545 return nfserr_inval;
546
547 err = nfsd_permission(rqstp, fhp->fh_export, fhp->fh_dentry, NFSD_MAY_WRITE);
548 if (err)
549 return err;
550
551 error = vfs_fallocate(file, flags, offset, len);
552 if (!error)
553 error = commit_metadata(fhp);
554
555 return nfserrno(error);
556}
536#endif /* defined(CONFIG_NFSD_V4) */ 557#endif /* defined(CONFIG_NFSD_V4) */
537 558
538#ifdef CONFIG_NFSD_V3 559#ifdef CONFIG_NFSD_V3
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index c2ff3f14e5f6..7ffdb144e486 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -54,6 +54,8 @@ int nfsd_mountpoint(struct dentry *, struct svc_export *);
54#ifdef CONFIG_NFSD_V4 54#ifdef CONFIG_NFSD_V4
55__be32 nfsd4_set_nfs4_label(struct svc_rqst *, struct svc_fh *, 55__be32 nfsd4_set_nfs4_label(struct svc_rqst *, struct svc_fh *,
56 struct xdr_netobj *); 56 struct xdr_netobj *);
57__be32 nfsd4_vfs_fallocate(struct svc_rqst *, struct svc_fh *,
58 struct file *, loff_t, loff_t, int);
57#endif /* CONFIG_NFSD_V4 */ 59#endif /* CONFIG_NFSD_V4 */
58__be32 nfsd_create(struct svc_rqst *, struct svc_fh *, 60__be32 nfsd_create(struct svc_rqst *, struct svc_fh *,
59 char *name, int len, struct iattr *attrs, 61 char *name, int len, struct iattr *attrs,
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 5720e9457f33..eeaa0d0c4f79 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -428,6 +428,13 @@ struct nfsd4_reclaim_complete {
428 u32 rca_one_fs; 428 u32 rca_one_fs;
429}; 429};
430 430
431struct nfsd4_fallocate {
432 /* request */
433 stateid_t falloc_stateid;
434 loff_t falloc_offset;
435 u64 falloc_length;
436};
437
431struct nfsd4_seek { 438struct nfsd4_seek {
432 /* request */ 439 /* request */
433 stateid_t seek_stateid; 440 stateid_t seek_stateid;
@@ -486,6 +493,7 @@ struct nfsd4_op {
486 struct nfsd4_free_stateid free_stateid; 493 struct nfsd4_free_stateid free_stateid;
487 494
488 /* NFSv4.2 */ 495 /* NFSv4.2 */
496 struct nfsd4_fallocate allocate;
489 struct nfsd4_seek seek; 497 struct nfsd4_seek seek;
490 } u; 498 } u;
491 struct nfs4_replay * replay; 499 struct nfs4_replay * replay;