linux-nfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] nfs:  add support for additional attributes and ioctl to access
@ 2016-05-29 17:14 Anne Marie Merritt
  2016-05-29 17:14 ` [PATCH 1/6] nfs: Add timecreate to nfs inode, along with corresponding bitfields, request, and decode xdr routines Anne Marie Merritt
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Anne Marie Merritt @ 2016-05-29 17:14 UTC (permalink / raw)
  To: trondmy; +Cc: linux-nfs, Anne Marie Merritt

Summary:

Add support for NFS attributes:
        timecreate
        hidden
        system
        archive
        timebackup

Add IOCTL to access these attributes. IOCTL client sample source is included in the ioctl patch for test purposes.  Note: These attributes can only be accessible if the remote nfsd supports them and underlying file system populates them.

This will permit the surfacing of these attributes via nfs for underlying filesystems that support them. SMB/Samba makes use of these attributes.


Signed-off-by: Anne Marie Merritt <annemarie.merritt@primarydata.com>

Anne Marie Merritt (6):
  nfs:  Add timecreate to nfs inode, along with corresponding bitfields,
    request, and decode xdr routines.
  nfs:  Add 'hidden' field to nfs inode, along with corresponding
    bitfields, request, and decode xdr routines.
  nfs:  Add 'system' field to nfs inode, along with corresponding
    bitfields, request, and decode xdr routines.
  nfs:  Add 'archive' field to nfs inode, along with corresponding
    bitfields, request, and decode xdr routines.
  nfs:  Add timebackup to nfs inode, along with corresponding bitfields,
    request, and decode xdr routines.
  nfs:  Add ioctl to retrieve timecreate, timebackup, 'hidden',
    'archive', and 'system' fields from inode.

 fs/nfs/inode.c            |  70 +++++++++++++++++++++++++
 fs/nfs/nfs4file.c         |  31 +++++++++++
 fs/nfs/nfs4proc.c         |  15 ++++++
 fs/nfs/nfs4xdr.c          | 130 ++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/nfs_fs.h    |   9 ++++
 include/linux/nfs_fs_sb.h |   5 ++
 include/linux/nfs_xdr.h   |  18 +++++++
 include/uapi/linux/nfs.h  |  13 +++++
 8 files changed, 291 insertions(+)

-- 
2.3.6


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/6] nfs:  Add timecreate to nfs inode, along with corresponding bitfields, request, and decode xdr routines.
  2016-05-29 17:14 [PATCH 0/6] nfs: add support for additional attributes and ioctl to access Anne Marie Merritt
@ 2016-05-29 17:14 ` Anne Marie Merritt
  2016-05-29 17:14 ` [PATCH 2/6] nfs: Add 'hidden' field " Anne Marie Merritt
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Anne Marie Merritt @ 2016-05-29 17:14 UTC (permalink / raw)
  To: trondmy; +Cc: linux-nfs, Anne Marie Merritt, Anne Marie Merritt

Summary:

Add xdr support for NFS attribute 'timecreate'.

This will permit the surfacing of this attribute for underlying filesystems that support it.

Signed-off-by: Anne Marie Merritt <annemarie.merritt@primarydata.com>
---
 fs/nfs/inode.c            | 14 ++++++++++++++
 fs/nfs/nfs4proc.c         |  3 +++
 fs/nfs/nfs4xdr.c          | 23 +++++++++++++++++++++++
 include/linux/nfs_fs.h    |  6 ++++++
 include/linux/nfs_fs_sb.h |  1 +
 include/linux/nfs_xdr.h   |  3 +++
 6 files changed, 50 insertions(+)

diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index cfdccdc..82528e0 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -439,6 +439,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
 		memset(&inode->i_atime, 0, sizeof(inode->i_atime));
 		memset(&inode->i_mtime, 0, sizeof(inode->i_mtime));
 		memset(&inode->i_ctime, 0, sizeof(inode->i_ctime));
+		memset(&nfsi->timecreate, 0, sizeof(nfsi->timecreate));
 		inode->i_version = 0;
 		inode->i_size = 0;
 		clear_nlink(inode);
@@ -463,6 +464,10 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
 			inode->i_ctime = fattr->ctime;
 		else if (nfs_server_capable(inode, NFS_CAP_CTIME))
 			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
+		if (fattr->valid & NFS_ATTR_FATTR_TIME_CREATE)
+			nfsi->timecreate = fattr->time_create;
+		else if (nfs_server_capable(inode, NFS_CAP_TIME_CREATE))
+			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
 		if (fattr->valid & NFS_ATTR_FATTR_CHANGE)
 			inode->i_version = fattr->change_attr;
 		else
@@ -1764,6 +1769,15 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
 		cache_revalidated = false;
 	}
 
+	if (fattr->valid & NFS_ATTR_FATTR_TIME_CREATE) {
+		memcpy(&nfsi->timecreate, &fattr->time_create, sizeof(nfsi->timecreate));
+	} else if (server->caps & NFS_CAP_TIME_CREATE) {
+		nfsi->cache_validity |= save_cache_validity &
+				(NFS_INO_INVALID_ATTR
+				| NFS_INO_REVAL_FORCED);
+		cache_revalidated = false;
+	}
+
 	/* Check if our cached file size is stale */
 	if (fattr->valid & NFS_ATTR_FATTR_SIZE) {
 		new_isize = nfs_size_to_loff_t(fattr->size);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 122d2ba..2e45c10 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -187,6 +187,7 @@ const u32 nfs4_fattr_bitmap[3] = {
 	| FATTR4_WORD1_RAWDEV
 	| FATTR4_WORD1_SPACE_USED
 	| FATTR4_WORD1_TIME_ACCESS
+	| FATTR4_WORD1_TIME_CREATE
 	| FATTR4_WORD1_TIME_METADATA
 	| FATTR4_WORD1_TIME_MODIFY
 	| FATTR4_WORD1_MOUNTED_ON_FILEID,
@@ -3073,6 +3074,8 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
 			server->caps |= NFS_CAP_CTIME;
 		if (res.attr_bitmask[1] & FATTR4_WORD1_TIME_MODIFY)
 			server->caps |= NFS_CAP_MTIME;
+		if (res.attr_bitmask[1] & FATTR4_WORD1_TIME_CREATE)
+			server->caps |= NFS_CAP_TIME_CREATE;
 #ifdef CONFIG_NFS_V4_SECURITY_LABEL
 		if (res.attr_bitmask[2] & FATTR4_WORD2_SECURITY_LABEL)
 			server->caps |= NFS_CAP_SECURITY_LABEL;
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index d5a5a32..bc0cfae 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -4129,6 +4129,24 @@ static int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, str
 	return status;
 }
 
+static int decode_attr_time_create(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)
+{
+	int status = 0;
+
+	time->tv_sec = 0;
+	time->tv_nsec = 0;
+	if (unlikely(bitmap[1] & (FATTR4_WORD1_TIME_CREATE - 1U)))
+		return -EIO;
+	if (likely(bitmap[1] & FATTR4_WORD1_TIME_CREATE)) {
+		status = decode_attr_time(xdr, time);
+		if (status == 0)
+			status = NFS_ATTR_FATTR_TIME_CREATE;
+		bitmap[1] &= ~FATTR4_WORD1_TIME_CREATE;
+	}
+	dprintk("%s: time_create=%ld\n", __func__, (long)time->tv_sec);
+	return status;
+}
+
 static int decode_attr_time_metadata(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)
 {
 	int status = 0;
@@ -4646,6 +4664,11 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
 		goto xdr_error;
 	fattr->valid |= status;
 
+	status = decode_attr_time_create(xdr, bitmap, &fattr->time_create);
+	if (status < 0)
+		goto xdr_error;
+	fattr->valid |= status;
+
 	status = decode_attr_time_metadata(xdr, bitmap, &fattr->ctime);
 	if (status < 0)
 		goto xdr_error;
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index eaeaca6..18d9535 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -131,6 +131,12 @@ struct nfs_inode {
 	unsigned long		cache_validity;		/* bit mask */
 
 	/*
+	 * NFS Attributes not included in struct inode
+	 */
+
+	struct timespec		timecreate;
+
+	/*
 	 * read_cache_jiffies is when we started read-caching this inode.
 	 * attrtimeo is for how long the cached information is assumed
 	 * to be valid. A successful attribute revalidation doubles
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 09b0352..7c1713c 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -245,5 +245,6 @@ struct nfs_server {
 #define NFS_CAP_CLONE		(1U << 23)
 #define NFS_CAP_ALLOW_ACLS	(1U << 24)
 #define NFS_CAP_DENY_ACLS	(1U << 25)
+#define NFS_CAP_TIME_CREATE	(1U << 26)
 
 #endif
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 74dbcb8..cc4a3f5 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -64,6 +64,7 @@ struct nfs_fattr {
 	struct timespec		atime;
 	struct timespec		mtime;
 	struct timespec		ctime;
+	struct timespec		time_create;
 	__u64			change_attr;	/* NFSv4 change attribute */
 	__u64			pre_change_attr;/* pre-op NFSv4 change attribute */
 	__u64			pre_size;	/* pre_op_attr.size	  */
@@ -102,6 +103,7 @@ struct nfs_fattr {
 #define NFS_ATTR_FATTR_OWNER_NAME	(1U << 23)
 #define NFS_ATTR_FATTR_GROUP_NAME	(1U << 24)
 #define NFS_ATTR_FATTR_V4_SECURITY_LABEL (1U << 25)
+#define NFS_ATTR_FATTR_TIME_CREATE	(1U << 26)
 
 #define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \
 		| NFS_ATTR_FATTR_MODE \
@@ -115,6 +117,7 @@ struct nfs_fattr {
 		| NFS_ATTR_FATTR_ATIME \
 		| NFS_ATTR_FATTR_MTIME \
 		| NFS_ATTR_FATTR_CTIME \
+		| NFS_ATTR_FATTR_TIME_CREATE \
 		| NFS_ATTR_FATTR_CHANGE)
 #define NFS_ATTR_FATTR_V2 (NFS_ATTR_FATTR \
 		| NFS_ATTR_FATTR_BLOCKS_USED)
-- 
2.3.6


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/6] nfs:  Add 'hidden' field to nfs inode, along with corresponding bitfields, request, and decode xdr routines.
  2016-05-29 17:14 [PATCH 0/6] nfs: add support for additional attributes and ioctl to access Anne Marie Merritt
  2016-05-29 17:14 ` [PATCH 1/6] nfs: Add timecreate to nfs inode, along with corresponding bitfields, request, and decode xdr routines Anne Marie Merritt
