aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWeston Andros Adamson <dros@netapp.com>2011-06-01 16:44:44 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-07-12 13:40:27 -0400
commit6382a44138e7aa40bf52170e7afc014443a24806 (patch)
tree9126d01d1fe2442fea057c3f45e4e3e532c85424
parent35dbbc99e93e57680837c17f96efe370f0535064 (diff)
NFS: move pnfs layouts to nfs_server structure
Layouts should be tracked per nfs_server (aka superblock) instead of per struct nfs_client, which may have multiple FSIDs associated with it. Signed-off-by: Weston Andros Adamson <dros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/callback_proc.c57
-rw-r--r--fs/nfs/client.c4
-rw-r--r--fs/nfs/pnfs.c13
-rw-r--r--include/linux/nfs_fs_sb.h2
4 files changed, 48 insertions, 28 deletions
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index d4d1954e9bb9..74780f9f852c 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -111,6 +111,7 @@ int nfs4_validate_delegation_stateid(struct nfs_delegation *delegation, const nf
111static u32 initiate_file_draining(struct nfs_client *clp, 111static u32 initiate_file_draining(struct nfs_client *clp,
112 struct cb_layoutrecallargs *args) 112 struct cb_layoutrecallargs *args)
113{ 113{
114 struct nfs_server *server;
114 struct pnfs_layout_hdr *lo; 115 struct pnfs_layout_hdr *lo;
115 struct inode *ino; 116 struct inode *ino;
116 bool found = false; 117 bool found = false;
@@ -118,21 +119,28 @@ static u32 initiate_file_draining(struct nfs_client *clp,
118 LIST_HEAD(free_me_list); 119 LIST_HEAD(free_me_list);
119 120
120 spin_lock(&clp->cl_lock); 121 spin_lock(&clp->cl_lock);
121 list_for_each_entry(lo, &clp->cl_layouts, plh_layouts) { 122 rcu_read_lock();
122 if (nfs_compare_fh(&args->cbl_fh, 123 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
123 &NFS_I(lo->plh_inode)->fh)) 124 list_for_each_entry(lo, &server->layouts, plh_layouts) {
124 continue; 125 if (nfs_compare_fh(&args->cbl_fh,
125 ino = igrab(lo->plh_inode); 126 &NFS_I(lo->plh_inode)->fh))
126 if (!ino) 127 continue;
127 continue; 128 ino = igrab(lo->plh_inode);
128 found = true; 129 if (!ino)
129 /* Without this, layout can be freed as soon 130 continue;
130 * as we release cl_lock. 131 found = true;
131 */ 132 /* Without this, layout can be freed as soon
132 get_layout_hdr(lo); 133 * as we release cl_lock.
133 break; 134 */
135 get_layout_hdr(lo);
136 break;
137 }
138 if (found)
139 break;
134 } 140 }
141 rcu_read_unlock();
135 spin_unlock(&clp->cl_lock); 142 spin_unlock(&clp->cl_lock);
143
136 if (!found) 144 if (!found)
137 return NFS4ERR_NOMATCHING_LAYOUT; 145 return NFS4ERR_NOMATCHING_LAYOUT;
138 146
@@ -154,6 +162,7 @@ static u32 initiate_file_draining(struct nfs_client *clp,
154static u32 initiate_bulk_draining(struct nfs_client *clp, 162static u32 initiate_bulk_draining(struct nfs_client *clp,
155 struct cb_layoutrecallargs *args) 163 struct cb_layoutrecallargs *args)
156{ 164{
165 struct nfs_server *server;
157 struct pnfs_layout_hdr *lo; 166 struct pnfs_layout_hdr *lo;
158 struct inode *ino; 167 struct inode *ino;
159 u32 rv = NFS4ERR_NOMATCHING_LAYOUT; 168 u32 rv = NFS4ERR_NOMATCHING_LAYOUT;
@@ -167,18 +176,24 @@ static u32 initiate_bulk_draining(struct nfs_client *clp,
167 }; 176 };
168 177
169 spin_lock(&clp->cl_lock); 178 spin_lock(&clp->cl_lock);
170 list_for_each_entry(lo, &clp->cl_layouts, plh_layouts) { 179 rcu_read_lock();
180 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
171 if ((args->cbl_recall_type == RETURN_FSID) && 181 if ((args->cbl_recall_type == RETURN_FSID) &&
172 memcmp(&NFS_SERVER(lo->plh_inode)->fsid, 182 memcmp(&server->fsid, &args->cbl_fsid,
173 &args->cbl_fsid, sizeof(struct nfs_fsid))) 183 sizeof(struct nfs_fsid)))
174 continue;
175 if (!igrab(lo->plh_inode))
176 continue; 184 continue;
177 get_layout_hdr(lo); 185
178 BUG_ON(!list_empty(&lo->plh_bulk_recall)); 186 list_for_each_entry(lo, &server->layouts, plh_layouts) {
179 list_add(&lo->plh_bulk_recall, &recall_list); 187 if (!igrab(lo->plh_inode))
188 continue;
189 get_layout_hdr(lo);
190 BUG_ON(!list_empty(&lo->plh_bulk_recall));
191 list_add(&lo->plh_bulk_recall, &recall_list);
192 }
180 } 193 }
194 rcu_read_unlock();
181 spin_unlock(&clp->cl_lock); 195 spin_unlock(&clp->cl_lock);
196
182 list_for_each_entry_safe(lo, tmp, 197 list_for_each_entry_safe(lo, tmp,
183 &recall_list, plh_bulk_recall) { 198 &recall_list, plh_bulk_recall) {
184 ino = lo->plh_inode; 199 ino = lo->plh_inode;
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 006f8ff0a3c0..5452ada59461 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -188,9 +188,6 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
188 cred = rpc_lookup_machine_cred(); 188 cred = rpc_lookup_machine_cred();
189 if (!IS_ERR(cred)) 189 if (!IS_ERR(cred))
190 clp->cl_machine_cred = cred; 190 clp->cl_machine_cred = cred;
191#if defined(CONFIG_NFS_V4_1)
192 INIT_LIST_HEAD(&clp->cl_layouts);
193#endif
194 nfs_fscache_get_client_cookie(clp); 191 nfs_fscache_get_client_cookie(clp);
195 192
196 return clp; 193 return clp;
@@ -1063,6 +1060,7 @@ static struct nfs_server *nfs_alloc_server(void)
1063 INIT_LIST_HEAD(&server->client_link); 1060 INIT_LIST_HEAD(&server->client_link);
1064 INIT_LIST_HEAD(&server->master_link); 1061 INIT_LIST_HEAD(&server->master_link);
1065 INIT_LIST_HEAD(&server->delegations); 1062 INIT_LIST_HEAD(&server->delegations);
1063 INIT_LIST_HEAD(&server->layouts);
1066 1064
1067 atomic_set(&server->active, 0); 1065 atomic_set(&server->active, 0);
1068 1066
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 29c0ca7fc347..ff8200772377 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -448,11 +448,17 @@ pnfs_destroy_layout(struct nfs_inode *nfsi)
448void 448void
449pnfs_destroy_all_layouts(struct nfs_client *clp) 449pnfs_destroy_all_layouts(struct nfs_client *clp)
450{ 450{
451 struct nfs_server *server;
451 struct pnfs_layout_hdr *lo; 452 struct pnfs_layout_hdr *lo;
452 LIST_HEAD(tmp_list); 453 LIST_HEAD(tmp_list);
453 454
454 spin_lock(&clp->cl_lock); 455 spin_lock(&clp->cl_lock);
455 list_splice_init(&clp->cl_layouts, &tmp_list); 456 rcu_read_lock();
457 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
458 if (!list_empty(&server->layouts))
459 list_splice_init(&server->layouts, &tmp_list);
460 }
461 rcu_read_unlock();
456 spin_unlock(&clp->cl_lock); 462 spin_unlock(&clp->cl_lock);
457 463
458 while (!list_empty(&tmp_list)) { 464 while (!list_empty(&tmp_list)) {
@@ -920,7 +926,8 @@ pnfs_update_layout(struct inode *ino,
920 }; 926 };
921 unsigned pg_offset; 927 unsigned pg_offset;
922 struct nfs_inode *nfsi = NFS_I(ino); 928 struct nfs_inode *nfsi = NFS_I(ino);
923 struct nfs_client *clp = NFS_SERVER(ino)->nfs_client; 929 struct nfs_server *server = NFS_SERVER(ino);
930 struct nfs_client *clp = server->nfs_client;
924 struct pnfs_layout_hdr *lo; 931 struct pnfs_layout_hdr *lo;
925 struct pnfs_layout_segment *lseg = NULL; 932 struct pnfs_layout_segment *lseg = NULL;
926 bool first = false; 933 bool first = false;
@@ -964,7 +971,7 @@ pnfs_update_layout(struct inode *ino,
964 */ 971 */
965 spin_lock(&clp->cl_lock); 972 spin_lock(&clp->cl_lock);
966 BUG_ON(!list_empty(&lo->plh_layouts)); 973 BUG_ON(!list_empty(&lo->plh_layouts));
967 list_add_tail(&lo->plh_layouts, &clp->cl_layouts); 974 list_add_tail(&lo->plh_layouts, &server->layouts);
968 spin_unlock(&clp->cl_lock); 975 spin_unlock(&clp->cl_lock);
969 } 976 }
970 977
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index f23b18831559..4faeac8f448a 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -78,7 +78,6 @@ struct nfs_client {
78 /* The flags used for obtaining the clientid during EXCHANGE_ID */ 78 /* The flags used for obtaining the clientid during EXCHANGE_ID */
79 u32 cl_exchange_flags; 79 u32 cl_exchange_flags;
80 struct nfs4_session *cl_session; /* sharred session */ 80 struct nfs4_session *cl_session; /* sharred session */
81 struct list_head cl_layouts;
82#endif /* CONFIG_NFS_V4 */ 81#endif /* CONFIG_NFS_V4 */
83 82
84#ifdef CONFIG_NFS_FSCACHE 83#ifdef CONFIG_NFS_FSCACHE
@@ -152,6 +151,7 @@ struct nfs_server {
152 struct rb_root openowner_id; 151 struct rb_root openowner_id;
153 struct rb_root lockowner_id; 152 struct rb_root lockowner_id;
154#endif 153#endif
154 struct list_head layouts;
155 struct list_head delegations; 155 struct list_head delegations;
156 void (*destroy)(struct nfs_server *); 156 void (*destroy)(struct nfs_server *);
157 157