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>
This commit is contained in:
Родитель
818d276ceb
Коммит
7a224228ed
|
@ -546,11 +546,11 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
|
|||
dentry->d_op = &afs_fs_dentry_operations;
|
||||
|
||||
d_add(dentry, inode);
|
||||
_leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%lu }",
|
||||
_leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%llu }",
|
||||
fid.vnode,
|
||||
fid.unique,
|
||||
dentry->d_inode->i_ino,
|
||||
dentry->d_inode->i_version);
|
||||
(unsigned long long)dentry->d_inode->i_version);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -630,9 +630,10 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
|
|||
* been deleted and replaced, and the original vnode ID has
|
||||
* been reused */
|
||||
if (fid.unique != vnode->fid.unique) {
|
||||
_debug("%s: file deleted (uq %u -> %u I:%lu)",
|
||||
_debug("%s: file deleted (uq %u -> %u I:%llu)",
|
||||
dentry->d_name.name, fid.unique,
|
||||
vnode->fid.unique, dentry->d_inode->i_version);
|
||||
vnode->fid.unique,
|
||||
(unsigned long long)dentry->d_inode->i_version);
|
||||
spin_lock(&vnode->lock);
|
||||
set_bit(AFS_VNODE_DELETED, &vnode->flags);
|
||||
spin_unlock(&vnode->lock);
|
||||
|
|
|
@ -301,7 +301,8 @@ int afs_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
|||
|
||||
inode = dentry->d_inode;
|
||||
|
||||
_enter("{ ino=%lu v=%lu }", inode->i_ino, inode->i_version);
|
||||
_enter("{ ino=%lu v=%llu }", inode->i_ino,
|
||||
(unsigned long long)inode->i_version);
|
||||
|
||||
generic_fillattr(inode, stat);
|
||||
return 0;
|
||||
|
|
22
fs/inode.c
22
fs/inode.c
|
@ -1242,6 +1242,23 @@ void touch_atime(struct vfsmount *mnt, struct dentry *dentry)
|
|||
}
|
||||
EXPORT_SYMBOL(touch_atime);
|
||||
|
||||
/**
|
||||
* inode_inc_iversion - increments i_version
|
||||
* @inode: inode that need to be updated
|
||||
*
|
||||
* Every time the inode is modified, the i_version field
|
||||
* will be incremented.
|
||||
* The filesystem has to be mounted with i_version flag
|
||||
*
|
||||
*/
|
||||
|
||||
void inode_inc_iversion(struct inode *inode)
|
||||
{
|
||||
spin_lock(&inode->i_lock);
|
||||
inode->i_version++;
|
||||
spin_unlock(&inode->i_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* file_update_time - update mtime and ctime time
|
||||
* @file: file accessed
|
||||
|
@ -1276,6 +1293,11 @@ void file_update_time(struct file *file)
|
|||
sync_it = 1;
|
||||
}
|
||||
|
||||
if (IS_I_VERSION(inode)) {
|
||||
inode_inc_iversion(inode);
|
||||
sync_it = 1;
|
||||
}
|
||||
|
||||
if (sync_it)
|
||||
mark_inode_dirty_sync(inode);
|
||||
}
|
||||
|
|
|
@ -124,6 +124,7 @@ extern int dir_notify_enable;
|
|||
#define MS_SHARED (1<<20) /* change to shared */
|
||||
#define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */
|
||||
#define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */
|
||||
#define MS_I_VERSION (1<<23) /* Update inode I_version field */
|
||||
#define MS_ACTIVE (1<<30)
|
||||
#define MS_NOUSER (1<<31)
|
||||
|
||||
|
@ -173,6 +174,7 @@ extern int dir_notify_enable;
|
|||
((inode)->i_flags & (S_SYNC|S_DIRSYNC)))
|
||||
#define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK)
|
||||
#define IS_NOATIME(inode) __IS_FLG(inode, MS_RDONLY|MS_NOATIME)
|
||||
#define IS_I_VERSION(inode) __IS_FLG(inode, MS_I_VERSION)
|
||||
|
||||
#define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA)
|
||||
#define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
|
||||
|
@ -599,7 +601,7 @@ struct inode {
|
|||
uid_t i_uid;
|
||||
gid_t i_gid;
|
||||
dev_t i_rdev;
|
||||
unsigned long i_version;
|
||||
u64 i_version;
|
||||
loff_t i_size;
|
||||
#ifdef __NEED_I_SIZE_ORDERED
|
||||
seqcount_t i_size_seqcount;
|
||||
|
@ -1394,6 +1396,7 @@ static inline void inode_dec_link_count(struct inode *inode)
|
|||
mark_inode_dirty(inode);
|
||||
}
|
||||
|
||||
extern void inode_inc_iversion(struct inode *inode);
|
||||
extern void touch_atime(struct vfsmount *mnt, struct dentry *dentry);
|
||||
static inline void file_accessed(struct file *file)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче