Commit f43bf0bebed7c33b698a8a25f95812f9e87c3843

Authored by Trond Myklebust
1 parent 2a3f5fd459

NFS: Add a boot parameter to disable 64 bit inode numbers

This boot parameter will allow legacy 32-bit applications which call stat()
to continue to function even if the NFSv3/v4 server uses 64-bit inode
numbers.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

Showing 4 changed files with 36 additions and 2 deletions Side-by-side Diff

Documentation/kernel-parameters.txt
... ... @@ -1073,6 +1073,13 @@
1073 1073 [NFS] set the maximum lifetime for idmapper cache
1074 1074 entries.
1075 1075  
  1076 + nfs.enable_ino64=
  1077 + [NFS] enable 64-bit inode numbers.
  1078 + If zero, the NFS client will fake up a 32-bit inode
  1079 + number for the readdir() and stat() syscalls instead
  1080 + of returning the full 64-bit number.
  1081 + The default is to return 64-bit inode numbers.
  1082 +
1076 1083 nmi_watchdog= [KNL,BUGS=X86-32] Debugging features for SMP kernels
1077 1084  
1078 1085 no387 [BUGS=X86-32] Tells the kernel to use the 387 maths
... ... @@ -427,7 +427,8 @@
427 427 }
428 428  
429 429 res = filldir(dirent, entry->name, entry->len,
430   - file->f_pos, fileid, d_type);
  430 + file->f_pos, nfs_compat_user_ino64(fileid),
  431 + d_type);
431 432 if (res < 0)
432 433 break;
433 434 file->f_pos++;
... ... @@ -49,6 +49,11 @@
49 49  
50 50 #define NFSDBG_FACILITY NFSDBG_VFS
51 51  
  52 +#define NFS_64_BIT_INODE_NUMBERS_ENABLED 1
  53 +
  54 +/* Default is to see 64-bit inode numbers */
  55 +static int enable_ino64 = NFS_64_BIT_INODE_NUMBERS_ENABLED;
  56 +
52 57 static void nfs_invalidate_inode(struct inode *);
53 58 static int nfs_update_inode(struct inode *, struct nfs_fattr *);
54 59  
... ... @@ -62,6 +67,25 @@
62 67 return nfs_fileid_to_ino_t(fattr->fileid);
63 68 }
64 69  
  70 +/**
  71 + * nfs_compat_user_ino64 - returns the user-visible inode number
  72 + * @fileid: 64-bit fileid
  73 + *
  74 + * This function returns a 32-bit inode number if the boot parameter
  75 + * nfs.enable_ino64 is zero.
  76 + */
  77 +u64 nfs_compat_user_ino64(u64 fileid)
  78 +{
  79 + int ino;
  80 +
  81 + if (enable_ino64)
  82 + return fileid;
  83 + ino = fileid;
  84 + if (sizeof(ino) < sizeof(fileid))
  85 + ino ^= fileid >> (sizeof(fileid)-sizeof(ino)) * 8;
  86 + return ino;
  87 +}
  88 +
65 89 int nfs_write_inode(struct inode *inode, int sync)
66 90 {
67 91 int ret;
... ... @@ -456,7 +480,7 @@
456 480 err = nfs_revalidate_inode(NFS_SERVER(inode), inode);
457 481 if (!err) {
458 482 generic_fillattr(inode, stat);
459   - stat->ino = NFS_FILEID(inode);
  483 + stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode));
460 484 }
461 485 return err;
462 486 }
... ... @@ -1235,6 +1259,7 @@
1235 1259 /* Not quite true; I just maintain it */
1236 1260 MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
1237 1261 MODULE_LICENSE("GPL");
  1262 +module_param(enable_ino64, bool, 0644);
1238 1263  
1239 1264 module_init(init_nfs_fs)
1240 1265 module_exit(exit_nfs_fs)
include/linux/nfs_fs.h
... ... @@ -289,6 +289,7 @@
289 289 extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx);
290 290 extern void put_nfs_open_context(struct nfs_open_context *ctx);
291 291 extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, int mode);
  292 +extern u64 nfs_compat_user_ino64(u64 fileid);
292 293  
293 294 /* linux/net/ipv4/ipconfig.c: trims ip addr off front of name, too. */
294 295 extern __be32 root_nfs_parse_addr(char *name); /*__init*/