@@ -784,6 +784,14 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
784
784
return status ;
785
785
}
786
786
787
+
788
+ static void
789
+ nfsd4_read_release (union nfsd4_op_u * u )
790
+ {
791
+ if (u -> read .rd_filp )
792
+ fput (u -> read .rd_filp );
793
+ }
794
+
787
795
static __be32
788
796
nfsd4_readdir (struct svc_rqst * rqstp , struct nfsd4_compound_state * cstate ,
789
797
union nfsd4_op_u * u )
@@ -912,6 +920,13 @@ nfsd4_secinfo_no_name(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstat
912
920
return nfs_ok ;
913
921
}
914
922
923
+ static void
924
+ nfsd4_secinfo_release (union nfsd4_op_u * u )
925
+ {
926
+ if (u -> secinfo .si_exp )
927
+ exp_put (u -> secinfo .si_exp );
928
+ }
929
+
915
930
static __be32
916
931
nfsd4_setattr (struct svc_rqst * rqstp , struct nfsd4_compound_state * cstate ,
917
932
union nfsd4_op_u * u )
@@ -1335,6 +1350,12 @@ nfsd4_getdeviceinfo(struct svc_rqst *rqstp,
1335
1350
return nfserr ;
1336
1351
}
1337
1352
1353
+ static void
1354
+ nfsd4_getdeviceinfo_release (union nfsd4_op_u * u )
1355
+ {
1356
+ kfree (u -> getdeviceinfo .gd_device );
1357
+ }
1358
+
1338
1359
static __be32
1339
1360
nfsd4_layoutget (struct svc_rqst * rqstp ,
1340
1361
struct nfsd4_compound_state * cstate , union nfsd4_op_u * u )
@@ -1415,6 +1436,12 @@ nfsd4_layoutget(struct svc_rqst *rqstp,
1415
1436
return nfserr ;
1416
1437
}
1417
1438
1439
+ static void
1440
+ nfsd4_layoutget_release (union nfsd4_op_u * u )
1441
+ {
1442
+ kfree (u -> layoutget .lg_content );
1443
+ }
1444
+
1418
1445
static __be32
1419
1446
nfsd4_layoutcommit (struct svc_rqst * rqstp ,
1420
1447
struct nfsd4_compound_state * cstate , union nfsd4_op_u * u )
@@ -1541,49 +1568,6 @@ static inline void nfsd4_increment_op_stats(u32 opnum)
1541
1568
nfsdstats .nfs4_opcount [opnum ]++ ;
1542
1569
}
1543
1570
1544
- enum nfsd4_op_flags {
1545
- ALLOWED_WITHOUT_FH = 1 << 0 , /* No current filehandle required */
1546
- ALLOWED_ON_ABSENT_FS = 1 << 1 , /* ops processed on absent fs */
1547
- ALLOWED_AS_FIRST_OP = 1 << 2 , /* ops reqired first in compound */
1548
- /* For rfc 5661 section 2.6.3.1.1: */
1549
- OP_HANDLES_WRONGSEC = 1 << 3 ,
1550
- OP_IS_PUTFH_LIKE = 1 << 4 ,
1551
- /*
1552
- * These are the ops whose result size we estimate before
1553
- * encoding, to avoid performing an op then not being able to
1554
- * respond or cache a response. This includes writes and setattrs
1555
- * as well as the operations usually called "nonidempotent":
1556
- */
1557
- OP_MODIFIES_SOMETHING = 1 << 5 ,
1558
- /*
1559
- * Cache compounds containing these ops in the xid-based drc:
1560
- * We use the DRC for compounds containing non-idempotent
1561
- * operations, *except* those that are 4.1-specific (since
1562
- * sessions provide their own EOS), and except for stateful
1563
- * operations other than setclientid and setclientid_confirm
1564
- * (since sequence numbers provide EOS for open, lock, etc in
1565
- * the v4.0 case).
1566
- */
1567
- OP_CACHEME = 1 << 6 ,
1568
- /*
1569
- * These are ops which clear current state id.
1570
- */
1571
- OP_CLEAR_STATEID = 1 << 7 ,
1572
- };
1573
-
1574
- struct nfsd4_operation {
1575
- __be32 (* op_func )(struct svc_rqst * , struct nfsd4_compound_state * ,
1576
- union nfsd4_op_u * );
1577
- u32 op_flags ;
1578
- char * op_name ;
1579
- /* Try to get response size before operation */
1580
- u32 (* op_rsize_bop )(struct svc_rqst * , struct nfsd4_op * );
1581
- void (* op_get_currentstateid )(struct nfsd4_compound_state * ,
1582
- union nfsd4_op_u * );
1583
- void (* op_set_currentstateid )(struct nfsd4_compound_state * ,
1584
- union nfsd4_op_u * );
1585
- };
1586
-
1587
1571
static const struct nfsd4_operation nfsd4_ops [];
1588
1572
1589
1573
static const char * nfsd4_op_name (unsigned opnum );
@@ -1621,7 +1605,7 @@ static __be32 nfs41_check_op_ordering(struct nfsd4_compoundargs *args)
1621
1605
return nfs_ok ;
1622
1606
}
1623
1607
1624
- static inline const struct nfsd4_operation * OPDESC (struct nfsd4_op * op )
1608
+ const struct nfsd4_operation * OPDESC (struct nfsd4_op * op )
1625
1609
{
1626
1610
return & nfsd4_ops [op -> opnum ];
1627
1611
}
@@ -1694,7 +1678,6 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
1694
1678
struct nfsd4_compoundargs * args = rqstp -> rq_argp ;
1695
1679
struct nfsd4_compoundres * resp = rqstp -> rq_resp ;
1696
1680
struct nfsd4_op * op ;
1697
- const struct nfsd4_operation * opdesc ;
1698
1681
struct nfsd4_compound_state * cstate = & resp -> cstate ;
1699
1682
struct svc_fh * current_fh = & cstate -> current_fh ;
1700
1683
struct svc_fh * save_fh = & cstate -> save_fh ;
@@ -1747,28 +1730,26 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
1747
1730
goto encode_op ;
1748
1731
}
1749
1732
1750
- opdesc = OPDESC (op );
1751
-
1752
1733
if (!current_fh -> fh_dentry ) {
1753
- if (!(opdesc -> op_flags & ALLOWED_WITHOUT_FH )) {
1734
+ if (!(op -> opdesc -> op_flags & ALLOWED_WITHOUT_FH )) {
1754
1735
op -> status = nfserr_nofilehandle ;
1755
1736
goto encode_op ;
1756
1737
}
1757
1738
} else if (current_fh -> fh_export -> ex_fslocs .migrated &&
1758
- !(opdesc -> op_flags & ALLOWED_ON_ABSENT_FS )) {
1739
+ !(op -> opdesc -> op_flags & ALLOWED_ON_ABSENT_FS )) {
1759
1740
op -> status = nfserr_moved ;
1760
1741
goto encode_op ;
1761
1742
}
1762
1743
1763
1744
fh_clear_wcc (current_fh );
1764
1745
1765
1746
/* If op is non-idempotent */
1766
- if (opdesc -> op_flags & OP_MODIFIES_SOMETHING ) {
1747
+ if (op -> opdesc -> op_flags & OP_MODIFIES_SOMETHING ) {
1767
1748
/*
1768
1749
* Don't execute this op if we couldn't encode a
1769
1750
* succesful reply:
1770
1751
*/
1771
- u32 plen = opdesc -> op_rsize_bop (rqstp , op );
1752
+ u32 plen = op -> opdesc -> op_rsize_bop (rqstp , op );
1772
1753
/*
1773
1754
* Plus if there's another operation, make sure
1774
1755
* we'll have space to at least encode an error:
@@ -1781,9 +1762,9 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
1781
1762
if (op -> status )
1782
1763
goto encode_op ;
1783
1764
1784
- if (opdesc -> op_get_currentstateid )
1785
- opdesc -> op_get_currentstateid (cstate , & op -> u );
1786
- op -> status = opdesc -> op_func (rqstp , cstate , & op -> u );
1765
+ if (op -> opdesc -> op_get_currentstateid )
1766
+ op -> opdesc -> op_get_currentstateid (cstate , & op -> u );
1767
+ op -> status = op -> opdesc -> op_func (rqstp , cstate , & op -> u );
1787
1768
1788
1769
/* Only from SEQUENCE */
1789
1770
if (cstate -> status == nfserr_replay_cache ) {
@@ -1792,10 +1773,10 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
1792
1773
goto out ;
1793
1774
}
1794
1775
if (!op -> status ) {
1795
- if (opdesc -> op_set_currentstateid )
1796
- opdesc -> op_set_currentstateid (cstate , & op -> u );
1776
+ if (op -> opdesc -> op_set_currentstateid )
1777
+ op -> opdesc -> op_set_currentstateid (cstate , & op -> u );
1797
1778
1798
- if (opdesc -> op_flags & OP_CLEAR_STATEID )
1779
+ if (op -> opdesc -> op_flags & OP_CLEAR_STATEID )
1799
1780
clear_current_stateid (cstate );
1800
1781
1801
1782
if (need_wrongsec_check (rqstp ))
@@ -2160,13 +2141,15 @@ static const struct nfsd4_operation nfsd4_ops[] = {
2160
2141
},
2161
2142
[OP_LOCK ] = {
2162
2143
.op_func = nfsd4_lock ,
2163
- .op_flags = OP_MODIFIES_SOMETHING ,
2144
+ .op_flags = OP_MODIFIES_SOMETHING |
2145
+ OP_NONTRIVIAL_ERROR_ENCODE ,
2164
2146
.op_name = "OP_LOCK" ,
2165
2147
.op_rsize_bop = nfsd4_lock_rsize ,
2166
2148
.op_set_currentstateid = nfsd4_set_lockstateid ,
2167
2149
},
2168
2150
[OP_LOCKT ] = {
2169
2151
.op_func = nfsd4_lockt ,
2152
+ .op_flags = OP_NONTRIVIAL_ERROR_ENCODE ,
2170
2153
.op_name = "OP_LOCKT" ,
2171
2154
.op_rsize_bop = nfsd4_lock_rsize ,
2172
2155
},
@@ -2238,6 +2221,7 @@ static const struct nfsd4_operation nfsd4_ops[] = {
2238
2221
},
2239
2222
[OP_READ ] = {
2240
2223
.op_func = nfsd4_read ,
2224
+ .op_release = nfsd4_read_release ,
2241
2225
.op_name = "OP_READ" ,
2242
2226
.op_rsize_bop = nfsd4_read_rsize ,
2243
2227
.op_get_currentstateid = nfsd4_get_readstateid ,
@@ -2287,21 +2271,24 @@ static const struct nfsd4_operation nfsd4_ops[] = {
2287
2271
},
2288
2272
[OP_SECINFO ] = {
2289
2273
.op_func = nfsd4_secinfo ,
2274
+ .op_release = nfsd4_secinfo_release ,
2290
2275
.op_flags = OP_HANDLES_WRONGSEC ,
2291
2276
.op_name = "OP_SECINFO" ,
2292
2277
.op_rsize_bop = nfsd4_secinfo_rsize ,
2293
2278
},
2294
2279
[OP_SETATTR ] = {
2295
2280
.op_func = nfsd4_setattr ,
2296
2281
.op_name = "OP_SETATTR" ,
2297
- .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME ,
2282
+ .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME
2283
+ | OP_NONTRIVIAL_ERROR_ENCODE ,
2298
2284
.op_rsize_bop = nfsd4_setattr_rsize ,
2299
2285
.op_get_currentstateid = nfsd4_get_setattrstateid ,
2300
2286
},
2301
2287
[OP_SETCLIENTID ] = {
2302
2288
.op_func = nfsd4_setclientid ,
2303
2289
.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
2304
- | OP_MODIFIES_SOMETHING | OP_CACHEME ,
2290
+ | OP_MODIFIES_SOMETHING | OP_CACHEME
2291
+ | OP_NONTRIVIAL_ERROR_ENCODE ,
2305
2292
.op_name = "OP_SETCLIENTID" ,
2306
2293
.op_rsize_bop = nfsd4_setclientid_rsize ,
2307
2294
},
@@ -2388,6 +2375,7 @@ static const struct nfsd4_operation nfsd4_ops[] = {
2388
2375
},
2389
2376
[OP_SECINFO_NO_NAME ] = {
2390
2377
.op_func = nfsd4_secinfo_no_name ,
2378
+ .op_release = nfsd4_secinfo_release ,
2391
2379
.op_flags = OP_HANDLES_WRONGSEC ,
2392
2380
.op_name = "OP_SECINFO_NO_NAME" ,
2393
2381
.op_rsize_bop = nfsd4_secinfo_rsize ,
@@ -2408,12 +2396,14 @@ static const struct nfsd4_operation nfsd4_ops[] = {
2408
2396
#ifdef CONFIG_NFSD_PNFS
2409
2397
[OP_GETDEVICEINFO ] = {
2410
2398
.op_func = nfsd4_getdeviceinfo ,
2399
+ .op_release = nfsd4_getdeviceinfo_release ,
2411
2400
.op_flags = ALLOWED_WITHOUT_FH ,
2412
2401
.op_name = "OP_GETDEVICEINFO" ,
2413
2402
.op_rsize_bop = nfsd4_getdeviceinfo_rsize ,
2414
2403
},
2415
2404
[OP_LAYOUTGET ] = {
2416
2405
.op_func = nfsd4_layoutget ,
2406
+ .op_release = nfsd4_layoutget_release ,
2417
2407
.op_flags = OP_MODIFIES_SOMETHING ,
2418
2408
.op_name = "OP_LAYOUTGET" ,
2419
2409
.op_rsize_bop = nfsd4_layoutget_rsize ,
0 commit comments