1313#include <linux/iversion.h>
1414#include <linux/ktime.h>
1515#include <linux/netfs.h>
16+ #include <trace/events/netfs.h>
1617
1718#include "super.h"
1819#include "mds_client.h"
@@ -205,21 +206,6 @@ static void ceph_netfs_expand_readahead(struct netfs_io_request *rreq)
205206 }
206207}
207208
208- static bool ceph_netfs_clamp_length (struct netfs_io_subrequest * subreq )
209- {
210- struct inode * inode = subreq -> rreq -> inode ;
211- struct ceph_fs_client * fsc = ceph_inode_to_fs_client (inode );
212- struct ceph_inode_info * ci = ceph_inode (inode );
213- u64 objno , objoff ;
214- u32 xlen ;
215-
216- /* Truncate the extent at the end of the current block */
217- ceph_calc_file_object_mapping (& ci -> i_layout , subreq -> start , subreq -> len ,
218- & objno , & objoff , & xlen );
219- subreq -> len = min (xlen , fsc -> mount_options -> rsize );
220- return true;
221- }
222-
223209static void finish_netfs_read (struct ceph_osd_request * req )
224210{
225211 struct inode * inode = req -> r_inode ;
@@ -264,7 +250,12 @@ static void finish_netfs_read(struct ceph_osd_request *req)
264250 calc_pages_for (osd_data -> alignment ,
265251 osd_data -> length ), false);
266252 }
267- netfs_subreq_terminated (subreq , err , false);
253+ if (err > 0 ) {
254+ subreq -> transferred = err ;
255+ err = 0 ;
256+ }
257+ trace_netfs_sreq (subreq , netfs_sreq_trace_io_progress );
258+ netfs_read_subreq_terminated (subreq , err , false);
268259 iput (req -> r_inode );
269260 ceph_dec_osd_stopping_blocker (fsc -> mdsc );
270261}
@@ -278,7 +269,6 @@ static bool ceph_netfs_issue_op_inline(struct netfs_io_subrequest *subreq)
278269 struct ceph_mds_request * req ;
279270 struct ceph_mds_client * mdsc = ceph_sb_to_mdsc (inode -> i_sb );
280271 struct ceph_inode_info * ci = ceph_inode (inode );
281- struct iov_iter iter ;
282272 ssize_t err = 0 ;
283273 size_t len ;
284274 int mode ;
@@ -301,6 +291,7 @@ static bool ceph_netfs_issue_op_inline(struct netfs_io_subrequest *subreq)
301291 req -> r_args .getattr .mask = cpu_to_le32 (CEPH_STAT_CAP_INLINE_DATA );
302292 req -> r_num_caps = 2 ;
303293
294+ trace_netfs_sreq (subreq , netfs_sreq_trace_submit );
304295 err = ceph_mdsc_do_request (mdsc , NULL , req );
305296 if (err < 0 )
306297 goto out ;
@@ -314,17 +305,36 @@ static bool ceph_netfs_issue_op_inline(struct netfs_io_subrequest *subreq)
314305 }
315306
316307 len = min_t (size_t , iinfo -> inline_len - subreq -> start , subreq -> len );
317- iov_iter_xarray (& iter , ITER_DEST , & rreq -> mapping -> i_pages , subreq -> start , len );
318- err = copy_to_iter (iinfo -> inline_data + subreq -> start , len , & iter );
319- if (err == 0 )
308+ err = copy_to_iter (iinfo -> inline_data + subreq -> start , len , & subreq -> io_iter );
309+ if (err == 0 ) {
320310 err = - EFAULT ;
311+ } else {
312+ subreq -> transferred += err ;
313+ err = 0 ;
314+ }
321315
322316 ceph_mdsc_put_request (req );
323317out :
324- netfs_subreq_terminated (subreq , err , false);
318+ netfs_read_subreq_terminated (subreq , err , false);
325319 return true;
326320}
327321
322+ static int ceph_netfs_prepare_read (struct netfs_io_subrequest * subreq )
323+ {
324+ struct netfs_io_request * rreq = subreq -> rreq ;
325+ struct inode * inode = rreq -> inode ;
326+ struct ceph_inode_info * ci = ceph_inode (inode );
327+ struct ceph_fs_client * fsc = ceph_inode_to_fs_client (inode );
328+ u64 objno , objoff ;
329+ u32 xlen ;
330+
331+ /* Truncate the extent at the end of the current block */
332+ ceph_calc_file_object_mapping (& ci -> i_layout , subreq -> start , subreq -> len ,
333+ & objno , & objoff , & xlen );
334+ rreq -> io_streams [0 ].sreq_max_len = umin (xlen , fsc -> mount_options -> rsize );
335+ return 0 ;
336+ }
337+
328338static void ceph_netfs_issue_read (struct netfs_io_subrequest * subreq )
329339{
330340 struct netfs_io_request * rreq = subreq -> rreq ;
@@ -334,9 +344,8 @@ static void ceph_netfs_issue_read(struct netfs_io_subrequest *subreq)
334344 struct ceph_client * cl = fsc -> client ;
335345 struct ceph_osd_request * req = NULL ;
336346 struct ceph_vino vino = ceph_vino (inode );
337- struct iov_iter iter ;
338- int err = 0 ;
339- u64 len = subreq -> len ;
347+ int err ;
348+ u64 len ;
340349 bool sparse = IS_ENCRYPTED (inode ) || ceph_test_mount_opt (fsc , SPARSEREAD );
341350 u64 off = subreq -> start ;
342351 int extent_cnt ;
@@ -349,6 +358,12 @@ static void ceph_netfs_issue_read(struct netfs_io_subrequest *subreq)
349358 if (ceph_has_inline_data (ci ) && ceph_netfs_issue_op_inline (subreq ))
350359 return ;
351360
361+ // TODO: This rounding here is slightly dodgy. It *should* work, for
362+ // now, as the cache only deals in blocks that are a multiple of
363+ // PAGE_SIZE and fscrypt blocks are at most PAGE_SIZE. What needs to
364+ // happen is for the fscrypt driving to be moved into netfslib and the
365+ // data in the cache also to be stored encrypted.
366+ len = subreq -> len ;
352367 ceph_fscrypt_adjust_off_and_len (inode , & off , & len );
353368
354369 req = ceph_osdc_new_request (& fsc -> client -> osdc , & ci -> i_layout , vino ,
@@ -371,8 +386,6 @@ static void ceph_netfs_issue_read(struct netfs_io_subrequest *subreq)
371386 doutc (cl , "%llx.%llx pos=%llu orig_len=%zu len=%llu\n" ,
372387 ceph_vinop (inode ), subreq -> start , subreq -> len , len );
373388
374- iov_iter_xarray (& iter , ITER_DEST , & rreq -> mapping -> i_pages , subreq -> start , len );
375-
376389 /*
377390 * FIXME: For now, use CEPH_OSD_DATA_TYPE_PAGES instead of _ITER for
378391 * encrypted inodes. We'd need infrastructure that handles an iov_iter
@@ -384,7 +397,7 @@ static void ceph_netfs_issue_read(struct netfs_io_subrequest *subreq)
384397 struct page * * pages ;
385398 size_t page_off ;
386399
387- err = iov_iter_get_pages_alloc2 (& iter , & pages , len , & page_off );
400+ err = iov_iter_get_pages_alloc2 (& subreq -> io_iter , & pages , len , & page_off );
388401 if (err < 0 ) {
389402 doutc (cl , "%llx.%llx failed to allocate pages, %d\n" ,
390403 ceph_vinop (inode ), err );
@@ -399,7 +412,7 @@ static void ceph_netfs_issue_read(struct netfs_io_subrequest *subreq)
399412 osd_req_op_extent_osd_data_pages (req , 0 , pages , len , 0 , false,
400413 false);
401414 } else {
402- osd_req_op_extent_osd_iter (req , 0 , & iter );
415+ osd_req_op_extent_osd_iter (req , 0 , & subreq -> io_iter );
403416 }
404417 if (!ceph_inc_osd_stopping_blocker (fsc -> mdsc )) {
405418 err = - EIO ;
@@ -410,17 +423,19 @@ static void ceph_netfs_issue_read(struct netfs_io_subrequest *subreq)
410423 req -> r_inode = inode ;
411424 ihold (inode );
412425
426+ trace_netfs_sreq (subreq , netfs_sreq_trace_submit );
413427 ceph_osdc_start_request (req -> r_osdc , req );
414428out :
415429 ceph_osdc_put_request (req );
416430 if (err )
417- netfs_subreq_terminated (subreq , err , false);
431+ netfs_read_subreq_terminated (subreq , err , false);
418432 doutc (cl , "%llx.%llx result %d\n" , ceph_vinop (inode ), err );
419433}
420434
421435static int ceph_init_request (struct netfs_io_request * rreq , struct file * file )
422436{
423437 struct inode * inode = rreq -> inode ;
438+ struct ceph_fs_client * fsc = ceph_inode_to_fs_client (inode );
424439 struct ceph_client * cl = ceph_inode_to_client (inode );
425440 int got = 0 , want = CEPH_CAP_FILE_CACHE ;
426441 struct ceph_netfs_request_data * priv ;
@@ -472,6 +487,7 @@ static int ceph_init_request(struct netfs_io_request *rreq, struct file *file)
472487
473488 priv -> caps = got ;
474489 rreq -> netfs_priv = priv ;
490+ rreq -> io_streams [0 ].sreq_max_len = fsc -> mount_options -> rsize ;
475491
476492out :
477493 if (ret < 0 )
@@ -496,9 +512,9 @@ static void ceph_netfs_free_request(struct netfs_io_request *rreq)
496512const struct netfs_request_ops ceph_netfs_ops = {
497513 .init_request = ceph_init_request ,
498514 .free_request = ceph_netfs_free_request ,
515+ .prepare_read = ceph_netfs_prepare_read ,
499516 .issue_read = ceph_netfs_issue_read ,
500517 .expand_readahead = ceph_netfs_expand_readahead ,
501- .clamp_length = ceph_netfs_clamp_length ,
502518 .check_write_begin = ceph_netfs_check_write_begin ,
503519};
504520
0 commit comments