flexfilelayoutdev.c (27fd38c5226ed0f1712d071880fa8e739eb78650) flexfilelayoutdev.c (93b717fd81bf6b9a73c3702e9b079b4de8148b34)
1/*
2 * Device operations for the pnfs nfs4 file layout driver.
3 *
4 * Copyright (c) 2014, Primary Data, Inc. All rights reserved.
5 *
6 * Tao Peng <bergwolf@primarydata.com>
7 */
8

--- 214 unchanged lines hidden (view full) ---

223 const struct nfs4_ff_layout_ds_err *e2)
224{
225 int ret;
226
227 if (e1->opnum != e2->opnum)
228 return e1->opnum < e2->opnum ? -1 : 1;
229 if (e1->status != e2->status)
230 return e1->status < e2->status ? -1 : 1;
1/*
2 * Device operations for the pnfs nfs4 file layout driver.
3 *
4 * Copyright (c) 2014, Primary Data, Inc. All rights reserved.
5 *
6 * Tao Peng <bergwolf@primarydata.com>
7 */
8

--- 214 unchanged lines hidden (view full) ---

223 const struct nfs4_ff_layout_ds_err *e2)
224{
225 int ret;
226
227 if (e1->opnum != e2->opnum)
228 return e1->opnum < e2->opnum ? -1 : 1;
229 if (e1->status != e2->status)
230 return e1->status < e2->status ? -1 : 1;
231 ret = memcmp(&e1->stateid, &e2->stateid, sizeof(e1->stateid));
231 ret = memcmp(e1->stateid.data, e2->stateid.data,
232 sizeof(e1->stateid.data));
232 if (ret != 0)
233 return ret;
234 ret = memcmp(&e1->deviceid, &e2->deviceid, sizeof(e1->deviceid));
235 if (ret != 0)
236 return ret;
237 if (end_offset(e1->offset, e1->length) < e2->offset)
238 return -1;
239 if (e1->offset > end_offset(e2->offset, e2->length))

--- 57 unchanged lines hidden (view full) ---

297
298 spin_lock(&flo->generic_hdr.plh_inode->i_lock);
299 ff_layout_add_ds_error_locked(flo, dserr);
300 spin_unlock(&flo->generic_hdr.plh_inode->i_lock);
301
302 return 0;
303}
304
233 if (ret != 0)
234 return ret;
235 ret = memcmp(&e1->deviceid, &e2->deviceid, sizeof(e1->deviceid));
236 if (ret != 0)
237 return ret;
238 if (end_offset(e1->offset, e1->length) < e2->offset)
239 return -1;
240 if (e1->offset > end_offset(e2->offset, e2->length))

--- 57 unchanged lines hidden (view full) ---

