Ejemplo n.º 1
0
/*
 * Caller must hold lock_page() or backend (otherwise, you may race
 * with buffer fork or clear dirty)
 */
int tux3_set_buffer_dirty_list(struct address_space *mapping,
			       struct buffer_head *buffer, int delta,
			       struct list_head *head)
{
	/* FIXME: we better to set this by caller? */
	if (!buffer_uptodate(buffer))
		set_buffer_uptodate(buffer);

	/*
	 * Basically, open code of mark_buffer_dirty() without mark
	 * inode dirty.  Caller decides whether dirty inode or not.
	 */
	if (!test_set_buffer_dirty(buffer)) {
		struct page *page = buffer->b_page;

		/* Mark dirty for delta, then add buffer to our dirty list */
		__tux3_set_buffer_dirty_list(mapping, buffer, delta, head);

		if (!TestSetPageDirty(page)) {
			struct address_space *mapping = page->mapping;
			if (mapping)
				__tux3_set_page_dirty(page, mapping, 0);
			return 1;
		}
	}
	return 0;
}
/**
 * nilfs_btnode_commit_change_key
 *  commit the change_key operation prepared by prepare_change_key().
 */
void nilfs_btnode_commit_change_key(struct address_space *btnc,
				    struct nilfs_btnode_chkey_ctxt *ctxt)
{
	struct buffer_head *obh = ctxt->bh, *nbh = ctxt->newbh;
	__u64 oldkey = ctxt->oldkey, newkey = ctxt->newkey;
	struct page *opage;

	if (oldkey == newkey)
		return;

	if (nbh == NULL) {	/* blocksize == pagesize */
		opage = obh->b_page;
		if (unlikely(oldkey != opage->index))
			NILFS_PAGE_BUG(opage,
				       "invalid oldkey %lld (newkey=%lld)",
				       (unsigned long long)oldkey,
				       (unsigned long long)newkey);
		if (!test_set_buffer_dirty(obh) && TestSetPageDirty(opage))
			BUG();

		WRITE_LOCK_IRQ(&btnc->tree_lock);
		radix_tree_delete(&btnc->page_tree, oldkey);
		radix_tree_tag_set(&btnc->page_tree, newkey,
				   PAGECACHE_TAG_DIRTY);
		WRITE_UNLOCK_IRQ(&btnc->tree_lock);

		opage->index = obh->b_blocknr = newkey;
		unlock_page(opage);
	} else {
		nilfs_copy_buffer(nbh, obh);
		nilfs_btnode_mark_dirty(nbh);

		nbh->b_blocknr = newkey;
		ctxt->bh = nbh;
		nilfs_btnode_delete(obh); /* will decrement bh->b_count */
	}
}
Ejemplo n.º 3
0
/*
 * Since the page cache of B-tree node pages or data page cache of pseudo
 * inodes does not have a valid mapping->host pointer, calling
 * mark_buffer_dirty() for their buffers causes a NULL pointer dereference;
 * it calls __mark_inode_dirty(NULL) through __set_page_dirty().
 * To avoid this problem, the old style mark_buffer_dirty() is used instead.
 */
void nilfs_mark_buffer_dirty(struct buffer_head *bh)
{
	if (!buffer_dirty(bh) && !test_set_buffer_dirty(bh))
		__set_page_dirty_nobuffers(bh->b_page);
}