diff options
| -rw-r--r-- | fs/nfs/dir.c | 1 | ||||
| -rw-r--r-- | fs/nfs/direct.c | 142 | ||||
| -rw-r--r-- | fs/nfs/getroot.c | 81 | ||||
| -rw-r--r-- | fs/nfs/super.c | 11 | ||||
| -rw-r--r-- | fs/nfs/write.c | 3 | ||||
| -rw-r--r-- | include/linux/nfs_fs.h | 1 | ||||
| -rw-r--r-- | include/linux/sunrpc/debug.h | 5 | ||||
| -rw-r--r-- | include/linux/sunrpc/xprtsock.h | 6 | ||||
| -rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 4 | ||||
| -rw-r--r-- | net/sunrpc/auth_gss/gss_krb5_mech.c | 8 | ||||
| -rw-r--r-- | net/sunrpc/auth_gss/gss_krb5_seal.c | 1 | ||||
| -rw-r--r-- | net/sunrpc/rpc_pipe.c | 2 | ||||
| -rw-r--r-- | net/sunrpc/xprtrdma/transport.c | 10 | ||||
| -rw-r--r-- | net/sunrpc/xprtsock.c | 4 |
14 files changed, 155 insertions, 124 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 35334539d9..f697b5c74b 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include "nfs4_fs.h" | 38 | #include "nfs4_fs.h" |
| 39 | #include "delegation.h" | 39 | #include "delegation.h" |
| 40 | #include "iostat.h" | 40 | #include "iostat.h" |
| 41 | #include "internal.h" | ||
| 41 | 42 | ||
| 42 | /* #define NFS_DEBUG_VERBOSE 1 */ | 43 | /* #define NFS_DEBUG_VERBOSE 1 */ |
| 43 | 44 | ||
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index afcab007a2..5e8d82f666 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
| @@ -263,17 +263,19 @@ static const struct rpc_call_ops nfs_read_direct_ops = { | |||
| 263 | * handled automatically by nfs_direct_read_result(). Otherwise, if | 263 | * handled automatically by nfs_direct_read_result(). Otherwise, if |
| 264 | * no requests have been sent, just return an error. | 264 | * no requests have been sent, just return an error. |
| 265 | */ | 265 | */ |
| 266 | static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned long user_addr, size_t count, loff_t pos) | 266 | static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq, |
| 267 | const struct iovec *iov, | ||
| 268 | loff_t pos) | ||
| 267 | { | 269 | { |
| 268 | struct nfs_open_context *ctx = dreq->ctx; | 270 | struct nfs_open_context *ctx = dreq->ctx; |
| 269 | struct inode *inode = ctx->path.dentry->d_inode; | 271 | struct inode *inode = ctx->path.dentry->d_inode; |
| 272 | unsigned long user_addr = (unsigned long)iov->iov_base; | ||
| 273 | size_t count = iov->iov_len; | ||
| 270 | size_t rsize = NFS_SERVER(inode)->rsize; | 274 | size_t rsize = NFS_SERVER(inode)->rsize; |
| 271 | unsigned int pgbase; | 275 | unsigned int pgbase; |
| 272 | int result; | 276 | int result; |
| 273 | ssize_t started = 0; | 277 | ssize_t started = 0; |
| 274 | 278 | ||
| 275 | get_dreq(dreq); | ||
| 276 | |||
| 277 | do { | 279 | do { |
| 278 | struct nfs_read_data *data; | 280 | struct nfs_read_data *data; |
| 279 | size_t bytes; | 281 | size_t bytes; |
| @@ -347,15 +349,46 @@ static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned lo | |||
| 347 | count -= bytes; | 349 | count -= bytes; |
| 348 | } while (count != 0); | 350 | } while (count != 0); |
| 349 | 351 | ||
| 352 | if (started) | ||
| 353 | return started; | ||
| 354 | return result < 0 ? (ssize_t) result : -EFAULT; | ||
| 355 | } | ||
| 356 | |||
| 357 | static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq, | ||
| 358 | const struct iovec *iov, | ||
| 359 | unsigned long nr_segs, | ||
| 360 | loff_t pos) | ||
| 361 | { | ||
| 362 | ssize_t result = -EINVAL; | ||
| 363 | size_t requested_bytes = 0; | ||
| 364 | unsigned long seg; | ||
| 365 | |||
| 366 | get_dreq(dreq); | ||
| 367 | |||
| 368 | for (seg = 0; seg < nr_segs; seg++) { | ||
| 369 | const struct iovec *vec = &iov[seg]; | ||
| 370 | result = nfs_direct_read_schedule_segment(dreq, vec, pos); | ||
| 371 | if (result < 0) | ||
| 372 | break; | ||
| 373 | requested_bytes += result; | ||
| 374 | if ((size_t)result < vec->iov_len) | ||
| 375 | break; | ||
| 376 | pos += vec->iov_len; | ||
| 377 | } | ||
| 378 | |||
| 350 | if (put_dreq(dreq)) | 379 | if (put_dreq(dreq)) |
| 351 | nfs_direct_complete(dreq); | 380 | nfs_direct_complete(dreq); |
| 352 | 381 | ||
| 353 | if (started) | 382 | if (requested_bytes != 0) |
| 354 | return 0; | 383 | return 0; |
| 355 | return result < 0 ? (ssize_t) result : -EFAULT; | 384 | |
| 385 | if (result < 0) | ||
| 386 | return result; | ||
| 387 | return -EIO; | ||
| 356 | } | 388 | } |
| 357 | 389 | ||
| 358 | static ssize_t nfs_direct_read(struct kiocb *iocb, unsigned long user_addr, size_t count, loff_t pos) | 390 | static ssize_t nfs_direct_read(struct kiocb *iocb, const struct iovec *iov, |
| 391 | unsigned long nr_segs, loff_t pos) | ||
| 359 | { | 392 | { |
| 360 | ssize_t result = 0; | 393 | ssize_t result = 0; |
| 361 | sigset_t oldset; | 394 | sigset_t oldset; |
| @@ -372,9 +405,8 @@ static ssize_t nfs_direct_read(struct kiocb *iocb, unsigned long user_addr, size | |||
| 372 | if (!is_sync_kiocb(iocb)) | 405 | if (!is_sync_kiocb(iocb)) |
| 373 | dreq->iocb = iocb; | 406 | dreq->iocb = iocb; |
| 374 | 407 | ||
| 375 | nfs_add_stats(inode, NFSIOS_DIRECTREADBYTES, count); | ||
| 376 | rpc_clnt_sigmask(clnt, &oldset); | 408 | rpc_clnt_sigmask(clnt, &oldset); |
| 377 | result = nfs_direct_read_schedule(dreq, user_addr, count, pos); | 409 | result = nfs_direct_read_schedule_iovec(dreq, iov, nr_segs, pos); |
| 378 | if (!result) | 410 | if (!result) |
| 379 | result = nfs_direct_wait(dreq); | 411 | result = nfs_direct_wait(dreq); |
| 380 | rpc_clnt_sigunmask(clnt, &oldset); | 412 | rpc_clnt_sigunmask(clnt, &oldset); |
| @@ -601,17 +633,19 @@ static const struct rpc_call_ops nfs_write_direct_ops = { | |||
| 601 | * handled automatically by nfs_direct_write_result(). Otherwise, if | 633 | * handled automatically by nfs_direct_write_result(). Otherwise, if |
| 602 | * no requests have been sent, just return an error. | 634 | * no requests have been sent, just return an error. |
| 603 | */ | 635 | */ |
| 604 | static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned long user_addr, size_t count, loff_t pos, int sync) | 636 | static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq, |
| 637 | const struct iovec *iov, | ||
| 638 | loff_t pos, int sync) | ||
| 605 | { | 639 | { |
| 606 | struct nfs_open_context *ctx = dreq->ctx; | 640 | struct nfs_open_context *ctx = dreq->ctx; |
| 607 | struct inode *inode = ctx->path.dentry->d_inode; | 641 | struct inode *inode = ctx->path.dentry->d_inode; |
| 642 | unsigned long user_addr = (unsigned long)iov->iov_base; | ||
| 643 | size_t count = iov->iov_len; | ||
| 608 | size_t wsize = NFS_SERVER(inode)->wsize; | 644 | size_t wsize = NFS_SERVER(inode)->wsize; |
| 609 | unsigned int pgbase; | 645 | unsigned int pgbase; |
| 610 | int result; | 646 | int result; |
| 611 | ssize_t started = 0; | 647 | ssize_t started = 0; |
| 612 | 648 | ||
| 613 | get_dreq(dreq); | ||
| 614 | |||
| 615 | do { | 649 | do { |
| 616 | struct nfs_write_data *data; | 650 | struct nfs_write_data *data; |
| 617 | size_t bytes; | 651 | size_t bytes; |
| @@ -689,15 +723,48 @@ static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned l | |||
| 689 | count -= bytes; | 723 | count -= bytes; |
| 690 | } while (count != 0); | 724 | } while (count != 0); |
| 691 | 725 | ||
| 726 | if (started) | ||
| 727 | return started; | ||
| 728 | return result < 0 ? (ssize_t) result : -EFAULT; | ||
| 729 | } | ||
| 730 | |||
| 731 | static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, | ||
| 732 | const struct iovec *iov, | ||
| 733 | unsigned long nr_segs, | ||
| 734 | loff_t pos, int sync) | ||
| 735 | { | ||
| 736 | ssize_t result = 0; | ||
| 737 | size_t requested_bytes = 0; | ||
| 738 | unsigned long seg; | ||
| 739 | |||
| 740 | get_dreq(dreq); | ||
| 741 | |||
| 742 | for (seg = 0; seg < nr_segs; seg++) { | ||
| 743 | const struct iovec *vec = &iov[seg]; | ||
| 744 | result = nfs_direct_write_schedule_segment(dreq, vec, | ||
| 745 | pos, sync); | ||
| 746 | if (result < 0) | ||
| 747 | break; | ||
| 748 | requested_bytes += result; | ||
| 749 | if ((size_t)result < vec->iov_len) | ||
| 750 | break; | ||
| 751 | pos += vec->iov_len; | ||
| 752 | } | ||
| 753 | |||
| 692 | if (put_dreq(dreq)) | 754 | if (put_dreq(dreq)) |
| 693 | nfs_direct_write_complete(dreq, inode); | 755 | nfs_direct_write_complete(dreq, dreq->inode); |
| 694 | 756 | ||
| 695 | if (started) | 757 | if (requested_bytes != 0) |
| 696 | return 0; | 758 | return 0; |
| 697 | return result < 0 ? (ssize_t) result : -EFAULT; | 759 | |
| 760 | if (result < 0) | ||
| 761 | return result; | ||
| 762 | return -EIO; | ||
| 698 | } | 763 | } |
| 699 | 764 | ||
| 700 | static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, size_t count, loff_t pos) | 765 | static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov, |
| 766 | unsigned long nr_segs, loff_t pos, | ||
| 767 | size_t count) | ||
| 701 | { | 768 | { |
| 702 | ssize_t result = 0; | 769 | ssize_t result = 0; |
| 703 | sigset_t oldset; | 770 | sigset_t oldset; |
| @@ -720,10 +787,8 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, siz | |||
| 720 | if (!is_sync_kiocb(iocb)) | 787 | if (!is_sync_kiocb(iocb)) |
| 721 | dreq->iocb = iocb; | 788 | dreq->iocb = iocb; |
| 722 | 789 | ||
| 723 | nfs_add_stats(inode, NFSIOS_DIRECTWRITTENBYTES, count); | ||
| 724 | |||
| 725 | rpc_clnt_sigmask(clnt, &oldset); | 790 | rpc_clnt_sigmask(clnt, &oldset); |
| 726 | result = nfs_direct_write_schedule(dreq, user_addr, count, pos, sync); | 791 | result = nfs_direct_write_schedule_iovec(dreq, iov, nr_segs, pos, sync); |
| 727 | if (!result) | 792 | if (!result) |
| 728 | result = nfs_direct_wait(dreq); | 793 | result = nfs_direct_wait(dreq); |
| 729 | rpc_clnt_sigunmask(clnt, &oldset); | 794 | rpc_clnt_sigunmask(clnt, &oldset); |
| @@ -759,21 +824,16 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov, | |||
| 759 | ssize_t retval = -EINVAL; | 824 | ssize_t retval = -EINVAL; |
| 760 | struct file *file = iocb->ki_filp; | 825 | struct file *file = iocb->ki_filp; |
| 761 | struct address_space *mapping = file->f_mapping; | 826 | struct address_space *mapping = file->f_mapping; |
| 762 | /* XXX: temporary */ | 827 | size_t count; |
| 763 | const char __user *buf = iov[0].iov_base; | 828 | |
| 764 | size_t count = iov[0].iov_len; | 829 | count = iov_length(iov, nr_segs); |
| 830 | nfs_add_stats(mapping->host, NFSIOS_DIRECTREADBYTES, count); | ||
| 765 | 831 | ||
| 766 | dprintk("nfs: direct read(%s/%s, %lu@%Ld)\n", | 832 | dprintk("nfs: direct read(%s/%s, %zd@%Ld)\n", |
| 767 | file->f_path.dentry->d_parent->d_name.name, | 833 | file->f_path.dentry->d_parent->d_name.name, |
| 768 | file->f_path.dentry->d_name.name, | 834 | file->f_path.dentry->d_name.name, |
| 769 | (unsigned long) count, (long long) pos); | 835 | count, (long long) pos); |
| 770 | |||
| 771 | if (nr_segs != 1) | ||
| 772 | goto out; | ||
| 773 | 836 | ||
| 774 | retval = -EFAULT; | ||
| 775 | if (!access_ok(VERIFY_WRITE, buf, count)) | ||
| 776 | goto out; | ||
| 777 | retval = 0; | 837 | retval = 0; |
| 778 | if (!count) | 838 | if (!count) |
| 779 | goto out; | 839 | goto out; |
| @@ -782,7 +842,7 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov, | |||
| 782 | if (retval) | 842 | if (retval) |
| 783 | goto out; | 843 | goto out; |
| 784 | 844 | ||
| 785 | retval = nfs_direct_read(iocb, (unsigned long) buf, count, pos); | 845 | retval = nfs_direct_read(iocb, iov, nr_segs, pos); |
| 786 | if (retval > 0) | 846 | if (retval > 0) |
| 787 | iocb->ki_pos = pos + retval; | 847 | iocb->ki_pos = pos + retval; |
| 788 | 848 | ||
| @@ -821,21 +881,21 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 821 | ssize_t retval = -EINVAL; | 881 | ssize_t retval = -EINVAL; |
| 822 | struct file *file = iocb->ki_filp; | 882 | struct file *file = iocb->ki_filp; |
| 823 | struct address_space *mapping = file->f_mapping; | 883 | struct address_space *mapping = file->f_mapping; |
| 824 | /* XXX: temporary */ | 884 | size_t count; |
| 825 | const char __user *buf = iov[0].iov_base; | 885 | |
| 826 | size_t count = iov[0].iov_len; | 886 | count = iov_length(iov, nr_segs); |
| 887 | nfs_add_stats(mapping->host, NFSIOS_DIRECTWRITTENBYTES, count); | ||
| 827 | 888 | ||
| 828 | dprintk("nfs: direct write(%s/%s, %lu@%Ld)\n", | 889 | dfprintk(VFS, "nfs: direct write(%s/%s, %zd@%Ld)\n", |
| 829 | file->f_path.dentry->d_parent->d_name.name, | 890 | file->f_path.dentry->d_parent->d_name.name, |
| 830 | file->f_path.dentry->d_name.name, | 891 | file->f_path.dentry->d_name.name, |
| 831 | (unsigned long) count, (long long) pos); | 892 | count, (long long) pos); |
| 832 | |||
| 833 | if (nr_segs != 1) | ||
| 834 | goto out; | ||
| 835 | 893 | ||
| 836 | retval = generic_write_checks(file, &pos, &count, 0); | 894 | retval = generic_write_checks(file, &pos, &count, 0); |
| 837 | if (retval) | 895 | if (retval) |
| 838 | goto out; | 896 | goto out; |
| 897 | if (!count) | ||
| 898 | goto out; /* return 0 */ | ||
| 839 | 899 | ||
| 840 | retval = -EINVAL; | 900 | retval = -EINVAL; |
| 841 | if ((ssize_t) count < 0) | 901 | if ((ssize_t) count < 0) |
| @@ -844,15 +904,11 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 844 | if (!count) | 904 | if (!count) |
| 845 | goto out; | 905 | goto out; |
| 846 | 906 | ||
| 847 | retval = -EFAULT; | ||
| 848 | if (!access_ok(VERIFY_READ, buf, count)) | ||
| 849 | goto out; | ||
| 850 | |||
| 851 | retval = nfs_sync_mapping(mapping); | 907 | retval = nfs_sync_mapping(mapping); |
| 852 | if (retval) | 908 | if (retval) |
| 853 | goto out; | 909 | goto out; |
| 854 | 910 | ||
| 855 | retval = nfs_direct_write(iocb, (unsigned long) buf, count, pos); | 911 | retval = nfs_direct_write(iocb, iov, nr_segs, pos, count); |
| 856 | 912 | ||
| 857 | if (retval > 0) | 913 | if (retval > 0) |
| 858 | iocb->ki_pos = pos + retval; | 914 | iocb->ki_pos = pos + retval; |
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c index 522e5ad4d8..0ee43843f4 100644 --- a/fs/nfs/getroot.c +++ b/fs/nfs/getroot.c | |||
| @@ -43,6 +43,25 @@ | |||
| 43 | #define NFSDBG_FACILITY NFSDBG_CLIENT | 43 | #define NFSDBG_FACILITY NFSDBG_CLIENT |
| 44 | 44 | ||
| 45 | /* | 45 | /* |
| 46 | * Set the superblock root dentry. | ||
| 47 | * Note that this function frees the inode in case of error. | ||
| 48 | */ | ||
| 49 | static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *inode) | ||
| 50 | { | ||
| 51 | /* The mntroot acts as the dummy root dentry for this superblock */ | ||
| 52 | if (sb->s_root == NULL) { | ||
| 53 | sb->s_root = d_alloc_root(inode); | ||
| 54 | if (sb->s_root == NULL) { | ||
| 55 | iput(inode); | ||
| 56 | return -ENOMEM; | ||
| 57 | } | ||
| 58 | /* Circumvent igrab(): we know the inode is not being freed */ | ||
| 59 | atomic_inc(&inode->i_count); | ||
| 60 | } | ||
| 61 | return 0; | ||
| 62 | } | ||
| 63 | |||
| 64 | /* | ||
| 46 | * get an NFS2/NFS3 root dentry from the root filehandle | 65 | * get an NFS2/NFS3 root dentry from the root filehandle |
| 47 | */ | 66 | */ |
| 48 | struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh) | 67 | struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh) |
| @@ -54,33 +73,6 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh) | |||
| 54 | struct inode *inode; | 73 | struct inode *inode; |
| 55 | int error; | 74 | int error; |
| 56 | 75 | ||
| 57 | /* create a dummy root dentry with dummy inode for this superblock */ | ||
| 58 | if (!sb->s_root) { | ||
| 59 | struct nfs_fh dummyfh; | ||
| 60 | struct dentry *root; | ||
| 61 | struct inode *iroot; | ||
| 62 | |||
| 63 | memset(&dummyfh, 0, sizeof(dummyfh)); | ||
| 64 | memset(&fattr, 0, sizeof(fattr)); | ||
| 65 | nfs_fattr_init(&fattr); | ||
| 66 | fattr.valid = NFS_ATTR_FATTR; | ||
| 67 | fattr.type = NFDIR; | ||
| 68 | fattr.mode = S_IFDIR | S_IRUSR | S_IWUSR; | ||
| 69 | fattr.nlink = 2; | ||
| 70 | |||
| 71 | iroot = nfs_fhget(sb, &dummyfh, &fattr); | ||
| 72 | if (IS_ERR(iroot)) | ||
| 73 | return ERR_PTR(PTR_ERR(iroot)); | ||
| 74 | |||
| 75 | root = d_alloc_root(iroot); | ||
| 76 | if (!root) { | ||
| 77 | iput(iroot); | ||
| 78 | return ERR_PTR(-ENOMEM); | ||
| 79 | } | ||
| 80 | |||
| 81 | sb->s_root = root; | ||
| 82 | } | ||
| 83 | |||
| 84 | /* get the actual root for this mount */ | 76 | /* get the actual root for this mount */ |
| 85 | fsinfo.fattr = &fattr; | 77 | fsinfo.fattr = &fattr; |
| 86 | 78 | ||
| @@ -96,6 +88,10 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh) | |||
| 96 | return ERR_PTR(PTR_ERR(inode)); | 88 | return ERR_PTR(PTR_ERR(inode)); |
| 97 | } | 89 | } |
| 98 | 90 | ||
| 91 | error = nfs_superblock_set_dummy_root(sb, inode); | ||
| 92 | if (error != 0) | ||
| 93 | return ERR_PTR(error); | ||
| 94 | |||
| 99 | /* root dentries normally start off anonymous and get spliced in later | 95 | /* root dentries normally start off anonymous and get spliced in later |
| 100 | * if the dentry tree reaches them; however if the dentry already | 96 | * if the dentry tree reaches them; however if the dentry already |
| 101 | * exists, we'll pick it up at this point and use it as the root | 97 | * exists, we'll pick it up at this point and use it as the root |
| @@ -241,33 +237,6 @@ struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh) | |||
| 241 | 237 | ||
| 242 | dprintk("--> nfs4_get_root()\n"); | 238 | dprintk("--> nfs4_get_root()\n"); |
| 243 | 239 | ||
| 244 | /* create a dummy root dentry with dummy inode for this superblock */ | ||
| 245 | if (!sb->s_root) { | ||
| 246 | struct nfs_fh dummyfh; | ||
| 247 | struct dentry *root; | ||
| 248 | struct inode *iroot; | ||
| 249 | |||
| 250 | memset(&dummyfh, 0, sizeof(dummyfh)); | ||
| 251 | memset(&fattr, 0, sizeof(fattr)); | ||
| 252 | nfs_fattr_init(&fattr); | ||
| 253 | fattr.valid = NFS_ATTR_FATTR; | ||
| 254 | fattr.type = NFDIR; | ||
| 255 | fattr.mode = S_IFDIR | S_IRUSR | S_IWUSR; | ||
| 256 | fattr.nlink = 2; | ||
| 257 | |||
| 258 | iroot = nfs_fhget(sb, &dummyfh, &fattr); | ||
| 259 | if (IS_ERR(iroot)) | ||
| 260 | return ERR_PTR(PTR_ERR(iroot)); | ||
| 261 | |||
| 262 | root = d_alloc_root(iroot); | ||
| 263 | if (!root) { | ||
| 264 | iput(iroot); | ||
| 265 | return ERR_PTR(-ENOMEM); | ||
| 266 | } | ||
| 267 | |||
| 268 | sb->s_root = root; | ||
| 269 | } | ||
| 270 | |||
| 271 | /* get the info about the server and filesystem */ | 240 | /* get the info about the server and filesystem */ |
| 272 | error = nfs4_server_capabilities(server, mntfh); | 241 | error = nfs4_server_capabilities(server, mntfh); |
| 273 | if (error < 0) { | 242 | if (error < 0) { |
| @@ -289,6 +258,10 @@ struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh) | |||
| 289 | return ERR_PTR(PTR_ERR(inode)); | 258 | return ERR_PTR(PTR_ERR(inode)); |
| 290 | } | 259 | } |
| 291 | 260 | ||
| 261 | error = nfs_superblock_set_dummy_root(sb, inode); | ||
| 262 | if (error != 0) | ||
| 263 | return ERR_PTR(error); | ||
| 264 | |||
| 292 | /* root dentries normally start off anonymous and get spliced in later | 265 | /* root dentries normally start off anonymous and get spliced in later |
| 293 | * if the dentry tree reaches them; however if the dentry already | 266 | * if the dentry tree reaches them; however if the dentry already |
| 294 | * exists, we'll pick it up at this point and use it as the root | 267 | * exists, we'll pick it up at this point and use it as the root |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index fa517ae920..2426e713b7 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
| @@ -1054,10 +1054,11 @@ static int nfs_validate_mount_data(void *options, | |||
| 1054 | { | 1054 | { |
| 1055 | struct nfs_mount_data *data = (struct nfs_mount_data *)options; | 1055 | struct nfs_mount_data *data = (struct nfs_mount_data *)options; |
| 1056 | 1056 | ||
| 1057 | memset(args, 0, sizeof(*args)); | ||
| 1058 | |||
| 1057 | if (data == NULL) | 1059 | if (data == NULL) |
| 1058 | goto out_no_data; | 1060 | goto out_no_data; |
| 1059 | 1061 | ||
| 1060 | memset(args, 0, sizeof(*args)); | ||
| 1061 | args->flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP); | 1062 | args->flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP); |
| 1062 | args->rsize = NFS_MAX_FILE_IO_SIZE; | 1063 | args->rsize = NFS_MAX_FILE_IO_SIZE; |
| 1063 | args->wsize = NFS_MAX_FILE_IO_SIZE; | 1064 | args->wsize = NFS_MAX_FILE_IO_SIZE; |
| @@ -1474,6 +1475,11 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags, | |||
| 1474 | error = PTR_ERR(mntroot); | 1475 | error = PTR_ERR(mntroot); |
| 1475 | goto error_splat_super; | 1476 | goto error_splat_super; |
| 1476 | } | 1477 | } |
| 1478 | if (mntroot->d_inode->i_op != &nfs_dir_inode_operations) { | ||
| 1479 | dput(mntroot); | ||
| 1480 | error = -ESTALE; | ||
| 1481 | goto error_splat_super; | ||
| 1482 | } | ||
| 1477 | 1483 | ||
| 1478 | s->s_flags |= MS_ACTIVE; | 1484 | s->s_flags |= MS_ACTIVE; |
| 1479 | mnt->mnt_sb = s; | 1485 | mnt->mnt_sb = s; |
| @@ -1531,10 +1537,11 @@ static int nfs4_validate_mount_data(void *options, | |||
| 1531 | struct nfs4_mount_data *data = (struct nfs4_mount_data *)options; | 1537 | struct nfs4_mount_data *data = (struct nfs4_mount_data *)options; |
| 1532 | char *c; | 1538 | char *c; |
| 1533 | 1539 | ||
| 1540 | memset(args, 0, sizeof(*args)); | ||
| 1541 | |||
| 1534 | if (data == NULL) | 1542 | if (data == NULL) |
| 1535 | goto out_no_data; | 1543 | goto out_no_data; |
| 1536 | 1544 | ||
| 1537 | memset(args, 0, sizeof(*args)); | ||
| 1538 | args->rsize = NFS_MAX_FILE_IO_SIZE; | 1545 | args->rsize = NFS_MAX_FILE_IO_SIZE; |
| 1539 | args->wsize = NFS_MAX_FILE_IO_SIZE; | 1546 | args->wsize = NFS_MAX_FILE_IO_SIZE; |
| 1540 | args->timeo = 600; | 1547 | args->timeo = 600; |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 89527a487e..51cc1bd6a1 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
| @@ -1436,7 +1436,8 @@ out: | |||
| 1436 | return ret; | 1436 | return ret; |
| 1437 | } | 1437 | } |
| 1438 | 1438 | ||
| 1439 | int nfs_wb_page_priority(struct inode *inode, struct page *page, int how) | 1439 | static int nfs_wb_page_priority(struct inode *inode, struct page *page, |
| 1440 | int how) | ||
| 1440 | { | 1441 | { |
| 1441 | loff_t range_start = page_offset(page); | 1442 | loff_t range_start = page_offset(page); |
| 1442 | loff_t range_end = range_start + (loff_t)(PAGE_CACHE_SIZE - 1); | 1443 | loff_t range_end = range_start + (loff_t)(PAGE_CACHE_SIZE - 1); |
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index e82a6ebc72..2d15d4aac0 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h | |||
| @@ -422,7 +422,6 @@ extern long nfs_sync_mapping_wait(struct address_space *, struct writeback_contr | |||
| 422 | extern int nfs_wb_all(struct inode *inode); | 422 | extern int nfs_wb_all(struct inode *inode); |
| 423 | extern int nfs_wb_nocommit(struct inode *inode); | 423 | extern int nfs_wb_nocommit(struct inode *inode); |
| 424 | extern int nfs_wb_page(struct inode *inode, struct page* page); | 424 | extern int nfs_wb_page(struct inode *inode, struct page* page); |
| 425 | extern int nfs_wb_page_priority(struct inode *inode, struct page* page, int how); | ||
| 426 | extern int nfs_wb_page_cancel(struct inode *inode, struct page* page); | 425 | extern int nfs_wb_page_cancel(struct inode *inode, struct page* page); |
| 427 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 426 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) |
| 428 | extern int nfs_commit_inode(struct inode *, int); | 427 | extern int nfs_commit_inode(struct inode *, int); |
diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h index 3347c72b84..3912cf1636 100644 --- a/include/linux/sunrpc/debug.h +++ b/include/linux/sunrpc/debug.h | |||
| @@ -88,11 +88,6 @@ enum { | |||
| 88 | CTL_SLOTTABLE_TCP, | 88 | CTL_SLOTTABLE_TCP, |
| 89 | CTL_MIN_RESVPORT, | 89 | CTL_MIN_RESVPORT, |
| 90 | CTL_MAX_RESVPORT, | 90 | CTL_MAX_RESVPORT, |
| 91 | CTL_SLOTTABLE_RDMA, | ||
| 92 | CTL_RDMA_MAXINLINEREAD, | ||
| 93 | CTL_RDMA_MAXINLINEWRITE, | ||
| 94 | CTL_RDMA_WRITEPADDING, | ||
| 95 | CTL_RDMA_MEMREG, | ||
| 96 | }; | 91 | }; |
| 97 | 92 | ||
| 98 | #endif /* _LINUX_SUNRPC_DEBUG_H_ */ | 93 | #endif /* _LINUX_SUNRPC_DEBUG_H_ */ |
diff --git a/include/linux/sunrpc/xprtsock.h b/include/linux/sunrpc/xprtsock.h index 2c6c2c2783..c2a46c45c8 100644 --- a/include/linux/sunrpc/xprtsock.h +++ b/include/linux/sunrpc/xprtsock.h | |||
| @@ -9,12 +9,6 @@ | |||
| 9 | 9 | ||
| 10 | #ifdef __KERNEL__ | 10 | #ifdef __KERNEL__ |
| 11 | 11 | ||
| 12 | /* | ||
| 13 | * Socket transport setup operations | ||
| 14 | */ | ||
| 15 | struct rpc_xprt *xs_setup_udp(struct xprt_create *args); | ||
| 16 | struct rpc_xprt *xs_setup_tcp(struct xprt_create *args); | ||
| 17 | |||
| 18 | int init_socket_xprt(void); | 12 | int init_socket_xprt(void); |
| 19 | void cleanup_socket_xprt(void); | 13 | void cleanup_socket_xprt(void); |
| 20 | 14 | ||
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 53995af9ca..a6e57d1c2e 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
| @@ -540,7 +540,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
| 540 | p = gss_fill_context(p, end, ctx, gss_msg->auth->mech); | 540 | p = gss_fill_context(p, end, ctx, gss_msg->auth->mech); |
| 541 | if (IS_ERR(p)) { | 541 | if (IS_ERR(p)) { |
| 542 | err = PTR_ERR(p); | 542 | err = PTR_ERR(p); |
| 543 | gss_msg->msg.errno = (err == -EACCES) ? -EACCES : -EAGAIN; | 543 | gss_msg->msg.errno = (err == -EAGAIN) ? -EAGAIN : -EACCES; |
| 544 | goto err_release_msg; | 544 | goto err_release_msg; |
| 545 | } | 545 | } |
| 546 | gss_msg->ctx = gss_get_ctx(ctx); | 546 | gss_msg->ctx = gss_get_ctx(ctx); |
| @@ -967,7 +967,7 @@ gss_validate(struct rpc_task *task, __be32 *p) | |||
| 967 | if (maj_stat == GSS_S_CONTEXT_EXPIRED) | 967 | if (maj_stat == GSS_S_CONTEXT_EXPIRED) |
| 968 | clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); | 968 | clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); |
| 969 | if (maj_stat) { | 969 | if (maj_stat) { |
| 970 | dprintk("RPC: %5u gss_validate: gss_verify_mic returned" | 970 | dprintk("RPC: %5u gss_validate: gss_verify_mic returned " |
| 971 | "error 0x%08x\n", task->tk_pid, maj_stat); | 971 | "error 0x%08x\n", task->tk_pid, maj_stat); |
| 972 | goto out_bad; | 972 | goto out_bad; |
| 973 | } | 973 | } |
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 9843eacef1..60c3dba545 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c | |||
| @@ -147,13 +147,17 @@ gss_import_sec_context_kerberos(const void *p, | |||
| 147 | p = simple_get_bytes(p, end, &tmp, sizeof(tmp)); | 147 | p = simple_get_bytes(p, end, &tmp, sizeof(tmp)); |
| 148 | if (IS_ERR(p)) | 148 | if (IS_ERR(p)) |
| 149 | goto out_err_free_ctx; | 149 | goto out_err_free_ctx; |
| 150 | if (tmp != SGN_ALG_DES_MAC_MD5) | 150 | if (tmp != SGN_ALG_DES_MAC_MD5) { |
| 151 | p = ERR_PTR(-ENOSYS); | ||
| 151 | goto out_err_free_ctx; | 152 | goto out_err_free_ctx; |
| 153 | } | ||
| 152 | p = simple_get_bytes(p, end, &tmp, sizeof(tmp)); | 154 | p = simple_get_bytes(p, end, &tmp, sizeof(tmp)); |
| 153 | if (IS_ERR(p)) | 155 | if (IS_ERR(p)) |
| 154 | goto out_err_free_ctx; | 156 | goto out_err_free_ctx; |
| 155 | if (tmp != SEAL_ALG_DES) | 157 | if (tmp != SEAL_ALG_DES) { |
| 158 | p = ERR_PTR(-ENOSYS); | ||
| 156 | goto out_err_free_ctx; | 159 | goto out_err_free_ctx; |
| 160 | } | ||
| 157 | p = simple_get_bytes(p, end, &ctx->endtime, sizeof(ctx->endtime)); | 161 | p = simple_get_bytes(p, end, &ctx->endtime, sizeof(ctx->endtime)); |
| 158 | if (IS_ERR(p)) | 162 | if (IS_ERR(p)) |
| 159 | goto out_err_free_ctx; | 163 | goto out_err_free_ctx; |
diff --git a/net/sunrpc/auth_gss/gss_krb5_seal.c b/net/sunrpc/auth_gss/gss_krb5_seal.c index 1c6eda5077..dedcbd6108 100644 --- a/net/sunrpc/auth_gss/gss_krb5_seal.c +++ b/net/sunrpc/auth_gss/gss_krb5_seal.c | |||
| @@ -83,6 +83,7 @@ gss_get_mic_kerberos(struct gss_ctx *gss_ctx, struct xdr_buf *text, | |||
| 83 | u32 seq_send; | 83 | u32 seq_send; |
| 84 | 84 | ||
| 85 | dprintk("RPC: gss_krb5_seal\n"); | 85 | dprintk("RPC: gss_krb5_seal\n"); |
| 86 | BUG_ON(ctx == NULL); | ||
| 86 | 87 | ||
| 87 | now = get_seconds(); | 88 | now = get_seconds(); |
| 88 | 89 | ||
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 18f0a8dcc0..c59f3ca2b4 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
| @@ -280,7 +280,7 @@ rpc_pipe_poll(struct file *filp, struct poll_table_struct *wait) | |||
| 280 | mask = POLLOUT | POLLWRNORM; | 280 | mask = POLLOUT | POLLWRNORM; |
| 281 | if (rpci->ops == NULL) | 281 | if (rpci->ops == NULL) |
| 282 | mask |= POLLERR | POLLHUP; | 282 | mask |= POLLERR | POLLHUP; |
| 283 | if (!list_empty(&rpci->pipe)) | 283 | if (filp->private_data || !list_empty(&rpci->pipe)) |
| 284 | mask |= POLLIN | POLLRDNORM; | 284 | mask |= POLLIN | POLLRDNORM; |
| 285 | return mask; | 285 | return mask; |
| 286 | } | 286 | } |
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index 1afeb3eb8e..6f2112dd9f 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c | |||
| @@ -89,7 +89,7 @@ static struct ctl_table_header *sunrpc_table_header; | |||
| 89 | 89 | ||
| 90 | static ctl_table xr_tunables_table[] = { | 90 | static ctl_table xr_tunables_table[] = { |
| 91 | { | 91 | { |
| 92 | .ctl_name = CTL_SLOTTABLE_RDMA, | 92 | .ctl_name = CTL_UNNUMBERED, |
| 93 | .procname = "rdma_slot_table_entries", | 93 | .procname = "rdma_slot_table_entries", |
| 94 | .data = &xprt_rdma_slot_table_entries, | 94 | .data = &xprt_rdma_slot_table_entries, |
| 95 | .maxlen = sizeof(unsigned int), | 95 | .maxlen = sizeof(unsigned int), |
| @@ -100,7 +100,7 @@ static ctl_table xr_tunables_table[] = { | |||
| 100 | .extra2 = &max_slot_table_size | 100 | .extra2 = &max_slot_table_size |
| 101 | }, | 101 | }, |
| 102 | { | 102 | { |
| 103 | .ctl_name = CTL_RDMA_MAXINLINEREAD, | 103 | .ctl_name = CTL_UNNUMBERED, |
| 104 | .procname = "rdma_max_inline_read", | 104 | .procname = "rdma_max_inline_read", |
| 105 | .data = &xprt_rdma_max_inline_read, | 105 | .data = &xprt_rdma_max_inline_read, |
| 106 | .maxlen = sizeof(unsigned int), | 106 | .maxlen = sizeof(unsigned int), |
| @@ -109,7 +109,7 @@ static ctl_table xr_tunables_table[] = { | |||
| 109 | .strategy = &sysctl_intvec, | 109 | .strategy = &sysctl_intvec, |
| 110 | }, | 110 | }, |
| 111 | { | 111 | { |
| 112 | .ctl_name = CTL_RDMA_MAXINLINEWRITE, | 112 | .ctl_name = CTL_UNNUMBERED, |
| 113 | .procname = "rdma_max_inline_write", | 113 | .procname = "rdma_max_inline_write", |
| 114 | .data = &xprt_rdma_max_inline_write, | 114 | .data = &xprt_rdma_max_inline_write, |
| 115 | .maxlen = sizeof(unsigned int), | 115 | .maxlen = sizeof(unsigned int), |
| @@ -118,7 +118,7 @@ static ctl_table xr_tunables_table[] = { | |||
| 118 | .strategy = &sysctl_intvec, | 118 | .strategy = &sysctl_intvec, |
| 119 | }, | 119 | }, |
| 120 | { | 120 | { |
| 121 | .ctl_name = CTL_RDMA_WRITEPADDING, | 121 | .ctl_name = CTL_UNNUMBERED, |
| 122 | .procname = "rdma_inline_write_padding", | 122 | .procname = "rdma_inline_write_padding", |
| 123 | .data = &xprt_rdma_inline_write_padding, | 123 | .data = &xprt_rdma_inline_write_padding, |
| 124 | .maxlen = sizeof(unsigned int), | 124 | .maxlen = sizeof(unsigned int), |
| @@ -129,7 +129,7 @@ static ctl_table xr_tunables_table[] = { | |||
| 129 | .extra2 = &max_padding, | 129 | .extra2 = &max_padding, |
| 130 | }, | 130 | }, |
| 131 | { | 131 | { |
| 132 | .ctl_name = CTL_RDMA_MEMREG, | 132 | .ctl_name = CTL_UNNUMBERED, |
| 133 | .procname = "rdma_memreg_strategy", | 133 | .procname = "rdma_memreg_strategy", |
| 134 | .data = &xprt_rdma_memreg_strategy, | 134 | .data = &xprt_rdma_memreg_strategy, |
| 135 | .maxlen = sizeof(unsigned int), | 135 | .maxlen = sizeof(unsigned int), |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 02298f529d..2f630a512a 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
| @@ -1828,7 +1828,7 @@ static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args, | |||
| 1828 | * @args: rpc transport creation arguments | 1828 | * @args: rpc transport creation arguments |
| 1829 | * | 1829 | * |
| 1830 | */ | 1830 | */ |
| 1831 | struct rpc_xprt *xs_setup_udp(struct xprt_create *args) | 1831 | static struct rpc_xprt *xs_setup_udp(struct xprt_create *args) |
| 1832 | { | 1832 | { |
| 1833 | struct sockaddr *addr = args->dstaddr; | 1833 | struct sockaddr *addr = args->dstaddr; |
| 1834 | struct rpc_xprt *xprt; | 1834 | struct rpc_xprt *xprt; |
| @@ -1894,7 +1894,7 @@ struct rpc_xprt *xs_setup_udp(struct xprt_create *args) | |||
| 1894 | * @args: rpc transport creation arguments | 1894 | * @args: rpc transport creation arguments |
| 1895 | * | 1895 | * |
| 1896 | */ | 1896 | */ |
| 1897 | struct rpc_xprt *xs_setup_tcp(struct xprt_create *args) | 1897 | static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args) |
| 1898 | { | 1898 | { |
| 1899 | struct sockaddr *addr = args->dstaddr; | 1899 | struct sockaddr *addr = args->dstaddr; |
| 1900 | struct rpc_xprt *xprt; | 1900 | struct rpc_xprt *xprt; |
