Loading fs/nfsd/nfsfh.c +27 −0 Original line number Diff line number Diff line Loading @@ -748,3 +748,30 @@ enum fsid_source fsid_source(const struct svc_fh *fhp) return FSIDSOURCE_UUID; return FSIDSOURCE_DEV; } /* * We could use i_version alone as the change attribute. However, * i_version can go backwards after a reboot. On its own that doesn't * necessarily cause a problem, but if i_version goes backwards and then * is incremented again it could reuse a value that was previously used * before boot, and a client who queried the two values might * incorrectly assume nothing changed. * * By using both ctime and the i_version counter we guarantee that as * long as time doesn't go backwards we never reuse an old value. */ u64 nfsd4_change_attribute(struct kstat *stat, struct inode *inode) { if (inode->i_sb->s_export_op->fetch_iversion) return inode->i_sb->s_export_op->fetch_iversion(inode); else if (IS_I_VERSION(inode)) { u64 chattr; chattr = stat->ctime.tv_sec; chattr <<= 30; chattr += stat->ctime.tv_nsec; chattr += inode_query_iversion(inode); return chattr; } else return time_to_chattr(&stat->ctime); } fs/nfsd/nfsfh.h +1 −28 Original line number Diff line number Diff line Loading @@ -293,34 +293,7 @@ static inline void fh_clear_pre_post_attrs(struct svc_fh *fhp) fhp->fh_pre_saved = false; } /* * We could use i_version alone as the change attribute. However, * i_version can go backwards after a reboot. On its own that doesn't * necessarily cause a problem, but if i_version goes backwards and then * is incremented again it could reuse a value that was previously used * before boot, and a client who queried the two values might * incorrectly assume nothing changed. * * By using both ctime and the i_version counter we guarantee that as * long as time doesn't go backwards we never reuse an old value. */ static inline u64 nfsd4_change_attribute(struct kstat *stat, struct inode *inode) { if (inode->i_sb->s_export_op->fetch_iversion) return inode->i_sb->s_export_op->fetch_iversion(inode); else if (IS_I_VERSION(inode)) { u64 chattr; chattr = stat->ctime.tv_sec; chattr <<= 30; chattr += stat->ctime.tv_nsec; chattr += inode_query_iversion(inode); return chattr; } else return time_to_chattr(&stat->ctime); } u64 nfsd4_change_attribute(struct kstat *stat, struct inode *inode); extern void fh_fill_pre_attrs(struct svc_fh *fhp); extern void fh_fill_post_attrs(struct svc_fh *fhp); extern void fh_fill_both_attrs(struct svc_fh *fhp); Loading Loading
fs/nfsd/nfsfh.c +27 −0 Original line number Diff line number Diff line Loading @@ -748,3 +748,30 @@ enum fsid_source fsid_source(const struct svc_fh *fhp) return FSIDSOURCE_UUID; return FSIDSOURCE_DEV; } /* * We could use i_version alone as the change attribute. However, * i_version can go backwards after a reboot. On its own that doesn't * necessarily cause a problem, but if i_version goes backwards and then * is incremented again it could reuse a value that was previously used * before boot, and a client who queried the two values might * incorrectly assume nothing changed. * * By using both ctime and the i_version counter we guarantee that as * long as time doesn't go backwards we never reuse an old value. */ u64 nfsd4_change_attribute(struct kstat *stat, struct inode *inode) { if (inode->i_sb->s_export_op->fetch_iversion) return inode->i_sb->s_export_op->fetch_iversion(inode); else if (IS_I_VERSION(inode)) { u64 chattr; chattr = stat->ctime.tv_sec; chattr <<= 30; chattr += stat->ctime.tv_nsec; chattr += inode_query_iversion(inode); return chattr; } else return time_to_chattr(&stat->ctime); }
fs/nfsd/nfsfh.h +1 −28 Original line number Diff line number Diff line Loading @@ -293,34 +293,7 @@ static inline void fh_clear_pre_post_attrs(struct svc_fh *fhp) fhp->fh_pre_saved = false; } /* * We could use i_version alone as the change attribute. However, * i_version can go backwards after a reboot. On its own that doesn't * necessarily cause a problem, but if i_version goes backwards and then * is incremented again it could reuse a value that was previously used * before boot, and a client who queried the two values might * incorrectly assume nothing changed. * * By using both ctime and the i_version counter we guarantee that as * long as time doesn't go backwards we never reuse an old value. */ static inline u64 nfsd4_change_attribute(struct kstat *stat, struct inode *inode) { if (inode->i_sb->s_export_op->fetch_iversion) return inode->i_sb->s_export_op->fetch_iversion(inode); else if (IS_I_VERSION(inode)) { u64 chattr; chattr = stat->ctime.tv_sec; chattr <<= 30; chattr += stat->ctime.tv_nsec; chattr += inode_query_iversion(inode); return chattr; } else return time_to_chattr(&stat->ctime); } u64 nfsd4_change_attribute(struct kstat *stat, struct inode *inode); extern void fh_fill_pre_attrs(struct svc_fh *fhp); extern void fh_fill_post_attrs(struct svc_fh *fhp); extern void fh_fill_both_attrs(struct svc_fh *fhp); Loading