Patchwork [BUG:1972] nfs: Introduce nfs.enable-ino32 to support legacy 32-bit only apps

login
register
Submitter Shehjar Tikoo
Date 2010-10-29 11:08:13
Message ID <1288350493-21532-1-git-send-email-shehjart@gluster.com>
Download mbox | patch
Permalink /patch/5603/
State Accepted
Headers show

Comments

Shehjar Tikoo - 2010-10-29 11:08:13
From: Shehjar Tikoo <shehjart@gluster.com>


Signed-off-by: Shehjar Tikoo <shehjart@gluster.com>
---
 xlators/nfs/server/src/nfs-common.c   |   32 ++++++++++++++++++++++++++++++++
 xlators/nfs/server/src/nfs-common.h   |    3 +++
 xlators/nfs/server/src/nfs.c          |   26 ++++++++++++++++++++++++++
 xlators/nfs/server/src/nfs.h          |    4 ++++
 xlators/nfs/server/src/nfs3-helpers.c |   10 ++++++++--
 5 files changed, 73 insertions(+), 2 deletions(-)

Patch

diff --git a/xlators/nfs/server/src/nfs-common.c b/xlators/nfs/server/src/nfs-common.c
index 6628c29..ef2d1d3 100644
--- a/xlators/nfs/server/src/nfs-common.c
+++ b/xlators/nfs/server/src/nfs-common.c
@@ -393,3 +393,35 @@  err:
 
         return ret;
 }
+
+
+uint32_t
+nfs_hash_gfid (uuid_t gfid)
+{
+        uint32_t                hash = 0;
+        uint64_t                msb64 = 0;
+        uint64_t                lsb64 = 0;
+        uint32_t                a1 = 0;
+        uint32_t                a2 = 0;
+        uint32_t                a3 = 0;
+        uint32_t                a4 = 0;
+        uint32_t                b1 = 0;
+        uint32_t                b2 = 0;
+
+        memcpy (&msb64, &gfid[8], 8);
+        memcpy (&lsb64, &gfid[0], 8);
+
+        a1 = (msb64 << 32);
+        a2 = (msb64 >> 32);
+        a3 = (lsb64 << 32);
+        a4 = (lsb64 >> 32);
+
+        b1 = a1 ^ a4;
+        b2 = a2 ^ a3;
+
+        hash = b1 ^ b2;
+
+        return hash;
+}
+
+
diff --git a/xlators/nfs/server/src/nfs-common.h b/xlators/nfs/server/src/nfs-common.h
index 2c851b2..ec46336 100644
--- a/xlators/nfs/server/src/nfs-common.h
+++ b/xlators/nfs/server/src/nfs-common.h
@@ -76,4 +76,7 @@  nfs_entry_loc_fill (inode_table_t *itable, uuid_t pargfid, char *entry,
 
 extern int
 nfs_root_loc_fill (inode_table_t *itable, loc_t *loc);
+
+extern uint32_t
+nfs_hash_gfid (uuid_t gfid);
 #endif
diff --git a/xlators/nfs/server/src/nfs.c b/xlators/nfs/server/src/nfs.c
index 0afd85f..c81e483 100644
--- a/xlators/nfs/server/src/nfs.c
+++ b/xlators/nfs/server/src/nfs.c
@@ -520,6 +520,25 @@  nfs_init_state (xlator_t *this)
                         nfs->dynamicvolumes = GF_NFS_DVM_ON;
         }
 
+        nfs->enable_ino32 = 0;
+        if (dict_get (this->options, "nfs.enable-ino32")) {
+                ret = dict_get_str (this->options, "nfs.enable-ino32",
+                                    &optstr);
+                if (ret < 0) {
+                        gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse dict");
+                        goto free_foppool;
+                }
+
+                ret = gf_string2boolean (optstr, &boolt);
+                if (ret < 0) {
+                        gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse bool "
+                                "string");
+                        goto free_foppool;
+                }
+
+                if (boolt == _gf_true)
+                        nfs->enable_ino32 = 1;
+        }
         this->private = (void *)nfs;
         INIT_LIST_HEAD (&nfs->versions);
 
@@ -802,6 +821,13 @@  struct volume_options options[] = {
                          "If all subvolumes do not have this option set, an "
                          "error is reported."
         },
+        { .key  = {"nfs.enable-ino32"},
+          .type = GF_OPTION_TYPE_BOOL,
+          .description = "For nfs clients or apps that do not support 64-bit "
+                         "inode numbers, use this option to make NFS return "
+                         "32-bit inode numbers instead. Disabled by default so "
+                         "NFS returns 64-bit inode numbers by default."
+        },
 	{ .key  = {NULL} },
 };
 
diff --git a/xlators/nfs/server/src/nfs.h b/xlators/nfs/server/src/nfs.h
index 2464eb2..b6a1d4a 100644
--- a/xlators/nfs/server/src/nfs.h
+++ b/xlators/nfs/server/src/nfs.h
@@ -72,10 +72,14 @@  struct nfs_state {
         xlator_t                **initedxl;
         int                     subvols_started;
         int                     dynamicvolumes;
+        int                     enable_ino32;
 };
 
 #define gf_nfs_dvm_on(nfsstt)   (((struct nfs_state *)nfsstt)->dynamicvolumes == GF_NFS_DVM_ON)
 #define gf_nfs_dvm_off(nfsstt)  (((struct nfs_state *)nfsstt)->dynamicvolumes == GF_NFS_DVM_OFF)
+#define __gf_nfs_enable_ino32(nfsstt)     (((struct nfs_state *)nfsstt)->enable_ino32)
+#define gf_nfs_this_private     ((struct nfs_state *)((xlator_t *)THIS)->private)
+#define gf_nfs_enable_ino32()     (__gf_nfs_enable_ino32(gf_nfs_this_private))
 
 /* We have one gid more than the glusterfs maximum since we pass the primary
  * gid as the first element of the array.
diff --git a/xlators/nfs/server/src/nfs3-helpers.c b/xlators/nfs/server/src/nfs3-helpers.c
index 2a8b1b5..298a5c8 100644
--- a/xlators/nfs/server/src/nfs3-helpers.c
+++ b/xlators/nfs/server/src/nfs3-helpers.c
@@ -99,11 +99,17 @@  nfs3_iatt_gfid_to_ino (struct iatt *buf)
         if (!buf)
                 return 0;
 
-        if (buf->ia_ino != 1)
+        if ((buf->ia_ino != 1) && (buf->ia_gfid[15] != 1)) {
+                if (gf_nfs_enable_ino32()) {
+                        ino = (uint32_t )nfs_hash_gfid (buf->ia_gfid);
+                        goto hashout;
+                }
+
                 memcpy (&ino, &buf->ia_gfid[8], sizeof (uint64_t));
-        else
+        } else
                 ino = 1;
 
+hashout:
         return ino;
 }