Пример #1
0
struct buffer_head *blockdirty(struct buffer_head *buffer, unsigned newdelta)
{
	map_t *map = buffer->map;

	assert(buffer->state < BUFFER_STATES);

	buftrace("---- before: fork buffer %p ----", buffer);
	if (buffer_dirty(buffer)) {
		if (buffer_already_dirty(buffer, newdelta))
			return buffer;

		/* Buffer can't modify already, we have to fork buffer */
		buftrace("---- fork buffer %p ----", buffer);
		struct buffer_head *clone = new_buffer(map);
		if (IS_ERR(clone))
			return clone;
		/* Create the cloned buffer */
		memcpy(bufdata(clone), bufdata(buffer), bufsize(buffer));
		clone->index = buffer->index;
		/* Replace the buffer by cloned buffer. */
		remove_buffer_hash(buffer);
		insert_buffer_hash(clone);

		/*
		 * The refcount of buffer is used for backend. So, the
		 * backend has to free this buffer (blockput(buffer))
		 */
		buffer = clone;
	}

	__tux3_mark_buffer_dirty(buffer, newdelta);

	return buffer;
}
Пример #2
0
static int tux3_set_page_dirty_buffers(struct page *page)
{
#if 0
	struct address_space *mapping = page->mapping;
	int newly_dirty;

	spin_lock(&mapping->private_lock);
	if (page_has_buffers(page)) {
		struct buffer_head *head = page_buffers(page);
		struct buffer_head *bh = head;

		do {
			set_buffer_dirty(bh);
			bh = bh->b_this_page;
		} while (bh != head);
	}
	newly_dirty = !TestSetPageDirty(page);
	spin_unlock(&mapping->private_lock);

	if (newly_dirty)
		__set_page_dirty(page, mapping, 1);

	return newly_dirty;
#else
	struct address_space *mapping = page->mapping;
	unsigned delta = tux3_get_current_delta();
	struct buffer_head *head, *buffer;
	int newly_dirty;

	/* This should be tux3 page and locked */
	assert(mapping);
	assert(PageLocked(page));
	/* This page should have buffers (caller should allocate) */
	assert(page_has_buffers(page));

	/*
	 * FIXME: we dirty all buffers on this page, so we optimize this
	 * by avoiding to check page-dirty/inode-dirty multiple times.
	 */
	newly_dirty = 0;
	if (!TestSetPageDirty(page)) {
		__tux3_set_page_dirty(page, mapping, 1);
		newly_dirty = 1;
	}
	buffer = head = page_buffers(page);
	do {
		__tux3_mark_buffer_dirty(buffer, delta);
		buffer = buffer->b_this_page;
	} while (buffer != head);
#endif
	return newly_dirty;
}