From: David Howells Building on the previous patch that expanded the inode numbers in struct kstat and filldir_t to an obligate 64-bits, make NFS represent 64-bit fileids as 64-bit inode numbers rather than compressing them down to 32-bits. Signed-off-by: David Howells Cc: Trond Myklebust Cc: Al Viro Signed-off-by: Andrew Morton --- fs/nfs/dir.c | 6 +++--- fs/nfs/inode.c | 21 ++++++++++----------- include/linux/nfs_fs.h | 9 --------- 3 files changed, 13 insertions(+), 23 deletions(-) diff -puN fs/nfs/dir.c~nfs-represent-64-bit-fileids-as-64-bit-inode-numbers-on-32-bit-systems fs/nfs/dir.c --- a/fs/nfs/dir.c~nfs-represent-64-bit-fileids-as-64-bit-inode-numbers-on-32-bit-systems +++ a/fs/nfs/dir.c @@ -398,7 +398,7 @@ int nfs_do_filldir(nfs_readdir_descripto struct file *file = desc->file; struct nfs_entry *entry = desc->entry; struct dentry *dentry = NULL; - unsigned long fileid; + u64 fileid; int loop_count = 0, res; @@ -409,7 +409,7 @@ int nfs_do_filldir(nfs_readdir_descripto unsigned d_type = DT_UNKNOWN; /* Note: entry->prev_cookie contains the cookie for * retrieving the current dirent on the server */ - fileid = nfs_fileid_to_ino_t(entry->ino); + fileid = entry->ino; /* Get a dentry if we have one */ if (dentry != NULL) @@ -419,7 +419,7 @@ int nfs_do_filldir(nfs_readdir_descripto /* Use readdirplus info */ if (dentry != NULL && dentry->d_inode != NULL) { d_type = dt_type(dentry->d_inode); - fileid = dentry->d_inode->i_ino; + fileid = NFS_FILEID(dentry->d_inode); } res = filldir(dirent, entry->name, entry->len, diff -puN fs/nfs/inode.c~nfs-represent-64-bit-fileids-as-64-bit-inode-numbers-on-32-bit-systems fs/nfs/inode.c --- a/fs/nfs/inode.c~nfs-represent-64-bit-fileids-as-64-bit-inode-numbers-on-32-bit-systems +++ a/fs/nfs/inode.c @@ -57,12 +57,6 @@ static void nfs_zap_acl_cache(struct ino static kmem_cache_t * nfs_inode_cachep; -static inline unsigned long -nfs_fattr_to_ino_t(struct nfs_fattr *fattr) -{ - return nfs_fileid_to_ino_t(fattr->fileid); -} - int nfs_write_inode(struct inode *inode, int sync) { int flags = sync ? FLUSH_SYNC : 0; @@ -220,7 +214,9 @@ nfs_fhget(struct super_block *sb, struct goto out_no_inode; } - hash = nfs_fattr_to_ino_t(fattr); + hash = fattr->fileid; + if (sizeof(hash) < sizeof(u64)) + hash ^= fattr->fileid >> (sizeof(u64) - sizeof(ino_t)) * 8; inode = iget5_locked(sb, hash, nfs_find_actor, nfs_init_locked, &desc); if (inode == NULL) { @@ -231,9 +227,10 @@ nfs_fhget(struct super_block *sb, struct if (inode->i_state & I_NEW) { struct nfs_inode *nfsi = NFS_I(inode); - /* We set i_ino for the few things that still rely on it, - * such as stat(2) */ - inode->i_ino = hash; + /* We set i_ino for the few things that still rely on it, such + * as printing messages; stat and filldir use the fileid + * directly since i_ino may not be large enough */ + inode->i_ino = fattr->fileid; /* We can't support update_atime(), since the server will reset it */ inode->i_flags |= S_NOATIME|S_NOCMTIME; @@ -440,8 +437,10 @@ int nfs_getattr(struct vfsmount *mnt, st err = __nfs_revalidate_inode(NFS_SERVER(inode), inode); else err = nfs_revalidate_inode(NFS_SERVER(inode), inode); - if (!err) + if (!err) { generic_fillattr(inode, stat); + stat->ino = NFS_FILEID(inode); + } return err; } diff -puN include/linux/nfs_fs.h~nfs-represent-64-bit-fileids-as-64-bit-inode-numbers-on-32-bit-systems include/linux/nfs_fs.h --- a/include/linux/nfs_fs.h~nfs-represent-64-bit-fileids-as-64-bit-inode-numbers-on-32-bit-systems +++ a/include/linux/nfs_fs.h @@ -542,15 +542,6 @@ nfs_size_to_loff_t(__u64 size) return (loff_t) size; } -static inline ino_t -nfs_fileid_to_ino_t(u64 fileid) -{ - ino_t ino = (ino_t) fileid; - if (sizeof(ino_t) < sizeof(u64)) - ino ^= fileid >> (sizeof(u64)-sizeof(ino_t)) * 8; - return ino; -} - /* NFS root */ extern void * nfs_root_data(void); _