Commit 81cb277e authored by Matthew Wilcox (Oracle)'s avatar Matthew Wilcox (Oracle) Committed by Andrew Morton
Browse files

gfs2: convert inode unstuffing to use a folio

Use the folio APIs, removing numerous hidden calls to compound_head(). 
Also remove the stale comment about the page being looked up if it's NULL.

Link: https://lkml.kernel.org/r/20231016201114.1928083-7-willy@infradead.org


Signed-off-by: default avatarMatthew Wilcox (Oracle) <willy@infradead.org>
Reviewed-by: default avatarAndreas Gruenbacher <agruenba@redhat.com>
Cc: Pankaj Raghav <p.raghav@samsung.com>
Cc: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 0217fbb0
Loading
Loading
Loading
Loading
+23 −25
Original line number Diff line number Diff line
@@ -43,53 +43,51 @@ struct metapath {
static int punch_hole(struct gfs2_inode *ip, u64 offset, u64 length);

/**
 * gfs2_unstuffer_page - unstuff a stuffed inode into a block cached by a page
 * gfs2_unstuffer_folio - unstuff a stuffed inode into a block cached by a folio
 * @ip: the inode
 * @dibh: the dinode buffer
 * @block: the block number that was allocated
 * @page: The (optional) page. This is looked up if @page is NULL
 * @folio: The folio.
 *
 * Returns: errno
 */

static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
			       u64 block, struct page *page)
static int gfs2_unstuffer_folio(struct gfs2_inode *ip, struct buffer_head *dibh,
			       u64 block, struct folio *folio)
{
	struct inode *inode = &ip->i_inode;

	if (!PageUptodate(page)) {
		void *kaddr = kmap(page);
	if (!folio_test_uptodate(folio)) {
		void *kaddr = kmap_local_folio(folio, 0);
		u64 dsize = i_size_read(inode);
 
		memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize);
		memset(kaddr + dsize, 0, PAGE_SIZE - dsize);
		kunmap(page);
		memset(kaddr + dsize, 0, folio_size(folio) - dsize);
		kunmap_local(kaddr);

		SetPageUptodate(page);
		folio_mark_uptodate(folio);
	}

	if (gfs2_is_jdata(ip)) {
		struct buffer_head *bh;
		struct buffer_head *bh = folio_buffers(folio);

		if (!page_has_buffers(page))
			create_empty_buffers(page, BIT(inode->i_blkbits),
					     BIT(BH_Uptodate));
		if (!bh)
			bh = folio_create_empty_buffers(folio,
				BIT(inode->i_blkbits), BIT(BH_Uptodate));

		bh = page_buffers(page);
		if (!buffer_mapped(bh))
			map_bh(bh, inode->i_sb, block);

		set_buffer_uptodate(bh);
		gfs2_trans_add_data(ip->i_gl, bh);
	} else {
		set_page_dirty(page);
		folio_mark_dirty(folio);
		gfs2_ordered_add_inode(ip);
	}

	return 0;
}

static int __gfs2_unstuff_inode(struct gfs2_inode *ip, struct page *page)
static int __gfs2_unstuff_inode(struct gfs2_inode *ip, struct folio *folio)
{
	struct buffer_head *bh, *dibh;
	struct gfs2_dinode *di;
@@ -118,7 +116,7 @@ static int __gfs2_unstuff_inode(struct gfs2_inode *ip, struct page *page)
					      dibh, sizeof(struct gfs2_dinode));
			brelse(bh);
		} else {
			error = gfs2_unstuffer_page(ip, dibh, block, page);
			error = gfs2_unstuffer_folio(ip, dibh, block, folio);
			if (error)
				goto out_brelse;
		}
@@ -157,17 +155,17 @@ static int __gfs2_unstuff_inode(struct gfs2_inode *ip, struct page *page)
int gfs2_unstuff_dinode(struct gfs2_inode *ip)
{
	struct inode *inode = &ip->i_inode;
	struct page *page;
	struct folio *folio;
	int error;

	down_write(&ip->i_rw_mutex);
	page = grab_cache_page(inode->i_mapping, 0);
	error = -ENOMEM;
	if (!page)
	folio = filemap_grab_folio(inode->i_mapping, 0);
	error = PTR_ERR(folio);
	if (IS_ERR(folio))
		goto out;
	error = __gfs2_unstuff_inode(ip, page);
	unlock_page(page);
	put_page(page);
	error = __gfs2_unstuff_inode(ip, folio);
	folio_unlock(folio);
	folio_put(folio);
out:
	up_write(&ip->i_rw_mutex);
	return error;