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_submit(bh, REQ_OP_READ, bh_end_read); 87 if (vbn) 88 bh->b_blocknr = vbn; 89 out: 90 err = 0; 91 *out_bh = bh; 92 93 failed: 94 folio_unlock(bh->b_folio); 95 folio_put(bh->b_folio); 96 if (unlikely(err)) 97 brelse(bh); 98 return err; 99 } 100 101 /* 102 * nilfs_gccache_submit_read_node() - add node buffer and submit read request 103 * @inode - gc inode 104 * @pbn - physical block number for the block 105 * @vbn - virtual block number for the block 106 * @out_bh - indirect pointer to a buffer_head struct to receive the results 107 * 108 * Description: nilfs_gccache_submit_read_node() registers the node buffer 109 * specified by @vbn to the GC pagecache. @pbn can be supplied by the 110 * caller to avoid translation of the disk block address. 111 * 112 * Return: 0 on success, or one of the following negative error codes on 113 * failure: 114 * * %-EIO - I/O error (including metadata corruption). 115 * * %-ENOENT - Invalid virtual block address. 116 * * %-ENOMEM - Insufficient memory available. 117 */ 118 int nilfs_gccache_submit_read_node(struct inode *inode, sector_t pbn, 119 __u64 vbn, struct buffer_head **out_bh) 120 { 121 struct inode *btnc_inode = NILFS_I(inode)->i_assoc_inode; 122 int ret; 123 124 ret = nilfs_btnode_submit_block(btnc_inode->i_mapping, vbn ? : pbn, pbn, 125 REQ_OP_READ, out_bh, &pbn); 126 if (ret == -EEXIST) /* internal code (cache hit) */ 127 ret = 0; 128 return ret; 129 } 130 131 int nilfs_gccache_wait_and_mark_dirty(struct buffer_head *bh) 132 { 133 wait_on_buffer(bh); 134 if (!buffer_uptodate(bh)) { 135 struct inode *inode = bh->b_folio->mapping->host; 136 137 nilfs_err(inode->i_sb, 138 "I/O error reading %s block for GC (ino=%llu, vblocknr=%llu)", 139 buffer_nilfs_node(bh) ? "node" : "data", 140 inode->i_ino, (unsigned long long)bh->b_blocknr); 141 return -EIO; 142 } 143 if (buffer_dirty(bh)) 144 return -EEXIST; 145 146 if (buffer_nilfs_node(bh) && nilfs_btree_broken_node_block(bh)) { 147 clear_buffer_uptodate(bh); 148 return -EIO; 149 } 150 mark_buffer_dirty(bh); 151 return 0; 152 } 153 154 int nilfs_init_gcinode(struct inode *inode) 155 { 156 struct nilfs_inode_info *ii = NILFS_I(inode); 157 158 inode->i_mode = S_IFREG; 159 mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); 160 inode->i_mapping->a_ops = &nilfs_buffer_cache_aops; 161 162 ii->i_flags = 0; 163 nilfs_bmap_init_gc(ii->i_bmap); 164 165 return nilfs_attach_btree_node_cache(inode); 166 } 167 168 /** 169 * nilfs_remove_all_gcinodes() - remove all unprocessed gc inodes 170 * @nilfs: NILFS filesystem instance 171 */ 172 void nilfs_remove_all_gcinodes(struct the_nilfs *nilfs) 173 { 174 struct list_head *head = &nilfs->ns_gc_inodes; 175 struct nilfs_inode_info *ii; 176 177 while (!list_empty(head)) { 178 ii = list_first_entry(head, struct nilfs_inode_info, i_dirty); 179 list_del_init(&ii->i_dirty); 180 truncate_inode_pages(&ii->vfs_inode.i_data, 0); 181 nilfs_btnode_cache_clear(ii->i_assoc_inode->i_mapping); 182 iput(&ii->vfs_inode); 183 } 184 } 185