Skip to content

Commit 40f45ab

Browse files
Trond MyklebustAnna Schumaker
authored andcommitted
NFS: Further fixes to attribute delegation a/mtime changes
When asked to set both an atime and an mtime to the current system time, ensure that the setting is atomic by calling inode_update_timestamps() only once with the appropriate flags. Fixes: e12912d ("NFSv4: Add support for delegated atime and mtime attributes") Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: Anna Schumaker <[email protected]>
1 parent d054c5e commit 40f45ab

File tree

1 file changed

+31
-18
lines changed

1 file changed

+31
-18
lines changed

fs/nfs/inode.c

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -628,23 +628,35 @@ nfs_fattr_fixup_delegated(struct inode *inode, struct nfs_fattr *fattr)
628628
}
629629
}
630630

631+
static void nfs_update_timestamps(struct inode *inode, unsigned int ia_valid)
632+
{
633+
enum file_time_flags time_flags = 0;
634+
unsigned int cache_flags = 0;
635+
636+
if (ia_valid & ATTR_MTIME) {
637+
time_flags |= S_MTIME | S_CTIME;
638+
cache_flags |= NFS_INO_INVALID_CTIME | NFS_INO_INVALID_MTIME;
639+
}
640+
if (ia_valid & ATTR_ATIME) {
641+
time_flags |= S_ATIME;
642+
cache_flags |= NFS_INO_INVALID_ATIME;
643+
}
644+
inode_update_timestamps(inode, time_flags);
645+
NFS_I(inode)->cache_validity &= ~cache_flags;
646+
}
647+
631648
void nfs_update_delegated_atime(struct inode *inode)
632649
{
633650
spin_lock(&inode->i_lock);
634-
if (nfs_have_delegated_atime(inode)) {
635-
inode_update_timestamps(inode, S_ATIME);
636-
NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_ATIME;
637-
}
651+
if (nfs_have_delegated_atime(inode))
652+
nfs_update_timestamps(inode, ATTR_ATIME);
638653
spin_unlock(&inode->i_lock);
639654
}
640655

641656
void nfs_update_delegated_mtime_locked(struct inode *inode)
642657
{
643-
if (nfs_have_delegated_mtime(inode)) {
644-
inode_update_timestamps(inode, S_CTIME | S_MTIME);
645-
NFS_I(inode)->cache_validity &= ~(NFS_INO_INVALID_CTIME |
646-
NFS_INO_INVALID_MTIME);
647-
}
658+
if (nfs_have_delegated_mtime(inode))
659+
nfs_update_timestamps(inode, ATTR_MTIME);
648660
}
649661

650662
void nfs_update_delegated_mtime(struct inode *inode)
@@ -682,15 +694,16 @@ nfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
682694
attr->ia_valid &= ~ATTR_SIZE;
683695
}
684696

685-
if (nfs_have_delegated_mtime(inode)) {
686-
if (attr->ia_valid & ATTR_MTIME) {
687-
nfs_update_delegated_mtime(inode);
688-
attr->ia_valid &= ~ATTR_MTIME;
689-
}
690-
if (attr->ia_valid & ATTR_ATIME) {
691-
nfs_update_delegated_atime(inode);
692-
attr->ia_valid &= ~ATTR_ATIME;
693-
}
697+
if (nfs_have_delegated_mtime(inode) && attr->ia_valid & ATTR_MTIME) {
698+
spin_lock(&inode->i_lock);
699+
nfs_update_timestamps(inode, attr->ia_valid);
700+
spin_unlock(&inode->i_lock);
701+
attr->ia_valid &= ~(ATTR_MTIME | ATTR_ATIME);
702+
} else if (nfs_have_delegated_atime(inode) &&
703+
attr->ia_valid & ATTR_ATIME &&
704+
!(attr->ia_valid & ATTR_MTIME)) {
705+
nfs_update_delegated_atime(inode);
706+
attr->ia_valid &= ~ATTR_ATIME;
694707
}
695708

696709
/* Optimization: if the end result is no change, don't RPC */

0 commit comments

Comments
 (0)