示例#1
0
void nilfs_page_bug(struct page *page)
{
	struct address_space *m;
	unsigned long ino = 0;

	if (unlikely(!page)) {
		printk(KERN_CRIT "NILFS_PAGE_BUG(NULL)\n");
		return;
	}

	m = page->mapping;
	if (m) {
		struct inode *inode = NILFS_AS_I(m);
		if (inode != NULL)
			ino = inode->i_ino;
	}
	printk(KERN_CRIT "NILFS_PAGE_BUG(%p): cnt=%d index#=%llu flags=0x%lx "
	       "mapping=%p ino=%lu\n",
	       page, atomic_read(&page->_count),
	       (unsigned long long)page->index, page->flags, m, ino);

	if (page_has_buffers(page)) {
		struct buffer_head *bh, *head;
		int i = 0;

		bh = head = page_buffers(page);
		do {
			printk(KERN_CRIT
			       " BH[%d] %p: cnt=%d block#=%llu state=0x%lx\n",
			       i++, bh, atomic_read(&bh->b_count),
			       (unsigned long long)bh->b_blocknr, bh->b_state);
			bh = bh->b_this_page;
		} while (bh != head);
	}
}
/*
 * For inode and page debug
 */
int nilfs_releasepage(struct page *page, gfp_t gfp_mask)
{
	struct address_space *mapping = page->mapping;
	struct inode *inode;
	int verbose = (nilfs_debug_info.verbose[NILFS_VERBOSE_PAGE] > 1);
	int ret;

	if (!verbose && mapping) {
		inode = NILFS_AS_I(mapping);
		if (inode->i_sb && !(inode->i_sb->s_flags & MS_ACTIVE))
			verbose = 1;
	}
	if (unlikely(!PagePrivate(page)))
		NILFS_PAGE_BUG(page, "no buffers");

	if (buffer_nilfs_allocated(page_buffers(page)))
		NILFS_PAGE_BUG(page, "nilfs allocated page");

	/*
	 * Note that non-busy buffer heads may be discarded though the
	 * try_to_free_buffers() call.  This may happen when the page is not
	 * dirty, not in writeback, not locked, and belongs to a mapping.
	 * Before changing the state of buffer heads to busy, the page lock
	 * must be held to protect them.
	 */
	ret = try_to_free_buffers(page);
	if (verbose && ret && mapping && mapping->host) {
		if (page_count(page) > 2 + !PageLRU(page))
			/*
			 * This may happen when the other task just happen to
			 * find and get the page during this invalidation.
			 */
			PAGE_DEBUG(page, "too many page count");
	}
	return ret;
}
void nilfs_page_debug(const char *fname, int line, struct page *page,
		      const char *m, ...)
{
	struct address_space *mapping;
	struct inode *inode;
	va_list args;
	int len;
	char b[MSIZ];

	/* The page should be locked */
	len = snprintf(b, MSIZ, "PAGE %p ", page);
	va_start(args, m);
	len += vsnprintf(b + len, MSIZ - len, m, args);
	va_end(args);

	if (page == NULL) {
		printk(KERN_DEBUG "%s: page=NULL %s at %d\n", b, fname, line);
		return;
	}
	mapping = page->mapping;
	len += snprintf(b + len, MSIZ - len,
			": cnt=%d index#=%llu mapping=%d lru=%d",
			atomic_read(&page->_count),
			(unsigned long long)page->index, !!mapping,
			!list_empty(&page->lru));
	len += snprintf(b + len, MSIZ - len, " %s(%d) flags=", fname, line);
	len += snprint_page_flags(b + len, MSIZ - len, page);
	if (mapping) {
		if (buffer_nilfs_node(page_buffers(page)))
			inode = NILFS_BTNC_I(mapping);
		else
			inode = NILFS_AS_I(mapping);
		if (inode != NULL)
			len += snprintf(b + len, MSIZ - len, " ino=%lu",
					inode->i_ino);
	}
	printk(KERN_DEBUG "%s\n", b);

	if (page_has_buffers(page)) {
		struct buffer_head *bh, *head;
		int i = 0;

		bh = head = page_buffers(page);
		if (!bh) {
			printk(KERN_DEBUG "PAGE %p: invalid page buffers\n",
			       page);
			return;
		}
		do {
			len = snprintf(b, MSIZ,
				       "  BH[%d] %p: cnt=%d blk#=%llu state=",
				       i, bh, atomic_read(&bh->b_count),
				       (unsigned long long)bh->b_blocknr);
			len += snprint_bh_state(b + len, MSIZ - len, bh);
			printk(KERN_DEBUG "%s\n", b);
			bh = bh->b_this_page;  i++;
			if (unlikely(!bh)) {
				printk(KERN_DEBUG
				       "PAGE %p: unexpected buffers end\n",
				       page);
				break;
			}
		} while (bh != head);
	}
}