These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / fs / nfs / client.c
index 892aeff..d6d5d2a 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/stat.h>
 #include <linux/errno.h>
 #include <linux/unistd.h>
+#include <linux/sunrpc/addr.h>
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/stats.h>
 #include <linux/sunrpc/metrics.h>
@@ -285,116 +286,6 @@ void nfs_put_client(struct nfs_client *clp)
 }
 EXPORT_SYMBOL_GPL(nfs_put_client);
 
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-/*
- * Test if two ip6 socket addresses refer to the same socket by
- * comparing relevant fields. The padding bytes specifically, are not
- * compared. sin6_flowinfo is not compared because it only affects QoS
- * and sin6_scope_id is only compared if the address is "link local"
- * because "link local" addresses need only be unique to a specific
- * link. Conversely, ordinary unicast addresses might have different
- * sin6_scope_id.
- *
- * The caller should ensure both socket addresses are AF_INET6.
- */
-static int nfs_sockaddr_match_ipaddr6(const struct sockaddr *sa1,
-                                     const struct sockaddr *sa2)
-{
-       const struct sockaddr_in6 *sin1 = (const struct sockaddr_in6 *)sa1;
-       const struct sockaddr_in6 *sin2 = (const struct sockaddr_in6 *)sa2;
-
-       if (!ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr))
-               return 0;
-       else if (ipv6_addr_type(&sin1->sin6_addr) & IPV6_ADDR_LINKLOCAL)
-               return sin1->sin6_scope_id == sin2->sin6_scope_id;
-
-       return 1;
-}
-#else  /* !defined(CONFIG_IPV6) && !defined(CONFIG_IPV6_MODULE) */
-static int nfs_sockaddr_match_ipaddr6(const struct sockaddr *sa1,
-                                     const struct sockaddr *sa2)
-{
-       return 0;
-}
-#endif
-
-/*
- * Test if two ip4 socket addresses refer to the same socket, by
- * comparing relevant fields. The padding bytes specifically, are
- * not compared.
- *
- * The caller should ensure both socket addresses are AF_INET.
- */
-static int nfs_sockaddr_match_ipaddr4(const struct sockaddr *sa1,
-                                     const struct sockaddr *sa2)
-{
-       const struct sockaddr_in *sin1 = (const struct sockaddr_in *)sa1;
-       const struct sockaddr_in *sin2 = (const struct sockaddr_in *)sa2;
-
-       return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr;
-}
-
-static int nfs_sockaddr_cmp_ip6(const struct sockaddr *sa1,
-                               const struct sockaddr *sa2)
-{
-       const struct sockaddr_in6 *sin1 = (const struct sockaddr_in6 *)sa1;
-       const struct sockaddr_in6 *sin2 = (const struct sockaddr_in6 *)sa2;
-
-       return nfs_sockaddr_match_ipaddr6(sa1, sa2) &&
-               (sin1->sin6_port == sin2->sin6_port);
-}
-
-static int nfs_sockaddr_cmp_ip4(const struct sockaddr *sa1,
-                               const struct sockaddr *sa2)
-{
-       const struct sockaddr_in *sin1 = (const struct sockaddr_in *)sa1;
-       const struct sockaddr_in *sin2 = (const struct sockaddr_in *)sa2;
-
-       return nfs_sockaddr_match_ipaddr4(sa1, sa2) &&
-               (sin1->sin_port == sin2->sin_port);
-}
-
-#if defined(CONFIG_NFS_V4_1)
-/*
- * Test if two socket addresses represent the same actual socket,
- * by comparing (only) relevant fields, excluding the port number.
- */
-int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1,
-                             const struct sockaddr *sa2)
-{
-       if (sa1->sa_family != sa2->sa_family)
-               return 0;
-
-       switch (sa1->sa_family) {
-       case AF_INET:
-               return nfs_sockaddr_match_ipaddr4(sa1, sa2);
-       case AF_INET6:
-               return nfs_sockaddr_match_ipaddr6(sa1, sa2);
-       }
-       return 0;
-}
-EXPORT_SYMBOL_GPL(nfs_sockaddr_match_ipaddr);
-#endif /* CONFIG_NFS_V4_1 */
-
-/*
- * Test if two socket addresses represent the same actual socket,
- * by comparing (only) relevant fields, including the port number.
- */
-static int nfs_sockaddr_cmp(const struct sockaddr *sa1,
-                           const struct sockaddr *sa2)
-{
-       if (sa1->sa_family != sa2->sa_family)
-               return 0;
-
-       switch (sa1->sa_family) {
-       case AF_INET:
-               return nfs_sockaddr_cmp_ip4(sa1, sa2);
-       case AF_INET6:
-               return nfs_sockaddr_cmp_ip6(sa1, sa2);
-       }
-       return 0;
-}
-
 /*
  * Find an nfs_client on the list that matches the initialisation data
  * that is supplied.
@@ -421,7 +312,7 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
                if (clp->cl_minorversion != data->minorversion)
                        continue;
                /* Match the full socket address */
-               if (!nfs_sockaddr_cmp(sap, clap))
+               if (!rpc_cmp_addr_port(sap, clap))
                        continue;
 
                atomic_inc(&clp->cl_count);
