read_collect.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /* Network filesystem read subrequest result collection, assessment and
  3. * retrying.
  4. *
  5. * Copyright (C) 2024 Red Hat, Inc. All Rights Reserved.
  6. * Written by David Howells (dhowells@redhat.com)
  7. */
  8. #include <linux/export.h>
  9. #include <linux/fs.h>
  10. #include <linux/mm.h>
  11. #include <linux/pagemap.h>
  12. #include <linux/slab.h>
  13. #include <linux/task_io_accounting_ops.h>
  14. #include "internal.h"
  15. /* Notes made in the collector */
  16. #define HIT_PENDING 0x01 /* A front op was still pending */
  17. #define MADE_PROGRESS 0x04 /* Made progress cleaning up a stream or the folio set */
  18. #define BUFFERED 0x08 /* The pagecache needs cleaning up */
  19. #define NEED_RETRY 0x10 /* A front op requests retrying */
  20. #define COPY_TO_CACHE 0x40 /* Need to copy subrequest to cache */
  21. #define ABANDON_SREQ 0x80 /* Need to abandon untransferred part of subrequest */
  22. /*
  23. * Clear the unread part of an I/O request.
  24. */
  25. static void netfs_clear_unread(struct netfs_io_subrequest *subreq)
  26. {
  27. netfs_reset_iter(subreq);
  28. WARN_ON_ONCE(subreq->len - subreq->transferred != iov_iter_count(&subreq->io_iter));
  29. iov_iter_zero(iov_iter_count(&subreq->io_iter), &subreq->io_iter);
  30. if (subreq->start + subreq->transferred >= subreq->rreq->i_size)
  31. __set_bit(NETFS_SREQ_HIT_EOF, &subreq->flags);
  32. }
  33. /*
  34. * Flush, mark and unlock a folio that's now completely read. If we want to
  35. * cache the folio, we set the group to NETFS_FOLIO_COPY_TO_CACHE, mark it
  36. * dirty and let writeback handle it.
  37. */
  38. static void netfs_unlock_read_folio(struct netfs_io_request *rreq,
  39. struct folio_queue *folioq,
  40. int slot)
  41. {
  42. struct netfs_folio *finfo;
  43. struct folio *folio = folioq_folio(folioq, slot);
  44. if (unlikely(folio_pos(folio) < rreq->abandon_to)) {
  45. trace_netfs_folio(folio, netfs_folio_trace_abandon);
  46. goto just_unlock;
  47. }
  48. flush_dcache_folio(folio);
  49. folio_mark_uptodate(folio);
  50. if (!test_bit(NETFS_RREQ_USE_PGPRIV2, &rreq->flags)) {
  51. finfo = netfs_folio_info(folio);
  52. if (finfo) {
  53. trace_netfs_folio(folio, netfs_folio_trace_filled_gaps);
  54. if (finfo->netfs_group)
  55. folio_change_private(folio, finfo->netfs_group);
  56. else
  57. folio_detach_private(folio);
  58. kfree(finfo);
  59. }
  60. if (test_bit(NETFS_RREQ_FOLIO_COPY_TO_CACHE, &rreq->flags)) {
  61. if (!WARN_ON_ONCE(folio_get_private(folio) != NULL)) {
  62. trace_netfs_folio(folio, netfs_folio_trace_copy_to_cache);
  63. folio_attach_private(folio, NETFS_FOLIO_COPY_TO_CACHE);
  64. folio_mark_dirty(folio);
  65. }
  66. } else {
  67. trace_netfs_folio(folio, netfs_folio_trace_read_done);
  68. }
  69. folioq_clear(folioq, slot);
  70. } else {
  71. // TODO: Use of PG_private_2 is deprecated.
  72. if (test_bit(NETFS_RREQ_FOLIO_COPY_TO_CACHE, &rreq->flags))
  73. netfs_pgpriv2_copy_to_cache(rreq, folio);
  74. }
  75. just_unlock:
  76. if (folio->index == rreq->no_unlock_folio &&
  77. test_bit(NETFS_RREQ_NO_UNLOCK_FOLIO, &rreq->flags)) {
  78. _debug("no unlock");
  79. } else {
  80. trace_netfs_folio(folio, netfs_folio_trace_read_unlock);
  81. folio_unlock(folio);
  82. }
  83. folioq_clear(folioq, slot);
  84. }
  85. /*
  86. * Unlock any folios we've finished with.
  87. */
  88. static void netfs_read_unlock_folios(struct netfs_io_request *rreq,
  89. unsigned int *notes)
  90. {
  91. struct folio_queue *folioq = rreq->buffer.tail;
  92. unsigned long long collected_to = rreq->collected_to;
  93. unsigned int slot = rreq->buffer.first_tail_slot;
  94. if (rreq->cleaned_to >= rreq->collected_to)
  95. return;
  96. // TODO: Begin decryption
  97. if (slot >= folioq_nr_slots(folioq)) {
  98. folioq = rolling_buffer_delete_spent(&rreq->buffer);
  99. if (!folioq) {
  100. rreq->front_folio_order = 0;
  101. return;
  102. }
  103. slot = 0;
  104. }
  105. for (;;) {
  106. struct folio *folio;
  107. unsigned long long fpos, fend;
  108. unsigned int order;
  109. size_t fsize;
  110. if (*notes & COPY_TO_CACHE)
  111. set_bit(NETFS_RREQ_FOLIO_COPY_TO_CACHE, &rreq->flags);
  112. folio = folioq_folio(folioq, slot);
  113. if (WARN_ONCE(!folio_test_locked(folio),
  114. "R=%08x: folio %lx is not locked\n",
  115. rreq->debug_id, folio->index))
  116. trace_netfs_folio(folio, netfs_folio_trace_not_locked);
  117. order = folioq_folio_order(folioq, slot);
  118. rreq->front_folio_order = order;
  119. fsize = PAGE_SIZE << order;
  120. fpos = folio_pos(folio);
  121. fend = fpos + fsize;
  122. trace_netfs_collect_folio(rreq, folio, fend, collected_to);
  123. /* Unlock any folio we've transferred all of. */
  124. if (collected_to < fend)
  125. break;
  126. netfs_unlock_read_folio(rreq, folioq, slot);
  127. WRITE_ONCE(rreq->cleaned_to, fpos + fsize);
  128. *notes |= MADE_PROGRESS;
  129. clear_bit(NETFS_RREQ_FOLIO_COPY_TO_CACHE, &rreq->flags);
  130. /* Clean up the head folioq. If we clear an entire folioq, then
  131. * we can get rid of it provided it's not also the tail folioq
  132. * being filled by the issuer.
  133. */
  134. folioq_clear(folioq, slot);
  135. slot++;
  136. if (slot >= folioq_nr_slots(folioq)) {
  137. folioq = rolling_buffer_delete_spent(&rreq->buffer);
  138. if (!folioq)
  139. goto done;
  140. slot = 0;
  141. trace_netfs_folioq(folioq, netfs_trace_folioq_read_progress);
  142. }
  143. if (fpos + fsize >= collected_to)
  144. break;
  145. }
  146. rreq->buffer.tail = folioq;
  147. done:
  148. rreq->buffer.first_tail_slot = slot;
  149. }
  150. /*
  151. * Collect and assess the results of various read subrequests. We may need to
  152. * retry some of the results.
  153. *
  154. * Note that we have a sequence of subrequests, which may be drawing on
  155. * different sources and may or may not be the same size or starting position
  156. * and may not even correspond in boundary alignment.
  157. */
  158. static void netfs_collect_read_results(struct netfs_io_request *rreq)
  159. {
  160. struct netfs_io_subrequest *front, *remove;
  161. struct netfs_io_stream *stream = &rreq->io_streams[0];
  162. unsigned int notes;
  163. _enter("%llx-%llx", rreq->start, rreq->start + rreq->len);
  164. trace_netfs_rreq(rreq, netfs_rreq_trace_collect);
  165. trace_netfs_collect(rreq);
  166. reassess:
  167. if (rreq->origin == NETFS_READAHEAD ||
  168. rreq->origin == NETFS_READPAGE ||
  169. rreq->origin == NETFS_READ_FOR_WRITE)
  170. notes = BUFFERED;
  171. else
  172. notes = 0;
  173. /* Remove completed subrequests from the front of the stream and
  174. * advance the completion point. We stop when we hit something that's
  175. * in progress. The issuer thread may be adding stuff to the tail
  176. * whilst we're doing this.
  177. */
  178. front = list_first_entry_or_null(&stream->subrequests,
  179. struct netfs_io_subrequest, rreq_link);
  180. while (front) {
  181. size_t transferred;
  182. trace_netfs_collect_sreq(rreq, front);
  183. _debug("sreq [%x] %llx %zx/%zx",
  184. front->debug_index, front->start, front->transferred, front->len);
  185. if (stream->collected_to < front->start) {
  186. trace_netfs_collect_gap(rreq, stream, front->start, 'F');
  187. stream->collected_to = front->start;
  188. }
  189. if (netfs_check_subreq_in_progress(front))
  190. notes |= HIT_PENDING;
  191. smp_rmb(); /* Read counters after IN_PROGRESS flag. */
  192. transferred = READ_ONCE(front->transferred);
  193. /* If we can now collect the next folio, do so. We don't want
  194. * to defer this as we have to decide whether we need to copy
  195. * to the cache or not, and that may differ between adjacent
  196. * subreqs.
  197. */
  198. if (notes & BUFFERED) {
  199. size_t fsize = PAGE_SIZE << rreq->front_folio_order;
  200. /* Clear the tail of a short read. */
  201. if (!(notes & HIT_PENDING) &&
  202. front->error == 0 &&
  203. transferred < front->len &&
  204. (test_bit(NETFS_SREQ_HIT_EOF, &front->flags) ||
  205. test_bit(NETFS_SREQ_CLEAR_TAIL, &front->flags))) {
  206. netfs_clear_unread(front);
  207. transferred = front->transferred = front->len;
  208. trace_netfs_sreq(front, netfs_sreq_trace_clear);
  209. }
  210. stream->collected_to = front->start + transferred;
  211. rreq->collected_to = stream->collected_to;
  212. if (test_bit(NETFS_SREQ_COPY_TO_CACHE, &front->flags))
  213. notes |= COPY_TO_CACHE;
  214. if (test_bit(NETFS_SREQ_FAILED, &front->flags)) {
  215. rreq->abandon_to = front->start + front->len;
  216. front->transferred = front->len;
  217. transferred = front->len;
  218. trace_netfs_rreq(rreq, netfs_rreq_trace_set_abandon);
  219. }
  220. if (front->start + transferred >= rreq->cleaned_to + fsize ||
  221. test_bit(NETFS_SREQ_HIT_EOF, &front->flags))
  222. netfs_read_unlock_folios(rreq, &notes);
  223. } else {
  224. stream->collected_to = front->start + transferred;
  225. rreq->collected_to = stream->collected_to;
  226. }
  227. /* Stall if the front is still undergoing I/O. */
  228. if (notes & HIT_PENDING)
  229. break;
  230. if (test_bit(NETFS_SREQ_FAILED, &front->flags)) {
  231. if (!stream->failed) {
  232. stream->error = front->error;
  233. rreq->error = front->error;
  234. set_bit(NETFS_RREQ_FAILED, &rreq->flags);
  235. stream->failed = true;
  236. }
  237. notes |= MADE_PROGRESS | ABANDON_SREQ;
  238. } else if (test_bit(NETFS_SREQ_NEED_RETRY, &front->flags)) {
  239. stream->need_retry = true;
  240. notes |= NEED_RETRY | MADE_PROGRESS;
  241. break;
  242. } else if (test_bit(NETFS_RREQ_SHORT_TRANSFER, &rreq->flags)) {
  243. notes |= MADE_PROGRESS;
  244. } else {
  245. if (!stream->failed) {
  246. stream->transferred += transferred;
  247. stream->transferred_valid = true;
  248. }
  249. if (front->transferred < front->len)
  250. set_bit(NETFS_RREQ_SHORT_TRANSFER, &rreq->flags);
  251. notes |= MADE_PROGRESS;
  252. }
  253. /* Remove if completely consumed. */
  254. stream->source = front->source;
  255. spin_lock(&rreq->lock);
  256. remove = front;
  257. trace_netfs_sreq(front,
  258. notes & ABANDON_SREQ ?
  259. netfs_sreq_trace_abandoned : netfs_sreq_trace_consumed);
  260. list_del_init(&front->rreq_link);
  261. front = list_first_entry_or_null(&stream->subrequests,
  262. struct netfs_io_subrequest, rreq_link);
  263. spin_unlock(&rreq->lock);
  264. netfs_put_subrequest(remove,
  265. notes & ABANDON_SREQ ?
  266. netfs_sreq_trace_put_abandon :
  267. netfs_sreq_trace_put_done);
  268. }
  269. trace_netfs_collect_stream(rreq, stream);
  270. trace_netfs_collect_state(rreq, rreq->collected_to, notes);
  271. if (!(notes & BUFFERED))
  272. rreq->cleaned_to = rreq->collected_to;
  273. if (notes & NEED_RETRY)
  274. goto need_retry;
  275. if (notes & MADE_PROGRESS) {
  276. netfs_wake_rreq_flag(rreq, NETFS_RREQ_PAUSE, netfs_rreq_trace_unpause);
  277. //cond_resched();
  278. goto reassess;
  279. }
  280. out:
  281. _leave(" = %x", notes);
  282. return;
  283. need_retry:
  284. /* Okay... We're going to have to retry parts of the stream. Note
  285. * that any partially completed op will have had any wholly transferred
  286. * folios removed from it.
  287. */
  288. _debug("retry");
  289. netfs_retry_reads(rreq);
  290. goto out;
  291. }
  292. /*
  293. * Do page flushing and suchlike after DIO.
  294. */
  295. static void netfs_rreq_assess_dio(struct netfs_io_request *rreq)
  296. {
  297. unsigned int i;
  298. if (rreq->origin == NETFS_UNBUFFERED_READ ||
  299. rreq->origin == NETFS_DIO_READ) {
  300. for (i = 0; i < rreq->direct_bv_count; i++) {
  301. flush_dcache_page(rreq->direct_bv[i].bv_page);
  302. // TODO: cifs marks pages in the destination buffer
  303. // dirty under some circumstances after a read. Do we
  304. // need to do that too?
  305. set_page_dirty(rreq->direct_bv[i].bv_page);
  306. }
  307. }
  308. if (rreq->iocb) {
  309. rreq->iocb->ki_pos += rreq->transferred;
  310. if (rreq->iocb->ki_complete) {
  311. trace_netfs_rreq(rreq, netfs_rreq_trace_ki_complete);
  312. rreq->iocb->ki_complete(
  313. rreq->iocb, rreq->error ? rreq->error : rreq->transferred);
  314. }
  315. }
  316. if (rreq->netfs_ops->done)
  317. rreq->netfs_ops->done(rreq);
  318. if (rreq->origin == NETFS_UNBUFFERED_READ ||
  319. rreq->origin == NETFS_DIO_READ)
  320. inode_dio_end(rreq->inode);
  321. }
  322. /*
  323. * Do processing after reading a monolithic single object.
  324. */
  325. static void netfs_rreq_assess_single(struct netfs_io_request *rreq)
  326. {
  327. struct netfs_io_stream *stream = &rreq->io_streams[0];
  328. if (!rreq->error && stream->source == NETFS_DOWNLOAD_FROM_SERVER &&
  329. fscache_resources_valid(&rreq->cache_resources)) {
  330. trace_netfs_rreq(rreq, netfs_rreq_trace_dirty);
  331. netfs_single_mark_inode_dirty(rreq->inode);
  332. }
  333. if (rreq->iocb) {
  334. rreq->iocb->ki_pos += rreq->transferred;
  335. if (rreq->iocb->ki_complete) {
  336. trace_netfs_rreq(rreq, netfs_rreq_trace_ki_complete);
  337. rreq->iocb->ki_complete(
  338. rreq->iocb, rreq->error ? rreq->error : rreq->transferred);
  339. }
  340. }
  341. if (rreq->netfs_ops->done)
  342. rreq->netfs_ops->done(rreq);
  343. }
  344. /*
  345. * Perform the collection of subrequests and folios.
  346. *
  347. * Note that we're in normal kernel thread context at this point, possibly
  348. * running on a workqueue.
  349. */
  350. bool netfs_read_collection(struct netfs_io_request *rreq)
  351. {
  352. struct netfs_io_stream *stream = &rreq->io_streams[0];
  353. netfs_collect_read_results(rreq);
  354. /* We're done when the app thread has finished posting subreqs and the
  355. * queue is empty.
  356. */
  357. if (!test_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags))
  358. return false;
  359. smp_rmb(); /* Read ALL_QUEUED before subreq lists. */
  360. if (!list_empty(&stream->subrequests))
  361. return false;
  362. /* Okay, declare that all I/O is complete. */
  363. rreq->transferred = stream->transferred;
  364. trace_netfs_rreq(rreq, netfs_rreq_trace_complete);
  365. //netfs_rreq_is_still_valid(rreq);
  366. switch (rreq->origin) {
  367. case NETFS_UNBUFFERED_READ:
  368. case NETFS_DIO_READ:
  369. case NETFS_READ_GAPS:
  370. netfs_rreq_assess_dio(rreq);
  371. break;
  372. case NETFS_READ_SINGLE:
  373. netfs_rreq_assess_single(rreq);
  374. break;
  375. default:
  376. break;
  377. }
  378. task_io_account_read(rreq->transferred);
  379. netfs_wake_rreq_flag(rreq, NETFS_RREQ_IN_PROGRESS, netfs_rreq_trace_wake_ip);
  380. /* As we cleared NETFS_RREQ_IN_PROGRESS, we acquired its ref. */
  381. trace_netfs_rreq(rreq, netfs_rreq_trace_done);
  382. netfs_clear_subrequests(rreq);
  383. netfs_unlock_abandoned_read_pages(rreq);
  384. if (unlikely(rreq->copy_to_cache))
  385. netfs_pgpriv2_end_copy_to_cache(rreq);
  386. return true;
  387. }
  388. void netfs_read_collection_worker(struct work_struct *work)
  389. {
  390. struct netfs_io_request *rreq = container_of(work, struct netfs_io_request, work);
  391. netfs_see_request(rreq, netfs_rreq_trace_see_work);
  392. if (netfs_check_rreq_in_progress(rreq)) {
  393. if (netfs_read_collection(rreq))
  394. /* Drop the ref from the IN_PROGRESS flag. */
  395. netfs_put_request(rreq, netfs_rreq_trace_put_work_ip);
  396. else
  397. netfs_see_request(rreq, netfs_rreq_trace_see_work_complete);
  398. }
  399. }
  400. /**
  401. * netfs_read_subreq_progress - Note progress of a read operation.
  402. * @subreq: The read request that has terminated.
  403. *
  404. * This tells the read side of netfs lib that a contributory I/O operation has
  405. * made some progress and that it may be possible to unlock some folios.
  406. *
  407. * Before calling, the filesystem should update subreq->transferred to track
  408. * the amount of data copied into the output buffer.
  409. */
  410. void netfs_read_subreq_progress(struct netfs_io_subrequest *subreq)
  411. {
  412. struct netfs_io_request *rreq = subreq->rreq;
  413. struct netfs_io_stream *stream = &rreq->io_streams[0];
  414. size_t fsize = PAGE_SIZE << rreq->front_folio_order;
  415. trace_netfs_sreq(subreq, netfs_sreq_trace_progress);
  416. /* If we are at the head of the queue, wake up the collector,
  417. * getting a ref to it if we were the ones to do so.
  418. */
  419. if (subreq->start + subreq->transferred > rreq->cleaned_to + fsize &&
  420. (rreq->origin == NETFS_READAHEAD ||
  421. rreq->origin == NETFS_READPAGE ||
  422. rreq->origin == NETFS_READ_FOR_WRITE) &&
  423. list_is_first(&subreq->rreq_link, &stream->subrequests)
  424. ) {
  425. __set_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags);
  426. netfs_wake_collector(rreq);
  427. }
  428. }
  429. EXPORT_SYMBOL(netfs_read_subreq_progress);
  430. /**
  431. * netfs_read_subreq_terminated - Note the termination of an I/O operation.
  432. * @subreq: The I/O request that has terminated.
  433. *
  434. * This tells the read helper that a contributory I/O operation has terminated,
  435. * one way or another, and that it should integrate the results.
  436. *
  437. * The caller indicates the outcome of the operation through @subreq->error,
  438. * supplying 0 to indicate a successful or retryable transfer (if
  439. * NETFS_SREQ_NEED_RETRY is set) or a negative error code. The helper will
  440. * look after reissuing I/O operations as appropriate and writing downloaded
  441. * data to the cache.
  442. *
  443. * Before calling, the filesystem should update subreq->transferred to track
  444. * the amount of data copied into the output buffer.
  445. */
  446. void netfs_read_subreq_terminated(struct netfs_io_subrequest *subreq)
  447. {
  448. struct netfs_io_request *rreq = subreq->rreq;
  449. switch (subreq->source) {
  450. case NETFS_READ_FROM_CACHE:
  451. netfs_stat(&netfs_n_rh_read_done);
  452. break;
  453. case NETFS_DOWNLOAD_FROM_SERVER:
  454. netfs_stat(&netfs_n_rh_download_done);
  455. break;
  456. default:
  457. break;
  458. }
  459. /* Deal with retry requests, short reads and errors. If we retry
  460. * but don't make progress, we abandon the attempt.
  461. */
  462. if (!subreq->error && subreq->transferred < subreq->len) {
  463. if (test_bit(NETFS_SREQ_HIT_EOF, &subreq->flags)) {
  464. trace_netfs_sreq(subreq, netfs_sreq_trace_hit_eof);
  465. } else if (test_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags)) {
  466. trace_netfs_sreq(subreq, netfs_sreq_trace_need_clear);
  467. } else if (test_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags)) {
  468. trace_netfs_sreq(subreq, netfs_sreq_trace_need_retry);
  469. } else if (test_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags)) {
  470. __set_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags);
  471. trace_netfs_sreq(subreq, netfs_sreq_trace_partial_read);
  472. } else {
  473. __set_bit(NETFS_SREQ_FAILED, &subreq->flags);
  474. subreq->error = -ENODATA;
  475. trace_netfs_sreq(subreq, netfs_sreq_trace_short);
  476. }
  477. }
  478. /* If need retry is set, error should not matter unless we hit too many
  479. * retries. Pause the generation of new subreqs
  480. */
  481. if (test_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags)) {
  482. trace_netfs_rreq(rreq, netfs_rreq_trace_set_pause);
  483. set_bit(NETFS_RREQ_PAUSE, &rreq->flags);
  484. goto skip_error_checks;
  485. }
  486. if (unlikely(subreq->error < 0)) {
  487. trace_netfs_failure(rreq, subreq, subreq->error, netfs_fail_read);
  488. if (subreq->source == NETFS_READ_FROM_CACHE) {
  489. netfs_stat(&netfs_n_rh_read_failed);
  490. __set_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags);
  491. } else {
  492. netfs_stat(&netfs_n_rh_download_failed);
  493. __set_bit(NETFS_SREQ_FAILED, &subreq->flags);
  494. }
  495. trace_netfs_rreq(rreq, netfs_rreq_trace_set_pause);
  496. set_bit(NETFS_RREQ_PAUSE, &rreq->flags);
  497. }
  498. skip_error_checks:
  499. trace_netfs_sreq(subreq, netfs_sreq_trace_terminated);
  500. netfs_subreq_clear_in_progress(subreq);
  501. netfs_put_subrequest(subreq, netfs_sreq_trace_put_terminated);
  502. }
  503. EXPORT_SYMBOL(netfs_read_subreq_terminated);
  504. /*
  505. * Handle termination of a read from the cache.
  506. */
  507. void netfs_cache_read_terminated(void *priv, ssize_t transferred_or_error)
  508. {
  509. struct netfs_io_subrequest *subreq = priv;
  510. if (transferred_or_error > 0) {
  511. subreq->error = 0;
  512. if (transferred_or_error > 0) {
  513. subreq->transferred += transferred_or_error;
  514. __set_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags);
  515. }
  516. } else {
  517. subreq->error = transferred_or_error;
  518. }
  519. netfs_read_subreq_terminated(subreq);
  520. }