1111#include <linux/nfs_mount.h>
1212#include <linux/nfs_page.h>
1313#include <linux/module.h>
14+ #include <linux/file.h>
1415#include <linux/sched/mm.h>
1516
1617#include <linux/sunrpc/metrics.h>
@@ -162,6 +163,21 @@ decode_name(struct xdr_stream *xdr, u32 *id)
162163 return 0 ;
163164}
164165
166+ static struct nfsd_file *
167+ ff_local_open_fh (struct nfs_client * clp , const struct cred * cred ,
168+ struct nfs_fh * fh , fmode_t mode )
169+ {
170+ if (mode & FMODE_WRITE ) {
171+ /*
172+ * Always request read and write access since this corresponds
173+ * to a rw layout.
174+ */
175+ mode |= FMODE_READ ;
176+ }
177+
178+ return nfs_local_open_fh (clp , cred , fh , mode );
179+ }
180+
165181static bool ff_mirror_match_fh (const struct nfs4_ff_layout_mirror * m1 ,
166182 const struct nfs4_ff_layout_mirror * m2 )
167183{
@@ -237,7 +253,7 @@ static struct nfs4_ff_layout_mirror *ff_layout_alloc_mirror(gfp_t gfp_flags)
237253
238254static void ff_layout_free_mirror (struct nfs4_ff_layout_mirror * mirror )
239255{
240- const struct cred * cred ;
256+ const struct cred * cred ;
241257
242258 ff_layout_remove_mirror (mirror );
243259 kfree (mirror -> fh_versions );
@@ -1756,6 +1772,7 @@ ff_layout_read_pagelist(struct nfs_pgio_header *hdr)
17561772 struct pnfs_layout_segment * lseg = hdr -> lseg ;
17571773 struct nfs4_pnfs_ds * ds ;
17581774 struct rpc_clnt * ds_clnt ;
1775+ struct nfsd_file * localio ;
17591776 struct nfs4_ff_layout_mirror * mirror ;
17601777 const struct cred * ds_cred ;
17611778 loff_t offset = hdr -> args .offset ;
@@ -1802,11 +1819,18 @@ ff_layout_read_pagelist(struct nfs_pgio_header *hdr)
18021819 hdr -> args .offset = offset ;
18031820 hdr -> mds_offset = offset ;
18041821
1822+ /* Start IO accounting for local read */
1823+ localio = ff_local_open_fh (ds -> ds_clp , ds_cred , fh , FMODE_READ );
1824+ if (localio ) {
1825+ hdr -> task .tk_start = ktime_get ();
1826+ ff_layout_read_record_layoutstats_start (& hdr -> task , hdr );
1827+ }
1828+
18051829 /* Perform an asynchronous read to ds */
18061830 nfs_initiate_pgio (ds_clnt , hdr , ds_cred , ds -> ds_clp -> rpc_ops ,
18071831 vers == 3 ? & ff_layout_read_call_ops_v3 :
18081832 & ff_layout_read_call_ops_v4 ,
1809- 0 , RPC_TASK_SOFTCONN , NULL );
1833+ 0 , RPC_TASK_SOFTCONN , localio );
18101834 put_cred (ds_cred );
18111835 return PNFS_ATTEMPTED ;
18121836
@@ -1826,6 +1850,7 @@ ff_layout_write_pagelist(struct nfs_pgio_header *hdr, int sync)
18261850 struct pnfs_layout_segment * lseg = hdr -> lseg ;
18271851 struct nfs4_pnfs_ds * ds ;
18281852 struct rpc_clnt * ds_clnt ;
1853+ struct nfsd_file * localio ;
18291854 struct nfs4_ff_layout_mirror * mirror ;
18301855 const struct cred * ds_cred ;
18311856 loff_t offset = hdr -> args .offset ;
@@ -1870,11 +1895,19 @@ ff_layout_write_pagelist(struct nfs_pgio_header *hdr, int sync)
18701895 */
18711896 hdr -> args .offset = offset ;
18721897
1898+ /* Start IO accounting for local write */
1899+ localio = ff_local_open_fh (ds -> ds_clp , ds_cred , fh ,
1900+ FMODE_READ |FMODE_WRITE );
1901+ if (localio ) {
1902+ hdr -> task .tk_start = ktime_get ();
1903+ ff_layout_write_record_layoutstats_start (& hdr -> task , hdr );
1904+ }
1905+
18731906 /* Perform an asynchronous write */
18741907 nfs_initiate_pgio (ds_clnt , hdr , ds_cred , ds -> ds_clp -> rpc_ops ,
18751908 vers == 3 ? & ff_layout_write_call_ops_v3 :
18761909 & ff_layout_write_call_ops_v4 ,
1877- sync , RPC_TASK_SOFTCONN , NULL );
1910+ sync , RPC_TASK_SOFTCONN , localio );
18781911 put_cred (ds_cred );
18791912 return PNFS_ATTEMPTED ;
18801913
@@ -1908,6 +1941,7 @@ static int ff_layout_initiate_commit(struct nfs_commit_data *data, int how)
19081941 struct pnfs_layout_segment * lseg = data -> lseg ;
19091942 struct nfs4_pnfs_ds * ds ;
19101943 struct rpc_clnt * ds_clnt ;
1944+ struct nfsd_file * localio ;
19111945 struct nfs4_ff_layout_mirror * mirror ;
19121946 const struct cred * ds_cred ;
19131947 u32 idx ;
@@ -1946,10 +1980,18 @@ static int ff_layout_initiate_commit(struct nfs_commit_data *data, int how)
19461980 if (fh )
19471981 data -> args .fh = fh ;
19481982
1983+ /* Start IO accounting for local commit */
1984+ localio = ff_local_open_fh (ds -> ds_clp , ds_cred , fh ,
1985+ FMODE_READ |FMODE_WRITE );
1986+ if (localio ) {
1987+ data -> task .tk_start = ktime_get ();
1988+ ff_layout_commit_record_layoutstats_start (& data -> task , data );
1989+ }
1990+
19491991 ret = nfs_initiate_commit (ds_clnt , data , ds -> ds_clp -> rpc_ops ,
19501992 vers == 3 ? & ff_layout_commit_call_ops_v3 :
19511993 & ff_layout_commit_call_ops_v4 ,
1952- how , RPC_TASK_SOFTCONN , NULL );
1994+ how , RPC_TASK_SOFTCONN , localio );
19531995 put_cred (ds_cred );
19541996 return ret ;
19551997out_err :
0 commit comments