write_collect.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /* Network filesystem write subrequest result collection, assessment
  3. * and 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 "internal.h"
  14. /* Notes made in the collector */
  15. #define HIT_PENDING 0x01 /* A front op was still pending */
  16. #define NEED_REASSESS 0x02 /* Need to loop round and reassess */
  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 SAW_FAILURE 0x20 /* One stream or hit a permanent failure */
  21. /*
  22. * Successful completion of write of a folio to the server and/or cache. Note
  23. * that we are not allowed to lock the folio here on pain of deadlocking with
  24. * truncate.
  25. */
  26. int netfs_folio_written_back(struct folio *folio)
  27. {
  28. enum netfs_folio_trace why = netfs_folio_trace_clear;
  29. struct netfs_inode *ictx = netfs_inode(folio->mapping->host);
  30. struct netfs_folio *finfo;
  31. struct netfs_group *group = NULL;
  32. int gcount = 0;
  33. if ((finfo = netfs_folio_info(folio))) {
  34. /* Streaming writes cannot be redirtied whilst under writeback,
  35. * so discard the streaming record.
  36. */
  37. unsigned long long fend;
  38. fend = folio_pos(folio) + finfo->dirty_offset + finfo->dirty_len;
  39. if (fend > ictx->zero_point)
  40. ictx->zero_point = fend;
  41. folio_detach_private(folio);
  42. group = finfo->netfs_group;
  43. gcount++;
  44. kfree(finfo);
  45. why = netfs_folio_trace_clear_s;
  46. goto end_wb;
  47. }
  48. if ((group = netfs_folio_group(folio))) {
  49. if (group == NETFS_FOLIO_COPY_TO_CACHE) {
  50. why = netfs_folio_trace_clear_cc;
  51. folio_detach_private(folio);
  52. goto end_wb;
  53. }
  54. /* Need to detach the group pointer if the page didn't get
  55. * redirtied. If it has been redirtied, then it must be within
  56. * the same group.
  57. */
  58. why = netfs_folio_trace_redirtied;
  59. if (!folio_test_dirty(folio)) {
  60. folio_detach_private(folio);
  61. gcount++;
  62. why = netfs_folio_trace_clear_g;
  63. }
  64. }
  65. end_wb:
  66. trace_netfs_folio(folio, why);
  67. folio_end_writeback(folio);
  68. return gcount;
  69. }
  70. /*
  71. * Unlock any folios we've finished with.
  72. */
  73. static void netfs_writeback_unlock_folios(struct netfs_io_request *wreq,
  74. unsigned int *notes)
  75. {
  76. struct folio_queue *folioq = wreq->buffer;
  77. unsigned long long collected_to = wreq->collected_to;
  78. unsigned int slot = wreq->buffer_head_slot;
  79. if (wreq->origin == NETFS_PGPRIV2_COPY_TO_CACHE) {
  80. if (netfs_pgpriv2_unlock_copied_folios(wreq))
  81. *notes |= MADE_PROGRESS;
  82. return;
  83. }
  84. if (slot >= folioq_nr_slots(folioq)) {
  85. folioq = netfs_delete_buffer_head(wreq);
  86. slot = 0;
  87. }
  88. for (;;) {
  89. struct folio *folio;
  90. struct netfs_folio *finfo;
  91. unsigned long long fpos, fend;
  92. size_t fsize, flen;
  93. folio = folioq_folio(folioq, slot);
  94. if (WARN_ONCE(!folio_test_writeback(folio),
  95. "R=%08x: folio %lx is not under writeback\n",
  96. wreq->debug_id, folio->index))
  97. trace_netfs_folio(folio, netfs_folio_trace_not_under_wback);
  98. fpos = folio_pos(folio);
  99. fsize = folio_size(folio);
  100. finfo = netfs_folio_info(folio);
  101. flen = finfo ? finfo->dirty_offset + finfo->dirty_len : fsize;
  102. fend = min_t(unsigned long long, fpos + flen, wreq->i_size);
  103. trace_netfs_collect_folio(wreq, folio, fend, collected_to);
  104. /* Unlock any folio we've transferred all of. */
  105. if (collected_to < fend)
  106. break;
  107. wreq->nr_group_rel += netfs_folio_written_back(folio);
  108. wreq->cleaned_to = fpos + fsize;
  109. *notes |= MADE_PROGRESS;
  110. /* Clean up the head folioq. If we clear an entire folioq, then
  111. * we can get rid of it provided it's not also the tail folioq
  112. * being filled by the issuer.
  113. */
  114. folioq_clear(folioq, slot);
  115. slot++;
  116. if (slot >= folioq_nr_slots(folioq)) {
  117. if (READ_ONCE(wreq->buffer_tail) == folioq)
  118. break;
  119. folioq = netfs_delete_buffer_head(wreq);
  120. slot = 0;
  121. }
  122. if (fpos + fsize >= collected_to)
  123. break;
  124. }
  125. wreq->buffer = folioq;
  126. wreq->buffer_head_slot = slot;
  127. }
  128. /*
  129. * Perform retries on the streams that need it.
  130. */
  131. static void netfs_retry_write_stream(struct netfs_io_request *wreq,
  132. struct netfs_io_stream *stream)
  133. {
  134. struct list_head *next;
  135. _enter("R=%x[%x:]", wreq->debug_id, stream->stream_nr);
  136. if (list_empty(&stream->subrequests))
  137. return;
  138. if (stream->source == NETFS_UPLOAD_TO_SERVER &&
  139. wreq->netfs_ops->retry_request)
  140. wreq->netfs_ops->retry_request(wreq, stream);
  141. if (unlikely(stream->failed))
  142. return;
  143. /* If there's no renegotiation to do, just resend each failed subreq. */
  144. if (!stream->prepare_write) {
  145. struct netfs_io_subrequest *subreq;
  146. list_for_each_entry(subreq, &stream->subrequests, rreq_link) {
  147. if (test_bit(NETFS_SREQ_FAILED, &subreq->flags))
  148. break;
  149. if (__test_and_clear_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags)) {
  150. struct iov_iter source;
  151. netfs_reset_iter(subreq);
  152. source = subreq->io_iter;
  153. __set_bit(NETFS_SREQ_RETRYING, &subreq->flags);
  154. netfs_get_subrequest(subreq, netfs_sreq_trace_get_resubmit);
  155. netfs_reissue_write(stream, subreq, &source);
  156. }
  157. }
  158. return;
  159. }
  160. next = stream->subrequests.next;
  161. do {
  162. struct netfs_io_subrequest *subreq = NULL, *from, *to, *tmp;
  163. struct iov_iter source;
  164. unsigned long long start, len;
  165. size_t part;
  166. bool boundary = false;
  167. /* Go through the stream and find the next span of contiguous
  168. * data that we then rejig (cifs, for example, needs the wsize
  169. * renegotiating) and reissue.
  170. */
  171. from = list_entry(next, struct netfs_io_subrequest, rreq_link);
  172. to = from;
  173. start = from->start + from->transferred;
  174. len = from->len - from->transferred;
  175. if (test_bit(NETFS_SREQ_FAILED, &from->flags) ||
  176. !test_bit(NETFS_SREQ_NEED_RETRY, &from->flags))
  177. return;
  178. list_for_each_continue(next, &stream->subrequests) {
  179. subreq = list_entry(next, struct netfs_io_subrequest, rreq_link);
  180. if (subreq->start + subreq->transferred != start + len ||
  181. test_bit(NETFS_SREQ_BOUNDARY, &subreq->flags) ||
  182. !test_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags))
  183. break;
  184. to = subreq;
  185. len += to->len;
  186. }
  187. /* Determine the set of buffers we're going to use. Each
  188. * subreq gets a subset of a single overall contiguous buffer.
  189. */
  190. netfs_reset_iter(from);
  191. source = from->io_iter;
  192. source.count = len;
  193. /* Work through the sublist. */
  194. subreq = from;
  195. list_for_each_entry_from(subreq, &stream->subrequests, rreq_link) {
  196. if (!len)
  197. break;
  198. /* Renegotiate max_len (wsize) */
  199. trace_netfs_sreq(subreq, netfs_sreq_trace_retry);
  200. __clear_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags);
  201. __set_bit(NETFS_SREQ_RETRYING, &subreq->flags);
  202. stream->prepare_write(subreq);
  203. part = min(len, stream->sreq_max_len);
  204. subreq->len = part;
  205. subreq->start = start;
  206. subreq->transferred = 0;
  207. len -= part;
  208. start += part;
  209. if (len && subreq == to &&
  210. __test_and_clear_bit(NETFS_SREQ_BOUNDARY, &to->flags))
  211. boundary = true;
  212. netfs_get_subrequest(subreq, netfs_sreq_trace_get_resubmit);
  213. netfs_reissue_write(stream, subreq, &source);
  214. if (subreq == to)
  215. break;
  216. }
  217. /* If we managed to use fewer subreqs, we can discard the
  218. * excess; if we used the same number, then we're done.
  219. */
  220. if (!len) {
  221. if (subreq == to)
  222. continue;
  223. list_for_each_entry_safe_from(subreq, tmp,
  224. &stream->subrequests, rreq_link) {
  225. trace_netfs_sreq(subreq, netfs_sreq_trace_discard);
  226. list_del(&subreq->rreq_link);
  227. netfs_put_subrequest(subreq, false, netfs_sreq_trace_put_done);
  228. if (subreq == to)
  229. break;
  230. }
  231. continue;
  232. }
  233. /* We ran out of subrequests, so we need to allocate some more
  234. * and insert them after.
  235. */
  236. do {
  237. subreq = netfs_alloc_subrequest(wreq);
  238. subreq->source = to->source;
  239. subreq->start = start;
  240. subreq->debug_index = atomic_inc_return(&wreq->subreq_counter);
  241. subreq->stream_nr = to->stream_nr;
  242. __set_bit(NETFS_SREQ_RETRYING, &subreq->flags);
  243. trace_netfs_sreq_ref(wreq->debug_id, subreq->debug_index,
  244. refcount_read(&subreq->ref),
  245. netfs_sreq_trace_new);
  246. trace_netfs_sreq(subreq, netfs_sreq_trace_split);
  247. list_add(&subreq->rreq_link, &to->rreq_link);
  248. to = list_next_entry(to, rreq_link);
  249. trace_netfs_sreq(subreq, netfs_sreq_trace_retry);
  250. stream->sreq_max_len = len;
  251. stream->sreq_max_segs = INT_MAX;
  252. switch (stream->source) {
  253. case NETFS_UPLOAD_TO_SERVER:
  254. netfs_stat(&netfs_n_wh_upload);
  255. stream->sreq_max_len = umin(len, wreq->wsize);
  256. break;
  257. case NETFS_WRITE_TO_CACHE:
  258. netfs_stat(&netfs_n_wh_write);
  259. break;
  260. default:
  261. WARN_ON_ONCE(1);
  262. }
  263. stream->prepare_write(subreq);
  264. part = umin(len, stream->sreq_max_len);
  265. subreq->len = subreq->transferred + part;
  266. len -= part;
  267. start += part;
  268. if (!len && boundary) {
  269. __set_bit(NETFS_SREQ_BOUNDARY, &to->flags);
  270. boundary = false;
  271. }
  272. netfs_reissue_write(stream, subreq, &source);
  273. if (!len)
  274. break;
  275. } while (len);
  276. } while (!list_is_head(next, &stream->subrequests));
  277. }
  278. /*
  279. * Perform retries on the streams that need it. If we're doing content
  280. * encryption and the server copy changed due to a third-party write, we may
  281. * need to do an RMW cycle and also rewrite the data to the cache.
  282. */
  283. static void netfs_retry_writes(struct netfs_io_request *wreq)
  284. {
  285. struct netfs_io_subrequest *subreq;
  286. struct netfs_io_stream *stream;
  287. int s;
  288. /* Wait for all outstanding I/O to quiesce before performing retries as
  289. * we may need to renegotiate the I/O sizes.
  290. */
  291. for (s = 0; s < NR_IO_STREAMS; s++) {
  292. stream = &wreq->io_streams[s];
  293. if (!stream->active)
  294. continue;
  295. list_for_each_entry(subreq, &stream->subrequests, rreq_link) {
  296. wait_on_bit(&subreq->flags, NETFS_SREQ_IN_PROGRESS,
  297. TASK_UNINTERRUPTIBLE);
  298. }
  299. }
  300. // TODO: Enc: Fetch changed partial pages
  301. // TODO: Enc: Reencrypt content if needed.
  302. // TODO: Enc: Wind back transferred point.
  303. // TODO: Enc: Mark cache pages for retry.
  304. for (s = 0; s < NR_IO_STREAMS; s++) {
  305. stream = &wreq->io_streams[s];
  306. if (stream->need_retry) {
  307. stream->need_retry = false;
  308. netfs_retry_write_stream(wreq, stream);
  309. }
  310. }
  311. }
  312. /*
  313. * Collect and assess the results of various write subrequests. We may need to
  314. * retry some of the results - or even do an RMW cycle for content crypto.
  315. *
  316. * Note that we have a number of parallel, overlapping lists of subrequests,
  317. * one to the server and one to the local cache for example, which may not be
  318. * the same size or starting position and may not even correspond in boundary
  319. * alignment.
  320. */
  321. static void netfs_collect_write_results(struct netfs_io_request *wreq)
  322. {
  323. struct netfs_io_subrequest *front, *remove;
  324. struct netfs_io_stream *stream;
  325. unsigned long long collected_to, issued_to;
  326. unsigned int notes;
  327. int s;
  328. _enter("%llx-%llx", wreq->start, wreq->start + wreq->len);
  329. trace_netfs_collect(wreq);
  330. trace_netfs_rreq(wreq, netfs_rreq_trace_collect);
  331. reassess_streams:
  332. issued_to = atomic64_read(&wreq->issued_to);
  333. smp_rmb();
  334. collected_to = ULLONG_MAX;
  335. if (wreq->origin == NETFS_WRITEBACK ||
  336. wreq->origin == NETFS_WRITETHROUGH ||
  337. wreq->origin == NETFS_PGPRIV2_COPY_TO_CACHE)
  338. notes = BUFFERED;
  339. else
  340. notes = 0;
  341. /* Remove completed subrequests from the front of the streams and
  342. * advance the completion point on each stream. We stop when we hit
  343. * something that's in progress. The issuer thread may be adding stuff
  344. * to the tail whilst we're doing this.
  345. */
  346. for (s = 0; s < NR_IO_STREAMS; s++) {
  347. stream = &wreq->io_streams[s];
  348. /* Read active flag before list pointers */
  349. if (!smp_load_acquire(&stream->active))
  350. continue;
  351. front = stream->front;
  352. while (front) {
  353. trace_netfs_collect_sreq(wreq, front);
  354. //_debug("sreq [%x] %llx %zx/%zx",
  355. // front->debug_index, front->start, front->transferred, front->len);
  356. if (stream->collected_to < front->start) {
  357. trace_netfs_collect_gap(wreq, stream, issued_to, 'F');
  358. stream->collected_to = front->start;
  359. }
  360. /* Stall if the front is still undergoing I/O. */
  361. if (test_bit(NETFS_SREQ_IN_PROGRESS, &front->flags)) {
  362. notes |= HIT_PENDING;
  363. break;
  364. }
  365. smp_rmb(); /* Read counters after I-P flag. */
  366. if (stream->failed) {
  367. stream->collected_to = front->start + front->len;
  368. notes |= MADE_PROGRESS | SAW_FAILURE;
  369. goto cancel;
  370. }
  371. if (front->start + front->transferred > stream->collected_to) {
  372. stream->collected_to = front->start + front->transferred;
  373. stream->transferred = stream->collected_to - wreq->start;
  374. stream->transferred_valid = true;
  375. notes |= MADE_PROGRESS;
  376. }
  377. if (test_bit(NETFS_SREQ_FAILED, &front->flags)) {
  378. stream->failed = true;
  379. stream->error = front->error;
  380. if (stream->source == NETFS_UPLOAD_TO_SERVER)
  381. mapping_set_error(wreq->mapping, front->error);
  382. notes |= NEED_REASSESS | SAW_FAILURE;
  383. break;
  384. }
  385. if (front->transferred < front->len) {
  386. stream->need_retry = true;
  387. notes |= NEED_RETRY | MADE_PROGRESS;
  388. break;
  389. }
  390. cancel:
  391. /* Remove if completely consumed. */
  392. spin_lock_bh(&wreq->lock);
  393. remove = front;
  394. list_del_init(&front->rreq_link);
  395. front = list_first_entry_or_null(&stream->subrequests,
  396. struct netfs_io_subrequest, rreq_link);
  397. stream->front = front;
  398. spin_unlock_bh(&wreq->lock);
  399. netfs_put_subrequest(remove, false,
  400. notes & SAW_FAILURE ?
  401. netfs_sreq_trace_put_cancel :
  402. netfs_sreq_trace_put_done);
  403. }
  404. /* If we have an empty stream, we need to jump it forward
  405. * otherwise the collection point will never advance.
  406. */
  407. if (!front && issued_to > stream->collected_to) {
  408. trace_netfs_collect_gap(wreq, stream, issued_to, 'E');
  409. stream->collected_to = issued_to;
  410. }
  411. if (stream->collected_to < collected_to)
  412. collected_to = stream->collected_to;
  413. }
  414. if (collected_to != ULLONG_MAX && collected_to > wreq->collected_to)
  415. wreq->collected_to = collected_to;
  416. for (s = 0; s < NR_IO_STREAMS; s++) {
  417. stream = &wreq->io_streams[s];
  418. if (stream->active)
  419. trace_netfs_collect_stream(wreq, stream);
  420. }
  421. trace_netfs_collect_state(wreq, wreq->collected_to, notes);
  422. /* Unlock any folios that we have now finished with. */
  423. if (notes & BUFFERED) {
  424. if (wreq->cleaned_to < wreq->collected_to)
  425. netfs_writeback_unlock_folios(wreq, &notes);
  426. } else {
  427. wreq->cleaned_to = wreq->collected_to;
  428. }
  429. // TODO: Discard encryption buffers
  430. if (notes & NEED_RETRY)
  431. goto need_retry;
  432. if ((notes & MADE_PROGRESS) && test_bit(NETFS_RREQ_PAUSE, &wreq->flags)) {
  433. trace_netfs_rreq(wreq, netfs_rreq_trace_unpause);
  434. clear_and_wake_up_bit(NETFS_RREQ_PAUSE, &wreq->flags);
  435. }
  436. if (notes & NEED_REASSESS) {
  437. //cond_resched();
  438. goto reassess_streams;
  439. }
  440. if (notes & MADE_PROGRESS) {
  441. //cond_resched();
  442. goto reassess_streams;
  443. }
  444. out:
  445. netfs_put_group_many(wreq->group, wreq->nr_group_rel);
  446. wreq->nr_group_rel = 0;
  447. _leave(" = %x", notes);
  448. return;
  449. need_retry:
  450. /* Okay... We're going to have to retry one or both streams. Note
  451. * that any partially completed op will have had any wholly transferred
  452. * folios removed from it.
  453. */
  454. _debug("retry");
  455. netfs_retry_writes(wreq);
  456. goto out;
  457. }
  458. /*
  459. * Perform the collection of subrequests, folios and encryption buffers.
  460. */
  461. void netfs_write_collection_worker(struct work_struct *work)
  462. {
  463. struct netfs_io_request *wreq = container_of(work, struct netfs_io_request, work);
  464. struct netfs_inode *ictx = netfs_inode(wreq->inode);
  465. size_t transferred;
  466. bool transferred_valid = false;
  467. int s;
  468. _enter("R=%x", wreq->debug_id);
  469. netfs_see_request(wreq, netfs_rreq_trace_see_work);
  470. if (!test_bit(NETFS_RREQ_IN_PROGRESS, &wreq->flags)) {
  471. netfs_put_request(wreq, false, netfs_rreq_trace_put_work);
  472. return;
  473. }
  474. netfs_collect_write_results(wreq);
  475. /* We're done when the app thread has finished posting subreqs and all
  476. * the queues in all the streams are empty.
  477. */
  478. if (!test_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags)) {
  479. netfs_put_request(wreq, false, netfs_rreq_trace_put_work);
  480. return;
  481. }
  482. smp_rmb(); /* Read ALL_QUEUED before lists. */
  483. transferred = LONG_MAX;
  484. for (s = 0; s < NR_IO_STREAMS; s++) {
  485. struct netfs_io_stream *stream = &wreq->io_streams[s];
  486. if (!stream->active)
  487. continue;
  488. if (!list_empty(&stream->subrequests)) {
  489. netfs_put_request(wreq, false, netfs_rreq_trace_put_work);
  490. return;
  491. }
  492. if (stream->transferred_valid &&
  493. stream->transferred < transferred) {
  494. transferred = stream->transferred;
  495. transferred_valid = true;
  496. }
  497. }
  498. /* Okay, declare that all I/O is complete. */
  499. if (transferred_valid)
  500. wreq->transferred = transferred;
  501. trace_netfs_rreq(wreq, netfs_rreq_trace_write_done);
  502. if (wreq->io_streams[1].active &&
  503. wreq->io_streams[1].failed &&
  504. ictx->ops->invalidate_cache) {
  505. /* Cache write failure doesn't prevent writeback completion
  506. * unless we're in disconnected mode.
  507. */
  508. ictx->ops->invalidate_cache(wreq);
  509. }
  510. if (wreq->cleanup)
  511. wreq->cleanup(wreq);
  512. if (wreq->origin == NETFS_DIO_WRITE &&
  513. wreq->mapping->nrpages) {
  514. /* mmap may have got underfoot and we may now have folios
  515. * locally covering the region we just wrote. Attempt to
  516. * discard the folios, but leave in place any modified locally.
  517. * ->write_iter() is prevented from interfering by the DIO
  518. * counter.
  519. */
  520. pgoff_t first = wreq->start >> PAGE_SHIFT;
  521. pgoff_t last = (wreq->start + wreq->transferred - 1) >> PAGE_SHIFT;
  522. invalidate_inode_pages2_range(wreq->mapping, first, last);
  523. }
  524. if (wreq->origin == NETFS_DIO_WRITE)
  525. inode_dio_end(wreq->inode);
  526. _debug("finished");
  527. trace_netfs_rreq(wreq, netfs_rreq_trace_wake_ip);
  528. clear_and_wake_up_bit(NETFS_RREQ_IN_PROGRESS, &wreq->flags);
  529. if (wreq->iocb) {
  530. size_t written = min(wreq->transferred, wreq->len);
  531. wreq->iocb->ki_pos += written;
  532. if (wreq->iocb->ki_complete)
  533. wreq->iocb->ki_complete(
  534. wreq->iocb, wreq->error ? wreq->error : written);
  535. wreq->iocb = VFS_PTR_POISON;
  536. }
  537. netfs_clear_subrequests(wreq, false);
  538. netfs_put_request(wreq, false, netfs_rreq_trace_put_work_complete);
  539. }
  540. /*
  541. * Wake the collection work item.
  542. */
  543. void netfs_wake_write_collector(struct netfs_io_request *wreq, bool was_async)
  544. {
  545. if (!work_pending(&wreq->work)) {
  546. netfs_get_request(wreq, netfs_rreq_trace_get_work);
  547. if (!queue_work(system_unbound_wq, &wreq->work))
  548. netfs_put_request(wreq, was_async, netfs_rreq_trace_put_work_nq);
  549. }
  550. }
  551. /**
  552. * netfs_write_subrequest_terminated - Note the termination of a write operation.
  553. * @_op: The I/O request that has terminated.
  554. * @transferred_or_error: The amount of data transferred or an error code.
  555. * @was_async: The termination was asynchronous
  556. *
  557. * This tells the library that a contributory write I/O operation has
  558. * terminated, one way or another, and that it should collect the results.
  559. *
  560. * The caller indicates in @transferred_or_error the outcome of the operation,
  561. * supplying a positive value to indicate the number of bytes transferred or a
  562. * negative error code. The library will look after reissuing I/O operations
  563. * as appropriate and writing downloaded data to the cache.
  564. *
  565. * If @was_async is true, the caller might be running in softirq or interrupt
  566. * context and we can't sleep.
  567. *
  568. * When this is called, ownership of the subrequest is transferred back to the
  569. * library, along with a ref.
  570. *
  571. * Note that %_op is a void* so that the function can be passed to
  572. * kiocb::term_func without the need for a casting wrapper.
  573. */
  574. void netfs_write_subrequest_terminated(void *_op, ssize_t transferred_or_error,
  575. bool was_async)
  576. {
  577. struct netfs_io_subrequest *subreq = _op;
  578. struct netfs_io_request *wreq = subreq->rreq;
  579. struct netfs_io_stream *stream = &wreq->io_streams[subreq->stream_nr];
  580. _enter("%x[%x] %zd", wreq->debug_id, subreq->debug_index, transferred_or_error);
  581. switch (subreq->source) {
  582. case NETFS_UPLOAD_TO_SERVER:
  583. netfs_stat(&netfs_n_wh_upload_done);
  584. break;
  585. case NETFS_WRITE_TO_CACHE:
  586. netfs_stat(&netfs_n_wh_write_done);
  587. break;
  588. case NETFS_INVALID_WRITE:
  589. break;
  590. default:
  591. BUG();
  592. }
  593. if (IS_ERR_VALUE(transferred_or_error)) {
  594. subreq->error = transferred_or_error;
  595. if (subreq->error == -EAGAIN)
  596. set_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags);
  597. else
  598. set_bit(NETFS_SREQ_FAILED, &subreq->flags);
  599. trace_netfs_failure(wreq, subreq, transferred_or_error, netfs_fail_write);
  600. switch (subreq->source) {
  601. case NETFS_WRITE_TO_CACHE:
  602. netfs_stat(&netfs_n_wh_write_failed);
  603. break;
  604. case NETFS_UPLOAD_TO_SERVER:
  605. netfs_stat(&netfs_n_wh_upload_failed);
  606. break;
  607. default:
  608. break;
  609. }
  610. trace_netfs_rreq(wreq, netfs_rreq_trace_set_pause);
  611. set_bit(NETFS_RREQ_PAUSE, &wreq->flags);
  612. } else {
  613. if (WARN(transferred_or_error > subreq->len - subreq->transferred,
  614. "Subreq excess write: R=%x[%x] %zd > %zu - %zu",
  615. wreq->debug_id, subreq->debug_index,
  616. transferred_or_error, subreq->len, subreq->transferred))
  617. transferred_or_error = subreq->len - subreq->transferred;
  618. subreq->error = 0;
  619. subreq->transferred += transferred_or_error;
  620. if (subreq->transferred < subreq->len)
  621. set_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags);
  622. }
  623. trace_netfs_sreq(subreq, netfs_sreq_trace_terminated);
  624. clear_and_wake_up_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags);
  625. /* If we are at the head of the queue, wake up the collector,
  626. * transferring a ref to it if we were the ones to do so.
  627. */
  628. if (list_is_first(&subreq->rreq_link, &stream->subrequests))
  629. netfs_wake_write_collector(wreq, was_async);
  630. netfs_put_subrequest(subreq, was_async, netfs_sreq_trace_put_terminated);
  631. }
  632. EXPORT_SYMBOL(netfs_write_subrequest_terminated);