@@ -775,7 +666,7 @@ static int nfs_init_server(struct nfs_server *server,
        server->options = data->options;
        server->caps |= NFS_CAP_HARDLINKS|NFS_CAP_SYMLINKS|NFS_CAP_FILEID|
                NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER|NFS_CAP_OWNER_GROUP|
-               NFS_CAP_ATIME|NFS_CAP_CTIME|NFS_CAP_MTIME|NFS_CAP_CHANGE_ATTR;
+               NFS_CAP_ATIME|NFS_CAP_CTIME|NFS_CAP_MTIME;
 
        if (data->rsize)
                server->rsize = nfs_block_size(data->rsize, NULL);
@@ -825,7 +716,6 @@ error:
  * Load up the server record from information gained in an fsinfo record
  */
 static void nfs_server_set_fsinfo(struct nfs_server *server,
-                                 struct nfs_fh *mntfh,
                                  struct nfs_fsinfo *fsinfo)
 {
        unsigned long max_rpc_payload;
@@ -874,6 +764,7 @@ static void nfs_server_set_fsinfo(struct nfs_server *server,
 
        server->time_delta = fsinfo->time_delta;
 
+       server->clone_blksize = fsinfo->clone_blksize;
        /* We're airborne Set socket buffersize */
        rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
 }
@@ -901,7 +792,7 @@ int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs
        if (error < 0)
                goto out_error;
 
-       nfs_server_set_fsinfo(server, mntfh, &fsinfo);
+       nfs_server_set_fsinfo(server, &fsinfo);
 
        /* Get some general file system info */
        if (server->namelen == 0) {
@@ -1193,8 +1084,6 @@ void nfs_clients_init(struct net *net)
 }
 
 #ifdef CONFIG_PROC_FS
-static struct proc_dir_entry *proc_fs_nfs;
-
 static int nfs_server_list_open(struct inode *inode, struct file *file);
 static void *nfs_server_list_start(struct seq_file *p, loff_t *pos);
 static void *nfs_server_list_next(struct seq_file *p, void *v, loff_t *pos);
@@ -1364,27 +1253,29 @@ static int nfs_volume_list_show(struct seq_file *m, void *v)
 {
        struct nfs_server *server;
        struct nfs_client *clp;
-       char dev[8], fsid[17];
+       char dev[13];   // 8 for 2^24, 1 for ':', 3 for 2^8, 1 for '\0'
+       char fsid[34];  // 2 * 16 for %llx, 1 for ':', 1 for '\0'
        struct nfs_net *nn = net_generic(seq_file_net(m), nfs_net_id);
 
        /* display header on line 1 */
        if (v == &nn->nfs_volume_list) {
-               seq_puts(m, "NV SERVER   PORT DEV     FSID              FSC\n");
+               seq_puts(m, "NV SERVER   PORT DEV          FSID"
+                           "                              FSC\n");
                return 0;
        }
        /* display one transport per line on subsequent lines */
        server = list_entry(v, struct nfs_server, master_link);
        clp = server->nfs_client;
 
-       snprintf(dev, 8, "%u:%u",
+       snprintf(dev, sizeof(dev), "%u:%u",
                 MAJOR(server->s_dev), MINOR(server->s_dev));
 
-       snprintf(fsid, 17, "%llx:%llx",
+       snprintf(fsid, sizeof(fsid), "%llx:%llx",
                 (unsigned long long) server->fsid.major,
                 (unsigned long long) server->fsid.minor);
 
        rcu_read_lock();
-       seq_printf(m, "v%u %s %s %-7s %-17s %s\n",
+       seq_printf(m, "v%u %s %s %-12s %-33s %s\n",
                   clp->rpc_ops->version,
                   rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR),
                   rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_PORT),
@@ -1434,27 +1325,20 @@ void nfs_fs_proc_net_exit(struct net *net)
  */
 int __init nfs_fs_proc_init(void)
 {
-       struct proc_dir_entry *p;
-
-       proc_fs_nfs = proc_mkdir("fs/nfsfs", NULL);
-       if (!proc_fs_nfs)
+       if (!proc_mkdir("fs/nfsfs", NULL))
                goto error_0;
 
        /* a file of servers with which we're dealing */
-       p = proc_symlink("servers", proc_fs_nfs, "../../net/nfsfs/servers");
-       if (!p)
+       if (!proc_symlink("fs/nfsfs/servers", NULL, "../../net/nfsfs/servers"))
                goto error_1;
 
        /* a file of volumes that we have mounted */
-       p = proc_symlink("volumes", proc_fs_nfs, "../../net/nfsfs/volumes");
-       if (!p)
-               goto error_2;
-       return 0;
+       if (!proc_symlink("fs/nfsfs/volumes", NULL, "../../net/nfsfs/volumes"))
+               goto error_1;
 
-error_2:
-       remove_proc_entry("servers", proc_fs_nfs);
+       return 0;
 error_1:
-       remove_proc_entry("fs/nfsfs", NULL);
+       remove_proc_subtree("fs/nfsfs", NULL);
 error_0:
        return -ENOMEM;
 }
@@ -1464,9 +1348,7 @@ error_0:
  */
 void nfs_fs_proc_exit(void)
 {
-       remove_proc_entry("volumes", proc_fs_nfs);
-       remove_proc_entry("servers", proc_fs_nfs);
-       remove_proc_entry("fs/nfsfs", NULL);
+       remove_proc_subtree("fs/nfsfs", NULL);
 }
 
 #endif /* CONFIG_PROC_FS */