Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Dummy inodes to buffer blocks for garbage collection
0004  *
0005  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
0006  *
0007  * Written by Seiji Kihara, Amagai Yoshiji, and Ryusuke Konishi.
0008  * Revised by Ryusuke Konishi.
0009  *
0010  */
0011 /*
0012  * This file adds the cache of on-disk blocks to be moved in garbage
0013  * collection.  The disk blocks are held with dummy inodes (called
0014  * gcinodes), and this file provides lookup function of the dummy
0015  * inodes and their buffer read function.
0016  *
0017  * Buffers and pages held by the dummy inodes will be released each
0018  * time after they are copied to a new log.  Dirty blocks made on the
0019  * current generation and the blocks to be moved by GC never overlap
0020  * because the dirty blocks make a new generation; they rather must be
0021  * written individually.
0022  */
0023 
0024 #include <linux/buffer_head.h>
0025 #include <linux/mpage.h>
0026 #include <linux/hash.h>
0027 #include <linux/slab.h>
0028 #include <linux/swap.h>
0029 #include "nilfs.h"
0030 #include "btree.h"
0031 #include "btnode.h"
0032 #include "page.h"
0033 #include "mdt.h"
0034 #include "dat.h"
0035 #include "ifile.h"
0036 
0037 /*
0038  * nilfs_gccache_submit_read_data() - add data buffer and submit read request
0039  * @inode - gc inode
0040  * @blkoff - dummy offset treated as the key for the page cache
0041  * @pbn - physical block number of the block
0042  * @vbn - virtual block number of the block, 0 for non-virtual block
0043  * @out_bh - indirect pointer to a buffer_head struct to receive the results
0044  *
0045  * Description: nilfs_gccache_submit_read_data() registers the data buffer
0046  * specified by @pbn to the GC pagecache with the key @blkoff.
0047  * This function sets @vbn (@pbn if @vbn is zero) in b_blocknr of the buffer.
0048  *
0049  * Return Value: On success, 0 is returned. On Error, one of the following
0050  * negative error code is returned.
0051  *
0052  * %-EIO - I/O error.
0053  *
0054  * %-ENOMEM - Insufficient amount of memory available.
0055  *
0056  * %-ENOENT - The block specified with @pbn does not exist.
0057  */
0058 int nilfs_gccache_submit_read_data(struct inode *inode, sector_t blkoff,
0059                    sector_t pbn, __u64 vbn,
0060                    struct buffer_head **out_bh)
0061 {
0062     struct buffer_head *bh;
0063     int err;
0064 
0065     bh = nilfs_grab_buffer(inode, inode->i_mapping, blkoff, 0);
0066     if (unlikely(!bh))
0067         return -ENOMEM;
0068 
0069     if (buffer_uptodate(bh))
0070         goto out;
0071 
0072     if (pbn == 0) {
0073         struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
0074 
0075         err = nilfs_dat_translate(nilfs->ns_dat, vbn, &pbn);
0076         if (unlikely(err)) { /* -EIO, -ENOMEM, -ENOENT */
0077             brelse(bh);
0078             goto failed;
0079         }
0080     }
0081 
0082     lock_buffer(bh);
0083     if (buffer_uptodate(bh)) {
0084         unlock_buffer(bh);
0085         goto out;
0086     }
0087 
0088     if (!buffer_mapped(bh)) {
0089         bh->b_bdev = inode->i_sb->s_bdev;
0090         set_buffer_mapped(bh);
0091     }
0092     bh->b_blocknr = pbn;
0093     bh->b_end_io = end_buffer_read_sync;
0094     get_bh(bh);
0095     submit_bh(REQ_OP_READ, bh);
0096     if (vbn)
0097         bh->b_blocknr = vbn;
0098  out:
0099     err = 0;
0100     *out_bh = bh;
0101 
0102  failed:
0103     unlock_page(bh->b_page);
0104     put_page(bh->b_page);
0105     return err;
0106 }
0107 
0108 /*
0109  * nilfs_gccache_submit_read_node() - add node buffer and submit read request
0110  * @inode - gc inode
0111  * @pbn - physical block number for the block
0112  * @vbn - virtual block number for the block
0113  * @out_bh - indirect pointer to a buffer_head struct to receive the results
0114  *
0115  * Description: nilfs_gccache_submit_read_node() registers the node buffer
0116  * specified by @vbn to the GC pagecache.  @pbn can be supplied by the
0117  * caller to avoid translation of the disk block address.
0118  *
0119  * Return Value: On success, 0 is returned. On Error, one of the following
0120  * negative error code is returned.
0121  *
0122  * %-EIO - I/O error.
0123  *
0124  * %-ENOMEM - Insufficient amount of memory available.
0125  */
0126 int nilfs_gccache_submit_read_node(struct inode *inode, sector_t pbn,
0127                    __u64 vbn, struct buffer_head **out_bh)
0128 {
0129     struct inode *btnc_inode = NILFS_I(inode)->i_assoc_inode;
0130     int ret;
0131 
0132     ret = nilfs_btnode_submit_block(btnc_inode->i_mapping, vbn ? : pbn, pbn,
0133                     REQ_OP_READ, out_bh, &pbn);
0134     if (ret == -EEXIST) /* internal code (cache hit) */
0135         ret = 0;
0136     return ret;
0137 }
0138 
0139 int nilfs_gccache_wait_and_mark_dirty(struct buffer_head *bh)
0140 {
0141     wait_on_buffer(bh);
0142     if (!buffer_uptodate(bh)) {
0143         struct inode *inode = bh->b_page->mapping->host;
0144 
0145         nilfs_err(inode->i_sb,
0146               "I/O error reading %s block for GC (ino=%lu, vblocknr=%llu)",
0147               buffer_nilfs_node(bh) ? "node" : "data",
0148               inode->i_ino, (unsigned long long)bh->b_blocknr);
0149         return -EIO;
0150     }
0151     if (buffer_dirty(bh))
0152         return -EEXIST;
0153 
0154     if (buffer_nilfs_node(bh) && nilfs_btree_broken_node_block(bh)) {
0155         clear_buffer_uptodate(bh);
0156         return -EIO;
0157     }
0158     mark_buffer_dirty(bh);
0159     return 0;
0160 }
0161 
0162 int nilfs_init_gcinode(struct inode *inode)
0163 {
0164     struct nilfs_inode_info *ii = NILFS_I(inode);
0165 
0166     inode->i_mode = S_IFREG;
0167     mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
0168     inode->i_mapping->a_ops = &empty_aops;
0169 
0170     ii->i_flags = 0;
0171     nilfs_bmap_init_gc(ii->i_bmap);
0172 
0173     return nilfs_attach_btree_node_cache(inode);
0174 }
0175 
0176 /**
0177  * nilfs_remove_all_gcinodes() - remove all unprocessed gc inodes
0178  */
0179 void nilfs_remove_all_gcinodes(struct the_nilfs *nilfs)
0180 {
0181     struct list_head *head = &nilfs->ns_gc_inodes;
0182     struct nilfs_inode_info *ii;
0183 
0184     while (!list_empty(head)) {
0185         ii = list_first_entry(head, struct nilfs_inode_info, i_dirty);
0186         list_del_init(&ii->i_dirty);
0187         truncate_inode_pages(&ii->vfs_inode.i_data, 0);
0188         nilfs_btnode_cache_clear(ii->i_assoc_inode->i_mapping);
0189         iput(&ii->vfs_inode);
0190     }
0191 }