* [PATCH v4 0/2] NFS: Add ALLOCATE and DEALLOCATE support
@ 2014-11-07 19:44 Anna Schumaker
2014-11-07 19:44 ` [PATCH v4 1/2] nfs: Add ALLOCATE support Anna Schumaker
2014-11-07 19:44 ` [PATCH v4 2/2] nfs: Add DEALLOCATE support Anna Schumaker
0 siblings, 2 replies; 6+ messages in thread
From: Anna Schumaker @ 2014-11-07 19:44 UTC (permalink / raw)
To: Trond.Myklebust, linux-nfs
These patches add client support for the ALLOCATE and DEALLOCATE operations
part of NFS v4.2, which are triggered by a vfs_fallocate() call.
Changes in v4:
- Use a single struct fallocate so code can be shared between both operations.
- Return -EOPNOTSUPP if we detect that the file is not a regular file.
- Call nfs_zap_caches() to invalidate cached size information (fixes xfstests
generic/075, generic/091, generic/112, generic/127, generic/214, and
generic/263)
These patches and the corresponding server changes are available in the
[fallocate] branch of
git://git.linux-nfs.org/projects/anna/linux-nfs.git
Questions? Comments? Thougts?
Anna
Anna Schumaker (2):
nfs: Add ALLOCATE support
nfs: Add DEALLOCATE support
fs/nfs/inode.c | 1 +
fs/nfs/nfs42.h | 2 +
fs/nfs/nfs42proc.c | 75 +++++++++++++++++++++++++
fs/nfs/nfs42xdr.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++
fs/nfs/nfs4_fs.h | 1 +
fs/nfs/nfs4file.c | 31 +++++++++++
fs/nfs/nfs4proc.c | 4 +-
fs/nfs/nfs4xdr.c | 2 +
include/linux/nfs4.h | 2 +
include/linux/nfs_fs_sb.h | 2 +
include/linux/nfs_xdr.h | 14 +++++
11 files changed, 272 insertions(+), 1 deletion(-)
--
2.1.3
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v4 1/2] nfs: Add ALLOCATE support
2014-11-07 19:44 [PATCH v4 0/2] NFS: Add ALLOCATE and DEALLOCATE support Anna Schumaker
@ 2014-11-07 19:44 ` Anna Schumaker
2014-11-24 21:45 ` Trond Myklebust
2014-11-07 19:44 ` [PATCH v4 2/2] nfs: Add DEALLOCATE support Anna Schumaker
1 sibling, 1 reply; 6+ messages in thread
From: Anna Schumaker @ 2014-11-07 19:44 UTC (permalink / raw)
To: Trond.Myklebust, linux-nfs
This patch adds support for using the NFS v4.2 operation ALLOCATE to
preallocate data in a file.
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
---
fs/nfs/inode.c | 1 +
fs/nfs/nfs42.h | 1 +
fs/nfs/nfs42proc.c | 58 ++++++++++++++++++++++++++++++++++++
fs/nfs/nfs42xdr.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++
fs/nfs/nfs4_fs.h | 1 +
fs/nfs/nfs4file.c | 28 ++++++++++++++++++
fs/nfs/nfs4proc.c | 3 +-
fs/nfs/nfs4xdr.c | 1 +
include/linux/nfs4.h | 1 +
include/linux/nfs_fs_sb.h | 1 +
include/linux/nfs_xdr.h | 14 +++++++++
11 files changed, 183 insertions(+), 1 deletion(-)
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 00689a8..bfffc33 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -192,6 +192,7 @@ void nfs_zap_caches(struct inode *inode)
nfs_zap_caches_locked(inode);
spin_unlock(&inode->i_lock);
}
+EXPORT_SYMBOL_GPL(nfs_zap_caches);
void nfs_zap_mapping(struct inode *inode, struct address_space *mapping)
{
diff --git a/fs/nfs/nfs42.h b/fs/nfs/nfs42.h
index d10333a..42656a9 100644
--- a/fs/nfs/nfs42.h
+++ b/fs/nfs/nfs42.h
@@ -6,6 +6,7 @@
#define __LINUX_FS_NFS_NFS4_2_H
/* nfs4.2proc.c */
+int nfs42_proc_allocate(struct file *, loff_t, loff_t);
loff_t nfs42_proc_llseek(struct file *, loff_t, int);
/* nfs4.2xdr.h */
diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c
index 0886f1d..5da6e8e 100644
--- a/fs/nfs/nfs42proc.c
+++ b/fs/nfs/nfs42proc.c
@@ -32,6 +32,64 @@ static int nfs42_set_rw_stateid(nfs4_stateid *dst, struct file *file,
return ret;
}
+int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
+ loff_t offset, loff_t len)
+{
+ struct inode *inode = file_inode(filep);
+ struct nfs42_falloc_args args = {
+ .falloc_fh = NFS_FH(inode),
+ .falloc_offset = offset,
+ .falloc_length = len,
+ };
+ struct nfs42_falloc_res res;
+ struct nfs_server *server = NFS_SERVER(inode);
+ int status;
+
+ msg->rpc_argp = &args;
+ msg->rpc_resp = &res;
+
+ status = nfs42_set_rw_stateid(&args.falloc_stateid, filep, FMODE_WRITE);
+ if (status)
+ return status;
+
+ return nfs4_call_sync(server->client, server, msg,
+ &args.seq_args, &res.seq_res, 0);
+}
+
+int nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
+ loff_t offset, loff_t len)
+{
+ struct nfs_server *server = NFS_SERVER(file_inode(filep));
+ struct nfs4_exception exception = { };
+ int err;
+
+ do {
+ err = _nfs42_proc_fallocate(msg, filep, offset, len);
+ if (err == -ENOTSUPP)
+ return -EOPNOTSUPP;
+ err = nfs4_handle_exception(server, err, &exception);
+ } while (exception.retry);
+
+ return err;
+}
+
+int nfs42_proc_allocate(struct file *filep, loff_t offset, loff_t len)
+{
+ struct rpc_message msg = {
+ .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ALLOCATE],
+ };
+ struct inode *inode = file_inode(filep);
+ int err;
+
+ if (!nfs_server_capable(inode, NFS_CAP_ALLOCATE))
+ return -EOPNOTSUPP;
+
+ err = nfs42_proc_fallocate(&msg, filep, offset, len);
+ if (err == -EOPNOTSUPP)
+ NFS_SERVER(inode)->caps &= ~NFS_CAP_ALLOCATE;
+ return err;
+}
+
loff_t nfs42_proc_llseek(struct file *filep, loff_t offset, int whence)
{
struct inode *inode = file_inode(filep);
diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c
index c90469b..4248d03 100644
--- a/fs/nfs/nfs42xdr.c
+++ b/fs/nfs/nfs42xdr.c
@@ -4,6 +4,12 @@
#ifndef __LINUX_FS_NFS_NFS4_2XDR_H
#define __LINUX_FS_NFS_NFS4_2XDR_H
+#define encode_fallocate_maxsz (encode_stateid_maxsz + \
+ 2 /* offset */ + \
+ 2 /* length */)
+#define encode_allocate_maxsz (op_encode_hdr_maxsz + \
+ encode_fallocate_maxsz)
+#define decode_allocate_maxsz (op_decode_hdr_maxsz)
#define encode_seek_maxsz (op_encode_hdr_maxsz + \
encode_stateid_maxsz + \
2 /* offset */ + \
@@ -14,6 +20,12 @@
2 /* offset */ + \
2 /* length */)
+#define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \
+ encode_putfh_maxsz + \
+ encode_allocate_maxsz)
+#define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \
+ decode_putfh_maxsz + \
+ decode_allocate_maxsz)
#define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
encode_seek_maxsz)
@@ -22,6 +34,22 @@
decode_seek_maxsz)
+static void encode_fallocate(struct xdr_stream *xdr,
+ struct nfs42_falloc_args *args)
+{
+ encode_nfs4_stateid(xdr, &args->falloc_stateid);
+ encode_uint64(xdr, args->falloc_offset);
+ encode_uint64(xdr, args->falloc_length);
+}
+
+static void encode_allocate(struct xdr_stream *xdr,
+ struct nfs42_falloc_args *args,
+ struct compound_hdr *hdr)
+{
+ encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr);
+ encode_fallocate(xdr, args);
+}
+
static void encode_seek(struct xdr_stream *xdr,
struct nfs42_seek_args *args,
struct compound_hdr *hdr)
@@ -33,6 +61,24 @@ static void encode_seek(struct xdr_stream *xdr,
}
/*
+ * Encode ALLOCATE request
+ */
+static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs42_falloc_args *args)
+{
+ struct compound_hdr hdr = {
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
+ };
+
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->falloc_fh, &hdr);
+ encode_allocate(xdr, args, &hdr);
+ encode_nops(&hdr);
+}
+
+/*
* Encode SEEK request
*/
static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
@@ -50,6 +96,11 @@ static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
encode_nops(&hdr);
}
+static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
+{
+ return decode_op_hdr(xdr, OP_ALLOCATE);
+}
+
static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
{
int status;
@@ -73,6 +124,30 @@ out_overflow:
}
/*
+ * Decode ALLOCATE request
+ */
+static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
+ struct xdr_stream *xdr,
+ struct nfs42_falloc_res *res)
+{
+ struct compound_hdr hdr;
+ int status;
+
+ status = decode_compound_hdr(xdr, &hdr);
+ if (status)
+ goto out;
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
+ status = decode_putfh(xdr);
+ if (status)
+ goto out;
+ status = decode_allocate(xdr, res);
+out:
+ return status;
+}
+
+/*
* Decode SEEK request
*/
static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp,
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index be6cac3..a081787 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -226,6 +226,7 @@ int nfs4_replace_transport(struct nfs_server *server,
const struct nfs4_fs_locations *locations);
/* nfs4proc.c */
+extern int nfs4_handle_exception(struct nfs_server *, int, struct nfs4_exception *);
extern int nfs4_call_sync(struct rpc_clnt *, struct nfs_server *,
struct rpc_message *, struct nfs4_sequence_args *,
struct nfs4_sequence_res *, int);
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c
index c51fb4d..f78e9fd 100644
--- a/fs/nfs/nfs4file.c
+++ b/fs/nfs/nfs4file.c
@@ -3,6 +3,8 @@
*
* Copyright (C) 1992 Rick Sladkey
*/
+#include <linux/fs.h>
+#include <linux/falloc.h>
#include <linux/nfs_fs.h>
#include "internal.h"
#include "fscache.h"
@@ -134,6 +136,29 @@ static loff_t nfs4_file_llseek(struct file *filep, loff_t offset, int whence)
return nfs_file_llseek(filep, offset, whence);
}
}
+
+static long nfs42_fallocate(struct file *filep, int mode, loff_t offset, loff_t len)
+{
+ struct inode *inode = file_inode(filep);
+ long ret;
+
+ if (!S_ISREG(inode->i_mode))
+ return -EOPNOTSUPP;
+
+ if (mode != 0)
+ return -EOPNOTSUPP;
+
+ ret = inode_newsize_ok(inode, offset + len);
+ if (ret < 0)
+ return ret;
+
+ mutex_lock(&inode->i_mutex);
+ ret = nfs42_proc_allocate(filep, offset, len);
+ mutex_unlock(&inode->i_mutex);
+
+ nfs_zap_caches(inode);
+ return ret;
+}
#endif /* CONFIG_NFS_V4_2 */
const struct file_operations nfs4_file_operations = {
@@ -155,6 +180,9 @@ const struct file_operations nfs4_file_operations = {
.flock = nfs_flock,
.splice_read = nfs_file_splice_read,
.splice_write = iter_file_splice_write,
+#ifdef CONFIG_NFS_V4_2
+ .fallocate = nfs42_fallocate,
+#endif /* CONFIG_NFS_V4_2 */
.check_flags = nfs_check_flags,
.setlease = simple_nosetlease,
};
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 773ebcb..99f73d3 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -344,7 +344,7 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
/* This is the error handling routine for processes that are allowed
* to sleep.
*/
-static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
+int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
{
struct nfs_client *clp = server->nfs_client;
struct nfs4_state *state = exception->state;
@@ -8420,6 +8420,7 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = {
| NFS_CAP_POSIX_LOCK
| NFS_CAP_STATEID_NFSV41
| NFS_CAP_ATOMIC_OPEN_V1
+ | NFS_CAP_ALLOCATE
| NFS_CAP_SEEK,
.init_client = nfs41_init_client,
.shutdown_client = nfs41_shutdown_client,
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 206c08a..0a14845 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -7394,6 +7394,7 @@ struct rpc_procinfo nfs4_procedures[] = {
#endif /* CONFIG_NFS_V4_1 */
#ifdef CONFIG_NFS_V4_2
PROC(SEEK, enc_seek, dec_seek),
+ PROC(ALLOCATE, enc_allocate, dec_allocate),
#endif /* CONFIG_NFS_V4_2 */
};
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 356acc2..2b28a21 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -490,6 +490,7 @@ enum {
/* nfs42 */
NFSPROC4_CLNT_SEEK,
+ NFSPROC4_CLNT_ALLOCATE,
};
/* nfs41 types */
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index a32ba0d..df6ed42 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -231,5 +231,6 @@ struct nfs_server {
#define NFS_CAP_ATOMIC_OPEN_V1 (1U << 17)
#define NFS_CAP_SECURITY_LABEL (1U << 18)
#define NFS_CAP_SEEK (1U << 19)
+#define NFS_CAP_ALLOCATE (1U << 20)
#endif
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 47ebb4f..467c84e 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1243,6 +1243,20 @@ nfs_free_pnfs_ds_cinfo(struct pnfs_ds_commit_info *cinfo)
#endif /* CONFIG_NFS_V4_1 */
#ifdef CONFIG_NFS_V4_2
+struct nfs42_falloc_args {
+ struct nfs4_sequence_args seq_args;
+
+ struct nfs_fh *falloc_fh;
+ nfs4_stateid falloc_stateid;
+ u64 falloc_offset;
+ u64 falloc_length;
+};
+
+struct nfs42_falloc_res {
+ struct nfs4_sequence_res seq_res;
+ unsigned int status;
+};
+
struct nfs42_seek_args {
struct nfs4_sequence_args seq_args;
--
2.1.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v4 2/2] nfs: Add DEALLOCATE support
2014-11-07 19:44 [PATCH v4 0/2] NFS: Add ALLOCATE and DEALLOCATE support Anna Schumaker
2014-11-07 19:44 ` [PATCH v4 1/2] nfs: Add ALLOCATE support Anna Schumaker
@ 2014-11-07 19:44 ` Anna Schumaker
1 sibling, 0 replies; 6+ messages in thread
From: Anna Schumaker @ 2014-11-07 19:44 UTC (permalink / raw)
To: Trond.Myklebust, linux-nfs
This patch adds support for using the NFS v4.2 operation DEALLOCATE to
punch holes in a file.
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
---
fs/nfs/nfs42.h | 1 +
fs/nfs/nfs42proc.c | 17 +++++++++++++
fs/nfs/nfs42xdr.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++
fs/nfs/nfs4file.c | 7 ++++--
fs/nfs/nfs4proc.c | 1 +
fs/nfs/nfs4xdr.c | 1 +
include/linux/nfs4.h | 1 +
include/linux/nfs_fs_sb.h | 1 +
8 files changed, 91 insertions(+), 2 deletions(-)
diff --git a/fs/nfs/nfs42.h b/fs/nfs/nfs42.h
index 42656a9..7afb894 100644
--- a/fs/nfs/nfs42.h
+++ b/fs/nfs/nfs42.h
@@ -7,6 +7,7 @@
/* nfs4.2proc.c */
int nfs42_proc_allocate(struct file *, loff_t, loff_t);
+int nfs42_proc_deallocate(struct file *, loff_t, loff_t);
loff_t nfs42_proc_llseek(struct file *, loff_t, int);
/* nfs4.2xdr.h */
diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c
index 5da6e8e..a73c083 100644
--- a/fs/nfs/nfs42proc.c
+++ b/fs/nfs/nfs42proc.c
@@ -90,6 +90,23 @@ int nfs42_proc_allocate(struct file *filep, loff_t offset, loff_t len)
return err;
}
+int nfs42_proc_deallocate(struct file *filep, loff_t offset, loff_t len)
+{
+ struct rpc_message msg = {
+ .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DEALLOCATE],
+ };
+ struct inode *inode = file_inode(filep);
+ int err;
+
+ if (!nfs_server_capable(inode, NFS_CAP_DEALLOCATE))
+ return -EOPNOTSUPP;
+
+ err = nfs42_proc_fallocate(&msg, filep, offset, len);
+ if (err == -EOPNOTSUPP)
+ NFS_SERVER(inode)->caps &= ~NFS_CAP_DEALLOCATE;
+ return err;
+}
+
loff_t nfs42_proc_llseek(struct file *filep, loff_t offset, int whence)
{
struct inode *inode = file_inode(filep);
diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c
index 4248d03..038a7e1 100644
--- a/fs/nfs/nfs42xdr.c
+++ b/fs/nfs/nfs42xdr.c
@@ -10,6 +10,9 @@
#define encode_allocate_maxsz (op_encode_hdr_maxsz + \
encode_fallocate_maxsz)
#define decode_allocate_maxsz (op_decode_hdr_maxsz)
+#define encode_deallocate_maxsz (op_encode_hdr_maxsz + \
+ encode_fallocate_maxsz)
+#define decode_deallocate_maxsz (op_decode_hdr_maxsz)
#define encode_seek_maxsz (op_encode_hdr_maxsz + \
encode_stateid_maxsz + \
2 /* offset */ + \
@@ -26,6 +29,12 @@
#define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
decode_allocate_maxsz)
+#define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \
+ encode_putfh_maxsz + \
+ encode_deallocate_maxsz)
+#define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \
+ decode_putfh_maxsz + \
+ decode_deallocate_maxsz)
#define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
encode_seek_maxsz)
@@ -50,6 +59,14 @@ static void encode_allocate(struct xdr_stream *xdr,
encode_fallocate(xdr, args);
}
+static void encode_deallocate(struct xdr_stream *xdr,
+ struct nfs42_falloc_args *args,
+ struct compound_hdr *hdr)
+{
+ encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr);
+ encode_fallocate(xdr, args);
+}
+
static void encode_seek(struct xdr_stream *xdr,
struct nfs42_seek_args *args,
struct compound_hdr *hdr)
@@ -79,6 +96,24 @@ static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
}
/*
+ * Encode DEALLOCATE request
+ */
+static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
+ struct xdr_stream *xdr,
+ struct nfs42_falloc_args *args)
+{
+ struct compound_hdr hdr = {
+ .minorversion = nfs4_xdr_minorversion(&args->seq_args),
+ };
+
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->falloc_fh, &hdr);
+ encode_deallocate(xdr, args, &hdr);
+ encode_nops(&hdr);
+}
+
+/*
* Encode SEEK request
*/
static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
@@ -101,6 +136,11 @@ static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
return decode_op_hdr(xdr, OP_ALLOCATE);
}
+static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
+{
+ return decode_op_hdr(xdr, OP_DEALLOCATE);
+}
+
static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
{
int status;
@@ -148,6 +188,30 @@ out:
}
/*
+ * Decode DEALLOCATE request
+ */
+static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
+ struct xdr_stream *xdr,
+ struct nfs42_falloc_res *res)
+{
+ struct compound_hdr hdr;
+ int status;
+
+ status = decode_compound_hdr(xdr, &hdr);
+ if (status)
+ goto out;
+ status = decode_sequence(xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
+ status = decode_putfh(xdr);
+ if (status)
+ goto out;
+ status = decode_deallocate(xdr, res);
+out:
+ return status;
+}
+
+/*
* Decode SEEK request
*/
static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp,
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c
index f78e9fd..8b46389 100644
--- a/fs/nfs/nfs4file.c
+++ b/fs/nfs/nfs4file.c
@@ -145,7 +145,7 @@ static long nfs42_fallocate(struct file *filep, int mode, loff_t offset, loff_t
if (!S_ISREG(inode->i_mode))
return -EOPNOTSUPP;
- if (mode != 0)
+ if ((mode != 0) && (mode != (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE)))
return -EOPNOTSUPP;
ret = inode_newsize_ok(inode, offset + len);
@@ -153,7 +153,10 @@ static long nfs42_fallocate(struct file *filep, int mode, loff_t offset, loff_t
return ret;
mutex_lock(&inode->i_mutex);
- ret = nfs42_proc_allocate(filep, offset, len);
+ if (mode & FALLOC_FL_PUNCH_HOLE)
+ ret = nfs42_proc_deallocate(filep, offset, len);
+ else
+ ret = nfs42_proc_allocate(filep, offset, len);
mutex_unlock(&inode->i_mutex);
nfs_zap_caches(inode);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 99f73d3..3027544 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -8421,6 +8421,7 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = {
| NFS_CAP_STATEID_NFSV41
| NFS_CAP_ATOMIC_OPEN_V1
| NFS_CAP_ALLOCATE
+ | NFS_CAP_DEALLOCATE
| NFS_CAP_SEEK,
.init_client = nfs41_init_client,
.shutdown_client = nfs41_shutdown_client,
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 0a14845..03d0fa6 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -7395,6 +7395,7 @@ struct rpc_procinfo nfs4_procedures[] = {
#ifdef CONFIG_NFS_V4_2
PROC(SEEK, enc_seek, dec_seek),
PROC(ALLOCATE, enc_allocate, dec_allocate),
+ PROC(DEALLOCATE, enc_deallocate, dec_deallocate),
#endif /* CONFIG_NFS_V4_2 */
};
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 2b28a21..022b761 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -491,6 +491,7 @@ enum {
/* nfs42 */
NFSPROC4_CLNT_SEEK,
NFSPROC4_CLNT_ALLOCATE,
+ NFSPROC4_CLNT_DEALLOCATE,
};
/* nfs41 types */
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index df6ed42..1e37fbb 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -232,5 +232,6 @@ struct nfs_server {
#define NFS_CAP_SECURITY_LABEL (1U << 18)
#define NFS_CAP_SEEK (1U << 19)
#define NFS_CAP_ALLOCATE (1U << 20)
+#define NFS_CAP_DEALLOCATE (1U << 21)
#endif
--
2.1.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v4 1/2] nfs: Add ALLOCATE support
2014-11-07 19:44 ` [PATCH v4 1/2] nfs: Add ALLOCATE support Anna Schumaker
@ 2014-11-24 21:45 ` Trond Myklebust
2014-11-25 15:40 ` Anna Schumaker
0 siblings, 1 reply; 6+ messages in thread
From: Trond Myklebust @ 2014-11-24 21:45 UTC (permalink / raw)
To: Anna Schumaker; +Cc: Linux NFS Mailing List
On Fri, Nov 7, 2014 at 2:44 PM, Anna Schumaker
<Anna.Schumaker@netapp.com> wrote:
> This patch adds support for using the NFS v4.2 operation ALLOCATE to
> preallocate data in a file.
>
> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
> ---
> fs/nfs/inode.c | 1 +
> fs/nfs/nfs42.h | 1 +
> fs/nfs/nfs42proc.c | 58 ++++++++++++++++++++++++++++++++++++
> fs/nfs/nfs42xdr.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++
> fs/nfs/nfs4_fs.h | 1 +
> fs/nfs/nfs4file.c | 28 ++++++++++++++++++
> fs/nfs/nfs4proc.c | 3 +-
> fs/nfs/nfs4xdr.c | 1 +
> include/linux/nfs4.h | 1 +
> include/linux/nfs_fs_sb.h | 1 +
> include/linux/nfs_xdr.h | 14 +++++++++
> 11 files changed, 183 insertions(+), 1 deletion(-)
>
> diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
> index 00689a8..bfffc33 100644
> --- a/fs/nfs/inode.c
> +++ b/fs/nfs/inode.c
> @@ -192,6 +192,7 @@ void nfs_zap_caches(struct inode *inode)
> nfs_zap_caches_locked(inode);
> spin_unlock(&inode->i_lock);
> }
> +EXPORT_SYMBOL_GPL(nfs_zap_caches);
>
> void nfs_zap_mapping(struct inode *inode, struct address_space *mapping)
> {
> diff --git a/fs/nfs/nfs42.h b/fs/nfs/nfs42.h
> index d10333a..42656a9 100644
> --- a/fs/nfs/nfs42.h
> +++ b/fs/nfs/nfs42.h
> @@ -6,6 +6,7 @@
> #define __LINUX_FS_NFS_NFS4_2_H
>
> /* nfs4.2proc.c */
> +int nfs42_proc_allocate(struct file *, loff_t, loff_t);
> loff_t nfs42_proc_llseek(struct file *, loff_t, int);
>
> /* nfs4.2xdr.h */
> diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c
> index 0886f1d..5da6e8e 100644
> --- a/fs/nfs/nfs42proc.c
> +++ b/fs/nfs/nfs42proc.c
> @@ -32,6 +32,64 @@ static int nfs42_set_rw_stateid(nfs4_stateid *dst, struct file *file,
> return ret;
> }
>
> +int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
> + loff_t offset, loff_t len)
> +{
> + struct inode *inode = file_inode(filep);
> + struct nfs42_falloc_args args = {
> + .falloc_fh = NFS_FH(inode),
> + .falloc_offset = offset,
> + .falloc_length = len,
> + };
> + struct nfs42_falloc_res res;
> + struct nfs_server *server = NFS_SERVER(inode);
> + int status;
> +
> + msg->rpc_argp = &args;
> + msg->rpc_resp = &res;
> +
> + status = nfs42_set_rw_stateid(&args.falloc_stateid, filep, FMODE_WRITE);
> + if (status)
> + return status;
> +
> + return nfs4_call_sync(server->client, server, msg,
> + &args.seq_args, &res.seq_res, 0);
> +}
/home/trondmy/devel/kernel/linux-nfs/fs/nfs/nfs42proc.c:35:5: warning:
no previous prototype for ‘_nfs42_proc_fallocate’
[-Wmissing-prototypes]
int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
^
/home/trondmy/devel/kernel/linux-nfs/fs/nfs/nfs42proc.c:59:5: warning:
no previous prototype for ‘nfs42_proc_fallocate’
[-Wmissing-prototypes]
int nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
^
--
Trond Myklebust
Linux NFS client maintainer, PrimaryData
trond.myklebust@primarydata.com
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v4 1/2] nfs: Add ALLOCATE support
2014-11-24 21:45 ` Trond Myklebust
@ 2014-11-25 15:40 ` Anna Schumaker
2014-11-25 15:56 ` Trond Myklebust
0 siblings, 1 reply; 6+ messages in thread
From: Anna Schumaker @ 2014-11-25 15:40 UTC (permalink / raw)
To: Trond Myklebust; +Cc: Linux NFS Mailing List
On 11/24/2014 04:45 PM, Trond Myklebust wrote:
> On Fri, Nov 7, 2014 at 2:44 PM, Anna Schumaker
> <Anna.Schumaker@netapp.com> wrote:
>> This patch adds support for using the NFS v4.2 operation ALLOCATE to
>> preallocate data in a file.
>>
>> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
>> ---
>> fs/nfs/inode.c | 1 +
>> fs/nfs/nfs42.h | 1 +
>> fs/nfs/nfs42proc.c | 58 ++++++++++++++++++++++++++++++++++++
>> fs/nfs/nfs42xdr.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++
>> fs/nfs/nfs4_fs.h | 1 +
>> fs/nfs/nfs4file.c | 28 ++++++++++++++++++
>> fs/nfs/nfs4proc.c | 3 +-
>> fs/nfs/nfs4xdr.c | 1 +
>> include/linux/nfs4.h | 1 +
>> include/linux/nfs_fs_sb.h | 1 +
>> include/linux/nfs_xdr.h | 14 +++++++++
>> 11 files changed, 183 insertions(+), 1 deletion(-)
>>
>> diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
>> index 00689a8..bfffc33 100644
>> --- a/fs/nfs/inode.c
>> +++ b/fs/nfs/inode.c
>> @@ -192,6 +192,7 @@ void nfs_zap_caches(struct inode *inode)
>> nfs_zap_caches_locked(inode);
>> spin_unlock(&inode->i_lock);
>> }
>> +EXPORT_SYMBOL_GPL(nfs_zap_caches);
>>
>> void nfs_zap_mapping(struct inode *inode, struct address_space *mapping)
>> {
>> diff --git a/fs/nfs/nfs42.h b/fs/nfs/nfs42.h
>> index d10333a..42656a9 100644
>> --- a/fs/nfs/nfs42.h
>> +++ b/fs/nfs/nfs42.h
>> @@ -6,6 +6,7 @@
>> #define __LINUX_FS_NFS_NFS4_2_H
>>
>> /* nfs4.2proc.c */
>> +int nfs42_proc_allocate(struct file *, loff_t, loff_t);
>> loff_t nfs42_proc_llseek(struct file *, loff_t, int);
>>
>> /* nfs4.2xdr.h */
>> diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c
>> index 0886f1d..5da6e8e 100644
>> --- a/fs/nfs/nfs42proc.c
>> +++ b/fs/nfs/nfs42proc.c
>> @@ -32,6 +32,64 @@ static int nfs42_set_rw_stateid(nfs4_stateid *dst, struct file *file,
>> return ret;
>> }
>>
>> +int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
>> + loff_t offset, loff_t len)
>> +{
>> + struct inode *inode = file_inode(filep);
>> + struct nfs42_falloc_args args = {
>> + .falloc_fh = NFS_FH(inode),
>> + .falloc_offset = offset,
>> + .falloc_length = len,
>> + };
>> + struct nfs42_falloc_res res;
>> + struct nfs_server *server = NFS_SERVER(inode);
>> + int status;
>> +
>> + msg->rpc_argp = &args;
>> + msg->rpc_resp = &res;
>> +
>> + status = nfs42_set_rw_stateid(&args.falloc_stateid, filep, FMODE_WRITE);
>> + if (status)
>> + return status;
>> +
>> + return nfs4_call_sync(server->client, server, msg,
>> + &args.seq_args, &res.seq_res, 0);
>> +}
>
> /home/trondmy/devel/kernel/linux-nfs/fs/nfs/nfs42proc.c:35:5: warning:
> no previous prototype for ‘_nfs42_proc_fallocate’
> [-Wmissing-prototypes]
Are you using a special config option to enable the -Wmissing-prototypes flag? I haven't been able to hit this.
Anna
> int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
> ^
> /home/trondmy/devel/kernel/linux-nfs/fs/nfs/nfs42proc.c:59:5: warning:
> no previous prototype for ‘nfs42_proc_fallocate’
> [-Wmissing-prototypes]
> int nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
> ^
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v4 1/2] nfs: Add ALLOCATE support
2014-11-25 15:40 ` Anna Schumaker
@ 2014-11-25 15:56 ` Trond Myklebust
0 siblings, 0 replies; 6+ messages in thread
From: Trond Myklebust @ 2014-11-25 15:56 UTC (permalink / raw)
To: Anna Schumaker; +Cc: Linux NFS Mailing List
On Tue, Nov 25, 2014 at 10:40 AM, Anna Schumaker
<Anna.Schumaker@netapp.com> wrote:
> On 11/24/2014 04:45 PM, Trond Myklebust wrote:
>> On Fri, Nov 7, 2014 at 2:44 PM, Anna Schumaker
>> <Anna.Schumaker@netapp.com> wrote:
>>> This patch adds support for using the NFS v4.2 operation ALLOCATE to
>>> preallocate data in a file.
>>>
>>> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
>>> ---
>>> fs/nfs/inode.c | 1 +
>>> fs/nfs/nfs42.h | 1 +
>>> fs/nfs/nfs42proc.c | 58 ++++++++++++++++++++++++++++++++++++
>>> fs/nfs/nfs42xdr.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++
>>> fs/nfs/nfs4_fs.h | 1 +
>>> fs/nfs/nfs4file.c | 28 ++++++++++++++++++
>>> fs/nfs/nfs4proc.c | 3 +-
>>> fs/nfs/nfs4xdr.c | 1 +
>>> include/linux/nfs4.h | 1 +
>>> include/linux/nfs_fs_sb.h | 1 +
>>> include/linux/nfs_xdr.h | 14 +++++++++
>>> 11 files changed, 183 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
>>> index 00689a8..bfffc33 100644
>>> --- a/fs/nfs/inode.c
>>> +++ b/fs/nfs/inode.c
>>> @@ -192,6 +192,7 @@ void nfs_zap_caches(struct inode *inode)
>>> nfs_zap_caches_locked(inode);
>>> spin_unlock(&inode->i_lock);
>>> }
>>> +EXPORT_SYMBOL_GPL(nfs_zap_caches);
>>>
>>> void nfs_zap_mapping(struct inode *inode, struct address_space *mapping)
>>> {
>>> diff --git a/fs/nfs/nfs42.h b/fs/nfs/nfs42.h
>>> index d10333a..42656a9 100644
>>> --- a/fs/nfs/nfs42.h
>>> +++ b/fs/nfs/nfs42.h
>>> @@ -6,6 +6,7 @@
>>> #define __LINUX_FS_NFS_NFS4_2_H
>>>
>>> /* nfs4.2proc.c */
>>> +int nfs42_proc_allocate(struct file *, loff_t, loff_t);
>>> loff_t nfs42_proc_llseek(struct file *, loff_t, int);
>>>
>>> /* nfs4.2xdr.h */
>>> diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c
>>> index 0886f1d..5da6e8e 100644
>>> --- a/fs/nfs/nfs42proc.c
>>> +++ b/fs/nfs/nfs42proc.c
>>> @@ -32,6 +32,64 @@ static int nfs42_set_rw_stateid(nfs4_stateid *dst, struct file *file,
>>> return ret;
>>> }
>>>
>>> +int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
>>> + loff_t offset, loff_t len)
>>> +{
>>> + struct inode *inode = file_inode(filep);
>>> + struct nfs42_falloc_args args = {
>>> + .falloc_fh = NFS_FH(inode),
>>> + .falloc_offset = offset,
>>> + .falloc_length = len,
>>> + };
>>> + struct nfs42_falloc_res res;
>>> + struct nfs_server *server = NFS_SERVER(inode);
>>> + int status;
>>> +
>>> + msg->rpc_argp = &args;
>>> + msg->rpc_resp = &res;
>>> +
>>> + status = nfs42_set_rw_stateid(&args.falloc_stateid, filep, FMODE_WRITE);
>>> + if (status)
>>> + return status;
>>> +
>>> + return nfs4_call_sync(server->client, server, msg,
>>> + &args.seq_args, &res.seq_res, 0);
>>> +}
>>
>> /home/trondmy/devel/kernel/linux-nfs/fs/nfs/nfs42proc.c:35:5: warning:
>> no previous prototype for ‘_nfs42_proc_fallocate’
>> [-Wmissing-prototypes]
>
> Are you using a special config option to enable the -Wmissing-prototypes flag? I haven't been able to hit this.
>
I'm just compiling with 'make W=1' on a recent Fedora 20 image.
Cheers
Trond
--
Trond Myklebust
Linux NFS client maintainer, PrimaryData
trond.myklebust@primarydata.com
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2014-11-25 15:56 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-11-07 19:44 [PATCH v4 0/2] NFS: Add ALLOCATE and DEALLOCATE support Anna Schumaker
2014-11-07 19:44 ` [PATCH v4 1/2] nfs: Add ALLOCATE support Anna Schumaker
2014-11-24 21:45 ` Trond Myklebust
2014-11-25 15:40 ` Anna Schumaker
2014-11-25 15:56 ` Trond Myklebust
2014-11-07 19:44 ` [PATCH v4 2/2] nfs: Add DEALLOCATE support Anna Schumaker
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.