// SPDX-License-Identifier: GPL-2.0+ /* * Dummy inodes to buffer blocks for garbage collection * * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation. * * Written by Seiji Kihara, Amagai Yoshiji, and Ryusuke Konishi. * Revised by Ryusuke Konishi. *
*/ /* * This file adds the cache of on-disk blocks to be moved in garbage * collection. The disk blocks are held with dummy inodes (called * gcinodes), and this file provides lookup function of the dummy * inodes and their buffer read function. * * Buffers and pages held by the dummy inodes will be released each * time after they are copied to a new log. Dirty blocks made on the * current generation and the blocks to be moved by GC never overlap * because the dirty blocks make a new generation; they rather must be * written individually.
*/
/* * nilfs_gccache_submit_read_data() - add data buffer and submit read request * @inode - gc inode * @blkoff - dummy offset treated as the key for the page cache * @pbn - physical block number of the block * @vbn - virtual block number of the block, 0 for non-virtual block * @out_bh - indirect pointer to a buffer_head struct to receive the results * * Description: nilfs_gccache_submit_read_data() registers the data buffer * specified by @pbn to the GC pagecache with the key @blkoff. * This function sets @vbn (@pbn if @vbn is zero) in b_blocknr of the buffer. * * Return: 0 on success, or one of the following negative error codes on * failure: * * %-EIO - I/O error (including metadata corruption). * * %-ENOENT - The block specified with @pbn does not exist. * * %-ENOMEM - Insufficient memory available.
*/ int nilfs_gccache_submit_read_data(struct inode *inode, sector_t blkoff,
sector_t pbn, __u64 vbn, struct buffer_head **out_bh)
{ struct buffer_head *bh; int err;
bh = nilfs_grab_buffer(inode, inode->i_mapping, blkoff, 0); if (unlikely(!bh)) return -ENOMEM;
if (buffer_uptodate(bh)) goto out;
if (pbn == 0) { struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
failed:
folio_unlock(bh->b_folio);
folio_put(bh->b_folio); if (unlikely(err))
brelse(bh); return err;
}
/* * nilfs_gccache_submit_read_node() - add node buffer and submit read request * @inode - gc inode * @pbn - physical block number for the block * @vbn - virtual block number for the block * @out_bh - indirect pointer to a buffer_head struct to receive the results * * Description: nilfs_gccache_submit_read_node() registers the node buffer * specified by @vbn to the GC pagecache. @pbn can be supplied by the * caller to avoid translation of the disk block address. * * Return: 0 on success, or one of the following negative error codes on * failure: * * %-EIO - I/O error (including metadata corruption). * * %-ENOENT - Invalid virtual block address. * * %-ENOMEM - Insufficient memory available.
*/ int nilfs_gccache_submit_read_node(struct inode *inode, sector_t pbn,
__u64 vbn, struct buffer_head **out_bh)
{ struct inode *btnc_inode = NILFS_I(inode)->i_assoc_inode; int ret;
ret = nilfs_btnode_submit_block(btnc_inode->i_mapping, vbn ? : pbn, pbn,
REQ_OP_READ, out_bh, &pbn); if (ret == -EEXIST) /* internal code (cache hit) */
ret = 0; return ret;
}
int nilfs_gccache_wait_and_mark_dirty(struct buffer_head *bh)
{
wait_on_buffer(bh); if (!buffer_uptodate(bh)) { struct inode *inode = bh->b_folio->mapping->host;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.