* [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