diff options
-rw-r--r-- | fs/nfsd/export.c | 77 |
1 files changed, 35 insertions, 42 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 9dc036f18356..2fa61f003fff 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c | |||
@@ -500,35 +500,22 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) | |||
500 | int len; | 500 | int len; |
501 | int err; | 501 | int err; |
502 | struct auth_domain *dom = NULL; | 502 | struct auth_domain *dom = NULL; |
503 | struct nameidata nd; | 503 | struct svc_export exp = {}, *expp; |
504 | struct svc_export exp, *expp; | ||
505 | int an_int; | 504 | int an_int; |
506 | 505 | ||
507 | nd.path.dentry = NULL; | ||
508 | exp.ex_pathname = NULL; | ||
509 | |||
510 | /* fs locations */ | ||
511 | exp.ex_fslocs.locations = NULL; | ||
512 | exp.ex_fslocs.locations_count = 0; | ||
513 | exp.ex_fslocs.migrated = 0; | ||
514 | |||
515 | exp.ex_uuid = NULL; | ||
516 | |||
517 | /* secinfo */ | ||
518 | exp.ex_nflavors = 0; | ||
519 | |||
520 | if (mesg[mlen-1] != '\n') | 506 | if (mesg[mlen-1] != '\n') |
521 | return -EINVAL; | 507 | return -EINVAL; |
522 | mesg[mlen-1] = 0; | 508 | mesg[mlen-1] = 0; |
523 | 509 | ||
524 | buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | 510 | buf = kmalloc(PAGE_SIZE, GFP_KERNEL); |
525 | err = -ENOMEM; | 511 | if (!buf) |
526 | if (!buf) goto out; | 512 | return -ENOMEM; |
527 | 513 | ||
528 | /* client */ | 514 | /* client */ |
529 | len = qword_get(&mesg, buf, PAGE_SIZE); | ||
530 | err = -EINVAL; | 515 | err = -EINVAL; |
531 | if (len <= 0) goto out; | 516 | len = qword_get(&mesg, buf, PAGE_SIZE); |
517 | if (len <= 0) | ||
518 | goto out; | ||
532 | 519 | ||
533 | err = -ENOENT; | 520 | err = -ENOENT; |
534 | dom = auth_domain_find(buf); | 521 | dom = auth_domain_find(buf); |
@@ -537,25 +524,25 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) | |||
537 | 524 | ||
538 | /* path */ | 525 | /* path */ |
539 | err = -EINVAL; | 526 | err = -EINVAL; |
540 | if ((len=qword_get(&mesg, buf, PAGE_SIZE)) <= 0) | 527 | if ((len = qword_get(&mesg, buf, PAGE_SIZE)) <= 0) |
541 | goto out; | 528 | goto out1; |
542 | err = path_lookup(buf, 0, &nd); | 529 | |
543 | if (err) goto out_no_path; | 530 | err = kern_path(buf, 0, &exp.ex_path); |
531 | if (err) | ||
532 | goto out1; | ||
544 | 533 | ||
545 | exp.h.flags = 0; | ||
546 | exp.ex_client = dom; | 534 | exp.ex_client = dom; |
547 | exp.ex_path.mnt = nd.path.mnt; | 535 | |
548 | exp.ex_path.dentry = nd.path.dentry; | ||
549 | exp.ex_pathname = kstrdup(buf, GFP_KERNEL); | ||
550 | err = -ENOMEM; | 536 | err = -ENOMEM; |
537 | exp.ex_pathname = kstrdup(buf, GFP_KERNEL); | ||
551 | if (!exp.ex_pathname) | 538 | if (!exp.ex_pathname) |
552 | goto out; | 539 | goto out2; |
553 | 540 | ||
554 | /* expiry */ | 541 | /* expiry */ |
555 | err = -EINVAL; | 542 | err = -EINVAL; |
556 | exp.h.expiry_time = get_expiry(&mesg); | 543 | exp.h.expiry_time = get_expiry(&mesg); |
557 | if (exp.h.expiry_time == 0) | 544 | if (exp.h.expiry_time == 0) |
558 | goto out; | 545 | goto out3; |
559 | 546 | ||
560 | /* flags */ | 547 | /* flags */ |
561 | err = get_int(&mesg, &an_int); | 548 | err = get_int(&mesg, &an_int); |
@@ -563,22 +550,26 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) | |||
563 | err = 0; | 550 | err = 0; |
564 | set_bit(CACHE_NEGATIVE, &exp.h.flags); | 551 | set_bit(CACHE_NEGATIVE, &exp.h.flags); |
565 | } else { | 552 | } else { |
566 | if (err || an_int < 0) goto out; | 553 | if (err || an_int < 0) |
554 | goto out3; | ||
567 | exp.ex_flags= an_int; | 555 | exp.ex_flags= an_int; |
568 | 556 | ||
569 | /* anon uid */ | 557 | /* anon uid */ |
570 | err = get_int(&mesg, &an_int); | 558 | err = get_int(&mesg, &an_int); |
571 | if (err) goto out; | 559 | if (err) |
560 | goto out3; | ||
572 | exp.ex_anon_uid= an_int; | 561 | exp.ex_anon_uid= an_int; |
573 | 562 | ||
574 | /* anon gid */ | 563 | /* anon gid */ |
575 | err = get_int(&mesg, &an_int); | 564 | err = get_int(&mesg, &an_int); |
576 | if (err) goto out; | 565 | if (err) |
566 | goto out3; | ||
577 | exp.ex_anon_gid= an_int; | 567 | exp.ex_anon_gid= an_int; |
578 | 568 | ||
579 | /* fsid */ | 569 | /* fsid */ |
580 | err = get_int(&mesg, &an_int); | 570 | err = get_int(&mesg, &an_int); |
581 | if (err) goto out; | 571 | if (err) |
572 | goto out3; | ||
582 | exp.ex_fsid = an_int; | 573 | exp.ex_fsid = an_int; |
583 | 574 | ||
584 | while ((len = qword_get(&mesg, buf, PAGE_SIZE)) > 0) { | 575 | while ((len = qword_get(&mesg, buf, PAGE_SIZE)) > 0) { |
@@ -604,12 +595,13 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) | |||
604 | */ | 595 | */ |
605 | break; | 596 | break; |
606 | if (err) | 597 | if (err) |
607 | goto out; | 598 | goto out4; |
608 | } | 599 | } |
609 | 600 | ||
610 | err = check_export(nd.path.dentry->d_inode, exp.ex_flags, | 601 | err = check_export(exp.ex_path.dentry->d_inode, exp.ex_flags, |
611 | exp.ex_uuid); | 602 | exp.ex_uuid); |
612 | if (err) goto out; | 603 | if (err) |
604 | goto out4; | ||
613 | } | 605 | } |
614 | 606 | ||
615 | expp = svc_export_lookup(&exp); | 607 | expp = svc_export_lookup(&exp); |
@@ -622,15 +614,16 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) | |||
622 | err = -ENOMEM; | 614 | err = -ENOMEM; |
623 | else | 615 | else |
624 | exp_put(expp); | 616 | exp_put(expp); |
625 | out: | 617 | out4: |
626 | nfsd4_fslocs_free(&exp.ex_fslocs); | 618 | nfsd4_fslocs_free(&exp.ex_fslocs); |
627 | kfree(exp.ex_uuid); | 619 | kfree(exp.ex_uuid); |
620 | out3: | ||
628 | kfree(exp.ex_pathname); | 621 | kfree(exp.ex_pathname); |
629 | if (nd.path.dentry) | 622 | out2: |
630 | path_put(&nd.path); | 623 | path_put(&exp.ex_path); |
631 | out_no_path: | 624 | out1: |
632 | if (dom) | 625 | auth_domain_put(dom); |
633 | auth_domain_put(dom); | 626 | out: |
634 | kfree(buf); | 627 | kfree(buf); |
635 | return err; | 628 | return err; |
636 | } | 629 | } |