struct buffer_head *nilfs_grab_buffer(struct inode *inode, struct address_space *mapping, unsigned long blkoff, unsigned long b_state) { int blkbits = inode->i_blkbits; pgoff_t index = blkoff >> (PAGE_CACHE_SHIFT - blkbits); struct page *page, *opage; struct buffer_head *bh, *obh; page = grab_cache_page(mapping, index); if (unlikely(!page)) return NULL; bh = __nilfs_get_page_block(page, blkoff, index, blkbits, b_state); if (unlikely(!bh)) { unlock_page(page); page_cache_release(page); return NULL; } if (!buffer_uptodate(bh) && mapping->assoc_mapping != NULL) { /* * Shadow page cache uses assoc_mapping to point its original * page cache. The following code tries the original cache * if the given cache is a shadow and it didn't hit. */ opage = find_lock_page(mapping->assoc_mapping, index); if (!opage) return bh; obh = __nilfs_get_page_block(opage, blkoff, index, blkbits, b_state); if (buffer_uptodate(obh)) { nilfs_copy_buffer(bh, obh); if (buffer_dirty(obh)) { nilfs_mark_buffer_dirty(bh); if (!buffer_nilfs_node(bh) && NILFS_MDT(inode)) nilfs_mdt_mark_dirty(inode); } } brelse(obh); unlock_page(opage); page_cache_release(opage); } return bh; }
struct buffer_head *nilfs_grab_buffer(struct inode *inode, struct address_space *mapping, unsigned long blkoff, unsigned long b_state) { int blkbits = inode->i_blkbits; pgoff_t index = blkoff >> (PAGE_SHIFT - blkbits); struct page *page; struct buffer_head *bh; page = grab_cache_page(mapping, index); if (unlikely(!page)) return NULL; bh = __nilfs_get_page_block(page, blkoff, index, blkbits, b_state); if (unlikely(!bh)) { unlock_page(page); put_page(page); return NULL; } return bh; }