diff options
author | Jean Noel Cordenner <jean-noel.cordenner@bull.net> | 2008-01-28 23:58:27 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2008-01-28 23:58:27 -0500 |
commit | 7a224228ed79d587ece2304869000aad1b8e97dd (patch) | |
tree | f2b299f5a5d04cf8d3d0ef10ff264bd34943f90e | |
parent | 818d276ceb83aa9fdebb5e0a53188290312de987 (diff) |
vfs: Add 64 bit i_version support
The i_version field of the inode is changed to be a 64-bit counter that
is set on every inode creation and that is incremented every time the
inode data is modified (similarly to the "ctime" time-stamp).
The aim is to fulfill a NFSv4 requirement for rfc3530.
This first part concerns the vfs, it converts the 32-bit i_version in
the generic inode to a 64-bit, a flag is added in the super block in
order to check if the feature is enabled and the i_version is
incremented in the vfs.
Signed-off-by: Mingming Cao <cmm@us.ibm.com>
Signed-off-by: Jean Noel Cordenner <jean-noel.cordenner@bull.net>
Signed-off-by: Kalpak Shah <kalpak@clusterfs.com>
-rw-r--r-- | fs/afs/dir.c | 9 | ||||
-rw-r--r-- | fs/afs/inode.c | 3 | ||||
-rw-r--r-- | fs/inode.c | 22 | ||||
-rw-r--r-- | include/linux/fs.h | 5 |
4 files changed, 33 insertions, 6 deletions
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 33fe39ad4e03..0cc3597c1197 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
@@ -546,11 +546,11 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, | |||
546 | dentry->d_op = &afs_fs_dentry_operations; | 546 | dentry->d_op = &afs_fs_dentry_operations; |
547 | 547 | ||
548 | d_add(dentry, inode); | 548 | d_add(dentry, inode); |
549 | _leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%lu }", | 549 | _leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%llu }", |
550 | fid.vnode, | 550 | fid.vnode, |
551 | fid.unique, | 551 | fid.unique, |
552 | dentry->d_inode->i_ino, | 552 | dentry->d_inode->i_ino, |
553 | dentry->d_inode->i_version); | 553 | (unsigned long long)dentry->d_inode->i_version); |
554 | 554 | ||
555 | return NULL; | 555 | return NULL; |
556 | } | 556 | } |
@@ -630,9 +630,10 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
630 | * been deleted and replaced, and the original vnode ID has | 630 | * been deleted and replaced, and the original vnode ID has |
631 | * been reused */ | 631 | * been reused */ |
632 | if (fid.unique != vnode->fid.unique) { | 632 | if (fid.unique != vnode->fid.unique) { |
633 | _debug("%s: file deleted (uq %u -> %u I:%lu)", | 633 | _debug("%s: file deleted (uq %u -> %u I:%llu)", |
634 | dentry->d_name.name, fid.unique, | 634 | dentry->d_name.name, fid.unique, |
635 | vnode->fid.unique, dentry->d_inode->i_version); | 635 | vnode->fid.unique, |
636 | (unsigned long long)dentry->d_inode->i_version); | ||
636 | spin_lock(&vnode->lock); | 637 | spin_lock(&vnode->lock); |
637 | set_bit(AFS_VNODE_DELETED, &vnode->flags); | 638 | set_bit(AFS_VNODE_DELETED, &vnode->flags); |
638 | spin_unlock(&vnode->lock); | 639 | spin_unlock(&vnode->lock); |
diff --git a/fs/afs/inode.c b/fs/afs/inode.c index d196840127c6..84750c8e9f95 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c | |||
@@ -301,7 +301,8 @@ int afs_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
301 | 301 | ||
302 | inode = dentry->d_inode; | 302 | inode = dentry->d_inode; |
303 | 303 | ||
304 | _enter("{ ino=%lu v=%lu }", inode->i_ino, inode->i_version); | 304 | _enter("{ ino=%lu v=%llu }", inode->i_ino, |
305 | (unsigned long long)inode->i_version); | ||
305 | 306 | ||
306 | generic_fillattr(inode, stat); | 307 | generic_fillattr(inode, stat); |
307 | return 0; | 308 | return 0; |
diff --git a/fs/inode.c b/fs/inode.c index ed35383d0b6c..b48324a94c2b 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -1243,6 +1243,23 @@ void touch_atime(struct vfsmount *mnt, struct dentry *dentry) | |||
1243 | EXPORT_SYMBOL(touch_atime); | 1243 | EXPORT_SYMBOL(touch_atime); |
1244 | 1244 | ||
1245 | /** | 1245 | /** |
1246 | * inode_inc_iversion - increments i_version | ||
1247 | * @inode: inode that need to be updated | ||
1248 | * | ||
1249 | * Every time the inode is modified, the i_version field | ||
1250 | * will be incremented. | ||
1251 | * The filesystem has to be mounted with i_version flag | ||
1252 | * | ||
1253 | */ | ||
1254 | |||
1255 | void inode_inc_iversion(struct inode *inode) | ||
1256 | { | ||
1257 | spin_lock(&inode->i_lock); | ||
1258 | inode->i_version++; | ||
1259 | spin_unlock(&inode->i_lock); | ||
1260 | } | ||
1261 | |||
1262 | /** | ||
1246 | * file_update_time - update mtime and ctime time | 1263 | * file_update_time - update mtime and ctime time |
1247 | * @file: file accessed | 1264 | * @file: file accessed |
1248 | * | 1265 | * |
@@ -1276,6 +1293,11 @@ void file_update_time(struct file *file) | |||
1276 | sync_it = 1; | 1293 | sync_it = 1; |
1277 | } | 1294 | } |
1278 | 1295 | ||
1296 | if (IS_I_VERSION(inode)) { | ||
1297 | inode_inc_iversion(inode); | ||
1298 | sync_it = 1; | ||
1299 | } | ||
1300 | |||
1279 | if (sync_it) | 1301 | if (sync_it) |
1280 | mark_inode_dirty_sync(inode); | 1302 | mark_inode_dirty_sync(inode); |
1281 | } | 1303 | } |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 21398a5d688d..9608839552b3 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -124,6 +124,7 @@ extern int dir_notify_enable; | |||
124 | #define MS_SHARED (1<<20) /* change to shared */ | 124 | #define MS_SHARED (1<<20) /* change to shared */ |
125 | #define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */ | 125 | #define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */ |
126 | #define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */ | 126 | #define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */ |
127 | #define MS_I_VERSION (1<<23) /* Update inode I_version field */ | ||
127 | #define MS_ACTIVE (1<<30) | 128 | #define MS_ACTIVE (1<<30) |
128 | #define MS_NOUSER (1<<31) | 129 | #define MS_NOUSER (1<<31) |
129 | 130 | ||
@@ -173,6 +174,7 @@ extern int dir_notify_enable; | |||
173 | ((inode)->i_flags & (S_SYNC|S_DIRSYNC))) | 174 | ((inode)->i_flags & (S_SYNC|S_DIRSYNC))) |
174 | #define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK) | 175 | #define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK) |
175 | #define IS_NOATIME(inode) __IS_FLG(inode, MS_RDONLY|MS_NOATIME) | 176 | #define IS_NOATIME(inode) __IS_FLG(inode, MS_RDONLY|MS_NOATIME) |
177 | #define IS_I_VERSION(inode) __IS_FLG(inode, MS_I_VERSION) | ||
176 | 178 | ||
177 | #define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA) | 179 | #define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA) |
178 | #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND) | 180 | #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND) |
@@ -599,7 +601,7 @@ struct inode { | |||
599 | uid_t i_uid; | 601 | uid_t i_uid; |
600 | gid_t i_gid; | 602 | gid_t i_gid; |
601 | dev_t i_rdev; | 603 | dev_t i_rdev; |
602 | unsigned long i_version; | 604 | u64 i_version; |
603 | loff_t i_size; | 605 | loff_t i_size; |
604 | #ifdef __NEED_I_SIZE_ORDERED | 606 | #ifdef __NEED_I_SIZE_ORDERED |
605 | seqcount_t i_size_seqcount; | 607 | seqcount_t i_size_seqcount; |
@@ -1394,6 +1396,7 @@ static inline void inode_dec_link_count(struct inode *inode) | |||
1394 | mark_inode_dirty(inode); | 1396 | mark_inode_dirty(inode); |
1395 | } | 1397 | } |
1396 | 1398 | ||
1399 | extern void inode_inc_iversion(struct inode *inode); | ||
1397 | extern void touch_atime(struct vfsmount *mnt, struct dentry *dentry); | 1400 | extern void touch_atime(struct vfsmount *mnt, struct dentry *dentry); |
1398 | static inline void file_accessed(struct file *file) | 1401 | static inline void file_accessed(struct file *file) |
1399 | { | 1402 | { |