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