aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStanislav Kinsbursky <skinsbursky@parallels.com>2012-01-23 12:26:14 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-02-06 18:48:02 -0500
commitc25d32b26361ce0814fef2281f164866c18c8692 (patch)
tree8429f6b0bc9deeab4a74792eb43e62d65dd57082
parent6b13168b36b6a7f603d962c232f1f2f325705832 (diff)
NFS: make nfs_volume_list per net ns
This patch splits global list of NFS servers into per-net-ns array of lists. This looks more strict and clearer. BTW, this patch also makes "/proc/fs/nfsfs/volumes" content depends on /proc mount owner pid namespace. See below for details. NOTE: few words about how was /proc/fs/nfsfs/ entries content show per network namespace done. This is a little bit tricky and not the best is could be. But it's cheap (proper fix for /proc conteinerization is a hard nut to crack). The idea is simple: take proper network namespace from pid namespace child reaper nsproxy of /proc/ mount creator. This actually means, that if there are 2 containers with different net namespace sharing pid namespace, then read of /proc/fs/nfsfs/ entries will always return content, taken from net namespace of pid namespace creator task (and thus second namespace set wil be unvisible). Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/client.c20
-rw-r--r--fs/nfs/netns.h1
2 files changed, 15 insertions, 6 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 058eb9bcfa9d..d58e8386e6bc 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -56,7 +56,6 @@
56#define NFSDBG_FACILITY NFSDBG_CLIENT 56#define NFSDBG_FACILITY NFSDBG_CLIENT
57 57
58DEFINE_SPINLOCK(nfs_client_lock); 58DEFINE_SPINLOCK(nfs_client_lock);
59static LIST_HEAD(nfs_volume_list);
60static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq); 59static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq);
61#ifdef CONFIG_NFS_V4 60#ifdef CONFIG_NFS_V4
62static DEFINE_IDR(cb_ident_idr); /* Protected by nfs_client_lock */ 61static DEFINE_IDR(cb_ident_idr); /* Protected by nfs_client_lock */
@@ -1036,10 +1035,11 @@ static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_serve
1036static void nfs_server_insert_lists(struct nfs_server *server) 1035static void nfs_server_insert_lists(struct nfs_server *server)
1037{ 1036{
1038 struct nfs_client *clp = server->nfs_client; 1037 struct nfs_client *clp = server->nfs_client;
1038 struct nfs_net *nn = net_generic(clp->net, nfs_net_id);
1039 1039
1040 spin_lock(&nfs_client_lock); 1040 spin_lock(&nfs_client_lock);
1041 list_add_tail_rcu(&server->client_link, &clp->cl_superblocks); 1041 list_add_tail_rcu(&server->client_link, &clp->cl_superblocks);
1042 list_add_tail(&server->master_link, &nfs_volume_list); 1042 list_add_tail(&server->master_link, &nn->nfs_volume_list);
1043 clear_bit(NFS_CS_STOP_RENEW, &clp->cl_res_state); 1043 clear_bit(NFS_CS_STOP_RENEW, &clp->cl_res_state);
1044 spin_unlock(&nfs_client_lock); 1044 spin_unlock(&nfs_client_lock);
1045 1045
@@ -1764,6 +1764,7 @@ void nfs_clients_init(struct net *net)
1764 struct nfs_net *nn = net_generic(net, nfs_net_id); 1764 struct nfs_net *nn = net_generic(net, nfs_net_id);
1765 1765
1766 INIT_LIST_HEAD(&nn->nfs_client_list); 1766 INIT_LIST_HEAD(&nn->nfs_client_list);
1767 INIT_LIST_HEAD(&nn->nfs_volume_list);
1767} 1768}
1768 1769
1769#ifdef CONFIG_PROC_FS 1770#ifdef CONFIG_PROC_FS
@@ -1900,13 +1901,15 @@ static int nfs_volume_list_open(struct inode *inode, struct file *file)
1900{ 1901{
1901 struct seq_file *m; 1902 struct seq_file *m;
1902 int ret; 1903 int ret;
1904 struct pid_namespace *pid_ns = file->f_dentry->d_sb->s_fs_info;
1905 struct net *net = pid_ns->child_reaper->nsproxy->net_ns;
1903 1906
1904 ret = seq_open(file, &nfs_volume_list_ops); 1907 ret = seq_open(file, &nfs_volume_list_ops);
1905 if (ret < 0) 1908 if (ret < 0)
1906 return ret; 1909 return ret;
1907 1910
1908 m = file->private_data; 1911 m = file->private_data;
1909 m->private = PDE(inode)->data; 1912 m->private = net;
1910 1913
1911 return 0; 1914 return 0;
1912} 1915}
@@ -1916,9 +1919,11 @@ static int nfs_volume_list_open(struct inode *inode, struct file *file)
1916 */ 1919 */
1917static void *nfs_volume_list_start(struct seq_file *m, loff_t *_pos) 1920static void *nfs_volume_list_start(struct seq_file *m, loff_t *_pos)
1918{ 1921{
1922 struct nfs_net *nn = net_generic(m->private, nfs_net_id);
1923
1919 /* lock the list against modification */ 1924 /* lock the list against modification */
1920 spin_lock(&nfs_client_lock); 1925 spin_lock(&nfs_client_lock);
1921 return seq_list_start_head(&nfs_volume_list, *_pos); 1926 return seq_list_start_head(&nn->nfs_volume_list, *_pos);
1922} 1927}
1923 1928
1924/* 1929/*
@@ -1926,7 +1931,9 @@ static void *nfs_volume_list_start(struct seq_file *m, loff_t *_pos)
1926 */ 1931 */
1927static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos) 1932static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos)
1928{ 1933{
1929 return seq_list_next(v, &nfs_volume_list, pos); 1934 struct nfs_net *nn = net_generic(p->private, nfs_net_id);
1935
1936 return seq_list_next(v, &nn->nfs_volume_list, pos);
1930} 1937}
1931 1938
1932/* 1939/*
@@ -1945,9 +1952,10 @@ static int nfs_volume_list_show(struct seq_file *m, void *v)
1945 struct nfs_server *server; 1952 struct nfs_server *server;
1946 struct nfs_client *clp; 1953 struct nfs_client *clp;
1947 char dev[8], fsid[17]; 1954 char dev[8], fsid[17];
1955 struct nfs_net *nn = net_generic(m->private, nfs_net_id);
1948 1956
1949 /* display header on line 1 */ 1957 /* display header on line 1 */
1950 if (v == &nfs_volume_list) { 1958 if (v == &nn->nfs_volume_list) {
1951 seq_puts(m, "NV SERVER PORT DEV FSID FSC\n"); 1959 seq_puts(m, "NV SERVER PORT DEV FSID FSC\n");
1952 return 0; 1960 return 0;
1953 } 1961 }
diff --git a/fs/nfs/netns.h b/fs/nfs/netns.h
index feb33c3f9a56..0fbd4e017d27 100644
--- a/fs/nfs/netns.h
+++ b/fs/nfs/netns.h
@@ -8,6 +8,7 @@ struct nfs_net {
8 struct cache_detail *nfs_dns_resolve; 8 struct cache_detail *nfs_dns_resolve;
9 struct rpc_pipe *bl_device_pipe; 9 struct rpc_pipe *bl_device_pipe;
10 struct list_head nfs_client_list; 10 struct list_head nfs_client_list;
11 struct list_head nfs_volume_list;
11}; 12};
12 13
13extern int nfs_net_id; 14extern int nfs_net_id;