Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'vfs-6.12-rc2.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull vfs fixes from Christian Brauner:
"afs:

- Fix setting of the server responding flag

- Remove unused struct afs_address_list and afs_put_address_list()
function

- Fix infinite loop because of unresponsive servers

- Ensure that afs_retry_request() function is correctly added to the
afs_req_ops netfs operations table

netfs:

- Fix netfs_folio tracepoint handling to handle NULL mappings

- Add a missing folio_queue API documentation

- Ensure that netfs_write_folio() correctly advances the iterator via
iov_iter_advance()

- Fix a dentry leak during concurrent cull and cookie lookup
operations in cachefiles

pidfs:

- Correctly handle accessing another task's pid namespace"

* tag 'vfs-6.12-rc2.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
netfs: Fix the netfs_folio tracepoint to handle NULL mapping
netfs: Add folio_queue API documentation
netfs: Advance iterator correctly rather than jumping it
afs: Fix the setting of the server responding flag
afs: Remove unused struct and function prototype
afs: Fix possible infinite loop with unresponsive servers
pidfs: check for valid pid namespace
afs: Fix missing wire-up of afs_retry_request()
cachefiles: fix dentry leak in cachefiles_open_file()

+410 -24
+212
Documentation/core-api/folio_queue.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0+ 2 + 3 + =========== 4 + Folio Queue 5 + =========== 6 + 7 + :Author: David Howells <dhowells@redhat.com> 8 + 9 + .. Contents: 10 + 11 + * Overview 12 + * Initialisation 13 + * Adding and removing folios 14 + * Querying information about a folio 15 + * Querying information about a folio_queue 16 + * Folio queue iteration 17 + * Folio marks 18 + * Lockless simultaneous production/consumption issues 19 + 20 + 21 + Overview 22 + ======== 23 + 24 + The folio_queue struct forms a single segment in a segmented list of folios 25 + that can be used to form an I/O buffer. As such, the list can be iterated over 26 + using the ITER_FOLIOQ iov_iter type. 27 + 28 + The publicly accessible members of the structure are:: 29 + 30 + struct folio_queue { 31 + struct folio_queue *next; 32 + struct folio_queue *prev; 33 + ... 34 + }; 35 + 36 + A pair of pointers are provided, ``next`` and ``prev``, that point to the 37 + segments on either side of the segment being accessed. Whilst this is a 38 + doubly-linked list, it is intentionally not a circular list; the outward 39 + sibling pointers in terminal segments should be NULL. 40 + 41 + Each segment in the list also stores: 42 + 43 + * an ordered sequence of folio pointers, 44 + * the size of each folio and 45 + * three 1-bit marks per folio, 46 + 47 + but hese should not be accessed directly as the underlying data structure may 48 + change, but rather the access functions outlined below should be used. 49 + 50 + The facility can be made accessible by:: 51 + 52 + #include <linux/folio_queue.h> 53 + 54 + and to use the iterator:: 55 + 56 + #include <linux/uio.h> 57 + 58 + 59 + Initialisation 60 + ============== 61 + 62 + A segment should be initialised by calling:: 63 + 64 + void folioq_init(struct folio_queue *folioq); 65 + 66 + with a pointer to the segment to be initialised. Note that this will not 67 + necessarily initialise all the folio pointers, so care must be taken to check 68 + the number of folios added. 69 + 70 + 71 + Adding and removing folios 72 + ========================== 73 + 74 + Folios can be set in the next unused slot in a segment struct by calling one 75 + of:: 76 + 77 + unsigned int folioq_append(struct folio_queue *folioq, 78 + struct folio *folio); 79 + 80 + unsigned int folioq_append_mark(struct folio_queue *folioq, 81 + struct folio *folio); 82 + 83 + Both functions update the stored folio count, store the folio and note its 84 + size. The second function also sets the first mark for the folio added. Both 85 + functions return the number of the slot used. [!] Note that no attempt is made 86 + to check that the capacity wasn't overrun and the list will not be extended 87 + automatically. 88 + 89 + A folio can be excised by calling:: 90 + 91 + void folioq_clear(struct folio_queue *folioq, unsigned int slot); 92 + 93 + This clears the slot in the array and also clears all the marks for that folio, 94 + but doesn't change the folio count - so future accesses of that slot must check 95 + if the slot is occupied. 96 + 97 + 98 + Querying information about a folio 99 + ================================== 100 + 101 + Information about the folio in a particular slot may be queried by the 102 + following function:: 103 + 104 + struct folio *folioq_folio(const struct folio_queue *folioq, 105 + unsigned int slot); 106 + 107 + If a folio has not yet been set in that slot, this may yield an undefined 108 + pointer. The size of the folio in a slot may be queried with either of:: 109 + 110 + unsigned int folioq_folio_order(const struct folio_queue *folioq, 111 + unsigned int slot); 112 + 113 + size_t folioq_folio_size(const struct folio_queue *folioq, 114 + unsigned int slot); 115 + 116 + The first function returns the size as an order and the second as a number of 117 + bytes. 118 + 119 + 120 + Querying information about a folio_queue 121 + ======================================== 122 + 123 + Information may be retrieved about a particular segment with the following 124 + functions:: 125 + 126 + unsigned int folioq_nr_slots(const struct folio_queue *folioq); 127 + 128 + unsigned int folioq_count(struct folio_queue *folioq); 129 + 130 + bool folioq_full(struct folio_queue *folioq); 131 + 132 + The first function returns the maximum capacity of a segment. It must not be 133 + assumed that this won't vary between segments. The second returns the number 134 + of folios added to a segments and the third is a shorthand to indicate if the 135 + segment has been filled to capacity. 136 + 137 + Not that the count and fullness are not affected by clearing folios from the 138 + segment. These are more about indicating how many slots in the array have been 139 + initialised, and it assumed that slots won't get reused, but rather the segment 140 + will get discarded as the queue is consumed. 141 + 142 + 143 + Folio marks 144 + =========== 145 + 146 + Folios within a queue can also have marks assigned to them. These marks can be 147 + used to note information such as if a folio needs folio_put() calling upon it. 148 + There are three marks available to be set for each folio. 149 + 150 + The marks can be set by:: 151 + 152 + void folioq_mark(struct folio_queue *folioq, unsigned int slot); 153 + void folioq_mark2(struct folio_queue *folioq, unsigned int slot); 154 + void folioq_mark3(struct folio_queue *folioq, unsigned int slot); 155 + 156 + Cleared by:: 157 + 158 + void folioq_unmark(struct folio_queue *folioq, unsigned int slot); 159 + void folioq_unmark2(struct folio_queue *folioq, unsigned int slot); 160 + void folioq_unmark3(struct folio_queue *folioq, unsigned int slot); 161 + 162 + And the marks can be queried by:: 163 + 164 + bool folioq_is_marked(const struct folio_queue *folioq, unsigned int slot); 165 + bool folioq_is_marked2(const struct folio_queue *folioq, unsigned int slot); 166 + bool folioq_is_marked3(const struct folio_queue *folioq, unsigned int slot); 167 + 168 + The marks can be used for any purpose and are not interpreted by this API. 169 + 170 + 171 + Folio queue iteration 172 + ===================== 173 + 174 + A list of segments may be iterated over using the I/O iterator facility using 175 + an ``iov_iter`` iterator of ``ITER_FOLIOQ`` type. The iterator may be 176 + initialised with:: 177 + 178 + void iov_iter_folio_queue(struct iov_iter *i, unsigned int direction, 179 + const struct folio_queue *folioq, 180 + unsigned int first_slot, unsigned int offset, 181 + size_t count); 182 + 183 + This may be told to start at a particular segment, slot and offset within a 184 + queue. The iov iterator functions will follow the next pointers when advancing 185 + and prev pointers when reverting when needed. 186 + 187 + 188 + Lockless simultaneous production/consumption issues 189 + =================================================== 190 + 191 + If properly managed, the list can be extended by the producer at the head end 192 + and shortened by the consumer at the tail end simultaneously without the need 193 + to take locks. The ITER_FOLIOQ iterator inserts appropriate barriers to aid 194 + with this. 195 + 196 + Care must be taken when simultaneously producing and consuming a list. If the 197 + last segment is reached and the folios it refers to are entirely consumed by 198 + the IOV iterators, an iov_iter struct will be left pointing to the last segment 199 + with a slot number equal to the capacity of that segment. The iterator will 200 + try to continue on from this if there's another segment available when it is 201 + used again, but care must be taken lest the segment got removed and freed by 202 + the consumer before the iterator was advanced. 203 + 204 + It is recommended that the queue always contain at least one segment, even if 205 + that segment has never been filled or is entirely spent. This prevents the 206 + head and tail pointers from collapsing. 207 + 208 + 209 + API Function Reference 210 + ====================== 211 + 212 + .. kernel-doc:: include/linux/folio_queue.h
-9
fs/afs/afs_vl.h
··· 134 134 __be32 spares9; 135 135 }; 136 136 137 - struct afs_address_list { 138 - refcount_t usage; 139 - unsigned int version; 140 - unsigned int nr_addrs; 141 - struct sockaddr_rxrpc addrs[]; 142 - }; 143 - 144 - extern void afs_put_address_list(struct afs_address_list *alist); 145 - 146 137 #endif /* AFS_VL_H */
+1
fs/afs/file.c
··· 420 420 .begin_writeback = afs_begin_writeback, 421 421 .prepare_write = afs_prepare_write, 422 422 .issue_write = afs_issue_write, 423 + .retry_request = afs_retry_request, 423 424 }; 424 425 425 426 static void afs_add_open_mmap(struct afs_vnode *vnode)
+1 -1
fs/afs/fs_operation.c
··· 201 201 } 202 202 } 203 203 204 - if (op->call_responded) 204 + if (op->call_responded && op->server) 205 205 set_bit(AFS_SERVER_FL_RESPONDING, &op->server->flags); 206 206 207 207 if (!afs_op_error(op)) {
+2 -2
fs/afs/fs_probe.c
··· 506 506 finish_wait(&server->probe_wq, &wait); 507 507 508 508 dont_wait: 509 - if (estate->responsive_set & ~exclude) 510 - return 1; 511 509 if (test_bit(AFS_ESTATE_SUPERSEDED, &estate->flags)) 512 510 return 0; 511 + if (estate->responsive_set & ~exclude) 512 + return 1; 513 513 if (is_intr && signal_pending(current)) 514 514 return -ERESTARTSYS; 515 515 if (timo == 0)
+8 -3
fs/afs/rotate.c
··· 632 632 wait_for_more_probe_results: 633 633 error = afs_wait_for_one_fs_probe(op->server, op->estate, op->addr_tried, 634 634 !(op->flags & AFS_OPERATION_UNINTR)); 635 - if (!error) 635 + if (error == 1) 636 636 goto iterate_address; 637 + if (!error) 638 + goto restart_from_beginning; 637 639 638 640 /* We've now had a failure to respond on all of a server's addresses - 639 641 * immediately probe them again and consider retrying the server. ··· 646 644 error = afs_wait_for_one_fs_probe(op->server, op->estate, op->addr_tried, 647 645 !(op->flags & AFS_OPERATION_UNINTR)); 648 646 switch (error) { 649 - case 0: 647 + case 1: 650 648 op->flags &= ~AFS_OPERATION_RETRY_SERVER; 651 - trace_afs_rotate(op, afs_rotate_trace_retry_server, 0); 649 + trace_afs_rotate(op, afs_rotate_trace_retry_server, 1); 652 650 goto retry_server; 651 + case 0: 652 + trace_afs_rotate(op, afs_rotate_trace_retry_server, 0); 653 + goto restart_from_beginning; 653 654 case -ERESTARTSYS: 654 655 afs_op_set_error(op, error); 655 656 goto failed;
+3 -4
fs/cachefiles/namei.c
··· 595 595 * write and readdir but not lookup or open). 596 596 */ 597 597 touch_atime(&file->f_path); 598 - dput(dentry); 599 598 return true; 600 599 601 600 check_failed: 602 601 fscache_cookie_lookup_negative(object->cookie); 603 602 cachefiles_unmark_inode_in_use(object, file); 604 603 fput(file); 605 - dput(dentry); 606 604 if (ret == -ESTALE) 607 605 return cachefiles_create_file(object); 608 606 return false; ··· 609 611 fput(file); 610 612 error: 611 613 cachefiles_do_unmark_inode_in_use(object, d_inode(dentry)); 612 - dput(dentry); 613 614 return false; 614 615 } 615 616 ··· 651 654 goto new_file; 652 655 } 653 656 654 - if (!cachefiles_open_file(object, dentry)) 657 + ret = cachefiles_open_file(object, dentry); 658 + dput(dentry); 659 + if (!ret) 655 660 return false; 656 661 657 662 _leave(" = t [%lu]", file_inode(object->file)->i_ino);
+9 -3
fs/netfs/write_issue.c
··· 317 317 struct netfs_io_stream *stream; 318 318 struct netfs_group *fgroup; /* TODO: Use this with ceph */ 319 319 struct netfs_folio *finfo; 320 + size_t iter_off = 0; 320 321 size_t fsize = folio_size(folio), flen = fsize, foff = 0; 321 322 loff_t fpos = folio_pos(folio), i_size; 322 323 bool to_eof = false, streamw = false; ··· 473 472 if (choose_s < 0) 474 473 break; 475 474 stream = &wreq->io_streams[choose_s]; 476 - wreq->io_iter.iov_offset = stream->submit_off; 475 + 476 + /* Advance the iterator(s). */ 477 + if (stream->submit_off > iter_off) { 478 + iov_iter_advance(&wreq->io_iter, stream->submit_off - iter_off); 479 + iter_off = stream->submit_off; 480 + } 477 481 478 482 atomic64_set(&wreq->issued_to, fpos + stream->submit_off); 479 483 stream->submit_extendable_to = fsize - stream->submit_off; ··· 493 487 debug = true; 494 488 } 495 489 496 - wreq->io_iter.iov_offset = 0; 497 - iov_iter_advance(&wreq->io_iter, fsize); 490 + if (fsize > iter_off) 491 + iov_iter_advance(&wreq->io_iter, fsize - iter_off); 498 492 atomic64_set(&wreq->issued_to, fpos + fsize); 499 493 500 494 if (!debug)
+4 -1
fs/pidfs.c
··· 120 120 struct nsproxy *nsp __free(put_nsproxy) = NULL; 121 121 struct pid *pid = pidfd_pid(file); 122 122 struct ns_common *ns_common = NULL; 123 + struct pid_namespace *pid_ns; 123 124 124 125 if (arg) 125 126 return -EINVAL; ··· 203 202 case PIDFD_GET_PID_NAMESPACE: 204 203 if (IS_ENABLED(CONFIG_PID_NS)) { 205 204 rcu_read_lock(); 206 - ns_common = to_ns_common( get_pid_ns(task_active_pid_ns(task))); 205 + pid_ns = task_active_pid_ns(task); 206 + if (pid_ns) 207 + ns_common = to_ns_common(get_pid_ns(pid_ns)); 207 208 rcu_read_unlock(); 208 209 } 209 210 break;
+168
include/linux/folio_queue.h
··· 3 3 * 4 4 * Copyright (C) 2024 Red Hat, Inc. All Rights Reserved. 5 5 * Written by David Howells (dhowells@redhat.com) 6 + * 7 + * See: 8 + * 9 + * Documentation/core-api/folio_queue.rst 10 + * 11 + * for a description of the API. 6 12 */ 7 13 8 14 #ifndef _LINUX_FOLIO_QUEUE_H ··· 39 33 #endif 40 34 }; 41 35 36 + /** 37 + * folioq_init - Initialise a folio queue segment 38 + * @folioq: The segment to initialise 39 + * 40 + * Initialise a folio queue segment. Note that the folio pointers are 41 + * left uninitialised. 42 + */ 42 43 static inline void folioq_init(struct folio_queue *folioq) 43 44 { 44 45 folio_batch_init(&folioq->vec); ··· 56 43 folioq->marks3 = 0; 57 44 } 58 45 46 + /** 47 + * folioq_nr_slots: Query the capacity of a folio queue segment 48 + * @folioq: The segment to query 49 + * 50 + * Query the number of folios that a particular folio queue segment might hold. 51 + * [!] NOTE: This must not be assumed to be the same for every segment! 52 + */ 59 53 static inline unsigned int folioq_nr_slots(const struct folio_queue *folioq) 60 54 { 61 55 return PAGEVEC_SIZE; 62 56 } 63 57 58 + /** 59 + * folioq_count: Query the occupancy of a folio queue segment 60 + * @folioq: The segment to query 61 + * 62 + * Query the number of folios that have been added to a folio queue segment. 63 + * Note that this is not decreased as folios are removed from a segment. 64 + */ 64 65 static inline unsigned int folioq_count(struct folio_queue *folioq) 65 66 { 66 67 return folio_batch_count(&folioq->vec); 67 68 } 68 69 70 + /** 71 + * folioq_count: Query if a folio queue segment is full 72 + * @folioq: The segment to query 73 + * 74 + * Query if a folio queue segment is fully occupied. Note that this does not 75 + * change if folios are removed from a segment. 76 + */ 69 77 static inline bool folioq_full(struct folio_queue *folioq) 70 78 { 71 79 //return !folio_batch_space(&folioq->vec); 72 80 return folioq_count(folioq) >= folioq_nr_slots(folioq); 73 81 } 74 82 83 + /** 84 + * folioq_is_marked: Check first folio mark in a folio queue segment 85 + * @folioq: The segment to query 86 + * @slot: The slot number of the folio to query 87 + * 88 + * Determine if the first mark is set for the folio in the specified slot in a 89 + * folio queue segment. 90 + */ 75 91 static inline bool folioq_is_marked(const struct folio_queue *folioq, unsigned int slot) 76 92 { 77 93 return test_bit(slot, &folioq->marks); 78 94 } 79 95 96 + /** 97 + * folioq_mark: Set the first mark on a folio in a folio queue segment 98 + * @folioq: The segment to modify 99 + * @slot: The slot number of the folio to modify 100 + * 101 + * Set the first mark for the folio in the specified slot in a folio queue 102 + * segment. 103 + */ 80 104 static inline void folioq_mark(struct folio_queue *folioq, unsigned int slot) 81 105 { 82 106 set_bit(slot, &folioq->marks); 83 107 } 84 108 109 + /** 110 + * folioq_unmark: Clear the first mark on a folio in a folio queue segment 111 + * @folioq: The segment to modify 112 + * @slot: The slot number of the folio to modify 113 + * 114 + * Clear the first mark for the folio in the specified slot in a folio queue 115 + * segment. 116 + */ 85 117 static inline void folioq_unmark(struct folio_queue *folioq, unsigned int slot) 86 118 { 87 119 clear_bit(slot, &folioq->marks); 88 120 } 89 121 122 + /** 123 + * folioq_is_marked2: Check second folio mark in a folio queue segment 124 + * @folioq: The segment to query 125 + * @slot: The slot number of the folio to query 126 + * 127 + * Determine if the second mark is set for the folio in the specified slot in a 128 + * folio queue segment. 129 + */ 90 130 static inline bool folioq_is_marked2(const struct folio_queue *folioq, unsigned int slot) 91 131 { 92 132 return test_bit(slot, &folioq->marks2); 93 133 } 94 134 135 + /** 136 + * folioq_mark2: Set the second mark on a folio in a folio queue segment 137 + * @folioq: The segment to modify 138 + * @slot: The slot number of the folio to modify 139 + * 140 + * Set the second mark for the folio in the specified slot in a folio queue 141 + * segment. 142 + */ 95 143 static inline void folioq_mark2(struct folio_queue *folioq, unsigned int slot) 96 144 { 97 145 set_bit(slot, &folioq->marks2); 98 146 } 99 147 148 + /** 149 + * folioq_unmark2: Clear the second mark on a folio in a folio queue segment 150 + * @folioq: The segment to modify 151 + * @slot: The slot number of the folio to modify 152 + * 153 + * Clear the second mark for the folio in the specified slot in a folio queue 154 + * segment. 155 + */ 100 156 static inline void folioq_unmark2(struct folio_queue *folioq, unsigned int slot) 101 157 { 102 158 clear_bit(slot, &folioq->marks2); 103 159 } 104 160 161 + /** 162 + * folioq_is_marked3: Check third folio mark in a folio queue segment 163 + * @folioq: The segment to query 164 + * @slot: The slot number of the folio to query 165 + * 166 + * Determine if the third mark is set for the folio in the specified slot in a 167 + * folio queue segment. 168 + */ 105 169 static inline bool folioq_is_marked3(const struct folio_queue *folioq, unsigned int slot) 106 170 { 107 171 return test_bit(slot, &folioq->marks3); 108 172 } 109 173 174 + /** 175 + * folioq_mark3: Set the third mark on a folio in a folio queue segment 176 + * @folioq: The segment to modify 177 + * @slot: The slot number of the folio to modify 178 + * 179 + * Set the third mark for the folio in the specified slot in a folio queue 180 + * segment. 181 + */ 110 182 static inline void folioq_mark3(struct folio_queue *folioq, unsigned int slot) 111 183 { 112 184 set_bit(slot, &folioq->marks3); 113 185 } 114 186 187 + /** 188 + * folioq_unmark3: Clear the third mark on a folio in a folio queue segment 189 + * @folioq: The segment to modify 190 + * @slot: The slot number of the folio to modify 191 + * 192 + * Clear the third mark for the folio in the specified slot in a folio queue 193 + * segment. 194 + */ 115 195 static inline void folioq_unmark3(struct folio_queue *folioq, unsigned int slot) 116 196 { 117 197 clear_bit(slot, &folioq->marks3); ··· 217 111 return folio->_flags_1 & 0xff; 218 112 } 219 113 114 + /** 115 + * folioq_append: Add a folio to a folio queue segment 116 + * @folioq: The segment to add to 117 + * @folio: The folio to add 118 + * 119 + * Add a folio to the tail of the sequence in a folio queue segment, increasing 120 + * the occupancy count and returning the slot number for the folio just added. 121 + * The folio size is extracted and stored in the queue and the marks are left 122 + * unmodified. 123 + * 124 + * Note that it's left up to the caller to check that the segment capacity will 125 + * not be exceeded and to extend the queue. 126 + */ 220 127 static inline unsigned int folioq_append(struct folio_queue *folioq, struct folio *folio) 221 128 { 222 129 unsigned int slot = folioq->vec.nr++; ··· 239 120 return slot; 240 121 } 241 122 123 + /** 124 + * folioq_append_mark: Add a folio to a folio queue segment 125 + * @folioq: The segment to add to 126 + * @folio: The folio to add 127 + * 128 + * Add a folio to the tail of the sequence in a folio queue segment, increasing 129 + * the occupancy count and returning the slot number for the folio just added. 130 + * The folio size is extracted and stored in the queue, the first mark is set 131 + * and and the second and third marks are left unmodified. 132 + * 133 + * Note that it's left up to the caller to check that the segment capacity will 134 + * not be exceeded and to extend the queue. 135 + */ 242 136 static inline unsigned int folioq_append_mark(struct folio_queue *folioq, struct folio *folio) 243 137 { 244 138 unsigned int slot = folioq->vec.nr++; ··· 262 130 return slot; 263 131 } 264 132 133 + /** 134 + * folioq_folio: Get a folio from a folio queue segment 135 + * @folioq: The segment to access 136 + * @slot: The folio slot to access 137 + * 138 + * Retrieve the folio in the specified slot from a folio queue segment. Note 139 + * that no bounds check is made and if the slot hasn't been added into yet, the 140 + * pointer will be undefined. If the slot has been cleared, NULL will be 141 + * returned. 142 + */ 265 143 static inline struct folio *folioq_folio(const struct folio_queue *folioq, unsigned int slot) 266 144 { 267 145 return folioq->vec.folios[slot]; 268 146 } 269 147 148 + /** 149 + * folioq_folio_order: Get the order of a folio from a folio queue segment 150 + * @folioq: The segment to access 151 + * @slot: The folio slot to access 152 + * 153 + * Retrieve the order of the folio in the specified slot from a folio queue 154 + * segment. Note that no bounds check is made and if the slot hasn't been 155 + * added into yet, the order returned will be 0. 156 + */ 270 157 static inline unsigned int folioq_folio_order(const struct folio_queue *folioq, unsigned int slot) 271 158 { 272 159 return folioq->orders[slot]; 273 160 } 274 161 162 + /** 163 + * folioq_folio_size: Get the size of a folio from a folio queue segment 164 + * @folioq: The segment to access 165 + * @slot: The folio slot to access 166 + * 167 + * Retrieve the size of the folio in the specified slot from a folio queue 168 + * segment. Note that no bounds check is made and if the slot hasn't been 169 + * added into yet, the size returned will be PAGE_SIZE. 170 + */ 275 171 static inline size_t folioq_folio_size(const struct folio_queue *folioq, unsigned int slot) 276 172 { 277 173 return PAGE_SIZE << folioq_folio_order(folioq, slot); 278 174 } 279 175 176 + /** 177 + * folioq_clear: Clear a folio from a folio queue segment 178 + * @folioq: The segment to clear 179 + * @slot: The folio slot to clear 180 + * 181 + * Clear a folio from a sequence in a folio queue segment and clear its marks. 182 + * The occupancy count is left unchanged. 183 + */ 280 184 static inline void folioq_clear(struct folio_queue *folioq, unsigned int slot) 281 185 { 282 186 folioq->vec.folios[slot] = NULL;
+2 -1
include/trace/events/netfs.h
··· 448 448 ), 449 449 450 450 TP_fast_assign( 451 - __entry->ino = folio->mapping->host->i_ino; 451 + struct address_space *__m = READ_ONCE(folio->mapping); 452 + __entry->ino = __m ? __m->host->i_ino : 0; 452 453 __entry->why = why; 453 454 __entry->index = folio_index(folio); 454 455 __entry->nr = folio_nr_pages(folio);