From 08038203fa3014243d9287af6140ad13f2bd5599 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 5 Mar 2011 10:44:22 +1100 Subject: [PATCH] getattr: make sure atime reported is repeatable. 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 --- dir.c | 2 +- file.c | 22 ++++++++++++++++++++++ inode.c | 1 + lafs.h | 3 +++ link.c | 1 + 5 files changed, 28 insertions(+), 1 deletion(-) diff --git a/dir.c b/dir.c index e795aaf..beab1b3 100644 --- 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 779c93b..a92f559 100644 --- 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 1cb2040..956b680 100644 --- 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 b9b7804..1be0354 100644 --- 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 677ebb3..c9172cf 100644 --- 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, }; -- 2.39.5