1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Dummy inodes to buffer blocks for garbage collection 4 * 5 * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation. 6 * 7 * Written by Seiji Kihara, Amagai Yoshiji, and Ryusuke Konishi. 8 * Revised by Ryusuke Konishi. 9 * 10 */ 11 /* 12 * This file adds the cache of on-disk blocks to be moved in garbage 13 * collection. The disk blocks are held with dummy inodes (called 14 * gcinodes), and this file provides lookup function of the dummy 15 * inodes and their buffer read function. 16 * 17 * Buffers and pages held by the dummy inodes will be released each 18 * time after they are copied to a new log. Dirty blocks made on the 19 * current generation and the blocks to be moved by GC never overlap 20 * because the dirty blocks make a new generation; they rather must be 21 * written individually. 22 */ 23 24 #include <linux/buffer_head.h> 25 #include <linux/mpage.h> 26 #include <linux/hash.h> 27 #include <linux/slab.h> 28 #include <linux/swap.h> 29 #include "nilfs.h" 30 #include "btree.h" 31 #include "btnode.h" 32 #include "page.h" 33 #include "mdt.h" 34 #include "dat.h" 35 #include "ifile.h" 36 37 /* 38 * nilfs_gccache_submit_read_data() - add data buffer and submit read request 39 * @inode - gc inode 40 * @blkoff - dummy offset treated as the key for the page cache 41 * @pbn - physical block number of the block 42 * @vbn - virtual block number of the block, 0 for non-virtual block 43 * @out_bh - indirect pointer to a buffer_head struct to receive the results 44 * 45 * Description: nilfs_gccache_submit_read_data() registers the data buffer 46 * specified by @pbn to the GC pagecache with the key @blkoff. 47 * This function sets @vbn (@pbn if @vbn is zero) in b_blocknr of the buffer. 48 * 49 * Return: 0 on success, or one of the following negative error codes on 50 * failure: 51 * * %-EIO - I/O error (including metadata corruption). 52 * * %-ENOENT - The block specified with @pbn does not exist. 53 * * %-ENOMEM - Insufficient memory available. 54 */ 55 int nilfs_gccache_submit_read_data(struct inode *inode, sector_t blkoff, 56 sector_t pbn, __u64 vbn, 57 struct buffer_head **out_bh) 58 { 59 struct buffer_head *bh; 60 int err; 61 62 bh = nilfs_grab_buffer(inode, inode->i_mapping, blkoff, 0); 63 if (unlikely(!bh)) 64 return -ENOMEM; 65 66 if (buffer_uptodate(bh)) 67 goto out; 68 69 if (pbn == 0) { 70 struct the_nilfs *nilfs = inode->i_sb->s_fs_info; 71 72 err = nilfs_dat_translate(nilfs->ns_dat, vbn, &pbn); 73 if (unlikely(err)) /* -EIO, -ENOMEM, -ENOENT */ 74 goto failed; 75 } 76 77 lock_buffer(bh); 78 if (buffer_uptodate(bh)) { 79 unlock_buffer(bh); 80 goto out; 81 } 82 83 if (!buffer_mapped(bh)) 84 set_buffer_mapped(bh); 85 bh->b_blocknr = pbn; 86 bh->b_end_io = end_buffer_read_sync; 87 get_bh(bh); 88 submit_bh(REQ_OP_READ, bh); 89 if (vbn) 90 bh->b_blocknr = vbn; 91 out: 92 err = 0; 93 *out_bh = bh; 94 95 failed: 96 folio_unlock(bh->b_folio); 97 folio_put(bh->b_folio); 98 if (unlikely(err)) 99 brelse(bh); 100 return err; 101 } 102 103 /* 104 * nilfs_gccache_submit_read_node() - add node buffer and submit read request 105 * @inode - gc inode 106 * @pbn - physical block number for the block 107 * @vbn - virtual block number for the block 108 * @out_bh - indirect pointer to a buffer_head struct to receive the results 109 * 110 * Description: nilfs_gccache_submit_read_node() registers the node buffer 111 * specified by @vbn to the GC pagecache. @pbn can be supplied by the 112 * caller to avoid translation of the disk block address. 113 * 114 * Return: 0 on success, or one of the following negative error codes on 115 * failure: 116 * * %-EIO - I/O error (including metadata corruption). 117 * * %-ENOENT - Invalid virtual block address. 118 * * %-ENOMEM - Insufficient memory available. 119 */ 120 int nilfs_gccache_submit_read_node(struct inode *inode, sector_t pbn, 121 __u64 vbn, struct buffer_head **out_bh) 122 { 123 struct inode *btnc_inode = NILFS_I(inode)->i_assoc_inode; 124 int ret; 125 126 ret = nilfs_btnode_submit_block(btnc_inode->i_mapping, vbn ? : pbn, pbn, 127 REQ_OP_READ, out_bh, &pbn); 128 if (ret == -EEXIST) /* internal code (cache hit) */ 129 ret = 0; 130 return ret; 131 } 132 133 int nilfs_gccache_wait_and_mark_dirty(struct buffer_head *bh) 134 { 135 wait_on_buffer(bh); 136 if (!buffer_uptodate(bh)) { 137 struct inode *inode = bh->b_folio->mapping->host; 138 139 nilfs_err(inode->i_sb, 140 "I/O error reading %s block for GC (ino=%lu, vblocknr=%llu)", 141 buffer_nilfs_node(bh) ? "node" : "data", 142 inode->i_ino, (unsigned long long)bh->b_blocknr); 143 return -EIO; 144 } 145 if (buffer_dirty(bh)) 146 return -EEXIST; 147 148 if (buffer_nilfs_node(bh) && nilfs_btree_broken_node_block(bh)) { 149 clear_buffer_uptodate(bh); 150 return -EIO; 151 } 152 mark_buffer_dirty(bh); 153 return 0; 154 } 155 156 int nilfs_init_gcinode(struct inode *inode) 157 { 158 struct nilfs_inode_info *ii = NILFS_I(inode); 159 160 inode->i_mode = S_IFREG; 161 mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); 162 inode->i_mapping->a_ops = &nilfs_buffer_cache_aops; 163 164 ii->i_flags = 0; 165 nilfs_bmap_init_gc(ii->i_bmap); 166 167 return nilfs_attach_btree_node_cache(inode); 168 } 169 170 /** 171 * nilfs_remove_all_gcinodes() - remove all unprocessed gc inodes 172 * @nilfs: NILFS filesystem instance 173 */ 174 void nilfs_remove_all_gcinodes(struct the_nilfs *nilfs) 175 { 176 struct list_head *head = &nilfs->ns_gc_inodes; 177 struct nilfs_inode_info *ii; 178 179 while (!list_empty(head)) { 180 ii = list_first_entry(head, struct nilfs_inode_info, i_dirty); 181 list_del_init(&ii->i_dirty); 182 truncate_inode_pages(&ii->vfs_inode.i_data, 0); 183 nilfs_btnode_cache_clear(ii->i_assoc_inode->i_mapping); 184 iput(&ii->vfs_inode); 185 } 186 } 187