hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/afs/write.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* handling of writes to regular files and writing back to the server
23 *
34 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
45 * Written by David Howells (dhowells@redhat.com)
5
- *
6
- * This program is free software; you can redistribute it and/or
7
- * modify it under the terms of the GNU General Public License
8
- * as published by the Free Software Foundation; either version
9
- * 2 of the License, or (at your option) any later version.
106 */
117
128 #include <linux/backing-dev.h>
....@@ -33,12 +29,22 @@
3329 loff_t pos, unsigned int len, struct page *page)
3430 {
3531 struct afs_read *req;
32
+ size_t p;
33
+ void *data;
3634 int ret;
3735
3836 _enter(",,%llu", (unsigned long long)pos);
3937
40
- req = kzalloc(sizeof(struct afs_read) + sizeof(struct page *),
41
- GFP_KERNEL);
38
+ if (pos >= vnode->vfs_inode.i_size) {
39
+ p = pos & ~PAGE_MASK;
40
+ ASSERTCMP(p + len, <=, PAGE_SIZE);
41
+ data = kmap(page);
42
+ memset(data + p, 0, len);
43
+ kunmap(page);
44
+ return 0;
45
+ }
46
+
47
+ req = kzalloc(struct_size(req, array, 1), GFP_KERNEL);
4248 if (!req)
4349 return -ENOMEM;
4450
....@@ -70,7 +76,7 @@
7076 */
7177 int afs_write_begin(struct file *file, struct address_space *mapping,
7278 loff_t pos, unsigned len, unsigned flags,
73
- struct page **pagep, void **fsdata)
79
+ struct page **_page, void **fsdata)
7480 {
7581 struct afs_vnode *vnode = AFS_FS_I(file_inode(file));
7682 struct page *page;
....@@ -81,13 +87,8 @@
8187 pgoff_t index = pos >> PAGE_SHIFT;
8288 int ret;
8389
84
- _enter("{%x:%u},{%lx},%u,%u",
90
+ _enter("{%llx:%llu},{%lx},%u,%u",
8591 vnode->fid.vid, vnode->fid.vnode, index, from, to);
86
-
87
- /* We want to store information about how much of a page is altered in
88
- * page->private.
89
- */
90
- BUILD_BUG_ON(PAGE_SIZE > 32768 && sizeof(page->private) < 8);
9192
9293 page = grab_cache_page_write_begin(mapping, index, flags);
9394 if (!page)
....@@ -104,9 +105,6 @@
104105 SetPageUptodate(page);
105106 }
106107
107
- /* page won't leak in error case: it eventually gets cleaned off LRU */
108
- *pagep = page;
109
-
110108 try_again:
111109 /* See if this page is already partially written in a way that we can
112110 * merge the new write with.
....@@ -114,8 +112,8 @@
114112 t = f = 0;
115113 if (PagePrivate(page)) {
116114 priv = page_private(page);
117
- f = priv & AFS_PRIV_MAX;
118
- t = priv >> AFS_PRIV_SHIFT;
115
+ f = afs_page_dirty_from(priv);
116
+ t = afs_page_dirty_to(priv);
119117 ASSERTCMP(f, <=, t);
120118 }
121119
....@@ -132,21 +130,9 @@
132130 if (!test_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags) &&
133131 (to < f || from > t))
134132 goto flush_conflicting_write;
135
- if (from < f)
136
- f = from;
137
- if (to > t)
138
- t = to;
139
- } else {
140
- f = from;
141
- t = to;
142133 }
143134
144
- priv = (unsigned long)t << AFS_PRIV_SHIFT;
145
- priv |= f;
146
- trace_afs_page_dirty(vnode, tracepoint_string("begin"),
147
- page->index, priv);
148
- SetPagePrivate(page);
149
- set_page_private(page, priv);
135
+ *_page = page;
150136 _leave(" = 0");
151137 return 0;
152138
....@@ -156,17 +142,18 @@
156142 flush_conflicting_write:
157143 _debug("flush conflict");
158144 ret = write_one_page(page);
159
- if (ret < 0) {
160
- _leave(" = %d", ret);
161
- return ret;
162
- }
145
+ if (ret < 0)
146
+ goto error;
163147
164148 ret = lock_page_killable(page);
165
- if (ret < 0) {
166
- _leave(" = %d", ret);
167
- return ret;
168
- }
149
+ if (ret < 0)
150
+ goto error;
169151 goto try_again;
152
+
153
+error:
154
+ put_page(page);
155
+ _leave(" = %d", ret);
156
+ return ret;
170157 }
171158
172159 /*
....@@ -178,11 +165,17 @@
178165 {
179166 struct afs_vnode *vnode = AFS_FS_I(file_inode(file));
180167 struct key *key = afs_file_key(file);
168
+ unsigned long priv;
169
+ unsigned int f, from = pos & (PAGE_SIZE - 1);
170
+ unsigned int t, to = from + copied;
181171 loff_t i_size, maybe_i_size;
182
- int ret;
172
+ int ret = 0;
183173
184
- _enter("{%x:%u},{%lx}",
174
+ _enter("{%llx:%llu},{%lx}",
185175 vnode->fid.vid, vnode->fid.vnode, page->index);
176
+
177
+ if (copied == 0)
178
+ goto out;
186179
187180 maybe_i_size = pos + copied;
188181
....@@ -191,7 +184,7 @@
191184 write_seqlock(&vnode->cb_lock);
192185 i_size = i_size_read(&vnode->vfs_inode);
193186 if (maybe_i_size > i_size)
194
- i_size_write(&vnode->vfs_inode, maybe_i_size);
187
+ afs_set_i_size(vnode, maybe_i_size);
195188 write_sequnlock(&vnode->cb_lock);
196189 }
197190
....@@ -207,6 +200,25 @@
207200 goto out;
208201 }
209202 SetPageUptodate(page);
203
+ }
204
+
205
+ if (PagePrivate(page)) {
206
+ priv = page_private(page);
207
+ f = afs_page_dirty_from(priv);
208
+ t = afs_page_dirty_to(priv);
209
+ if (from < f)
210
+ f = from;
211
+ if (to > t)
212
+ t = to;
213
+ priv = afs_page_dirty(f, t);
214
+ set_page_private(page, priv);
215
+ trace_afs_page_dirty(vnode, tracepoint_string("dirty+"),
216
+ page->index, priv);
217
+ } else {
218
+ priv = afs_page_dirty(from, to);
219
+ attach_page_private(page, (void *)priv);
220
+ trace_afs_page_dirty(vnode, tracepoint_string("dirty"),
221
+ page->index, priv);
210222 }
211223
212224 set_page_dirty(page);
....@@ -230,7 +242,7 @@
230242 struct pagevec pv;
231243 unsigned count, loop;
232244
233
- _enter("{%x:%u},%lx-%lx",
245
+ _enter("{%llx:%llu},%lx-%lx",
234246 vnode->fid.vid, vnode->fid.vnode, first, last);
235247
236248 pagevec_init(&pv);
....@@ -273,7 +285,7 @@
273285 struct pagevec pv;
274286 unsigned count, loop;
275287
276
- _enter("{%x:%u},%lx-%lx",
288
+ _enter("{%llx:%llu},%lx-%lx",
277289 vnode->fid.vid, vnode->fid.vnode, first, last);
278290
279291 pagevec_init(&pv);
....@@ -303,71 +315,156 @@
303315 }
304316
305317 /*
306
- * write to a file
318
+ * completion of write to server
307319 */
308
-static int afs_store_data(struct address_space *mapping,
309
- pgoff_t first, pgoff_t last,
310
- unsigned offset, unsigned to)
320
+static void afs_pages_written_back(struct afs_vnode *vnode,
321
+ pgoff_t first, pgoff_t last)
311322 {
312
- struct afs_vnode *vnode = AFS_FS_I(mapping->host);
313
- struct afs_fs_cursor fc;
323
+ struct pagevec pv;
324
+ unsigned long priv;
325
+ unsigned count, loop;
326
+
327
+ _enter("{%llx:%llu},{%lx-%lx}",
328
+ vnode->fid.vid, vnode->fid.vnode, first, last);
329
+
330
+ pagevec_init(&pv);
331
+
332
+ do {
333
+ _debug("done %lx-%lx", first, last);
334
+
335
+ count = last - first + 1;
336
+ if (count > PAGEVEC_SIZE)
337
+ count = PAGEVEC_SIZE;
338
+ pv.nr = find_get_pages_contig(vnode->vfs_inode.i_mapping,
339
+ first, count, pv.pages);
340
+ ASSERTCMP(pv.nr, ==, count);
341
+
342
+ for (loop = 0; loop < count; loop++) {
343
+ priv = (unsigned long)detach_page_private(pv.pages[loop]);
344
+ trace_afs_page_dirty(vnode, tracepoint_string("clear"),
345
+ pv.pages[loop]->index, priv);
346
+ end_page_writeback(pv.pages[loop]);
347
+ }
348
+ first += count;
349
+ __pagevec_release(&pv);
350
+ } while (first <= last);
351
+
352
+ afs_prune_wb_keys(vnode);
353
+ _leave("");
354
+}
355
+
356
+/*
357
+ * Find a key to use for the writeback. We cached the keys used to author the
358
+ * writes on the vnode. *_wbk will contain the last writeback key used or NULL
359
+ * and we need to start from there if it's set.
360
+ */
361
+static int afs_get_writeback_key(struct afs_vnode *vnode,
362
+ struct afs_wb_key **_wbk)
363
+{
314364 struct afs_wb_key *wbk = NULL;
315365 struct list_head *p;
316366 int ret = -ENOKEY, ret2;
317367
318
- _enter("%s{%x:%u.%u},%lx,%lx,%x,%x",
319
- vnode->volume->name,
320
- vnode->fid.vid,
321
- vnode->fid.vnode,
322
- vnode->fid.unique,
323
- first, last, offset, to);
324
-
325368 spin_lock(&vnode->wb_lock);
326
- p = vnode->wb_keys.next;
369
+ if (*_wbk)
370
+ p = (*_wbk)->vnode_link.next;
371
+ else
372
+ p = vnode->wb_keys.next;
327373
328
- /* Iterate through the list looking for a valid key to use. */
329
-try_next_key:
330374 while (p != &vnode->wb_keys) {
331375 wbk = list_entry(p, struct afs_wb_key, vnode_link);
332376 _debug("wbk %u", key_serial(wbk->key));
333377 ret2 = key_validate(wbk->key);
334
- if (ret2 == 0)
335
- goto found_key;
378
+ if (ret2 == 0) {
379
+ refcount_inc(&wbk->usage);
380
+ _debug("USE WB KEY %u", key_serial(wbk->key));
381
+ break;
382
+ }
383
+
384
+ wbk = NULL;
336385 if (ret == -ENOKEY)
337386 ret = ret2;
338387 p = p->next;
339388 }
340389
341390 spin_unlock(&vnode->wb_lock);
342
- afs_put_wb_key(wbk);
343
- _leave(" = %d [no keys]", ret);
344
- return ret;
391
+ if (*_wbk)
392
+ afs_put_wb_key(*_wbk);
393
+ *_wbk = wbk;
394
+ return 0;
395
+}
345396
346
-found_key:
347
- refcount_inc(&wbk->usage);
348
- spin_unlock(&vnode->wb_lock);
397
+static void afs_store_data_success(struct afs_operation *op)
398
+{
399
+ struct afs_vnode *vnode = op->file[0].vnode;
349400
350
- _debug("USE WB KEY %u", key_serial(wbk->key));
401
+ op->ctime = op->file[0].scb.status.mtime_client;
402
+ afs_vnode_commit_status(op, &op->file[0]);
403
+ if (op->error == 0) {
404
+ if (!op->store.laundering)
405
+ afs_pages_written_back(vnode, op->store.first, op->store.last);
406
+ afs_stat_v(vnode, n_stores);
407
+ atomic_long_add((op->store.last * PAGE_SIZE + op->store.last_to) -
408
+ (op->store.first * PAGE_SIZE + op->store.first_offset),
409
+ &afs_v2net(vnode)->n_store_bytes);
410
+ }
411
+}
351412
352
- ret = -ERESTARTSYS;
353
- if (afs_begin_vnode_operation(&fc, vnode, wbk->key)) {
354
- while (afs_select_fileserver(&fc)) {
355
- fc.cb_break = afs_calc_vnode_cb_break(vnode);
356
- afs_fs_store_data(&fc, mapping, first, last, offset, to);
357
- }
413
+static const struct afs_operation_ops afs_store_data_operation = {
414
+ .issue_afs_rpc = afs_fs_store_data,
415
+ .issue_yfs_rpc = yfs_fs_store_data,
416
+ .success = afs_store_data_success,
417
+};
358418
359
- afs_check_for_remote_deletion(&fc, fc.vnode);
360
- afs_vnode_commit_status(&fc, vnode, fc.cb_break);
361
- ret = afs_end_vnode_operation(&fc);
419
+/*
420
+ * write to a file
421
+ */
422
+static int afs_store_data(struct address_space *mapping,
423
+ pgoff_t first, pgoff_t last,
424
+ unsigned offset, unsigned to, bool laundering)
425
+{
426
+ struct afs_vnode *vnode = AFS_FS_I(mapping->host);
427
+ struct afs_operation *op;
428
+ struct afs_wb_key *wbk = NULL;
429
+ int ret;
430
+
431
+ _enter("%s{%llx:%llu.%u},%lx,%lx,%x,%x",
432
+ vnode->volume->name,
433
+ vnode->fid.vid,
434
+ vnode->fid.vnode,
435
+ vnode->fid.unique,
436
+ first, last, offset, to);
437
+
438
+ ret = afs_get_writeback_key(vnode, &wbk);
439
+ if (ret) {
440
+ _leave(" = %d [no keys]", ret);
441
+ return ret;
362442 }
363443
364
- switch (ret) {
365
- case 0:
366
- afs_stat_v(vnode, n_stores);
367
- atomic_long_add((last * PAGE_SIZE + to) -
368
- (first * PAGE_SIZE + offset),
369
- &afs_v2net(vnode)->n_store_bytes);
370
- break;
444
+ op = afs_alloc_operation(wbk->key, vnode->volume);
445
+ if (IS_ERR(op)) {
446
+ afs_put_wb_key(wbk);
447
+ return -ENOMEM;
448
+ }
449
+
450
+ afs_op_set_vnode(op, 0, vnode);
451
+ op->file[0].dv_delta = 1;
452
+ op->store.mapping = mapping;
453
+ op->file[0].modification = true;
454
+ op->store.first = first;
455
+ op->store.last = last;
456
+ op->store.first_offset = offset;
457
+ op->store.last_to = to;
458
+ op->store.laundering = laundering;
459
+ op->mtime = vnode->vfs_inode.i_mtime;
460
+ op->flags |= AFS_OPERATION_UNINTR;
461
+ op->ops = &afs_store_data_operation;
462
+
463
+try_next_key:
464
+ afs_begin_vnode_operation(op);
465
+ afs_wait_for_operation(op);
466
+
467
+ switch (op->error) {
371468 case -EACCES:
372469 case -EPERM:
373470 case -ENOKEY:
....@@ -375,15 +472,19 @@
375472 case -EKEYREJECTED:
376473 case -EKEYREVOKED:
377474 _debug("next");
378
- spin_lock(&vnode->wb_lock);
379
- p = wbk->vnode_link.next;
380
- afs_put_wb_key(wbk);
381
- goto try_next_key;
475
+
476
+ ret = afs_get_writeback_key(vnode, &wbk);
477
+ if (ret == 0) {
478
+ key_put(op->key);
479
+ op->key = key_get(wbk->key);
480
+ goto try_next_key;
481
+ }
482
+ break;
382483 }
383484
384485 afs_put_wb_key(wbk);
385
- _leave(" = %d", ret);
386
- return ret;
486
+ _leave(" = %d", op->error);
487
+ return afs_put_operation(op);
387488 }
388489
389490 /*
....@@ -400,6 +501,7 @@
400501 unsigned long count, priv;
401502 unsigned n, offset, to, f, t;
402503 pgoff_t start, first, last;
504
+ loff_t i_size, end;
403505 int loop, ret;
404506
405507 _enter(",%lx", primary_page->index);
....@@ -415,8 +517,8 @@
415517 */
416518 start = primary_page->index;
417519 priv = page_private(primary_page);
418
- offset = priv & AFS_PRIV_MAX;
419
- to = priv >> AFS_PRIV_SHIFT;
520
+ offset = afs_page_dirty_from(priv);
521
+ to = afs_page_dirty_to(priv);
420522 trace_afs_page_dirty(vnode, tracepoint_string("store"),
421523 primary_page->index, priv);
422524
....@@ -461,8 +563,8 @@
461563 }
462564
463565 priv = page_private(page);
464
- f = priv & AFS_PRIV_MAX;
465
- t = priv >> AFS_PRIV_SHIFT;
566
+ f = afs_page_dirty_from(priv);
567
+ t = afs_page_dirty_to(priv);
466568 if (f != 0 &&
467569 !test_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags)) {
468570 unlock_page(page);
....@@ -500,9 +602,14 @@
500602 first = primary_page->index;
501603 last = first + count - 1;
502604
503
- _debug("write back %lx[%u..] to %lx[..%u]", first, offset, last, to);
605
+ end = (loff_t)last * PAGE_SIZE + to;
606
+ i_size = i_size_read(&vnode->vfs_inode);
504607
505
- ret = afs_store_data(mapping, first, last, offset, to);
608
+ _debug("write back %lx[%u..] to %lx[..%u]", first, offset, last, to);
609
+ if (end > i_size)
610
+ to = i_size & ~PAGE_MASK;
611
+
612
+ ret = afs_store_data(mapping, first, last, offset, to, false);
506613 switch (ret) {
507614 case 0:
508615 ret = count;
....@@ -510,7 +617,7 @@
510617
511618 default:
512619 pr_notice("kAFS: Unexpected error from FS.StoreData %d\n", ret);
513
- /* Fall through */
620
+ fallthrough;
514621 case -EACCES:
515622 case -EPERM:
516623 case -ENOKEY:
....@@ -534,6 +641,7 @@
534641 case -ENOENT:
535642 case -ENOMEDIUM:
536643 case -ENXIO:
644
+ trace_afs_file_error(vnode, ret, afs_file_error_writeback_fail);
537645 afs_kill_pages(mapping, first, last);
538646 mapping_set_error(mapping, ret);
539647 break;
....@@ -638,10 +746,20 @@
638746 int afs_writepages(struct address_space *mapping,
639747 struct writeback_control *wbc)
640748 {
749
+ struct afs_vnode *vnode = AFS_FS_I(mapping->host);
641750 pgoff_t start, end, next;
642751 int ret;
643752
644753 _enter("");
754
+
755
+ /* We have to be careful as we can end up racing with setattr()
756
+ * truncating the pagecache since the caller doesn't take a lock here
757
+ * to prevent it.
758
+ */
759
+ if (wbc->sync_mode == WB_SYNC_ALL)
760
+ down_read(&vnode->validate_lock);
761
+ else if (!down_read_trylock(&vnode->validate_lock))
762
+ return 0;
645763
646764 if (wbc->range_cyclic) {
647765 start = mapping->writeback_index;
....@@ -662,48 +780,9 @@
662780 ret = afs_writepages_region(mapping, wbc, start, end, &next);
663781 }
664782
783
+ up_read(&vnode->validate_lock);
665784 _leave(" = %d", ret);
666785 return ret;
667
-}
668
-
669
-/*
670
- * completion of write to server
671
- */
672
-void afs_pages_written_back(struct afs_vnode *vnode, struct afs_call *call)
673
-{
674
- struct pagevec pv;
675
- unsigned long priv;
676
- unsigned count, loop;
677
- pgoff_t first = call->first, last = call->last;
678
-
679
- _enter("{%x:%u},{%lx-%lx}",
680
- vnode->fid.vid, vnode->fid.vnode, first, last);
681
-
682
- pagevec_init(&pv);
683
-
684
- do {
685
- _debug("done %lx-%lx", first, last);
686
-
687
- count = last - first + 1;
688
- if (count > PAGEVEC_SIZE)
689
- count = PAGEVEC_SIZE;
690
- pv.nr = find_get_pages_contig(vnode->vfs_inode.i_mapping,
691
- first, count, pv.pages);
692
- ASSERTCMP(pv.nr, ==, count);
693
-
694
- for (loop = 0; loop < count; loop++) {
695
- priv = page_private(pv.pages[loop]);
696
- trace_afs_page_dirty(vnode, tracepoint_string("clear"),
697
- pv.pages[loop]->index, priv);
698
- set_page_private(pv.pages[loop], 0);
699
- end_page_writeback(pv.pages[loop]);
700
- }
701
- first += count;
702
- __pagevec_release(&pv);
703
- } while (first <= last);
704
-
705
- afs_prune_wb_keys(vnode);
706
- _leave("");
707786 }
708787
709788 /*
....@@ -715,7 +794,7 @@
715794 ssize_t result;
716795 size_t count = iov_iter_count(from);
717796
718
- _enter("{%x.%u},{%zu},",
797
+ _enter("{%llx:%llu},{%zu},",
719798 vnode->fid.vid, vnode->fid.vnode, count);
720799
721800 if (IS_SWAPFILE(&vnode->vfs_inode)) {
....@@ -743,7 +822,7 @@
743822 struct inode *inode = file_inode(file);
744823 struct afs_vnode *vnode = AFS_FS_I(inode);
745824
746
- _enter("{%x:%u},{n=%pD},%d",
825
+ _enter("{%llx:%llu},{n=%pD},%d",
747826 vnode->fid.vid, vnode->fid.vnode, file,
748827 datasync);
749828
....@@ -761,7 +840,7 @@
761840 struct afs_vnode *vnode = AFS_FS_I(inode);
762841 unsigned long priv;
763842
764
- _enter("{{%x:%u}},{%lx}",
843
+ _enter("{{%llx:%llu}},{%lx}",
765844 vnode->fid.vid, vnode->fid.vnode, vmf->page->index);
766845
767846 sb_start_pagefault(inode->i_sb);
....@@ -786,12 +865,14 @@
786865 */
787866 wait_on_page_writeback(vmf->page);
788867
789
- priv = (unsigned long)PAGE_SIZE << AFS_PRIV_SHIFT; /* To */
790
- priv |= 0; /* From */
868
+ priv = afs_page_dirty(0, PAGE_SIZE);
869
+ priv = afs_page_dirty_mmapped(priv);
791870 trace_afs_page_dirty(vnode, tracepoint_string("mkwrite"),
792871 vmf->page->index, priv);
793
- SetPagePrivate(vmf->page);
794
- set_page_private(vmf->page, priv);
872
+ if (PagePrivate(vmf->page))
873
+ set_page_private(vmf->page, priv);
874
+ else
875
+ attach_page_private(vmf->page, (void *)priv);
795876 file_update_time(file);
796877
797878 sb_end_pagefault(inode->i_sb);
....@@ -844,19 +925,18 @@
844925 f = 0;
845926 t = PAGE_SIZE;
846927 if (PagePrivate(page)) {
847
- f = priv & AFS_PRIV_MAX;
848
- t = priv >> AFS_PRIV_SHIFT;
928
+ f = afs_page_dirty_from(priv);
929
+ t = afs_page_dirty_to(priv);
849930 }
850931
851932 trace_afs_page_dirty(vnode, tracepoint_string("launder"),
852933 page->index, priv);
853
- ret = afs_store_data(mapping, page->index, page->index, t, f);
934
+ ret = afs_store_data(mapping, page->index, page->index, t, f, true);
854935 }
855936
937
+ priv = (unsigned long)detach_page_private(page);
856938 trace_afs_page_dirty(vnode, tracepoint_string("laundered"),
857939 page->index, priv);
858
- set_page_private(page, 0);
859
- ClearPagePrivate(page);
860940
861941 #ifdef CONFIG_AFS_FSCACHE
862942 if (PageFsCache(page)) {