Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=fd00a8ff8e37815c9df49f5cf09786e441e1396b
Commit:     fd00a8ff8e37815c9df49f5cf09786e441e1396b
Parent:     3f43c6667acb4e02962b2829a4d4ebb6b6e6f70e
Author:     Chuck Lever <[EMAIL PROTECTED]>
AuthorDate: Mon Dec 10 14:57:38 2007 -0500
Committer:  Trond Myklebust <[EMAIL PROTECTED]>
CommitDate: Wed Jan 30 02:05:53 2008 -0500

    NFS: Add support for AF_INET6 addresses in nfs_compare_super()
    
    Refactor nfs_compare_super() and add AF_INET6 support.
    
    Replace the generic memcmp() to document explicitly what parts of the
    addresses must match in this check, and make the comparison independent
    of the lengths of both addresses.
    
    A side benefit is both tests are more computationally efficient than a
    memcmp().
    
    Signed-off-by: Chuck Lever <[EMAIL PROTECTED]>
    Signed-off-by: Trond Myklebust <[EMAIL PROTECTED]>
---
 fs/nfs/super.c |   43 ++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 75f3cbf..c3d8fcf 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -45,6 +45,8 @@
 #include <linux/nfs_idmap.h>
 #include <linux/vfs.h>
 #include <linux/inet.h>
+#include <linux/in6.h>
+#include <net/ipv6.h>
 #include <linux/nfs_xdr.h>
 #include <linux/magic.h>
 #include <linux/parser.h>
@@ -1326,15 +1328,50 @@ static int nfs_set_super(struct super_block *s, void 
*data)
        return ret;
 }
 
+static int nfs_compare_super_address(struct nfs_server *server1,
+                                    struct nfs_server *server2)
+{
+       struct sockaddr *sap1, *sap2;
+
+       sap1 = (struct sockaddr *)&server1->nfs_client->cl_addr;
+       sap2 = (struct sockaddr *)&server2->nfs_client->cl_addr;
+
+       if (sap1->sa_family != sap2->sa_family)
+               return 0;
+
+       switch (sap1->sa_family) {
+       case AF_INET: {
+               struct sockaddr_in *sin1 = (struct sockaddr_in *)sap1;
+               struct sockaddr_in *sin2 = (struct sockaddr_in *)sap2;
+               if (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr)
+                       return 0;
+               if (sin1->sin_port != sin2->sin_port)
+                       return 0;
+               break;
+       }
+       case AF_INET6: {
+               struct sockaddr_in6 *sin1 = (struct sockaddr_in6 *)sap1;
+               struct sockaddr_in6 *sin2 = (struct sockaddr_in6 *)sap2;
+               if (!ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr))
+                       return 0;
+               if (sin1->sin6_port != sin2->sin6_port)
+                       return 0;
+               break;
+       }
+       default:
+               return 0;
+       }
+
+       return 1;
+}
+
 static int nfs_compare_super(struct super_block *sb, void *data)
 {
        struct nfs_sb_mountdata *sb_mntdata = data;
        struct nfs_server *server = sb_mntdata->server, *old = NFS_SB(sb);
        int mntflags = sb_mntdata->mntflags;
 
-       if (memcmp(&old->nfs_client->cl_addr,
-                               &server->nfs_client->cl_addr,
-                               sizeof(old->nfs_client->cl_addr)) != 0)
+       if (!nfs_compare_super_address(old, server))
                return 0;
        /* Note: NFS_MOUNT_UNSHARED == NFS4_MOUNT_UNSHARED */
        if (old->flags & NFS_MOUNT_UNSHARED)
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to