@ 2016-05-29 17:14 ` Anne Marie Merritt
  2016-05-29 17:14 ` [PATCH 3/6] nfs: Add 'system' " Anne Marie Merritt
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Anne Marie Merritt @ 2016-05-29 17:14 UTC (permalink / raw)
  To: trondmy; +Cc: linux-nfs, Anne Marie Merritt

Summary:

Add xdr support for NFS attribute 'hidden'.

This will permit the surfacing of this attribute for underlying filesystems that support it.

Signed-off-by: Anne Marie Merritt <annemarie.merritt@primarydata.com>
---
 fs/nfs/inode.c            | 14 ++++++++++++++
 fs/nfs/nfs4proc.c         |  3 +++
 fs/nfs/nfs4xdr.c          | 28 ++++++++++++++++++++++++++++
 include/linux/nfs_fs.h    |  2 +-
 include/linux/nfs_fs_sb.h |  1 +
 include/linux/nfs_xdr.h   |  6 ++++++
 6 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 82528e0..0cd1d95 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -440,6 +440,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
 		memset(&inode->i_mtime, 0, sizeof(inode->i_mtime));
 		memset(&inode->i_ctime, 0, sizeof(inode->i_ctime));
 		memset(&nfsi->timecreate, 0, sizeof(nfsi->timecreate));
+		nfsi->hidden = 0;
 		inode->i_version = 0;
 		inode->i_size = 0;
 		clear_nlink(inode);
@@ -468,6 +469,10 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
 			nfsi->timecreate = fattr->time_create;
 		else if (nfs_server_capable(inode, NFS_CAP_TIME_CREATE))
 			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
+		if (fattr->valid & NFS_ATTR_FATTR_HIDDEN)
+			nfsi->hidden = (fattr->hsa_flags & NFS_HSA_HIDDEN) != 0;
+		else if (nfs_server_capable(inode, NFS_CAP_HIDDEN))
+			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
 		if (fattr->valid & NFS_ATTR_FATTR_CHANGE)
 			inode->i_version = fattr->change_attr;
 		else
@@ -1778,6 +1783,15 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
 		cache_revalidated = false;
 	}
 