298
299 spin_lock(&flo->generic_hdr.plh_inode->i_lock);
300 ff_layout_add_ds_error_locked(flo, dserr);
301 spin_unlock(&flo->generic_hdr.plh_inode->i_lock);
302
303 return 0;
304}
305
305/* currently we only support AUTH_NONE and AUTH_SYS */
306static rpc_authflavor_t
307nfs4_ff_layout_choose_authflavor(struct nfs4_ff_layout_mirror *mirror)
306static struct rpc_cred *
307ff_layout_get_mirror_cred(struct nfs4_ff_layout_mirror *mirror, u32 iomode)
308{
308{
309 if (mirror->uid == (u32)-1)
310 return RPC_AUTH_NULL;
311 return RPC_AUTH_UNIX;
312}
309 struct rpc_cred *cred, __rcu **pcred;
313
310
314/* fetch cred for NFSv3 DS */
315static int ff_layout_update_mirror_cred(struct nfs4_ff_layout_mirror *mirror,
316 struct nfs4_pnfs_ds *ds)
317{
318 if (ds->ds_clp && !mirror->cred &&
319 mirror->mirror_ds->ds_versions[0].version == 3) {
320 struct rpc_auth *auth = ds->ds_clp->cl_rpcclient->cl_auth;
321 struct rpc_cred *cred;
322 struct auth_cred acred = {
323 .uid = make_kuid(&init_user_ns, mirror->uid),
324 .gid = make_kgid(&init_user_ns, mirror->gid),
325 };
311 if (iomode == IOMODE_READ)
312 pcred = &mirror->ro_cred;
313 else
314 pcred = &mirror->rw_cred;
326
315
327 /* AUTH_NULL ignores acred */
328 cred = auth->au_ops->lookup_cred(auth, &acred, 0);
329 if (IS_ERR(cred)) {
330 dprintk("%s: lookup_cred failed with %ld\n",
331 __func__, PTR_ERR(cred));
332 return PTR_ERR(cred);
333 } else {
334 if (cmpxchg(&mirror->cred, NULL, cred))
335 put_rpccred(cred);
336 }
337 }
338 return 0;
316 rcu_read_lock();
317 do {
318 cred = rcu_dereference(*pcred);
319 if (!cred)
320 break;
321
322 cred = get_rpccred_rcu(cred);
323 } while(!cred);
324 rcu_read_unlock();
325 return cred;
339}
340
341struct nfs_fh *
342nfs4_ff_layout_select_ds_fh(struct pnfs_layout_segment *lseg, u32 mirror_idx)
343{
344 struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, mirror_idx);
345 struct nfs_fh *fh = NULL;
346

--- 15 unchanged lines hidden (view full) ---

362 bool fail_return)
363{
364 struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, ds_idx);
365 struct nfs4_pnfs_ds *ds = NULL;
366 struct nfs4_deviceid_node *devid;
367 struct inode *ino = lseg->pls_layout->plh_inode;
368 struct nfs_server *s = NFS_SERVER(ino);
369 unsigned int max_payload;
326}
327
328struct nfs_fh *
329nfs4_ff_layout_select_ds_fh(struct pnfs_layout_segment *lseg, u32 mirror_idx)
330{
331 struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, mirror_idx);
332 struct nfs_fh *fh = NULL;
333

--- 15 unchanged lines hidden (view full) ---

