diff options
Diffstat (limited to 'fs/nfs/nfs4filelayoutdev.c')
-rw-r--r-- | fs/nfs/nfs4filelayoutdev.c | 102 |
1 files changed, 51 insertions, 51 deletions
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c index c9cff9adb2d3..a1fab8da7f03 100644 --- a/fs/nfs/nfs4filelayoutdev.c +++ b/fs/nfs/nfs4filelayoutdev.c | |||
@@ -30,12 +30,16 @@ | |||
30 | 30 | ||
31 | #include <linux/nfs_fs.h> | 31 | #include <linux/nfs_fs.h> |
32 | #include <linux/vmalloc.h> | 32 | #include <linux/vmalloc.h> |
33 | #include <linux/module.h> | ||
33 | 34 | ||
34 | #include "internal.h" | 35 | #include "internal.h" |
35 | #include "nfs4filelayout.h" | 36 | #include "nfs4filelayout.h" |
36 | 37 | ||
37 | #define NFSDBG_FACILITY NFSDBG_PNFS_LD | 38 | #define NFSDBG_FACILITY NFSDBG_PNFS_LD |
38 | 39 | ||
40 | static unsigned int dataserver_timeo = NFS4_DEF_DS_TIMEO; | ||
41 | static unsigned int dataserver_retrans = NFS4_DEF_DS_RETRANS; | ||
42 | |||
39 | /* | 43 | /* |
40 | * Data server cache | 44 | * Data server cache |
41 | * | 45 | * |
@@ -145,6 +149,28 @@ _data_server_lookup_locked(const struct list_head *dsaddrs) | |||
145 | } | 149 | } |
146 | 150 | ||
147 | /* | 151 | /* |
152 | * Lookup DS by nfs_client pointer. Zero data server client pointer | ||
153 | */ | ||
154 | void nfs4_ds_disconnect(struct nfs_client *clp) | ||
155 | { | ||
156 | struct nfs4_pnfs_ds *ds; | ||
157 | struct nfs_client *found = NULL; | ||
158 | |||
159 | dprintk("%s clp %p\n", __func__, clp); | ||
160 | spin_lock(&nfs4_ds_cache_lock); | ||
161 | list_for_each_entry(ds, &nfs4_data_server_cache, ds_node) | ||
162 | if (ds->ds_clp && ds->ds_clp == clp) { | ||
163 | found = ds->ds_clp; | ||
164 | ds->ds_clp = NULL; | ||
165 | } | ||
166 | spin_unlock(&nfs4_ds_cache_lock); | ||
167 | if (found) { | ||
168 | set_bit(NFS_CS_STOP_RENEW, &clp->cl_res_state); | ||
169 | nfs_put_client(clp); | ||
170 | } | ||
171 | } | ||
172 | |||
173 | /* | ||
148 | * Create an rpc connection to the nfs4_pnfs_ds data server | 174 | * Create an rpc connection to the nfs4_pnfs_ds data server |
149 | * Currently only supports IPv4 and IPv6 addresses | 175 | * Currently only supports IPv4 and IPv6 addresses |
150 | */ | 176 | */ |
@@ -165,8 +191,9 @@ nfs4_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds) | |||
165 | __func__, ds->ds_remotestr, da->da_remotestr); | 191 | __func__, ds->ds_remotestr, da->da_remotestr); |
166 | 192 | ||
167 | clp = nfs4_set_ds_client(mds_srv->nfs_client, | 193 | clp = nfs4_set_ds_client(mds_srv->nfs_client, |
168 | (struct sockaddr *)&da->da_addr, | 194 | (struct sockaddr *)&da->da_addr, |
169 | da->da_addrlen, IPPROTO_TCP); | 195 | da->da_addrlen, IPPROTO_TCP, |
196 | dataserver_timeo, dataserver_retrans); | ||
170 | if (!IS_ERR(clp)) | 197 | if (!IS_ERR(clp)) |
171 | break; | 198 | break; |
172 | } | 199 | } |
@@ -176,28 +203,7 @@ nfs4_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds) | |||
176 | goto out; | 203 | goto out; |
177 | } | 204 | } |
178 | 205 | ||
179 | if ((clp->cl_exchange_flags & EXCHGID4_FLAG_MASK_PNFS) != 0) { | 206 | status = nfs4_init_ds_session(clp, mds_srv->nfs_client->cl_lease_time); |
180 | if (!is_ds_client(clp)) { | ||
181 | status = -ENODEV; | ||
182 | goto out_put; | ||
183 | } | ||
184 | ds->ds_clp = clp; | ||
185 | dprintk("%s [existing] server=%s\n", __func__, | ||
186 | ds->ds_remotestr); | ||
187 | goto out; | ||
188 | } | ||
189 | |||
190 | /* | ||
191 | * Do not set NFS_CS_CHECK_LEASE_TIME instead set the DS lease to | ||
192 | * be equal to the MDS lease. Renewal is scheduled in create_session. | ||
193 | */ | ||
194 | spin_lock(&mds_srv->nfs_client->cl_lock); | ||
195 | clp->cl_lease_time = mds_srv->nfs_client->cl_lease_time; | ||
196 | spin_unlock(&mds_srv->nfs_client->cl_lock); | ||
197 | clp->cl_last_renewal = jiffies; | ||
198 | |||
199 | /* New nfs_client */ | ||
200 | status = nfs4_init_ds_session(clp); | ||
201 | if (status) | 207 | if (status) |
202 | goto out_put; | 208 | goto out_put; |
203 | 209 | ||
@@ -602,7 +608,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags) | |||
602 | 608 | ||
603 | mp_count = be32_to_cpup(p); /* multipath count */ | 609 | mp_count = be32_to_cpup(p); /* multipath count */ |
604 | for (j = 0; j < mp_count; j++) { | 610 | for (j = 0; j < mp_count; j++) { |
605 | da = decode_ds_addr(NFS_SERVER(ino)->nfs_client->net, | 611 | da = decode_ds_addr(NFS_SERVER(ino)->nfs_client->cl_net, |
606 | &stream, gfp_flags); | 612 | &stream, gfp_flags); |
607 | if (da) | 613 | if (da) |
608 | list_add_tail(&da->da_node, &dsaddrs); | 614 | list_add_tail(&da->da_node, &dsaddrs); |
@@ -791,48 +797,42 @@ nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j) | |||
791 | return flseg->fh_array[i]; | 797 | return flseg->fh_array[i]; |
792 | } | 798 | } |
793 | 799 | ||
794 | static void | ||
795 | filelayout_mark_devid_negative(struct nfs4_file_layout_dsaddr *dsaddr, | ||
796 | int err, const char *ds_remotestr) | ||
797 | { | ||
798 | u32 *p = (u32 *)&dsaddr->id_node.deviceid; | ||
799 | |||
800 | printk(KERN_ERR "NFS: data server %s connection error %d." | ||
801 | " Deviceid [%x%x%x%x] marked out of use.\n", | ||
802 | ds_remotestr, err, p[0], p[1], p[2], p[3]); | ||
803 | |||
804 | spin_lock(&nfs4_ds_cache_lock); | ||
805 | dsaddr->flags |= NFS4_DEVICE_ID_NEG_ENTRY; | ||
806 | spin_unlock(&nfs4_ds_cache_lock); | ||
807 | } | ||
808 | |||
809 | struct nfs4_pnfs_ds * | 800 | struct nfs4_pnfs_ds * |
810 | nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx) | 801 | nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx) |
811 | { | 802 | { |
812 | struct nfs4_file_layout_dsaddr *dsaddr = FILELAYOUT_LSEG(lseg)->dsaddr; | 803 | struct nfs4_file_layout_dsaddr *dsaddr = FILELAYOUT_LSEG(lseg)->dsaddr; |
813 | struct nfs4_pnfs_ds *ds = dsaddr->ds_list[ds_idx]; | 804 | struct nfs4_pnfs_ds *ds = dsaddr->ds_list[ds_idx]; |
805 | struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg); | ||
806 | |||
807 | if (filelayout_test_devid_invalid(devid)) | ||
808 | return NULL; | ||
814 | 809 | ||
815 | if (ds == NULL) { | 810 | if (ds == NULL) { |
816 | printk(KERN_ERR "NFS: %s: No data server for offset index %d\n", | 811 | printk(KERN_ERR "NFS: %s: No data server for offset index %d\n", |
817 | __func__, ds_idx); | 812 | __func__, ds_idx); |
818 | return NULL; | 813 | goto mark_dev_invalid; |
819 | } | 814 | } |
820 | 815 | ||
821 | if (!ds->ds_clp) { | 816 | if (!ds->ds_clp) { |
822 | struct nfs_server *s = NFS_SERVER(lseg->pls_layout->plh_inode); | 817 | struct nfs_server *s = NFS_SERVER(lseg->pls_layout->plh_inode); |
823 | int err; | 818 | int err; |
824 | 819 | ||
825 | if (dsaddr->flags & NFS4_DEVICE_ID_NEG_ENTRY) { | ||
826 | /* Already tried to connect, don't try again */ | ||
827 | dprintk("%s Deviceid marked out of use\n", __func__); | ||
828 | return NULL; | ||
829 | } | ||
830 | err = nfs4_ds_connect(s, ds); | 820 | err = nfs4_ds_connect(s, ds); |
831 | if (err) { | 821 | if (err) |
832 | filelayout_mark_devid_negative(dsaddr, err, | 822 | goto mark_dev_invalid; |
833 | ds->ds_remotestr); | ||
834 | return NULL; | ||
835 | } | ||
836 | } | 823 | } |
837 | return ds; | 824 | return ds; |
825 | |||
826 | mark_dev_invalid: | ||
827 | filelayout_mark_devid_invalid(devid); | ||
828 | return NULL; | ||
838 | } | 829 | } |
830 | |||
831 | module_param(dataserver_retrans, uint, 0644); | ||
832 | MODULE_PARM_DESC(dataserver_retrans, "The number of times the NFSv4.1 client " | ||
833 | "retries a request before it attempts further " | ||
834 | " recovery action."); | ||
835 | module_param(dataserver_timeo, uint, 0644); | ||
836 | MODULE_PARM_DESC(dataserver_timeo, "The time (in tenths of a second) the " | ||
837 | "NFSv4.1 client waits for a response from a " | ||
838 | " data server before it retries an NFS request."); | ||