+	if (fattr->valid & NFS_ATTR_FATTR_HIDDEN) {
+		nfsi->hidden = (fattr->hsa_flags | NFS_HSA_HIDDEN) != 0;
+	} else if (server->caps & NFS_CAP_HIDDEN) {
+		nfsi->cache_validity |= save_cache_validity &
+				(NFS_INO_INVALID_ATTR
+				| NFS_INO_REVAL_FORCED);
+		cache_revalidated = false;
+	}
+
 	/* Check if our cached file size is stale */
 	if (fattr->valid & NFS_ATTR_FATTR_SIZE) {
 		new_isize = nfs_size_to_loff_t(fattr->size);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 2e45c10..cec7d19 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -179,6 +179,7 @@ const u32 nfs4_fattr_bitmap[3] = {
 	| FATTR4_WORD0_CHANGE
 	| FATTR4_WORD0_SIZE
 	| FATTR4_WORD0_FSID
+	| FATTR4_WORD0_HIDDEN
 	| FATTR4_WORD0_FILEID,
 	FATTR4_WORD1_MODE
 	| FATTR4_WORD1_NUMLINKS
@@ -3060,6 +3061,8 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
 			server->caps |= NFS_CAP_SYMLINKS;
 		if (res.attr_bitmask[0] & FATTR4_WORD0_FILEID)
 			server->caps |= NFS_CAP_FILEID;
+		if (res.attr_bitmask[0] & FATTR4_WORD0_HIDDEN)
+			server->caps |= NFS_CAP_HIDDEN;
 		if (res.attr_bitmask[1] & FATTR4_WORD1_MODE)
 			server->caps |= NFS_CAP_MODE;
 		if (res.attr_bitmask[1] & FATTR4_WORD1_NUMLINKS)
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index bc0cfae..e870385 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -4147,6 +4147,29 @@ static int decode_attr_time_create(struct xdr_stream *xdr, uint32_t *bitmap, str
 	return status;
 }
 
+static int decode_attr_hidden(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
+{
+	__be32 *p;
+
+	*res = 0;
+	if (unlikely(bitmap[0] & (FATTR4_WORD0_HIDDEN - 1U)))
+		return -EIO;
+	if (likely(bitmap[0] & FATTR4_WORD0_HIDDEN)) {
+		p = xdr_inline_decode(xdr, 4);
+		if (unlikely(!p))
+			goto out_overflow;
+		if (be32_to_cpup(p)) {
+			*res |= NFS_HSA_HIDDEN;
+		}
+		bitmap[0] &= ~FATTR4_WORD0_HIDDEN;
+	}
+	dprintk("%s: hidden file: =%s\n", __func__, (*res & NFS_HSA_HIDDEN) == 0 ? "false" : "true");
+	return 0;
+out_overflow:
+	print_overflow_msg(__func__, xdr);
+	return -EIO;
+}
+
 static int decode_attr_time_metadata(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)
 {
 	int status = 0;
@@ -4621,6 +4644,11 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
 		goto xdr_error;
 	fattr->valid |= status;
 
+	status = decode_attr_hidden(xdr, bitmap, &fattr->hsa_flags);
+	if (status < 0)
+		goto xdr_error;
+	fattr->valid |= status;
+
 	status = decode_attr_fs_locations(xdr, bitmap, fs_loc);
 	if (status < 0)
 		goto xdr_error;
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 18d9535..75e7a2c 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -135,7 +135,7 @@ struct nfs_inode {
 	 */
 
 	struct timespec		timecreate;
-
+	bool			hidden;
 	/*
 	 * read_cache_jiffies is when we started read-caching this inode.
 	 * attrtimeo is for how long the cached information is assumed
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 7c1713c..fe2ade7 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -246,5 +246,6 @@ struct nfs_server {
 #define NFS_CAP_ALLOW_ACLS	(1U << 24)
 #define NFS_CAP_DENY_ACLS	(1U << 25)
 #define NFS_CAP_TIME_CREATE	(1U << 26)
+#define NFS_CAP_HIDDEN          (1U << 27)
 
 #endif
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index cc4a3f5..204e031 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -14,6 +14,9 @@
 #define NFS_DEF_FILE_IO_SIZE	(4096U)
 #define NFS_MIN_FILE_IO_SIZE	(1024U)
 
+/* HIDDEN bitfield in hsa_flags in nfs_fattr */
+#define NFS_HSA_HIDDEN		(1U << 0)
+
 struct nfs4_string {
 	unsigned int len;
 	char *data;
@@ -65,6 +68,7 @@ struct nfs_fattr {
 	struct timespec		mtime;
 	struct timespec		ctime;
 	struct timespec		time_create;
+	__u32			hsa_flags;	/* hidden, system, archive flags bitfield */
 	__u64			change_attr;	/* NFSv4 change attribute */
 	__u64			pre_change_attr;/* pre-op NFSv4 change attribute */
 	__u64			pre_size;	/* pre_op_attr.size	  */
@@ -104,6 +108,7 @@ struct nfs_fattr {
 #define NFS_ATTR_FATTR_GROUP_NAME	(1U << 24)
 #define NFS_ATTR_FATTR_V4_SECURITY_LABEL (1U << 25)
 #define NFS_ATTR_FATTR_TIME_CREATE	(1U << 26)
+#define NFS_ATTR_FATTR_HIDDEN           (1U << 27)
 
 #define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \
 		| NFS_ATTR_FATTR_MODE \
@@ -118,6 +123,7 @@ struct nfs_fattr {
 		| NFS_ATTR_FATTR_MTIME \
 		| NFS_ATTR_FATTR_CTIME \
 		| NFS_ATTR_FATTR_TIME_CREATE \
+		| NFS_ATTR_FATTR_HIDDEN \
 		| NFS_ATTR_FATTR_CHANGE)
 #define NFS_ATTR_FATTR_V2 (NFS_ATTR_FATTR \
 		| NFS_ATTR_FATTR_BLOCKS_USED)
-- 
2.3.6


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/6] nfs:  Add 'system' field to nfs inode, along with corresponding bitfields, request, and decode xdr routines.
  2016-05-29 17:14 [PATCH 0/6] nfs: add support for additional attributes and ioctl to access Anne Marie Merritt
  2016-05-29 17:14 ` [PATCH 1/6] nfs: Add timecreate to nfs inode, along with corresponding bitfields, request, and decode xdr routines Anne Marie Merritt
  2016-05-29 17:14 ` [PATCH 2/6] nfs: Add 'hidden' field " Anne Marie Merritt
@ 2016-05-29 17:14 ` Anne Marie Merritt
  2016-05-29 17:14 ` [PATCH 4/6] nfs: Add 'archive' " Anne Marie Merritt
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Anne Marie Merritt @ 2016-05-29 17:14 UTC (permalink / raw)
  To: trondmy; +Cc: linux-nfs, Anne Marie Merritt

Summary:

Add xdr support for NFS attribute 'system'.

This will permit the surfacing of this attribute for underlying filesystems that support it.

Signed-off-by: Anne Marie Merritt <annemarie.merritt@primarydata.com>
---
 fs/nfs/inode.c            | 14 ++++++++++++++
 fs/nfs/nfs4proc.c         |  3 +++
 fs/nfs/nfs4xdr.c          | 28 ++++++++++++++++++++++++++++
 include/linux/nfs_fs.h    |  1 +
 include/linux/nfs_fs_sb.h |  1 +
 include/linux/nfs_xdr.h   |  5 ++++-
 6 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 0cd1d95..e995b0f 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -441,6 +441,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
 		memset(&inode->i_ctime, 0, sizeof(inode->i_ctime));
 		memset(&nfsi->timecreate, 0, sizeof(nfsi->timecreate));
 		nfsi->hidden = 0;
+		nfsi->system = 0;
 		inode->i_version = 0;
 		inode->i_size = 0;
 		clear_nlink(inode);
@@ -473,6 +474,10 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
 			nfsi->hidden = (fattr->hsa_flags & NFS_HSA_HIDDEN) != 0;
 		else if (nfs_server_capable(inode, NFS_CAP_HIDDEN))
 			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
+		if (fattr->valid & NFS_ATTR_FATTR_SYSTEM)
+			nfsi->system = (fattr->hsa_flags & NFS_HSA_SYSTEM) != 0;
+		else if (nfs_server_capable(inode, NFS_CAP_SYSTEM))
+			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
 		if (fattr->valid & NFS_ATTR_FATTR_CHANGE)
 			inode->i_version = fattr->change_attr;
 		else
@@ -1792,6 +1797,15 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
 		cache_revalidated = false;
 	}
 
+	if (fattr->valid & NFS_ATTR_FATTR_SYSTEM) {
+		nfsi->system = (fattr->hsa_flags | NFS_HSA_SYSTEM) != 0;
+	} else if (server->caps & NFS_CAP_SYSTEM) {
+		nfsi->cache_validity |= save_cache_validity &
+				(NFS_INO_INVALID_ATTR
+				| NFS_INO_REVAL_FORCED);
+		cache_revalidated = false;
+	}
+
 	/* Check if our cached file size is stale */
 	if (fattr->valid & NFS_ATTR_FATTR_SIZE) {
 		new_isize = nfs_size_to_loff_t(fattr->size);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index cec7d19..5ee8084 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -189,6 +189,7 @@ const u32 nfs4_fattr_bitmap[3] = {
 	| FATTR4_WORD1_SPACE_USED
 	| FATTR4_WORD1_TIME_ACCESS
 	| FATTR4_WORD1_TIME_CREATE
+	| FATTR4_WORD1_SYSTEM
 	| FATTR4_WORD1_TIME_METADATA
 	| FATTR4_WORD1_TIME_MODIFY
 	| FATTR4_WORD1_MOUNTED_ON_FILEID,
@@ -3079,6 +3080,8 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
 			server->caps |= NFS_CAP_MTIME;
 		if (res.attr_bitmask[1] & FATTR4_WORD1_TIME_CREATE)
 			server->caps |= NFS_CAP_TIME_CREATE;
+		if (res.attr_bitmask[1] & FATTR4_WORD1_SYSTEM)
+			server->caps |= NFS_CAP_SYSTEM;
 #ifdef CONFIG_NFS_V4_SECURITY_LABEL
 		if (res.attr_bitmask[2] & FATTR4_WORD2_SECURITY_LABEL)
 			server->caps |= NFS_CAP_SECURITY_LABEL;
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index e870385..5de5950 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -4170,6 +4170,29 @@ out_overflow:
 	return -EIO;
 }
 
+static int decode_attr_system(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
+{
+	__be32 *p;
+
+	*res = 0;
+	if (unlikely(bitmap[1] & (FATTR4_WORD1_SYSTEM - 1U)))
+		return -EIO;
+	if (likely(bitmap[1] & FATTR4_WORD1_SYSTEM)) {
+		p = xdr_inline_decode(xdr, 4);
+		if (unlikely(!p))
+			goto out_overflow;
+		if (be32_to_cpup(p)) {
+			*res |= NFS_HSA_SYSTEM;
+		}
+		bitmap[1] &= ~FATTR4_WORD1_SYSTEM;
+	}
+	dprintk("%s: system file: =%s\n", __func__, (*res & NFS_HSA_HIDDEN) == 0 ? "false" : "true");
+	return 0;
+out_overflow:
+	print_overflow_msg(__func__, xdr);
+	return -EIO;
+}
+
 static int decode_attr_time_metadata(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)
 {
 	int status = 0;
@@ -4687,6 +4710,11 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
 		goto xdr_error;
 	fattr->valid |= status;
 
+	status = decode_attr_system(xdr, bitmap, &fattr->hsa_flags);
+	if (status < 0)
+		goto xdr_error;
+	fattr->valid |= status;
+
 	status = decode_attr_time_access(xdr, bitmap, &fattr->atime);
 	if (status < 0)
 		goto xdr_error;
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 75e7a2c..1283505 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -136,6 +136,7 @@ struct nfs_inode {
 
 	struct timespec		timecreate;
 	bool			hidden;
+	bool			system;
 	/*
 	 * read_cache_jiffies is when we started read-caching this inode.
 	 * attrtimeo is for how long the cached information is assumed
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index fe2ade7..7ce3922 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -247,5 +247,6 @@ struct nfs_server {
 #define NFS_CAP_DENY_ACLS	(1U << 25)
 #define NFS_CAP_TIME_CREATE	(1U << 26)
 #define NFS_CAP_HIDDEN          (1U << 27)
+#define NFS_CAP_SYSTEM          (1U << 28)
 
 #endif
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 204e031..405b8c4 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -14,8 +14,9 @@
 #define NFS_DEF_FILE_IO_SIZE	(4096U)
 #define NFS_MIN_FILE_IO_SIZE	(1024U)
 
-/* HIDDEN bitfield in hsa_flags in nfs_fattr */
+/* HIDDEN, SYSTEM bitfields in hsa_flags in nfs_fattr */
 #define NFS_HSA_HIDDEN		(1U << 0)
+#define NFS_HSA_SYSTEM		(1U << 1)
 
 struct nfs4_string {
 	unsigned int len;
@@ -109,6 +110,7 @@ struct nfs_fattr {
 #define NFS_ATTR_FATTR_V4_SECURITY_LABEL (1U << 25)
 #define NFS_ATTR_FATTR_TIME_CREATE	(1U << 26)
 #define NFS_ATTR_FATTR_HIDDEN           (1U << 27)
+#define NFS_ATTR_FATTR_SYSTEM           (1U << 28)
 
 #define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \
 		| NFS_ATTR_FATTR_MODE \
@@ -124,6 +126,7 @@ struct nfs_fattr {
 		| NFS_ATTR_FATTR_CTIME \
 		| NFS_ATTR_FATTR_TIME_CREATE \
 		| NFS_ATTR_FATTR_HIDDEN \
+		| NFS_ATTR_FATTR_SYSTEM \
 		| NFS_ATTR_FATTR_CHANGE)
 #define NFS_ATTR_FATTR_V2 (NFS_ATTR_FATTR \
 		| NFS_ATTR_FATTR_BLOCKS_USED)
-- 
2.3.6


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/6] nfs:  Add 'archive' field to nfs inode, along with corresponding bitfields, request, and decode xdr routines.
  2016-05-29 17:14 [PATCH 0/6] nfs: add support for additional attributes and ioctl to access Anne Marie Merritt
                   ` (2 preceding siblings ...)
  2016-05-29 17:14 ` [PATCH 3/6] nfs: Add 'system' " Anne Marie Merritt
@ 2016-05-29 17:14 ` Anne Marie Merritt
  2016-05-29 17:14 ` [PATCH 5/6] nfs: Add timebackup " Anne Marie Merritt
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Anne Marie Merritt @ 2016-05-29 17:14 UTC (permalink / raw)
  To: trondmy; +Cc: linux-nfs, Anne Marie Merritt

Summary:

Add xdr support for NFS attribute 'archive'.

This will permit the surfacing of this attribute for underlying filesystems that support it.

Signed-off-by: Anne Marie Merritt <annemarie.merritt@primarydata.com>
---
 fs/nfs/inode.c            | 14 ++++++++++++++
 fs/nfs/nfs4proc.c         |  3 +++
 fs/nfs/nfs4xdr.c          | 28 ++++++++++++++++++++++++++++
 include/linux/nfs_fs.h    |  1 +
 include/linux/nfs_fs_sb.h |  1 +
 include/linux/nfs_xdr.h   |  3 +++
 6 files changed, 50 insertions(+)

diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index e995b0f..7a6ee66 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -442,6 +442,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
 		memset(&nfsi->timecreate, 0, sizeof(nfsi->timecreate));
 		nfsi->hidden = 0;
 		nfsi->system = 0;
+		nfsi->archive = 0;
 		inode->i_version = 0;
 		inode->i_size = 0;
 		clear_nlink(inode);
@@ -478,6 +479,10 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
 			nfsi->system = (fattr->hsa_flags & NFS_HSA_SYSTEM) != 0;
 		else if (nfs_server_capable(inode, NFS_CAP_SYSTEM))
 			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
+		if (fattr->valid & NFS_ATTR_FATTR_ARCHIVE)
+			nfsi->archive = (fattr->hsa_flags & NFS_HSA_ARCHIVE) !=0;
+		else if (nfs_server_capable(inode, NFS_CAP_ARCHIVE))
+			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
 		if (fattr->valid & NFS_ATTR_FATTR_CHANGE)
 			inode->i_version = fattr->change_attr;
 		else
@@ -1806,6 +1811,15 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
 		cache_revalidated = false;
 	}
 
+	if (fattr->valid & NFS_ATTR_FATTR_ARCHIVE) {
+		nfsi->archive = (fattr->hsa_flags | NFS_HSA_ARCHIVE) != 0;
+	} else if (server->caps & NFS_CAP_ARCHIVE) {
+		nfsi->cache_validity |= save_cache_validity &
+				(NFS_INO_INVALID_ATTR
+				| NFS_INO_REVAL_FORCED);
+		cache_revalidated = false;
+	}
+
 	/* Check if our cached file size is stale */
 	if (fattr->valid & NFS_ATTR_FATTR_SIZE) {
 		new_isize = nfs_size_to_loff_t(fattr->size);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 5ee8084..1d84b5c 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -180,6 +180,7 @@ const u32 nfs4_fattr_bitmap[3] = {
 	| FATTR4_WORD0_SIZE
 	| FATTR4_WORD0_FSID
 	| FATTR4_WORD0_HIDDEN
+	| FATTR4_WORD0_ARCHIVE
 	| FATTR4_WORD0_FILEID,
 	FATTR4_WORD1_MODE
 	| FATTR4_WORD1_NUMLINKS
@@ -3064,6 +3065,8 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
 			server->caps |= NFS_CAP_FILEID;
 		if (res.attr_bitmask[0] & FATTR4_WORD0_HIDDEN)
 			server->caps |= NFS_CAP_HIDDEN;
+		if (res.attr_bitmask[0] & FATTR4_WORD0_ARCHIVE)
+			server->caps |= NFS_CAP_ARCHIVE;
 		if (res.attr_bitmask[1] & FATTR4_WORD1_MODE)
 			server->caps |= NFS_CAP_MODE;
 		if (res.attr_bitmask[1] & FATTR4_WORD1_NUMLINKS)
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 5de5950..d8328a5 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -4193,6 +4193,29 @@ out_overflow:
 	return -EIO;
 }
 
+static int decode_attr_archive(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
+{
+	__be32 *p;
+
+	*res = 0;
+	if (unlikely(bitmap[0] & (FATTR4_WORD0_ARCHIVE - 1U)))
+		return -EIO;
+	if (likely(bitmap[0] & FATTR4_WORD0_ARCHIVE)) {
+		p = xdr_inline_decode(xdr, 4);
+		if (unlikely(!p))
+			goto out_overflow;
+		if (be32_to_cpup(p)) {
+			*res |= NFS_HSA_ARCHIVE;
+		}
+		bitmap[0] &= ~FATTR4_WORD0_ARCHIVE;
+	}
+	dprintk("%s: archive file: =%s\n", __func__, (*res & NFS_HSA_ARCHIVE) == 0 ? "false" : "true");
+	return 0;
+out_overflow:
+	print_overflow_msg(__func__, xdr);
+	return -EIO;
+}
+
 static int decode_attr_time_metadata(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)
 {
 	int status = 0;
@@ -4658,6 +4681,11 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
 	if (status < 0)
 		goto xdr_error;
 
+	status = decode_attr_archive(xdr, bitmap, &fattr->hsa_flags);
+	if (status < 0) 
+		goto xdr_error;
+	fattr->valid |= status;
+
 	status = decode_attr_filehandle(xdr, bitmap, fh);
 	if (status < 0)
 		goto xdr_error;
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 1283505..83c42f6 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -137,6 +137,7 @@ struct nfs_inode {
 	struct timespec		timecreate;
 	bool			hidden;
 	bool			system;
+	bool			archive;
 	/*
 	 * read_cache_jiffies is when we started read-caching this inode.
 	 * attrtimeo is for how long the cached information is assumed
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 7ce3922..3f972e7 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -248,5 +248,6 @@ struct nfs_server {
 #define NFS_CAP_TIME_CREATE	(1U << 26)
 #define NFS_CAP_HIDDEN          (1U << 27)
 #define NFS_CAP_SYSTEM          (1U << 28)
+#define NFS_CAP_ARCHIVE         (1U << 29)
 
 #endif
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 405b8c4..de90f90 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -17,6 +17,7 @@
 /* HIDDEN, SYSTEM bitfields in hsa_flags in nfs_fattr */
 #define NFS_HSA_HIDDEN		(1U << 0)
 #define NFS_HSA_SYSTEM		(1U << 1)
+#define NFS_HSA_ARCHIVE		(1U << 2)
 
 struct nfs4_string {
 	unsigned int len;
@@ -111,6 +112,7 @@ struct nfs_fattr {
 #define NFS_ATTR_FATTR_TIME_CREATE	(1U << 26)
 #define NFS_ATTR_FATTR_HIDDEN           (1U << 27)
 #define NFS_ATTR_FATTR_SYSTEM           (1U << 28)
+#define NFS_ATTR_FATTR_ARCHIVE          (1U << 29)
 
 #define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \
 		| NFS_ATTR_FATTR_MODE \
@@ -127,6 +129,7 @@ struct nfs_fattr {
 		| NFS_ATTR_FATTR_TIME_CREATE \
 		| NFS_ATTR_FATTR_HIDDEN \
 		| NFS_ATTR_FATTR_SYSTEM \
+		| NFS_ATTR_FATTR_ARCHIVE \
 		| NFS_ATTR_FATTR_CHANGE)
 #define NFS_ATTR_FATTR_V2 (NFS_ATTR_FATTR \
 		| NFS_ATTR_FATTR_BLOCKS_USED)
-- 
2.3.6


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 5/6] nfs:  Add timebackup to nfs inode, along with corresponding bitfields, request, and decode xdr routines.
  2016-05-29 17:14 [PATCH 0/6] nfs: add support for additional attributes and ioctl to access Anne Marie Merritt
                   ` (3 preceding siblings ...)
  2016-05-29 17:14 ` [PATCH 4/6] nfs: Add 'archive' " Anne Marie Merritt
@ 2016-05-29 17:14 ` Anne Marie Merritt
  2016-05-29 17:14 ` [PATCH 6/6] nfs: Add ioctl to retrieve timecreate, timebackup, 'hidden', 'archive', and 'system' fields from inode Anne Marie Merritt
  2016-05-30 16:03 ` [PATCH 0/6] nfs: add support for additional attributes and ioctl to access Christoph Hellwig
  6 siblings, 0 replies; 8+ messages in thread
From: Anne Marie Merritt @ 2016-05-29 17:14 UTC (permalink / raw)
  To: trondmy; +Cc: linux-nfs, Anne Marie Merritt

Summary:

Add xdr support for NFS attribute 'timebackup'.

This will permit the surfacing of this attribute for underlying filesystems that support it.

Signed-off-by: Anne Marie Merritt <annemarie.merritt@primarydata.com>
---
 fs/nfs/inode.c            | 14 ++++++++++++++
 fs/nfs/nfs4proc.c         |  3 +++
 fs/nfs/nfs4xdr.c          | 23 +++++++++++++++++++++++
 include/linux/nfs_fs.h    |  1 +
 include/linux/nfs_fs_sb.h |  1 +
 include/linux/nfs_xdr.h   |  3 +++
 6 files changed, 45 insertions(+)

diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 7a6ee66..e2e347f 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -440,6 +440,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
 		memset(&inode->i_mtime, 0, sizeof(inode->i_mtime));
 		memset(&inode->i_ctime, 0, sizeof(inode->i_ctime));
 		memset(&nfsi->timecreate, 0, sizeof(nfsi->timecreate));
+		memset(&nfsi->timebackup, 0, sizeof(nfsi->timebackup));
 		nfsi->hidden = 0;
 		nfsi->system = 0;
 		nfsi->archive = 0;
@@ -483,6 +484,10 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
 			nfsi->archive = (fattr->hsa_flags & NFS_HSA_ARCHIVE) !=0;
 		else if (nfs_server_capable(inode, NFS_CAP_ARCHIVE))
 			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
+		if (fattr->valid & NFS_ATTR_FATTR_TIME_BACKUP)
+			nfsi->timebackup = fattr->time_backup;
+		else if (nfs_server_capable(inode, NFS_CAP_TIME_BACKUP))
+			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
 		if (fattr->valid & NFS_ATTR_FATTR_CHANGE)
 			inode->i_version = fattr->change_attr;
 		else
@@ -1820,6 +1825,15 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
 		cache_revalidated = false;
 	}
 
+	if (fattr->valid & NFS_ATTR_FATTR_TIME_BACKUP) {
+		memcpy(&nfsi->timebackup, &fattr->time_backup, sizeof(nfsi->timebackup));
+	} else if (server->caps & NFS_CAP_TIME_BACKUP) {
+		nfsi->cache_validity |= save_cache_validity &
+				(NFS_INO_INVALID_ATTR
+				| NFS_INO_REVAL_FORCED);
+		cache_revalidated = false;
+	}
+
 	/* Check if our cached file size is stale */
 	if (fattr->valid & NFS_ATTR_FATTR_SIZE) {
 		new_isize = nfs_size_to_loff_t(fattr->size);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 1d84b5c..2e148f3 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -191,6 +191,7 @@ const u32 nfs4_fattr_bitmap[3] = {
 	| FATTR4_WORD1_TIME_ACCESS
 	| FATTR4_WORD1_TIME_CREATE
 	| FATTR4_WORD1_SYSTEM
+	| FATTR4_WORD1_TIME_BACKUP
 	| FATTR4_WORD1_TIME_METADATA
 	| FATTR4_WORD1_TIME_MODIFY
 	| FATTR4_WORD1_MOUNTED_ON_FILEID,
@@ -3085,6 +3086,8 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
 			server->caps |= NFS_CAP_TIME_CREATE;
 		if (res.attr_bitmask[1] & FATTR4_WORD1_SYSTEM)
 			server->caps |= NFS_CAP_SYSTEM;
+		if (res.attr_bitmask[1] & FATTR4_WORD1_TIME_BACKUP)
+			server->caps |= NFS_CAP_TIME_BACKUP;
 #ifdef CONFIG_NFS_V4_SECURITY_LABEL
 		if (res.attr_bitmask[2] & FATTR4_WORD2_SECURITY_LABEL)
 			server->caps |= NFS_CAP_SECURITY_LABEL;
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index d8328a5..d3ecb7e 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -4193,6 +4193,24 @@ out_overflow:
 	return -EIO;
 }
 
+static int decode_attr_time_backup(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)
+{
+	int status = 0;
+
+	time->tv_sec = 0;
+	time->tv_nsec = 0;
+	if (unlikely(bitmap[1] & (FATTR4_WORD1_TIME_BACKUP - 1U)))
+		return -EIO;
+	if (likely(bitmap[1] & FATTR4_WORD1_TIME_BACKUP)) {
+		status = decode_attr_time(xdr, time);
+		if (status == 0)
+			status = NFS_ATTR_FATTR_TIME_BACKUP;
+		bitmap[1] &= ~FATTR4_WORD1_TIME_BACKUP;
+	}
+	dprintk("%s: time_backup=%ld\n", __func__, (long)time->tv_sec);
+	return status;
+}
+
 static int decode_attr_archive(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
 {
 	__be32 *p;
@@ -4748,6 +4766,11 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
 		goto xdr_error;
 	fattr->valid |= status;
 
+	status = decode_attr_time_backup(xdr, bitmap, &fattr->time_backup);
+	if (status < 0)
+		goto xdr_error;
+	fattr->valid |= status;
+
 	status = decode_attr_time_create(xdr, bitmap, &fattr->time_create);
 	if (status < 0)
 		goto xdr_error;
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 83c42f6..82eae20 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -135,6 +135,7 @@ struct nfs_inode {
 	 */
 
 	struct timespec		timecreate;
+	struct timespec		timebackup;
 	bool			hidden;
 	bool			system;
 	bool			archive;
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 3f972e7..256d37f 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -249,5 +249,6 @@ struct nfs_server {
 #define NFS_CAP_HIDDEN          (1U << 27)
 #define NFS_CAP_SYSTEM          (1U << 28)
 #define NFS_CAP_ARCHIVE         (1U << 29)
+#define NFS_CAP_TIME_BACKUP     (1U << 30)
 
 #endif
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index de90f90..0fe5bdb 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -71,6 +71,7 @@ struct nfs_fattr {
 	struct timespec		ctime;
 	struct timespec		time_create;
 	__u32			hsa_flags;	/* hidden, system, archive flags bitfield */
+	struct timespec		time_backup;
 	__u64			change_attr;	/* NFSv4 change attribute */
 	__u64			pre_change_attr;/* pre-op NFSv4 change attribute */
 	__u64			pre_size;	/* pre_op_attr.size	  */
@@ -113,6 +114,7 @@ struct nfs_fattr {
 #define NFS_ATTR_FATTR_HIDDEN           (1U << 27)
 #define NFS_ATTR_FATTR_SYSTEM           (1U << 28)
 #define NFS_ATTR_FATTR_ARCHIVE          (1U << 29)
+#define NFS_ATTR_FATTR_TIME_BACKUP      (1U << 30)
 
 #define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \
 		| NFS_ATTR_FATTR_MODE \
@@ -130,6 +132,7 @@ struct nfs_fattr {
 		| NFS_ATTR_FATTR_HIDDEN \
 		| NFS_ATTR_FATTR_SYSTEM \
 		| NFS_ATTR_FATTR_ARCHIVE \
+		| NFS_ATTR_FATTR_TIME_BACKUP \
 		| NFS_ATTR_FATTR_CHANGE)
 #define NFS_ATTR_FATTR_V2 (NFS_ATTR_FATTR \
 		| NFS_ATTR_FATTR_BLOCKS_USED)
-- 
2.3.6


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 6/6] nfs:  Add ioctl to retrieve timecreate, timebackup, 'hidden', 'archive', and 'system' fields from inode.
  2016-05-29 17:14 [PATCH 0/6] nfs: add support for additional attributes and ioctl to access Anne Marie Merritt
                   ` (4 preceding siblings ...)
  2016-05-29 17:14 ` [PATCH 5/6] nfs: Add timebackup " Anne Marie Merritt
@ 2016-05-29 17:14 ` Anne Marie Merritt
  2016-05-30 16:03 ` [PATCH 0/6] nfs: add support for additional attributes and ioctl to access Christoph Hellwig
  6 siblings, 0 replies; 8+ messages in thread
From: Anne Marie Merritt @ 2016-05-29 17:14 UTC (permalink / raw)
  To: trondmy; +Cc: linux-nfs, Anne Marie Merritt


Summary:

Add IOCTL to retrieve attributes:
	timecreate
	timebackup
	hidden
	archive
	system

This will permit access to these attributes from user-level for software that requires them.  

Test code:

-=-=-

# cat ~/scripts/ioctl_attribs.c 
/*
 *  Author: Anne Marie Merritt (annemarie.merritt@primarydata.com)
 *  Test the ioctl to fetch a file's hidden, system,archive,
 *  timecreate, and timebackup attributes.
 *
 *  compile:  
 *    #> gcc -o attribstest ioctl_attribs.c
 *
 *  mount remote nfs share:
 *    #> mount -o vers=4.2 172.16.38.10:/ladybug /mnt/ladybug
 *  
 *  invoke:
 *    #> ./attribstest /mnt/ladybug/aphid.txt
 */

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <memory.h>
#include <errno.h>
#include <stdbool.h>


/* from nfs header file */
#define NFS_IOC_FILE_DATES_FLAGS _IOR('N', 10, struct nfs_ioctl_file_dates_flags_args *)

struct nfs_ioctl_file_dates_flags_args {
        bool hidden;
        bool system;
        bool archive;
        __u64 timebackup_seconds;
        __u32 timebackup_nseconds;
        __u64 timecreate_seconds;
        __u32 timecreate_nseconds;
};

void ioctl_get_attribs(int file_desc, struct nfs_ioctl_file_dates_flags_args * args)
{
    int ret_val;
    struct nfs_ioctl_file_dates_flags_args tempargs;

    memset(&tempargs, 0, sizeof(struct nfs_ioctl_file_dates_flags_args));
  
    ret_val = ioctl(file_desc, NFS_IOC_FILE_DATES_FLAGS, &tempargs);

    if (ret_val < 0) {
      int errsv = errno;
      printf ("ioctl_get_attribs failed:returned [%d]\n", ret_val);
      printf("ERROR: [%d][%s]\n", errsv, strerror(errsv));
    } else {
        printf ("ioctl_get_attribs: hidden:[%s] system [%s] archive [%s]\n",
		(tempargs.hidden == 0 ? "false" : "true"), 
		(tempargs.system == 0 ? "false" : "true"), 
		(tempargs.archive == 0 ? "false" : "true"));
	printf ("timebackup-seconds:[%lld] timebackup-nseconds:[%d]\n", 
		tempargs.timebackup_seconds,
		tempargs.timebackup_nseconds);
	printf ("timecreate-seconds:[%lld] timecreate-nseconds:[%d]\n", 
		tempargs.timecreate_seconds,
		tempargs.timecreate_nseconds);

	*args = tempargs;
    }
}

/* Main - Invoke the ioctl function */
int main ( int argc, char **argv ) {

    char * filename;
    int file_desc;
    struct nfs_ioctl_file_dates_flags_args attribs;

    if (argc != 2)
    {
      printf("This test takes exactly one argument.\n");
    }

    filename = argv[1];

    file_desc = open(filename, O_RDWR);
    if (file_desc < 0) {
        printf ("Can't open file: %s\n", 
        filename);
        exit(-1);
    }

    ioctl_get_attribs(file_desc, &attribs);

    close(file_desc); 
    exit(0);
}


-=-=-


Signed-off-by: Anne Marie Merritt <annemarie.merritt@primarydata.com>

---
 fs/nfs/nfs4file.c        | 31 +++++++++++++++++++++++++++++++
 include/uapi/linux/nfs.h | 13 +++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c
index 8ab34a7..076ca99 100644
--- a/fs/nfs/nfs4file.c
+++ b/fs/nfs/nfs4file.c
@@ -159,6 +159,35 @@ nfs4_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
 	return ret;
 }
 
+static long nfs4_ioctl_file_dates_flags(struct file *dst_file, void __user *argp)
+{
+	int ret = 0;
+	struct nfs_inode *nfsi;
+	struct nfs_ioctl_file_dates_flags_args args;
+	struct inode *dst_inode = file_inode(dst_file);
+	struct nfs_server *server = NFS_SERVER(dst_inode);
+
+	ret = nfs_revalidate_inode(server, dst_inode);
+	if (ret != 0)
+		return ret; 
+
+	nfsi = NFS_I(dst_inode);
+	args.hidden = nfsi->hidden;
+	args.system = nfsi->system;
+	args.archive = nfsi->archive;
+
+	args.timebackup_seconds = nfsi->timebackup.tv_sec;
+	args.timebackup_nseconds = nfsi->timebackup.tv_nsec;
+
+	args.timecreate_seconds = nfsi->timecreate.tv_sec;
+	args.timecreate_nseconds = nfsi->timecreate.tv_nsec;
+
+	if (copy_to_user(argp, &args, sizeof(args)))
+		return -EFAULT;
+
+	return 0;
+}
+
 #ifdef CONFIG_NFS_V4_2
 static loff_t nfs4_file_llseek(struct file *filep, loff_t offset, int whence)
 {
@@ -306,6 +335,8 @@ long nfs4_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	void __user *argp = (void __user *)arg;
 
 	switch (cmd) {
+	case NFS_IOC_FILE_DATES_FLAGS:
+		return nfs4_ioctl_file_dates_flags(file, argp);
 #ifdef CONFIG_NFS_V4_2
 	case NFS_IOC_CLONE:
 		return nfs42_ioctl_clone(file, arg, 0, 0, 0);
diff --git a/include/uapi/linux/nfs.h b/include/uapi/linux/nfs.h
index c6b86cc..e14168a 100644
--- a/include/uapi/linux/nfs.h
+++ b/include/uapi/linux/nfs.h
@@ -7,6 +7,8 @@
 #ifndef _UAPI_LINUX_NFS_H
 #define _UAPI_LINUX_NFS_H
 
+#include <linux/types.h>
+
 #define NFS_PROGRAM	100003
 #define NFS_PORT	2049
 #define NFS_MAXDATA	8192
@@ -35,6 +37,7 @@
 /* Let's follow btrfs lead on CLONE to avoid messing userspace */
 #define NFS_IOC_CLONE		_IOW(0x94, 9, int)
 #define NFS_IOC_CLONE_RANGE	_IOW(0x94, 13, int)
+#define NFS_IOC_FILE_DATES_FLAGS	_IOR('N', 10, struct nfs_ioctl_file_dates_flags_args *) 
 
 struct nfs_ioctl_clone_range_args {
 	__s64 src_fd;
@@ -42,6 +45,16 @@ struct nfs_ioctl_clone_range_args {
 	__u64 dst_off;
 };
 
+struct nfs_ioctl_file_dates_flags_args {
+	bool hidden;
+	bool system;
+	bool archive;
+	__u64 timebackup_seconds;
+	__u32 timebackup_nseconds;
+	__u64 timecreate_seconds;
+	__u32 timecreate_nseconds;
+};
+
 /*
  * NFS stats. The good thing with these values is that NFSv3 errors are
  * a superset of NFSv2 errors (with the exception of NFSERR_WFLUSH which
-- 
2.3.6


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/6] nfs:  add support for additional attributes and ioctl to access
  2016-05-29 17:14 [PATCH 0/6] nfs: add support for additional attributes and ioctl to access Anne Marie Merritt
                   ` (5 preceding siblings ...)
  2016-05-29 17:14 ` [PATCH 6/6] nfs: Add ioctl to retrieve timecreate, timebackup, 'hidden', 'archive', and 'system' fields from inode Anne Marie Merritt
@ 2016-05-30 16:03 ` Christoph Hellwig
  6 siblings, 0 replies; 8+ messages in thread
From: Christoph Hellwig @ 2016-05-30 16:03 UTC (permalink / raw)
  To: Anne Marie Merritt; +Cc: trondmy, linux-nfs, Anne Marie Merritt

Hi Anne,

we really should not any of these as a special hacks specific to a file
system.  Take a look at thread on xstat on linux-fsdevel for a more
general solution.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2016-05-30 16:03 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-05-29 17:14 [PATCH 0/6] nfs: add support for additional attributes and ioctl to access Anne Marie Merritt
2016-05-29 17:14 ` [PATCH 1/6] nfs: Add timecreate to nfs inode, along with corresponding bitfields, request, and decode xdr routines Anne Marie Merritt
2016-05-29 17:14 ` [PATCH 2/6] nfs: Add 'hidden' field " Anne Marie Merritt
2016-05-29 17:14 ` [PATCH 3/6] nfs: Add 'system' " Anne Marie Merritt
2016-05-29 17:14 ` [PATCH 4/6] nfs: Add 'archive' " Anne Marie Merritt
2016-05-29 17:14 ` [PATCH 5/6] nfs: Add timebackup " Anne Marie Merritt
2016-05-29 17:14 ` [PATCH 6/6] nfs: Add ioctl to retrieve timecreate, timebackup, 'hidden', 'archive', and 'system' fields from inode Anne Marie Merritt
2016-05-30 16:03 ` [PATCH 0/6] nfs: add support for additional attributes and ioctl to access Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).