349 bool fail_return)
350{
351 struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, ds_idx);
352 struct nfs4_pnfs_ds *ds = NULL;
353 struct nfs4_deviceid_node *devid;
354 struct inode *ino = lseg->pls_layout->plh_inode;
355 struct nfs_server *s = NFS_SERVER(ino);
356 unsigned int max_payload;
370 rpc_authflavor_t flavor;
371
372 if (!ff_layout_mirror_valid(lseg, mirror)) {
373 pr_err_ratelimited("NFS: %s: No data server for offset index %d\n",
374 __func__, ds_idx);
375 goto out;
376 }
377
378 devid = &mirror->mirror_ds->id_node;
379 if (ff_layout_test_devid_unavailable(devid))
380 goto out;
381
382 ds = mirror->mirror_ds->ds;
383 /* matching smp_wmb() in _nfs4_pnfs_v3/4_ds_connect */
384 smp_rmb();
385 if (ds->ds_clp)
357
358 if (!ff_layout_mirror_valid(lseg, mirror)) {
359 pr_err_ratelimited("NFS: %s: No data server for offset index %d\n",
360 __func__, ds_idx);
361 goto out;
362 }
363
364 devid = &mirror->mirror_ds->id_node;
365 if (ff_layout_test_devid_unavailable(devid))
366 goto out;
367
368 ds = mirror->mirror_ds->ds;
369 /* matching smp_wmb() in _nfs4_pnfs_v3/4_ds_connect */
370 smp_rmb();
371 if (ds->ds_clp)
386 goto out_update_creds;
372 goto out;
387
373
388 flavor = nfs4_ff_layout_choose_authflavor(mirror);
389
390 /* FIXME: For now we assume the server sent only one version of NFS
391 * to use for the DS.
392 */
393 nfs4_pnfs_ds_connect(s, ds, devid, dataserver_timeo,
394 dataserver_retrans,
395 mirror->mirror_ds->ds_versions[0].version,
396 mirror->mirror_ds->ds_versions[0].minor_version,
374 /* FIXME: For now we assume the server sent only one version of NFS
375 * to use for the DS.
376 */
377 nfs4_pnfs_ds_connect(s, ds, devid, dataserver_timeo,
378 dataserver_retrans,
379 mirror->mirror_ds->ds_versions[0].version,
380 mirror->mirror_ds->ds_versions[0].minor_version,
397 flavor);
381 RPC_AUTH_UNIX);
398
399 /* connect success, check rsize/wsize limit */
400 if (ds->ds_clp) {
401 max_payload =
402 nfs_block_size(rpc_max_payload(ds->ds_clp->cl_rpcclient),
403 NULL);
404 if (mirror->mirror_ds->ds_versions[0].rsize > max_payload)
405 mirror->mirror_ds->ds_versions[0].rsize = max_payload;

--- 8 unchanged lines hidden (view full) ---

414 if (ff_layout_has_available_ds(lseg))
415 set_bit(NFS_LAYOUT_RETURN_REQUESTED,
416 &lseg->pls_layout->plh_flags);
417 else
418 pnfs_error_mark_layout_for_return(ino, lseg);
419 } else
420 pnfs_error_mark_layout_for_return(ino, lseg);
421 ds = NULL;
382
383 /* connect success, check rsize/wsize limit */
384 if (ds->ds_clp) {
385 max_payload =
386 nfs_block_size(rpc_max_payload(ds->ds_clp->cl_rpcclient),
387 NULL);
388 if (mirror->mirror_ds->ds_versions[0].rsize > max_payload)
389 mirror->mirror_ds->ds_versions[0].rsize = max_payload;

--- 8 unchanged lines hidden (view full) ---

398 if (ff_layout_has_available_ds(lseg))
399 set_bit(NFS_LAYOUT_RETURN_REQUESTED,
400 &lseg->pls_layout->plh_flags);
401 else
402 pnfs_error_mark_layout_for_return(ino, lseg);
403 } else
404 pnfs_error_mark_layout_for_return(ino, lseg);
405 ds = NULL;
422 goto out;
423 }
406 }
424out_update_creds:
425 if (ff_layout_update_mirror_cred(mirror, ds))
426 ds = NULL;
427out:
428 return ds;
429}
430
431struct rpc_cred *
432ff_layout_get_ds_cred(struct pnfs_layout_segment *lseg, u32 ds_idx,
433 struct rpc_cred *mdscred)
434{
435 struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, ds_idx);
407out:
408 return ds;
409}
410
411struct rpc_cred *
412ff_layout_get_ds_cred(struct pnfs_layout_segment *lseg, u32 ds_idx,
413 struct rpc_cred *mdscred)
414{
415 struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, ds_idx);
436 struct rpc_cred *cred = ERR_PTR(-EINVAL);
416 struct rpc_cred *cred;
437
417
438 if (!nfs4_ff_layout_prepare_ds(lseg, ds_idx, true))
439 goto out;
440
441 if (mirror && mirror->cred)
442 cred = mirror->cred;
443 else
444 cred = mdscred;
445out:
418 if (mirror) {
419 cred = ff_layout_get_mirror_cred(mirror, lseg->pls_range.iomode);
420 if (!cred)
421 cred = get_rpccred(mdscred);
422 } else {
423 cred = get_rpccred(mdscred);
424 }
446 return cred;
447}
448
449/**
450* Find or create a DS rpc client with th MDS server rpc client auth flavor
451* in the nfs_client cl_ds_clients list.
452*/
453struct rpc_clnt *

--- 119 unchanged lines hidden ---
425 return cred;
426}
427
428/**
429* Find or create a DS rpc client with th MDS server rpc client auth flavor
430* in the nfs_client cl_ds_clients list.
431*/
432struct rpc_clnt *

--- 119 unchanged lines hidden ---