]> git.neil.brown.name Git - LaFS.git/commitdiff
getattr: make sure atime reported is repeatable.
authorNeilBrown <neilb@suse.de>
Fri, 4 Mar 2011 23:44:22 +0000 (10:44 +1100)
committerNeilBrown <neilb@suse.de>
Fri, 4 Mar 2011 23:44:22 +0000 (10:44 +1100)
We cannot allow getattr to simply report i_atime as we may not
store it with sufficient granularity.

So always recompute for the stored values, which are kept in
the in-mem inode.

Signed-off-by: NeilBrown <neilb@suse.de>
dir.c
file.c
inode.c
lafs.h
link.c

diff --git a/dir.c b/dir.c
index e795aaf33730c5a537044ceaf40bd16adcc49d07..beab1b3b33baf20c3884ead8c065d9a37c14611a 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -1813,7 +1813,7 @@ lafs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
 static int lafs_getattr_dir(struct vfsmount *mnt, struct dentry *dentry,
                            struct kstat *stat)
 {
-       generic_fillattr(dentry->d_inode, stat);
+       lafs_fillattr(dentry->d_inode, stat);
        /* hide 'holes' in directories by making the size match
         * the number of allocated blocks.
         */
diff --git a/file.c b/file.c
index 779c93b4de9cf3a430b636efff449d0901d9f883..a92f559afb29eb5e1e3ecc8b00d9a8be8aaa3dc2 100644 (file)
--- a/file.c
+++ b/file.c
@@ -443,6 +443,27 @@ lafs_sync_file(struct file *file, struct dentry *de, int datasync)
        return err;
 }
 
+void lafs_fillattr(struct inode *ino, struct kstat *stat)
+{
+       /* This makes sure the reported 'atime' is a time that
+        * we can store and return after a clean restart
+        */
+       generic_fillattr(ino, stat);
+
+       if (!test_bit(I_AccessTime, &LAFSI(ino)->iflags))
+               return;
+
+       stat->atime = LAFSI(ino)->md.file.i_accesstime;
+       lafs_add_atime_offset(&stat->atime, LAFSI(ino)->md.file.atime_offset);
+}
+
+int lafs_getattr(struct vfsmount *mnt, struct dentry *dentry,
+                struct kstat *stat)
+{
+       lafs_fillattr(dentry->d_inode, stat);
+       return 0;
+}
+
 const struct file_operations lafs_file_file_operations = {
        .llseek         = generic_file_llseek,
        .read           = do_sync_read,
@@ -460,6 +481,7 @@ const struct file_operations lafs_file_file_operations = {
 
 const struct inode_operations lafs_file_ino_operations = {
        .setattr        = lafs_setattr,
+       .getattr        = lafs_getattr,
 };
 
 const struct address_space_operations lafs_file_aops = {
diff --git a/inode.c b/inode.c
index 1cb204037f9d471e5d211404ef944d44a35f9995..956b680cbea56ae976afc8d09437fba3903181ad 100644 (file)
--- a/inode.c
+++ b/inode.c
@@ -2023,5 +2023,6 @@ void lafs_truncate(struct inode *ino)
 
 const struct inode_operations lafs_special_ino_operations = {
        .setattr        = lafs_setattr,
+       .getattr        = lafs_getattr,
        .truncate       = lafs_truncate,
 };
diff --git a/lafs.h b/lafs.h
index b9b7804fc53a6cb6b66a8facff4369d7cf155bf4..1be035488c365354c9a9da9708422e8d86bf4089 100644 (file)
--- a/lafs.h
+++ b/lafs.h
@@ -181,6 +181,9 @@ int has_ref(struct block *b, char *ref);
 #endif
 
 int lafs_setattr(struct dentry *dentry, struct iattr *attr);
+int lafs_getattr(struct vfsmount *mnt, struct dentry *denty,
+                struct kstat *stat);
+void lafs_fillattr(struct inode *ino, struct kstat *stat);
 
 char *strblk(struct block *b);
 int lafs_print_tree(struct block *b, int depth);
diff --git a/link.c b/link.c
index 677ebb306bbc5a936ccb4a83f40b56a664c06163..c9172cffa6d647cee016c4826d0786d63312568d 100644 (file)
--- a/link.c
+++ b/link.c
@@ -14,4 +14,5 @@ const struct inode_operations lafs_link_ino_operations = {
        .readlink       = generic_readlink,
        .follow_link    = page_follow_link_light,
        .put_link       = page_put_link,
+       .getattr        = lafs_getattr,
 };