if (unlikely(req->pr_desc_bh == NULL || req->pr_bitmap_bh == NULL)) {
nilfs_error(dat->i_sb, "state inconsistency probably due to duplicate use of vblocknr = %llu",
(unsignedlonglong)req->pr_entry_nr); return;
}
nilfs_palloc_commit_free_entry(dat, req);
}
/** * nilfs_dat_mark_dirty - mark the DAT block buffer containing the specified * virtual block address entry as dirty * @dat: DAT file inode * @vblocknr: virtual block number * * Return: 0 on success, or one of the following negative error codes on * failure: * * %-EINVAL - Invalid DAT entry (internal code). * * %-EIO - I/O error (including metadata corruption). * * %-ENOMEM - Insufficient memory available.
*/ int nilfs_dat_mark_dirty(struct inode *dat, __u64 vblocknr)
{ struct nilfs_palloc_req req; int ret;
req.pr_entry_nr = vblocknr;
ret = nilfs_dat_prepare_entry(dat, &req, 0); if (ret == 0)
nilfs_dat_commit_entry(dat, &req); return ret;
}
/** * nilfs_dat_freev - free virtual block numbers * @dat: DAT file inode * @vblocknrs: array of virtual block numbers * @nitems: number of virtual block numbers * * Description: nilfs_dat_freev() frees the virtual block numbers specified by * @vblocknrs and @nitems. * * Return: 0 on success, or one of the following negative error codes on * failure: * * %-EIO - I/O error (including metadata corruption). * * %-ENOENT - The virtual block number have not been allocated. * * %-ENOMEM - Insufficient memory available.
*/ int nilfs_dat_freev(struct inode *dat, __u64 *vblocknrs, size_t nitems)
{ return nilfs_palloc_freev(dat, vblocknrs, nitems);
}
/** * nilfs_dat_move - change a block number * @dat: DAT file inode * @vblocknr: virtual block number * @blocknr: block number * * Description: nilfs_dat_move() changes the block number associated with * @vblocknr to @blocknr. * * Return: 0 on success, or one of the following negative error codes on * failure: * * %-EIO - I/O error (including metadata corruption). * * %-ENOMEM - Insufficient memory available.
*/ int nilfs_dat_move(struct inode *dat, __u64 vblocknr, sector_t blocknr)
{ struct buffer_head *entry_bh; struct nilfs_dat_entry *entry;
size_t offset; int ret;
ret = nilfs_palloc_get_entry_block(dat, vblocknr, 0, &entry_bh); if (ret < 0) return ret;
/* * The given disk block number (blocknr) is not yet written to * the device at this point. * * To prevent nilfs_dat_translate() from returning the * uncommitted block number, this makes a copy of the entry * buffer and redirects nilfs_dat_translate() to the copy.
*/ if (!buffer_nilfs_redirected(entry_bh)) {
ret = nilfs_mdt_freeze_buffer(dat, entry_bh); if (ret) {
brelse(entry_bh); return ret;
}
}
/** * nilfs_dat_translate - translate a virtual block number to a block number * @dat: DAT file inode * @vblocknr: virtual block number * @blocknrp: pointer to a block number * * Description: nilfs_dat_translate() maps the virtual block number @vblocknr * to the corresponding block number. The block number associated with * @vblocknr is stored in the place pointed to by @blocknrp. * * Return: 0 on success, or one of the following negative error codes on * failure: * * %-EIO - I/O error (including metadata corruption). * * %-ENOENT - A block number associated with @vblocknr does not exist. * * %-ENOMEM - Insufficient memory available.
*/ int nilfs_dat_translate(struct inode *dat, __u64 vblocknr, sector_t *blocknrp)
{ struct buffer_head *entry_bh, *bh; struct nilfs_dat_entry *entry;
sector_t blocknr;
size_t offset; int ret;
ret = nilfs_palloc_get_entry_block(dat, vblocknr, 0, &entry_bh); if (ret < 0) return ret;
if (!nilfs_doing_gc() && buffer_nilfs_redirected(entry_bh)) {
bh = nilfs_mdt_get_frozen_buffer(dat, entry_bh); if (bh) {
WARN_ON(!buffer_uptodate(bh));
brelse(entry_bh);
entry_bh = bh;
}
}
/** * nilfs_dat_read - read or get dat inode * @sb: super block instance * @entry_size: size of a dat entry * @raw_inode: on-disk dat inode * @inodep: buffer to store the inode * * Return: 0 on success, or a negative error code on failure.
*/ int nilfs_dat_read(struct super_block *sb, size_t entry_size, struct nilfs_inode *raw_inode, struct inode **inodep)
{ staticstruct lock_class_key dat_lock_key; struct inode *dat; struct nilfs_dat_info *di; int err;
if (entry_size > sb->s_blocksize) {
nilfs_err(sb, "too large DAT entry size: %zu bytes",
entry_size); return -EINVAL;
} elseif (entry_size < NILFS_MIN_DAT_ENTRY_SIZE) {
nilfs_err(sb, "too small DAT entry size: %zu bytes",
entry_size); return -EINVAL;
}
dat = nilfs_iget_locked(sb, NULL, NILFS_DAT_INO); if (unlikely(!dat)) return -ENOMEM; if (!(dat->i_state & I_NEW)) goto out;
err = nilfs_mdt_init(dat, NILFS_MDT_GFP, sizeof(*di)); if (err) goto failed;
err = nilfs_palloc_init_blockgroup(dat, entry_size); if (err) goto failed;
di = NILFS_DAT_I(dat);
lockdep_set_class(&di->mi.mi_sem, &dat_lock_key);
nilfs_palloc_setup_cache(dat, &di->palloc_cache);
err = nilfs_mdt_setup_shadow_map(dat, &di->shadow); if (err) goto failed;
err = nilfs_read_inode_common(dat, raw_inode); if (err) goto failed;
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.