aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-04-27 13:48:18 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-05-01 15:42:43 -0400
commit3a1556e8662cc425c433b463fcdae138908ca467 (patch)
treec4c16f7e33612c3ce3b504e9eedbf336d0c4bf20
parent6a4506c0b56889aaa15bcf50b3c75f46a8d0a3bd (diff)
NFSv2/v3: Simulate the change attribute
Use the ctime to simulate a change attribute for NFSv2 and NFSv3. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/client.c2
-rw-r--r--fs/nfs/internal.h12
-rw-r--r--fs/nfs/nfs2xdr.c2
-rw-r--r--fs/nfs/nfs3xdr.c3
-rw-r--r--include/linux/nfs_xdr.h6
5 files changed, 21 insertions, 4 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 60f7e4ec842c..a8f8de618d73 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -880,7 +880,7 @@ static int nfs_init_server(struct nfs_server *server,
880 server->options = data->options; 880 server->options = data->options;
881 server->caps |= NFS_CAP_HARDLINKS|NFS_CAP_SYMLINKS|NFS_CAP_FILEID| 881 server->caps |= NFS_CAP_HARDLINKS|NFS_CAP_SYMLINKS|NFS_CAP_FILEID|
882 NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER|NFS_CAP_OWNER_GROUP| 882 NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER|NFS_CAP_OWNER_GROUP|
883 NFS_CAP_ATIME|NFS_CAP_CTIME|NFS_CAP_MTIME; 883 NFS_CAP_ATIME|NFS_CAP_CTIME|NFS_CAP_MTIME|NFS_CAP_CHANGE_ATTR;
884 884
885 if (data->rsize) 885 if (data->rsize)
886 server->rsize = nfs_block_size(data->rsize, NULL); 886 server->rsize = nfs_block_size(data->rsize, NULL);
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 0fd1efaf1cff..1855e8fea423 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -493,3 +493,15 @@ unsigned int nfs_page_array_len(unsigned int base, size_t len)
493 PAGE_SIZE - 1) >> PAGE_SHIFT; 493 PAGE_SIZE - 1) >> PAGE_SHIFT;
494} 494}
495 495
496/*
497 * Convert a struct timespec into a 64-bit change attribute
498 *
499 * This does approximately the same thing as timespec_to_ns(),
500 * but for calculation efficiency, we multiply the seconds by
501 * 1024*1024*1024.
502 */
503static inline
504u64 nfs_timespec_to_change_attr(const struct timespec *ts)
505{
506 return ((u64)ts->tv_sec << 30) + ts->tv_nsec;
507}
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 1f56000fabbd..c99008e9d8a4 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -313,6 +313,8 @@ static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
313 p = xdr_decode_time(p, &fattr->atime); 313 p = xdr_decode_time(p, &fattr->atime);
314 p = xdr_decode_time(p, &fattr->mtime); 314 p = xdr_decode_time(p, &fattr->mtime);
315 xdr_decode_time(p, &fattr->ctime); 315 xdr_decode_time(p, &fattr->ctime);
316 fattr->change_attr = nfs_timespec_to_change_attr(&fattr->ctime);
317
316 return 0; 318 return 0;
317out_overflow: 319out_overflow:
318 print_overflow_msg(__func__, xdr); 320 print_overflow_msg(__func__, xdr);
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index 01e53e94f53d..ee284c2b2757 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -675,6 +675,7 @@ static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr)
675 p = xdr_decode_nfstime3(p, &fattr->atime); 675 p = xdr_decode_nfstime3(p, &fattr->atime);
676 p = xdr_decode_nfstime3(p, &fattr->mtime); 676 p = xdr_decode_nfstime3(p, &fattr->mtime);
677 xdr_decode_nfstime3(p, &fattr->ctime); 677 xdr_decode_nfstime3(p, &fattr->ctime);
678 fattr->change_attr = nfs_timespec_to_change_attr(&fattr->ctime);
678 679
679 fattr->valid |= NFS_ATTR_FATTR_V3; 680 fattr->valid |= NFS_ATTR_FATTR_V3;
680 return 0; 681 return 0;
@@ -725,12 +726,14 @@ static int decode_wcc_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
725 goto out_overflow; 726 goto out_overflow;
726 727
727 fattr->valid |= NFS_ATTR_FATTR_PRESIZE 728 fattr->valid |= NFS_ATTR_FATTR_PRESIZE
729 | NFS_ATTR_FATTR_PRECHANGE
728 | NFS_ATTR_FATTR_PREMTIME 730 | NFS_ATTR_FATTR_PREMTIME
729 | NFS_ATTR_FATTR_PRECTIME; 731 | NFS_ATTR_FATTR_PRECTIME;
730 732
731 p = xdr_decode_size3(p, &fattr->pre_size); 733 p = xdr_decode_size3(p, &fattr->pre_size);
732 p = xdr_decode_nfstime3(p, &fattr->pre_mtime); 734 p = xdr_decode_nfstime3(p, &fattr->pre_mtime);
733 xdr_decode_nfstime3(p, &fattr->pre_ctime); 735 xdr_decode_nfstime3(p, &fattr->pre_ctime);
736 fattr->pre_change_attr = nfs_timespec_to_change_attr(&fattr->pre_ctime);
734 737
735 return 0; 738 return 0;
736out_overflow: 739out_overflow:
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 6deb8f097c42..bc3680885428 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -106,14 +106,14 @@ struct nfs_fattr {
106 | NFS_ATTR_FATTR_FILEID \ 106 | NFS_ATTR_FATTR_FILEID \
107 | NFS_ATTR_FATTR_ATIME \ 107 | NFS_ATTR_FATTR_ATIME \
108 | NFS_ATTR_FATTR_MTIME \ 108 | NFS_ATTR_FATTR_MTIME \
109 | NFS_ATTR_FATTR_CTIME) 109 | NFS_ATTR_FATTR_CTIME \
110 | NFS_ATTR_FATTR_CHANGE)
110#define NFS_ATTR_FATTR_V2 (NFS_ATTR_FATTR \ 111#define NFS_ATTR_FATTR_V2 (NFS_ATTR_FATTR \
111 | NFS_ATTR_FATTR_BLOCKS_USED) 112 | NFS_ATTR_FATTR_BLOCKS_USED)
112#define NFS_ATTR_FATTR_V3 (NFS_ATTR_FATTR \ 113#define NFS_ATTR_FATTR_V3 (NFS_ATTR_FATTR \
113 | NFS_ATTR_FATTR_SPACE_USED) 114 | NFS_ATTR_FATTR_SPACE_USED)
114#define NFS_ATTR_FATTR_V4 (NFS_ATTR_FATTR \ 115#define NFS_ATTR_FATTR_V4 (NFS_ATTR_FATTR \
115 | NFS_ATTR_FATTR_SPACE_USED \ 116 | NFS_ATTR_FATTR_SPACE_USED)
116 | NFS_ATTR_FATTR_CHANGE)
117 117
118/* 118/*
119 * Info on the file system 119 * Info on the file system