diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-07 17:24:41 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-07 17:24:41 -0400 |
commit | 0d9f9e122c74583de15a86d1c660c08dc298f2c8 (patch) | |
tree | a04ad387e231db43db112753fa2eae23754189a9 /fs/nfsd/vfs.c | |
parent | df44f9f4f9b5d362b5a2d1c8444fe7e6d4c42653 (diff) | |
parent | 998db52c03cd293d16a457f1b396cea932244147 (diff) |
Merge branch 'for-2.6.36' of git://linux-nfs.org/~bfields/linux
* 'for-2.6.36' of git://linux-nfs.org/~bfields/linux: (34 commits)
nfsd4: fix file open accounting for RDWR opens
nfsd: don't allow setting maxblksize after svc created
nfsd: initialize nfsd versions before creating svc
net: sunrpc: removed duplicated #include
nfsd41: Fix a crash when a callback is retried
nfsd: fix startup/shutdown order bug
nfsd: minor nfsd read api cleanup
gcc-4.6: nfsd: fix initialized but not read warnings
nfsd4: share file descriptors between stateid's
nfsd4: fix openmode checking on IO using lock stateid
nfsd4: miscellaneous process_open2 cleanup
nfsd4: don't pretend to support write delegations
nfsd: bypass readahead cache when have struct file
nfsd: minor nfsd_svc() cleanup
nfsd: move more into nfsd_startup()
nfsd: just keep single lockd reference for nfsd
nfsd: clean up nfsd_create_serv error handling
nfsd: fix error handling in __write_ports_addxprt
nfsd: fix error handling when starting nfsd with rpcbind down
nfsd4: fix v4 state shutdown error paths
...
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r-- | fs/nfsd/vfs.c | 79 |
1 files changed, 42 insertions, 37 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 3c111120b619..9df85a13af28 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -604,7 +604,7 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, struct nfs4_ac | |||
604 | return error; | 604 | return error; |
605 | } | 605 | } |
606 | 606 | ||
607 | #endif /* defined(CONFIG_NFS_V4) */ | 607 | #endif /* defined(CONFIG_NFSD_V4) */ |
608 | 608 | ||
609 | #ifdef CONFIG_NFSD_V3 | 609 | #ifdef CONFIG_NFSD_V3 |
610 | /* | 610 | /* |
@@ -903,7 +903,6 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | |||
903 | loff_t offset, struct kvec *vec, int vlen, unsigned long *count) | 903 | loff_t offset, struct kvec *vec, int vlen, unsigned long *count) |
904 | { | 904 | { |
905 | struct inode *inode; | 905 | struct inode *inode; |
906 | struct raparms *ra; | ||
907 | mm_segment_t oldfs; | 906 | mm_segment_t oldfs; |
908 | __be32 err; | 907 | __be32 err; |
909 | int host_err; | 908 | int host_err; |
@@ -914,12 +913,6 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | |||
914 | if (svc_msnfs(fhp) && !lock_may_read(inode, offset, *count)) | 913 | if (svc_msnfs(fhp) && !lock_may_read(inode, offset, *count)) |
915 | goto out; | 914 | goto out; |
916 | 915 | ||
917 | /* Get readahead parameters */ | ||
918 | ra = nfsd_get_raparms(inode->i_sb->s_dev, inode->i_ino); | ||
919 | |||
920 | if (ra && ra->p_set) | ||
921 | file->f_ra = ra->p_ra; | ||
922 | |||
923 | if (file->f_op->splice_read && rqstp->rq_splice_ok) { | 916 | if (file->f_op->splice_read && rqstp->rq_splice_ok) { |
924 | struct splice_desc sd = { | 917 | struct splice_desc sd = { |
925 | .len = 0, | 918 | .len = 0, |
@@ -937,16 +930,6 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | |||
937 | set_fs(oldfs); | 930 | set_fs(oldfs); |
938 | } | 931 | } |
939 | 932 | ||
940 | /* Write back readahead params */ | ||
941 | if (ra) { | ||
942 | struct raparm_hbucket *rab = &raparm_hash[ra->p_hindex]; | ||
943 | spin_lock(&rab->pb_lock); | ||
944 | ra->p_ra = file->f_ra; | ||
945 | ra->p_set = 1; | ||
946 | ra->p_count--; | ||
947 | spin_unlock(&rab->pb_lock); | ||
948 | } | ||
949 | |||
950 | if (host_err >= 0) { | 933 | if (host_err >= 0) { |
951 | nfsdstats.io_read += host_err; | 934 | nfsdstats.io_read += host_err; |
952 | *count = host_err; | 935 | *count = host_err; |
@@ -1086,8 +1069,45 @@ out: | |||
1086 | * on entry. On return, *count contains the number of bytes actually read. | 1069 | * on entry. On return, *count contains the number of bytes actually read. |
1087 | * N.B. After this call fhp needs an fh_put | 1070 | * N.B. After this call fhp needs an fh_put |
1088 | */ | 1071 | */ |
1072 | __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, | ||
1073 | loff_t offset, struct kvec *vec, int vlen, unsigned long *count) | ||
1074 | { | ||
1075 | struct file *file; | ||
1076 | struct inode *inode; | ||
1077 | struct raparms *ra; | ||
1078 | __be32 err; | ||
1079 | |||
1080 | err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file); | ||
1081 | if (err) | ||
1082 | return err; | ||
1083 | |||
1084 | inode = file->f_path.dentry->d_inode; | ||
1085 | |||
1086 | /* Get readahead parameters */ | ||
1087 | ra = nfsd_get_raparms(inode->i_sb->s_dev, inode->i_ino); | ||
1088 | |||
1089 | if (ra && ra->p_set) | ||
1090 | file->f_ra = ra->p_ra; | ||
1091 | |||
1092 | err = nfsd_vfs_read(rqstp, fhp, file, offset, vec, vlen, count); | ||
1093 | |||
1094 | /* Write back readahead params */ | ||
1095 | if (ra) { | ||
1096 | struct raparm_hbucket *rab = &raparm_hash[ra->p_hindex]; | ||
1097 | spin_lock(&rab->pb_lock); | ||
1098 | ra->p_ra = file->f_ra; | ||
1099 | ra->p_set = 1; | ||
1100 | ra->p_count--; | ||
1101 | spin_unlock(&rab->pb_lock); | ||
1102 | } | ||
1103 | |||
1104 | nfsd_close(file); | ||
1105 | return err; | ||
1106 | } | ||
1107 | |||
1108 | /* As above, but use the provided file descriptor. */ | ||
1089 | __be32 | 1109 | __be32 |
1090 | nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | 1110 | nfsd_read_file(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, |
1091 | loff_t offset, struct kvec *vec, int vlen, | 1111 | loff_t offset, struct kvec *vec, int vlen, |
1092 | unsigned long *count) | 1112 | unsigned long *count) |
1093 | { | 1113 | { |
@@ -1099,13 +1119,8 @@ nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | |||
1099 | if (err) | 1119 | if (err) |
1100 | goto out; | 1120 | goto out; |
1101 | err = nfsd_vfs_read(rqstp, fhp, file, offset, vec, vlen, count); | 1121 | err = nfsd_vfs_read(rqstp, fhp, file, offset, vec, vlen, count); |
1102 | } else { | 1122 | } else /* Note file may still be NULL in NFSv4 special stateid case: */ |
1103 | err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file); | 1123 | err = nfsd_read(rqstp, fhp, offset, vec, vlen, count); |
1104 | if (err) | ||
1105 | goto out; | ||
1106 | err = nfsd_vfs_read(rqstp, fhp, file, offset, vec, vlen, count); | ||
1107 | nfsd_close(file); | ||
1108 | } | ||
1109 | out: | 1124 | out: |
1110 | return err; | 1125 | return err; |
1111 | } | 1126 | } |
@@ -1631,7 +1646,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, | |||
1631 | char *name, int len, struct svc_fh *tfhp) | 1646 | char *name, int len, struct svc_fh *tfhp) |
1632 | { | 1647 | { |
1633 | struct dentry *ddir, *dnew, *dold; | 1648 | struct dentry *ddir, *dnew, *dold; |
1634 | struct inode *dirp, *dest; | 1649 | struct inode *dirp; |
1635 | __be32 err; | 1650 | __be32 err; |
1636 | int host_err; | 1651 | int host_err; |
1637 | 1652 | ||
@@ -1659,7 +1674,6 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, | |||
1659 | goto out_nfserr; | 1674 | goto out_nfserr; |
1660 | 1675 | ||
1661 | dold = tfhp->fh_dentry; | 1676 | dold = tfhp->fh_dentry; |
1662 | dest = dold->d_inode; | ||
1663 | 1677 | ||
1664 | host_err = mnt_want_write(tfhp->fh_export->ex_path.mnt); | 1678 | host_err = mnt_want_write(tfhp->fh_export->ex_path.mnt); |
1665 | if (host_err) { | 1679 | if (host_err) { |
@@ -2038,7 +2052,6 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, | |||
2038 | struct dentry *dentry, int acc) | 2052 | struct dentry *dentry, int acc) |
2039 | { | 2053 | { |
2040 | struct inode *inode = dentry->d_inode; | 2054 | struct inode *inode = dentry->d_inode; |
2041 | struct path path; | ||
2042 | int err; | 2055 | int err; |
2043 | 2056 | ||
2044 | if (acc == NFSD_MAY_NOP) | 2057 | if (acc == NFSD_MAY_NOP) |
@@ -2111,15 +2124,7 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, | |||
2111 | if (err == -EACCES && S_ISREG(inode->i_mode) && | 2124 | if (err == -EACCES && S_ISREG(inode->i_mode) && |
2112 | acc == (NFSD_MAY_READ | NFSD_MAY_OWNER_OVERRIDE)) | 2125 | acc == (NFSD_MAY_READ | NFSD_MAY_OWNER_OVERRIDE)) |
2113 | err = inode_permission(inode, MAY_EXEC); | 2126 | err = inode_permission(inode, MAY_EXEC); |
2114 | if (err) | ||
2115 | goto nfsd_out; | ||
2116 | 2127 | ||
2117 | /* Do integrity (permission) checking now, but defer incrementing | ||
2118 | * IMA counts to the actual file open. | ||
2119 | */ | ||
2120 | path.mnt = exp->ex_path.mnt; | ||
2121 | path.dentry = dentry; | ||
2122 | nfsd_out: | ||
2123 | return err? nfserrno(err) : 0; | 2128 | return err? nfserrno(err) : 0; |
2124 | } | 2129 | } |
2125 | 2130 | ||