@@ -95,11 +95,15 @@ check_attr_support(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
95
95
u32 * bmval , u32 * writable )
96
96
{
97
97
struct dentry * dentry = cstate -> current_fh .fh_dentry ;
98
+ struct svc_export * exp = cstate -> current_fh .fh_export ;
98
99
99
100
if (!nfsd_attrs_supported (cstate -> minorversion , bmval ))
100
101
return nfserr_attrnotsupp ;
101
102
if ((bmval [0 ] & FATTR4_WORD0_ACL ) && !IS_POSIXACL (d_inode (dentry )))
102
103
return nfserr_attrnotsupp ;
104
+ if ((bmval [2 ] & FATTR4_WORD2_SECURITY_LABEL ) &&
105
+ !(exp -> ex_flags & NFSEXP_SECURITY_LABEL ))
106
+ return nfserr_attrnotsupp ;
103
107
if (writable && !bmval_is_subset (bmval , writable ))
104
108
return nfserr_inval ;
105
109
if (writable && (bmval [2 ] & FATTR4_WORD2_MODE_UMASK ) &&
@@ -983,7 +987,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
983
987
984
988
status = nfsd_vfs_write (rqstp , & cstate -> current_fh , filp ,
985
989
write -> wr_offset , rqstp -> rq_vec , nvecs , & cnt ,
986
- & write -> wr_how_written );
990
+ write -> wr_how_written );
987
991
fput (filp );
988
992
989
993
write -> wr_bytes_written = cnt ;
@@ -1838,6 +1842,12 @@ static inline u32 nfsd4_status_stateid_rsize(struct svc_rqst *rqstp, struct nfsd
1838
1842
return (op_encode_hdr_size + op_encode_stateid_maxsz )* sizeof (__be32 );
1839
1843
}
1840
1844
1845
+ static inline u32 nfsd4_access_rsize (struct svc_rqst * rqstp , struct nfsd4_op * op )
1846
+ {
1847
+ /* ac_supported, ac_resp_access */
1848
+ return (op_encode_hdr_size + 2 )* sizeof (__be32 );
1849
+ }
1850
+
1841
1851
static inline u32 nfsd4_commit_rsize (struct svc_rqst * rqstp , struct nfsd4_op * op )
1842
1852
{
1843
1853
return (op_encode_hdr_size + op_encode_verifier_maxsz ) * sizeof (__be32 );
@@ -1892,6 +1902,11 @@ static inline u32 nfsd4_getattr_rsize(struct svc_rqst *rqstp,
1892
1902
return ret ;
1893
1903
}
1894
1904
1905
+ static inline u32 nfsd4_getfh_rsize (struct svc_rqst * rqstp , struct nfsd4_op * op )
1906
+ {
1907
+ return (op_encode_hdr_size + 1 ) * sizeof (__be32 ) + NFS4_FHSIZE ;
1908
+ }
1909
+
1895
1910
static inline u32 nfsd4_link_rsize (struct svc_rqst * rqstp , struct nfsd4_op * op )
1896
1911
{
1897
1912
return (op_encode_hdr_size + op_encode_change_info_maxsz )
@@ -1933,6 +1948,11 @@ static inline u32 nfsd4_readdir_rsize(struct svc_rqst *rqstp, struct nfsd4_op *o
1933
1948
XDR_QUADLEN (rlen )) * sizeof (__be32 );
1934
1949
}
1935
1950
1951
+ static inline u32 nfsd4_readlink_rsize (struct svc_rqst * rqstp , struct nfsd4_op * op )
1952
+ {
1953
+ return (op_encode_hdr_size + 1 ) * sizeof (__be32 ) + PAGE_SIZE ;
1954
+ }
1955
+
1936
1956
static inline u32 nfsd4_remove_rsize (struct svc_rqst * rqstp , struct nfsd4_op * op )
1937
1957
{
1938
1958
return (op_encode_hdr_size + op_encode_change_info_maxsz )
@@ -1952,11 +1972,23 @@ static inline u32 nfsd4_sequence_rsize(struct svc_rqst *rqstp,
1952
1972
+ XDR_QUADLEN (NFS4_MAX_SESSIONID_LEN ) + 5 ) * sizeof (__be32 );
1953
1973
}
1954
1974
1975
+ static inline u32 nfsd4_test_stateid_rsize (struct svc_rqst * rqstp , struct nfsd4_op * op )
1976
+ {
1977
+ return (op_encode_hdr_size + 1 + op -> u .test_stateid .ts_num_ids )
1978
+ * sizeof (__be32 );
1979
+ }
1980
+
1955
1981
static inline u32 nfsd4_setattr_rsize (struct svc_rqst * rqstp , struct nfsd4_op * op )
1956
1982
{
1957
1983
return (op_encode_hdr_size + nfs4_fattr_bitmap_maxsz ) * sizeof (__be32 );
1958
1984
}
1959
1985
1986
+ static inline u32 nfsd4_secinfo_rsize (struct svc_rqst * rqstp , struct nfsd4_op * op )
1987
+ {
1988
+ return (op_encode_hdr_size + RPC_AUTH_MAXFLAVOR *
1989
+ (4 + XDR_QUADLEN (GSS_OID_MAX_LEN ))) * sizeof (__be32 );
1990
+ }
1991
+
1960
1992
static inline u32 nfsd4_setclientid_rsize (struct svc_rqst * rqstp , struct nfsd4_op * op )
1961
1993
{
1962
1994
return (op_encode_hdr_size + 2 + XDR_QUADLEN (NFS4_VERIFIER_SIZE )) *
@@ -2011,6 +2043,19 @@ static inline u32 nfsd4_copy_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
2011
2043
}
2012
2044
2013
2045
#ifdef CONFIG_NFSD_PNFS
2046
+ static inline u32 nfsd4_getdeviceinfo_rsize (struct svc_rqst * rqstp , struct nfsd4_op * op )
2047
+ {
2048
+ u32 maxcount = 0 , rlen = 0 ;
2049
+
2050
+ maxcount = svc_max_payload (rqstp );
2051
+ rlen = min (op -> u .getdeviceinfo .gd_maxcount , maxcount );
2052
+
2053
+ return (op_encode_hdr_size +
2054
+ 1 /* gd_layout_type*/ +
2055
+ XDR_QUADLEN (rlen ) +
2056
+ 2 /* gd_notify_types */ ) * sizeof (__be32 );
2057
+ }
2058
+
2014
2059
/*
2015
2060
* At this stage we don't really know what layout driver will handle the request,
2016
2061
* so we need to define an arbitrary upper bound here.
@@ -2040,10 +2085,17 @@ static inline u32 nfsd4_layoutreturn_rsize(struct svc_rqst *rqstp, struct nfsd4_
2040
2085
}
2041
2086
#endif /* CONFIG_NFSD_PNFS */
2042
2087
2088
+
2089
+ static inline u32 nfsd4_seek_rsize (struct svc_rqst * rqstp , struct nfsd4_op * op )
2090
+ {
2091
+ return (op_encode_hdr_size + 3 ) * sizeof (__be32 );
2092
+ }
2093
+
2043
2094
static struct nfsd4_operation nfsd4_ops [] = {
2044
2095
[OP_ACCESS ] = {
2045
2096
.op_func = (nfsd4op_func )nfsd4_access ,
2046
2097
.op_name = "OP_ACCESS" ,
2098
+ .op_rsize_bop = (nfsd4op_rsize )nfsd4_access_rsize ,
2047
2099
},
2048
2100
[OP_CLOSE ] = {
2049
2101
.op_func = (nfsd4op_func )nfsd4_close ,
@@ -2081,6 +2133,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
2081
2133
[OP_GETFH ] = {
2082
2134
.op_func = (nfsd4op_func )nfsd4_getfh ,
2083
2135
.op_name = "OP_GETFH" ,
2136
+ .op_rsize_bop = (nfsd4op_rsize )nfsd4_getfh_rsize ,
2084
2137
},
2085
2138
[OP_LINK ] = {
2086
2139
.op_func = (nfsd4op_func )nfsd4_link ,
@@ -2099,6 +2152,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
2099
2152
[OP_LOCKT ] = {
2100
2153
.op_func = (nfsd4op_func )nfsd4_lockt ,
2101
2154
.op_name = "OP_LOCKT" ,
2155
+ .op_rsize_bop = (nfsd4op_rsize )nfsd4_lock_rsize ,
2102
2156
},
2103
2157
[OP_LOCKU ] = {
2104
2158
.op_func = (nfsd4op_func )nfsd4_locku ,
@@ -2111,15 +2165,18 @@ static struct nfsd4_operation nfsd4_ops[] = {
2111
2165
.op_func = (nfsd4op_func )nfsd4_lookup ,
2112
2166
.op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID ,
2113
2167
.op_name = "OP_LOOKUP" ,
2168
+ .op_rsize_bop = (nfsd4op_rsize )nfsd4_only_status_rsize ,
2114
2169
},
2115
2170
[OP_LOOKUPP ] = {
2116
2171
.op_func = (nfsd4op_func )nfsd4_lookupp ,
2117
2172
.op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID ,
2118
2173
.op_name = "OP_LOOKUPP" ,
2174
+ .op_rsize_bop = (nfsd4op_rsize )nfsd4_only_status_rsize ,
2119
2175
},
2120
2176
[OP_NVERIFY ] = {
2121
2177
.op_func = (nfsd4op_func )nfsd4_nverify ,
2122
2178
.op_name = "OP_NVERIFY" ,
2179
+ .op_rsize_bop = (nfsd4op_rsize )nfsd4_only_status_rsize ,
2123
2180
},
2124
2181
[OP_OPEN ] = {
2125
2182
.op_func = (nfsd4op_func )nfsd4_open ,
@@ -2177,6 +2234,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
2177
2234
[OP_READLINK ] = {
2178
2235
.op_func = (nfsd4op_func )nfsd4_readlink ,
2179
2236
.op_name = "OP_READLINK" ,
2237
+ .op_rsize_bop = (nfsd4op_rsize )nfsd4_readlink_rsize ,
2180
2238
},
2181
2239
[OP_REMOVE ] = {
2182
2240
.op_func = (nfsd4op_func )nfsd4_remove ,
@@ -2215,6 +2273,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
2215
2273
.op_func = (nfsd4op_func )nfsd4_secinfo ,
2216
2274
.op_flags = OP_HANDLES_WRONGSEC ,
2217
2275
.op_name = "OP_SECINFO" ,
2276
+ .op_rsize_bop = (nfsd4op_rsize )nfsd4_secinfo_rsize ,
2218
2277
},
2219
2278
[OP_SETATTR ] = {
2220
2279
.op_func = (nfsd4op_func )nfsd4_setattr ,
@@ -2240,6 +2299,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
2240
2299
[OP_VERIFY ] = {
2241
2300
.op_func = (nfsd4op_func )nfsd4_verify ,
2242
2301
.op_name = "OP_VERIFY" ,
2302
+ .op_rsize_bop = (nfsd4op_rsize )nfsd4_only_status_rsize ,
2243
2303
},
2244
2304
[OP_WRITE ] = {
2245
2305
.op_func = (nfsd4op_func )nfsd4_write ,
@@ -2314,11 +2374,13 @@ static struct nfsd4_operation nfsd4_ops[] = {
2314
2374
.op_func = (nfsd4op_func )nfsd4_secinfo_no_name ,
2315
2375
.op_flags = OP_HANDLES_WRONGSEC ,
2316
2376
.op_name = "OP_SECINFO_NO_NAME" ,
2377
+ .op_rsize_bop = (nfsd4op_rsize )nfsd4_secinfo_rsize ,
2317
2378
},
2318
2379
[OP_TEST_STATEID ] = {
2319
2380
.op_func = (nfsd4op_func )nfsd4_test_stateid ,
2320
2381
.op_flags = ALLOWED_WITHOUT_FH ,
2321
2382
.op_name = "OP_TEST_STATEID" ,
2383
+ .op_rsize_bop = (nfsd4op_rsize )nfsd4_test_stateid_rsize ,
2322
2384
},
2323
2385
[OP_FREE_STATEID ] = {
2324
2386
.op_func = (nfsd4op_func )nfsd4_free_stateid ,
@@ -2332,6 +2394,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
2332
2394
.op_func = (nfsd4op_func )nfsd4_getdeviceinfo ,
2333
2395
.op_flags = ALLOWED_WITHOUT_FH ,
2334
2396
.op_name = "OP_GETDEVICEINFO" ,
2397
+ .op_rsize_bop = (nfsd4op_rsize )nfsd4_getdeviceinfo_rsize ,
2335
2398
},
2336
2399
[OP_LAYOUTGET ] = {
2337
2400
.op_func = (nfsd4op_func )nfsd4_layoutget ,
@@ -2381,6 +2444,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
2381
2444
[OP_SEEK ] = {
2382
2445
.op_func = (nfsd4op_func )nfsd4_seek ,
2383
2446
.op_name = "OP_SEEK" ,
2447
+ .op_rsize_bop = (nfsd4op_rsize )nfsd4_seek_rsize ,
2384
2448
},
2385
2449
};
2386
2450
@@ -2425,14 +2489,11 @@ bool nfsd4_spo_must_allow(struct svc_rqst *rqstp)
2425
2489
2426
2490
int nfsd4_max_reply (struct svc_rqst * rqstp , struct nfsd4_op * op )
2427
2491
{
2428
- struct nfsd4_operation * opdesc ;
2429
- nfsd4op_rsize estimator ;
2430
-
2431
2492
if (op -> opnum == OP_ILLEGAL )
2432
2493
return op_encode_hdr_size * sizeof (__be32 );
2433
- opdesc = OPDESC ( op );
2434
- estimator = opdesc -> op_rsize_bop ;
2435
- return estimator ? estimator ( rqstp , op ) : PAGE_SIZE ;
2494
+
2495
+ BUG_ON ( OPDESC ( op ) -> op_rsize_bop == NULL ) ;
2496
+ return OPDESC ( op ) -> op_rsize_bop ( rqstp , op );
2436
2497
}
2437
2498
2438
2499
void warn_on_nonidempotent_op (struct nfsd4_op * op )
@@ -2476,12 +2537,13 @@ static struct svc_procedure nfsd_procedures4[2] = {
2476
2537
};
2477
2538
2478
2539
struct svc_version nfsd_version4 = {
2479
- .vs_vers = 4 ,
2480
- .vs_nproc = 2 ,
2481
- .vs_proc = nfsd_procedures4 ,
2482
- .vs_dispatch = nfsd_dispatch ,
2483
- .vs_xdrsize = NFS4_SVC_XDRSIZE ,
2484
- .vs_rpcb_optnl = 1 ,
2540
+ .vs_vers = 4 ,
2541
+ .vs_nproc = 2 ,
2542
+ .vs_proc = nfsd_procedures4 ,
2543
+ .vs_dispatch = nfsd_dispatch ,
2544
+ .vs_xdrsize = NFS4_SVC_XDRSIZE ,
2545
+ .vs_rpcb_optnl = true,
2546
+ .vs_need_cong_ctrl = true,
2485
2547
};
2486
2548
2487
2549
/*
0 commit comments