From 8b2e77c1634935aefc9a4e2aacadda9cd30b78d7 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 11 Jul 2018 22:25:56 -0700 Subject: xfs: use iomap for blocksize == PAGE_SIZE readpage and readpages For file systems with a block size that equals the page size we never do partial reads, so we can use the buffer_head-less iomap versions of readpage and readpages without conflicting with the buffer_head structures create later in write_begin. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 8eb3ba3d4d00..85e1a625d42a 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1401,6 +1401,8 @@ xfs_vm_readpage( struct page *page) { trace_xfs_vm_readpage(page->mapping->host, 1); + if (i_blocksize(page->mapping->host) == PAGE_SIZE) + return iomap_readpage(page, &xfs_iomap_ops); return mpage_readpage(page, xfs_get_blocks); } @@ -1412,6 +1414,8 @@ xfs_vm_readpages( unsigned nr_pages) { trace_xfs_vm_readpages(mapping->host, nr_pages); + if (i_blocksize(mapping->host) == PAGE_SIZE) + return iomap_readpages(mapping, pages, nr_pages, &xfs_iomap_ops); return mpage_readpages(mapping, pages, nr_pages, xfs_get_blocks); } -- cgit v1.2.3 From 036257213836e13f08d1b28e528ba99e4ed3fc68 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 11 Jul 2018 22:25:57 -0700 Subject: xfs: simplify xfs_aops_discard_page Instead of looking at the buffer heads to see if a block is delalloc just call xfs_bmap_punch_delalloc_range on the whole page - this will leave any non-delalloc block intact and handle the iteration for us. As a side effect one more place stops caring about buffer heads and we can remove the xfs_check_page_type function entirely. Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 85 ++++++------------------------------------------------- 1 file changed, 9 insertions(+), 76 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 85e1a625d42a..9b1a17b4cacb 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -710,49 +710,6 @@ xfs_map_at_offset( clear_buffer_unwritten(bh); } -/* - * Test if a given page contains at least one buffer of a given @type. - * If @check_all_buffers is true, then we walk all the buffers in the page to - * try to find one of the type passed in. If it is not set, then the caller only - * needs to check the first buffer on the page for a match. - */ -STATIC bool -xfs_check_page_type( - struct page *page, - unsigned int type, - bool check_all_buffers) -{ - struct buffer_head *bh; - struct buffer_head *head; - - if (PageWriteback(page)) - return false; - if (!page->mapping) - return false; - if (!page_has_buffers(page)) - return false; - - bh = head = page_buffers(page); - do { - if (buffer_unwritten(bh)) { - if (type == XFS_IO_UNWRITTEN) - return true; - } else if (buffer_delay(bh)) { - if (type == XFS_IO_DELALLOC) - return true; - } else if (buffer_dirty(bh) && buffer_mapped(bh)) { - if (type == XFS_IO_OVERWRITE) - return true; - } - - /* If we are only checking the first buffer, we are done now. */ - if (!check_all_buffers) - break; - } while ((bh = bh->b_this_page) != head); - - return false; -} - STATIC void xfs_vm_invalidatepage( struct page *page, @@ -784,9 +741,6 @@ xfs_vm_invalidatepage( * transaction. Indeed - if we get ENOSPC errors, we have to be able to do this * truncation without a transaction as there is no space left for block * reservation (typically why we see a ENOSPC in writeback). - * - * This is not a performance critical path, so for now just do the punching a - * buffer head at a time. */ STATIC void xfs_aops_discard_page( @@ -794,47 +748,26 @@ xfs_aops_discard_page( { struct inode *inode = page->mapping->host; struct xfs_inode *ip = XFS_I(inode); - struct buffer_head *bh, *head; + struct xfs_mount *mp = ip->i_mount; loff_t offset = page_offset(page); + xfs_fileoff_t start_fsb = XFS_B_TO_FSBT(mp, offset); + int error; - if (!xfs_check_page_type(page, XFS_IO_DELALLOC, true)) - goto out_invalidate; - - if (XFS_FORCED_SHUTDOWN(ip->i_mount)) + if (XFS_FORCED_SHUTDOWN(mp)) goto out_invalidate; - xfs_alert(ip->i_mount, + xfs_alert(mp, "page discard on page "PTR_FMT", inode 0x%llx, offset %llu.", page, ip->i_ino, offset); xfs_ilock(ip, XFS_ILOCK_EXCL); - bh = head = page_buffers(page); - do { - int error; - xfs_fileoff_t start_fsb; - - if (!buffer_delay(bh)) - goto next_buffer; - - start_fsb = XFS_B_TO_FSBT(ip->i_mount, offset); - error = xfs_bmap_punch_delalloc_range(ip, start_fsb, 1); - if (error) { - /* something screwed, just bail */ - if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) { - xfs_alert(ip->i_mount, - "page discard unable to remove delalloc mapping."); - } - break; - } -next_buffer: - offset += i_blocksize(inode); - - } while ((bh = bh->b_this_page) != head); - + error = xfs_bmap_punch_delalloc_range(ip, start_fsb, + PAGE_SIZE / i_blocksize(inode)); xfs_iunlock(ip, XFS_ILOCK_EXCL); + if (error && !XFS_FORCED_SHUTDOWN(mp)) + xfs_alert(mp, "page discard unable to remove delalloc mapping."); out_invalidate: xfs_vm_invalidatepage(page, 0, PAGE_SIZE); - return; } static int -- cgit v1.2.3 From d43801775766972535a0f4b78af65d0c13055e36 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 11 Jul 2018 22:25:57 -0700 Subject: xfs: move locking into xfs_bmap_punch_delalloc_range Both callers want the same looking, so do it only once. Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 2 -- fs/xfs/xfs_bmap_util.c | 9 +++++---- fs/xfs/xfs_iomap.c | 3 --- 3 files changed, 5 insertions(+), 9 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 9b1a17b4cacb..5c549e983d69 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -760,10 +760,8 @@ xfs_aops_discard_page( "page discard on page "PTR_FMT", inode 0x%llx, offset %llu.", page, ip->i_ino, offset); - xfs_ilock(ip, XFS_ILOCK_EXCL); error = xfs_bmap_punch_delalloc_range(ip, start_fsb, PAGE_SIZE / i_blocksize(inode)); - xfs_iunlock(ip, XFS_ILOCK_EXCL); if (error && !XFS_FORCED_SHUTDOWN(mp)) xfs_alert(mp, "page discard unable to remove delalloc mapping."); out_invalidate: diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 83b1e8c6c18f..da561882c349 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -702,16 +702,15 @@ xfs_bmap_punch_delalloc_range( struct xfs_iext_cursor icur; int error = 0; - ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); - + xfs_ilock(ip, XFS_ILOCK_EXCL); if (!(ifp->if_flags & XFS_IFEXTENTS)) { error = xfs_iread_extents(NULL, ip, XFS_DATA_FORK); if (error) - return error; + goto out_unlock; } if (!xfs_iext_lookup_extent_before(ip, ifp, &end_fsb, &icur, &got)) - return 0; + goto out_unlock; while (got.br_startoff + got.br_blockcount > start_fsb) { del = got; @@ -735,6 +734,8 @@ xfs_bmap_punch_delalloc_range( break; } +out_unlock: + xfs_iunlock(ip, XFS_ILOCK_EXCL); return error; } diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index e08a84d9ee72..10c54fc7d1b4 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -1204,11 +1204,8 @@ xfs_file_iomap_end_delalloc( truncate_pagecache_range(VFS_I(ip), XFS_FSB_TO_B(mp, start_fsb), XFS_FSB_TO_B(mp, end_fsb) - 1); - xfs_ilock(ip, XFS_ILOCK_EXCL); error = xfs_bmap_punch_delalloc_range(ip, start_fsb, end_fsb - start_fsb); - xfs_iunlock(ip, XFS_ILOCK_EXCL); - if (error && !XFS_FORCED_SHUTDOWN(mp)) { xfs_alert(mp, "%s: unable to clean up ino %lld", __func__, ip->i_ino); -- cgit v1.2.3 From 91cdfd1761659f338e673aca72af3d0d50b88847 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 11 Jul 2018 22:25:58 -0700 Subject: xfs: do not set the page uptodate in xfs_writepage_map We already track the page uptodate status based on the buffer uptodate status, which is updated whenever reading or zeroing blocks. This code has been there since commit a ptool commit in 2002, which claims to: "merge" the 2.4 fsx fix for block size < page size to 2.5. This needed major changes to actually fit. and isn't present in other writepage implementations. Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 5c549e983d69..df80a383ccd8 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -849,7 +849,6 @@ xfs_writepage_map( uint64_t offset; int error = 0; int count = 0; - int uptodate = 1; unsigned int new_type; bh = head = page_buffers(page); @@ -857,8 +856,6 @@ xfs_writepage_map( do { if (offset >= end_offset) break; - if (!buffer_uptodate(bh)) - uptodate = 0; /* * set_page_dirty dirties all buffers in a page, independent @@ -922,9 +919,6 @@ xfs_writepage_map( } while (offset += len, ((bh = bh->b_this_page) != head)); - if (uptodate && bh == head) - SetPageUptodate(page); - ASSERT(wpc->ioend || list_empty(&submit_list)); out: -- cgit v1.2.3 From c57371a16d074bb4eafe6b73f29360085ecb2064 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 11 Jul 2018 22:25:58 -0700 Subject: xfs: don't clear imap_valid for a non-uptodate buffers Finding a buffer that isn't uptodate doesn't invalidate the mapping for any given block. The last_sector check will already take care of starting another ioend as soon as we find any non-update buffer, and if the current mapping doesn't include the next uptodate buffer the xfs_imap_valid check will take care of it. Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index df80a383ccd8..1d1cb917cc6e 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -863,10 +863,8 @@ xfs_writepage_map( * meaningless for holes (!mapped && uptodate), so skip * buffers covering holes here. */ - if (!buffer_mapped(bh) && buffer_uptodate(bh)) { - wpc->imap_valid = false; + if (!buffer_mapped(bh) && buffer_uptodate(bh)) continue; - } if (buffer_unwritten(bh)) new_type = XFS_IO_UNWRITTEN; @@ -879,11 +877,8 @@ xfs_writepage_map( ASSERT(buffer_mapped(bh)); /* * This buffer is not uptodate and will not be - * written to disk. Ensure that we will put any - * subsequent writeable buffers into a new - * ioend. + * written to disk. */ - wpc->imap_valid = false; continue; } -- cgit v1.2.3 From a7b28f72ab90fe7a2f438360df5f6fda4237afdc Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 11 Jul 2018 22:25:59 -0700 Subject: xfs: don't use XFS_BMAPI_IGSTATE in xfs_map_blocks We want to be able to use the extent state as a reliably indicator for the type of I/O, and stop using the buffer head state. For this we need to stop using the XFS_BMAPI_IGSTATE so that we don't see merged extents of different types. Based on a patch from Dave Chinner. Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 1d1cb917cc6e..6b6150683343 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -373,7 +373,6 @@ xfs_map_blocks( ssize_t count = i_blocksize(inode); xfs_fileoff_t offset_fsb, end_fsb; int error = 0; - int bmapi_flags = XFS_BMAPI_ENTIRE; int nimaps = 1; if (XFS_FORCED_SHUTDOWN(mp)) @@ -393,8 +392,6 @@ xfs_map_blocks( return 0; ASSERT(type != XFS_IO_COW); - if (type == XFS_IO_UNWRITTEN) - bmapi_flags |= XFS_BMAPI_IGSTATE; xfs_ilock(ip, XFS_ILOCK_SHARED); ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || @@ -406,7 +403,7 @@ xfs_map_blocks( end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); offset_fsb = XFS_B_TO_FSBT(mp, offset); error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, - imap, &nimaps, bmapi_flags); + imap, &nimaps, XFS_BMAPI_ENTIRE); /* * Truncate an overwrite extent if there's a pending CoW * reservation before the end of this extent. This forces us -- cgit v1.2.3 From fca8c805425c0d9435097a6c780e95332e54613a Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 11 Jul 2018 22:25:59 -0700 Subject: xfs: remove xfs_reflink_trim_irec_to_next_cow We already have to check for overlapping COW extents everytime we come back to a page in xfs_writepage_map / xfs_map_cow, so this additional trim is not required. Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 7 ------- fs/xfs/xfs_reflink.c | 33 --------------------------------- fs/xfs/xfs_reflink.h | 2 -- fs/xfs/xfs_trace.h | 1 - 4 files changed, 43 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 6b6150683343..08605432c497 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -404,13 +404,6 @@ xfs_map_blocks( offset_fsb = XFS_B_TO_FSBT(mp, offset); error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, imap, &nimaps, XFS_BMAPI_ENTIRE); - /* - * Truncate an overwrite extent if there's a pending CoW - * reservation before the end of this extent. This forces us - * to come back to writepage to take care of the CoW. - */ - if (nimaps && type == XFS_IO_OVERWRITE) - xfs_reflink_trim_irec_to_next_cow(ip, offset_fsb, imap); xfs_iunlock(ip, XFS_ILOCK_SHARED); if (error) diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 592fb2071a03..22c11b98ab26 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -500,39 +500,6 @@ xfs_reflink_find_cow_mapping( return true; } -/* - * Trim an extent to end at the next CoW reservation past offset_fsb. - */ -void -xfs_reflink_trim_irec_to_next_cow( - struct xfs_inode *ip, - xfs_fileoff_t offset_fsb, - struct xfs_bmbt_irec *imap) -{ - struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK); - struct xfs_bmbt_irec got; - struct xfs_iext_cursor icur; - - if (!xfs_is_reflink_inode(ip)) - return; - - /* Find the extent in the CoW fork. */ - if (!xfs_iext_lookup_extent(ip, ifp, offset_fsb, &icur, &got)) - return; - - /* This is the extent before; try sliding up one. */ - if (got.br_startoff < offset_fsb) { - if (!xfs_iext_next_extent(ifp, &icur, &got)) - return; - } - - if (got.br_startoff >= imap->br_startoff + imap->br_blockcount) - return; - - imap->br_blockcount = got.br_startoff - imap->br_startoff; - trace_xfs_reflink_trim_irec(ip, imap); -} - /* * Cancel CoW reservations for some block range of an inode. * diff --git a/fs/xfs/xfs_reflink.h b/fs/xfs/xfs_reflink.h index 1532827ba911..6f9f98894abc 100644 --- a/fs/xfs/xfs_reflink.h +++ b/fs/xfs/xfs_reflink.h @@ -20,8 +20,6 @@ extern int xfs_reflink_convert_cow(struct xfs_inode *ip, xfs_off_t offset, xfs_off_t count); extern bool xfs_reflink_find_cow_mapping(struct xfs_inode *ip, xfs_off_t offset, struct xfs_bmbt_irec *imap); -extern void xfs_reflink_trim_irec_to_next_cow(struct xfs_inode *ip, - xfs_fileoff_t offset_fsb, struct xfs_bmbt_irec *imap); extern int xfs_reflink_cancel_cow_blocks(struct xfs_inode *ip, struct xfs_trans **tpp, xfs_fileoff_t offset_fsb, diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 972d45d28097..a5b01529ecf6 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -3216,7 +3216,6 @@ DEFINE_RW_EVENT(xfs_reflink_reserve_cow); DEFINE_SIMPLE_IO_EVENT(xfs_reflink_bounce_dio_write); DEFINE_IOMAP_EVENT(xfs_reflink_find_cow_mapping); -DEFINE_INODE_IREC_EVENT(xfs_reflink_trim_irec); DEFINE_SIMPLE_IO_EVENT(xfs_reflink_cancel_cow_range); DEFINE_SIMPLE_IO_EVENT(xfs_reflink_end_cow); -- cgit v1.2.3 From 5c665e5b5af6b8ad3e38ee73cb495ec695bcf589 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 11 Jul 2018 22:25:59 -0700 Subject: xfs: remove xfs_map_cow We can handle the existing cow mapping case as a special case directly in xfs_writepage_map, and share code for allocating delalloc blocks with regular I/O in xfs_map_blocks. This means we need to always call xfs_map_blocks for reflink inodes, but we can still skip most of the work if it turns out that there is no COW mapping overlapping the current block. As a subtle detail we need to start caching holes in the wpc to deal with the case of COW reservations between EOF. But we'll need that infrastructure later anyway, so this is no big deal. Based on a patch from Dave Chinner. Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 195 +++++++++++++++++++++++++++--------------------------- fs/xfs/xfs_aops.h | 4 +- 2 files changed, 100 insertions(+), 99 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 08605432c497..65454a4f4d93 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -363,70 +363,107 @@ xfs_end_bio( STATIC int xfs_map_blocks( + struct xfs_writepage_ctx *wpc, struct inode *inode, - loff_t offset, - struct xfs_bmbt_irec *imap, - int type) + loff_t offset) { struct xfs_inode *ip = XFS_I(inode); struct xfs_mount *mp = ip->i_mount; ssize_t count = i_blocksize(inode); - xfs_fileoff_t offset_fsb, end_fsb; + xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset), end_fsb; + struct xfs_bmbt_irec imap; + int whichfork = XFS_DATA_FORK; int error = 0; int nimaps = 1; if (XFS_FORCED_SHUTDOWN(mp)) return -EIO; - /* - * Truncate can race with writeback since writeback doesn't take the - * iolock and truncate decreases the file size before it starts - * truncating the pages between new_size and old_size. Therefore, we - * can end up in the situation where writeback gets a CoW fork mapping - * but the truncate makes the mapping invalid and we end up in here - * trying to get a new mapping. Bail out here so that we simply never - * get a valid mapping and so we drop the write altogether. The page - * truncation will kill the contents anyway. - */ - if (type == XFS_IO_COW && offset > i_size_read(inode)) - return 0; - - ASSERT(type != XFS_IO_COW); - xfs_ilock(ip, XFS_ILOCK_SHARED); ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || (ip->i_df.if_flags & XFS_IFEXTENTS)); ASSERT(offset <= mp->m_super->s_maxbytes); + if (xfs_is_reflink_inode(ip) && + xfs_reflink_find_cow_mapping(ip, offset, &imap)) { + xfs_iunlock(ip, XFS_ILOCK_SHARED); + /* + * Truncate can race with writeback since writeback doesn't + * take the iolock and truncate decreases the file size before + * it starts truncating the pages between new_size and old_size. + * Therefore, we can end up in the situation where writeback + * gets a CoW fork mapping but the truncate makes the mapping + * invalid and we end up in here trying to get a new mapping. + * bail out here so that we simply never get a valid mapping + * and so we drop the write altogether. The page truncation + * will kill the contents anyway. + */ + if (offset > i_size_read(inode)) { + wpc->io_type = XFS_IO_HOLE; + return 0; + } + whichfork = XFS_COW_FORK; + wpc->io_type = XFS_IO_COW; + goto allocate_blocks; + } + + /* + * Map valid and no COW extent in the way? We're done. + */ + if (wpc->imap_valid) { + xfs_iunlock(ip, XFS_ILOCK_SHARED); + return 0; + } + + /* + * If we don't have a valid map, now it's time to get a new one for this + * offset. This will convert delayed allocations (including COW ones) + * into real extents. + */ if (offset > mp->m_super->s_maxbytes - count) count = mp->m_super->s_maxbytes - offset; end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); offset_fsb = XFS_B_TO_FSBT(mp, offset); error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, - imap, &nimaps, XFS_BMAPI_ENTIRE); + &imap, &nimaps, XFS_BMAPI_ENTIRE); xfs_iunlock(ip, XFS_ILOCK_SHARED); - if (error) return error; - if (type == XFS_IO_DELALLOC && - (!nimaps || isnullstartblock(imap->br_startblock))) { - error = xfs_iomap_write_allocate(ip, XFS_DATA_FORK, offset, - imap); - if (!error) - trace_xfs_map_blocks_alloc(ip, offset, count, type, imap); - return error; + if (!nimaps) { + /* + * Lookup returns no match? Beyond eof? regardless, + * return it as a hole so we don't write it + */ + imap.br_startoff = offset_fsb; + imap.br_blockcount = end_fsb - offset_fsb; + imap.br_startblock = HOLESTARTBLOCK; + wpc->io_type = XFS_IO_HOLE; + } else if (imap.br_startblock == HOLESTARTBLOCK) { + /* landed in a hole */ + wpc->io_type = XFS_IO_HOLE; } + if (wpc->io_type == XFS_IO_DELALLOC && + (!nimaps || isnullstartblock(imap.br_startblock))) + goto allocate_blocks; + #ifdef DEBUG - if (type == XFS_IO_UNWRITTEN) { + if (wpc->io_type == XFS_IO_UNWRITTEN) { ASSERT(nimaps); - ASSERT(imap->br_startblock != HOLESTARTBLOCK); - ASSERT(imap->br_startblock != DELAYSTARTBLOCK); + ASSERT(imap.br_startblock != HOLESTARTBLOCK); + ASSERT(imap.br_startblock != DELAYSTARTBLOCK); } #endif - if (nimaps) - trace_xfs_map_blocks_found(ip, offset, count, type, imap); + wpc->imap = imap; + trace_xfs_map_blocks_found(ip, offset, count, wpc->io_type, &imap); + return 0; +allocate_blocks: + error = xfs_iomap_write_allocate(ip, whichfork, offset, &imap); + if (error) + return error; + wpc->imap = imap; + trace_xfs_map_blocks_alloc(ip, offset, count, wpc->io_type, &imap); return 0; } @@ -758,56 +795,6 @@ out_invalidate: xfs_vm_invalidatepage(page, 0, PAGE_SIZE); } -static int -xfs_map_cow( - struct xfs_writepage_ctx *wpc, - struct inode *inode, - loff_t offset, - unsigned int *new_type) -{ - struct xfs_inode *ip = XFS_I(inode); - struct xfs_bmbt_irec imap; - bool is_cow = false; - int error; - - /* - * If we already have a valid COW mapping keep using it. - */ - if (wpc->io_type == XFS_IO_COW) { - wpc->imap_valid = xfs_imap_valid(inode, &wpc->imap, offset); - if (wpc->imap_valid) { - *new_type = XFS_IO_COW; - return 0; - } - } - - /* - * Else we need to check if there is a COW mapping at this offset. - */ - xfs_ilock(ip, XFS_ILOCK_SHARED); - is_cow = xfs_reflink_find_cow_mapping(ip, offset, &imap); - xfs_iunlock(ip, XFS_ILOCK_SHARED); - - if (!is_cow) - return 0; - - /* - * And if the COW mapping has a delayed extent here we need to - * allocate real space for it now. - */ - if (isnullstartblock(imap.br_startblock)) { - error = xfs_iomap_write_allocate(ip, XFS_COW_FORK, offset, - &imap); - if (error) - return error; - } - - wpc->io_type = *new_type = XFS_IO_COW; - wpc->imap_valid = true; - wpc->imap = imap; - return 0; -} - /* * We implement an immediate ioend submission policy here to avoid needing to * chain multiple ioends and hence nest mempool allocations which can violate @@ -836,7 +823,7 @@ xfs_writepage_map( struct xfs_ioend *ioend, *next; struct buffer_head *bh, *head; ssize_t len = i_blocksize(inode); - uint64_t offset; + uint64_t offset; /* file offset of page */ int error = 0; int count = 0; unsigned int new_type; @@ -872,10 +859,13 @@ xfs_writepage_map( continue; } - if (xfs_is_reflink_inode(XFS_I(inode))) { - error = xfs_map_cow(wpc, inode, offset, &new_type); - if (error) - goto out; + /* + * If we already have a valid COW mapping keep using it. + */ + if (wpc->io_type == XFS_IO_COW && + xfs_imap_valid(inode, &wpc->imap, offset)) { + wpc->imap_valid = true; + new_type = XFS_IO_COW; } if (wpc->io_type != new_type) { @@ -886,22 +876,31 @@ xfs_writepage_map( if (wpc->imap_valid) wpc->imap_valid = xfs_imap_valid(inode, &wpc->imap, offset); - if (!wpc->imap_valid) { - error = xfs_map_blocks(inode, offset, &wpc->imap, - wpc->io_type); + + /* + * COW fork blocks can overlap data fork blocks even if the + * blocks aren't shared. COW I/O always takes precedent, so we + * must always check for overlap on reflink inodes unless the + * mapping is already a COW one. + */ + if (!wpc->imap_valid || + (xfs_is_reflink_inode(XFS_I(inode)) && + wpc->io_type != XFS_IO_COW)) { + error = xfs_map_blocks(wpc, inode, offset); if (error) goto out; wpc->imap_valid = xfs_imap_valid(inode, &wpc->imap, offset); } - if (wpc->imap_valid) { - lock_buffer(bh); - if (wpc->io_type != XFS_IO_OVERWRITE) - xfs_map_at_offset(inode, bh, &wpc->imap, offset); - xfs_add_to_ioend(inode, bh, offset, wpc, wbc, &submit_list); - count++; - } + if (!wpc->imap_valid || wpc->io_type == XFS_IO_HOLE) + continue; + + lock_buffer(bh); + if (wpc->io_type != XFS_IO_OVERWRITE) + xfs_map_at_offset(inode, bh, &wpc->imap, offset); + xfs_add_to_ioend(inode, bh, offset, wpc, wbc, &submit_list); + count++; } while (offset += len, ((bh = bh->b_this_page) != head)); ASSERT(wpc->ioend || list_empty(&submit_list)); diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h index 25bc6d4a1231..9af867951a10 100644 --- a/fs/xfs/xfs_aops.h +++ b/fs/xfs/xfs_aops.h @@ -17,6 +17,7 @@ enum { XFS_IO_UNWRITTEN, /* covers allocated but uninitialized data */ XFS_IO_OVERWRITE, /* covers already allocated extent */ XFS_IO_COW, /* covers copy-on-write extent */ + XFS_IO_HOLE, /* covers region without any block allocation */ }; #define XFS_IO_TYPES \ @@ -24,7 +25,8 @@ enum { { XFS_IO_DELALLOC, "delalloc" }, \ { XFS_IO_UNWRITTEN, "unwritten" }, \ { XFS_IO_OVERWRITE, "overwrite" }, \ - { XFS_IO_COW, "CoW" } + { XFS_IO_COW, "CoW" }, \ + { XFS_IO_HOLE, "hole" } /* * Structure for buffered I/O completions. -- cgit v1.2.3 From 6a4c95013608120b2d88be67c6871cb6b86aa5d6 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 11 Jul 2018 22:26:00 -0700 Subject: xfs: rename the offset variable in xfs_writepage_map Calling it file_offset makes the usage more clear, especially with a new poffset variable that will be added soon for the offset inside the page. Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 65454a4f4d93..4dc5fcff226e 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -823,15 +823,15 @@ xfs_writepage_map( struct xfs_ioend *ioend, *next; struct buffer_head *bh, *head; ssize_t len = i_blocksize(inode); - uint64_t offset; /* file offset of page */ + uint64_t file_offset; /* file offset of page */ int error = 0; int count = 0; unsigned int new_type; bh = head = page_buffers(page); - offset = page_offset(page); + file_offset = page_offset(page); do { - if (offset >= end_offset) + if (file_offset >= end_offset) break; /* @@ -863,7 +863,7 @@ xfs_writepage_map( * If we already have a valid COW mapping keep using it. */ if (wpc->io_type == XFS_IO_COW && - xfs_imap_valid(inode, &wpc->imap, offset)) { + xfs_imap_valid(inode, &wpc->imap, file_offset)) { wpc->imap_valid = true; new_type = XFS_IO_COW; } @@ -875,7 +875,7 @@ xfs_writepage_map( if (wpc->imap_valid) wpc->imap_valid = xfs_imap_valid(inode, &wpc->imap, - offset); + file_offset); /* * COW fork blocks can overlap data fork blocks even if the @@ -886,11 +886,11 @@ xfs_writepage_map( if (!wpc->imap_valid || (xfs_is_reflink_inode(XFS_I(inode)) && wpc->io_type != XFS_IO_COW)) { - error = xfs_map_blocks(wpc, inode, offset); + error = xfs_map_blocks(wpc, inode, file_offset); if (error) goto out; wpc->imap_valid = xfs_imap_valid(inode, &wpc->imap, - offset); + file_offset); } if (!wpc->imap_valid || wpc->io_type == XFS_IO_HOLE) @@ -898,10 +898,10 @@ xfs_writepage_map( lock_buffer(bh); if (wpc->io_type != XFS_IO_OVERWRITE) - xfs_map_at_offset(inode, bh, &wpc->imap, offset); - xfs_add_to_ioend(inode, bh, offset, wpc, wbc, &submit_list); + xfs_map_at_offset(inode, bh, &wpc->imap, file_offset); + xfs_add_to_ioend(inode, bh, file_offset, wpc, wbc, &submit_list); count++; - } while (offset += len, ((bh = bh->b_this_page) != head)); + } while (file_offset += len, ((bh = bh->b_this_page) != head)); ASSERT(wpc->ioend || list_empty(&submit_list)); -- cgit v1.2.3 From e2f6ad4624dfbde3a6c42c0cfbfc5553d93c3cae Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Wed, 11 Jul 2018 22:26:00 -0700 Subject: xfs: make xfs_writepage_map extent map centric xfs_writepage_map() iterates over the bufferheads on a page to decide what sort of IO to do and what actions to take. However, when it comes to reflink and deciding when it needs to execute a COW operation, we no longer look at the bufferhead state but instead we ignore than and look up internal state held in the COW fork extent list. This means xfs_writepage_map() is somewhat confused. It does stuff, then ignores it, then tries to handle the impedence mismatch by shovelling the results inside the existing mapping code. It works, but it's a bit of a mess and it makes it hard to fix the cached map bug that the writepage code currently has. To unify the two different mechanisms, we first have to choose a direction. That's already been set - we're de-emphasising bufferheads so they are no longer a control structure as we need to do taht to allow for eventual removal. Hence we need to move away from looking at bufferhead state to determine what operations we need to perform. We can't completely get rid of bufferheads yet - they do contain some state that is absolutely necessary, such as whether that part of the page contains valid data or not (buffer_uptodate()). Other state in the bufferhead is redundant: BH_dirty - the page is dirty, so we can ignore this and just write it BH_delay - we have delalloc extent info in the DATA fork extent tree BH_unwritten - same as BH_delay BH_mapped - indicates we've already used it once for IO and it is mapped to a disk address. Needs to be ignored for COW blocks. The BH_mapped flag is an interesting case - it's supposed to indicate that it's already mapped to disk and so we can just use it "as is". In theory, we don't even have to do an extent lookup to find where to write it too, but we have to do that anyway to determine we are actually writing over a valid extent. Hence it's not even serving the purpose of avoiding a an extent lookup during writeback, and so we can pretty much ignore it. Especially as we have to ignore it for COW operations... Therefore, use the extent map as the source of information to tell us what actions we need to take and what sort of IO we should perform. The first step is to have xfs_map_blocks() set the io type according to what it looks up. This means it can easily handle both normal overwrite and COW cases. The only thing we also need to add is the ability to return hole mappings. We need to return and cache hole mappings now for the case of multiple blocks per page. We no longer use the BH_mapped to indicate a block over a hole, so we have to get that info from xfs_map_blocks(). We cache it so that holes that span two pages don't need separate lookups. This allows us to avoid ever doing write IO over a hole, too. Now that we have xfs_map_blocks() returning both a cached map and the type of IO we need to perform, we can rewrite xfs_writepage_map() to drop all the bufferhead control. It's also much simplified because it doesn't need to explicitly handle COW operations. Instead of iterating bufferheads, it iterates blocks within the page and then looks up what per-block state is required from the appropriate bufferhead. It then validates the cached map, and if it's not valid, we get a new map. If we don't get a valid map or it's over a hole, we skip the block. At this point, we have to remap the bufferhead via xfs_map_at_offset(). As previously noted, we had to do this even if the buffer was already mapped as the mapping would be stale for XFS_IO_DELALLOC, XFS_IO_UNWRITTEN and XFS_IO_COW IO types. With xfs_map_blocks() now controlling the type, even XFS_IO_OVERWRITE types need remapping, as converted-but-not-yet- written delalloc extents beyond EOF can be reported at XFS_IO_OVERWRITE. Bufferheads that span such regions still need their BH_Delay flags cleared and their block numbers calculated, so we now unconditionally map each bufferhead before submission. But wait! There's more - remember the old "treat unwritten extents as holes on read" hack? Yeah, that means we can have a dirty page with unmapped, unwritten bufferheads that contain data! What makes these so special is that the unwritten "hole" bufferheads do not have a valid block device pointer, so if we attempt to write them xfs_add_to_ioend() blows up. So we make xfs_map_at_offset() do the "realtime or data device" lookup from the inode and ignore what was or wasn't put into the bufferhead when the buffer was instantiated. The astute reader will have realised by now that this code treats unwritten extents in multiple-blocks-per-page situations differently. If we get any combination of unwritten blocks on a dirty page that contain valid data in the page, we're going to convert them to real extents. This can actually be a win, because it means that pages with interleaving unwritten and written blocks will get converted to a single written extent with zeros replacing the interspersed unwritten blocks. This is actually good for reducing extent list and conversion overhead, and it means we issue a contiguous IO instead of lots of little ones. The downside is that we use up a little extra IO bandwidth. Neither of these seem like a bad thing given that spinning disks are seek sensitive, and SSDs/pmem have bandwidth to burn and the lower Io latency/CPU overhead of fewer, larger IOs will result in better performance on them... As a result of all this, the only state we actually care about from the bufferhead is a single flag - BH_Uptodate. We still use the bufferhead to pass some information to the bio via xfs_add_to_ioend(), but that is trivial to separate and pass explicitly. This means we really only need 1 bit of state per block per page from the buffered write path in the writeback path. Everything else we do with the bufferhead is purely to make the buffered IO front end continue to work correctly. i.e we've pretty much marginalised bufferheads in the writeback path completely. Signed-off-By: Dave Chinner [hch: forward port, refactor and split off bits into other commits] Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 88 +++++++++++++++++++++++-------------------------------- 1 file changed, 36 insertions(+), 52 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 4dc5fcff226e..815b0b29438b 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -442,19 +442,19 @@ xfs_map_blocks( } else if (imap.br_startblock == HOLESTARTBLOCK) { /* landed in a hole */ wpc->io_type = XFS_IO_HOLE; - } - - if (wpc->io_type == XFS_IO_DELALLOC && - (!nimaps || isnullstartblock(imap.br_startblock))) - goto allocate_blocks; + } else { + if (isnullstartblock(imap.br_startblock)) { + /* got a delalloc extent */ + wpc->io_type = XFS_IO_DELALLOC; + goto allocate_blocks; + } -#ifdef DEBUG - if (wpc->io_type == XFS_IO_UNWRITTEN) { - ASSERT(nimaps); - ASSERT(imap.br_startblock != HOLESTARTBLOCK); - ASSERT(imap.br_startblock != DELAYSTARTBLOCK); + if (imap.br_state == XFS_EXT_UNWRITTEN) + wpc->io_type = XFS_IO_UNWRITTEN; + else + wpc->io_type = XFS_IO_OVERWRITE; } -#endif + wpc->imap = imap; trace_xfs_map_blocks_found(ip, offset, count, wpc->io_type, &imap); return 0; @@ -735,6 +735,14 @@ xfs_map_at_offset( set_buffer_mapped(bh); clear_buffer_delay(bh); clear_buffer_unwritten(bh); + + /* + * If this is a realtime file, data may be on a different device. + * to that pointed to from the buffer_head b_bdev currently. We can't + * trust that the bufferhead has a already been mapped correctly, so + * set the bdev now. + */ + bh->b_bdev = xfs_find_bdev_for_inode(inode); } STATIC void @@ -821,58 +829,35 @@ xfs_writepage_map( { LIST_HEAD(submit_list); struct xfs_ioend *ioend, *next; - struct buffer_head *bh, *head; + struct buffer_head *bh; ssize_t len = i_blocksize(inode); uint64_t file_offset; /* file offset of page */ + unsigned poffset; /* offset into page */ int error = 0; int count = 0; - unsigned int new_type; - bh = head = page_buffers(page); + /* + * Walk the blocks on the page, and if we run off the end of the current + * map or find the current map invalid, grab a new one. We only use + * bufferheads here to check per-block state - they no longer control + * the iteration through the page. This allows us to replace the + * bufferhead with some other state tracking mechanism in future. + */ file_offset = page_offset(page); - do { + bh = page_buffers(page); + for (poffset = 0; + poffset < PAGE_SIZE; + poffset += len, file_offset += len, bh = bh->b_this_page) { + /* past the range we are writing, so nothing more to write. */ if (file_offset >= end_offset) break; - /* - * set_page_dirty dirties all buffers in a page, independent - * of their state. The dirty state however is entirely - * meaningless for holes (!mapped && uptodate), so skip - * buffers covering holes here. - */ - if (!buffer_mapped(bh) && buffer_uptodate(bh)) - continue; - - if (buffer_unwritten(bh)) - new_type = XFS_IO_UNWRITTEN; - else if (buffer_delay(bh)) - new_type = XFS_IO_DELALLOC; - else if (buffer_uptodate(bh)) - new_type = XFS_IO_OVERWRITE; - else { + if (!buffer_uptodate(bh)) { if (PageUptodate(page)) ASSERT(buffer_mapped(bh)); - /* - * This buffer is not uptodate and will not be - * written to disk. - */ continue; } - /* - * If we already have a valid COW mapping keep using it. - */ - if (wpc->io_type == XFS_IO_COW && - xfs_imap_valid(inode, &wpc->imap, file_offset)) { - wpc->imap_valid = true; - new_type = XFS_IO_COW; - } - - if (wpc->io_type != new_type) { - wpc->io_type = new_type; - wpc->imap_valid = false; - } - if (wpc->imap_valid) wpc->imap_valid = xfs_imap_valid(inode, &wpc->imap, file_offset); @@ -897,11 +882,10 @@ xfs_writepage_map( continue; lock_buffer(bh); - if (wpc->io_type != XFS_IO_OVERWRITE) - xfs_map_at_offset(inode, bh, &wpc->imap, file_offset); + xfs_map_at_offset(inode, bh, &wpc->imap, file_offset); xfs_add_to_ioend(inode, bh, file_offset, wpc, wbc, &submit_list); count++; - } while (file_offset += len, ((bh = bh->b_this_page) != head)); + } ASSERT(wpc->ioend || list_empty(&submit_list)); -- cgit v1.2.3 From c3a2f9fff1bbe3cfc2070b2e9f1f0ad0d5ccda91 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 11 Jul 2018 22:26:01 -0700 Subject: xfs: remove the now unused XFS_BMAPI_IGSTATE flag Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 6 ++---- fs/xfs/libxfs/xfs_bmap.h | 3 --- 2 files changed, 2 insertions(+), 7 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 7205268b30bc..68ea1f4b9c3f 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3788,8 +3788,7 @@ xfs_bmapi_update_map( mval[-1].br_startblock != HOLESTARTBLOCK && mval->br_startblock == mval[-1].br_startblock + mval[-1].br_blockcount && - ((flags & XFS_BMAPI_IGSTATE) || - mval[-1].br_state == mval->br_state)) { + mval[-1].br_state == mval->br_state) { ASSERT(mval->br_startoff == mval[-1].br_startoff + mval[-1].br_blockcount); mval[-1].br_blockcount += mval->br_blockcount; @@ -3834,7 +3833,7 @@ xfs_bmapi_read( ASSERT(*nmap >= 1); ASSERT(!(flags & ~(XFS_BMAPI_ATTRFORK|XFS_BMAPI_ENTIRE| - XFS_BMAPI_IGSTATE|XFS_BMAPI_COWFORK))); + XFS_BMAPI_COWFORK))); ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED|XFS_ILOCK_EXCL)); if (unlikely(XFS_TEST_ERROR( @@ -4279,7 +4278,6 @@ xfs_bmapi_write( ASSERT(*nmap >= 1); ASSERT(*nmap <= XFS_BMAP_MAX_NMAP); - ASSERT(!(flags & XFS_BMAPI_IGSTATE)); ASSERT(tp != NULL || (flags & (XFS_BMAPI_CONVERT | XFS_BMAPI_COWFORK)) == (XFS_BMAPI_CONVERT | XFS_BMAPI_COWFORK)); diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 9b49ddf99c41..44639588d1c7 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -68,8 +68,6 @@ struct xfs_extent_free_item #define XFS_BMAPI_METADATA 0x002 /* mapping metadata not user data */ #define XFS_BMAPI_ATTRFORK 0x004 /* use attribute fork not data */ #define XFS_BMAPI_PREALLOC 0x008 /* preallocation op: unwritten space */ -#define XFS_BMAPI_IGSTATE 0x010 /* Ignore state - */ - /* combine contig. space */ #define XFS_BMAPI_CONTIG 0x020 /* must allocate only one extent */ /* * unwritten extent conversion - this needs write cache flushing and no additional @@ -116,7 +114,6 @@ struct xfs_extent_free_item { XFS_BMAPI_METADATA, "METADATA" }, \ { XFS_BMAPI_ATTRFORK, "ATTRFORK" }, \ { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ - { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ { XFS_BMAPI_CONTIG, "CONTIG" }, \ { XFS_BMAPI_CONVERT, "CONVERT" }, \ { XFS_BMAPI_ZERO, "ZERO" }, \ -- cgit v1.2.3 From 060d4eaa0bf30a8fc2d189e4d4922f6e9027857b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 11 Jul 2018 22:26:01 -0700 Subject: xfs: remove xfs_reflink_find_cow_mapping We only have one caller left, and open coding the simple extent list lookup in it allows us to make the code both more understandable and reuse calculations and variables already present. Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 19 +++++++++++++------ fs/xfs/xfs_reflink.c | 30 ------------------------------ fs/xfs/xfs_reflink.h | 2 -- fs/xfs/xfs_trace.h | 1 - 4 files changed, 13 insertions(+), 39 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 815b0b29438b..5c5d8c832dcc 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -370,9 +370,10 @@ xfs_map_blocks( struct xfs_inode *ip = XFS_I(inode); struct xfs_mount *mp = ip->i_mount; ssize_t count = i_blocksize(inode); - xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset), end_fsb; + xfs_fileoff_t offset_fsb, end_fsb; struct xfs_bmbt_irec imap; int whichfork = XFS_DATA_FORK; + struct xfs_iext_cursor icur; int error = 0; int nimaps = 1; @@ -384,8 +385,18 @@ xfs_map_blocks( (ip->i_df.if_flags & XFS_IFEXTENTS)); ASSERT(offset <= mp->m_super->s_maxbytes); + if (offset > mp->m_super->s_maxbytes - count) + count = mp->m_super->s_maxbytes - offset; + end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); + offset_fsb = XFS_B_TO_FSBT(mp, offset); + + /* + * Check if this is offset is covered by a COW extents, and if yes use + * it directly instead of looking up anything in the data fork. + */ if (xfs_is_reflink_inode(ip) && - xfs_reflink_find_cow_mapping(ip, offset, &imap)) { + xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, &imap) && + imap.br_startoff <= offset_fsb) { xfs_iunlock(ip, XFS_ILOCK_SHARED); /* * Truncate can race with writeback since writeback doesn't @@ -420,10 +431,6 @@ xfs_map_blocks( * offset. This will convert delayed allocations (including COW ones) * into real extents. */ - if (offset > mp->m_super->s_maxbytes - count) - count = mp->m_super->s_maxbytes - offset; - end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); - offset_fsb = XFS_B_TO_FSBT(mp, offset); error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, &imap, &nimaps, XFS_BMAPI_ENTIRE); xfs_iunlock(ip, XFS_ILOCK_SHARED); diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 22c11b98ab26..49e4913fa779 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -470,36 +470,6 @@ out: return error; } -/* - * Find the CoW reservation for a given byte offset of a file. - */ -bool -xfs_reflink_find_cow_mapping( - struct xfs_inode *ip, - xfs_off_t offset, - struct xfs_bmbt_irec *imap) -{ - struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK); - xfs_fileoff_t offset_fsb; - struct xfs_bmbt_irec got; - struct xfs_iext_cursor icur; - - ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL | XFS_ILOCK_SHARED)); - - if (!xfs_is_reflink_inode(ip)) - return false; - offset_fsb = XFS_B_TO_FSBT(ip->i_mount, offset); - if (!xfs_iext_lookup_extent(ip, ifp, offset_fsb, &icur, &got)) - return false; - if (got.br_startoff > offset_fsb) - return false; - - trace_xfs_reflink_find_cow_mapping(ip, offset, 1, XFS_IO_OVERWRITE, - &got); - *imap = got; - return true; -} - /* * Cancel CoW reservations for some block range of an inode. * diff --git a/fs/xfs/xfs_reflink.h b/fs/xfs/xfs_reflink.h index 6f9f98894abc..c585ad9552b2 100644 --- a/fs/xfs/xfs_reflink.h +++ b/fs/xfs/xfs_reflink.h @@ -18,8 +18,6 @@ extern int xfs_reflink_allocate_cow(struct xfs_inode *ip, struct xfs_bmbt_irec *imap, bool *shared, uint *lockmode); extern int xfs_reflink_convert_cow(struct xfs_inode *ip, xfs_off_t offset, xfs_off_t count); -extern bool xfs_reflink_find_cow_mapping(struct xfs_inode *ip, xfs_off_t offset, - struct xfs_bmbt_irec *imap); extern int xfs_reflink_cancel_cow_blocks(struct xfs_inode *ip, struct xfs_trans **tpp, xfs_fileoff_t offset_fsb, diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index a5b01529ecf6..1af123df19b5 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -3215,7 +3215,6 @@ DEFINE_INODE_IREC_EVENT(xfs_reflink_convert_cow); DEFINE_RW_EVENT(xfs_reflink_reserve_cow); DEFINE_SIMPLE_IO_EVENT(xfs_reflink_bounce_dio_write); -DEFINE_IOMAP_EVENT(xfs_reflink_find_cow_mapping); DEFINE_SIMPLE_IO_EVENT(xfs_reflink_cancel_cow_range); DEFINE_SIMPLE_IO_EVENT(xfs_reflink_end_cow); -- cgit v1.2.3 From 3345746ef38bb794ae9d4d0762adf151e452663e Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 11 Jul 2018 22:26:02 -0700 Subject: xfs: simplify xfs_map_blocks by using xfs_iext_lookup_extent directly xfs_bmapi_read adds zero value in xfs_map_blocks. Replace it with a direct call to the low-level extent lookup function. Note that we now always pass a 0 length to the trace points as we ask for an unspecified len. Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 5c5d8c832dcc..0bfcc2d06658 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -375,7 +375,6 @@ xfs_map_blocks( int whichfork = XFS_DATA_FORK; struct xfs_iext_cursor icur; int error = 0; - int nimaps = 1; if (XFS_FORCED_SHUTDOWN(mp)) return -EIO; @@ -431,24 +430,16 @@ xfs_map_blocks( * offset. This will convert delayed allocations (including COW ones) * into real extents. */ - error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, - &imap, &nimaps, XFS_BMAPI_ENTIRE); + if (!xfs_iext_lookup_extent(ip, &ip->i_df, offset_fsb, &icur, &imap)) + imap.br_startoff = end_fsb; /* fake a hole past EOF */ xfs_iunlock(ip, XFS_ILOCK_SHARED); - if (error) - return error; - if (!nimaps) { - /* - * Lookup returns no match? Beyond eof? regardless, - * return it as a hole so we don't write it - */ + if (imap.br_startoff > offset_fsb) { + /* landed in a hole or beyond EOF */ + imap.br_blockcount = imap.br_startoff - offset_fsb; imap.br_startoff = offset_fsb; - imap.br_blockcount = end_fsb - offset_fsb; imap.br_startblock = HOLESTARTBLOCK; wpc->io_type = XFS_IO_HOLE; - } else if (imap.br_startblock == HOLESTARTBLOCK) { - /* landed in a hole */ - wpc->io_type = XFS_IO_HOLE; } else { if (isnullstartblock(imap.br_startblock)) { /* got a delalloc extent */ -- cgit v1.2.3 From 889c65b3f60af4c840896478fc6151363ffa279f Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 11 Jul 2018 22:26:02 -0700 Subject: xfs: remove the imap_valid flag Simplify the way we check for a valid imap - we know we have a valid mapping after xfs_map_blocks returned successfully, and we know we can call xfs_imap_valid on any imap, as it will always fail on a zero-initialized map. We can also remove the xfs_imap_valid function and fold it into xfs_map_blocks now. Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 89 ++++++++++++++++++++++++------------------------------- 1 file changed, 38 insertions(+), 51 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 0bfcc2d06658..09092f10cff3 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -30,7 +30,6 @@ */ struct xfs_writepage_ctx { struct xfs_bmbt_irec imap; - bool imap_valid; unsigned int io_type; struct xfs_ioend *ioend; sector_t last_block; @@ -370,15 +369,47 @@ xfs_map_blocks( struct xfs_inode *ip = XFS_I(inode); struct xfs_mount *mp = ip->i_mount; ssize_t count = i_blocksize(inode); - xfs_fileoff_t offset_fsb, end_fsb; + xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset), end_fsb; struct xfs_bmbt_irec imap; int whichfork = XFS_DATA_FORK; struct xfs_iext_cursor icur; + bool imap_valid; int error = 0; + /* + * We have to make sure the cached mapping is within EOF to protect + * against eofblocks trimming on file release leaving us with a stale + * mapping. Otherwise, a page for a subsequent file extending buffered + * write could get picked up by this writeback cycle and written to the + * wrong blocks. + * + * Note that what we really want here is a generic mapping invalidation + * mechanism to protect us from arbitrary extent modifying contexts, not + * just eofblocks. + */ + xfs_trim_extent_eof(&wpc->imap, ip); + + /* + * COW fork blocks can overlap data fork blocks even if the blocks + * aren't shared. COW I/O always takes precedent, so we must always + * check for overlap on reflink inodes unless the mapping is already a + * COW one. + */ + imap_valid = offset_fsb >= wpc->imap.br_startoff && + offset_fsb < wpc->imap.br_startoff + wpc->imap.br_blockcount; + if (imap_valid && + (!xfs_is_reflink_inode(ip) || wpc->io_type == XFS_IO_COW)) + return 0; + if (XFS_FORCED_SHUTDOWN(mp)) return -EIO; + /* + * If we don't have a valid map, now it's time to get a new one for this + * offset. This will convert delayed allocations (including COW ones) + * into real extents. If we return without a valid map, it means we + * landed in a hole and we skip the block. + */ xfs_ilock(ip, XFS_ILOCK_SHARED); ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || (ip->i_df.if_flags & XFS_IFEXTENTS)); @@ -387,7 +418,6 @@ xfs_map_blocks( if (offset > mp->m_super->s_maxbytes - count) count = mp->m_super->s_maxbytes - offset; end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); - offset_fsb = XFS_B_TO_FSBT(mp, offset); /* * Check if this is offset is covered by a COW extents, and if yes use @@ -420,7 +450,7 @@ xfs_map_blocks( /* * Map valid and no COW extent in the way? We're done. */ - if (wpc->imap_valid) { + if (imap_valid) { xfs_iunlock(ip, XFS_ILOCK_SHARED); return 0; } @@ -465,31 +495,6 @@ allocate_blocks: return 0; } -STATIC bool -xfs_imap_valid( - struct inode *inode, - struct xfs_bmbt_irec *imap, - xfs_off_t offset) -{ - offset >>= inode->i_blkbits; - - /* - * We have to make sure the cached mapping is within EOF to protect - * against eofblocks trimming on file release leaving us with a stale - * mapping. Otherwise, a page for a subsequent file extending buffered - * write could get picked up by this writeback cycle and written to the - * wrong blocks. - * - * Note that what we really want here is a generic mapping invalidation - * mechanism to protect us from arbitrary extent modifying contexts, not - * just eofblocks. - */ - xfs_trim_extent_eof(imap, XFS_I(inode)); - - return offset >= imap->br_startoff && - offset < imap->br_startoff + imap->br_blockcount; -} - STATIC void xfs_start_buffer_writeback( struct buffer_head *bh) @@ -856,27 +861,10 @@ xfs_writepage_map( continue; } - if (wpc->imap_valid) - wpc->imap_valid = xfs_imap_valid(inode, &wpc->imap, - file_offset); - - /* - * COW fork blocks can overlap data fork blocks even if the - * blocks aren't shared. COW I/O always takes precedent, so we - * must always check for overlap on reflink inodes unless the - * mapping is already a COW one. - */ - if (!wpc->imap_valid || - (xfs_is_reflink_inode(XFS_I(inode)) && - wpc->io_type != XFS_IO_COW)) { - error = xfs_map_blocks(wpc, inode, file_offset); - if (error) - goto out; - wpc->imap_valid = xfs_imap_valid(inode, &wpc->imap, - file_offset); - } - - if (!wpc->imap_valid || wpc->io_type == XFS_IO_HOLE) + error = xfs_map_blocks(wpc, inode, file_offset); + if (error) + break; + if (wpc->io_type == XFS_IO_HOLE) continue; lock_buffer(bh); @@ -887,7 +875,6 @@ xfs_writepage_map( ASSERT(wpc->ioend || list_empty(&submit_list)); -out: /* * On error, we have to fail the ioend here because we have locked * buffers in the ioend. If we don't do this, we'll deadlock -- cgit v1.2.3 From 3faed667644d787c3cf6f977f80bac7a013eb045 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 11 Jul 2018 22:26:02 -0700 Subject: xfs: don't look at buffer heads in xfs_add_to_ioend Calculate all information for the bio based on the passed in information without requiring a buffer_head structure. Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 68 ++++++++++++++++++++++++++----------------------------- 1 file changed, 32 insertions(+), 36 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 09092f10cff3..6402e4323031 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -32,7 +32,6 @@ struct xfs_writepage_ctx { struct xfs_bmbt_irec imap; unsigned int io_type; struct xfs_ioend *ioend; - sector_t last_block; }; void @@ -534,11 +533,6 @@ xfs_start_page_writeback( unlock_page(page); } -static inline int xfs_bio_add_buffer(struct bio *bio, struct buffer_head *bh) -{ - return bio_add_page(bio, bh->b_page, bh->b_size, bh_offset(bh)); -} - /* * Submit the bio for an ioend. We are passed an ioend with a bio attached to * it, and we submit that bio. The ioend may be used for multiple bio @@ -604,27 +598,20 @@ xfs_submit_ioend( return 0; } -static void -xfs_init_bio_from_bh( - struct bio *bio, - struct buffer_head *bh) -{ - bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9); - bio_set_dev(bio, bh->b_bdev); -} - static struct xfs_ioend * xfs_alloc_ioend( struct inode *inode, unsigned int type, xfs_off_t offset, - struct buffer_head *bh) + struct block_device *bdev, + sector_t sector) { struct xfs_ioend *ioend; struct bio *bio; bio = bio_alloc_bioset(GFP_NOFS, BIO_MAX_PAGES, &xfs_ioend_bioset); - xfs_init_bio_from_bh(bio, bh); + bio_set_dev(bio, bdev); + bio->bi_iter.bi_sector = sector; ioend = container_of(bio, struct xfs_ioend, io_inline_bio); INIT_LIST_HEAD(&ioend->io_list); @@ -649,13 +636,14 @@ static void xfs_chain_bio( struct xfs_ioend *ioend, struct writeback_control *wbc, - struct buffer_head *bh) + struct block_device *bdev, + sector_t sector) { struct bio *new; new = bio_alloc(GFP_NOFS, BIO_MAX_PAGES); - xfs_init_bio_from_bh(new, bh); - + bio_set_dev(new, bdev); + new->bi_iter.bi_sector = sector; bio_chain(ioend->io_bio, new); bio_get(ioend->io_bio); /* for xfs_destroy_ioend */ ioend->io_bio->bi_opf = REQ_OP_WRITE | wbc_to_write_flags(wbc); @@ -665,39 +653,45 @@ xfs_chain_bio( } /* - * Test to see if we've been building up a completion structure for - * earlier buffers -- if so, we try to append to this ioend if we - * can, otherwise we finish off any current ioend and start another. - * Return the ioend we finished off so that the caller can submit it - * once it has finished processing the dirty page. + * Test to see if we have an existing ioend structure that we could append to + * first, otherwise finish off the current ioend and start another. */ STATIC void xfs_add_to_ioend( struct inode *inode, - struct buffer_head *bh, xfs_off_t offset, + struct page *page, struct xfs_writepage_ctx *wpc, struct writeback_control *wbc, struct list_head *iolist) { + struct xfs_inode *ip = XFS_I(inode); + struct xfs_mount *mp = ip->i_mount; + struct block_device *bdev = xfs_find_bdev_for_inode(inode); + unsigned len = i_blocksize(inode); + unsigned poff = offset & (PAGE_SIZE - 1); + sector_t sector; + + sector = xfs_fsb_to_db(ip, wpc->imap.br_startblock) + + ((offset - XFS_FSB_TO_B(mp, wpc->imap.br_startoff)) >> 9); + if (!wpc->ioend || wpc->io_type != wpc->ioend->io_type || - bh->b_blocknr != wpc->last_block + 1 || + sector != bio_end_sector(wpc->ioend->io_bio) || offset != wpc->ioend->io_offset + wpc->ioend->io_size) { if (wpc->ioend) list_add(&wpc->ioend->io_list, iolist); - wpc->ioend = xfs_alloc_ioend(inode, wpc->io_type, offset, bh); + wpc->ioend = xfs_alloc_ioend(inode, wpc->io_type, offset, + bdev, sector); } /* - * If the buffer doesn't fit into the bio we need to allocate a new - * one. This shouldn't happen more than once for a given buffer. + * If the block doesn't fit into the bio we need to allocate a new + * one. This shouldn't happen more than once for a given block. */ - while (xfs_bio_add_buffer(wpc->ioend->io_bio, bh) != bh->b_size) - xfs_chain_bio(wpc->ioend, wbc, bh); + while (bio_add_page(wpc->ioend->io_bio, page, len, poff) != len) + xfs_chain_bio(wpc->ioend, wbc, bdev, sector); - wpc->ioend->io_size += bh->b_size; - wpc->last_block = bh->b_blocknr; - xfs_start_buffer_writeback(bh); + wpc->ioend->io_size += len; } STATIC void @@ -869,7 +863,9 @@ xfs_writepage_map( lock_buffer(bh); xfs_map_at_offset(inode, bh, &wpc->imap, file_offset); - xfs_add_to_ioend(inode, bh, file_offset, wpc, wbc, &submit_list); + xfs_add_to_ioend(inode, file_offset, page, wpc, wbc, + &submit_list); + xfs_start_buffer_writeback(bh); count++; } -- cgit v1.2.3 From 6d465e895343225e3ad35fe10d7b3e9f2f18faec Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 11 Jul 2018 22:26:03 -0700 Subject: xfs: move all writeback buffer_head manipulation into xfs_map_at_offset This keeps it in a single place so it can be made otional more easily. Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 6402e4323031..71b4ca60ff40 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -494,21 +494,6 @@ allocate_blocks: return 0; } -STATIC void -xfs_start_buffer_writeback( - struct buffer_head *bh) -{ - ASSERT(buffer_mapped(bh)); - ASSERT(buffer_locked(bh)); - ASSERT(!buffer_delay(bh)); - ASSERT(!buffer_unwritten(bh)); - - bh->b_end_io = NULL; - set_buffer_async_write(bh); - set_buffer_uptodate(bh); - clear_buffer_dirty(bh); -} - STATIC void xfs_start_page_writeback( struct page *page, @@ -728,6 +713,7 @@ xfs_map_at_offset( ASSERT(imap->br_startblock != HOLESTARTBLOCK); ASSERT(imap->br_startblock != DELAYSTARTBLOCK); + lock_buffer(bh); xfs_map_buffer(inode, bh, imap, offset); set_buffer_mapped(bh); clear_buffer_delay(bh); @@ -740,6 +726,10 @@ xfs_map_at_offset( * set the bdev now. */ bh->b_bdev = xfs_find_bdev_for_inode(inode); + bh->b_end_io = NULL; + set_buffer_async_write(bh); + set_buffer_uptodate(bh); + clear_buffer_dirty(bh); } STATIC void @@ -861,11 +851,9 @@ xfs_writepage_map( if (wpc->io_type == XFS_IO_HOLE) continue; - lock_buffer(bh); xfs_map_at_offset(inode, bh, &wpc->imap, file_offset); xfs_add_to_ioend(inode, file_offset, page, wpc, wbc, &submit_list); - xfs_start_buffer_writeback(bh); count++; } -- cgit v1.2.3 From 1b65d3dd2d5e938b035b2ad73d0b47f35b5ef9a0 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 11 Jul 2018 22:26:03 -0700 Subject: xfs: remove xfs_start_page_writeback This helper only has two callers, one of them with a constant error argument. Remove it to make pending changes to the code a little easier. Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 46 ++++++++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 26 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 71b4ca60ff40..af9224ea4ebf 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -494,30 +494,6 @@ allocate_blocks: return 0; } -STATIC void -xfs_start_page_writeback( - struct page *page, - int clear_dirty) -{ - ASSERT(PageLocked(page)); - ASSERT(!PageWriteback(page)); - - /* - * if the page was not fully cleaned, we need to ensure that the higher - * layers come back to it correctly. That means we need to keep the page - * dirty, and for WB_SYNC_ALL writeback we need to ensure the - * PAGECACHE_TAG_TOWRITE index mark is not removed so another attempt to - * write this page in this writeback sweep will be made. - */ - if (clear_dirty) { - clear_page_dirty_for_io(page); - set_page_writeback(page); - } else - set_page_writeback_keepwrite(page); - - unlock_page(page); -} - /* * Submit the bio for an ioend. We are passed an ioend with a bio attached to * it, and we submit that bio. The ioend may be used for multiple bio @@ -858,6 +834,8 @@ xfs_writepage_map( } ASSERT(wpc->ioend || list_empty(&submit_list)); + ASSERT(PageLocked(page)); + ASSERT(!PageWriteback(page)); /* * On error, we have to fail the ioend here because we have locked @@ -877,7 +855,21 @@ xfs_writepage_map( * treated correctly on error. */ if (count) { - xfs_start_page_writeback(page, !error); + /* + * If the page was not fully cleaned, we need to ensure that the + * higher layers come back to it correctly. That means we need + * to keep the page dirty, and for WB_SYNC_ALL writeback we need + * to ensure the PAGECACHE_TAG_TOWRITE index mark is not removed + * so another attempt to write this page in this writeback sweep + * will be made. + */ + if (error) { + set_page_writeback_keepwrite(page); + } else { + clear_page_dirty_for_io(page); + set_page_writeback(page); + } + unlock_page(page); /* * Preserve the original error if there was one, otherwise catch @@ -902,7 +894,9 @@ xfs_writepage_map( * race with a partial page truncate on a sub-page block sized * filesystem. In that case we need to mark the page clean. */ - xfs_start_page_writeback(page, 1); + clear_page_dirty_for_io(page); + set_page_writeback(page); + unlock_page(page); end_page_writeback(page); } -- cgit v1.2.3 From 8e1f065bea1b1c128c92ef7e386779a23cd5d342 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 11 Jul 2018 22:26:04 -0700 Subject: xfs: refactor the tail of xfs_writepage_map Rejuggle how we deal with the different error vs non-error and have ioends vs not have ioend cases to keep the fast path streamlined, and the duplicate code at a minimum. Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 65 +++++++++++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 33 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index af9224ea4ebf..c8e0d3055153 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -854,7 +854,14 @@ xfs_writepage_map( * submission of outstanding ioends on the writepage context so they are * treated correctly on error. */ - if (count) { + if (unlikely(error)) { + if (!count) { + xfs_aops_discard_page(page); + ClearPageUptodate(page); + unlock_page(page); + goto done; + } + /* * If the page was not fully cleaned, we need to ensure that the * higher layers come back to it correctly. That means we need @@ -863,43 +870,35 @@ xfs_writepage_map( * so another attempt to write this page in this writeback sweep * will be made. */ - if (error) { - set_page_writeback_keepwrite(page); - } else { - clear_page_dirty_for_io(page); - set_page_writeback(page); - } - unlock_page(page); - - /* - * Preserve the original error if there was one, otherwise catch - * submission errors here and propagate into subsequent ioend - * submissions. - */ - list_for_each_entry_safe(ioend, next, &submit_list, io_list) { - int error2; - - list_del_init(&ioend->io_list); - error2 = xfs_submit_ioend(wbc, ioend, error); - if (error2 && !error) - error = error2; - } - } else if (error) { - xfs_aops_discard_page(page); - ClearPageUptodate(page); - unlock_page(page); + set_page_writeback_keepwrite(page); } else { - /* - * We can end up here with no error and nothing to write if we - * race with a partial page truncate on a sub-page block sized - * filesystem. In that case we need to mark the page clean. - */ clear_page_dirty_for_io(page); set_page_writeback(page); - unlock_page(page); - end_page_writeback(page); } + unlock_page(page); + + /* + * Preserve the original error if there was one, otherwise catch + * submission errors here and propagate into subsequent ioend + * submissions. + */ + list_for_each_entry_safe(ioend, next, &submit_list, io_list) { + int error2; + + list_del_init(&ioend->io_list); + error2 = xfs_submit_ioend(wbc, ioend, error); + if (error2 && !error) + error = error2; + } + + /* + * We can end up here with no error and nothing to write if we race with + * a partial page truncate on a sub-page block sized filesystem. + */ + if (!count) + end_page_writeback(page); +done: mapping_set_error(page->mapping, error); return error; } -- cgit v1.2.3 From ac8ee54669c07e6b38b4cae13a65f5ec06a11323 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 11 Jul 2018 22:26:04 -0700 Subject: xfs: allow writeback on pages without buffer heads Disable the IOMAP_F_BUFFER_HEAD flag on file systems with a block size equal to the page size, and deal with pages without buffer heads in writeback. Thanks to the previous refactoring this is basically trivial now. Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 51 +++++++++++++++++++++++++++++++++++++-------------- fs/xfs/xfs_iomap.c | 3 ++- 2 files changed, 39 insertions(+), 15 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index c8e0d3055153..0058f9893705 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -79,6 +79,19 @@ xfs_find_daxdev_for_inode( return mp->m_ddev_targp->bt_daxdev; } +static void +xfs_finish_page_writeback( + struct inode *inode, + struct bio_vec *bvec, + int error) +{ + if (error) { + SetPageError(bvec->bv_page); + mapping_set_error(inode->i_mapping, -EIO); + } + end_page_writeback(bvec->bv_page); +} + /* * We're now finished for good with this page. Update the page state via the * associated buffer_heads, paying attention to the start and end offsets that @@ -91,7 +104,7 @@ xfs_find_daxdev_for_inode( * and buffers potentially freed after every call to end_buffer_async_write. */ static void -xfs_finish_page_writeback( +xfs_finish_buffer_writeback( struct inode *inode, struct bio_vec *bvec, int error) @@ -166,9 +179,12 @@ xfs_destroy_ioend( next = bio->bi_private; /* walk each page on bio, ending page IO on them */ - bio_for_each_segment_all(bvec, bio, i) - xfs_finish_page_writeback(inode, bvec, error); - + bio_for_each_segment_all(bvec, bio, i) { + if (page_has_buffers(bvec->bv_page)) + xfs_finish_buffer_writeback(inode, bvec, error); + else + xfs_finish_page_writeback(inode, bvec, error); + } bio_put(bio); } @@ -792,13 +808,16 @@ xfs_writepage_map( { LIST_HEAD(submit_list); struct xfs_ioend *ioend, *next; - struct buffer_head *bh; + struct buffer_head *bh = NULL; ssize_t len = i_blocksize(inode); uint64_t file_offset; /* file offset of page */ unsigned poffset; /* offset into page */ int error = 0; int count = 0; + if (page_has_buffers(page)) + bh = page_buffers(page); + /* * Walk the blocks on the page, and if we run off the end of the current * map or find the current map invalid, grab a new one. We only use @@ -806,28 +825,34 @@ xfs_writepage_map( * the iteration through the page. This allows us to replace the * bufferhead with some other state tracking mechanism in future. */ - file_offset = page_offset(page); - bh = page_buffers(page); - for (poffset = 0; + for (poffset = 0, file_offset = page_offset(page); poffset < PAGE_SIZE; - poffset += len, file_offset += len, bh = bh->b_this_page) { + poffset += len, file_offset += len) { /* past the range we are writing, so nothing more to write. */ if (file_offset >= end_offset) break; - if (!buffer_uptodate(bh)) { + if (bh && !buffer_uptodate(bh)) { if (PageUptodate(page)) ASSERT(buffer_mapped(bh)); + bh = bh->b_this_page; continue; } error = xfs_map_blocks(wpc, inode, file_offset); if (error) break; - if (wpc->io_type == XFS_IO_HOLE) + + if (wpc->io_type == XFS_IO_HOLE) { + if (bh) + bh = bh->b_this_page; continue; + } - xfs_map_at_offset(inode, bh, &wpc->imap, file_offset); + if (bh) { + xfs_map_at_offset(inode, bh, &wpc->imap, file_offset); + bh = bh->b_this_page; + } xfs_add_to_ioend(inode, file_offset, page, wpc, wbc, &submit_list); count++; @@ -925,8 +950,6 @@ xfs_do_writepage( trace_xfs_writepage(inode, page, 0, 0); - ASSERT(page_has_buffers(page)); - /* * Refuse to write the page out if we are called from reclaim context. * diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 10c54fc7d1b4..7fe42a126ec1 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -1032,7 +1032,8 @@ xfs_file_iomap_begin( if (XFS_FORCED_SHUTDOWN(mp)) return -EIO; - iomap->flags |= IOMAP_F_BUFFER_HEAD; + if (i_blocksize(inode) < PAGE_SIZE) + iomap->flags |= IOMAP_F_BUFFER_HEAD; if (((flags & (IOMAP_WRITE | IOMAP_DIRECT)) == IOMAP_WRITE) && !IS_DAX(inode) && !xfs_get_extsz_hint(ip)) { -- cgit v1.2.3 From 82cb14175e7ddb08721fb1d766195cd10dad791a Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 11 Jul 2018 22:26:05 -0700 Subject: xfs: add support for sub-pagesize writeback without buffer_heads Switch to using the iomap_page structure for checking sub-page uptodate status and track sub-page I/O completion status, and remove large quantities of boilerplate code working around buffer heads. Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 492 +++++++---------------------------------------------- fs/xfs/xfs_buf.h | 1 - fs/xfs/xfs_iomap.c | 3 - fs/xfs/xfs_super.c | 2 +- fs/xfs/xfs_trace.h | 18 +- 5 files changed, 61 insertions(+), 455 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 0058f9893705..bae88ac1101d 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -20,9 +20,6 @@ #include "xfs_bmap_util.h" #include "xfs_bmap_btree.h" #include "xfs_reflink.h" -#include -#include -#include #include /* @@ -34,25 +31,6 @@ struct xfs_writepage_ctx { struct xfs_ioend *ioend; }; -void -xfs_count_page_state( - struct page *page, - int *delalloc, - int *unwritten) -{ - struct buffer_head *bh, *head; - - *delalloc = *unwritten = 0; - - bh = head = page_buffers(page); - do { - if (buffer_unwritten(bh)) - (*unwritten) = 1; - else if (buffer_delay(bh)) - (*delalloc) = 1; - } while ((bh = bh->b_this_page) != head); -} - struct block_device * xfs_find_bdev_for_inode( struct inode *inode) @@ -85,67 +63,17 @@ xfs_finish_page_writeback( struct bio_vec *bvec, int error) { + struct iomap_page *iop = to_iomap_page(bvec->bv_page); + if (error) { SetPageError(bvec->bv_page); mapping_set_error(inode->i_mapping, -EIO); } - end_page_writeback(bvec->bv_page); -} -/* - * We're now finished for good with this page. Update the page state via the - * associated buffer_heads, paying attention to the start and end offsets that - * we need to process on the page. - * - * Note that we open code the action in end_buffer_async_write here so that we - * only have to iterate over the buffers attached to the page once. This is not - * only more efficient, but also ensures that we only calls end_page_writeback - * at the end of the iteration, and thus avoids the pitfall of having the page - * and buffers potentially freed after every call to end_buffer_async_write. - */ -static void -xfs_finish_buffer_writeback( - struct inode *inode, - struct bio_vec *bvec, - int error) -{ - struct buffer_head *head = page_buffers(bvec->bv_page), *bh = head; - bool busy = false; - unsigned int off = 0; - unsigned long flags; - - ASSERT(bvec->bv_offset < PAGE_SIZE); - ASSERT((bvec->bv_offset & (i_blocksize(inode) - 1)) == 0); - ASSERT(bvec->bv_offset + bvec->bv_len <= PAGE_SIZE); - ASSERT((bvec->bv_len & (i_blocksize(inode) - 1)) == 0); - - local_irq_save(flags); - bit_spin_lock(BH_Uptodate_Lock, &head->b_state); - do { - if (off >= bvec->bv_offset && - off < bvec->bv_offset + bvec->bv_len) { - ASSERT(buffer_async_write(bh)); - ASSERT(bh->b_end_io == NULL); - - if (error) { - mark_buffer_write_io_error(bh); - clear_buffer_uptodate(bh); - SetPageError(bvec->bv_page); - } else { - set_buffer_uptodate(bh); - } - clear_buffer_async_write(bh); - unlock_buffer(bh); - } else if (buffer_async_write(bh)) { - ASSERT(buffer_locked(bh)); - busy = true; - } - off += bh->b_size; - } while ((bh = bh->b_this_page) != head); - bit_spin_unlock(BH_Uptodate_Lock, &head->b_state); - local_irq_restore(flags); + ASSERT(iop || i_blocksize(inode) == PAGE_SIZE); + ASSERT(!iop || atomic_read(&iop->write_count) > 0); - if (!busy) + if (!iop || atomic_dec_and_test(&iop->write_count)) end_page_writeback(bvec->bv_page); } @@ -179,12 +107,8 @@ xfs_destroy_ioend( next = bio->bi_private; /* walk each page on bio, ending page IO on them */ - bio_for_each_segment_all(bvec, bio, i) { - if (page_has_buffers(bvec->bv_page)) - xfs_finish_buffer_writeback(inode, bvec, error); - else - xfs_finish_page_writeback(inode, bvec, error); - } + bio_for_each_segment_all(bvec, bio, i) + xfs_finish_page_writeback(inode, bvec, error); bio_put(bio); } @@ -638,6 +562,7 @@ xfs_add_to_ioend( struct inode *inode, xfs_off_t offset, struct page *page, + struct iomap_page *iop, struct xfs_writepage_ctx *wpc, struct writeback_control *wbc, struct list_head *iolist) @@ -661,100 +586,37 @@ xfs_add_to_ioend( bdev, sector); } - /* - * If the block doesn't fit into the bio we need to allocate a new - * one. This shouldn't happen more than once for a given block. - */ - while (bio_add_page(wpc->ioend->io_bio, page, len, poff) != len) - xfs_chain_bio(wpc->ioend, wbc, bdev, sector); + if (!__bio_try_merge_page(wpc->ioend->io_bio, page, len, poff)) { + if (iop) + atomic_inc(&iop->write_count); + if (bio_full(wpc->ioend->io_bio)) + xfs_chain_bio(wpc->ioend, wbc, bdev, sector); + __bio_add_page(wpc->ioend->io_bio, page, len, poff); + } wpc->ioend->io_size += len; } -STATIC void -xfs_map_buffer( - struct inode *inode, - struct buffer_head *bh, - struct xfs_bmbt_irec *imap, - xfs_off_t offset) -{ - sector_t bn; - struct xfs_mount *m = XFS_I(inode)->i_mount; - xfs_off_t iomap_offset = XFS_FSB_TO_B(m, imap->br_startoff); - xfs_daddr_t iomap_bn = xfs_fsb_to_db(XFS_I(inode), imap->br_startblock); - - ASSERT(imap->br_startblock != HOLESTARTBLOCK); - ASSERT(imap->br_startblock != DELAYSTARTBLOCK); - - bn = (iomap_bn >> (inode->i_blkbits - BBSHIFT)) + - ((offset - iomap_offset) >> inode->i_blkbits); - - ASSERT(bn || XFS_IS_REALTIME_INODE(XFS_I(inode))); - - bh->b_blocknr = bn; - set_buffer_mapped(bh); -} - -STATIC void -xfs_map_at_offset( - struct inode *inode, - struct buffer_head *bh, - struct xfs_bmbt_irec *imap, - xfs_off_t offset) -{ - ASSERT(imap->br_startblock != HOLESTARTBLOCK); - ASSERT(imap->br_startblock != DELAYSTARTBLOCK); - - lock_buffer(bh); - xfs_map_buffer(inode, bh, imap, offset); - set_buffer_mapped(bh); - clear_buffer_delay(bh); - clear_buffer_unwritten(bh); - - /* - * If this is a realtime file, data may be on a different device. - * to that pointed to from the buffer_head b_bdev currently. We can't - * trust that the bufferhead has a already been mapped correctly, so - * set the bdev now. - */ - bh->b_bdev = xfs_find_bdev_for_inode(inode); - bh->b_end_io = NULL; - set_buffer_async_write(bh); - set_buffer_uptodate(bh); - clear_buffer_dirty(bh); -} - STATIC void xfs_vm_invalidatepage( struct page *page, unsigned int offset, unsigned int length) { - trace_xfs_invalidatepage(page->mapping->host, page, offset, - length); - - /* - * If we are invalidating the entire page, clear the dirty state from it - * so that we can check for attempts to release dirty cached pages in - * xfs_vm_releasepage(). - */ - if (offset == 0 && length >= PAGE_SIZE) - cancel_dirty_page(page); - block_invalidatepage(page, offset, length); + trace_xfs_invalidatepage(page->mapping->host, page, offset, length); + iomap_invalidatepage(page, offset, length); } /* - * If the page has delalloc buffers on it, we need to punch them out before we - * invalidate the page. If we don't, we leave a stale delalloc mapping on the - * inode that can trip a BUG() in xfs_get_blocks() later on if a direct IO read - * is done on that same region - the delalloc extent is returned when none is - * supposed to be there. + * If the page has delalloc blocks on it, we need to punch them out before we + * invalidate the page. If we don't, we leave a stale delalloc mapping on the + * inode that can trip up a later direct I/O read operation on the same region. * - * We prevent this by truncating away the delalloc regions on the page before - * invalidating it. Because they are delalloc, we can do this without needing a - * transaction. Indeed - if we get ENOSPC errors, we have to be able to do this - * truncation without a transaction as there is no space left for block - * reservation (typically why we see a ENOSPC in writeback). + * We prevent this by truncating away the delalloc regions on the page. Because + * they are delalloc, we can do this without needing a transaction. Indeed - if + * we get ENOSPC errors, we have to be able to do this truncation without a + * transaction as there is no space left for block reservation (typically why we + * see a ENOSPC in writeback). */ STATIC void xfs_aops_discard_page( @@ -786,7 +648,7 @@ out_invalidate: * We implement an immediate ioend submission policy here to avoid needing to * chain multiple ioends and hence nest mempool allocations which can violate * forward progress guarantees we need to provide. The current ioend we are - * adding buffers to is cached on the writepage context, and if the new buffer + * adding blocks to is cached on the writepage context, and if the new block * does not append to the cached ioend it will create a new ioend and cache that * instead. * @@ -807,54 +669,33 @@ xfs_writepage_map( uint64_t end_offset) { LIST_HEAD(submit_list); + struct iomap_page *iop = to_iomap_page(page); + unsigned len = i_blocksize(inode); struct xfs_ioend *ioend, *next; - struct buffer_head *bh = NULL; - ssize_t len = i_blocksize(inode); uint64_t file_offset; /* file offset of page */ - unsigned poffset; /* offset into page */ - int error = 0; - int count = 0; + int error = 0, count = 0, i; - if (page_has_buffers(page)) - bh = page_buffers(page); + ASSERT(iop || i_blocksize(inode) == PAGE_SIZE); + ASSERT(!iop || atomic_read(&iop->write_count) == 0); /* - * Walk the blocks on the page, and if we run off the end of the current - * map or find the current map invalid, grab a new one. We only use - * bufferheads here to check per-block state - they no longer control - * the iteration through the page. This allows us to replace the - * bufferhead with some other state tracking mechanism in future. + * Walk through the page to find areas to write back. If we run off the + * end of the current map or find the current map invalid, grab a new + * one. */ - for (poffset = 0, file_offset = page_offset(page); - poffset < PAGE_SIZE; - poffset += len, file_offset += len) { - /* past the range we are writing, so nothing more to write. */ - if (file_offset >= end_offset) - break; - - if (bh && !buffer_uptodate(bh)) { - if (PageUptodate(page)) - ASSERT(buffer_mapped(bh)); - bh = bh->b_this_page; + for (i = 0, file_offset = page_offset(page); + i < (PAGE_SIZE >> inode->i_blkbits) && file_offset < end_offset; + i++, file_offset += len) { + if (iop && !test_bit(i, iop->uptodate)) continue; - } error = xfs_map_blocks(wpc, inode, file_offset); if (error) break; - - if (wpc->io_type == XFS_IO_HOLE) { - if (bh) - bh = bh->b_this_page; + if (wpc->io_type == XFS_IO_HOLE) continue; - } - - if (bh) { - xfs_map_at_offset(inode, bh, &wpc->imap, file_offset); - bh = bh->b_this_page; - } - xfs_add_to_ioend(inode, file_offset, page, wpc, wbc, - &submit_list); + xfs_add_to_ioend(inode, file_offset, page, iop, wpc, wbc, + &submit_list); count++; } @@ -863,21 +704,18 @@ xfs_writepage_map( ASSERT(!PageWriteback(page)); /* - * On error, we have to fail the ioend here because we have locked - * buffers in the ioend. If we don't do this, we'll deadlock - * invalidating the page as that tries to lock the buffers on the page. - * Also, because we may have set pages under writeback, we have to make - * sure we run IO completion to mark the error state of the IO - * appropriately, so we can't cancel the ioend directly here. That means - * we have to mark this page as under writeback if we included any - * buffers from it in the ioend chain so that completion treats it - * correctly. + * On error, we have to fail the ioend here because we may have set + * pages under writeback, we have to make sure we run IO completion to + * mark the error state of the IO appropriately, so we can't cancel the + * ioend directly here. That means we have to mark this page as under + * writeback if we included any blocks from it in the ioend chain so + * that completion treats it correctly. * * If we didn't include the page in the ioend, the on error we can * simply discard and unlock it as there are no other users of the page - * or it's buffers right now. The caller will still need to trigger - * submission of outstanding ioends on the writepage context so they are - * treated correctly on error. + * now. The caller will still need to trigger submission of outstanding + * ioends on the writepage context so they are treated correctly on + * error. */ if (unlikely(error)) { if (!count) { @@ -918,8 +756,8 @@ xfs_writepage_map( } /* - * We can end up here with no error and nothing to write if we race with - * a partial page truncate on a sub-page block sized filesystem. + * We can end up here with no error and nothing to write only if we race + * with a partial page truncate on a sub-page block sized filesystem. */ if (!count) end_page_writeback(page); @@ -934,7 +772,6 @@ done: * For delalloc space on the page we need to allocate space and flush it. * For unwritten space on the page we need to start the conversion to * regular allocated space. - * For any other dirty buffer heads on the page we should flush them. */ STATIC int xfs_do_writepage( @@ -1088,166 +925,13 @@ xfs_dax_writepages( xfs_find_bdev_for_inode(mapping->host), wbc); } -/* - * Called to move a page into cleanable state - and from there - * to be released. The page should already be clean. We always - * have buffer heads in this call. - * - * Returns 1 if the page is ok to release, 0 otherwise. - */ STATIC int xfs_vm_releasepage( struct page *page, gfp_t gfp_mask) { - int delalloc, unwritten; - trace_xfs_releasepage(page->mapping->host, page, 0, 0); - - /* - * mm accommodates an old ext3 case where clean pages might not have had - * the dirty bit cleared. Thus, it can send actual dirty pages to - * ->releasepage() via shrink_active_list(). Conversely, - * block_invalidatepage() can send pages that are still marked dirty but - * otherwise have invalidated buffers. - * - * We want to release the latter to avoid unnecessary buildup of the - * LRU, so xfs_vm_invalidatepage() clears the page dirty flag on pages - * that are entirely invalidated and need to be released. Hence the - * only time we should get dirty pages here is through - * shrink_active_list() and so we can simply skip those now. - * - * warn if we've left any lingering delalloc/unwritten buffers on clean - * or invalidated pages we are about to release. - */ - if (PageDirty(page)) - return 0; - - xfs_count_page_state(page, &delalloc, &unwritten); - - if (WARN_ON_ONCE(delalloc)) - return 0; - if (WARN_ON_ONCE(unwritten)) - return 0; - - return try_to_free_buffers(page); -} - -/* - * If this is O_DIRECT or the mpage code calling tell them how large the mapping - * is, so that we can avoid repeated get_blocks calls. - * - * If the mapping spans EOF, then we have to break the mapping up as the mapping - * for blocks beyond EOF must be marked new so that sub block regions can be - * correctly zeroed. We can't do this for mappings within EOF unless the mapping - * was just allocated or is unwritten, otherwise the callers would overwrite - * existing data with zeros. Hence we have to split the mapping into a range up - * to and including EOF, and a second mapping for beyond EOF. - */ -static void -xfs_map_trim_size( - struct inode *inode, - sector_t iblock, - struct buffer_head *bh_result, - struct xfs_bmbt_irec *imap, - xfs_off_t offset, - ssize_t size) -{ - xfs_off_t mapping_size; - - mapping_size = imap->br_startoff + imap->br_blockcount - iblock; - mapping_size <<= inode->i_blkbits; - - ASSERT(mapping_size > 0); - if (mapping_size > size) - mapping_size = size; - if (offset < i_size_read(inode) && - (xfs_ufsize_t)offset + mapping_size >= i_size_read(inode)) { - /* limit mapping to block that spans EOF */ - mapping_size = roundup_64(i_size_read(inode) - offset, - i_blocksize(inode)); - } - if (mapping_size > LONG_MAX) - mapping_size = LONG_MAX; - - bh_result->b_size = mapping_size; -} - -static int -xfs_get_blocks( - struct inode *inode, - sector_t iblock, - struct buffer_head *bh_result, - int create) -{ - struct xfs_inode *ip = XFS_I(inode); - struct xfs_mount *mp = ip->i_mount; - xfs_fileoff_t offset_fsb, end_fsb; - int error = 0; - int lockmode = 0; - struct xfs_bmbt_irec imap; - int nimaps = 1; - xfs_off_t offset; - ssize_t size; - - BUG_ON(create); - - if (XFS_FORCED_SHUTDOWN(mp)) - return -EIO; - - offset = (xfs_off_t)iblock << inode->i_blkbits; - ASSERT(bh_result->b_size >= i_blocksize(inode)); - size = bh_result->b_size; - - if (offset >= i_size_read(inode)) - return 0; - - /* - * Direct I/O is usually done on preallocated files, so try getting - * a block mapping without an exclusive lock first. - */ - lockmode = xfs_ilock_data_map_shared(ip); - - ASSERT(offset <= mp->m_super->s_maxbytes); - if (offset > mp->m_super->s_maxbytes - size) - size = mp->m_super->s_maxbytes - offset; - end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + size); - offset_fsb = XFS_B_TO_FSBT(mp, offset); - - error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, &imap, - &nimaps, 0); - if (error) - goto out_unlock; - if (!nimaps) { - trace_xfs_get_blocks_notfound(ip, offset, size); - goto out_unlock; - } - - trace_xfs_get_blocks_found(ip, offset, size, - imap.br_state == XFS_EXT_UNWRITTEN ? - XFS_IO_UNWRITTEN : XFS_IO_OVERWRITE, &imap); - xfs_iunlock(ip, lockmode); - - /* trim mapping down to size requested */ - xfs_map_trim_size(inode, iblock, bh_result, &imap, offset, size); - - /* - * For unwritten extents do not report a disk address in the buffered - * read case (treat as if we're reading into a hole). - */ - if (xfs_bmap_is_real_extent(&imap)) - xfs_map_buffer(inode, bh_result, &imap, offset); - - /* - * If this is a realtime file, data may be on a different device. - * to that pointed to from the buffer_head b_bdev currently. - */ - bh_result->b_bdev = xfs_find_bdev_for_inode(inode); - return 0; - -out_unlock: - xfs_iunlock(ip, lockmode); - return error; + return iomap_releasepage(page, gfp_mask); } STATIC sector_t @@ -1279,9 +963,7 @@ xfs_vm_readpage( struct page *page) { trace_xfs_vm_readpage(page->mapping->host, 1); - if (i_blocksize(page->mapping->host) == PAGE_SIZE) - return iomap_readpage(page, &xfs_iomap_ops); - return mpage_readpage(page, xfs_get_blocks); + return iomap_readpage(page, &xfs_iomap_ops); } STATIC int @@ -1292,65 +974,7 @@ xfs_vm_readpages( unsigned nr_pages) { trace_xfs_vm_readpages(mapping->host, nr_pages); - if (i_blocksize(mapping->host) == PAGE_SIZE) - return iomap_readpages(mapping, pages, nr_pages, &xfs_iomap_ops); - return mpage_readpages(mapping, pages, nr_pages, xfs_get_blocks); -} - -/* - * This is basically a copy of __set_page_dirty_buffers() with one - * small tweak: buffers beyond EOF do not get marked dirty. If we mark them - * dirty, we'll never be able to clean them because we don't write buffers - * beyond EOF, and that means we can't invalidate pages that span EOF - * that have been marked dirty. Further, the dirty state can leak into - * the file interior if the file is extended, resulting in all sorts of - * bad things happening as the state does not match the underlying data. - * - * XXX: this really indicates that bufferheads in XFS need to die. Warts like - * this only exist because of bufferheads and how the generic code manages them. - */ -STATIC int -xfs_vm_set_page_dirty( - struct page *page) -{ - struct address_space *mapping = page->mapping; - struct inode *inode = mapping->host; - loff_t end_offset; - loff_t offset; - int newly_dirty; - - if (unlikely(!mapping)) - return !TestSetPageDirty(page); - - end_offset = i_size_read(inode); - offset = page_offset(page); - - spin_lock(&mapping->private_lock); - if (page_has_buffers(page)) { - struct buffer_head *head = page_buffers(page); - struct buffer_head *bh = head; - - do { - if (offset < end_offset) - set_buffer_dirty(bh); - bh = bh->b_this_page; - offset += i_blocksize(inode); - } while (bh != head); - } - /* - * Lock out page->mem_cgroup migration to keep PageDirty - * synchronized with per-memcg dirty page counters. - */ - lock_page_memcg(page); - newly_dirty = !TestSetPageDirty(page); - spin_unlock(&mapping->private_lock); - - if (newly_dirty) - __set_page_dirty(page, mapping, 1); - unlock_page_memcg(page); - if (newly_dirty) - __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); - return newly_dirty; + return iomap_readpages(mapping, pages, nr_pages, &xfs_iomap_ops); } static int @@ -1368,13 +992,13 @@ const struct address_space_operations xfs_address_space_operations = { .readpages = xfs_vm_readpages, .writepage = xfs_vm_writepage, .writepages = xfs_vm_writepages, - .set_page_dirty = xfs_vm_set_page_dirty, + .set_page_dirty = iomap_set_page_dirty, .releasepage = xfs_vm_releasepage, .invalidatepage = xfs_vm_invalidatepage, .bmap = xfs_vm_bmap, .direct_IO = noop_direct_IO, - .migratepage = buffer_migrate_page, - .is_partially_uptodate = block_is_partially_uptodate, + .migratepage = iomap_migrate_page, + .is_partially_uptodate = iomap_is_partially_uptodate, .error_remove_page = generic_error_remove_page, .swap_activate = xfs_iomap_swapfile_activate, }; diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index d24dbd4dac39..6ddf1907fc7a 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -12,7 +12,6 @@ #include #include #include -#include #include #include diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 7fe42a126ec1..778b8c850de3 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -1032,9 +1032,6 @@ xfs_file_iomap_begin( if (XFS_FORCED_SHUTDOWN(mp)) return -EIO; - if (i_blocksize(inode) < PAGE_SIZE) - iomap->flags |= IOMAP_F_BUFFER_HEAD; - if (((flags & (IOMAP_WRITE | IOMAP_DIRECT)) == IOMAP_WRITE) && !IS_DAX(inode) && !xfs_get_extsz_hint(ip)) { /* Reserve delalloc blocks for regular writeback. */ diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 9d791f158dfe..f9f8dc490d3d 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1860,7 +1860,7 @@ MODULE_ALIAS_FS("xfs"); STATIC int __init xfs_init_zones(void) { - if (bioset_init(&xfs_ioend_bioset, 4 * MAX_BUF_PER_PAGE, + if (bioset_init(&xfs_ioend_bioset, 4 * (PAGE_SIZE / SECTOR_SIZE), offsetof(struct xfs_ioend, io_inline_bio), BIOSET_NEED_BVECS)) goto out; diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 1af123df19b5..7f4c7071e7ed 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -1153,33 +1153,23 @@ DECLARE_EVENT_CLASS(xfs_page_class, __field(loff_t, size) __field(unsigned long, offset) __field(unsigned int, length) - __field(int, delalloc) - __field(int, unwritten) ), TP_fast_assign( - int delalloc = -1, unwritten = -1; - - if (page_has_buffers(page)) - xfs_count_page_state(page, &delalloc, &unwritten); __entry->dev = inode->i_sb->s_dev; __entry->ino = XFS_I(inode)->i_ino; __entry->pgoff = page_offset(page); __entry->size = i_size_read(inode); __entry->offset = off; __entry->length = len; - __entry->delalloc = delalloc; - __entry->unwritten = unwritten; ), TP_printk("dev %d:%d ino 0x%llx pgoff 0x%lx size 0x%llx offset %lx " - "length %x delalloc %d unwritten %d", + "length %x", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->ino, __entry->pgoff, __entry->size, __entry->offset, - __entry->length, - __entry->delalloc, - __entry->unwritten) + __entry->length) ) #define DEFINE_PAGE_EVENT(name) \ @@ -1263,9 +1253,6 @@ DEFINE_EVENT(xfs_imap_class, name, \ TP_ARGS(ip, offset, count, type, irec)) DEFINE_IOMAP_EVENT(xfs_map_blocks_found); DEFINE_IOMAP_EVENT(xfs_map_blocks_alloc); -DEFINE_IOMAP_EVENT(xfs_get_blocks_found); -DEFINE_IOMAP_EVENT(xfs_get_blocks_alloc); -DEFINE_IOMAP_EVENT(xfs_get_blocks_map_direct); DEFINE_IOMAP_EVENT(xfs_iomap_alloc); DEFINE_IOMAP_EVENT(xfs_iomap_found); @@ -1304,7 +1291,6 @@ DEFINE_EVENT(xfs_simple_io_class, name, \ TP_ARGS(ip, offset, count)) DEFINE_SIMPLE_IO_EVENT(xfs_delalloc_enospc); DEFINE_SIMPLE_IO_EVENT(xfs_unwritten_convert); -DEFINE_SIMPLE_IO_EVENT(xfs_get_blocks_notfound); DEFINE_SIMPLE_IO_EVENT(xfs_setfilesize); DEFINE_SIMPLE_IO_EVENT(xfs_zero_eof); DEFINE_SIMPLE_IO_EVENT(xfs_end_io_direct_write); -- cgit v1.2.3 From 98c1a7c0ece345dc8e34c0c85703e4df9fdfd071 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 11 Jul 2018 22:26:06 -0700 Subject: xfs: update my copyrights for the writeback and iomap code Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 1 + fs/xfs/xfs_iomap.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index bae88ac1101d..f4d3252236c1 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. + * Copyright (c) 2016-2018 Christoph Hellwig. * All Rights Reserved. */ #include "xfs.h" diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 778b8c850de3..fb9746cc7338 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2000-2006 Silicon Graphics, Inc. - * Copyright (c) 2016 Christoph Hellwig. + * Copyright (c) 2016-2018 Christoph Hellwig. * All Rights Reserved. */ #include -- cgit v1.2.3 From 8a749386498327c98c2792e19eeeaa21dafc6954 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:06 -0700 Subject: xfs: cow unwritten conversion uses uninitialized dfops A couple COW fork unwritten extent conversion helpers pass an uninitialized dfops pointer to xfs_bmapi_write(). This does not cause problems because conversion does not use a transaction or the dfops structure for the COW fork. Drop the uninitialized usage of dfops in these codepaths and pass NULL along to xfs_bmapi_write() instead. Signed-off-by: Brian Foster Reviewed-by: Carlos Maiolino Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_reflink.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 49e4913fa779..33845009bec5 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -312,8 +312,7 @@ xfs_reflink_convert_cow_extent( struct xfs_inode *ip, struct xfs_bmbt_irec *imap, xfs_fileoff_t offset_fsb, - xfs_filblks_t count_fsb, - struct xfs_defer_ops *dfops) + xfs_filblks_t count_fsb) { xfs_fsblock_t first_block = NULLFSBLOCK; int nimaps = 1; @@ -327,7 +326,7 @@ xfs_reflink_convert_cow_extent( return 0; return xfs_bmapi_write(NULL, ip, imap->br_startoff, imap->br_blockcount, XFS_BMAPI_COWFORK | XFS_BMAPI_CONVERT, &first_block, - 0, imap, &nimaps, dfops); + 0, imap, &nimaps, NULL); } /* Convert all of the unwritten CoW extents in a file's range to real ones. */ @@ -342,7 +341,6 @@ xfs_reflink_convert_cow( xfs_fileoff_t end_fsb = XFS_B_TO_FSB(mp, offset + count); xfs_filblks_t count_fsb = end_fsb - offset_fsb; struct xfs_bmbt_irec imap; - struct xfs_defer_ops dfops; xfs_fsblock_t first_block = NULLFSBLOCK; int nimaps = 1, error = 0; @@ -352,7 +350,7 @@ xfs_reflink_convert_cow( error = xfs_bmapi_write(NULL, ip, offset_fsb, count_fsb, XFS_BMAPI_COWFORK | XFS_BMAPI_CONVERT | XFS_BMAPI_CONVERT_ONLY, &first_block, 0, &imap, &nimaps, - &dfops); + NULL); xfs_iunlock(ip, XFS_ILOCK_EXCL); return error; } @@ -458,8 +456,7 @@ retry: if (nimaps == 0) return -ENOSPC; convert: - return xfs_reflink_convert_cow_extent(ip, imap, offset_fsb, count_fsb, - &dfops); + return xfs_reflink_convert_cow_extent(ip, imap, offset_fsb, count_fsb); out_bmap_cancel: xfs_defer_cancel(&dfops); xfs_trans_unreserve_quota_nblks(tp, ip, (long)resblks, 0, -- cgit v1.2.3 From 6aa6718439ac6907b3c34cbe7ac2c71408f84f6e Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:07 -0700 Subject: xfs: rename xfs_trans ->t_agfl_dfops to ->t_dfops The ->t_agfl_dfops field is currently used to defer agfl block frees from associated transaction contexts. While all known problematic contexts have already been updated to use ->t_agfl_dfops, the broader goal is defer agfl frees from all callers that already use a deferred operations structure. Further, the transaction field facilitates a good amount of code clean up where the transaction and dfops have historically been passed down through the stack separately. Rename the field to something more generic to prepare to use it as such throughout XFS. This patch does not change behavior. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_alloc.c | 4 ++-- fs/xfs/libxfs/xfs_defer.c | 8 ++++---- fs/xfs/xfs_inode.c | 10 +++++----- fs/xfs/xfs_symlink.c | 2 +- fs/xfs/xfs_trans.c | 6 +++--- fs/xfs/xfs_trans.h | 2 +- 6 files changed, 16 insertions(+), 16 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index eef466260d43..5b1607d76fe9 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -2323,8 +2323,8 @@ xfs_alloc_fix_freelist( goto out_agbp_relse; /* defer agfl frees if dfops is provided */ - if (tp->t_agfl_dfops) { - xfs_defer_agfl_block(mp, tp->t_agfl_dfops, args->agno, + if (tp->t_dfops) { + xfs_defer_agfl_block(mp, tp->t_dfops, args->agno, bno, &targs.oinfo); } else { error = xfs_free_agfl_block(tp, args->agno, bno, agbp, diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index c3e5bffda4f5..560a7d178c1e 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -350,9 +350,9 @@ xfs_defer_finish( * Note that this code can go away once all dfops users attach to the * associated tp. */ - ASSERT(!(*tp)->t_agfl_dfops || ((*tp)->t_agfl_dfops == dop)); - orig_dop = (*tp)->t_agfl_dfops; - (*tp)->t_agfl_dfops = dop; + ASSERT(!(*tp)->t_dfops || ((*tp)->t_dfops == dop)); + orig_dop = (*tp)->t_dfops; + (*tp)->t_dfops = dop; /* Until we run out of pending work to finish... */ while (xfs_defer_has_unfinished_work(dop)) { @@ -425,7 +425,7 @@ xfs_defer_finish( } out: - (*tp)->t_agfl_dfops = orig_dop; + (*tp)->t_dfops = orig_dop; if (error) trace_xfs_defer_finish_error((*tp)->t_mountp, dop, error); else diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 5df4de666cc1..9c5fbc94cf14 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1196,7 +1196,7 @@ xfs_create( unlock_dp_on_error = true; xfs_defer_init(&dfops, &first_block); - tp->t_agfl_dfops = &dfops; + tp->t_dfops = &dfops; /* * Reserve disk quota and the inode. @@ -1452,7 +1452,7 @@ xfs_link( } xfs_defer_init(&dfops, &first_block); - tp->t_agfl_dfops = &dfops; + tp->t_dfops = &dfops; /* * Handle initial link state of O_TMPFILE inode @@ -1813,7 +1813,7 @@ xfs_inactive_ifree( xfs_trans_ijoin(tp, ip, 0); xfs_defer_init(&dfops, &first_block); - tp->t_agfl_dfops = &dfops; + tp->t_dfops = &dfops; error = xfs_ifree(tp, ip, &dfops); if (error) { /* @@ -2659,7 +2659,7 @@ xfs_remove( goto out_trans_cancel; xfs_defer_init(&dfops, &first_block); - tp->t_agfl_dfops = &dfops; + tp->t_dfops = &dfops; error = xfs_dir_removename(tp, dp, name, ip->i_ino, &first_block, &dfops, resblks); if (error) { @@ -3027,7 +3027,7 @@ xfs_rename( } xfs_defer_init(&dfops, &first_block); - tp->t_agfl_dfops = &dfops; + tp->t_dfops = &dfops; /* RENAME_EXCHANGE is unique from here on. */ if (flags & RENAME_EXCHANGE) diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 3783afcb68d2..44335bdebea2 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -247,7 +247,7 @@ xfs_symlink( * bmapi or the directory create code. */ xfs_defer_init(&dfops, &first_block); - tp->t_agfl_dfops = &dfops; + tp->t_dfops = &dfops; /* * Allocate an inode for the symlink. diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 524f543c5b82..630993387517 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -118,7 +118,7 @@ xfs_trans_dup( ntp->t_rtx_res = tp->t_rtx_res - tp->t_rtx_res_used; tp->t_rtx_res = tp->t_rtx_res_used; ntp->t_pflags = tp->t_pflags; - ntp->t_agfl_dfops = tp->t_agfl_dfops; + ntp->t_dfops = tp->t_dfops; xfs_trans_dup_dqinfo(tp, ntp); @@ -914,8 +914,8 @@ __xfs_trans_commit( int error = 0; int sync = tp->t_flags & XFS_TRANS_SYNC; - ASSERT(!tp->t_agfl_dfops || - !xfs_defer_has_unfinished_work(tp->t_agfl_dfops) || regrant); + ASSERT(!tp->t_dfops || + !xfs_defer_has_unfinished_work(tp->t_dfops) || regrant); trace_xfs_trans_commit(tp, _RET_IP_); diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 6526314f0b8f..d8a695c57103 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -105,7 +105,7 @@ typedef struct xfs_trans { struct xlog_ticket *t_ticket; /* log mgr ticket */ struct xfs_mount *t_mountp; /* ptr to fs mount struct */ struct xfs_dquot_acct *t_dqinfo; /* acctg info for dquots */ - struct xfs_defer_ops *t_agfl_dfops; /* optional agfl fixup dfops */ + struct xfs_defer_ops *t_dfops; /* dfops reference */ unsigned int t_flags; /* misc flags */ int64_t t_icount_delta; /* superblock icount change */ int64_t t_ifree_delta; /* superblock ifree change */ -- cgit v1.2.3 From 0e0417f3e54668cec9f677850130e6fbb64edcf2 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:07 -0700 Subject: xfs: remove dfops parameter from ifree call stack The inode free callchain starting in xfs_inactive_ifree() already associates its dfops with the transaction. It still passes the dfops on the stack down through xfs_difree_inobt(), however. Clean up the call stack and reference dfops directly from the transaction. This patch does not change behavior. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_ialloc.c | 6 ++---- fs/xfs/libxfs/xfs_ialloc.h | 1 - fs/xfs/xfs_inode.c | 9 ++++----- fs/xfs/xfs_inode.h | 3 +-- 4 files changed, 7 insertions(+), 12 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 0d968e8143aa..c38d14106b53 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -1915,7 +1915,6 @@ xfs_difree_inobt( struct xfs_trans *tp, struct xfs_buf *agbp, xfs_agino_t agino, - struct xfs_defer_ops *dfops, struct xfs_icluster *xic, struct xfs_inobt_rec_incore *orec) { @@ -2003,7 +2002,7 @@ xfs_difree_inobt( goto error0; } - xfs_difree_inode_chunk(mp, agno, &rec, dfops); + xfs_difree_inode_chunk(mp, agno, &rec, tp->t_dfops); } else { xic->deleted = false; @@ -2148,7 +2147,6 @@ int xfs_difree( struct xfs_trans *tp, /* transaction pointer */ xfs_ino_t inode, /* inode to be freed */ - struct xfs_defer_ops *dfops, /* extents to free */ struct xfs_icluster *xic) /* cluster info if deleted */ { /* REFERENCED */ @@ -2200,7 +2198,7 @@ xfs_difree( /* * Fix up the inode allocation btree. */ - error = xfs_difree_inobt(mp, tp, agbp, agino, dfops, xic, &rec); + error = xfs_difree_inobt(mp, tp, agbp, agino, xic, &rec); if (error) goto error0; diff --git a/fs/xfs/libxfs/xfs_ialloc.h b/fs/xfs/libxfs/xfs_ialloc.h index 90b09c5f163b..e936b7cc9389 100644 --- a/fs/xfs/libxfs/xfs_ialloc.h +++ b/fs/xfs/libxfs/xfs_ialloc.h @@ -82,7 +82,6 @@ int /* error */ xfs_difree( struct xfs_trans *tp, /* transaction pointer */ xfs_ino_t inode, /* inode to be freed */ - struct xfs_defer_ops *dfops, /* extents to free */ struct xfs_icluster *ifree); /* cluster info if deleted */ /* diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 9c5fbc94cf14..f5649a023d46 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1814,7 +1814,7 @@ xfs_inactive_ifree( xfs_defer_init(&dfops, &first_block); tp->t_dfops = &dfops; - error = xfs_ifree(tp, ip, &dfops); + error = xfs_ifree(tp, ip); if (error) { /* * If we fail to free the inode, shut down. The cancel @@ -2445,9 +2445,8 @@ xfs_ifree_local_data( */ int xfs_ifree( - xfs_trans_t *tp, - xfs_inode_t *ip, - struct xfs_defer_ops *dfops) + struct xfs_trans *tp, + struct xfs_inode *ip) { int error; struct xfs_icluster xic = { 0 }; @@ -2466,7 +2465,7 @@ xfs_ifree( if (error) return error; - error = xfs_difree(tp, ip->i_ino, dfops, &xic); + error = xfs_difree(tp, ip->i_ino, &xic); if (error) return error; diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 2ed63a49e890..b1f0e8394f3b 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -415,8 +415,7 @@ uint xfs_ilock_data_map_shared(struct xfs_inode *); uint xfs_ilock_attr_map_shared(struct xfs_inode *); uint xfs_ip2xflags(struct xfs_inode *); -int xfs_ifree(struct xfs_trans *, xfs_inode_t *, - struct xfs_defer_ops *); +int xfs_ifree(struct xfs_trans *, struct xfs_inode *); int xfs_itruncate_extents_flags(struct xfs_trans **, struct xfs_inode *, int, xfs_fsize_t, int); void xfs_iext_realloc(xfs_inode_t *, int, int); -- cgit v1.2.3 From c9cfdb381172174ade2445e7b468f1be550b1a44 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:08 -0700 Subject: xfs: remove dfops param from high level dirname calls All callers of the directory create, rename and remove interfaces already associate the dfops with the transaction. Drop the dfops parameters in these calls in preparation for further cleanups in the layers below. This patch does not change behavior. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_dir2.c | 17 ++++++++-------- fs/xfs/libxfs/xfs_dir2.h | 9 +++------ fs/xfs/xfs_inode.c | 50 ++++++++++++++++++++++-------------------------- fs/xfs/xfs_symlink.c | 2 +- 4 files changed, 36 insertions(+), 42 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 59169aff30fe..c98250f0de50 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -244,7 +244,6 @@ xfs_dir_createname( struct xfs_name *name, xfs_ino_t inum, /* new entry inode number */ xfs_fsblock_t *first, /* bmap's firstblock */ - struct xfs_defer_ops *dfops, /* bmap's freeblock list */ xfs_extlen_t total) /* bmap's total block count */ { struct xfs_da_args *args; @@ -252,6 +251,8 @@ xfs_dir_createname( int v; /* type-checking value */ ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); + ASSERT(tp->t_dfops || !first); + if (inum) { rval = xfs_dir_ino_validate(tp->t_mountp, inum); if (rval) @@ -270,11 +271,11 @@ xfs_dir_createname( args->hashval = dp->i_mount->m_dirnameops->hashname(name); args->inumber = inum; args->dp = dp; - args->firstblock = first; - args->dfops = dfops; args->total = total; args->whichfork = XFS_DATA_FORK; args->trans = tp; + args->dfops = tp->t_dfops; + args->firstblock = first; args->op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; if (!inum) args->op_flags |= XFS_DA_OP_JUSTCHECK; @@ -421,7 +422,6 @@ xfs_dir_removename( struct xfs_name *name, xfs_ino_t ino, xfs_fsblock_t *first, /* bmap's firstblock */ - struct xfs_defer_ops *dfops, /* bmap's freeblock list */ xfs_extlen_t total) /* bmap's total block count */ { struct xfs_da_args *args; @@ -429,6 +429,7 @@ xfs_dir_removename( int v; /* type-checking value */ ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); + ASSERT(tp->t_dfops); XFS_STATS_INC(dp->i_mount, xs_dir_remove); args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS); @@ -443,10 +444,10 @@ xfs_dir_removename( args->inumber = ino; args->dp = dp; args->firstblock = first; - args->dfops = dfops; args->total = total; args->whichfork = XFS_DATA_FORK; args->trans = tp; + args->dfops = tp->t_dfops; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { rval = xfs_dir2_sf_removename(args); @@ -483,7 +484,6 @@ xfs_dir_replace( struct xfs_name *name, /* name of entry to replace */ xfs_ino_t inum, /* new inode number */ xfs_fsblock_t *first, /* bmap's firstblock */ - struct xfs_defer_ops *dfops, /* bmap's freeblock list */ xfs_extlen_t total) /* bmap's total block count */ { struct xfs_da_args *args; @@ -491,6 +491,7 @@ xfs_dir_replace( int v; /* type-checking value */ ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); + ASSERT(tp->t_dfops); rval = xfs_dir_ino_validate(tp->t_mountp, inum); if (rval) @@ -508,10 +509,10 @@ xfs_dir_replace( args->inumber = inum; args->dp = dp; args->firstblock = first; - args->dfops = dfops; args->total = total; args->whichfork = XFS_DATA_FORK; args->trans = tp; + args->dfops = tp->t_dfops; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { rval = xfs_dir2_sf_replace(args); @@ -547,7 +548,7 @@ xfs_dir_canenter( xfs_inode_t *dp, struct xfs_name *name) /* name of entry to add */ { - return xfs_dir_createname(tp, dp, name, 0, NULL, NULL, 0); + return xfs_dir_createname(tp, dp, name, 0, NULL, 0); } /* diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index ed385316c7dc..f203aebc07ed 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -118,19 +118,16 @@ extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_inode *pdp); extern int xfs_dir_createname(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_name *name, xfs_ino_t inum, - xfs_fsblock_t *first, - struct xfs_defer_ops *dfops, xfs_extlen_t tot); + xfs_fsblock_t *first, xfs_extlen_t tot); extern int xfs_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_name *name, xfs_ino_t *inum, struct xfs_name *ci_name); extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_name *name, xfs_ino_t ino, - xfs_fsblock_t *first, - struct xfs_defer_ops *dfops, xfs_extlen_t tot); + xfs_fsblock_t *first, xfs_extlen_t tot); extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_name *name, xfs_ino_t inum, - xfs_fsblock_t *first, - struct xfs_defer_ops *dfops, xfs_extlen_t tot); + xfs_fsblock_t *first, xfs_extlen_t tot); extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_name *name); diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index f5649a023d46..e1bc686b70b4 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1225,8 +1225,8 @@ xfs_create( xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); unlock_dp_on_error = false; - error = xfs_dir_createname(tp, dp, name, ip->i_ino, - &first_block, &dfops, resblks ? + error = xfs_dir_createname(tp, dp, name, ip->i_ino, &first_block, + resblks ? resblks - XFS_IALLOC_SPACE_RES(mp) : 0); if (error) { ASSERT(error != -ENOSPC); @@ -1464,7 +1464,7 @@ xfs_link( } error = xfs_dir_createname(tp, tdp, target_name, sip->i_ino, - &first_block, &dfops, resblks); + &first_block, resblks); if (error) goto error_return; xfs_trans_ichgtime(tp, tdp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); @@ -2659,8 +2659,8 @@ xfs_remove( xfs_defer_init(&dfops, &first_block); tp->t_dfops = &dfops; - error = xfs_dir_removename(tp, dp, name, ip->i_ino, - &first_block, &dfops, resblks); + error = xfs_dir_removename(tp, dp, name, ip->i_ino, &first_block, + resblks); if (error) { ASSERT(error != -ENOENT); goto out_bmap_cancel; @@ -2748,9 +2748,9 @@ xfs_sort_for_rename( static int xfs_finish_rename( - struct xfs_trans *tp, - struct xfs_defer_ops *dfops) + struct xfs_trans *tp) { + struct xfs_defer_ops *dfops = tp->t_dfops; int error; /* @@ -2784,7 +2784,6 @@ xfs_cross_rename( struct xfs_inode *dp2, struct xfs_name *name2, struct xfs_inode *ip2, - struct xfs_defer_ops *dfops, xfs_fsblock_t *first_block, int spaceres) { @@ -2794,16 +2793,14 @@ xfs_cross_rename( int dp2_flags = 0; /* Swap inode number for dirent in first parent */ - error = xfs_dir_replace(tp, dp1, name1, - ip2->i_ino, - first_block, dfops, spaceres); + error = xfs_dir_replace(tp, dp1, name1, ip2->i_ino, first_block, + spaceres); if (error) goto out_trans_abort; /* Swap inode number for dirent in second parent */ - error = xfs_dir_replace(tp, dp2, name2, - ip1->i_ino, - first_block, dfops, spaceres); + error = xfs_dir_replace(tp, dp2, name2, ip1->i_ino, first_block, + spaceres); if (error) goto out_trans_abort; @@ -2818,7 +2815,7 @@ xfs_cross_rename( if (S_ISDIR(VFS_I(ip2)->i_mode)) { error = xfs_dir_replace(tp, ip2, &xfs_name_dotdot, dp1->i_ino, first_block, - dfops, spaceres); + spaceres); if (error) goto out_trans_abort; @@ -2845,7 +2842,7 @@ xfs_cross_rename( if (S_ISDIR(VFS_I(ip1)->i_mode)) { error = xfs_dir_replace(tp, ip1, &xfs_name_dotdot, dp2->i_ino, first_block, - dfops, spaceres); + spaceres); if (error) goto out_trans_abort; @@ -2884,10 +2881,10 @@ xfs_cross_rename( } xfs_trans_ichgtime(tp, dp1, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); xfs_trans_log_inode(tp, dp1, XFS_ILOG_CORE); - return xfs_finish_rename(tp, dfops); + return xfs_finish_rename(tp); out_trans_abort: - xfs_defer_cancel(dfops); + xfs_defer_cancel(tp->t_dfops); xfs_trans_cancel(tp); return error; } @@ -3032,7 +3029,7 @@ xfs_rename( if (flags & RENAME_EXCHANGE) return xfs_cross_rename(tp, src_dp, src_name, src_ip, target_dp, target_name, target_ip, - &dfops, &first_block, spaceres); + &first_block, spaceres); /* * Set up the target. @@ -3054,7 +3051,7 @@ xfs_rename( */ error = xfs_dir_createname(tp, target_dp, target_name, src_ip->i_ino, &first_block, - &dfops, spaceres); + spaceres); if (error) goto out_bmap_cancel; @@ -3093,8 +3090,7 @@ xfs_rename( * name at the destination directory, remove it first. */ error = xfs_dir_replace(tp, target_dp, target_name, - src_ip->i_ino, - &first_block, &dfops, spaceres); + src_ip->i_ino, &first_block, spaceres); if (error) goto out_bmap_cancel; @@ -3128,8 +3124,8 @@ xfs_rename( * directory. */ error = xfs_dir_replace(tp, src_ip, &xfs_name_dotdot, - target_dp->i_ino, - &first_block, &dfops, spaceres); + target_dp->i_ino, &first_block, + spaceres); ASSERT(error != -EEXIST); if (error) goto out_bmap_cancel; @@ -3168,10 +3164,10 @@ xfs_rename( */ if (wip) { error = xfs_dir_replace(tp, src_dp, src_name, wip->i_ino, - &first_block, &dfops, spaceres); + &first_block, spaceres); } else error = xfs_dir_removename(tp, src_dp, src_name, src_ip->i_ino, - &first_block, &dfops, spaceres); + &first_block, spaceres); if (error) goto out_bmap_cancel; @@ -3206,7 +3202,7 @@ xfs_rename( if (new_parent) xfs_trans_log_inode(tp, target_dp, XFS_ILOG_CORE); - error = xfs_finish_rename(tp, &dfops); + error = xfs_finish_rename(tp); if (wip) IRELE(wip); return error; diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 44335bdebea2..e347a3db018f 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -339,7 +339,7 @@ xfs_symlink( * Create the directory entry for the symlink. */ error = xfs_dir_createname(tp, dp, link_name, ip->i_ino, - &first_block, &dfops, resblks); + &first_block, resblks); if (error) goto out_bmap_cancel; xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); -- cgit v1.2.3 From 813d08cb6de0af43da40393aebff914d2de9e50e Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:09 -0700 Subject: xfs: use ->t_dfops for recovery of [b|c]ui log items Log recovery passes down a central dfops structure to recovery handlers for bui and cui log items. Each of these handlers allocates and commits a transaction and defers any remaining operations to be completed by the main recovery sequence. Since dfops outlives the transaction in this context, set and clear ->t_dfops appropriately such that the *_finish_item() paths and below (i.e., xfs_bmapi*()) can expect to find the dfops in the transaction without it being committed with the dfops attached. This is required because transaction commit expects that an associated dfops is finished and in this context the dfops may be populated at commit time. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_bmap_item.c | 8 ++++++++ fs/xfs/xfs_refcount_item.c | 8 ++++++++ 2 files changed, 16 insertions(+) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c index 956ebd583e27..478bfc798861 100644 --- a/fs/xfs/xfs_bmap_item.c +++ b/fs/xfs/xfs_bmap_item.c @@ -441,6 +441,7 @@ xfs_bui_recover( XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK), 0, 0, &tp); if (error) return error; + tp->t_dfops = dfops; budp = xfs_trans_get_bud(tp, buip); /* Grab the inode. */ @@ -487,6 +488,12 @@ xfs_bui_recover( } set_bit(XFS_BUI_RECOVERED, &buip->bui_flags); + /* + * Recovery finishes all deferred ops once intent processing is + * complete. Reset the trans reference because commit expects a finished + * dfops or none at all. + */ + tp->t_dfops = NULL; error = xfs_trans_commit(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); IRELE(ip); @@ -494,6 +501,7 @@ xfs_bui_recover( return error; err_inode: + tp->t_dfops = NULL; xfs_trans_cancel(tp); if (ip) { xfs_iunlock(ip, XFS_ILOCK_EXCL); diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c index 472a73e9d331..2064c689bc72 100644 --- a/fs/xfs/xfs_refcount_item.c +++ b/fs/xfs/xfs_refcount_item.c @@ -452,6 +452,7 @@ xfs_cui_recover( mp->m_refc_maxlevels * 2, 0, XFS_TRANS_RESERVE, &tp); if (error) return error; + tp->t_dfops = dfops; cudp = xfs_trans_get_cud(tp, cuip); for (i = 0; i < cuip->cui_format.cui_nextents; i++) { @@ -514,11 +515,18 @@ xfs_cui_recover( xfs_refcount_finish_one_cleanup(tp, rcur, error); set_bit(XFS_CUI_RECOVERED, &cuip->cui_flags); + /* + * Recovery finishes all deferred ops once intent processing is + * complete. Reset the trans reference because commit expects a finished + * dfops or none at all. + */ + tp->t_dfops = NULL; error = xfs_trans_commit(tp); return error; abort_error: xfs_refcount_finish_one_cleanup(tp, rcur, error); + tp->t_dfops = NULL; xfs_trans_cancel(tp); return error; } -- cgit v1.2.3 From 40d03ac6aa2bebe05190462734690472310167e4 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:09 -0700 Subject: xfs: use ->t_dfops for attr set/remove operations Attach the local dfops to the transaction allocated for xattr add and remove operations. Add an earlier initialization in xfs_attr_remove() to ensure the structure is valid if it remains unused at transaction commit time. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr.c | 11 +++++++---- fs/xfs/libxfs/xfs_bmap.c | 3 ++- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 99590f61d624..cc23c269f2bf 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -254,6 +254,8 @@ xfs_attr_set( rsvd ? XFS_TRANS_RESERVE : 0, &args.trans); if (error) return error; + xfs_defer_init(&dfops, &firstblock); + args.trans->t_dfops = &dfops; xfs_ilock(dp, XFS_ILOCK_EXCL); error = xfs_trans_reserve_quota_nblks(args.trans, dp, args.total, 0, @@ -315,7 +317,6 @@ xfs_attr_set( * It won't fit in the shortform, transform to a leaf block. * GROT: another possible req'mt for a double-split btree op. */ - xfs_defer_init(args.dfops, args.firstblock); error = xfs_attr_shortform_to_leaf(&args, &leaf_bp); if (error) goto out_defer_cancel; @@ -325,9 +326,9 @@ xfs_attr_set( * buffer and run into problems with the write verifier. */ xfs_trans_bhold(args.trans, leaf_bp); - xfs_defer_bjoin(args.dfops, leaf_bp); - xfs_defer_ijoin(args.dfops, dp); - error = xfs_defer_finish(&args.trans, args.dfops); + xfs_defer_bjoin(&dfops, leaf_bp); + xfs_defer_ijoin(&dfops, dp); + error = xfs_defer_finish(&args.trans, &dfops); if (error) goto out_defer_cancel; @@ -429,6 +430,8 @@ xfs_attr_remove( &args.trans); if (error) return error; + xfs_defer_init(&dfops, &firstblock); + args.trans->t_dfops = &dfops; xfs_ilock(dp, XFS_ILOCK_EXCL); /* diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 68ea1f4b9c3f..bc73375769a0 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -1057,6 +1057,8 @@ xfs_bmap_add_attrfork( rsvd ? XFS_TRANS_RESERVE : 0, &tp); if (error) return error; + xfs_defer_init(&dfops, &firstblock); + tp->t_dfops = &dfops; xfs_ilock(ip, XFS_ILOCK_EXCL); error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ? @@ -1104,7 +1106,6 @@ xfs_bmap_add_attrfork( ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP); ip->i_afp->if_flags = XFS_IFEXTENTS; logflags = 0; - xfs_defer_init(&dfops, &firstblock); switch (ip->i_d.di_format) { case XFS_DINODE_FMT_LOCAL: error = xfs_bmap_add_attrfork_local(tp, ip, &firstblock, &dfops, -- cgit v1.2.3 From 0bd6207f836446f9d472f342a0ba3c21fe5e986f Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:10 -0700 Subject: xfs: remove dfops param in attr fork add path Now that the attribute fork add tx carries dfops along with the transaction, it is unnecessary to pass it down the stack. Remove the dfops parameter and access ->t_dfops directly where necessary. This patch does not change behavior. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index bc73375769a0..7a414e7fbbb8 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -918,7 +918,6 @@ xfs_bmap_add_attrfork_btree( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode pointer */ xfs_fsblock_t *firstblock, /* first block allocated */ - struct xfs_defer_ops *dfops, /* blocks to free at commit */ int *flags) /* inode logging flags */ { xfs_btree_cur_t *cur; /* btree cursor */ @@ -931,7 +930,7 @@ xfs_bmap_add_attrfork_btree( *flags |= XFS_ILOG_DBROOT; else { cur = xfs_bmbt_init_cursor(mp, tp, ip, XFS_DATA_FORK); - cur->bc_private.b.dfops = dfops; + cur->bc_private.b.dfops = tp->t_dfops; cur->bc_private.b.firstblock = *firstblock; error = xfs_bmbt_lookup_first(cur, &stat); if (error) @@ -962,7 +961,6 @@ xfs_bmap_add_attrfork_extents( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode pointer */ xfs_fsblock_t *firstblock, /* first block allocated */ - struct xfs_defer_ops *dfops, /* blocks to free at commit */ int *flags) /* inode logging flags */ { xfs_btree_cur_t *cur; /* bmap btree cursor */ @@ -971,7 +969,7 @@ xfs_bmap_add_attrfork_extents( if (ip->i_d.di_nextents * sizeof(xfs_bmbt_rec_t) <= XFS_IFORK_DSIZE(ip)) return 0; cur = NULL; - error = xfs_bmap_extents_to_btree(tp, ip, firstblock, dfops, &cur, 0, + error = xfs_bmap_extents_to_btree(tp, ip, firstblock, tp->t_dfops, &cur, 0, flags, XFS_DATA_FORK); if (cur) { cur->bc_private.b.allocated = 0; @@ -997,7 +995,6 @@ xfs_bmap_add_attrfork_local( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode pointer */ xfs_fsblock_t *firstblock, /* first block allocated */ - struct xfs_defer_ops *dfops, /* blocks to free at commit */ int *flags) /* inode logging flags */ { xfs_da_args_t dargs; /* args for dir/attr code */ @@ -1010,7 +1007,7 @@ xfs_bmap_add_attrfork_local( dargs.geo = ip->i_mount->m_dir_geo; dargs.dp = ip; dargs.firstblock = firstblock; - dargs.dfops = dfops; + dargs.dfops = tp->t_dfops; dargs.total = dargs.geo->fsbcount; dargs.whichfork = XFS_DATA_FORK; dargs.trans = tp; @@ -1108,16 +1105,16 @@ xfs_bmap_add_attrfork( logflags = 0; switch (ip->i_d.di_format) { case XFS_DINODE_FMT_LOCAL: - error = xfs_bmap_add_attrfork_local(tp, ip, &firstblock, &dfops, - &logflags); + error = xfs_bmap_add_attrfork_local(tp, ip, &firstblock, + &logflags); break; case XFS_DINODE_FMT_EXTENTS: error = xfs_bmap_add_attrfork_extents(tp, ip, &firstblock, - &dfops, &logflags); + &logflags); break; case XFS_DINODE_FMT_BTREE: - error = xfs_bmap_add_attrfork_btree(tp, ip, &firstblock, &dfops, - &logflags); + error = xfs_bmap_add_attrfork_btree(tp, ip, &firstblock, + &logflags); break; default: error = 0; -- cgit v1.2.3 From d76e6ce8ed6943941c0c964d8ae43fdaefdcbb5a Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:10 -0700 Subject: xfs: use ->t_dfops in extent split tx and remove param Attach the local dfops to ->t_dfops of the extent split transaction. Since this is the only caller of xfs_bmap_split_extent_at(), remove the dfops parameter as well. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 7a414e7fbbb8..459a29cb17c2 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -5919,8 +5919,7 @@ xfs_bmap_split_extent_at( struct xfs_trans *tp, struct xfs_inode *ip, xfs_fileoff_t split_fsb, - xfs_fsblock_t *firstfsb, - struct xfs_defer_ops *dfops) + xfs_fsblock_t *firstfsb) { int whichfork = XFS_DATA_FORK; struct xfs_btree_cur *cur = NULL; @@ -5970,7 +5969,7 @@ xfs_bmap_split_extent_at( if (ifp->if_flags & XFS_IFBROOT) { cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); cur->bc_private.b.firstblock = *firstfsb; - cur->bc_private.b.dfops = dfops; + cur->bc_private.b.dfops = tp->t_dfops; cur->bc_private.b.flags = 0; error = xfs_bmbt_lookup_eq(cur, &got, &i); if (error) @@ -6014,7 +6013,7 @@ xfs_bmap_split_extent_at( int tmp_logflags; /* partial log flag return val */ ASSERT(cur == NULL); - error = xfs_bmap_extents_to_btree(tp, ip, firstfsb, dfops, + error = xfs_bmap_extents_to_btree(tp, ip, firstfsb, tp->t_dfops, &cur, 0, &tmp_logflags, whichfork); logflags |= tmp_logflags; } @@ -6046,14 +6045,14 @@ xfs_bmap_split_extent( XFS_DIOSTRAT_SPACE_RES(mp, 0), 0, 0, &tp); if (error) return error; + xfs_defer_init(&dfops, &firstfsb); + tp->t_dfops = &dfops; xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); - xfs_defer_init(&dfops, &firstfsb); - error = xfs_bmap_split_extent_at(tp, ip, split_fsb, - &firstfsb, &dfops); + &firstfsb); if (error) goto out; -- cgit v1.2.3 From 32a9b7c65cfc7d9283055fc9d61e6393ee2aa984 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:11 -0700 Subject: xfs: replace xfs_da_args->dfops accesses with ->t_dfops and remove Now that xfs_da_args->dfops is always assigned from a ->t_dfops pointer (or one that is immediately attached), replace all downstream accesses of the former with the latter and remove the field from struct xfs_da_args. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr.c | 103 +++++++++++++++++++++------------------- fs/xfs/libxfs/xfs_attr_leaf.c | 24 +++++----- fs/xfs/libxfs/xfs_attr_remote.c | 23 ++++----- fs/xfs/libxfs/xfs_bmap.c | 1 - fs/xfs/libxfs/xfs_da_btree.c | 19 ++++---- fs/xfs/libxfs/xfs_da_btree.h | 1 - fs/xfs/libxfs/xfs_dir2.c | 65 ++++++++++++------------- 7 files changed, 117 insertions(+), 119 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index cc23c269f2bf..a14ab9b2669e 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -220,7 +220,6 @@ xfs_attr_set( args.value = value; args.valuelen = valuelen; args.firstblock = &firstblock; - args.dfops = &dfops; args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; args.total = xfs_attr_calc_size(&args, &local); @@ -407,7 +406,6 @@ xfs_attr_remove( return error; args.firstblock = &firstblock; - args.dfops = &dfops; /* * we have no control over the attribute names that userspace passes us @@ -539,11 +537,12 @@ xfs_attr_shortform_addname(xfs_da_args_t *args) * if bmap_one_block() says there is only one block (ie: no remote blks). */ STATIC int -xfs_attr_leaf_addname(xfs_da_args_t *args) +xfs_attr_leaf_addname( + struct xfs_da_args *args) { - xfs_inode_t *dp; - struct xfs_buf *bp; - int retval, error, forkoff; + struct xfs_inode *dp; + struct xfs_buf *bp; + int retval, error, forkoff; trace_xfs_attr_leaf_addname(args); @@ -601,12 +600,12 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) * Commit that transaction so that the node_addname() call * can manage its own transactions. */ - xfs_defer_init(args->dfops, args->firstblock); + xfs_defer_init(args->trans->t_dfops, args->firstblock); error = xfs_attr3_leaf_to_node(args); if (error) goto out_defer_cancel; - xfs_defer_ijoin(args->dfops, dp); - error = xfs_defer_finish(&args->trans, args->dfops); + xfs_defer_ijoin(args->trans->t_dfops, dp); + error = xfs_defer_finish(&args->trans, args->trans->t_dfops); if (error) goto out_defer_cancel; @@ -690,13 +689,13 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) * If the result is small enough, shrink it all into the inode. */ if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { - xfs_defer_init(args->dfops, args->firstblock); + xfs_defer_init(args->trans->t_dfops, args->firstblock); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (error) goto out_defer_cancel; - xfs_defer_ijoin(args->dfops, dp); - error = xfs_defer_finish(&args->trans, args->dfops); + xfs_defer_ijoin(args->trans->t_dfops, dp); + error = xfs_defer_finish(&args->trans, args->trans->t_dfops); if (error) goto out_defer_cancel; } @@ -714,7 +713,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) } return error; out_defer_cancel: - xfs_defer_cancel(args->dfops); + xfs_defer_cancel(args->trans->t_dfops); return error; } @@ -725,11 +724,12 @@ out_defer_cancel: * if bmap_one_block() says there is only one block (ie: no remote blks). */ STATIC int -xfs_attr_leaf_removename(xfs_da_args_t *args) +xfs_attr_leaf_removename( + struct xfs_da_args *args) { - xfs_inode_t *dp; - struct xfs_buf *bp; - int error, forkoff; + struct xfs_inode *dp; + struct xfs_buf *bp; + int error, forkoff; trace_xfs_attr_leaf_removename(args); @@ -754,19 +754,19 @@ xfs_attr_leaf_removename(xfs_da_args_t *args) * If the result is small enough, shrink it all into the inode. */ if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { - xfs_defer_init(args->dfops, args->firstblock); + xfs_defer_init(args->trans->t_dfops, args->firstblock); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (error) goto out_defer_cancel; - xfs_defer_ijoin(args->dfops, dp); - error = xfs_defer_finish(&args->trans, args->dfops); + xfs_defer_ijoin(args->trans->t_dfops, dp); + error = xfs_defer_finish(&args->trans, args->trans->t_dfops); if (error) goto out_defer_cancel; } return 0; out_defer_cancel: - xfs_defer_cancel(args->dfops); + xfs_defer_cancel(args->trans->t_dfops); return error; } @@ -817,13 +817,14 @@ xfs_attr_leaf_get(xfs_da_args_t *args) * add a whole extra layer of confusion on top of that. */ STATIC int -xfs_attr_node_addname(xfs_da_args_t *args) +xfs_attr_node_addname( + struct xfs_da_args *args) { - xfs_da_state_t *state; - xfs_da_state_blk_t *blk; - xfs_inode_t *dp; - xfs_mount_t *mp; - int retval, error; + struct xfs_da_state *state; + struct xfs_da_state_blk *blk; + struct xfs_inode *dp; + struct xfs_mount *mp; + int retval, error; trace_xfs_attr_node_addname(args); @@ -882,12 +883,13 @@ restart: */ xfs_da_state_free(state); state = NULL; - xfs_defer_init(args->dfops, args->firstblock); + xfs_defer_init(args->trans->t_dfops, args->firstblock); error = xfs_attr3_leaf_to_node(args); if (error) goto out_defer_cancel; - xfs_defer_ijoin(args->dfops, dp); - error = xfs_defer_finish(&args->trans, args->dfops); + xfs_defer_ijoin(args->trans->t_dfops, dp); + error = xfs_defer_finish(&args->trans, + args->trans->t_dfops); if (error) goto out_defer_cancel; @@ -908,12 +910,12 @@ restart: * in the index/blkno/rmtblkno/rmtblkcnt fields and * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields. */ - xfs_defer_init(args->dfops, args->firstblock); + xfs_defer_init(args->trans->t_dfops, args->firstblock); error = xfs_da3_split(state); if (error) goto out_defer_cancel; - xfs_defer_ijoin(args->dfops, dp); - error = xfs_defer_finish(&args->trans, args->dfops); + xfs_defer_ijoin(args->trans->t_dfops, dp); + error = xfs_defer_finish(&args->trans, args->trans->t_dfops); if (error) goto out_defer_cancel; } else { @@ -1006,12 +1008,12 @@ restart: * Check to see if the tree needs to be collapsed. */ if (retval && (state->path.active > 1)) { - xfs_defer_init(args->dfops, args->firstblock); + xfs_defer_init(args->trans->t_dfops, args->firstblock); error = xfs_da3_join(state); if (error) goto out_defer_cancel; - xfs_defer_ijoin(args->dfops, dp); - error = xfs_defer_finish(&args->trans, args->dfops); + xfs_defer_ijoin(args->trans->t_dfops, dp); + error = xfs_defer_finish(&args->trans, args->trans->t_dfops); if (error) goto out_defer_cancel; } @@ -1040,7 +1042,7 @@ out: return error; return retval; out_defer_cancel: - xfs_defer_cancel(args->dfops); + xfs_defer_cancel(args->trans->t_dfops); goto out; } @@ -1052,13 +1054,14 @@ out_defer_cancel: * the root node (a special case of an intermediate node). */ STATIC int -xfs_attr_node_removename(xfs_da_args_t *args) +xfs_attr_node_removename( + struct xfs_da_args *args) { - xfs_da_state_t *state; - xfs_da_state_blk_t *blk; - xfs_inode_t *dp; - struct xfs_buf *bp; - int retval, error, forkoff; + struct xfs_da_state *state; + struct xfs_da_state_blk *blk; + struct xfs_inode *dp; + struct xfs_buf *bp; + int retval, error, forkoff; trace_xfs_attr_node_removename(args); @@ -1130,12 +1133,12 @@ xfs_attr_node_removename(xfs_da_args_t *args) * Check to see if the tree needs to be collapsed. */ if (retval && (state->path.active > 1)) { - xfs_defer_init(args->dfops, args->firstblock); + xfs_defer_init(args->trans->t_dfops, args->firstblock); error = xfs_da3_join(state); if (error) goto out_defer_cancel; - xfs_defer_ijoin(args->dfops, dp); - error = xfs_defer_finish(&args->trans, args->dfops); + xfs_defer_ijoin(args->trans->t_dfops, dp); + error = xfs_defer_finish(&args->trans, args->trans->t_dfops); if (error) goto out_defer_cancel; /* @@ -1162,13 +1165,13 @@ xfs_attr_node_removename(xfs_da_args_t *args) goto out; if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { - xfs_defer_init(args->dfops, args->firstblock); + xfs_defer_init(args->trans->t_dfops, args->firstblock); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (error) goto out_defer_cancel; - xfs_defer_ijoin(args->dfops, dp); - error = xfs_defer_finish(&args->trans, args->dfops); + xfs_defer_ijoin(args->trans->t_dfops, dp); + error = xfs_defer_finish(&args->trans, args->trans->t_dfops); if (error) goto out_defer_cancel; } else @@ -1180,7 +1183,7 @@ out: xfs_da_state_free(state); return error; out_defer_cancel: - xfs_defer_cancel(args->dfops); + xfs_defer_cancel(args->trans->t_dfops); goto out; } diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index 76e90046731c..c131469db0f1 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -747,18 +747,18 @@ xfs_attr_shortform_getvalue(xfs_da_args_t *args) */ int xfs_attr_shortform_to_leaf( - struct xfs_da_args *args, - struct xfs_buf **leaf_bp) + struct xfs_da_args *args, + struct xfs_buf **leaf_bp) { - xfs_inode_t *dp; - xfs_attr_shortform_t *sf; - xfs_attr_sf_entry_t *sfe; - xfs_da_args_t nargs; - char *tmpbuffer; - int error, i, size; - xfs_dablk_t blkno; - struct xfs_buf *bp; - xfs_ifork_t *ifp; + struct xfs_inode *dp; + struct xfs_attr_shortform *sf; + struct xfs_attr_sf_entry *sfe; + struct xfs_da_args nargs; + char *tmpbuffer; + int error, i, size; + xfs_dablk_t blkno; + struct xfs_buf *bp; + struct xfs_ifork *ifp; trace_xfs_attr_sf_to_leaf(args); @@ -803,7 +803,6 @@ xfs_attr_shortform_to_leaf( nargs.dp = dp; nargs.geo = args->geo; nargs.firstblock = args->firstblock; - nargs.dfops = args->dfops; nargs.total = args->total; nargs.whichfork = XFS_ATTR_FORK; nargs.trans = args->trans; @@ -1007,7 +1006,6 @@ xfs_attr3_leaf_to_shortform( nargs.geo = args->geo; nargs.dp = dp; nargs.firstblock = args->firstblock; - nargs.dfops = args->dfops; nargs.total = args->total; nargs.whichfork = XFS_ATTR_FORK; nargs.trans = args->trans; diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index bf2e0371149b..577c4c372265 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -480,15 +480,16 @@ xfs_attr_rmtval_set( * extent and then crash then the block may not contain the * correct metadata after log recovery occurs. */ - xfs_defer_init(args->dfops, args->firstblock); + xfs_defer_init(args->trans->t_dfops, args->firstblock); nmap = 1; error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)lblkno, blkcnt, XFS_BMAPI_ATTRFORK, args->firstblock, - args->total, &map, &nmap, args->dfops); + args->total, &map, &nmap, + args->trans->t_dfops); if (error) goto out_defer_cancel; - xfs_defer_ijoin(args->dfops, dp); - error = xfs_defer_finish(&args->trans, args->dfops); + xfs_defer_ijoin(args->trans->t_dfops, dp); + error = xfs_defer_finish(&args->trans, args->trans->t_dfops); if (error) goto out_defer_cancel; @@ -522,7 +523,7 @@ xfs_attr_rmtval_set( ASSERT(blkcnt > 0); - xfs_defer_init(args->dfops, args->firstblock); + xfs_defer_init(args->trans->t_dfops, args->firstblock); nmap = 1; error = xfs_bmapi_read(dp, (xfs_fileoff_t)lblkno, blkcnt, &map, &nmap, @@ -557,7 +558,7 @@ xfs_attr_rmtval_set( ASSERT(valuelen == 0); return 0; out_defer_cancel: - xfs_defer_cancel(args->dfops); + xfs_defer_cancel(args->trans->t_dfops); args->trans = NULL; return error; } @@ -626,14 +627,14 @@ xfs_attr_rmtval_remove( blkcnt = args->rmtblkcnt; done = 0; while (!done) { - xfs_defer_init(args->dfops, args->firstblock); + xfs_defer_init(args->trans->t_dfops, args->firstblock); error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, XFS_BMAPI_ATTRFORK, 1, args->firstblock, - args->dfops, &done); + args->trans->t_dfops, &done); if (error) goto out_defer_cancel; - xfs_defer_ijoin(args->dfops, args->dp); - error = xfs_defer_finish(&args->trans, args->dfops); + xfs_defer_ijoin(args->trans->t_dfops, args->dp); + error = xfs_defer_finish(&args->trans, args->trans->t_dfops); if (error) goto out_defer_cancel; @@ -646,7 +647,7 @@ xfs_attr_rmtval_remove( } return 0; out_defer_cancel: - xfs_defer_cancel(args->dfops); + xfs_defer_cancel(args->trans->t_dfops); args->trans = NULL; return error; } diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 459a29cb17c2..c65aeb088552 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -1007,7 +1007,6 @@ xfs_bmap_add_attrfork_local( dargs.geo = ip->i_mount->m_dir_geo; dargs.dp = ip; dargs.firstblock = firstblock; - dargs.dfops = tp->t_dfops; dargs.total = dargs.geo->fsbcount; dargs.whichfork = XFS_DATA_FORK; dargs.trans = tp; diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index 8a301402bbc4..d2048e4e93ec 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -2063,7 +2063,7 @@ xfs_da_grow_inode_int( error = xfs_bmapi_write(tp, dp, *bno, count, xfs_bmapi_aflag(w)|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG, args->firstblock, args->total, &map, &nmap, - args->dfops); + args->trans->t_dfops); if (error) return error; @@ -2086,7 +2086,8 @@ xfs_da_grow_inode_int( error = xfs_bmapi_write(tp, dp, b, c, xfs_bmapi_aflag(w)|XFS_BMAPI_METADATA, args->firstblock, args->total, - &mapp[mapi], &nmap, args->dfops); + &mapp[mapi], &nmap, + args->trans->t_dfops); if (error) goto out_free_map; if (nmap < 1) @@ -2375,13 +2376,13 @@ done: */ int xfs_da_shrink_inode( - xfs_da_args_t *args, - xfs_dablk_t dead_blkno, - struct xfs_buf *dead_buf) + struct xfs_da_args *args, + xfs_dablk_t dead_blkno, + struct xfs_buf *dead_buf) { - xfs_inode_t *dp; - int done, error, w, count; - xfs_trans_t *tp; + struct xfs_inode *dp; + int done, error, w, count; + struct xfs_trans *tp; trace_xfs_da_shrink_inode(args); @@ -2396,7 +2397,7 @@ xfs_da_shrink_inode( */ error = xfs_bunmapi(tp, dp, dead_blkno, count, xfs_bmapi_aflag(w), 0, args->firstblock, - args->dfops, &done); + args->trans->t_dfops, &done); if (error == -ENOSPC) { if (w != XFS_DATA_FORK) break; diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h index 28260073ae71..6b8a04f3f162 100644 --- a/fs/xfs/libxfs/xfs_da_btree.h +++ b/fs/xfs/libxfs/xfs_da_btree.h @@ -58,7 +58,6 @@ typedef struct xfs_da_args { xfs_ino_t inumber; /* input/output inode number */ struct xfs_inode *dp; /* directory inode to manipulate */ xfs_fsblock_t *firstblock; /* ptr to firstblock for bmap calls */ - struct xfs_defer_ops *dfops; /* ptr to freelist for bmap_finish */ struct xfs_trans *trans; /* current trans (changes over time) */ xfs_extlen_t total; /* total blocks needed, for 1st bmap */ int whichfork; /* data or attribute fork */ diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index c98250f0de50..b21f55a11f35 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -239,8 +239,8 @@ xfs_dir_init( */ int xfs_dir_createname( - xfs_trans_t *tp, - xfs_inode_t *dp, + struct xfs_trans *tp, + struct xfs_inode *dp, struct xfs_name *name, xfs_ino_t inum, /* new entry inode number */ xfs_fsblock_t *first, /* bmap's firstblock */ @@ -274,7 +274,6 @@ xfs_dir_createname( args->total = total; args->whichfork = XFS_DATA_FORK; args->trans = tp; - args->dfops = tp->t_dfops; args->firstblock = first; args->op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; if (!inum) @@ -417,16 +416,16 @@ out_free: */ int xfs_dir_removename( - xfs_trans_t *tp, - xfs_inode_t *dp, - struct xfs_name *name, - xfs_ino_t ino, - xfs_fsblock_t *first, /* bmap's firstblock */ - xfs_extlen_t total) /* bmap's total block count */ + struct xfs_trans *tp, + struct xfs_inode *dp, + struct xfs_name *name, + xfs_ino_t ino, + xfs_fsblock_t *first, /* bmap's firstblock */ + xfs_extlen_t total) /* bmap's total block count */ { - struct xfs_da_args *args; - int rval; - int v; /* type-checking value */ + struct xfs_da_args *args; + int rval; + int v; /* type-checking value */ ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); ASSERT(tp->t_dfops); @@ -447,7 +446,6 @@ xfs_dir_removename( args->total = total; args->whichfork = XFS_DATA_FORK; args->trans = tp; - args->dfops = tp->t_dfops; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { rval = xfs_dir2_sf_removename(args); @@ -479,16 +477,16 @@ out_free: */ int xfs_dir_replace( - xfs_trans_t *tp, - xfs_inode_t *dp, - struct xfs_name *name, /* name of entry to replace */ - xfs_ino_t inum, /* new inode number */ - xfs_fsblock_t *first, /* bmap's firstblock */ - xfs_extlen_t total) /* bmap's total block count */ + struct xfs_trans *tp, + struct xfs_inode *dp, + struct xfs_name *name, /* name of entry to replace */ + xfs_ino_t inum, /* new inode number */ + xfs_fsblock_t *first, /* bmap's firstblock */ + xfs_extlen_t total) /* bmap's total block count */ { - struct xfs_da_args *args; - int rval; - int v; /* type-checking value */ + struct xfs_da_args *args; + int rval; + int v; /* type-checking value */ ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); ASSERT(tp->t_dfops); @@ -512,7 +510,6 @@ xfs_dir_replace( args->total = total; args->whichfork = XFS_DATA_FORK; args->trans = tp; - args->dfops = tp->t_dfops; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { rval = xfs_dir2_sf_replace(args); @@ -646,17 +643,17 @@ xfs_dir2_isleaf( */ int xfs_dir2_shrink_inode( - xfs_da_args_t *args, - xfs_dir2_db_t db, - struct xfs_buf *bp) + struct xfs_da_args *args, + xfs_dir2_db_t db, + struct xfs_buf *bp) { - xfs_fileoff_t bno; /* directory file offset */ - xfs_dablk_t da; /* directory file offset */ - int done; /* bunmap is finished */ - xfs_inode_t *dp; - int error; - xfs_mount_t *mp; - xfs_trans_t *tp; + xfs_fileoff_t bno; /* directory file offset */ + xfs_dablk_t da; /* directory file offset */ + int done; /* bunmap is finished */ + struct xfs_inode *dp; + int error; + struct xfs_mount *mp; + struct xfs_trans *tp; trace_xfs_dir2_shrink_inode(args, db); @@ -667,7 +664,7 @@ xfs_dir2_shrink_inode( /* Unmap the fsblock(s). */ error = xfs_bunmapi(tp, dp, da, args->geo->fsbcount, 0, 0, - args->firstblock, args->dfops, &done); + args->firstblock, args->trans->t_dfops, &done); if (error) { /* * ENOSPC actually can happen if we're in a removename with no -- cgit v1.2.3 From 2ba13721257e2c76e90e8d83dfd9ba91c434355d Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:11 -0700 Subject: xfs: use ->t_dfops in dqalloc transaction xfs_dquot_disk_alloc() receives a transaction from the caller and passes a local dfops along to xfs_bmapi_write(). If we attach this dfops to the transaction, we have to make sure to clear it before returning to avoid invalid access of stack memory. Since xfs_qm_dqread_alloc() is the only caller, pull dfops into the caller and attach it to the transaction to eliminate this pattern entirely. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_dquot.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 0973a0423bed..aa62f8b17376 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -286,8 +286,8 @@ xfs_dquot_disk_alloc( struct xfs_buf **bpp) { struct xfs_bmbt_irec map; - struct xfs_defer_ops dfops; - struct xfs_mount *mp = (*tpp)->t_mountp; + struct xfs_trans *tp = *tpp; + struct xfs_mount *mp = tp->t_mountp; struct xfs_buf *bp; struct xfs_inode *quotip = xfs_quota_inode(mp, dqp->dq_flags); xfs_fsblock_t firstblock; @@ -296,7 +296,8 @@ xfs_dquot_disk_alloc( trace_xfs_dqalloc(dqp); - xfs_defer_init(&dfops, &firstblock); + xfs_defer_init(tp->t_dfops, &firstblock); + xfs_ilock(quotip, XFS_ILOCK_EXCL); if (!xfs_this_quota_on(dqp->q_mount, dqp->dq_flags)) { /* @@ -308,11 +309,11 @@ xfs_dquot_disk_alloc( } /* Create the block mapping. */ - xfs_trans_ijoin(*tpp, quotip, XFS_ILOCK_EXCL); - error = xfs_bmapi_write(*tpp, quotip, dqp->q_fileoffset, + xfs_trans_ijoin(tp, quotip, XFS_ILOCK_EXCL); + error = xfs_bmapi_write(tp, quotip, dqp->q_fileoffset, XFS_DQUOT_CLUSTER_SIZE_FSB, XFS_BMAPI_METADATA, &firstblock, XFS_QM_DQALLOC_SPACE_RES(mp), - &map, &nmaps, &dfops); + &map, &nmaps, tp->t_dfops); if (error) goto error0; ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB); @@ -326,7 +327,7 @@ xfs_dquot_disk_alloc( dqp->q_blkno = XFS_FSB_TO_DADDR(mp, map.br_startblock); /* now we can just get the buffer (there's nothing to read yet) */ - bp = xfs_trans_get_buf(*tpp, mp->m_ddev_targp, dqp->q_blkno, + bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, dqp->q_blkno, mp->m_quotainfo->qi_dqchunklen, 0); if (!bp) { error = -ENOMEM; @@ -338,7 +339,7 @@ xfs_dquot_disk_alloc( * Make a chunk of dquots out of this buffer and log * the entire thing. */ - xfs_qm_init_dquot_blk(*tpp, mp, be32_to_cpu(dqp->q_core.d_id), + xfs_qm_init_dquot_blk(tp, mp, be32_to_cpu(dqp->q_core.d_id), dqp->dq_flags & XFS_DQ_ALLTYPES, bp); xfs_buf_set_ref(bp, XFS_DQUOT_REF); @@ -364,14 +365,15 @@ xfs_dquot_disk_alloc( * is responsible for unlocking any buffer passed back, either * manually or by committing the transaction. */ - xfs_trans_bhold(*tpp, bp); - error = xfs_defer_bjoin(&dfops, bp); + xfs_trans_bhold(tp, bp); + error = xfs_defer_bjoin(tp->t_dfops, bp); if (error) { - xfs_trans_bhold_release(*tpp, bp); - xfs_trans_brelse(*tpp, bp); + xfs_trans_bhold_release(tp, bp); + xfs_trans_brelse(tp, bp); goto error1; } - error = xfs_defer_finish(tpp, &dfops); + error = xfs_defer_finish(tpp, tp->t_dfops); + tp = *tpp; if (error) { xfs_buf_relse(bp); goto error1; @@ -380,7 +382,7 @@ xfs_dquot_disk_alloc( return 0; error1: - xfs_defer_cancel(&dfops); + xfs_defer_cancel(tp->t_dfops); error0: return error; } @@ -538,13 +540,17 @@ xfs_qm_dqread_alloc( struct xfs_buf **bpp) { struct xfs_trans *tp; + struct xfs_defer_ops dfops; struct xfs_buf *bp; + xfs_fsblock_t firstblock; int error; error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_dqalloc, XFS_QM_DQALLOC_SPACE_RES(mp), 0, 0, &tp); if (error) goto err; + xfs_defer_init(&dfops, &firstblock); + tp->t_dfops = &dfops; error = xfs_dquot_disk_alloc(&tp, dqp, &bp); if (error) -- cgit v1.2.3 From 175d1a013eaf35c802e0195d87ac2a8df83ad42a Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:12 -0700 Subject: xfs: use ->t_dfops for all xfs_bmapi_write() callers Attach ->t_dfops for all remaining callers of xfs_bmapi_write(). This prepares the latter to no longer require a separate dfops parameter. Note that xfs_symlink() already uses ->t_dfops. Fix up the local references for consistency. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_bmap_util.c | 5 +++-- fs/xfs/xfs_iomap.c | 21 ++++++++++++--------- fs/xfs/xfs_reflink.c | 7 ++++--- fs/xfs/xfs_rtalloc.c | 7 ++++--- fs/xfs/xfs_symlink.c | 6 +++--- 5 files changed, 26 insertions(+), 20 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index da561882c349..4a698dab85d2 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -973,16 +973,17 @@ xfs_alloc_file_space( xfs_trans_ijoin(tp, ip, 0); xfs_defer_init(&dfops, &firstfsb); + tp->t_dfops = &dfops; error = xfs_bmapi_write(tp, ip, startoffset_fsb, allocatesize_fsb, alloc_type, &firstfsb, - resblks, imapp, &nimaps, &dfops); + resblks, imapp, &nimaps, tp->t_dfops); if (error) goto error0; /* * Complete the transaction */ - error = xfs_defer_finish(&tp, &dfops); + error = xfs_defer_finish(&tp, tp->t_dfops); if (error) goto error0; diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index fb9746cc7338..7c0b858f6723 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -255,17 +255,18 @@ xfs_iomap_write_direct( * caller gave to us. */ xfs_defer_init(&dfops, &firstfsb); + tp->t_dfops = &dfops; nimaps = 1; error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, bmapi_flags, &firstfsb, resblks, imap, - &nimaps, &dfops); + &nimaps, tp->t_dfops); if (error) goto out_bmap_cancel; /* * Complete the transaction */ - error = xfs_defer_finish(&tp, &dfops); + error = xfs_defer_finish(&tp, tp->t_dfops); if (error) goto out_bmap_cancel; @@ -289,7 +290,7 @@ out_unlock: return error; out_bmap_cancel: - xfs_defer_cancel(&dfops); + xfs_defer_cancel(tp->t_dfops); xfs_trans_unreserve_quota_nblks(tp, ip, (long)qblocks, 0, quota_flag); out_trans_cancel: xfs_trans_cancel(tp); @@ -717,6 +718,7 @@ xfs_iomap_write_allocate( xfs_trans_ijoin(tp, ip, 0); xfs_defer_init(&dfops, &first_block); + tp->t_dfops = &dfops; /* * it is possible that the extents have changed since @@ -772,11 +774,11 @@ xfs_iomap_write_allocate( error = xfs_bmapi_write(tp, ip, map_start_fsb, count_fsb, flags, &first_block, nres, imap, &nimaps, - &dfops); + tp->t_dfops); if (error) goto trans_cancel; - error = xfs_defer_finish(&tp, &dfops); + error = xfs_defer_finish(&tp, tp->t_dfops); if (error) goto trans_cancel; @@ -810,7 +812,7 @@ xfs_iomap_write_allocate( } trans_cancel: - xfs_defer_cancel(&dfops); + xfs_defer_cancel(tp->t_dfops); xfs_trans_cancel(tp); error0: xfs_iunlock(ip, XFS_ILOCK_EXCL); @@ -878,10 +880,11 @@ xfs_iomap_write_unwritten( * Modify the unwritten extent state of the buffer. */ xfs_defer_init(&dfops, &firstfsb); + tp->t_dfops = &dfops; nimaps = 1; error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, XFS_BMAPI_CONVERT, &firstfsb, resblks, - &imap, &nimaps, &dfops); + &imap, &nimaps, tp->t_dfops); if (error) goto error_on_bmapi_transaction; @@ -901,7 +904,7 @@ xfs_iomap_write_unwritten( xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); } - error = xfs_defer_finish(&tp, &dfops); + error = xfs_defer_finish(&tp, tp->t_dfops); if (error) goto error_on_bmapi_transaction; @@ -928,7 +931,7 @@ xfs_iomap_write_unwritten( return 0; error_on_bmapi_transaction: - xfs_defer_cancel(&dfops); + xfs_defer_cancel(tp->t_dfops); xfs_trans_cancel(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); return error; diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 33845009bec5..3c28e7ff7365 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -429,19 +429,20 @@ retry: xfs_trans_ijoin(tp, ip, 0); xfs_defer_init(&dfops, &first_block); + tp->t_dfops = &dfops; nimaps = 1; /* Allocate the entire reservation as unwritten blocks. */ error = xfs_bmapi_write(tp, ip, imap->br_startoff, imap->br_blockcount, XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC, &first_block, - resblks, imap, &nimaps, &dfops); + resblks, imap, &nimaps, tp->t_dfops); if (error) goto out_bmap_cancel; xfs_inode_set_cowblocks_tag(ip); /* Finish up. */ - error = xfs_defer_finish(&tp, &dfops); + error = xfs_defer_finish(&tp, tp->t_dfops); if (error) goto out_bmap_cancel; @@ -458,7 +459,7 @@ retry: convert: return xfs_reflink_convert_cow_extent(ip, imap, offset_fsb, count_fsb); out_bmap_cancel: - xfs_defer_cancel(&dfops); + xfs_defer_cancel(tp->t_dfops); xfs_trans_unreserve_quota_nblks(tp, ip, (long)resblks, 0, XFS_QMOPT_RES_REGBLKS); out: diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 329d4d26c13e..312d410d91fb 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -788,13 +788,14 @@ xfs_growfs_rt_alloc( xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); xfs_defer_init(&dfops, &firstblock); + tp->t_dfops = &dfops; /* * Allocate blocks to the bitmap file. */ nmap = 1; error = xfs_bmapi_write(tp, ip, oblocks, nblocks - oblocks, XFS_BMAPI_METADATA, &firstblock, - resblks, &map, &nmap, &dfops); + resblks, &map, &nmap, tp->t_dfops); if (!error && nmap < 1) error = -ENOSPC; if (error) @@ -802,7 +803,7 @@ xfs_growfs_rt_alloc( /* * Free any blocks freed up in the transaction, then commit. */ - error = xfs_defer_finish(&tp, &dfops); + error = xfs_defer_finish(&tp, tp->t_dfops); if (error) goto out_bmap_cancel; error = xfs_trans_commit(tp); @@ -855,7 +856,7 @@ xfs_growfs_rt_alloc( return 0; out_bmap_cancel: - xfs_defer_cancel(&dfops); + xfs_defer_cancel(tp->t_dfops); out_trans_cancel: xfs_trans_cancel(tp); return error; diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index e347a3db018f..6825a31727d1 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -291,7 +291,7 @@ xfs_symlink( error = xfs_bmapi_write(tp, ip, first_fsb, fs_blocks, XFS_BMAPI_METADATA, &first_block, resblks, - mval, &nmaps, &dfops); + mval, &nmaps, tp->t_dfops); if (error) goto out_bmap_cancel; @@ -354,7 +354,7 @@ xfs_symlink( xfs_trans_set_sync(tp); } - error = xfs_defer_finish(&tp, &dfops); + error = xfs_defer_finish(&tp, tp->t_dfops); if (error) goto out_bmap_cancel; @@ -370,7 +370,7 @@ xfs_symlink( return 0; out_bmap_cancel: - xfs_defer_cancel(&dfops); + xfs_defer_cancel(tp->t_dfops); out_trans_cancel: xfs_trans_cancel(tp); out_release_inode: -- cgit v1.2.3 From 6e702a5dcbe1d38cf479931dd2e2a3da884143f0 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:12 -0700 Subject: xfs: remove xfs_bmapi_write() dfops param Now that all callers use ->t_dfops, the xfs_bmapi_write() dfops parameter is no longer necessary. Remove it and access ->t_dfops directly. This patch does not change behavior. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr_remote.c | 3 +-- fs/xfs/libxfs/xfs_bmap.c | 10 +++++----- fs/xfs/libxfs/xfs_bmap.h | 3 +-- fs/xfs/libxfs/xfs_da_btree.c | 6 ++---- fs/xfs/xfs_bmap_util.c | 2 +- fs/xfs/xfs_dquot.c | 2 +- fs/xfs/xfs_iomap.c | 7 +++---- fs/xfs/xfs_reflink.c | 8 ++++---- fs/xfs/xfs_rtalloc.c | 2 +- fs/xfs/xfs_symlink.c | 2 +- 10 files changed, 20 insertions(+), 25 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index 577c4c372265..1f2bc86a28ed 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -484,8 +484,7 @@ xfs_attr_rmtval_set( nmap = 1; error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)lblkno, blkcnt, XFS_BMAPI_ATTRFORK, args->firstblock, - args->total, &map, &nmap, - args->trans->t_dfops); + args->total, &map, &nmap); if (error) goto out_defer_cancel; xfs_defer_ijoin(args->trans->t_dfops, dp); diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index c65aeb088552..02e72c195c4f 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -4245,8 +4245,7 @@ xfs_bmapi_write( controls a.g. for allocs */ xfs_extlen_t total, /* total blocks needed */ struct xfs_bmbt_irec *mval, /* output: map values */ - int *nmap, /* i/o: mval size/count */ - struct xfs_defer_ops *dfops) /* i/o: list extents to free */ + int *nmap) /* i/o: mval size/count */ { struct xfs_mount *mp = ip->i_mount; struct xfs_ifork *ifp; @@ -4337,7 +4336,7 @@ xfs_bmapi_write( bma.ip = ip; bma.total = total; bma.datatype = 0; - bma.dfops = dfops; + bma.dfops = tp ? tp->t_dfops : NULL; bma.firstblock = firstblock; while (bno < end && n < *nmap) { @@ -4414,8 +4413,9 @@ xfs_bmapi_write( * the refcount btree for orphan recovery. */ if (whichfork == XFS_COW_FORK) { - error = xfs_refcount_alloc_cow_extent(mp, dfops, - bma.blkno, bma.length); + error = xfs_refcount_alloc_cow_extent(mp, + tp->t_dfops, bma.blkno, + bma.length); if (error) goto error0; } diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 44639588d1c7..fc86cc218c58 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -203,8 +203,7 @@ int xfs_bmapi_read(struct xfs_inode *ip, xfs_fileoff_t bno, int xfs_bmapi_write(struct xfs_trans *tp, struct xfs_inode *ip, xfs_fileoff_t bno, xfs_filblks_t len, int flags, xfs_fsblock_t *firstblock, xfs_extlen_t total, - struct xfs_bmbt_irec *mval, int *nmap, - struct xfs_defer_ops *dfops); + struct xfs_bmbt_irec *mval, int *nmap); int __xfs_bunmapi(struct xfs_trans *tp, struct xfs_inode *ip, xfs_fileoff_t bno, xfs_filblks_t *rlen, int flags, xfs_extnum_t nexts, xfs_fsblock_t *firstblock, diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index d2048e4e93ec..e43f1dda02e4 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -2062,8 +2062,7 @@ xfs_da_grow_inode_int( ASSERT(args->firstblock != NULL); error = xfs_bmapi_write(tp, dp, *bno, count, xfs_bmapi_aflag(w)|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG, - args->firstblock, args->total, &map, &nmap, - args->trans->t_dfops); + args->firstblock, args->total, &map, &nmap); if (error) return error; @@ -2086,8 +2085,7 @@ xfs_da_grow_inode_int( error = xfs_bmapi_write(tp, dp, b, c, xfs_bmapi_aflag(w)|XFS_BMAPI_METADATA, args->firstblock, args->total, - &mapp[mapi], &nmap, - args->trans->t_dfops); + &mapp[mapi], &nmap); if (error) goto out_free_map; if (nmap < 1) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 4a698dab85d2..cf54da3187d5 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -976,7 +976,7 @@ xfs_alloc_file_space( tp->t_dfops = &dfops; error = xfs_bmapi_write(tp, ip, startoffset_fsb, allocatesize_fsb, alloc_type, &firstfsb, - resblks, imapp, &nimaps, tp->t_dfops); + resblks, imapp, &nimaps); if (error) goto error0; diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index aa62f8b17376..1ef38e1df679 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -313,7 +313,7 @@ xfs_dquot_disk_alloc( error = xfs_bmapi_write(tp, quotip, dqp->q_fileoffset, XFS_DQUOT_CLUSTER_SIZE_FSB, XFS_BMAPI_METADATA, &firstblock, XFS_QM_DQALLOC_SPACE_RES(mp), - &map, &nmaps, tp->t_dfops); + &map, &nmaps); if (error) goto error0; ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB); diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 7c0b858f6723..0c736c938f52 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -259,7 +259,7 @@ xfs_iomap_write_direct( nimaps = 1; error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, bmapi_flags, &firstfsb, resblks, imap, - &nimaps, tp->t_dfops); + &nimaps); if (error) goto out_bmap_cancel; @@ -773,8 +773,7 @@ xfs_iomap_write_allocate( */ error = xfs_bmapi_write(tp, ip, map_start_fsb, count_fsb, flags, &first_block, - nres, imap, &nimaps, - tp->t_dfops); + nres, imap, &nimaps); if (error) goto trans_cancel; @@ -884,7 +883,7 @@ xfs_iomap_write_unwritten( nimaps = 1; error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, XFS_BMAPI_CONVERT, &firstfsb, resblks, - &imap, &nimaps, tp->t_dfops); + &imap, &nimaps); if (error) goto error_on_bmapi_transaction; diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 3c28e7ff7365..9f3f144bf9ff 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -326,7 +326,7 @@ xfs_reflink_convert_cow_extent( return 0; return xfs_bmapi_write(NULL, ip, imap->br_startoff, imap->br_blockcount, XFS_BMAPI_COWFORK | XFS_BMAPI_CONVERT, &first_block, - 0, imap, &nimaps, NULL); + 0, imap, &nimaps); } /* Convert all of the unwritten CoW extents in a file's range to real ones. */ @@ -349,8 +349,8 @@ xfs_reflink_convert_cow( xfs_ilock(ip, XFS_ILOCK_EXCL); error = xfs_bmapi_write(NULL, ip, offset_fsb, count_fsb, XFS_BMAPI_COWFORK | XFS_BMAPI_CONVERT | - XFS_BMAPI_CONVERT_ONLY, &first_block, 0, &imap, &nimaps, - NULL); + XFS_BMAPI_CONVERT_ONLY, &first_block, 0, &imap, + &nimaps); xfs_iunlock(ip, XFS_ILOCK_EXCL); return error; } @@ -435,7 +435,7 @@ retry: /* Allocate the entire reservation as unwritten blocks. */ error = xfs_bmapi_write(tp, ip, imap->br_startoff, imap->br_blockcount, XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC, &first_block, - resblks, imap, &nimaps, tp->t_dfops); + resblks, imap, &nimaps); if (error) goto out_bmap_cancel; diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 312d410d91fb..1c7d1238ff3b 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -795,7 +795,7 @@ xfs_growfs_rt_alloc( nmap = 1; error = xfs_bmapi_write(tp, ip, oblocks, nblocks - oblocks, XFS_BMAPI_METADATA, &firstblock, - resblks, &map, &nmap, tp->t_dfops); + resblks, &map, &nmap); if (!error && nmap < 1) error = -ENOSPC; if (error) diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 6825a31727d1..2b6bcfd39c14 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -291,7 +291,7 @@ xfs_symlink( error = xfs_bmapi_write(tp, ip, first_fsb, fs_blocks, XFS_BMAPI_METADATA, &first_block, resblks, - mval, &nmaps, tp->t_dfops); + mval, &nmaps); if (error) goto out_bmap_cancel; -- cgit v1.2.3 From 4bcfa613a0582a9992a6c2af82273bd770103d12 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:13 -0700 Subject: xfs: use ->t_dfops for all xfs_bunmapi() callers Use ->t_dfops for all remaining xfs_bunmapi() callers. This prepares the latter to no longer require a dfops parameter. Note that xfs_itruncate_extents_flags() associates a local dfops with a transaction provided from the caller. Since there are multiple callers, set and reset ->t_dfops before the function returns to avoid exposure of stack memory to the caller. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_bmap_util.c | 9 +++++---- fs/xfs/xfs_inode.c | 12 ++++++++---- fs/xfs/xfs_reflink.c | 27 +++++++++++++++------------ fs/xfs/xfs_symlink.c | 9 +++++---- 4 files changed, 33 insertions(+), 24 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index cf54da3187d5..76f28b823866 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1044,13 +1044,14 @@ xfs_unmap_extent( xfs_trans_ijoin(tp, ip, 0); xfs_defer_init(&dfops, &firstfsb); + tp->t_dfops = &dfops; error = xfs_bunmapi(tp, ip, startoffset_fsb, len_fsb, 0, 2, &firstfsb, - &dfops, done); + tp->t_dfops, done); if (error) goto out_bmap_cancel; - xfs_defer_ijoin(&dfops, ip); - error = xfs_defer_finish(&tp, &dfops); + xfs_defer_ijoin(tp->t_dfops, ip); + error = xfs_defer_finish(&tp, tp->t_dfops); if (error) goto out_bmap_cancel; @@ -1060,7 +1061,7 @@ out_unlock: return error; out_bmap_cancel: - xfs_defer_cancel(&dfops); + xfs_defer_cancel(tp->t_dfops); out_trans_cancel: xfs_trans_cancel(tp); goto out_unlock; diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index e1bc686b70b4..539d96201666 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1545,6 +1545,7 @@ xfs_itruncate_extents_flags( { struct xfs_mount *mp = ip->i_mount; struct xfs_trans *tp = *tpp; + struct xfs_defer_ops *odfops = tp->t_dfops; struct xfs_defer_ops dfops; xfs_fsblock_t first_block; xfs_fileoff_t first_unmap_block; @@ -1584,9 +1585,10 @@ xfs_itruncate_extents_flags( unmap_len = last_block - first_unmap_block + 1; while (!done) { xfs_defer_init(&dfops, &first_block); + tp->t_dfops = &dfops; error = xfs_bunmapi(tp, ip, first_unmap_block, unmap_len, flags, XFS_ITRUNC_MAX_EXTENTS, &first_block, - &dfops, &done); + tp->t_dfops, &done); if (error) goto out_bmap_cancel; @@ -1594,8 +1596,8 @@ xfs_itruncate_extents_flags( * Duplicate the transaction that has the permanent * reservation and commit the old transaction. */ - xfs_defer_ijoin(&dfops, ip); - error = xfs_defer_finish(&tp, &dfops); + xfs_defer_ijoin(tp->t_dfops, ip); + error = xfs_defer_finish(&tp, tp->t_dfops); if (error) goto out_bmap_cancel; @@ -1623,6 +1625,8 @@ xfs_itruncate_extents_flags( trace_xfs_itruncate_extents_end(ip, new_size); out: + /* ->t_dfops points to local stack, don't leak it! */ + tp->t_dfops = odfops; *tpp = tp; return error; out_bmap_cancel: @@ -1631,7 +1635,7 @@ out_bmap_cancel: * the transaction can be properly aborted. We just need to make sure * we're not holding any resources that we were not when we came in. */ - xfs_defer_cancel(&dfops); + xfs_defer_cancel(tp->t_dfops); goto out; } diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 9f3f144bf9ff..c119cd33766e 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -700,9 +700,10 @@ xfs_reflink_end_cow( /* Unmap the old blocks in the data fork. */ xfs_defer_init(&dfops, &firstfsb); + tp->t_dfops = &dfops; rlen = del.br_blockcount; error = __xfs_bunmapi(tp, ip, del.br_startoff, &rlen, 0, 1, - &firstfsb, &dfops); + &firstfsb, tp->t_dfops); if (error) goto out_defer; @@ -714,13 +715,14 @@ xfs_reflink_end_cow( trace_xfs_reflink_cow_remap(ip, &del); /* Free the CoW orphan record. */ - error = xfs_refcount_free_cow_extent(tp->t_mountp, &dfops, + error = xfs_refcount_free_cow_extent(tp->t_mountp, tp->t_dfops, del.br_startblock, del.br_blockcount); if (error) goto out_defer; /* Map the new blocks into the data fork. */ - error = xfs_bmap_map_extent(tp->t_mountp, &dfops, ip, &del); + error = xfs_bmap_map_extent(tp->t_mountp, tp->t_dfops, ip, + &del); if (error) goto out_defer; @@ -731,8 +733,8 @@ xfs_reflink_end_cow( /* Remove the mapping from the CoW fork. */ xfs_bmap_del_extent_cow(ip, &icur, &got, &del); - xfs_defer_ijoin(&dfops, ip); - error = xfs_defer_finish(&tp, &dfops); + xfs_defer_ijoin(tp->t_dfops, ip); + error = xfs_defer_finish(&tp, tp->t_dfops); if (error) goto out_defer; if (!xfs_iext_get_extent(ifp, &icur, &got)) @@ -750,7 +752,7 @@ prev_extent: return 0; out_defer: - xfs_defer_cancel(&dfops); + xfs_defer_cancel(tp->t_dfops); out_cancel: xfs_trans_cancel(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); @@ -1049,8 +1051,9 @@ xfs_reflink_remap_extent( rlen = unmap_len; while (rlen) { xfs_defer_init(&dfops, &firstfsb); + tp->t_dfops = &dfops; error = __xfs_bunmapi(tp, ip, destoff, &rlen, 0, 1, - &firstfsb, &dfops); + &firstfsb, tp->t_dfops); if (error) goto out_defer; @@ -1071,12 +1074,12 @@ xfs_reflink_remap_extent( uirec.br_blockcount, uirec.br_startblock); /* Update the refcount tree */ - error = xfs_refcount_increase_extent(mp, &dfops, &uirec); + error = xfs_refcount_increase_extent(mp, tp->t_dfops, &uirec); if (error) goto out_defer; /* Map the new blocks into the data fork. */ - error = xfs_bmap_map_extent(mp, &dfops, ip, &uirec); + error = xfs_bmap_map_extent(mp, tp->t_dfops, ip, &uirec); if (error) goto out_defer; @@ -1097,8 +1100,8 @@ xfs_reflink_remap_extent( next_extent: /* Process all the deferred stuff. */ - xfs_defer_ijoin(&dfops, ip); - error = xfs_defer_finish(&tp, &dfops); + xfs_defer_ijoin(tp->t_dfops, ip); + error = xfs_defer_finish(&tp, tp->t_dfops); if (error) goto out_defer; } @@ -1110,7 +1113,7 @@ next_extent: return 0; out_defer: - xfs_defer_cancel(&dfops); + xfs_defer_cancel(tp->t_dfops); out_cancel: xfs_trans_cancel(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 2b6bcfd39c14..290ae13d4673 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -444,6 +444,7 @@ xfs_inactive_symlink_rmt( */ done = 0; xfs_defer_init(&dfops, &first_block); + tp->t_dfops = &dfops; nmaps = ARRAY_SIZE(mval); error = xfs_bmapi_read(ip, 0, xfs_symlink_blocks(mp, size), mval, &nmaps, 0); @@ -466,15 +467,15 @@ xfs_inactive_symlink_rmt( * Unmap the dead block(s) to the dfops. */ error = xfs_bunmapi(tp, ip, 0, size, 0, nmaps, - &first_block, &dfops, &done); + &first_block, tp->t_dfops, &done); if (error) goto error_bmap_cancel; ASSERT(done); /* * Commit the first transaction. This logs the EFI and the inode. */ - xfs_defer_ijoin(&dfops, ip); - error = xfs_defer_finish(&tp, &dfops); + xfs_defer_ijoin(tp->t_dfops, ip); + error = xfs_defer_finish(&tp, tp->t_dfops); if (error) goto error_bmap_cancel; @@ -499,7 +500,7 @@ xfs_inactive_symlink_rmt( return 0; error_bmap_cancel: - xfs_defer_cancel(&dfops); + xfs_defer_cancel(tp->t_dfops); error_trans_cancel: xfs_trans_cancel(tp); error_unlock: -- cgit v1.2.3 From ccd9d91148780a5e979ac00bce67c2155fb6378f Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:13 -0700 Subject: xfs: remove xfs_bunmapi() dfops param Now that all xfs_bunmapi() callers use ->t_dfops, remove the unnecessary parameter and access ->t_dfops directly. This patch does not change behavior. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr_remote.c | 2 +- fs/xfs/libxfs/xfs_bmap.c | 20 +++++++++----------- fs/xfs/libxfs/xfs_bmap.h | 5 ++--- fs/xfs/libxfs/xfs_da_btree.c | 2 +- fs/xfs/libxfs/xfs_dir2.c | 2 +- fs/xfs/xfs_bmap_util.c | 2 +- fs/xfs/xfs_inode.c | 2 +- fs/xfs/xfs_reflink.c | 5 ++--- fs/xfs/xfs_symlink.c | 3 +-- 9 files changed, 19 insertions(+), 24 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index 1f2bc86a28ed..179259fd1b5e 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -629,7 +629,7 @@ xfs_attr_rmtval_remove( xfs_defer_init(args->trans->t_dfops, args->firstblock); error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, XFS_BMAPI_ATTRFORK, 1, args->firstblock, - args->trans->t_dfops, &done); + &done); if (error) goto out_defer_cancel; xfs_defer_ijoin(args->trans->t_dfops, args->dp); diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 02e72c195c4f..9c778e50ad19 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -5143,26 +5143,26 @@ done: */ int /* error */ __xfs_bunmapi( - xfs_trans_t *tp, /* transaction pointer */ + struct xfs_trans *tp, /* transaction pointer */ struct xfs_inode *ip, /* incore inode */ xfs_fileoff_t start, /* first file offset deleted */ xfs_filblks_t *rlen, /* i/o: amount remaining */ int flags, /* misc flags */ xfs_extnum_t nexts, /* number of extents max */ - xfs_fsblock_t *firstblock, /* first allocated block + xfs_fsblock_t *firstblock) /* first allocated block controls a.g. for allocs */ - struct xfs_defer_ops *dfops) /* i/o: deferred updates */ { - xfs_btree_cur_t *cur; /* bmap btree cursor */ - xfs_bmbt_irec_t del; /* extent being deleted */ + struct xfs_defer_ops *dfops = tp ? tp->t_dfops : NULL; + struct xfs_btree_cur *cur; /* bmap btree cursor */ + struct xfs_bmbt_irec del; /* extent being deleted */ int error; /* error return value */ xfs_extnum_t extno; /* extent number in list */ - xfs_bmbt_irec_t got; /* current extent record */ + struct xfs_bmbt_irec got; /* current extent record */ xfs_ifork_t *ifp; /* inode fork pointer */ int isrt; /* freeing in rt area */ int logflags; /* transaction logging flags */ xfs_extlen_t mod; /* rt extent offset */ - xfs_mount_t *mp; /* mount structure */ + struct xfs_mount *mp; /* mount structure */ int tmp_logflags; /* partial logging flags */ int wasdel; /* was a delayed alloc extent */ int whichfork; /* data or attribute fork */ @@ -5516,13 +5516,11 @@ xfs_bunmapi( int flags, xfs_extnum_t nexts, xfs_fsblock_t *firstblock, - struct xfs_defer_ops *dfops, int *done) { int error; - error = __xfs_bunmapi(tp, ip, bno, &len, flags, nexts, firstblock, - dfops); + error = __xfs_bunmapi(tp, ip, bno, &len, flags, nexts, firstblock); *done = (len == 0); return error; } @@ -6193,7 +6191,7 @@ xfs_bmap_finish_one( break; case XFS_BMAP_UNMAP: error = __xfs_bunmapi(tp, ip, startoff, blockcount, - XFS_BMAPI_REMAP, 1, &firstfsb, dfops); + XFS_BMAPI_REMAP, 1, &firstfsb); break; default: ASSERT(0); diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index fc86cc218c58..a83906ec6141 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -206,12 +206,11 @@ int xfs_bmapi_write(struct xfs_trans *tp, struct xfs_inode *ip, struct xfs_bmbt_irec *mval, int *nmap); int __xfs_bunmapi(struct xfs_trans *tp, struct xfs_inode *ip, xfs_fileoff_t bno, xfs_filblks_t *rlen, int flags, - xfs_extnum_t nexts, xfs_fsblock_t *firstblock, - struct xfs_defer_ops *dfops); + xfs_extnum_t nexts, xfs_fsblock_t *firstblock); int xfs_bunmapi(struct xfs_trans *tp, struct xfs_inode *ip, xfs_fileoff_t bno, xfs_filblks_t len, int flags, xfs_extnum_t nexts, xfs_fsblock_t *firstblock, - struct xfs_defer_ops *dfops, int *done); + int *done); int xfs_bmap_del_extent_delay(struct xfs_inode *ip, int whichfork, struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *got, struct xfs_bmbt_irec *del); diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index e43f1dda02e4..68a72e3d9f53 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -2395,7 +2395,7 @@ xfs_da_shrink_inode( */ error = xfs_bunmapi(tp, dp, dead_blkno, count, xfs_bmapi_aflag(w), 0, args->firstblock, - args->trans->t_dfops, &done); + &done); if (error == -ENOSPC) { if (w != XFS_DATA_FORK) break; diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index b21f55a11f35..781dc63d305d 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -664,7 +664,7 @@ xfs_dir2_shrink_inode( /* Unmap the fsblock(s). */ error = xfs_bunmapi(tp, dp, da, args->geo->fsbcount, 0, 0, - args->firstblock, args->trans->t_dfops, &done); + args->firstblock, &done); if (error) { /* * ENOSPC actually can happen if we're in a removename with no diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 76f28b823866..6c02cd264045 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1046,7 +1046,7 @@ xfs_unmap_extent( xfs_defer_init(&dfops, &firstfsb); tp->t_dfops = &dfops; error = xfs_bunmapi(tp, ip, startoffset_fsb, len_fsb, 0, 2, &firstfsb, - tp->t_dfops, done); + done); if (error) goto out_bmap_cancel; diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 539d96201666..f456df2e1394 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1588,7 +1588,7 @@ xfs_itruncate_extents_flags( tp->t_dfops = &dfops; error = xfs_bunmapi(tp, ip, first_unmap_block, unmap_len, flags, XFS_ITRUNC_MAX_EXTENTS, &first_block, - tp->t_dfops, &done); + &done); if (error) goto out_bmap_cancel; diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index c119cd33766e..0ac0706c98e8 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -703,7 +703,7 @@ xfs_reflink_end_cow( tp->t_dfops = &dfops; rlen = del.br_blockcount; error = __xfs_bunmapi(tp, ip, del.br_startoff, &rlen, 0, 1, - &firstfsb, tp->t_dfops); + &firstfsb); if (error) goto out_defer; @@ -1052,8 +1052,7 @@ xfs_reflink_remap_extent( while (rlen) { xfs_defer_init(&dfops, &firstfsb); tp->t_dfops = &dfops; - error = __xfs_bunmapi(tp, ip, destoff, &rlen, 0, 1, - &firstfsb, tp->t_dfops); + error = __xfs_bunmapi(tp, ip, destoff, &rlen, 0, 1, &firstfsb); if (error) goto out_defer; diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 290ae13d4673..a54f095c1409 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -466,8 +466,7 @@ xfs_inactive_symlink_rmt( /* * Unmap the dead block(s) to the dfops. */ - error = xfs_bunmapi(tp, ip, 0, size, 0, nmaps, - &first_block, tp->t_dfops, &done); + error = xfs_bunmapi(tp, ip, 0, size, 0, nmaps, &first_block, &done); if (error) goto error_bmap_cancel; ASSERT(done); -- cgit v1.2.3 From ff3edf255da7a1ceb0fb2cb7f195fc27edd0091d Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:14 -0700 Subject: xfs: remove xfs_bmapi_remap() dfops param All xfs_bmapi_remap() callers already use ->t_dfops. Note that deferred completion context unconditionally sets ->t_dfops if it hasn't already been set by the caller. Remove the unnecessary parameter and access ->t_dfops directly. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 8 ++++---- fs/xfs/libxfs/xfs_bmap.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 9c778e50ad19..236e773073cf 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -4511,7 +4511,6 @@ xfs_bmapi_remap( xfs_fileoff_t bno, xfs_filblks_t len, xfs_fsblock_t startblock, - struct xfs_defer_ops *dfops, int flags) { struct xfs_mount *mp = ip->i_mount; @@ -4561,7 +4560,7 @@ xfs_bmapi_remap( if (ifp->if_flags & XFS_IFBROOT) { cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); cur->bc_private.b.firstblock = firstblock; - cur->bc_private.b.dfops = dfops; + cur->bc_private.b.dfops = tp->t_dfops; cur->bc_private.b.flags = 0; } @@ -4574,7 +4573,7 @@ xfs_bmapi_remap( got.br_state = XFS_EXT_NORM; error = xfs_bmap_add_extent_hole_real(tp, ip, whichfork, &icur, - &cur, &got, &firstblock, dfops, &logflags, flags); + &cur, &got, &firstblock, tp->t_dfops, &logflags, flags); if (error) goto error0; @@ -6185,8 +6184,9 @@ xfs_bmap_finish_one( switch (type) { case XFS_BMAP_MAP: + ASSERT(dfops == tp->t_dfops); error = xfs_bmapi_remap(tp, ip, startoff, *blockcount, - startblock, dfops, 0); + startblock, 0); *blockcount = 0; break; case XFS_BMAP_UNMAP: diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index a83906ec6141..2728e98e991a 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -284,6 +284,6 @@ xfs_failaddr_t xfs_bmap_validate_extent(struct xfs_inode *ip, int whichfork, int xfs_bmapi_remap(struct xfs_trans *tp, struct xfs_inode *ip, xfs_fileoff_t bno, xfs_filblks_t len, xfs_fsblock_t startblock, - struct xfs_defer_ops *dfops, int flags); + int flags); #endif /* __XFS_BMAP_H__ */ -- cgit v1.2.3 From 3e3673e3029c1dedf75a1688a5203d9550adf490 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:14 -0700 Subject: xfs: remove struct xfs_bmalloca dfops field Now that bma.dfops is only assigned from ->t_dfops, replace all accesses to the former with the latter and remove the unnecessary field. This patch does not change behavior. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 30 +++++++++++++++--------------- fs/xfs/libxfs/xfs_bmap.h | 1 - fs/xfs/xfs_filestream.c | 3 ++- 3 files changed, 17 insertions(+), 17 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 236e773073cf..e24c54799aae 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -1806,7 +1806,7 @@ xfs_bmap_add_extent_delay_real( if (xfs_bmap_needs_btree(bma->ip, whichfork)) { error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, - bma->firstblock, bma->dfops, + bma->firstblock, bma->tp->t_dfops, &bma->cur, 1, &tmp_rval, whichfork); rval |= tmp_rval; if (error) @@ -1884,7 +1884,7 @@ xfs_bmap_add_extent_delay_real( if (xfs_bmap_needs_btree(bma->ip, whichfork)) { error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, - bma->firstblock, bma->dfops, &bma->cur, 1, + bma->firstblock, bma->tp->t_dfops, &bma->cur, 1, &tmp_rval, whichfork); rval |= tmp_rval; if (error) @@ -1965,8 +1965,8 @@ xfs_bmap_add_extent_delay_real( if (xfs_bmap_needs_btree(bma->ip, whichfork)) { error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, - bma->firstblock, bma->dfops, &bma->cur, - 1, &tmp_rval, whichfork); + bma->firstblock, bma->tp->t_dfops, + &bma->cur, 1, &tmp_rval, whichfork); rval |= tmp_rval; if (error) goto done; @@ -1991,7 +1991,7 @@ xfs_bmap_add_extent_delay_real( /* add reverse mapping unless caller opted out */ if (!(bma->flags & XFS_BMAPI_NORMAP)) { - error = xfs_rmap_map_extent(mp, bma->dfops, bma->ip, + error = xfs_rmap_map_extent(mp, bma->tp->t_dfops, bma->ip, whichfork, new); if (error) goto done; @@ -2003,7 +2003,7 @@ xfs_bmap_add_extent_delay_real( ASSERT(bma->cur == NULL); error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, - bma->firstblock, bma->dfops, &bma->cur, + bma->firstblock, bma->tp->t_dfops, &bma->cur, da_old > 0, &tmp_logflags, whichfork); bma->logflags |= tmp_logflags; if (error) @@ -3480,7 +3480,7 @@ xfs_bmap_btalloc( error = xfs_bmap_btalloc_nullfb(ap, &args, &blen); if (error) return error; - } else if (ap->dfops->dop_low) { + } else if (ap->tp->t_dfops->dop_low) { if (xfs_inode_is_filestream(ap->ip)) args.type = XFS_ALLOCTYPE_FIRST_AG; else @@ -3515,7 +3515,7 @@ xfs_bmap_btalloc( * is >= the stripe unit and the allocation offset is * at the end of file. */ - if (!ap->dfops->dop_low && ap->aeof) { + if (!ap->tp->t_dfops->dop_low && ap->aeof) { if (!ap->offset) { args.alignment = stripe_align; atype = args.type; @@ -3607,7 +3607,7 @@ xfs_bmap_btalloc( args.total = ap->minlen; if ((error = xfs_alloc_vextent(&args))) return error; - ap->dfops->dop_low = true; + ap->tp->t_dfops->dop_low = true; } if (args.fsbno != NULLFSBLOCK) { /* @@ -4082,7 +4082,7 @@ xfs_bmapi_allocate( if ((ifp->if_flags & XFS_IFBROOT) && !bma->cur) { bma->cur = xfs_bmbt_init_cursor(mp, bma->tp, bma->ip, whichfork); bma->cur->bc_private.b.firstblock = *bma->firstblock; - bma->cur->bc_private.b.dfops = bma->dfops; + bma->cur->bc_private.b.dfops = bma->tp->t_dfops; } /* * Bump the number of extents we've allocated @@ -4118,8 +4118,8 @@ xfs_bmapi_allocate( else error = xfs_bmap_add_extent_hole_real(bma->tp, bma->ip, whichfork, &bma->icur, &bma->cur, &bma->got, - bma->firstblock, bma->dfops, &bma->logflags, - bma->flags); + bma->firstblock, bma->tp->t_dfops, + &bma->logflags, bma->flags); bma->logflags |= tmp_logflags; if (error) @@ -4171,7 +4171,7 @@ xfs_bmapi_convert_unwritten( bma->cur = xfs_bmbt_init_cursor(bma->ip->i_mount, bma->tp, bma->ip, whichfork); bma->cur->bc_private.b.firstblock = *bma->firstblock; - bma->cur->bc_private.b.dfops = bma->dfops; + bma->cur->bc_private.b.dfops = bma->tp->t_dfops; } mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN; @@ -4189,7 +4189,7 @@ xfs_bmapi_convert_unwritten( error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, whichfork, &bma->icur, &bma->cur, mval, bma->firstblock, - bma->dfops, &tmp_logflags); + bma->tp->t_dfops, &tmp_logflags); /* * Log the inode core unconditionally in the unwritten extent conversion * path because the conversion might not have done so (e.g., if the @@ -4336,8 +4336,8 @@ xfs_bmapi_write( bma.ip = ip; bma.total = total; bma.datatype = 0; - bma.dfops = tp ? tp->t_dfops : NULL; bma.firstblock = firstblock; + ASSERT(!tp || tp->t_dfops); while (bno < end && n < *nmap) { bool need_alloc = false, wasdelay = false; diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 2728e98e991a..560235603444 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -20,7 +20,6 @@ extern kmem_zone_t *xfs_bmap_free_item_zone; */ struct xfs_bmalloca { xfs_fsblock_t *firstblock; /* i/o first block allocated */ - struct xfs_defer_ops *dfops; /* bmap freelist */ struct xfs_trans *tp; /* transaction pointer */ struct xfs_inode *ip; /* incore inode pointer */ struct xfs_bmbt_irec prev; /* extent before the new one */ diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index 2d2c5ab9143c..56a3999cefae 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -19,6 +19,7 @@ #include "xfs_filestream.h" #include "xfs_trace.h" #include "xfs_ag_resv.h" +#include "xfs_trans.h" struct xfs_fstrm_item { struct xfs_mru_cache_elem mru; @@ -377,7 +378,7 @@ xfs_filestream_new_ag( if (xfs_alloc_is_userdata(ap->datatype)) flags |= XFS_PICK_USERDATA; - if (ap->dfops->dop_low) + if (ap->tp->t_dfops->dop_low) flags |= XFS_PICK_LOWSPACE; err = xfs_filestream_pick_ag(pip, startag, agp, flags, minlen); -- cgit v1.2.3 From f4a9cf97faf4adb27e4e105beda420bb5253c502 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:15 -0700 Subject: xfs: use ->t_dfops for collapse/insert range operations Use ->t_dfops for the collapse and insert range transactions. These are the only callers of the respective bmap helpers, so replace the unnecessary dfops parameters with direct accesses to ->t_dfops. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 16 +++++++--------- fs/xfs/libxfs/xfs_bmap.h | 6 ++---- fs/xfs/xfs_bmap_util.c | 14 ++++++++------ 3 files changed, 17 insertions(+), 19 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index e24c54799aae..89a21dc7a7cb 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -5683,8 +5683,7 @@ xfs_bmap_collapse_extents( xfs_fileoff_t *next_fsb, xfs_fileoff_t offset_shift_fsb, bool *done, - xfs_fsblock_t *firstblock, - struct xfs_defer_ops *dfops) + xfs_fsblock_t *firstblock) { int whichfork = XFS_DATA_FORK; struct xfs_mount *mp = ip->i_mount; @@ -5718,7 +5717,7 @@ xfs_bmap_collapse_extents( if (ifp->if_flags & XFS_IFBROOT) { cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); cur->bc_private.b.firstblock = *firstblock; - cur->bc_private.b.dfops = dfops; + cur->bc_private.b.dfops = tp->t_dfops; cur->bc_private.b.flags = 0; } @@ -5739,7 +5738,7 @@ xfs_bmap_collapse_extents( if (xfs_bmse_can_merge(&prev, &got, offset_shift_fsb)) { error = xfs_bmse_merge(ip, whichfork, offset_shift_fsb, &icur, &got, &prev, cur, &logflags, - dfops); + tp->t_dfops); if (error) goto del_cursor; goto done; @@ -5752,7 +5751,7 @@ xfs_bmap_collapse_extents( } error = xfs_bmap_shift_update_extent(ip, whichfork, &icur, &got, cur, - &logflags, dfops, new_startoff); + &logflags, tp->t_dfops, new_startoff); if (error) goto del_cursor; @@ -5806,8 +5805,7 @@ xfs_bmap_insert_extents( xfs_fileoff_t offset_shift_fsb, bool *done, xfs_fileoff_t stop_fsb, - xfs_fsblock_t *firstblock, - struct xfs_defer_ops *dfops) + xfs_fsblock_t *firstblock) { int whichfork = XFS_DATA_FORK; struct xfs_mount *mp = ip->i_mount; @@ -5841,7 +5839,7 @@ xfs_bmap_insert_extents( if (ifp->if_flags & XFS_IFBROOT) { cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); cur->bc_private.b.firstblock = *firstblock; - cur->bc_private.b.dfops = dfops; + cur->bc_private.b.dfops = tp->t_dfops; cur->bc_private.b.flags = 0; } @@ -5884,7 +5882,7 @@ xfs_bmap_insert_extents( } error = xfs_bmap_shift_update_extent(ip, whichfork, &icur, &got, cur, - &logflags, dfops, new_startoff); + &logflags, tp->t_dfops, new_startoff); if (error) goto del_cursor; diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 560235603444..83180c7cf3ee 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -219,14 +219,12 @@ void xfs_bmap_del_extent_cow(struct xfs_inode *ip, uint xfs_default_attroffset(struct xfs_inode *ip); int xfs_bmap_collapse_extents(struct xfs_trans *tp, struct xfs_inode *ip, xfs_fileoff_t *next_fsb, xfs_fileoff_t offset_shift_fsb, - bool *done, xfs_fsblock_t *firstblock, - struct xfs_defer_ops *dfops); + bool *done, xfs_fsblock_t *firstblock); int xfs_bmap_can_insert_extents(struct xfs_inode *ip, xfs_fileoff_t off, xfs_fileoff_t shift); int xfs_bmap_insert_extents(struct xfs_trans *tp, struct xfs_inode *ip, xfs_fileoff_t *next_fsb, xfs_fileoff_t offset_shift_fsb, - bool *done, xfs_fileoff_t stop_fsb, xfs_fsblock_t *firstblock, - struct xfs_defer_ops *dfops); + bool *done, xfs_fileoff_t stop_fsb, xfs_fsblock_t *firstblock); int xfs_bmap_split_extent(struct xfs_inode *ip, xfs_fileoff_t split_offset); int xfs_bmapi_reserve_delalloc(struct xfs_inode *ip, int whichfork, xfs_fileoff_t off, xfs_filblks_t len, xfs_filblks_t prealloc, diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 6c02cd264045..cd5d410acc73 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1348,12 +1348,13 @@ xfs_collapse_file_space( xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); xfs_defer_init(&dfops, &first_block); + tp->t_dfops = &dfops; error = xfs_bmap_collapse_extents(tp, ip, &next_fsb, shift_fsb, - &done, &first_block, &dfops); + &done, &first_block); if (error) goto out_bmap_cancel; - error = xfs_defer_finish(&tp, &dfops); + error = xfs_defer_finish(&tp, tp->t_dfops); if (error) goto out_bmap_cancel; error = xfs_trans_commit(tp); @@ -1362,7 +1363,7 @@ xfs_collapse_file_space( return error; out_bmap_cancel: - xfs_defer_cancel(&dfops); + xfs_defer_cancel(tp->t_dfops); out_trans_cancel: xfs_trans_cancel(tp); return error; @@ -1427,12 +1428,13 @@ xfs_insert_file_space( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); xfs_defer_init(&dfops, &first_block); + tp->t_dfops = &dfops; error = xfs_bmap_insert_extents(tp, ip, &next_fsb, shift_fsb, - &done, stop_fsb, &first_block, &dfops); + &done, stop_fsb, &first_block); if (error) goto out_bmap_cancel; - error = xfs_defer_finish(&tp, &dfops); + error = xfs_defer_finish(&tp, tp->t_dfops); if (error) goto out_bmap_cancel; error = xfs_trans_commit(tp); @@ -1441,7 +1443,7 @@ xfs_insert_file_space( return error; out_bmap_cancel: - xfs_defer_cancel(&dfops); + xfs_defer_cancel(tp->t_dfops); xfs_trans_cancel(tp); return error; } -- cgit v1.2.3 From 81ba8f3e947c3c53beb535c7f29fe402429cae37 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:16 -0700 Subject: xfs: remove dfops param from internal bmap extent helpers All callers of the various bmap extent helpers now use ->t_dfops. Remove the unnecessary dfops params and access ->t_dfops directly. This patch does not change behavior. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 92 +++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 48 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 89a21dc7a7cb..66655973c229 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -644,25 +644,24 @@ xfs_bmap_btree_to_extents( */ STATIC int /* error */ xfs_bmap_extents_to_btree( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *ip, /* incore inode pointer */ + struct xfs_trans *tp, /* transaction pointer */ + struct xfs_inode *ip, /* incore inode pointer */ xfs_fsblock_t *firstblock, /* first-block-allocated */ - struct xfs_defer_ops *dfops, /* blocks freed in xaction */ - xfs_btree_cur_t **curp, /* cursor returned to caller */ + struct xfs_btree_cur **curp, /* cursor returned to caller */ int wasdel, /* converting a delayed alloc */ int *logflagsp, /* inode logging flags */ int whichfork) /* data or attr fork */ { struct xfs_btree_block *ablock; /* allocated (child) bt block */ - xfs_buf_t *abp; /* buffer for ablock */ - xfs_alloc_arg_t args; /* allocation arguments */ - xfs_bmbt_rec_t *arp; /* child record pointer */ + struct xfs_buf *abp; /* buffer for ablock */ + struct xfs_alloc_arg args; /* allocation arguments */ + struct xfs_bmbt_rec *arp; /* child record pointer */ struct xfs_btree_block *block; /* btree root block */ - xfs_btree_cur_t *cur; /* bmap btree cursor */ + struct xfs_btree_cur *cur; /* bmap btree cursor */ int error; /* error return value */ - xfs_ifork_t *ifp; /* inode fork pointer */ - xfs_bmbt_key_t *kp; /* root block key pointer */ - xfs_mount_t *mp; /* mount structure */ + struct xfs_ifork *ifp; /* inode fork pointer */ + struct xfs_bmbt_key *kp; /* root block key pointer */ + struct xfs_mount *mp; /* mount structure */ xfs_bmbt_ptr_t *pp; /* root block address pointer */ struct xfs_iext_cursor icur; struct xfs_bmbt_irec rec; @@ -691,7 +690,7 @@ xfs_bmap_extents_to_btree( */ cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); cur->bc_private.b.firstblock = *firstblock; - cur->bc_private.b.dfops = dfops; + cur->bc_private.b.dfops = tp->t_dfops; cur->bc_private.b.flags = wasdel ? XFS_BTCUR_BPRV_WASDEL : 0; /* * Convert to a btree with two levels, one record in root. @@ -705,7 +704,7 @@ xfs_bmap_extents_to_btree( if (*firstblock == NULLFSBLOCK) { args.type = XFS_ALLOCTYPE_START_BNO; args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); - } else if (dfops->dop_low) { + } else if (tp->t_dfops->dop_low) { args.type = XFS_ALLOCTYPE_START_BNO; args.fsbno = *firstblock; } else { @@ -958,8 +957,8 @@ error0: */ STATIC int /* error */ xfs_bmap_add_attrfork_extents( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *ip, /* incore inode pointer */ + struct xfs_trans *tp, /* transaction pointer */ + struct xfs_inode *ip, /* incore inode pointer */ xfs_fsblock_t *firstblock, /* first block allocated */ int *flags) /* inode logging flags */ { @@ -969,8 +968,8 @@ xfs_bmap_add_attrfork_extents( if (ip->i_d.di_nextents * sizeof(xfs_bmbt_rec_t) <= XFS_IFORK_DSIZE(ip)) return 0; cur = NULL; - error = xfs_bmap_extents_to_btree(tp, ip, firstblock, tp->t_dfops, &cur, 0, - flags, XFS_DATA_FORK); + error = xfs_bmap_extents_to_btree(tp, ip, firstblock, &cur, 0, flags, + XFS_DATA_FORK); if (cur) { cur->bc_private.b.allocated = 0; xfs_btree_del_cursor(cur, @@ -1806,8 +1805,8 @@ xfs_bmap_add_extent_delay_real( if (xfs_bmap_needs_btree(bma->ip, whichfork)) { error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, - bma->firstblock, bma->tp->t_dfops, - &bma->cur, 1, &tmp_rval, whichfork); + bma->firstblock, &bma->cur, 1, + &tmp_rval, whichfork); rval |= tmp_rval; if (error) goto done; @@ -1884,8 +1883,8 @@ xfs_bmap_add_extent_delay_real( if (xfs_bmap_needs_btree(bma->ip, whichfork)) { error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, - bma->firstblock, bma->tp->t_dfops, &bma->cur, 1, - &tmp_rval, whichfork); + bma->firstblock, &bma->cur, 1, &tmp_rval, + whichfork); rval |= tmp_rval; if (error) goto done; @@ -1965,8 +1964,8 @@ xfs_bmap_add_extent_delay_real( if (xfs_bmap_needs_btree(bma->ip, whichfork)) { error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, - bma->firstblock, bma->tp->t_dfops, - &bma->cur, 1, &tmp_rval, whichfork); + bma->firstblock, &bma->cur, 1, + &tmp_rval, whichfork); rval |= tmp_rval; if (error) goto done; @@ -2003,8 +2002,8 @@ xfs_bmap_add_extent_delay_real( ASSERT(bma->cur == NULL); error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, - bma->firstblock, bma->tp->t_dfops, &bma->cur, - da_old > 0, &tmp_logflags, whichfork); + bma->firstblock, &bma->cur, da_old > 0, + &tmp_logflags, whichfork); bma->logflags |= tmp_logflags; if (error) goto done; @@ -2044,7 +2043,6 @@ xfs_bmap_add_extent_unwritten_real( xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ xfs_bmbt_irec_t *new, /* new data to add to file extents */ xfs_fsblock_t *first, /* pointer to firstblock variable */ - struct xfs_defer_ops *dfops, /* list of extents to be freed */ int *logflagsp) /* inode logging flags */ { xfs_btree_cur_t *cur; /* btree cursor */ @@ -2058,6 +2056,7 @@ xfs_bmap_add_extent_unwritten_real( int state = xfs_bmap_fork_to_state(whichfork); struct xfs_mount *mp = ip->i_mount; struct xfs_bmbt_irec old; + struct xfs_defer_ops *dfops = tp ? tp->t_dfops : NULL; *logflagsp = 0; @@ -2485,8 +2484,8 @@ xfs_bmap_add_extent_unwritten_real( int tmp_logflags; /* partial log flag return val */ ASSERT(cur == NULL); - error = xfs_bmap_extents_to_btree(tp, ip, first, dfops, &cur, - 0, &tmp_logflags, whichfork); + error = xfs_bmap_extents_to_btree(tp, ip, first, &cur, 0, + &tmp_logflags, whichfork); *logflagsp |= tmp_logflags; if (error) goto done; @@ -2658,7 +2657,6 @@ xfs_bmap_add_extent_hole_real( struct xfs_btree_cur **curp, struct xfs_bmbt_irec *new, xfs_fsblock_t *first, - struct xfs_defer_ops *dfops, int *logflagsp, int flags) { @@ -2839,7 +2837,8 @@ xfs_bmap_add_extent_hole_real( /* add reverse mapping unless caller opted out */ if (!(flags & XFS_BMAPI_NORMAP)) { - error = xfs_rmap_map_extent(mp, dfops, ip, whichfork, new); + error = xfs_rmap_map_extent(mp, tp->t_dfops, ip, whichfork, + new); if (error) goto done; } @@ -2849,8 +2848,8 @@ xfs_bmap_add_extent_hole_real( int tmp_logflags; /* partial log flag return val */ ASSERT(cur == NULL); - error = xfs_bmap_extents_to_btree(tp, ip, first, dfops, curp, - 0, &tmp_logflags, whichfork); + error = xfs_bmap_extents_to_btree(tp, ip, first, curp, 0, + &tmp_logflags, whichfork); *logflagsp |= tmp_logflags; cur = *curp; if (error) @@ -4118,8 +4117,7 @@ xfs_bmapi_allocate( else error = xfs_bmap_add_extent_hole_real(bma->tp, bma->ip, whichfork, &bma->icur, &bma->cur, &bma->got, - bma->firstblock, bma->tp->t_dfops, - &bma->logflags, bma->flags); + bma->firstblock, &bma->logflags, bma->flags); bma->logflags |= tmp_logflags; if (error) @@ -4189,7 +4187,7 @@ xfs_bmapi_convert_unwritten( error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, whichfork, &bma->icur, &bma->cur, mval, bma->firstblock, - bma->tp->t_dfops, &tmp_logflags); + &tmp_logflags); /* * Log the inode core unconditionally in the unwritten extent conversion * path because the conversion might not have done so (e.g., if the @@ -4573,7 +4571,7 @@ xfs_bmapi_remap( got.br_state = XFS_EXT_NORM; error = xfs_bmap_add_extent_hole_real(tp, ip, whichfork, &icur, - &cur, &got, &firstblock, tp->t_dfops, &logflags, flags); + &cur, &got, &firstblock, &logflags, flags); if (error) goto error0; @@ -4892,7 +4890,6 @@ xfs_bmap_del_extent_real( xfs_inode_t *ip, /* incore inode pointer */ xfs_trans_t *tp, /* current transaction pointer */ struct xfs_iext_cursor *icur, - struct xfs_defer_ops *dfops, /* list of extents to be freed */ xfs_btree_cur_t *cur, /* if null, not a btree */ xfs_bmbt_irec_t *del, /* data to remove from extents */ int *logflagsp, /* inode logging flags */ @@ -4915,6 +4912,7 @@ xfs_bmap_del_extent_real( uint qfield; /* quota field to update */ int state = xfs_bmap_fork_to_state(whichfork); struct xfs_bmbt_irec old; + struct xfs_defer_ops *dfops = tp ? tp->t_dfops : NULL; mp = ip->i_mount; XFS_STATS_INC(mp, xs_del_exlist); @@ -5341,7 +5339,7 @@ __xfs_bunmapi( del.br_state = XFS_EXT_UNWRITTEN; error = xfs_bmap_add_extent_unwritten_real(tp, ip, whichfork, &icur, &cur, &del, - firstblock, dfops, &logflags); + firstblock, &logflags); if (error) goto error0; goto nodelete; @@ -5398,8 +5396,7 @@ __xfs_bunmapi( prev.br_state = XFS_EXT_UNWRITTEN; error = xfs_bmap_add_extent_unwritten_real(tp, ip, whichfork, &icur, &cur, - &prev, firstblock, dfops, - &logflags); + &prev, firstblock, &logflags); if (error) goto error0; goto nodelete; @@ -5408,8 +5405,7 @@ __xfs_bunmapi( del.br_state = XFS_EXT_UNWRITTEN; error = xfs_bmap_add_extent_unwritten_real(tp, ip, whichfork, &icur, &cur, - &del, firstblock, dfops, - &logflags); + &del, firstblock, &logflags); if (error) goto error0; goto nodelete; @@ -5421,8 +5417,8 @@ delete: error = xfs_bmap_del_extent_delay(ip, whichfork, &icur, &got, &del); } else { - error = xfs_bmap_del_extent_real(ip, tp, &icur, dfops, - cur, &del, &tmp_logflags, whichfork, + error = xfs_bmap_del_extent_real(ip, tp, &icur, cur, + &del, &tmp_logflags, whichfork, flags); logflags |= tmp_logflags; } @@ -5456,8 +5452,8 @@ nodelete: */ if (xfs_bmap_needs_btree(ip, whichfork)) { ASSERT(cur == NULL); - error = xfs_bmap_extents_to_btree(tp, ip, firstblock, dfops, - &cur, 0, &tmp_logflags, whichfork); + error = xfs_bmap_extents_to_btree(tp, ip, firstblock, &cur, 0, + &tmp_logflags, whichfork); logflags |= tmp_logflags; if (error) goto error0; @@ -6007,8 +6003,8 @@ xfs_bmap_split_extent_at( int tmp_logflags; /* partial log flag return val */ ASSERT(cur == NULL); - error = xfs_bmap_extents_to_btree(tp, ip, firstfsb, tp->t_dfops, - &cur, 0, &tmp_logflags, whichfork); + error = xfs_bmap_extents_to_btree(tp, ip, firstfsb, &cur, 0, + &tmp_logflags, whichfork); logflags |= tmp_logflags; } -- cgit v1.2.3 From 42b394a92562b464e9ef81954ca93930c037a51b Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:16 -0700 Subject: xfs: remove xfs_btree_cur bmbt dfops field All assignments of xfs_btree_cur.bc_private.b.dfops originate from ->t_dfops. Replace accesses of the former with the latter and remove the unnecessary field. This patch does not change behavior. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 12 +----------- fs/xfs/libxfs/xfs_bmap_btree.c | 9 +++------ fs/xfs/libxfs/xfs_btree.h | 1 - 3 files changed, 4 insertions(+), 18 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 66655973c229..32d8d87b7582 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -624,7 +624,7 @@ xfs_bmap_btree_to_extents( if ((error = xfs_btree_check_block(cur, cblock, 0, cbp))) return error; xfs_rmap_ino_bmbt_owner(&oinfo, ip->i_ino, whichfork); - xfs_bmap_add_free(mp, cur->bc_private.b.dfops, cbno, 1, &oinfo); + xfs_bmap_add_free(mp, cur->bc_tp->t_dfops, cbno, 1, &oinfo); ip->i_d.di_nblocks--; xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); xfs_trans_binval(tp, cbp); @@ -690,7 +690,6 @@ xfs_bmap_extents_to_btree( */ cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); cur->bc_private.b.firstblock = *firstblock; - cur->bc_private.b.dfops = tp->t_dfops; cur->bc_private.b.flags = wasdel ? XFS_BTCUR_BPRV_WASDEL : 0; /* * Convert to a btree with two levels, one record in root. @@ -929,7 +928,6 @@ xfs_bmap_add_attrfork_btree( *flags |= XFS_ILOG_DBROOT; else { cur = xfs_bmbt_init_cursor(mp, tp, ip, XFS_DATA_FORK); - cur->bc_private.b.dfops = tp->t_dfops; cur->bc_private.b.firstblock = *firstblock; error = xfs_bmbt_lookup_first(cur, &stat); if (error) @@ -4081,7 +4079,6 @@ xfs_bmapi_allocate( if ((ifp->if_flags & XFS_IFBROOT) && !bma->cur) { bma->cur = xfs_bmbt_init_cursor(mp, bma->tp, bma->ip, whichfork); bma->cur->bc_private.b.firstblock = *bma->firstblock; - bma->cur->bc_private.b.dfops = bma->tp->t_dfops; } /* * Bump the number of extents we've allocated @@ -4169,7 +4166,6 @@ xfs_bmapi_convert_unwritten( bma->cur = xfs_bmbt_init_cursor(bma->ip->i_mount, bma->tp, bma->ip, whichfork); bma->cur->bc_private.b.firstblock = *bma->firstblock; - bma->cur->bc_private.b.dfops = bma->tp->t_dfops; } mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN; @@ -4558,7 +4554,6 @@ xfs_bmapi_remap( if (ifp->if_flags & XFS_IFBROOT) { cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); cur->bc_private.b.firstblock = firstblock; - cur->bc_private.b.dfops = tp->t_dfops; cur->bc_private.b.flags = 0; } @@ -5149,7 +5144,6 @@ __xfs_bunmapi( xfs_fsblock_t *firstblock) /* first allocated block controls a.g. for allocs */ { - struct xfs_defer_ops *dfops = tp ? tp->t_dfops : NULL; struct xfs_btree_cur *cur; /* bmap btree cursor */ struct xfs_bmbt_irec del; /* extent being deleted */ int error; /* error return value */ @@ -5223,7 +5217,6 @@ __xfs_bunmapi( ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); cur->bc_private.b.firstblock = *firstblock; - cur->bc_private.b.dfops = dfops; cur->bc_private.b.flags = 0; } else cur = NULL; @@ -5713,7 +5706,6 @@ xfs_bmap_collapse_extents( if (ifp->if_flags & XFS_IFBROOT) { cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); cur->bc_private.b.firstblock = *firstblock; - cur->bc_private.b.dfops = tp->t_dfops; cur->bc_private.b.flags = 0; } @@ -5835,7 +5827,6 @@ xfs_bmap_insert_extents( if (ifp->if_flags & XFS_IFBROOT) { cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); cur->bc_private.b.firstblock = *firstblock; - cur->bc_private.b.dfops = tp->t_dfops; cur->bc_private.b.flags = 0; } @@ -5959,7 +5950,6 @@ xfs_bmap_split_extent_at( if (ifp->if_flags & XFS_IFBROOT) { cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); cur->bc_private.b.firstblock = *firstfsb; - cur->bc_private.b.dfops = tp->t_dfops; cur->bc_private.b.flags = 0; error = xfs_bmbt_lookup_eq(cur, &got, &i); if (error) diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index e1a2d9ceb615..e8b01af09db5 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -176,7 +176,6 @@ xfs_bmbt_dup_cursor( * since init cursor doesn't get them. */ new->bc_private.b.firstblock = cur->bc_private.b.firstblock; - new->bc_private.b.dfops = cur->bc_private.b.dfops; new->bc_private.b.flags = cur->bc_private.b.flags; return new; @@ -189,7 +188,6 @@ xfs_bmbt_update_cursor( { ASSERT((dst->bc_private.b.firstblock != NULLFSBLOCK) || (dst->bc_private.b.ip->i_d.di_flags & XFS_DIFLAG_REALTIME)); - ASSERT(dst->bc_private.b.dfops == src->bc_private.b.dfops); dst->bc_private.b.allocated += src->bc_private.b.allocated; dst->bc_private.b.firstblock = src->bc_private.b.firstblock; @@ -230,7 +228,7 @@ xfs_bmbt_alloc_block( * block allocation here and corrupt the filesystem. */ args.minleft = args.tp->t_blk_res; - } else if (cur->bc_private.b.dfops->dop_low) { + } else if (cur->bc_tp->t_dfops->dop_low) { args.type = XFS_ALLOCTYPE_START_BNO; } else { args.type = XFS_ALLOCTYPE_NEAR_BNO; @@ -257,7 +255,7 @@ xfs_bmbt_alloc_block( error = xfs_alloc_vextent(&args); if (error) goto error0; - cur->bc_private.b.dfops->dop_low = true; + cur->bc_tp->t_dfops->dop_low = true; } if (WARN_ON_ONCE(args.fsbno == NULLFSBLOCK)) { *stat = 0; @@ -293,7 +291,7 @@ xfs_bmbt_free_block( struct xfs_owner_info oinfo; xfs_rmap_ino_bmbt_owner(&oinfo, ip->i_ino, cur->bc_private.b.whichfork); - xfs_bmap_add_free(mp, cur->bc_private.b.dfops, fsbno, 1, &oinfo); + xfs_bmap_add_free(mp, cur->bc_tp->t_dfops, fsbno, 1, &oinfo); ip->i_d.di_nblocks--; xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); @@ -565,7 +563,6 @@ xfs_bmbt_init_cursor( cur->bc_private.b.forksize = XFS_IFORK_SIZE(ip, whichfork); cur->bc_private.b.ip = ip; cur->bc_private.b.firstblock = NULLFSBLOCK; - cur->bc_private.b.dfops = NULL; cur->bc_private.b.allocated = 0; cur->bc_private.b.flags = 0; cur->bc_private.b.whichfork = whichfork; diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 0a4fdf7f11a7..cc94ac765dec 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -215,7 +215,6 @@ typedef struct xfs_btree_cur } a; struct { /* needed for BMAP */ struct xfs_inode *ip; /* pointer to our inode */ - struct xfs_defer_ops *dfops; /* deferred updates */ xfs_fsblock_t firstblock; /* 1st blk allocated */ int allocated; /* count of alloced */ short forksize; /* fork's inode space */ -- cgit v1.2.3 From ed7ef8e55c6f24ae4347b5bda89e00af475ebc89 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:17 -0700 Subject: xfs: remove unused btree cursor bc_private.a.dfops field The xfs_btree_cur.bc_private.a.dfops field is only ever initialized by the refcountbt cursor init function. The only caller of that function with a non-NULL dfops is from deferred completion context, which already has attached to ->t_dfops. In addition to that, the only actual reference of a.dfops is the cursor duplication function, which means the field is effectively unused. Remove the dfops field from the bc_private.a union. Any future users can acquire the dfops from the transaction. This patch does not change behavior. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_btree.h | 1 - fs/xfs/libxfs/xfs_refcount.c | 4 ++-- fs/xfs/libxfs/xfs_refcount_btree.c | 7 ++----- fs/xfs/libxfs/xfs_refcount_btree.h | 4 ++-- fs/xfs/scrub/common.c | 2 +- fs/xfs/xfs_fsmap.c | 2 +- fs/xfs/xfs_reflink.c | 2 +- 7 files changed, 9 insertions(+), 13 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index cc94ac765dec..b986a8fc8d40 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -209,7 +209,6 @@ typedef struct xfs_btree_cur union { struct { /* needed for BNO, CNT, INO */ struct xfs_buf *agbp; /* agf/agi buffer pointer */ - struct xfs_defer_ops *dfops; /* deferred updates */ xfs_agnumber_t agno; /* ag number */ union xfs_btree_cur_private priv; } a; diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index 9dda6fd0bb13..8e330a196060 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -1132,7 +1132,7 @@ xfs_refcount_finish_one( if (!agbp) return -EFSCORRUPTED; - rcur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno, dfops); + rcur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno); if (!rcur) { error = -ENOMEM; goto out_cur; @@ -1666,7 +1666,7 @@ xfs_refcount_recover_cow_leftovers( error = -ENOMEM; goto out_trans; } - cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno, NULL); + cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno); /* Find all the leftover CoW staging extents. */ memset(&low, 0, sizeof(low)); diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index b71937982c5b..393aa88f93db 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c @@ -27,8 +27,7 @@ xfs_refcountbt_dup_cursor( struct xfs_btree_cur *cur) { return xfs_refcountbt_init_cursor(cur->bc_mp, cur->bc_tp, - cur->bc_private.a.agbp, cur->bc_private.a.agno, - cur->bc_private.a.dfops); + cur->bc_private.a.agbp, cur->bc_private.a.agno); } STATIC void @@ -323,8 +322,7 @@ xfs_refcountbt_init_cursor( struct xfs_mount *mp, struct xfs_trans *tp, struct xfs_buf *agbp, - xfs_agnumber_t agno, - struct xfs_defer_ops *dfops) + xfs_agnumber_t agno) { struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); struct xfs_btree_cur *cur; @@ -344,7 +342,6 @@ xfs_refcountbt_init_cursor( cur->bc_private.a.agbp = agbp; cur->bc_private.a.agno = agno; - cur->bc_private.a.dfops = dfops; cur->bc_flags |= XFS_BTREE_CRC_BLOCKS; cur->bc_private.a.priv.refc.nr_ops = 0; diff --git a/fs/xfs/libxfs/xfs_refcount_btree.h b/fs/xfs/libxfs/xfs_refcount_btree.h index d2852b6e1fa8..801c2c7732fd 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.h +++ b/fs/xfs/libxfs/xfs_refcount_btree.h @@ -44,8 +44,8 @@ struct xfs_mount; ((index) - 1) * sizeof(xfs_refcount_ptr_t))) extern struct xfs_btree_cur *xfs_refcountbt_init_cursor(struct xfs_mount *mp, - struct xfs_trans *tp, struct xfs_buf *agbp, xfs_agnumber_t agno, - struct xfs_defer_ops *dfops); + struct xfs_trans *tp, struct xfs_buf *agbp, + xfs_agnumber_t agno); extern int xfs_refcountbt_maxrecs(int blocklen, bool leaf); extern void xfs_refcountbt_compute_maxlevels(struct xfs_mount *mp); diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index 70e70c69f83f..385fa5b9c878 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -499,7 +499,7 @@ xfs_scrub_ag_btcur_init( /* Set up a refcountbt cursor for cross-referencing. */ if (sa->agf_bp && xfs_sb_version_hasreflink(&mp->m_sb)) { sa->refc_cur = xfs_refcountbt_init_cursor(mp, sc->tp, - sa->agf_bp, agno, NULL); + sa->agf_bp, agno); if (!sa->refc_cur) goto err; } diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c index c7157bc48bd1..297d7ce2901e 100644 --- a/fs/xfs/xfs_fsmap.c +++ b/fs/xfs/xfs_fsmap.c @@ -214,7 +214,7 @@ xfs_getfsmap_is_shared( /* Are there any shared blocks here? */ flen = 0; cur = xfs_refcountbt_init_cursor(mp, tp, info->agf_bp, - info->agno, NULL); + info->agno); error = xfs_refcount_find_shared(cur, rec->rm_startblock, rec->rm_blockcount, &fbno, &flen, false); diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 0ac0706c98e8..90457c2a7569 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -157,7 +157,7 @@ xfs_reflink_find_shared( if (!agbp) return -ENOMEM; - cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno, NULL); + cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno); error = xfs_refcount_find_shared(cur, agbno, aglen, fbno, flen, find_end_of_shared); -- cgit v1.2.3 From 7a7943c7e09546d4cc78b9756de23fd395b2cba4 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:17 -0700 Subject: xfs: use ->t_dfops for rmap extent swap operations xfs_swap_extent_rmap() uses a local dfops instance with a transaction from the caller. Since there is only one caller, pull the dfops structure into the caller and attach it to the transaction. This avoids the need to clear ->t_dfops to prevent invalid stack memory access. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_bmap_util.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index cd5d410acc73..6bea8df348bc 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1571,6 +1571,8 @@ xfs_swap_extent_rmap( struct xfs_inode *ip, struct xfs_inode *tip) { + struct xfs_trans *tp = *tpp; + struct xfs_mount *mp = tp->t_mountp; struct xfs_bmbt_irec irec; struct xfs_bmbt_irec uirec; struct xfs_bmbt_irec tirec; @@ -1578,7 +1580,6 @@ xfs_swap_extent_rmap( xfs_fileoff_t end_fsb; xfs_filblks_t count_fsb; xfs_fsblock_t firstfsb; - struct xfs_defer_ops dfops; int error; xfs_filblks_t ilen; xfs_filblks_t rlen; @@ -1614,7 +1615,7 @@ xfs_swap_extent_rmap( /* Unmap the old blocks in the source file. */ while (tirec.br_blockcount) { - xfs_defer_init(&dfops, &firstfsb); + xfs_defer_init(tp->t_dfops, &firstfsb); trace_xfs_swap_extent_rmap_remap_piece(tip, &tirec); /* Read extent from the source file */ @@ -1636,31 +1637,32 @@ xfs_swap_extent_rmap( trace_xfs_swap_extent_rmap_remap_piece(tip, &uirec); /* Remove the mapping from the donor file. */ - error = xfs_bmap_unmap_extent((*tpp)->t_mountp, &dfops, - tip, &uirec); + error = xfs_bmap_unmap_extent(mp, tp->t_dfops, tip, + &uirec); if (error) goto out_defer; /* Remove the mapping from the source file. */ - error = xfs_bmap_unmap_extent((*tpp)->t_mountp, &dfops, - ip, &irec); + error = xfs_bmap_unmap_extent(mp, tp->t_dfops, ip, + &irec); if (error) goto out_defer; /* Map the donor file's blocks into the source file. */ - error = xfs_bmap_map_extent((*tpp)->t_mountp, &dfops, - ip, &uirec); + error = xfs_bmap_map_extent(mp, tp->t_dfops, ip, + &uirec); if (error) goto out_defer; /* Map the source file's blocks into the donor file. */ - error = xfs_bmap_map_extent((*tpp)->t_mountp, &dfops, - tip, &irec); + error = xfs_bmap_map_extent(mp, tp->t_dfops, tip, + &irec); if (error) goto out_defer; - xfs_defer_ijoin(&dfops, ip); - error = xfs_defer_finish(tpp, &dfops); + xfs_defer_ijoin(tp->t_dfops, ip); + error = xfs_defer_finish(tpp, tp->t_dfops); + tp = *tpp; if (error) goto out_defer; @@ -1680,7 +1682,7 @@ xfs_swap_extent_rmap( return 0; out_defer: - xfs_defer_cancel(&dfops); + xfs_defer_cancel(tp->t_dfops); out: trace_xfs_swap_extent_rmap_error(ip, error, _RET_IP_); tip->i_d.di_flags2 = tip_flags2; @@ -1847,6 +1849,7 @@ xfs_swap_extents( { struct xfs_mount *mp = ip->i_mount; struct xfs_trans *tp; + struct xfs_defer_ops dfops; struct xfs_bstat *sbp = &sxp->sx_stat; int src_log_flags, target_log_flags; int error = 0; @@ -1854,6 +1857,7 @@ xfs_swap_extents( struct xfs_ifork *cowfp; uint64_t f; int resblks = 0; + xfs_fsblock_t firstfsb; /* * Lock the inodes against other IO, page faults and truncate to @@ -1916,6 +1920,8 @@ xfs_swap_extents( error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0, 0, &tp); if (error) goto out_unlock; + xfs_defer_init(&dfops, &firstfsb); + tp->t_dfops = &dfops; /* * Lock and join the inodes to the tansaction so that transaction commit -- cgit v1.2.3 From 27356a063a8572b2d3bf57d92b0a12399478958a Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:18 -0700 Subject: xfs: use ->t_dfops in cancel cow blocks operation Use ->t_dfops of the transaction from the caller. Reset it before we return to avoid leaks of local stack memory. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_reflink.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 90457c2a7569..8ea4ba0e45d8 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -490,6 +490,7 @@ xfs_reflink_cancel_cow_blocks( struct xfs_iext_cursor icur; xfs_fsblock_t firstfsb; struct xfs_defer_ops dfops; + struct xfs_defer_ops *odfops = (*tpp)->t_dfops; int error = 0; if (!xfs_is_reflink_inode(ip)) @@ -517,23 +518,24 @@ xfs_reflink_cancel_cow_blocks( break; } else if (del.br_state == XFS_EXT_UNWRITTEN || cancel_real) { xfs_defer_init(&dfops, &firstfsb); + (*tpp)->t_dfops = &dfops; /* Free the CoW orphan record. */ error = xfs_refcount_free_cow_extent(ip->i_mount, - &dfops, del.br_startblock, + (*tpp)->t_dfops, del.br_startblock, del.br_blockcount); if (error) break; - xfs_bmap_add_free(ip->i_mount, &dfops, + xfs_bmap_add_free(ip->i_mount, (*tpp)->t_dfops, del.br_startblock, del.br_blockcount, NULL); /* Roll the transaction */ - xfs_defer_ijoin(&dfops, ip); - error = xfs_defer_finish(tpp, &dfops); + xfs_defer_ijoin((*tpp)->t_dfops, ip); + error = xfs_defer_finish(tpp, (*tpp)->t_dfops); if (error) { - xfs_defer_cancel(&dfops); + xfs_defer_cancel((*tpp)->t_dfops); break; } @@ -558,7 +560,7 @@ next_extent: /* clear tag if cow fork is emptied */ if (!ifp->if_bytes) xfs_inode_clear_cowblocks_tag(ip); - + (*tpp)->t_dfops = odfops; return error; } -- cgit v1.2.3 From d5669ed58175f85d2c13e914c5c4e2bd3647d893 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:18 -0700 Subject: xfs: use ->t_dfops in reflink cow recover path Use ->t_dfops of the leftover COW reservation cleanup transaction. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_refcount.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index 8e330a196060..df67821fb5f4 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -1692,18 +1692,19 @@ xfs_refcount_recover_cow_leftovers( /* Free the orphan record */ xfs_defer_init(&dfops, &fsb); + tp->t_dfops = &dfops; agbno = rr->rr_rrec.rc_startblock - XFS_REFC_COW_START; fsb = XFS_AGB_TO_FSB(mp, agno, agbno); - error = xfs_refcount_free_cow_extent(mp, &dfops, fsb, + error = xfs_refcount_free_cow_extent(mp, tp->t_dfops, fsb, rr->rr_rrec.rc_blockcount); if (error) goto out_defer; /* Free the block. */ - xfs_bmap_add_free(mp, &dfops, fsb, + xfs_bmap_add_free(mp, tp->t_dfops, fsb, rr->rr_rrec.rc_blockcount, NULL); - error = xfs_defer_finish(&tp, &dfops); + error = xfs_defer_finish(&tp, tp->t_dfops); if (error) goto out_defer; @@ -1717,7 +1718,7 @@ xfs_refcount_recover_cow_leftovers( return error; out_defer: - xfs_defer_cancel(&dfops); + xfs_defer_cancel(tp->t_dfops); out_trans: xfs_trans_cancel(tp); out_free: -- cgit v1.2.3 From bcd2c9f33559764e0d306e226a8aa88bc2e1e6fb Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:19 -0700 Subject: xfs: refactor dfops init to attach to transaction Most callers of xfs_defer_init() immediately attach the dfops structure to a transaction. Add a transaction parameter to eliminate much of this boilerplate code. This also helps self-document the fact that many codepaths now expect a dfops pointer implicitly via xfs_trans->t_dfops. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr.c | 26 ++++++++++++++------------ fs/xfs/libxfs/xfs_attr_remote.c | 6 +++--- fs/xfs/libxfs/xfs_bmap.c | 6 ++---- fs/xfs/libxfs/xfs_defer.c | 9 ++++++++- fs/xfs/libxfs/xfs_defer.h | 3 ++- fs/xfs/libxfs/xfs_refcount.c | 3 +-- fs/xfs/xfs_bmap_util.c | 17 ++++++----------- fs/xfs/xfs_dquot.c | 5 ++--- fs/xfs/xfs_inode.c | 18 ++++++------------ fs/xfs/xfs_iomap.c | 9 +++------ fs/xfs/xfs_log_recover.c | 2 +- fs/xfs/xfs_reflink.c | 12 ++++-------- fs/xfs/xfs_rtalloc.c | 3 +-- fs/xfs/xfs_symlink.c | 6 ++---- 14 files changed, 55 insertions(+), 70 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index a14ab9b2669e..8a7e2c0308c4 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -253,8 +253,7 @@ xfs_attr_set( rsvd ? XFS_TRANS_RESERVE : 0, &args.trans); if (error) return error; - xfs_defer_init(&dfops, &firstblock); - args.trans->t_dfops = &dfops; + xfs_defer_init(args.trans, &dfops, &firstblock); xfs_ilock(dp, XFS_ILOCK_EXCL); error = xfs_trans_reserve_quota_nblks(args.trans, dp, args.total, 0, @@ -428,8 +427,7 @@ xfs_attr_remove( &args.trans); if (error) return error; - xfs_defer_init(&dfops, &firstblock); - args.trans->t_dfops = &dfops; + xfs_defer_init(args.trans, &dfops, &firstblock); xfs_ilock(dp, XFS_ILOCK_EXCL); /* @@ -600,7 +598,7 @@ xfs_attr_leaf_addname( * Commit that transaction so that the node_addname() call * can manage its own transactions. */ - xfs_defer_init(args->trans->t_dfops, args->firstblock); + xfs_defer_init(NULL, args->trans->t_dfops, args->firstblock); error = xfs_attr3_leaf_to_node(args); if (error) goto out_defer_cancel; @@ -689,7 +687,8 @@ xfs_attr_leaf_addname( * If the result is small enough, shrink it all into the inode. */ if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { - xfs_defer_init(args->trans->t_dfops, args->firstblock); + xfs_defer_init(NULL, args->trans->t_dfops, + args->firstblock); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (error) @@ -754,7 +753,7 @@ xfs_attr_leaf_removename( * If the result is small enough, shrink it all into the inode. */ if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { - xfs_defer_init(args->trans->t_dfops, args->firstblock); + xfs_defer_init(NULL, args->trans->t_dfops, args->firstblock); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (error) @@ -883,7 +882,8 @@ restart: */ xfs_da_state_free(state); state = NULL; - xfs_defer_init(args->trans->t_dfops, args->firstblock); + xfs_defer_init(NULL, args->trans->t_dfops, + args->firstblock); error = xfs_attr3_leaf_to_node(args); if (error) goto out_defer_cancel; @@ -910,7 +910,7 @@ restart: * in the index/blkno/rmtblkno/rmtblkcnt fields and * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields. */ - xfs_defer_init(args->trans->t_dfops, args->firstblock); + xfs_defer_init(NULL, args->trans->t_dfops, args->firstblock); error = xfs_da3_split(state); if (error) goto out_defer_cancel; @@ -1008,7 +1008,8 @@ restart: * Check to see if the tree needs to be collapsed. */ if (retval && (state->path.active > 1)) { - xfs_defer_init(args->trans->t_dfops, args->firstblock); + xfs_defer_init(NULL, args->trans->t_dfops, + args->firstblock); error = xfs_da3_join(state); if (error) goto out_defer_cancel; @@ -1133,7 +1134,7 @@ xfs_attr_node_removename( * Check to see if the tree needs to be collapsed. */ if (retval && (state->path.active > 1)) { - xfs_defer_init(args->trans->t_dfops, args->firstblock); + xfs_defer_init(NULL, args->trans->t_dfops, args->firstblock); error = xfs_da3_join(state); if (error) goto out_defer_cancel; @@ -1165,7 +1166,8 @@ xfs_attr_node_removename( goto out; if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { - xfs_defer_init(args->trans->t_dfops, args->firstblock); + xfs_defer_init(NULL, args->trans->t_dfops, + args->firstblock); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (error) diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index 179259fd1b5e..ab7c2755ad8c 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -480,7 +480,7 @@ xfs_attr_rmtval_set( * extent and then crash then the block may not contain the * correct metadata after log recovery occurs. */ - xfs_defer_init(args->trans->t_dfops, args->firstblock); + xfs_defer_init(NULL, args->trans->t_dfops, args->firstblock); nmap = 1; error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)lblkno, blkcnt, XFS_BMAPI_ATTRFORK, args->firstblock, @@ -522,7 +522,7 @@ xfs_attr_rmtval_set( ASSERT(blkcnt > 0); - xfs_defer_init(args->trans->t_dfops, args->firstblock); + xfs_defer_init(NULL, args->trans->t_dfops, args->firstblock); nmap = 1; error = xfs_bmapi_read(dp, (xfs_fileoff_t)lblkno, blkcnt, &map, &nmap, @@ -626,7 +626,7 @@ xfs_attr_rmtval_remove( blkcnt = args->rmtblkcnt; done = 0; while (!done) { - xfs_defer_init(args->trans->t_dfops, args->firstblock); + xfs_defer_init(NULL, args->trans->t_dfops, args->firstblock); error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, XFS_BMAPI_ATTRFORK, 1, args->firstblock, &done); diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 32d8d87b7582..dfff840c79f9 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -1050,8 +1050,7 @@ xfs_bmap_add_attrfork( rsvd ? XFS_TRANS_RESERVE : 0, &tp); if (error) return error; - xfs_defer_init(&dfops, &firstblock); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &firstblock); xfs_ilock(ip, XFS_ILOCK_EXCL); error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ? @@ -6025,8 +6024,7 @@ xfs_bmap_split_extent( XFS_DIOSTRAT_SPACE_RES(mp, 0), 0, 0, &tp); if (error) return error; - xfs_defer_init(&dfops, &firstfsb); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &firstfsb); xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index 560a7d178c1e..6b25a9436829 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -523,12 +523,19 @@ xfs_defer_init_op_type( /* Initialize a deferred operation. */ void xfs_defer_init( + struct xfs_trans *tp, struct xfs_defer_ops *dop, xfs_fsblock_t *fbp) { + struct xfs_mount *mp = NULL; + memset(dop, 0, sizeof(struct xfs_defer_ops)); *fbp = NULLFSBLOCK; INIT_LIST_HEAD(&dop->dop_intake); INIT_LIST_HEAD(&dop->dop_pending); - trace_xfs_defer_init(NULL, dop, _RET_IP_); + if (tp) { + tp->t_dfops = dop; + mp = tp->t_mountp; + } + trace_xfs_defer_init(mp, dop, _RET_IP_); } diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index a02b2b748b6d..56eaaac31df5 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h @@ -63,7 +63,8 @@ void xfs_defer_add(struct xfs_defer_ops *dop, enum xfs_defer_ops_type type, struct list_head *h); int xfs_defer_finish(struct xfs_trans **tp, struct xfs_defer_ops *dop); void xfs_defer_cancel(struct xfs_defer_ops *dop); -void xfs_defer_init(struct xfs_defer_ops *dop, xfs_fsblock_t *fbp); +void xfs_defer_init(struct xfs_trans *tp, struct xfs_defer_ops *dop, + xfs_fsblock_t *fbp); bool xfs_defer_has_unfinished_work(struct xfs_defer_ops *dop); int xfs_defer_ijoin(struct xfs_defer_ops *dop, struct xfs_inode *ip); int xfs_defer_bjoin(struct xfs_defer_ops *dop, struct xfs_buf *bp); diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index df67821fb5f4..8dc380574cd8 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -1691,8 +1691,7 @@ xfs_refcount_recover_cow_leftovers( trace_xfs_refcount_recover_extent(mp, agno, &rr->rr_rrec); /* Free the orphan record */ - xfs_defer_init(&dfops, &fsb); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &fsb); agbno = rr->rr_rrec.rc_startblock - XFS_REFC_COW_START; fsb = XFS_AGB_TO_FSB(mp, agno, agbno); error = xfs_refcount_free_cow_extent(mp, tp->t_dfops, fsb, diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 6bea8df348bc..1259e599158d 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -972,8 +972,7 @@ xfs_alloc_file_space( xfs_trans_ijoin(tp, ip, 0); - xfs_defer_init(&dfops, &firstfsb); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &firstfsb); error = xfs_bmapi_write(tp, ip, startoffset_fsb, allocatesize_fsb, alloc_type, &firstfsb, resblks, imapp, &nimaps); @@ -1043,8 +1042,7 @@ xfs_unmap_extent( xfs_trans_ijoin(tp, ip, 0); - xfs_defer_init(&dfops, &firstfsb); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &firstfsb); error = xfs_bunmapi(tp, ip, startoffset_fsb, len_fsb, 0, 2, &firstfsb, done); if (error) @@ -1347,8 +1345,7 @@ xfs_collapse_file_space( goto out_trans_cancel; xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); - xfs_defer_init(&dfops, &first_block); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &first_block); error = xfs_bmap_collapse_extents(tp, ip, &next_fsb, shift_fsb, &done, &first_block); if (error) @@ -1427,8 +1424,7 @@ xfs_insert_file_space( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); - xfs_defer_init(&dfops, &first_block); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &first_block); error = xfs_bmap_insert_extents(tp, ip, &next_fsb, shift_fsb, &done, stop_fsb, &first_block); if (error) @@ -1615,7 +1611,7 @@ xfs_swap_extent_rmap( /* Unmap the old blocks in the source file. */ while (tirec.br_blockcount) { - xfs_defer_init(tp->t_dfops, &firstfsb); + xfs_defer_init(tp, tp->t_dfops, &firstfsb); trace_xfs_swap_extent_rmap_remap_piece(tip, &tirec); /* Read extent from the source file */ @@ -1920,8 +1916,7 @@ xfs_swap_extents( error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0, 0, &tp); if (error) goto out_unlock; - xfs_defer_init(&dfops, &firstfsb); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &firstfsb); /* * Lock and join the inodes to the tansaction so that transaction commit diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 1ef38e1df679..c698e7f6f744 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -296,7 +296,7 @@ xfs_dquot_disk_alloc( trace_xfs_dqalloc(dqp); - xfs_defer_init(tp->t_dfops, &firstblock); + xfs_defer_init(tp, tp->t_dfops, &firstblock); xfs_ilock(quotip, XFS_ILOCK_EXCL); if (!xfs_this_quota_on(dqp->q_mount, dqp->dq_flags)) { @@ -549,8 +549,7 @@ xfs_qm_dqread_alloc( XFS_QM_DQALLOC_SPACE_RES(mp), 0, 0, &tp); if (error) goto err; - xfs_defer_init(&dfops, &firstblock); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &firstblock); error = xfs_dquot_disk_alloc(&tp, dqp, &bp); if (error) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index f456df2e1394..04e17234e5d7 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1195,8 +1195,7 @@ xfs_create( xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); unlock_dp_on_error = true; - xfs_defer_init(&dfops, &first_block); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &first_block); /* * Reserve disk quota and the inode. @@ -1451,8 +1450,7 @@ xfs_link( goto error_return; } - xfs_defer_init(&dfops, &first_block); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &first_block); /* * Handle initial link state of O_TMPFILE inode @@ -1584,8 +1582,7 @@ xfs_itruncate_extents_flags( ASSERT(first_unmap_block < last_block); unmap_len = last_block - first_unmap_block + 1; while (!done) { - xfs_defer_init(&dfops, &first_block); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &first_block); error = xfs_bunmapi(tp, ip, first_unmap_block, unmap_len, flags, XFS_ITRUNC_MAX_EXTENTS, &first_block, &done); @@ -1816,8 +1813,7 @@ xfs_inactive_ifree( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, 0); - xfs_defer_init(&dfops, &first_block); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &first_block); error = xfs_ifree(tp, ip); if (error) { /* @@ -2661,8 +2657,7 @@ xfs_remove( if (error) goto out_trans_cancel; - xfs_defer_init(&dfops, &first_block); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &first_block); error = xfs_dir_removename(tp, dp, name, ip->i_ino, &first_block, resblks); if (error) { @@ -3026,8 +3021,7 @@ xfs_rename( goto out_trans_cancel; } - xfs_defer_init(&dfops, &first_block); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &first_block); /* RENAME_EXCHANGE is unique from here on. */ if (flags & RENAME_EXCHANGE) diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 0c736c938f52..777c349607b3 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -254,8 +254,7 @@ xfs_iomap_write_direct( * From this point onwards we overwrite the imap pointer that the * caller gave to us. */ - xfs_defer_init(&dfops, &firstfsb); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &firstfsb); nimaps = 1; error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, bmapi_flags, &firstfsb, resblks, imap, @@ -717,8 +716,7 @@ xfs_iomap_write_allocate( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, 0); - xfs_defer_init(&dfops, &first_block); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &first_block); /* * it is possible that the extents have changed since @@ -878,8 +876,7 @@ xfs_iomap_write_unwritten( /* * Modify the unwritten extent state of the buffer. */ - xfs_defer_init(&dfops, &firstfsb); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &firstfsb); nimaps = 1; error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, XFS_BMAPI_CONVERT, &firstfsb, resblks, diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index b181b5f57a19..940eb30e0271 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4902,7 +4902,7 @@ xlog_recover_process_intents( #if defined(DEBUG) || defined(XFS_WARN) last_lsn = xlog_assign_lsn(log->l_curr_cycle, log->l_curr_block); #endif - xfs_defer_init(&dfops, &firstfsb); + xfs_defer_init(NULL, &dfops, &firstfsb); while (lip != NULL) { /* * We're done when we see something other than an intent. diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 8ea4ba0e45d8..bef780171962 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -428,8 +428,7 @@ retry: xfs_trans_ijoin(tp, ip, 0); - xfs_defer_init(&dfops, &first_block); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &first_block); nimaps = 1; /* Allocate the entire reservation as unwritten blocks. */ @@ -517,8 +516,7 @@ xfs_reflink_cancel_cow_blocks( if (error) break; } else if (del.br_state == XFS_EXT_UNWRITTEN || cancel_real) { - xfs_defer_init(&dfops, &firstfsb); - (*tpp)->t_dfops = &dfops; + xfs_defer_init(*tpp, &dfops, &firstfsb); /* Free the CoW orphan record. */ error = xfs_refcount_free_cow_extent(ip->i_mount, @@ -701,8 +699,7 @@ xfs_reflink_end_cow( goto prev_extent; /* Unmap the old blocks in the data fork. */ - xfs_defer_init(&dfops, &firstfsb); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &firstfsb); rlen = del.br_blockcount; error = __xfs_bunmapi(tp, ip, del.br_startoff, &rlen, 0, 1, &firstfsb); @@ -1052,8 +1049,7 @@ xfs_reflink_remap_extent( /* Unmap the old blocks in the data fork. */ rlen = unmap_len; while (rlen) { - xfs_defer_init(&dfops, &firstfsb); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &firstfsb); error = __xfs_bunmapi(tp, ip, destoff, &rlen, 0, 1, &firstfsb); if (error) goto out_defer; diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 1c7d1238ff3b..c102b0d26bc1 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -787,8 +787,7 @@ xfs_growfs_rt_alloc( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); - xfs_defer_init(&dfops, &firstblock); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &firstblock); /* * Allocate blocks to the bitmap file. */ diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index a54f095c1409..e50e97308f81 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -246,8 +246,7 @@ xfs_symlink( * Initialize the bmap freelist prior to calling either * bmapi or the directory create code. */ - xfs_defer_init(&dfops, &first_block); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &first_block); /* * Allocate an inode for the symlink. @@ -443,8 +442,7 @@ xfs_inactive_symlink_rmt( * Find the block(s) so we can inval and unmap them. */ done = 0; - xfs_defer_init(&dfops, &first_block); - tp->t_dfops = &dfops; + xfs_defer_init(tp, &dfops, &first_block); nmaps = ARRAY_SIZE(mval); error = xfs_bmapi_read(ip, 0, xfs_symlink_blocks(mp, size), mval, &nmaps, 0); -- cgit v1.2.3 From 3ae2d89174e4ba581093320afb48421ca95191d2 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:19 -0700 Subject: xfs: allow null firstblock in xfs_bmapi_write() when tp is null xfs_bmapi_write() always expects a valid firstblock pointer. It immediately dereferences the pointer to help determine how to initialize the bma.minleft field. The remaining accesses are related to modifying btree format forks, which is only relevant for !COW fork callers. The reflink code passes a NULL transaction to xfs_bmapi_write() in a couple places that do COW fork unwritten conversion. The purpose of the firstblock field is to track the first block allocation in the current transaction, so technically firstblock should not be required for these callers either. Tweak xfs_bmapi_write() to initialize the bma correctly without accessing the firstblock pointer if no transaction is provided in the first place. Update the reflink callers to pass NULL instead of otherwise unused firstblock references. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 2 +- fs/xfs/xfs_reflink.c | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index dfff840c79f9..0b476a8e751c 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -4302,7 +4302,7 @@ xfs_bmapi_write( XFS_STATS_INC(mp, xs_blk_mapw); - if (*firstblock == NULLFSBLOCK) { + if (!tp || *firstblock == NULLFSBLOCK) { if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE) bma.minleft = be16_to_cpu(ifp->if_broot->bb_level) + 1; else diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index bef780171962..b1bc2eb54a14 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -314,7 +314,6 @@ xfs_reflink_convert_cow_extent( xfs_fileoff_t offset_fsb, xfs_filblks_t count_fsb) { - xfs_fsblock_t first_block = NULLFSBLOCK; int nimaps = 1; if (imap->br_state == XFS_EXT_NORM) @@ -325,8 +324,8 @@ xfs_reflink_convert_cow_extent( if (imap->br_blockcount == 0) return 0; return xfs_bmapi_write(NULL, ip, imap->br_startoff, imap->br_blockcount, - XFS_BMAPI_COWFORK | XFS_BMAPI_CONVERT, &first_block, - 0, imap, &nimaps); + XFS_BMAPI_COWFORK | XFS_BMAPI_CONVERT, NULL, 0, imap, + &nimaps); } /* Convert all of the unwritten CoW extents in a file's range to real ones. */ @@ -341,7 +340,6 @@ xfs_reflink_convert_cow( xfs_fileoff_t end_fsb = XFS_B_TO_FSB(mp, offset + count); xfs_filblks_t count_fsb = end_fsb - offset_fsb; struct xfs_bmbt_irec imap; - xfs_fsblock_t first_block = NULLFSBLOCK; int nimaps = 1, error = 0; ASSERT(count != 0); @@ -349,8 +347,7 @@ xfs_reflink_convert_cow( xfs_ilock(ip, XFS_ILOCK_EXCL); error = xfs_bmapi_write(NULL, ip, offset_fsb, count_fsb, XFS_BMAPI_COWFORK | XFS_BMAPI_CONVERT | - XFS_BMAPI_CONVERT_ONLY, &first_block, 0, &imap, - &nimaps); + XFS_BMAPI_CONVERT_ONLY, NULL, 0, &imap, &nimaps); xfs_iunlock(ip, XFS_ILOCK_EXCL); return error; } -- cgit v1.2.3 From bba59c5e4b38e160c6be25b2f4fe36ebc84f53df Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:20 -0700 Subject: xfs: add firstblock field to xfs_trans A firstblock var is typically allocated and initialized along with xfs_defer_ops structures and passed around independent from the associated transaction. To facilitate combining the two, add an optional ->t_firstblock field to xfs_trans that can be used in place of an on-stack variable. The firstblock value follows the lifetime of the transaction, so initialize it on allocation and when a transaction rolls. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_trans.c | 2 ++ fs/xfs/xfs_trans.h | 1 + 2 files changed, 3 insertions(+) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 630993387517..de00f79ff698 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -100,6 +100,7 @@ xfs_trans_dup( ntp->t_mountp = tp->t_mountp; INIT_LIST_HEAD(&ntp->t_items); INIT_LIST_HEAD(&ntp->t_busy); + ntp->t_firstblock = NULLFSBLOCK; ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); ASSERT(tp->t_ticket != NULL); @@ -273,6 +274,7 @@ xfs_trans_alloc( tp->t_mountp = mp; INIT_LIST_HEAD(&tp->t_items); INIT_LIST_HEAD(&tp->t_busy); + tp->t_firstblock = NULLFSBLOCK; error = xfs_trans_reserve(tp, resp, blocks, rtextents); if (error) { diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index d8a695c57103..37fdacc690c7 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -102,6 +102,7 @@ typedef struct xfs_trans { unsigned int t_blk_res_used; /* # of resvd blocks used */ unsigned int t_rtx_res; /* # of rt extents resvd */ unsigned int t_rtx_res_used; /* # of resvd rt extents used */ + xfs_fsblock_t t_firstblock; /* first block allocated */ struct xlog_ticket *t_ticket; /* log mgr ticket */ struct xfs_mount *t_mountp; /* ptr to fs mount struct */ struct xfs_dquot_acct *t_dqinfo; /* acctg info for dquots */ -- cgit v1.2.3 From f16dea54b789aad464ae4f34caea9f8d81052729 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:20 -0700 Subject: xfs: use ->t_firstblock in dir ops Callers of the xfs_dir_*() functions currently pass an on-stack firstblock variable. While the dirops infrastructure carries a pointer to this variable, it never rolls the transaction and so it is safe to use ->t_firstblock instead. Fix up the various xfs_dir_*() callers to use ->t_firstblock. Also remove the unnecessary parameter for xfs_cross_rename(). Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_inode.c | 42 +++++++++++++++++++----------------------- fs/xfs/xfs_symlink.c | 9 ++++----- 2 files changed, 23 insertions(+), 28 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 04e17234e5d7..6a3fe2d3df6c 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1143,7 +1143,6 @@ xfs_create( struct xfs_trans *tp = NULL; int error; struct xfs_defer_ops dfops; - xfs_fsblock_t first_block; bool unlock_dp_on_error = false; prid_t prid; struct xfs_dquot *udqp = NULL; @@ -1195,7 +1194,7 @@ xfs_create( xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); unlock_dp_on_error = true; - xfs_defer_init(tp, &dfops, &first_block); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); /* * Reserve disk quota and the inode. @@ -1224,7 +1223,7 @@ xfs_create( xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); unlock_dp_on_error = false; - error = xfs_dir_createname(tp, dp, name, ip->i_ino, &first_block, + error = xfs_dir_createname(tp, dp, name, ip->i_ino, &tp->t_firstblock, resblks ? resblks - XFS_IALLOC_SPACE_RES(mp) : 0); if (error) { @@ -1401,7 +1400,6 @@ xfs_link( xfs_trans_t *tp; int error; struct xfs_defer_ops dfops; - xfs_fsblock_t first_block; int resblks; trace_xfs_link(tdp, target_name); @@ -1450,7 +1448,7 @@ xfs_link( goto error_return; } - xfs_defer_init(tp, &dfops, &first_block); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); /* * Handle initial link state of O_TMPFILE inode @@ -1462,7 +1460,7 @@ xfs_link( } error = xfs_dir_createname(tp, tdp, target_name, sip->i_ino, - &first_block, resblks); + &tp->t_firstblock, resblks); if (error) goto error_return; xfs_trans_ichgtime(tp, tdp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); @@ -2577,7 +2575,6 @@ xfs_remove( int is_dir = S_ISDIR(VFS_I(ip)->i_mode); int error = 0; struct xfs_defer_ops dfops; - xfs_fsblock_t first_block; uint resblks; trace_xfs_remove(dp, name); @@ -2657,8 +2654,8 @@ xfs_remove( if (error) goto out_trans_cancel; - xfs_defer_init(tp, &dfops, &first_block); - error = xfs_dir_removename(tp, dp, name, ip->i_ino, &first_block, + xfs_defer_init(tp, &dfops, &tp->t_firstblock); + error = xfs_dir_removename(tp, dp, name, ip->i_ino, &tp->t_firstblock, resblks); if (error) { ASSERT(error != -ENOENT); @@ -2783,7 +2780,6 @@ xfs_cross_rename( struct xfs_inode *dp2, struct xfs_name *name2, struct xfs_inode *ip2, - xfs_fsblock_t *first_block, int spaceres) { int error = 0; @@ -2792,13 +2788,13 @@ xfs_cross_rename( int dp2_flags = 0; /* Swap inode number for dirent in first parent */ - error = xfs_dir_replace(tp, dp1, name1, ip2->i_ino, first_block, + error = xfs_dir_replace(tp, dp1, name1, ip2->i_ino, &tp->t_firstblock, spaceres); if (error) goto out_trans_abort; /* Swap inode number for dirent in second parent */ - error = xfs_dir_replace(tp, dp2, name2, ip1->i_ino, first_block, + error = xfs_dir_replace(tp, dp2, name2, ip1->i_ino, &tp->t_firstblock, spaceres); if (error) goto out_trans_abort; @@ -2813,7 +2809,7 @@ xfs_cross_rename( if (S_ISDIR(VFS_I(ip2)->i_mode)) { error = xfs_dir_replace(tp, ip2, &xfs_name_dotdot, - dp1->i_ino, first_block, + dp1->i_ino, &tp->t_firstblock, spaceres); if (error) goto out_trans_abort; @@ -2840,7 +2836,7 @@ xfs_cross_rename( if (S_ISDIR(VFS_I(ip1)->i_mode)) { error = xfs_dir_replace(tp, ip1, &xfs_name_dotdot, - dp2->i_ino, first_block, + dp2->i_ino, &tp->t_firstblock, spaceres); if (error) goto out_trans_abort; @@ -2939,7 +2935,6 @@ xfs_rename( struct xfs_mount *mp = src_dp->i_mount; struct xfs_trans *tp; struct xfs_defer_ops dfops; - xfs_fsblock_t first_block; struct xfs_inode *wip = NULL; /* whiteout inode */ struct xfs_inode *inodes[__XFS_SORT_INODES]; int num_inodes = __XFS_SORT_INODES; @@ -3021,13 +3016,13 @@ xfs_rename( goto out_trans_cancel; } - xfs_defer_init(tp, &dfops, &first_block); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); /* RENAME_EXCHANGE is unique from here on. */ if (flags & RENAME_EXCHANGE) return xfs_cross_rename(tp, src_dp, src_name, src_ip, target_dp, target_name, target_ip, - &first_block, spaceres); + spaceres); /* * Set up the target. @@ -3048,8 +3043,8 @@ xfs_rename( * to account for the ".." reference from the new entry. */ error = xfs_dir_createname(tp, target_dp, target_name, - src_ip->i_ino, &first_block, - spaceres); + src_ip->i_ino, &tp->t_firstblock, + spaceres); if (error) goto out_bmap_cancel; @@ -3088,7 +3083,8 @@ xfs_rename( * name at the destination directory, remove it first. */ error = xfs_dir_replace(tp, target_dp, target_name, - src_ip->i_ino, &first_block, spaceres); + src_ip->i_ino, &tp->t_firstblock, + spaceres); if (error) goto out_bmap_cancel; @@ -3122,7 +3118,7 @@ xfs_rename( * directory. */ error = xfs_dir_replace(tp, src_ip, &xfs_name_dotdot, - target_dp->i_ino, &first_block, + target_dp->i_ino, &tp->t_firstblock, spaceres); ASSERT(error != -EEXIST); if (error) @@ -3162,10 +3158,10 @@ xfs_rename( */ if (wip) { error = xfs_dir_replace(tp, src_dp, src_name, wip->i_ino, - &first_block, spaceres); + &tp->t_firstblock, spaceres); } else error = xfs_dir_removename(tp, src_dp, src_name, src_ip->i_ino, - &first_block, spaceres); + &tp->t_firstblock, spaceres); if (error) goto out_bmap_cancel; diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index e50e97308f81..8ddc7f1147dc 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -164,7 +164,6 @@ xfs_symlink( int error = 0; int pathlen; struct xfs_defer_ops dfops; - xfs_fsblock_t first_block; bool unlock_dp_on_error = false; xfs_fileoff_t first_fsb; xfs_filblks_t fs_blocks; @@ -246,7 +245,7 @@ xfs_symlink( * Initialize the bmap freelist prior to calling either * bmapi or the directory create code. */ - xfs_defer_init(tp, &dfops, &first_block); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); /* * Allocate an inode for the symlink. @@ -289,8 +288,8 @@ xfs_symlink( nmaps = XFS_SYMLINK_MAPS; error = xfs_bmapi_write(tp, ip, first_fsb, fs_blocks, - XFS_BMAPI_METADATA, &first_block, resblks, - mval, &nmaps); + XFS_BMAPI_METADATA, &tp->t_firstblock, + resblks, mval, &nmaps); if (error) goto out_bmap_cancel; @@ -338,7 +337,7 @@ xfs_symlink( * Create the directory entry for the symlink. */ error = xfs_dir_createname(tp, dp, link_name, ip->i_ino, - &first_block, resblks); + &tp->t_firstblock, resblks); if (error) goto out_bmap_cancel; xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); -- cgit v1.2.3 From 381eee69f862d38bef468e91517e37fc53f60885 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:21 -0700 Subject: xfs: remove firstblock param from xfs dir ops All callers of the xfs_dir_*() functions pass ->t_firstblock as the firstblock parameter. Drop the parameter and access ->t_firstblock directly. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_dir2.c | 12 ++++-------- fs/xfs/libxfs/xfs_dir2.h | 6 +++--- fs/xfs/xfs_inode.c | 32 ++++++++++++-------------------- fs/xfs/xfs_symlink.c | 3 +-- 4 files changed, 20 insertions(+), 33 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 781dc63d305d..a3983e3eb64a 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -243,7 +243,6 @@ xfs_dir_createname( struct xfs_inode *dp, struct xfs_name *name, xfs_ino_t inum, /* new entry inode number */ - xfs_fsblock_t *first, /* bmap's firstblock */ xfs_extlen_t total) /* bmap's total block count */ { struct xfs_da_args *args; @@ -251,7 +250,6 @@ xfs_dir_createname( int v; /* type-checking value */ ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); - ASSERT(tp->t_dfops || !first); if (inum) { rval = xfs_dir_ino_validate(tp->t_mountp, inum); @@ -274,7 +272,7 @@ xfs_dir_createname( args->total = total; args->whichfork = XFS_DATA_FORK; args->trans = tp; - args->firstblock = first; + args->firstblock = &tp->t_firstblock; args->op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; if (!inum) args->op_flags |= XFS_DA_OP_JUSTCHECK; @@ -420,7 +418,6 @@ xfs_dir_removename( struct xfs_inode *dp, struct xfs_name *name, xfs_ino_t ino, - xfs_fsblock_t *first, /* bmap's firstblock */ xfs_extlen_t total) /* bmap's total block count */ { struct xfs_da_args *args; @@ -442,7 +439,7 @@ xfs_dir_removename( args->hashval = dp->i_mount->m_dirnameops->hashname(name); args->inumber = ino; args->dp = dp; - args->firstblock = first; + args->firstblock = &tp->t_firstblock; args->total = total; args->whichfork = XFS_DATA_FORK; args->trans = tp; @@ -481,7 +478,6 @@ xfs_dir_replace( struct xfs_inode *dp, struct xfs_name *name, /* name of entry to replace */ xfs_ino_t inum, /* new inode number */ - xfs_fsblock_t *first, /* bmap's firstblock */ xfs_extlen_t total) /* bmap's total block count */ { struct xfs_da_args *args; @@ -506,7 +502,7 @@ xfs_dir_replace( args->hashval = dp->i_mount->m_dirnameops->hashname(name); args->inumber = inum; args->dp = dp; - args->firstblock = first; + args->firstblock = &tp->t_firstblock; args->total = total; args->whichfork = XFS_DATA_FORK; args->trans = tp; @@ -545,7 +541,7 @@ xfs_dir_canenter( xfs_inode_t *dp, struct xfs_name *name) /* name of entry to add */ { - return xfs_dir_createname(tp, dp, name, 0, NULL, 0); + return xfs_dir_createname(tp, dp, name, 0, 0); } /* diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index f203aebc07ed..ba5acd03de94 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -118,16 +118,16 @@ extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_inode *pdp); extern int xfs_dir_createname(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_name *name, xfs_ino_t inum, - xfs_fsblock_t *first, xfs_extlen_t tot); + xfs_extlen_t tot); extern int xfs_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_name *name, xfs_ino_t *inum, struct xfs_name *ci_name); extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_name *name, xfs_ino_t ino, - xfs_fsblock_t *first, xfs_extlen_t tot); + xfs_extlen_t tot); extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_name *name, xfs_ino_t inum, - xfs_fsblock_t *first, xfs_extlen_t tot); + xfs_extlen_t tot); extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_name *name); diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 6a3fe2d3df6c..ab1fd696500c 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1223,7 +1223,7 @@ xfs_create( xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); unlock_dp_on_error = false; - error = xfs_dir_createname(tp, dp, name, ip->i_ino, &tp->t_firstblock, + error = xfs_dir_createname(tp, dp, name, ip->i_ino, resblks ? resblks - XFS_IALLOC_SPACE_RES(mp) : 0); if (error) { @@ -1460,7 +1460,7 @@ xfs_link( } error = xfs_dir_createname(tp, tdp, target_name, sip->i_ino, - &tp->t_firstblock, resblks); + resblks); if (error) goto error_return; xfs_trans_ichgtime(tp, tdp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); @@ -2655,8 +2655,7 @@ xfs_remove( goto out_trans_cancel; xfs_defer_init(tp, &dfops, &tp->t_firstblock); - error = xfs_dir_removename(tp, dp, name, ip->i_ino, &tp->t_firstblock, - resblks); + error = xfs_dir_removename(tp, dp, name, ip->i_ino, resblks); if (error) { ASSERT(error != -ENOENT); goto out_bmap_cancel; @@ -2788,14 +2787,12 @@ xfs_cross_rename( int dp2_flags = 0; /* Swap inode number for dirent in first parent */ - error = xfs_dir_replace(tp, dp1, name1, ip2->i_ino, &tp->t_firstblock, - spaceres); + error = xfs_dir_replace(tp, dp1, name1, ip2->i_ino, spaceres); if (error) goto out_trans_abort; /* Swap inode number for dirent in second parent */ - error = xfs_dir_replace(tp, dp2, name2, ip1->i_ino, &tp->t_firstblock, - spaceres); + error = xfs_dir_replace(tp, dp2, name2, ip1->i_ino, spaceres); if (error) goto out_trans_abort; @@ -2809,8 +2806,7 @@ xfs_cross_rename( if (S_ISDIR(VFS_I(ip2)->i_mode)) { error = xfs_dir_replace(tp, ip2, &xfs_name_dotdot, - dp1->i_ino, &tp->t_firstblock, - spaceres); + dp1->i_ino, spaceres); if (error) goto out_trans_abort; @@ -2836,8 +2832,7 @@ xfs_cross_rename( if (S_ISDIR(VFS_I(ip1)->i_mode)) { error = xfs_dir_replace(tp, ip1, &xfs_name_dotdot, - dp2->i_ino, &tp->t_firstblock, - spaceres); + dp2->i_ino, spaceres); if (error) goto out_trans_abort; @@ -3043,8 +3038,7 @@ xfs_rename( * to account for the ".." reference from the new entry. */ error = xfs_dir_createname(tp, target_dp, target_name, - src_ip->i_ino, &tp->t_firstblock, - spaceres); + src_ip->i_ino, spaceres); if (error) goto out_bmap_cancel; @@ -3083,8 +3077,7 @@ xfs_rename( * name at the destination directory, remove it first. */ error = xfs_dir_replace(tp, target_dp, target_name, - src_ip->i_ino, &tp->t_firstblock, - spaceres); + src_ip->i_ino, spaceres); if (error) goto out_bmap_cancel; @@ -3118,8 +3111,7 @@ xfs_rename( * directory. */ error = xfs_dir_replace(tp, src_ip, &xfs_name_dotdot, - target_dp->i_ino, &tp->t_firstblock, - spaceres); + target_dp->i_ino, spaceres); ASSERT(error != -EEXIST); if (error) goto out_bmap_cancel; @@ -3158,10 +3150,10 @@ xfs_rename( */ if (wip) { error = xfs_dir_replace(tp, src_dp, src_name, wip->i_ino, - &tp->t_firstblock, spaceres); + spaceres); } else error = xfs_dir_removename(tp, src_dp, src_name, src_ip->i_ino, - &tp->t_firstblock, spaceres); + spaceres); if (error) goto out_bmap_cancel; diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 8ddc7f1147dc..583ca83353f7 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -336,8 +336,7 @@ xfs_symlink( /* * Create the directory entry for the symlink. */ - error = xfs_dir_createname(tp, dp, link_name, ip->i_ino, - &tp->t_firstblock, resblks); + error = xfs_dir_createname(tp, dp, link_name, ip->i_ino, resblks); if (error) goto out_bmap_cancel; xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); -- cgit v1.2.3 From 825d75cd8c1b53883dd8c2fe1d8833c371b08074 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:21 -0700 Subject: xfs: use ->t_firstblock in attrfork add Note that this codepath is a user of struct xfs_da_args. Switch it over to ->t_firstblock in preparation to remove xfs_da_args.firstblock. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 0b476a8e751c..da73c1a011d3 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -915,7 +915,6 @@ STATIC int /* error */ xfs_bmap_add_attrfork_btree( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode pointer */ - xfs_fsblock_t *firstblock, /* first block allocated */ int *flags) /* inode logging flags */ { xfs_btree_cur_t *cur; /* btree cursor */ @@ -928,7 +927,7 @@ xfs_bmap_add_attrfork_btree( *flags |= XFS_ILOG_DBROOT; else { cur = xfs_bmbt_init_cursor(mp, tp, ip, XFS_DATA_FORK); - cur->bc_private.b.firstblock = *firstblock; + cur->bc_private.b.firstblock = tp->t_firstblock; error = xfs_bmbt_lookup_first(cur, &stat); if (error) goto error0; @@ -940,7 +939,7 @@ xfs_bmap_add_attrfork_btree( xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); return -ENOSPC; } - *firstblock = cur->bc_private.b.firstblock; + tp->t_firstblock = cur->bc_private.b.firstblock; cur->bc_private.b.allocated = 0; xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); } @@ -957,7 +956,6 @@ STATIC int /* error */ xfs_bmap_add_attrfork_extents( struct xfs_trans *tp, /* transaction pointer */ struct xfs_inode *ip, /* incore inode pointer */ - xfs_fsblock_t *firstblock, /* first block allocated */ int *flags) /* inode logging flags */ { xfs_btree_cur_t *cur; /* bmap btree cursor */ @@ -966,8 +964,8 @@ xfs_bmap_add_attrfork_extents( if (ip->i_d.di_nextents * sizeof(xfs_bmbt_rec_t) <= XFS_IFORK_DSIZE(ip)) return 0; cur = NULL; - error = xfs_bmap_extents_to_btree(tp, ip, firstblock, &cur, 0, flags, - XFS_DATA_FORK); + error = xfs_bmap_extents_to_btree(tp, ip, &tp->t_firstblock, &cur, 0, + flags, XFS_DATA_FORK); if (cur) { cur->bc_private.b.allocated = 0; xfs_btree_del_cursor(cur, @@ -989,12 +987,11 @@ xfs_bmap_add_attrfork_extents( */ STATIC int /* error */ xfs_bmap_add_attrfork_local( - xfs_trans_t *tp, /* transaction pointer */ - xfs_inode_t *ip, /* incore inode pointer */ - xfs_fsblock_t *firstblock, /* first block allocated */ + struct xfs_trans *tp, /* transaction pointer */ + struct xfs_inode *ip, /* incore inode pointer */ int *flags) /* inode logging flags */ { - xfs_da_args_t dargs; /* args for dir/attr code */ + struct xfs_da_args dargs; /* args for dir/attr code */ if (ip->i_df.if_bytes <= XFS_IFORK_DSIZE(ip)) return 0; @@ -1003,7 +1000,7 @@ xfs_bmap_add_attrfork_local( memset(&dargs, 0, sizeof(dargs)); dargs.geo = ip->i_mount->m_dir_geo; dargs.dp = ip; - dargs.firstblock = firstblock; + dargs.firstblock = &tp->t_firstblock; dargs.total = dargs.geo->fsbcount; dargs.whichfork = XFS_DATA_FORK; dargs.trans = tp; @@ -1011,7 +1008,7 @@ xfs_bmap_add_attrfork_local( } if (S_ISLNK(VFS_I(ip)->i_mode)) - return xfs_bmap_local_to_extents(tp, ip, firstblock, 1, + return xfs_bmap_local_to_extents(tp, ip, &tp->t_firstblock, 1, flags, XFS_DATA_FORK, xfs_symlink_local_to_remote); @@ -1030,7 +1027,6 @@ xfs_bmap_add_attrfork( int size, /* space new attribute needs */ int rsvd) /* xact may use reserved blks */ { - xfs_fsblock_t firstblock; /* 1st block/ag allocated */ struct xfs_defer_ops dfops; /* freed extent records */ xfs_mount_t *mp; /* mount structure */ xfs_trans_t *tp; /* transaction pointer */ @@ -1050,7 +1046,7 @@ xfs_bmap_add_attrfork( rsvd ? XFS_TRANS_RESERVE : 0, &tp); if (error) return error; - xfs_defer_init(tp, &dfops, &firstblock); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); xfs_ilock(ip, XFS_ILOCK_EXCL); error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ? @@ -1100,16 +1096,13 @@ xfs_bmap_add_attrfork( logflags = 0; switch (ip->i_d.di_format) { case XFS_DINODE_FMT_LOCAL: - error = xfs_bmap_add_attrfork_local(tp, ip, &firstblock, - &logflags); + error = xfs_bmap_add_attrfork_local(tp, ip, &logflags); break; case XFS_DINODE_FMT_EXTENTS: - error = xfs_bmap_add_attrfork_extents(tp, ip, &firstblock, - &logflags); + error = xfs_bmap_add_attrfork_extents(tp, ip, &logflags); break; case XFS_DINODE_FMT_BTREE: - error = xfs_bmap_add_attrfork_btree(tp, ip, &firstblock, - &logflags); + error = xfs_bmap_add_attrfork_btree(tp, ip, &logflags); break; default: error = 0; -- cgit v1.2.3 From 766139032f95bb41031f6de9c2ee0538bd035229 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:22 -0700 Subject: xfs: use ->t_firstblock in xattr ops Similar to the dirops code, the xattr code uses an on-stack firstblock variable for the various operations. This code rolls the underlying transaction in various places, however, which means we cannot simply replace the local firstblock vars with ->t_firstblock. Doing so (without further changes) would invalidate the memory pointed to by xfs_da_args.firstblock as soon as the first transaction rolls. To avoid this problem, remove xfs_da_args.firstblock and replace all such accesses with ->t_firstblock at the same time. This ensures that accesses to the current firstblock always occur through the current transaction rather than a potentially invalid xfs_da_args pointer. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr.c | 37 ++++++++++++++++++------------------- fs/xfs/libxfs/xfs_attr_leaf.c | 2 -- fs/xfs/libxfs/xfs_attr_remote.c | 18 +++++++++++------- fs/xfs/libxfs/xfs_bmap.c | 1 - fs/xfs/libxfs/xfs_da_btree.c | 7 +++---- fs/xfs/libxfs/xfs_da_btree.h | 1 - fs/xfs/libxfs/xfs_dir2.c | 5 +---- 7 files changed, 33 insertions(+), 38 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 8a7e2c0308c4..153d2e29f872 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -204,7 +204,6 @@ xfs_attr_set( struct xfs_da_args args; struct xfs_defer_ops dfops; struct xfs_trans_res tres; - xfs_fsblock_t firstblock; int rsvd = (flags & ATTR_ROOT) != 0; int error, err2, local; @@ -219,7 +218,6 @@ xfs_attr_set( args.value = value; args.valuelen = valuelen; - args.firstblock = &firstblock; args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; args.total = xfs_attr_calc_size(&args, &local); @@ -253,7 +251,7 @@ xfs_attr_set( rsvd ? XFS_TRANS_RESERVE : 0, &args.trans); if (error) return error; - xfs_defer_init(args.trans, &dfops, &firstblock); + xfs_defer_init(args.trans, &dfops, &args.trans->t_firstblock); xfs_ilock(dp, XFS_ILOCK_EXCL); error = xfs_trans_reserve_quota_nblks(args.trans, dp, args.total, 0, @@ -392,7 +390,6 @@ xfs_attr_remove( struct xfs_mount *mp = dp->i_mount; struct xfs_da_args args; struct xfs_defer_ops dfops; - xfs_fsblock_t firstblock; int error; XFS_STATS_INC(mp, xs_attr_remove); @@ -404,8 +401,6 @@ xfs_attr_remove( if (error) return error; - args.firstblock = &firstblock; - /* * we have no control over the attribute names that userspace passes us * to remove, so we have to allow the name lookup prior to attribute @@ -427,7 +422,7 @@ xfs_attr_remove( &args.trans); if (error) return error; - xfs_defer_init(args.trans, &dfops, &firstblock); + xfs_defer_init(args.trans, &dfops, &args.trans->t_firstblock); xfs_ilock(dp, XFS_ILOCK_EXCL); /* @@ -598,7 +593,8 @@ xfs_attr_leaf_addname( * Commit that transaction so that the node_addname() call * can manage its own transactions. */ - xfs_defer_init(NULL, args->trans->t_dfops, args->firstblock); + xfs_defer_init(args->trans, args->trans->t_dfops, + &args->trans->t_firstblock); error = xfs_attr3_leaf_to_node(args); if (error) goto out_defer_cancel; @@ -687,8 +683,8 @@ xfs_attr_leaf_addname( * If the result is small enough, shrink it all into the inode. */ if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { - xfs_defer_init(NULL, args->trans->t_dfops, - args->firstblock); + xfs_defer_init(args->trans, args->trans->t_dfops, + &args->trans->t_firstblock); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (error) @@ -753,7 +749,8 @@ xfs_attr_leaf_removename( * If the result is small enough, shrink it all into the inode. */ if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { - xfs_defer_init(NULL, args->trans->t_dfops, args->firstblock); + xfs_defer_init(args->trans, args->trans->t_dfops, + &args->trans->t_firstblock); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (error) @@ -882,8 +879,8 @@ restart: */ xfs_da_state_free(state); state = NULL; - xfs_defer_init(NULL, args->trans->t_dfops, - args->firstblock); + xfs_defer_init(args->trans, args->trans->t_dfops, + &args->trans->t_firstblock); error = xfs_attr3_leaf_to_node(args); if (error) goto out_defer_cancel; @@ -910,7 +907,8 @@ restart: * in the index/blkno/rmtblkno/rmtblkcnt fields and * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields. */ - xfs_defer_init(NULL, args->trans->t_dfops, args->firstblock); + xfs_defer_init(args->trans, args->trans->t_dfops, + &args->trans->t_firstblock); error = xfs_da3_split(state); if (error) goto out_defer_cancel; @@ -1008,8 +1006,8 @@ restart: * Check to see if the tree needs to be collapsed. */ if (retval && (state->path.active > 1)) { - xfs_defer_init(NULL, args->trans->t_dfops, - args->firstblock); + xfs_defer_init(args->trans, args->trans->t_dfops, + &args->trans->t_firstblock); error = xfs_da3_join(state); if (error) goto out_defer_cancel; @@ -1134,7 +1132,8 @@ xfs_attr_node_removename( * Check to see if the tree needs to be collapsed. */ if (retval && (state->path.active > 1)) { - xfs_defer_init(NULL, args->trans->t_dfops, args->firstblock); + xfs_defer_init(args->trans, args->trans->t_dfops, + &args->trans->t_firstblock); error = xfs_da3_join(state); if (error) goto out_defer_cancel; @@ -1166,8 +1165,8 @@ xfs_attr_node_removename( goto out; if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { - xfs_defer_init(NULL, args->trans->t_dfops, - args->firstblock); + xfs_defer_init(args->trans, args->trans->t_dfops, + &args->trans->t_firstblock); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (error) diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index c131469db0f1..251304f3bc5d 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -802,7 +802,6 @@ xfs_attr_shortform_to_leaf( memset((char *)&nargs, 0, sizeof(nargs)); nargs.dp = dp; nargs.geo = args->geo; - nargs.firstblock = args->firstblock; nargs.total = args->total; nargs.whichfork = XFS_ATTR_FORK; nargs.trans = args->trans; @@ -1005,7 +1004,6 @@ xfs_attr3_leaf_to_shortform( memset((char *)&nargs, 0, sizeof(nargs)); nargs.geo = args->geo; nargs.dp = dp; - nargs.firstblock = args->firstblock; nargs.total = args->total; nargs.whichfork = XFS_ATTR_FORK; nargs.trans = args->trans; diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index ab7c2755ad8c..205098aeb4bc 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -480,11 +480,13 @@ xfs_attr_rmtval_set( * extent and then crash then the block may not contain the * correct metadata after log recovery occurs. */ - xfs_defer_init(NULL, args->trans->t_dfops, args->firstblock); + xfs_defer_init(args->trans, args->trans->t_dfops, + &args->trans->t_firstblock); nmap = 1; error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)lblkno, - blkcnt, XFS_BMAPI_ATTRFORK, args->firstblock, - args->total, &map, &nmap); + blkcnt, XFS_BMAPI_ATTRFORK, + &args->trans->t_firstblock, args->total, &map, + &nmap); if (error) goto out_defer_cancel; xfs_defer_ijoin(args->trans->t_dfops, dp); @@ -522,7 +524,8 @@ xfs_attr_rmtval_set( ASSERT(blkcnt > 0); - xfs_defer_init(NULL, args->trans->t_dfops, args->firstblock); + xfs_defer_init(args->trans, args->trans->t_dfops, + &args->trans->t_firstblock); nmap = 1; error = xfs_bmapi_read(dp, (xfs_fileoff_t)lblkno, blkcnt, &map, &nmap, @@ -626,10 +629,11 @@ xfs_attr_rmtval_remove( blkcnt = args->rmtblkcnt; done = 0; while (!done) { - xfs_defer_init(NULL, args->trans->t_dfops, args->firstblock); + xfs_defer_init(args->trans, args->trans->t_dfops, + &args->trans->t_firstblock); error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, - XFS_BMAPI_ATTRFORK, 1, args->firstblock, - &done); + XFS_BMAPI_ATTRFORK, 1, + &args->trans->t_firstblock, &done); if (error) goto out_defer_cancel; xfs_defer_ijoin(args->trans->t_dfops, args->dp); diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index da73c1a011d3..6f9b2cddb933 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -1000,7 +1000,6 @@ xfs_bmap_add_attrfork_local( memset(&dargs, 0, sizeof(dargs)); dargs.geo = ip->i_mount->m_dir_geo; dargs.dp = ip; - dargs.firstblock = &tp->t_firstblock; dargs.total = dargs.geo->fsbcount; dargs.whichfork = XFS_DATA_FORK; dargs.trans = tp; diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index 68a72e3d9f53..2f2be86c10dc 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -2059,10 +2059,9 @@ xfs_da_grow_inode_int( * Try mapping it in one filesystem block. */ nmap = 1; - ASSERT(args->firstblock != NULL); error = xfs_bmapi_write(tp, dp, *bno, count, xfs_bmapi_aflag(w)|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG, - args->firstblock, args->total, &map, &nmap); + &tp->t_firstblock, args->total, &map, &nmap); if (error) return error; @@ -2084,7 +2083,7 @@ xfs_da_grow_inode_int( c = (int)(*bno + count - b); error = xfs_bmapi_write(tp, dp, b, c, xfs_bmapi_aflag(w)|XFS_BMAPI_METADATA, - args->firstblock, args->total, + &tp->t_firstblock, args->total, &mapp[mapi], &nmap); if (error) goto out_free_map; @@ -2394,7 +2393,7 @@ xfs_da_shrink_inode( * the last block to the place we want to kill. */ error = xfs_bunmapi(tp, dp, dead_blkno, count, - xfs_bmapi_aflag(w), 0, args->firstblock, + xfs_bmapi_aflag(w), 0, &tp->t_firstblock, &done); if (error == -ENOSPC) { if (w != XFS_DATA_FORK) diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h index 6b8a04f3f162..59e290ef334f 100644 --- a/fs/xfs/libxfs/xfs_da_btree.h +++ b/fs/xfs/libxfs/xfs_da_btree.h @@ -57,7 +57,6 @@ typedef struct xfs_da_args { xfs_dahash_t hashval; /* hash value of name */ xfs_ino_t inumber; /* input/output inode number */ struct xfs_inode *dp; /* directory inode to manipulate */ - xfs_fsblock_t *firstblock; /* ptr to firstblock for bmap calls */ struct xfs_trans *trans; /* current trans (changes over time) */ xfs_extlen_t total; /* total blocks needed, for 1st bmap */ int whichfork; /* data or attribute fork */ diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index a3983e3eb64a..5db73d96b99e 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -272,7 +272,6 @@ xfs_dir_createname( args->total = total; args->whichfork = XFS_DATA_FORK; args->trans = tp; - args->firstblock = &tp->t_firstblock; args->op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; if (!inum) args->op_flags |= XFS_DA_OP_JUSTCHECK; @@ -439,7 +438,6 @@ xfs_dir_removename( args->hashval = dp->i_mount->m_dirnameops->hashname(name); args->inumber = ino; args->dp = dp; - args->firstblock = &tp->t_firstblock; args->total = total; args->whichfork = XFS_DATA_FORK; args->trans = tp; @@ -502,7 +500,6 @@ xfs_dir_replace( args->hashval = dp->i_mount->m_dirnameops->hashname(name); args->inumber = inum; args->dp = dp; - args->firstblock = &tp->t_firstblock; args->total = total; args->whichfork = XFS_DATA_FORK; args->trans = tp; @@ -660,7 +657,7 @@ xfs_dir2_shrink_inode( /* Unmap the fsblock(s). */ error = xfs_bunmapi(tp, dp, da, args->geo->fsbcount, 0, 0, - args->firstblock, &done); + &tp->t_firstblock, &done); if (error) { /* * ENOSPC actually can happen if we're in a removename with no -- cgit v1.2.3 From 650919f13182e8deeeeaeb580570afb0cdf8bd0d Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:23 -0700 Subject: xfs: use ->t_firstblock for all xfs_bmapi_write() callers Convert all xfs_bmapi_write() users to ->t_firstblock. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_bmap_util.c | 8 ++++---- fs/xfs/xfs_dquot.c | 5 ++--- fs/xfs/xfs_iomap.c | 20 +++++++++----------- fs/xfs/xfs_reflink.c | 7 +++---- fs/xfs/xfs_rtalloc.c | 5 ++--- 5 files changed, 20 insertions(+), 25 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 1259e599158d..dd563f4a82e8 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -873,7 +873,6 @@ xfs_alloc_file_space( xfs_filblks_t allocatesize_fsb; xfs_extlen_t extsz, temp; xfs_fileoff_t startoffset_fsb; - xfs_fsblock_t firstfsb; int nimaps; int quota_flag; int rt; @@ -972,10 +971,11 @@ xfs_alloc_file_space( xfs_trans_ijoin(tp, ip, 0); - xfs_defer_init(tp, &dfops, &firstfsb); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); error = xfs_bmapi_write(tp, ip, startoffset_fsb, - allocatesize_fsb, alloc_type, &firstfsb, - resblks, imapp, &nimaps); + allocatesize_fsb, alloc_type, + &tp->t_firstblock, resblks, imapp, + &nimaps); if (error) goto error0; diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index c698e7f6f744..2fc5e21373be 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -290,13 +290,12 @@ xfs_dquot_disk_alloc( struct xfs_mount *mp = tp->t_mountp; struct xfs_buf *bp; struct xfs_inode *quotip = xfs_quota_inode(mp, dqp->dq_flags); - xfs_fsblock_t firstblock; int nmaps = 1; int error; trace_xfs_dqalloc(dqp); - xfs_defer_init(tp, tp->t_dfops, &firstblock); + xfs_defer_init(tp, tp->t_dfops, &tp->t_firstblock); xfs_ilock(quotip, XFS_ILOCK_EXCL); if (!xfs_this_quota_on(dqp->q_mount, dqp->dq_flags)) { @@ -312,7 +311,7 @@ xfs_dquot_disk_alloc( xfs_trans_ijoin(tp, quotip, XFS_ILOCK_EXCL); error = xfs_bmapi_write(tp, quotip, dqp->q_fileoffset, XFS_DQUOT_CLUSTER_SIZE_FSB, XFS_BMAPI_METADATA, - &firstblock, XFS_QM_DQALLOC_SPACE_RES(mp), + &tp->t_firstblock, XFS_QM_DQALLOC_SPACE_RES(mp), &map, &nmaps); if (error) goto error0; diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 777c349607b3..a2b302ba40a8 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -152,7 +152,6 @@ xfs_iomap_write_direct( xfs_fileoff_t offset_fsb; xfs_fileoff_t last_fsb; xfs_filblks_t count_fsb, resaligned; - xfs_fsblock_t firstfsb; xfs_extlen_t extsz; int nimaps; int quota_flag; @@ -254,10 +253,10 @@ xfs_iomap_write_direct( * From this point onwards we overwrite the imap pointer that the * caller gave to us. */ - xfs_defer_init(tp, &dfops, &firstfsb); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); nimaps = 1; error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, - bmapi_flags, &firstfsb, resblks, imap, + bmapi_flags, &tp->t_firstblock, resblks, imap, &nimaps); if (error) goto out_bmap_cancel; @@ -665,7 +664,6 @@ xfs_iomap_write_allocate( xfs_mount_t *mp = ip->i_mount; xfs_fileoff_t offset_fsb, last_block; xfs_fileoff_t end_fsb, map_start_fsb; - xfs_fsblock_t first_block; struct xfs_defer_ops dfops; xfs_filblks_t count_fsb; xfs_trans_t *tp; @@ -716,7 +714,7 @@ xfs_iomap_write_allocate( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, 0); - xfs_defer_init(tp, &dfops, &first_block); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); /* * it is possible that the extents have changed since @@ -770,8 +768,9 @@ xfs_iomap_write_allocate( * pointer that the caller gave to us. */ error = xfs_bmapi_write(tp, ip, map_start_fsb, - count_fsb, flags, &first_block, - nres, imap, &nimaps); + count_fsb, flags, + &tp->t_firstblock, nres, imap, + &nimaps); if (error) goto trans_cancel; @@ -827,7 +826,6 @@ xfs_iomap_write_unwritten( xfs_fileoff_t offset_fsb; xfs_filblks_t count_fsb; xfs_filblks_t numblks_fsb; - xfs_fsblock_t firstfsb; int nimaps; xfs_trans_t *tp; xfs_bmbt_irec_t imap; @@ -876,11 +874,11 @@ xfs_iomap_write_unwritten( /* * Modify the unwritten extent state of the buffer. */ - xfs_defer_init(tp, &dfops, &firstfsb); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); nimaps = 1; error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, - XFS_BMAPI_CONVERT, &firstfsb, resblks, - &imap, &nimaps); + XFS_BMAPI_CONVERT, &tp->t_firstblock, + resblks, &imap, &nimaps); if (error) goto error_on_bmapi_transaction; diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index b1bc2eb54a14..d0397622be9f 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -366,7 +366,6 @@ xfs_reflink_allocate_cow( struct xfs_bmbt_irec got; struct xfs_defer_ops dfops; struct xfs_trans *tp = NULL; - xfs_fsblock_t first_block; int nimaps, error = 0; bool trimmed; xfs_filblks_t resaligned; @@ -425,13 +424,13 @@ retry: xfs_trans_ijoin(tp, ip, 0); - xfs_defer_init(tp, &dfops, &first_block); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); nimaps = 1; /* Allocate the entire reservation as unwritten blocks. */ error = xfs_bmapi_write(tp, ip, imap->br_startoff, imap->br_blockcount, - XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC, &first_block, - resblks, imap, &nimaps); + XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC, + &tp->t_firstblock, resblks, imap, &nimaps); if (error) goto out_bmap_cancel; diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index c102b0d26bc1..1c894ea2abca 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -761,7 +761,6 @@ xfs_growfs_rt_alloc( struct xfs_buf *bp; /* temporary buffer for zeroing */ xfs_daddr_t d; /* disk block address */ int error; /* error return value */ - xfs_fsblock_t firstblock;/* first block allocated in xaction */ struct xfs_defer_ops dfops; /* list of freed blocks */ xfs_fsblock_t fsbno; /* filesystem block for bno */ struct xfs_bmbt_irec map; /* block map output */ @@ -787,13 +786,13 @@ xfs_growfs_rt_alloc( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); - xfs_defer_init(tp, &dfops, &firstblock); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); /* * Allocate blocks to the bitmap file. */ nmap = 1; error = xfs_bmapi_write(tp, ip, oblocks, nblocks - oblocks, - XFS_BMAPI_METADATA, &firstblock, + XFS_BMAPI_METADATA, &tp->t_firstblock, resblks, &map, &nmap); if (!error && nmap < 1) error = -ENOSPC; -- cgit v1.2.3 From 372837978d90d1c563315192196735c09623a5d6 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:23 -0700 Subject: xfs: use ->t_firstblock for all xfs_bunmapi() callers Convert all xfs_bunmapi() callers to ->t_firstblock. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 12 ++---------- fs/xfs/xfs_bmap_util.c | 7 +++---- fs/xfs/xfs_inode.c | 5 ++--- fs/xfs/xfs_reflink.c | 11 +++++------ fs/xfs/xfs_symlink.c | 6 +++--- 5 files changed, 15 insertions(+), 26 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 6f9b2cddb933..572c8d0c40db 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -6132,17 +6132,9 @@ xfs_bmap_finish_one( xfs_filblks_t *blockcount, xfs_exntst_t state) { - xfs_fsblock_t firstfsb; int error = 0; - /* - * firstfsb is tied to the transaction lifetime and is used to - * ensure correct AG locking order and schedule work item - * continuations. XFS_BUI_MAX_FAST_EXTENTS (== 1) restricts us - * to only making one bmap call per transaction, so it should - * be safe to have it as a local variable here. - */ - firstfsb = NULLFSBLOCK; + ASSERT(tp->t_firstblock == NULLFSBLOCK); trace_xfs_bmap_deferred(tp->t_mountp, XFS_FSB_TO_AGNO(tp->t_mountp, startblock), type, @@ -6165,7 +6157,7 @@ xfs_bmap_finish_one( break; case XFS_BMAP_UNMAP: error = __xfs_bunmapi(tp, ip, startoff, blockcount, - XFS_BMAPI_REMAP, 1, &firstfsb); + XFS_BMAPI_REMAP, 1, &tp->t_firstblock); break; default: ASSERT(0); diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index dd563f4a82e8..0b2b52854061 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1024,7 +1024,6 @@ xfs_unmap_extent( struct xfs_mount *mp = ip->i_mount; struct xfs_trans *tp; struct xfs_defer_ops dfops; - xfs_fsblock_t firstfsb; uint resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0); int error; @@ -1042,9 +1041,9 @@ xfs_unmap_extent( xfs_trans_ijoin(tp, ip, 0); - xfs_defer_init(tp, &dfops, &firstfsb); - error = xfs_bunmapi(tp, ip, startoffset_fsb, len_fsb, 0, 2, &firstfsb, - done); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); + error = xfs_bunmapi(tp, ip, startoffset_fsb, len_fsb, 0, 2, + &tp->t_firstblock, done); if (error) goto out_bmap_cancel; diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index ab1fd696500c..3cdfd795a50c 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1543,7 +1543,6 @@ xfs_itruncate_extents_flags( struct xfs_trans *tp = *tpp; struct xfs_defer_ops *odfops = tp->t_dfops; struct xfs_defer_ops dfops; - xfs_fsblock_t first_block; xfs_fileoff_t first_unmap_block; xfs_fileoff_t last_block; xfs_filblks_t unmap_len; @@ -1580,9 +1579,9 @@ xfs_itruncate_extents_flags( ASSERT(first_unmap_block < last_block); unmap_len = last_block - first_unmap_block + 1; while (!done) { - xfs_defer_init(tp, &dfops, &first_block); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); error = xfs_bunmapi(tp, ip, first_unmap_block, unmap_len, flags, - XFS_ITRUNC_MAX_EXTENTS, &first_block, + XFS_ITRUNC_MAX_EXTENTS, &tp->t_firstblock, &done); if (error) goto out_bmap_cancel; diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index d0397622be9f..83c02f6b1d02 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -627,7 +627,6 @@ xfs_reflink_end_cow( struct xfs_trans *tp; xfs_fileoff_t offset_fsb; xfs_fileoff_t end_fsb; - xfs_fsblock_t firstfsb; struct xfs_defer_ops dfops; int error; unsigned int resblks; @@ -695,10 +694,10 @@ xfs_reflink_end_cow( goto prev_extent; /* Unmap the old blocks in the data fork. */ - xfs_defer_init(tp, &dfops, &firstfsb); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); rlen = del.br_blockcount; error = __xfs_bunmapi(tp, ip, del.br_startoff, &rlen, 0, 1, - &firstfsb); + &tp->t_firstblock); if (error) goto out_defer; @@ -1002,7 +1001,6 @@ xfs_reflink_remap_extent( struct xfs_mount *mp = ip->i_mount; bool real_extent = xfs_bmap_is_real_extent(irec); struct xfs_trans *tp; - xfs_fsblock_t firstfsb; unsigned int resblks; struct xfs_defer_ops dfops; struct xfs_bmbt_irec uirec; @@ -1045,8 +1043,9 @@ xfs_reflink_remap_extent( /* Unmap the old blocks in the data fork. */ rlen = unmap_len; while (rlen) { - xfs_defer_init(tp, &dfops, &firstfsb); - error = __xfs_bunmapi(tp, ip, destoff, &rlen, 0, 1, &firstfsb); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); + error = __xfs_bunmapi(tp, ip, destoff, &rlen, 0, 1, + &tp->t_firstblock); if (error) goto out_defer; diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 583ca83353f7..18d9b4d301e5 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -400,7 +400,6 @@ xfs_inactive_symlink_rmt( xfs_buf_t *bp; int done; int error; - xfs_fsblock_t first_block; struct xfs_defer_ops dfops; int i; xfs_mount_t *mp; @@ -440,7 +439,7 @@ xfs_inactive_symlink_rmt( * Find the block(s) so we can inval and unmap them. */ done = 0; - xfs_defer_init(tp, &dfops, &first_block); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); nmaps = ARRAY_SIZE(mval); error = xfs_bmapi_read(ip, 0, xfs_symlink_blocks(mp, size), mval, &nmaps, 0); @@ -462,7 +461,8 @@ xfs_inactive_symlink_rmt( /* * Unmap the dead block(s) to the dfops. */ - error = xfs_bunmapi(tp, ip, 0, size, 0, nmaps, &first_block, &done); + error = xfs_bunmapi(tp, ip, 0, size, 0, nmaps, &tp->t_firstblock, + &done); if (error) goto error_bmap_cancel; ASSERT(done); -- cgit v1.2.3 From 580c4ff9484ac3395ad48b1118b269a6d68c9318 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:24 -0700 Subject: xfs: use ->t_firstblock in xfs_bmapi_remap() Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 572c8d0c40db..e37e1319d733 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -4501,7 +4501,6 @@ xfs_bmapi_remap( struct xfs_mount *mp = ip->i_mount; struct xfs_ifork *ifp; struct xfs_btree_cur *cur = NULL; - xfs_fsblock_t firstblock = NULLFSBLOCK; struct xfs_bmbt_irec got; struct xfs_iext_cursor icur; int whichfork = xfs_bmapi_whichfork(flags); @@ -4544,7 +4543,7 @@ xfs_bmapi_remap( if (ifp->if_flags & XFS_IFBROOT) { cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); - cur->bc_private.b.firstblock = firstblock; + cur->bc_private.b.firstblock = tp->t_firstblock; cur->bc_private.b.flags = 0; } @@ -4557,7 +4556,7 @@ xfs_bmapi_remap( got.br_state = XFS_EXT_NORM; error = xfs_bmap_add_extent_hole_real(tp, ip, whichfork, &icur, - &cur, &got, &firstblock, &logflags, flags); + &cur, &got, &tp->t_firstblock, &logflags, flags); if (error) goto error0; -- cgit v1.2.3 From d0a9d795729945fc7eea77387af7780a5a0ec4c5 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:24 -0700 Subject: xfs: use ->t_firstblock in insert/collapse range Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_bmap_util.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 0b2b52854061..d98f6e3065db 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1311,7 +1311,6 @@ xfs_collapse_file_space( struct xfs_trans *tp; int error; struct xfs_defer_ops dfops; - xfs_fsblock_t first_block; xfs_fileoff_t next_fsb = XFS_B_TO_FSB(mp, offset + len); xfs_fileoff_t shift_fsb = XFS_B_TO_FSB(mp, len); uint resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0); @@ -1344,9 +1343,9 @@ xfs_collapse_file_space( goto out_trans_cancel; xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); - xfs_defer_init(tp, &dfops, &first_block); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); error = xfs_bmap_collapse_extents(tp, ip, &next_fsb, shift_fsb, - &done, &first_block); + &done, &tp->t_firstblock); if (error) goto out_bmap_cancel; @@ -1387,7 +1386,6 @@ xfs_insert_file_space( struct xfs_trans *tp; int error; struct xfs_defer_ops dfops; - xfs_fsblock_t first_block; xfs_fileoff_t stop_fsb = XFS_B_TO_FSB(mp, offset); xfs_fileoff_t next_fsb = NULLFSBLOCK; xfs_fileoff_t shift_fsb = XFS_B_TO_FSB(mp, len); @@ -1423,9 +1421,9 @@ xfs_insert_file_space( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); - xfs_defer_init(tp, &dfops, &first_block); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); error = xfs_bmap_insert_extents(tp, ip, &next_fsb, shift_fsb, - &done, stop_fsb, &first_block); + &done, stop_fsb, &tp->t_firstblock); if (error) goto out_bmap_cancel; -- cgit v1.2.3 From a7beabeae221db2118a51f6948239d63b84499ca Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:25 -0700 Subject: xfs: remove xfs_bmapi_write() firstblock param All callers pass ->t_firstblock from the current transaction. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr_remote.c | 3 +-- fs/xfs/libxfs/xfs_bmap.c | 18 +++++------------- fs/xfs/libxfs/xfs_bmap.h | 3 +-- fs/xfs/libxfs/xfs_da_btree.c | 5 ++--- fs/xfs/xfs_bmap_util.c | 5 ++--- fs/xfs/xfs_dquot.c | 3 +-- fs/xfs/xfs_iomap.c | 10 ++++------ fs/xfs/xfs_reflink.c | 6 +++--- fs/xfs/xfs_rtalloc.c | 4 ++-- fs/xfs/xfs_symlink.c | 3 +-- 10 files changed, 22 insertions(+), 38 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index 205098aeb4bc..2db9ef186e05 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -484,8 +484,7 @@ xfs_attr_rmtval_set( &args->trans->t_firstblock); nmap = 1; error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)lblkno, - blkcnt, XFS_BMAPI_ATTRFORK, - &args->trans->t_firstblock, args->total, &map, + blkcnt, XFS_BMAPI_ATTRFORK, args->total, &map, &nmap); if (error) goto out_defer_cancel; diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index e37e1319d733..ca30e972288a 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -4212,12 +4212,6 @@ xfs_bmapi_convert_unwritten( * extent state if necessary. Details behaviour is controlled by the flags * parameter. Only allocates blocks from a single allocation group, to avoid * locking problems. - * - * The returned value in "firstblock" from the first call in a transaction - * must be remembered and presented to subsequent calls in "firstblock". - * An upper bound for the number of blocks to be allocated is supplied to - * the first call in "total"; if no allocation group has that many free - * blocks then the call will fail (return NULLFSBLOCK in "firstblock"). */ int xfs_bmapi_write( @@ -4226,8 +4220,6 @@ xfs_bmapi_write( xfs_fileoff_t bno, /* starting file offs. mapped */ xfs_filblks_t len, /* length to map in file */ int flags, /* XFS_BMAPI_... */ - xfs_fsblock_t *firstblock, /* first allocated block - controls a.g. for allocs */ xfs_extlen_t total, /* total blocks needed */ struct xfs_bmbt_irec *mval, /* output: map values */ int *nmap) /* i/o: mval size/count */ @@ -4294,7 +4286,7 @@ xfs_bmapi_write( XFS_STATS_INC(mp, xs_blk_mapw); - if (!tp || *firstblock == NULLFSBLOCK) { + if (!tp || tp->t_firstblock == NULLFSBLOCK) { if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE) bma.minleft = be16_to_cpu(ifp->if_broot->bb_level) + 1; else @@ -4321,7 +4313,7 @@ xfs_bmapi_write( bma.ip = ip; bma.total = total; bma.datatype = 0; - bma.firstblock = firstblock; + bma.firstblock = &tp->t_firstblock; ASSERT(!tp || tp->t_dfops); while (bno < end && n < *nmap) { @@ -4474,11 +4466,11 @@ error0: if (bma.cur) { if (!error) { - ASSERT(*firstblock == NULLFSBLOCK || - XFS_FSB_TO_AGNO(mp, *firstblock) <= + ASSERT(tp->t_firstblock == NULLFSBLOCK || + XFS_FSB_TO_AGNO(mp, tp->t_firstblock) <= XFS_FSB_TO_AGNO(mp, bma.cur->bc_private.b.firstblock)); - *firstblock = bma.cur->bc_private.b.firstblock; + tp->t_firstblock = bma.cur->bc_private.b.firstblock; } xfs_btree_del_cursor(bma.cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 83180c7cf3ee..88c2b5dc499e 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -201,8 +201,7 @@ int xfs_bmapi_read(struct xfs_inode *ip, xfs_fileoff_t bno, int *nmap, int flags); int xfs_bmapi_write(struct xfs_trans *tp, struct xfs_inode *ip, xfs_fileoff_t bno, xfs_filblks_t len, int flags, - xfs_fsblock_t *firstblock, xfs_extlen_t total, - struct xfs_bmbt_irec *mval, int *nmap); + xfs_extlen_t total, struct xfs_bmbt_irec *mval, int *nmap); int __xfs_bunmapi(struct xfs_trans *tp, struct xfs_inode *ip, xfs_fileoff_t bno, xfs_filblks_t *rlen, int flags, xfs_extnum_t nexts, xfs_fsblock_t *firstblock); diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index 2f2be86c10dc..fe4a192696ae 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -2061,7 +2061,7 @@ xfs_da_grow_inode_int( nmap = 1; error = xfs_bmapi_write(tp, dp, *bno, count, xfs_bmapi_aflag(w)|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG, - &tp->t_firstblock, args->total, &map, &nmap); + args->total, &map, &nmap); if (error) return error; @@ -2083,8 +2083,7 @@ xfs_da_grow_inode_int( c = (int)(*bno + count - b); error = xfs_bmapi_write(tp, dp, b, c, xfs_bmapi_aflag(w)|XFS_BMAPI_METADATA, - &tp->t_firstblock, args->total, - &mapp[mapi], &nmap); + args->total, &mapp[mapi], &nmap); if (error) goto out_free_map; if (nmap < 1) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index d98f6e3065db..4f4b1d3fb898 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -973,9 +973,8 @@ xfs_alloc_file_space( xfs_defer_init(tp, &dfops, &tp->t_firstblock); error = xfs_bmapi_write(tp, ip, startoffset_fsb, - allocatesize_fsb, alloc_type, - &tp->t_firstblock, resblks, imapp, - &nimaps); + allocatesize_fsb, alloc_type, resblks, + imapp, &nimaps); if (error) goto error0; diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 2fc5e21373be..84359eeb20f4 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -311,8 +311,7 @@ xfs_dquot_disk_alloc( xfs_trans_ijoin(tp, quotip, XFS_ILOCK_EXCL); error = xfs_bmapi_write(tp, quotip, dqp->q_fileoffset, XFS_DQUOT_CLUSTER_SIZE_FSB, XFS_BMAPI_METADATA, - &tp->t_firstblock, XFS_QM_DQALLOC_SPACE_RES(mp), - &map, &nmaps); + XFS_QM_DQALLOC_SPACE_RES(mp), &map, &nmaps); if (error) goto error0; ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB); diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index a2b302ba40a8..0ae822538a63 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -256,8 +256,7 @@ xfs_iomap_write_direct( xfs_defer_init(tp, &dfops, &tp->t_firstblock); nimaps = 1; error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, - bmapi_flags, &tp->t_firstblock, resblks, imap, - &nimaps); + bmapi_flags, resblks, imap, &nimaps); if (error) goto out_bmap_cancel; @@ -768,8 +767,7 @@ xfs_iomap_write_allocate( * pointer that the caller gave to us. */ error = xfs_bmapi_write(tp, ip, map_start_fsb, - count_fsb, flags, - &tp->t_firstblock, nres, imap, + count_fsb, flags, nres, imap, &nimaps); if (error) goto trans_cancel; @@ -877,8 +875,8 @@ xfs_iomap_write_unwritten( xfs_defer_init(tp, &dfops, &tp->t_firstblock); nimaps = 1; error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, - XFS_BMAPI_CONVERT, &tp->t_firstblock, - resblks, &imap, &nimaps); + XFS_BMAPI_CONVERT, resblks, &imap, + &nimaps); if (error) goto error_on_bmapi_transaction; diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 83c02f6b1d02..7010f3453c29 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -324,7 +324,7 @@ xfs_reflink_convert_cow_extent( if (imap->br_blockcount == 0) return 0; return xfs_bmapi_write(NULL, ip, imap->br_startoff, imap->br_blockcount, - XFS_BMAPI_COWFORK | XFS_BMAPI_CONVERT, NULL, 0, imap, + XFS_BMAPI_COWFORK | XFS_BMAPI_CONVERT, 0, imap, &nimaps); } @@ -347,7 +347,7 @@ xfs_reflink_convert_cow( xfs_ilock(ip, XFS_ILOCK_EXCL); error = xfs_bmapi_write(NULL, ip, offset_fsb, count_fsb, XFS_BMAPI_COWFORK | XFS_BMAPI_CONVERT | - XFS_BMAPI_CONVERT_ONLY, NULL, 0, &imap, &nimaps); + XFS_BMAPI_CONVERT_ONLY, 0, &imap, &nimaps); xfs_iunlock(ip, XFS_ILOCK_EXCL); return error; } @@ -430,7 +430,7 @@ retry: /* Allocate the entire reservation as unwritten blocks. */ error = xfs_bmapi_write(tp, ip, imap->br_startoff, imap->br_blockcount, XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC, - &tp->t_firstblock, resblks, imap, &nimaps); + resblks, imap, &nimaps); if (error) goto out_bmap_cancel; diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 1c894ea2abca..edd949376a51 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -792,8 +792,8 @@ xfs_growfs_rt_alloc( */ nmap = 1; error = xfs_bmapi_write(tp, ip, oblocks, nblocks - oblocks, - XFS_BMAPI_METADATA, &tp->t_firstblock, - resblks, &map, &nmap); + XFS_BMAPI_METADATA, resblks, &map, + &nmap); if (!error && nmap < 1) error = -ENOSPC; if (error) diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 18d9b4d301e5..94301b63525f 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -288,8 +288,7 @@ xfs_symlink( nmaps = XFS_SYMLINK_MAPS; error = xfs_bmapi_write(tp, ip, first_fsb, fs_blocks, - XFS_BMAPI_METADATA, &tp->t_firstblock, - resblks, mval, &nmaps); + XFS_BMAPI_METADATA, resblks, mval, &nmaps); if (error) goto out_bmap_cancel; -- cgit v1.2.3 From 2af528425342dc8f696b28693c5e61587cd72b43 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:25 -0700 Subject: xfs: remove xfs_bunmapi() firstblock param All callers pass ->t_firstblock from the current transaction. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr_remote.c | 3 +-- fs/xfs/libxfs/xfs_bmap.c | 25 ++++++++++++------------- fs/xfs/libxfs/xfs_bmap.h | 5 ++--- fs/xfs/libxfs/xfs_da_btree.c | 3 +-- fs/xfs/libxfs/xfs_dir2.c | 3 +-- fs/xfs/xfs_bmap_util.c | 3 +-- fs/xfs/xfs_inode.c | 3 +-- fs/xfs/xfs_reflink.c | 6 ++---- fs/xfs/xfs_symlink.c | 3 +-- 9 files changed, 22 insertions(+), 32 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index 2db9ef186e05..f02c705965ff 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -631,8 +631,7 @@ xfs_attr_rmtval_remove( xfs_defer_init(args->trans, args->trans->t_dfops, &args->trans->t_firstblock); error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, - XFS_BMAPI_ATTRFORK, 1, - &args->trans->t_firstblock, &done); + XFS_BMAPI_ATTRFORK, 1, &done); if (error) goto out_defer_cancel; xfs_defer_ijoin(args->trans->t_dfops, args->dp); diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index ca30e972288a..619d3adc5923 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -5122,9 +5122,7 @@ __xfs_bunmapi( xfs_fileoff_t start, /* first file offset deleted */ xfs_filblks_t *rlen, /* i/o: amount remaining */ int flags, /* misc flags */ - xfs_extnum_t nexts, /* number of extents max */ - xfs_fsblock_t *firstblock) /* first allocated block - controls a.g. for allocs */ + xfs_extnum_t nexts) /* number of extents max */ { struct xfs_btree_cur *cur; /* bmap btree cursor */ struct xfs_bmbt_irec del; /* extent being deleted */ @@ -5198,7 +5196,7 @@ __xfs_bunmapi( if (ifp->if_flags & XFS_IFBROOT) { ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); - cur->bc_private.b.firstblock = *firstblock; + cur->bc_private.b.firstblock = tp->t_firstblock; cur->bc_private.b.flags = 0; } else cur = NULL; @@ -5314,7 +5312,7 @@ __xfs_bunmapi( del.br_state = XFS_EXT_UNWRITTEN; error = xfs_bmap_add_extent_unwritten_real(tp, ip, whichfork, &icur, &cur, &del, - firstblock, &logflags); + &tp->t_firstblock, &logflags); if (error) goto error0; goto nodelete; @@ -5371,7 +5369,8 @@ __xfs_bunmapi( prev.br_state = XFS_EXT_UNWRITTEN; error = xfs_bmap_add_extent_unwritten_real(tp, ip, whichfork, &icur, &cur, - &prev, firstblock, &logflags); + &prev, &tp->t_firstblock, + &logflags); if (error) goto error0; goto nodelete; @@ -5380,7 +5379,8 @@ __xfs_bunmapi( del.br_state = XFS_EXT_UNWRITTEN; error = xfs_bmap_add_extent_unwritten_real(tp, ip, whichfork, &icur, &cur, - &del, firstblock, &logflags); + &del, &tp->t_firstblock, + &logflags); if (error) goto error0; goto nodelete; @@ -5427,8 +5427,8 @@ nodelete: */ if (xfs_bmap_needs_btree(ip, whichfork)) { ASSERT(cur == NULL); - error = xfs_bmap_extents_to_btree(tp, ip, firstblock, &cur, 0, - &tmp_logflags, whichfork); + error = xfs_bmap_extents_to_btree(tp, ip, &tp->t_firstblock, + &cur, 0, &tmp_logflags, whichfork); logflags |= tmp_logflags; if (error) goto error0; @@ -5467,7 +5467,7 @@ error0: xfs_trans_log_inode(tp, ip, logflags); if (cur) { if (!error) { - *firstblock = cur->bc_private.b.firstblock; + tp->t_firstblock = cur->bc_private.b.firstblock; cur->bc_private.b.allocated = 0; } xfs_btree_del_cursor(cur, @@ -5485,12 +5485,11 @@ xfs_bunmapi( xfs_filblks_t len, int flags, xfs_extnum_t nexts, - xfs_fsblock_t *firstblock, int *done) { int error; - error = __xfs_bunmapi(tp, ip, bno, &len, flags, nexts, firstblock); + error = __xfs_bunmapi(tp, ip, bno, &len, flags, nexts); *done = (len == 0); return error; } @@ -6148,7 +6147,7 @@ xfs_bmap_finish_one( break; case XFS_BMAP_UNMAP: error = __xfs_bunmapi(tp, ip, startoff, blockcount, - XFS_BMAPI_REMAP, 1, &tp->t_firstblock); + XFS_BMAPI_REMAP, 1); break; default: ASSERT(0); diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 88c2b5dc499e..108a3073d658 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -204,11 +204,10 @@ int xfs_bmapi_write(struct xfs_trans *tp, struct xfs_inode *ip, xfs_extlen_t total, struct xfs_bmbt_irec *mval, int *nmap); int __xfs_bunmapi(struct xfs_trans *tp, struct xfs_inode *ip, xfs_fileoff_t bno, xfs_filblks_t *rlen, int flags, - xfs_extnum_t nexts, xfs_fsblock_t *firstblock); + xfs_extnum_t nexts); int xfs_bunmapi(struct xfs_trans *tp, struct xfs_inode *ip, xfs_fileoff_t bno, xfs_filblks_t len, int flags, - xfs_extnum_t nexts, xfs_fsblock_t *firstblock, - int *done); + xfs_extnum_t nexts, int *done); int xfs_bmap_del_extent_delay(struct xfs_inode *ip, int whichfork, struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *got, struct xfs_bmbt_irec *del); diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index fe4a192696ae..9efbd2038ffb 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -2392,8 +2392,7 @@ xfs_da_shrink_inode( * the last block to the place we want to kill. */ error = xfs_bunmapi(tp, dp, dead_blkno, count, - xfs_bmapi_aflag(w), 0, &tp->t_firstblock, - &done); + xfs_bmapi_aflag(w), 0, &done); if (error == -ENOSPC) { if (w != XFS_DATA_FORK) break; diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 5db73d96b99e..4ea1fddb126f 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -656,8 +656,7 @@ xfs_dir2_shrink_inode( da = xfs_dir2_db_to_da(args->geo, db); /* Unmap the fsblock(s). */ - error = xfs_bunmapi(tp, dp, da, args->geo->fsbcount, 0, 0, - &tp->t_firstblock, &done); + error = xfs_bunmapi(tp, dp, da, args->geo->fsbcount, 0, 0, &done); if (error) { /* * ENOSPC actually can happen if we're in a removename with no diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 4f4b1d3fb898..f225707c89be 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1041,8 +1041,7 @@ xfs_unmap_extent( xfs_trans_ijoin(tp, ip, 0); xfs_defer_init(tp, &dfops, &tp->t_firstblock); - error = xfs_bunmapi(tp, ip, startoffset_fsb, len_fsb, 0, 2, - &tp->t_firstblock, done); + error = xfs_bunmapi(tp, ip, startoffset_fsb, len_fsb, 0, 2, done); if (error) goto out_bmap_cancel; diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 3cdfd795a50c..5e1eaa26435c 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1581,8 +1581,7 @@ xfs_itruncate_extents_flags( while (!done) { xfs_defer_init(tp, &dfops, &tp->t_firstblock); error = xfs_bunmapi(tp, ip, first_unmap_block, unmap_len, flags, - XFS_ITRUNC_MAX_EXTENTS, &tp->t_firstblock, - &done); + XFS_ITRUNC_MAX_EXTENTS, &done); if (error) goto out_bmap_cancel; diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 7010f3453c29..2972efeee5cc 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -696,8 +696,7 @@ xfs_reflink_end_cow( /* Unmap the old blocks in the data fork. */ xfs_defer_init(tp, &dfops, &tp->t_firstblock); rlen = del.br_blockcount; - error = __xfs_bunmapi(tp, ip, del.br_startoff, &rlen, 0, 1, - &tp->t_firstblock); + error = __xfs_bunmapi(tp, ip, del.br_startoff, &rlen, 0, 1); if (error) goto out_defer; @@ -1044,8 +1043,7 @@ xfs_reflink_remap_extent( rlen = unmap_len; while (rlen) { xfs_defer_init(tp, &dfops, &tp->t_firstblock); - error = __xfs_bunmapi(tp, ip, destoff, &rlen, 0, 1, - &tp->t_firstblock); + error = __xfs_bunmapi(tp, ip, destoff, &rlen, 0, 1); if (error) goto out_defer; diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 94301b63525f..a3dc552a5b97 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -460,8 +460,7 @@ xfs_inactive_symlink_rmt( /* * Unmap the dead block(s) to the dfops. */ - error = xfs_bunmapi(tp, ip, 0, size, 0, nmaps, &tp->t_firstblock, - &done); + error = xfs_bunmapi(tp, ip, 0, size, 0, nmaps, &done); if (error) goto error_bmap_cancel; ASSERT(done); -- cgit v1.2.3 From 333f950c89a17018f812eae13daaa2a404c413c1 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:27 -0700 Subject: xfs: remove bmap insert/collapse firstblock param The only callers pass ->t_firstblock. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 10 ++++------ fs/xfs/libxfs/xfs_bmap.h | 4 ++-- fs/xfs/xfs_bmap_util.c | 4 ++-- 3 files changed, 8 insertions(+), 10 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 619d3adc5923..5b4bee4645df 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -5652,8 +5652,7 @@ xfs_bmap_collapse_extents( struct xfs_inode *ip, xfs_fileoff_t *next_fsb, xfs_fileoff_t offset_shift_fsb, - bool *done, - xfs_fsblock_t *firstblock) + bool *done) { int whichfork = XFS_DATA_FORK; struct xfs_mount *mp = ip->i_mount; @@ -5686,7 +5685,7 @@ xfs_bmap_collapse_extents( if (ifp->if_flags & XFS_IFBROOT) { cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); - cur->bc_private.b.firstblock = *firstblock; + cur->bc_private.b.firstblock = tp->t_firstblock; cur->bc_private.b.flags = 0; } @@ -5773,8 +5772,7 @@ xfs_bmap_insert_extents( xfs_fileoff_t *next_fsb, xfs_fileoff_t offset_shift_fsb, bool *done, - xfs_fileoff_t stop_fsb, - xfs_fsblock_t *firstblock) + xfs_fileoff_t stop_fsb) { int whichfork = XFS_DATA_FORK; struct xfs_mount *mp = ip->i_mount; @@ -5807,7 +5805,7 @@ xfs_bmap_insert_extents( if (ifp->if_flags & XFS_IFBROOT) { cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); - cur->bc_private.b.firstblock = *firstblock; + cur->bc_private.b.firstblock = tp->t_firstblock; cur->bc_private.b.flags = 0; } diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 108a3073d658..3cad9c3e3bda 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -217,12 +217,12 @@ void xfs_bmap_del_extent_cow(struct xfs_inode *ip, uint xfs_default_attroffset(struct xfs_inode *ip); int xfs_bmap_collapse_extents(struct xfs_trans *tp, struct xfs_inode *ip, xfs_fileoff_t *next_fsb, xfs_fileoff_t offset_shift_fsb, - bool *done, xfs_fsblock_t *firstblock); + bool *done); int xfs_bmap_can_insert_extents(struct xfs_inode *ip, xfs_fileoff_t off, xfs_fileoff_t shift); int xfs_bmap_insert_extents(struct xfs_trans *tp, struct xfs_inode *ip, xfs_fileoff_t *next_fsb, xfs_fileoff_t offset_shift_fsb, - bool *done, xfs_fileoff_t stop_fsb, xfs_fsblock_t *firstblock); + bool *done, xfs_fileoff_t stop_fsb); int xfs_bmap_split_extent(struct xfs_inode *ip, xfs_fileoff_t split_offset); int xfs_bmapi_reserve_delalloc(struct xfs_inode *ip, int whichfork, xfs_fileoff_t off, xfs_filblks_t len, xfs_filblks_t prealloc, diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index f225707c89be..e9907bbe9529 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1343,7 +1343,7 @@ xfs_collapse_file_space( xfs_defer_init(tp, &dfops, &tp->t_firstblock); error = xfs_bmap_collapse_extents(tp, ip, &next_fsb, shift_fsb, - &done, &tp->t_firstblock); + &done); if (error) goto out_bmap_cancel; @@ -1421,7 +1421,7 @@ xfs_insert_file_space( xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); xfs_defer_init(tp, &dfops, &tp->t_firstblock); error = xfs_bmap_insert_extents(tp, ip, &next_fsb, shift_fsb, - &done, stop_fsb, &tp->t_firstblock); + &done, stop_fsb); if (error) goto out_bmap_cancel; -- cgit v1.2.3 From 4b77a088d781b53d263c37e75222439297b410e5 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:27 -0700 Subject: xfs: use ->t_firstblock in bmap extent split Also remove the unnecessary xfs_bmap_split_extent_at() parameter. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 5b4bee4645df..6e8254599fab 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -5878,8 +5878,7 @@ STATIC int xfs_bmap_split_extent_at( struct xfs_trans *tp, struct xfs_inode *ip, - xfs_fileoff_t split_fsb, - xfs_fsblock_t *firstfsb) + xfs_fileoff_t split_fsb) { int whichfork = XFS_DATA_FORK; struct xfs_btree_cur *cur = NULL; @@ -5928,7 +5927,7 @@ xfs_bmap_split_extent_at( if (ifp->if_flags & XFS_IFBROOT) { cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); - cur->bc_private.b.firstblock = *firstfsb; + cur->bc_private.b.firstblock = tp->t_firstblock; cur->bc_private.b.flags = 0; error = xfs_bmbt_lookup_eq(cur, &got, &i); if (error) @@ -5972,8 +5971,8 @@ xfs_bmap_split_extent_at( int tmp_logflags; /* partial log flag return val */ ASSERT(cur == NULL); - error = xfs_bmap_extents_to_btree(tp, ip, firstfsb, &cur, 0, - &tmp_logflags, whichfork); + error = xfs_bmap_extents_to_btree(tp, ip, &tp->t_firstblock, + &cur, 0, &tmp_logflags, whichfork); logflags |= tmp_logflags; } @@ -5997,20 +5996,18 @@ xfs_bmap_split_extent( struct xfs_mount *mp = ip->i_mount; struct xfs_trans *tp; struct xfs_defer_ops dfops; - xfs_fsblock_t firstfsb; int error; error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, XFS_DIOSTRAT_SPACE_RES(mp, 0), 0, 0, &tp); if (error) return error; - xfs_defer_init(tp, &dfops, &firstfsb); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); - error = xfs_bmap_split_extent_at(tp, ip, split_fsb, - &firstfsb); + error = xfs_bmap_split_extent_at(tp, ip, split_fsb); if (error) goto out; -- cgit v1.2.3 From 94c07b4dba01481740ce893d05a71578150b8f0b Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:28 -0700 Subject: xfs: remove xfs_bmalloca firstblock field The xfs_bmalloca.firstblock field carries the firstblock value from the transaction into the bmap infrastructure. It's initialized in one place from ->t_firstblock, so drop the field and access ->t_firstblock directly throughout the bmap code. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 44 +++++++++++++++++++++++--------------------- fs/xfs/libxfs/xfs_bmap.h | 1 - 2 files changed, 23 insertions(+), 22 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 6e8254599fab..815600d39b03 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -1794,7 +1794,7 @@ xfs_bmap_add_extent_delay_real( if (xfs_bmap_needs_btree(bma->ip, whichfork)) { error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, - bma->firstblock, &bma->cur, 1, + &bma->tp->t_firstblock, &bma->cur, 1, &tmp_rval, whichfork); rval |= tmp_rval; if (error) @@ -1872,7 +1872,7 @@ xfs_bmap_add_extent_delay_real( if (xfs_bmap_needs_btree(bma->ip, whichfork)) { error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, - bma->firstblock, &bma->cur, 1, &tmp_rval, + &bma->tp->t_firstblock, &bma->cur, 1, &tmp_rval, whichfork); rval |= tmp_rval; if (error) @@ -1953,7 +1953,7 @@ xfs_bmap_add_extent_delay_real( if (xfs_bmap_needs_btree(bma->ip, whichfork)) { error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, - bma->firstblock, &bma->cur, 1, + &bma->tp->t_firstblock, &bma->cur, 1, &tmp_rval, whichfork); rval |= tmp_rval; if (error) @@ -1991,7 +1991,7 @@ xfs_bmap_add_extent_delay_real( ASSERT(bma->cur == NULL); error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, - bma->firstblock, &bma->cur, da_old > 0, + &bma->tp->t_firstblock, &bma->cur, da_old > 0, &tmp_logflags, whichfork); bma->logflags |= tmp_logflags; if (error) @@ -3056,10 +3056,11 @@ xfs_bmap_adjacent( XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks) mp = ap->ip->i_mount; - nullfb = *ap->firstblock == NULLFSBLOCK; + nullfb = ap->tp->t_firstblock == NULLFSBLOCK; rt = XFS_IS_REALTIME_INODE(ap->ip) && xfs_alloc_is_userdata(ap->datatype); - fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, *ap->firstblock); + fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, + ap->tp->t_firstblock); /* * If allocating at eof, and there's a previous real block, * try to use its last block as our starting point. @@ -3417,8 +3418,9 @@ xfs_bmap_btalloc( } - nullfb = *ap->firstblock == NULLFSBLOCK; - fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, *ap->firstblock); + nullfb = ap->tp->t_firstblock == NULLFSBLOCK; + fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, + ap->tp->t_firstblock); if (nullfb) { if (xfs_alloc_is_userdata(ap->datatype) && xfs_inode_is_filestream(ap->ip)) { @@ -3429,7 +3431,7 @@ xfs_bmap_btalloc( ap->blkno = XFS_INO_TO_FSB(mp, ap->ip->i_ino); } } else - ap->blkno = *ap->firstblock; + ap->blkno = ap->tp->t_firstblock; xfs_bmap_adjacent(ap); @@ -3440,7 +3442,7 @@ xfs_bmap_btalloc( if (nullfb || XFS_FSB_TO_AGNO(mp, ap->blkno) == fb_agno) ; else - ap->blkno = *ap->firstblock; + ap->blkno = ap->tp->t_firstblock; /* * Normal allocation, done through xfs_alloc_vextent. */ @@ -3453,7 +3455,7 @@ xfs_bmap_btalloc( /* Trim the allocation back to the maximum an AG can fit. */ args.maxlen = min(ap->length, mp->m_ag_max_usable); - args.firstblock = *ap->firstblock; + args.firstblock = ap->tp->t_firstblock; blen = 0; if (nullfb) { /* @@ -3602,13 +3604,13 @@ xfs_bmap_btalloc( * check the allocation happened at the same or higher AG than * the first block that was allocated. */ - ASSERT(*ap->firstblock == NULLFSBLOCK || - XFS_FSB_TO_AGNO(mp, *ap->firstblock) <= + ASSERT(ap->tp->t_firstblock == NULLFSBLOCK || + XFS_FSB_TO_AGNO(mp, ap->tp->t_firstblock) <= XFS_FSB_TO_AGNO(mp, args.fsbno)); ap->blkno = args.fsbno; - if (*ap->firstblock == NULLFSBLOCK) - *ap->firstblock = args.fsbno; + if (ap->tp->t_firstblock == NULLFSBLOCK) + ap->tp->t_firstblock = args.fsbno; ASSERT(nullfb || fb_agno <= args.agno); ap->length = args.len; /* @@ -4064,12 +4066,12 @@ xfs_bmapi_allocate( return error; if (bma->cur) - bma->cur->bc_private.b.firstblock = *bma->firstblock; + bma->cur->bc_private.b.firstblock = bma->tp->t_firstblock; if (bma->blkno == NULLFSBLOCK) return 0; if ((ifp->if_flags & XFS_IFBROOT) && !bma->cur) { bma->cur = xfs_bmbt_init_cursor(mp, bma->tp, bma->ip, whichfork); - bma->cur->bc_private.b.firstblock = *bma->firstblock; + bma->cur->bc_private.b.firstblock = bma->tp->t_firstblock; } /* * Bump the number of extents we've allocated @@ -4105,7 +4107,8 @@ xfs_bmapi_allocate( else error = xfs_bmap_add_extent_hole_real(bma->tp, bma->ip, whichfork, &bma->icur, &bma->cur, &bma->got, - bma->firstblock, &bma->logflags, bma->flags); + &bma->tp->t_firstblock, &bma->logflags, + bma->flags); bma->logflags |= tmp_logflags; if (error) @@ -4156,7 +4159,7 @@ xfs_bmapi_convert_unwritten( if ((ifp->if_flags & XFS_IFBROOT) && !bma->cur) { bma->cur = xfs_bmbt_init_cursor(bma->ip->i_mount, bma->tp, bma->ip, whichfork); - bma->cur->bc_private.b.firstblock = *bma->firstblock; + bma->cur->bc_private.b.firstblock = bma->tp->t_firstblock; } mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN; @@ -4173,7 +4176,7 @@ xfs_bmapi_convert_unwritten( } error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, whichfork, - &bma->icur, &bma->cur, mval, bma->firstblock, + &bma->icur, &bma->cur, mval, &bma->tp->t_firstblock, &tmp_logflags); /* * Log the inode core unconditionally in the unwritten extent conversion @@ -4313,7 +4316,6 @@ xfs_bmapi_write( bma.ip = ip; bma.total = total; bma.datatype = 0; - bma.firstblock = &tp->t_firstblock; ASSERT(!tp || tp->t_dfops); while (bno < end && n < *nmap) { diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 3cad9c3e3bda..2e8555c1229a 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -19,7 +19,6 @@ extern kmem_zone_t *xfs_bmap_free_item_zone; * Argument structure for xfs_bmap_alloc. */ struct xfs_bmalloca { - xfs_fsblock_t *firstblock; /* i/o first block allocated */ struct xfs_trans *tp; /* transaction pointer */ struct xfs_inode *ip; /* incore inode pointer */ struct xfs_bmbt_irec prev; /* extent before the new one */ -- cgit v1.2.3 From 92f9da30f57bdb653ee46f26df2d51484b27c7f0 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:28 -0700 Subject: xfs: remove bmap extent add helper firstblock params The add extent helpers all receive firstblock via ->t_firstblock. Drop the parameter and access it directly. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 815600d39b03..cb2a4cde4c3f 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -2031,7 +2031,6 @@ xfs_bmap_add_extent_unwritten_real( struct xfs_iext_cursor *icur, xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ xfs_bmbt_irec_t *new, /* new data to add to file extents */ - xfs_fsblock_t *first, /* pointer to firstblock variable */ int *logflagsp) /* inode logging flags */ { xfs_btree_cur_t *cur; /* btree cursor */ @@ -2473,8 +2472,8 @@ xfs_bmap_add_extent_unwritten_real( int tmp_logflags; /* partial log flag return val */ ASSERT(cur == NULL); - error = xfs_bmap_extents_to_btree(tp, ip, first, &cur, 0, - &tmp_logflags, whichfork); + error = xfs_bmap_extents_to_btree(tp, ip, &tp->t_firstblock, + &cur, 0, &tmp_logflags, whichfork); *logflagsp |= tmp_logflags; if (error) goto done; @@ -2645,7 +2644,6 @@ xfs_bmap_add_extent_hole_real( struct xfs_iext_cursor *icur, struct xfs_btree_cur **curp, struct xfs_bmbt_irec *new, - xfs_fsblock_t *first, int *logflagsp, int flags) { @@ -2837,8 +2835,8 @@ xfs_bmap_add_extent_hole_real( int tmp_logflags; /* partial log flag return val */ ASSERT(cur == NULL); - error = xfs_bmap_extents_to_btree(tp, ip, first, curp, 0, - &tmp_logflags, whichfork); + error = xfs_bmap_extents_to_btree(tp, ip, &tp->t_firstblock, + curp, 0, &tmp_logflags, whichfork); *logflagsp |= tmp_logflags; cur = *curp; if (error) @@ -4107,8 +4105,7 @@ xfs_bmapi_allocate( else error = xfs_bmap_add_extent_hole_real(bma->tp, bma->ip, whichfork, &bma->icur, &bma->cur, &bma->got, - &bma->tp->t_firstblock, &bma->logflags, - bma->flags); + &bma->logflags, bma->flags); bma->logflags |= tmp_logflags; if (error) @@ -4176,8 +4173,7 @@ xfs_bmapi_convert_unwritten( } error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, whichfork, - &bma->icur, &bma->cur, mval, &bma->tp->t_firstblock, - &tmp_logflags); + &bma->icur, &bma->cur, mval, &tmp_logflags); /* * Log the inode core unconditionally in the unwritten extent conversion * path because the conversion might not have done so (e.g., if the @@ -4550,7 +4546,7 @@ xfs_bmapi_remap( got.br_state = XFS_EXT_NORM; error = xfs_bmap_add_extent_hole_real(tp, ip, whichfork, &icur, - &cur, &got, &tp->t_firstblock, &logflags, flags); + &cur, &got, &logflags, flags); if (error) goto error0; @@ -5314,7 +5310,7 @@ __xfs_bunmapi( del.br_state = XFS_EXT_UNWRITTEN; error = xfs_bmap_add_extent_unwritten_real(tp, ip, whichfork, &icur, &cur, &del, - &tp->t_firstblock, &logflags); + &logflags); if (error) goto error0; goto nodelete; @@ -5371,8 +5367,7 @@ __xfs_bunmapi( prev.br_state = XFS_EXT_UNWRITTEN; error = xfs_bmap_add_extent_unwritten_real(tp, ip, whichfork, &icur, &cur, - &prev, &tp->t_firstblock, - &logflags); + &prev, &logflags); if (error) goto error0; goto nodelete; @@ -5381,8 +5376,7 @@ __xfs_bunmapi( del.br_state = XFS_EXT_UNWRITTEN; error = xfs_bmap_add_extent_unwritten_real(tp, ip, whichfork, &icur, &cur, - &del, &tp->t_firstblock, - &logflags); + &del, &logflags); if (error) goto error0; goto nodelete; -- cgit v1.2.3 From 280253d213fb735b565532be2836f94cf574260d Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:29 -0700 Subject: xfs: remove bmap format helpers firstblock params The bmap format helpers receive firstblock via ->t_firstblock. Drop the param and access it directly. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 63 ++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 34 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index cb2a4cde4c3f..183450f1df19 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -646,7 +646,6 @@ STATIC int /* error */ xfs_bmap_extents_to_btree( struct xfs_trans *tp, /* transaction pointer */ struct xfs_inode *ip, /* incore inode pointer */ - xfs_fsblock_t *firstblock, /* first-block-allocated */ struct xfs_btree_cur **curp, /* cursor returned to caller */ int wasdel, /* converting a delayed alloc */ int *logflagsp, /* inode logging flags */ @@ -689,7 +688,7 @@ xfs_bmap_extents_to_btree( * Need a cursor. Can't allocate until bb_level is filled in. */ cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); - cur->bc_private.b.firstblock = *firstblock; + cur->bc_private.b.firstblock = tp->t_firstblock; cur->bc_private.b.flags = wasdel ? XFS_BTCUR_BPRV_WASDEL : 0; /* * Convert to a btree with two levels, one record in root. @@ -699,16 +698,16 @@ xfs_bmap_extents_to_btree( args.tp = tp; args.mp = mp; xfs_rmap_ino_bmbt_owner(&args.oinfo, ip->i_ino, whichfork); - args.firstblock = *firstblock; - if (*firstblock == NULLFSBLOCK) { + args.firstblock = tp->t_firstblock; + if (tp->t_firstblock == NULLFSBLOCK) { args.type = XFS_ALLOCTYPE_START_BNO; args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); } else if (tp->t_dfops->dop_low) { args.type = XFS_ALLOCTYPE_START_BNO; - args.fsbno = *firstblock; + args.fsbno = tp->t_firstblock; } else { args.type = XFS_ALLOCTYPE_NEAR_BNO; - args.fsbno = *firstblock; + args.fsbno = tp->t_firstblock; } args.minlen = args.maxlen = args.prod = 1; args.wasdel = wasdel; @@ -731,9 +730,9 @@ xfs_bmap_extents_to_btree( /* * Allocation can't fail, the space was reserved. */ - ASSERT(*firstblock == NULLFSBLOCK || - args.agno >= XFS_FSB_TO_AGNO(mp, *firstblock)); - *firstblock = cur->bc_private.b.firstblock = args.fsbno; + ASSERT(tp->t_firstblock == NULLFSBLOCK || + args.agno >= XFS_FSB_TO_AGNO(mp, tp->t_firstblock)); + tp->t_firstblock = cur->bc_private.b.firstblock = args.fsbno; cur->bc_private.b.allocated++; ip->i_d.di_nblocks++; xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L); @@ -810,7 +809,6 @@ STATIC int /* error */ xfs_bmap_local_to_extents( xfs_trans_t *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode pointer */ - xfs_fsblock_t *firstblock, /* first block allocated in xaction */ xfs_extlen_t total, /* total blocks needed by transaction */ int *logflagsp, /* inode logging flags */ int whichfork, @@ -848,16 +846,16 @@ xfs_bmap_local_to_extents( args.tp = tp; args.mp = ip->i_mount; xfs_rmap_ino_owner(&args.oinfo, ip->i_ino, whichfork, 0); - args.firstblock = *firstblock; + args.firstblock = tp->t_firstblock; /* * Allocate a block. We know we need only one, since the * file currently fits in an inode. */ - if (*firstblock == NULLFSBLOCK) { + if (tp->t_firstblock == NULLFSBLOCK) { args.fsbno = XFS_INO_TO_FSB(args.mp, ip->i_ino); args.type = XFS_ALLOCTYPE_START_BNO; } else { - args.fsbno = *firstblock; + args.fsbno = tp->t_firstblock; args.type = XFS_ALLOCTYPE_NEAR_BNO; } args.total = total; @@ -869,7 +867,7 @@ xfs_bmap_local_to_extents( /* Can't fail, the space was reserved. */ ASSERT(args.fsbno != NULLFSBLOCK); ASSERT(args.len == 1); - *firstblock = args.fsbno; + tp->t_firstblock = args.fsbno; bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0); /* @@ -964,8 +962,8 @@ xfs_bmap_add_attrfork_extents( if (ip->i_d.di_nextents * sizeof(xfs_bmbt_rec_t) <= XFS_IFORK_DSIZE(ip)) return 0; cur = NULL; - error = xfs_bmap_extents_to_btree(tp, ip, &tp->t_firstblock, &cur, 0, - flags, XFS_DATA_FORK); + error = xfs_bmap_extents_to_btree(tp, ip, &cur, 0, flags, + XFS_DATA_FORK); if (cur) { cur->bc_private.b.allocated = 0; xfs_btree_del_cursor(cur, @@ -1007,8 +1005,8 @@ xfs_bmap_add_attrfork_local( } if (S_ISLNK(VFS_I(ip)->i_mode)) - return xfs_bmap_local_to_extents(tp, ip, &tp->t_firstblock, 1, - flags, XFS_DATA_FORK, + return xfs_bmap_local_to_extents(tp, ip, 1, flags, + XFS_DATA_FORK, xfs_symlink_local_to_remote); /* should only be called for types that support local format data */ @@ -1794,8 +1792,7 @@ xfs_bmap_add_extent_delay_real( if (xfs_bmap_needs_btree(bma->ip, whichfork)) { error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, - &bma->tp->t_firstblock, &bma->cur, 1, - &tmp_rval, whichfork); + &bma->cur, 1, &tmp_rval, whichfork); rval |= tmp_rval; if (error) goto done; @@ -1872,8 +1869,7 @@ xfs_bmap_add_extent_delay_real( if (xfs_bmap_needs_btree(bma->ip, whichfork)) { error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, - &bma->tp->t_firstblock, &bma->cur, 1, &tmp_rval, - whichfork); + &bma->cur, 1, &tmp_rval, whichfork); rval |= tmp_rval; if (error) goto done; @@ -1953,8 +1949,7 @@ xfs_bmap_add_extent_delay_real( if (xfs_bmap_needs_btree(bma->ip, whichfork)) { error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, - &bma->tp->t_firstblock, &bma->cur, 1, - &tmp_rval, whichfork); + &bma->cur, 1, &tmp_rval, whichfork); rval |= tmp_rval; if (error) goto done; @@ -1991,8 +1986,8 @@ xfs_bmap_add_extent_delay_real( ASSERT(bma->cur == NULL); error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, - &bma->tp->t_firstblock, &bma->cur, da_old > 0, - &tmp_logflags, whichfork); + &bma->cur, da_old > 0, &tmp_logflags, + whichfork); bma->logflags |= tmp_logflags; if (error) goto done; @@ -2472,8 +2467,8 @@ xfs_bmap_add_extent_unwritten_real( int tmp_logflags; /* partial log flag return val */ ASSERT(cur == NULL); - error = xfs_bmap_extents_to_btree(tp, ip, &tp->t_firstblock, - &cur, 0, &tmp_logflags, whichfork); + error = xfs_bmap_extents_to_btree(tp, ip, &cur, 0, + &tmp_logflags, whichfork); *logflagsp |= tmp_logflags; if (error) goto done; @@ -2835,8 +2830,8 @@ xfs_bmap_add_extent_hole_real( int tmp_logflags; /* partial log flag return val */ ASSERT(cur == NULL); - error = xfs_bmap_extents_to_btree(tp, ip, &tp->t_firstblock, - curp, 0, &tmp_logflags, whichfork); + error = xfs_bmap_extents_to_btree(tp, ip, curp, 0, + &tmp_logflags, whichfork); *logflagsp |= tmp_logflags; cur = *curp; if (error) @@ -5423,8 +5418,8 @@ nodelete: */ if (xfs_bmap_needs_btree(ip, whichfork)) { ASSERT(cur == NULL); - error = xfs_bmap_extents_to_btree(tp, ip, &tp->t_firstblock, - &cur, 0, &tmp_logflags, whichfork); + error = xfs_bmap_extents_to_btree(tp, ip, &cur, 0, + &tmp_logflags, whichfork); logflags |= tmp_logflags; if (error) goto error0; @@ -5967,8 +5962,8 @@ xfs_bmap_split_extent_at( int tmp_logflags; /* partial log flag return val */ ASSERT(cur == NULL); - error = xfs_bmap_extents_to_btree(tp, ip, &tp->t_firstblock, - &cur, 0, &tmp_logflags, whichfork); + error = xfs_bmap_extents_to_btree(tp, ip, &cur, 0, + &tmp_logflags, whichfork); logflags |= tmp_logflags; } -- cgit v1.2.3 From cf612de732cb6ef626019ca085406d183f0a055a Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:29 -0700 Subject: xfs: remove xfs_btree_cur private firstblock field The bmbt cursor private structure has a firstblock field that is used to maintain locking order on bmbt allocations. The field holds an actual firstblock value (as opposed to a pointer), so it is initialized on cursor creation, updated on allocation and then the value is transferred back to the source before the cursor is destroyed. This value is always transferred from and back to the ->t_firstblock field. Since xfs_btree_cur already carries a reference to the transaction, we can remove this field from xfs_btree_cur and the associated copying. The bmbt allocations will update the value in the transaction directly. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 28 +++------------------------- fs/xfs/libxfs/xfs_bmap_btree.c | 10 ++++------ fs/xfs/libxfs/xfs_btree.h | 1 - 3 files changed, 7 insertions(+), 32 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 183450f1df19..8a1e6890a64b 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -688,7 +688,6 @@ xfs_bmap_extents_to_btree( * Need a cursor. Can't allocate until bb_level is filled in. */ cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); - cur->bc_private.b.firstblock = tp->t_firstblock; cur->bc_private.b.flags = wasdel ? XFS_BTCUR_BPRV_WASDEL : 0; /* * Convert to a btree with two levels, one record in root. @@ -732,7 +731,7 @@ xfs_bmap_extents_to_btree( */ ASSERT(tp->t_firstblock == NULLFSBLOCK || args.agno >= XFS_FSB_TO_AGNO(mp, tp->t_firstblock)); - tp->t_firstblock = cur->bc_private.b.firstblock = args.fsbno; + tp->t_firstblock = args.fsbno; cur->bc_private.b.allocated++; ip->i_d.di_nblocks++; xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L); @@ -925,7 +924,6 @@ xfs_bmap_add_attrfork_btree( *flags |= XFS_ILOG_DBROOT; else { cur = xfs_bmbt_init_cursor(mp, tp, ip, XFS_DATA_FORK); - cur->bc_private.b.firstblock = tp->t_firstblock; error = xfs_bmbt_lookup_first(cur, &stat); if (error) goto error0; @@ -937,7 +935,6 @@ xfs_bmap_add_attrfork_btree( xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); return -ENOSPC; } - tp->t_firstblock = cur->bc_private.b.firstblock; cur->bc_private.b.allocated = 0; xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); } @@ -4058,14 +4055,10 @@ xfs_bmapi_allocate( if (error) return error; - if (bma->cur) - bma->cur->bc_private.b.firstblock = bma->tp->t_firstblock; if (bma->blkno == NULLFSBLOCK) return 0; - if ((ifp->if_flags & XFS_IFBROOT) && !bma->cur) { + if ((ifp->if_flags & XFS_IFBROOT) && !bma->cur) bma->cur = xfs_bmbt_init_cursor(mp, bma->tp, bma->ip, whichfork); - bma->cur->bc_private.b.firstblock = bma->tp->t_firstblock; - } /* * Bump the number of extents we've allocated * in this call. @@ -4151,7 +4144,6 @@ xfs_bmapi_convert_unwritten( if ((ifp->if_flags & XFS_IFBROOT) && !bma->cur) { bma->cur = xfs_bmbt_init_cursor(bma->ip->i_mount, bma->tp, bma->ip, whichfork); - bma->cur->bc_private.b.firstblock = bma->tp->t_firstblock; } mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN; @@ -4458,13 +4450,6 @@ error0: xfs_trans_log_inode(tp, ip, bma.logflags); if (bma.cur) { - if (!error) { - ASSERT(tp->t_firstblock == NULLFSBLOCK || - XFS_FSB_TO_AGNO(mp, tp->t_firstblock) <= - XFS_FSB_TO_AGNO(mp, - bma.cur->bc_private.b.firstblock)); - tp->t_firstblock = bma.cur->bc_private.b.firstblock; - } xfs_btree_del_cursor(bma.cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); } @@ -4528,7 +4513,6 @@ xfs_bmapi_remap( if (ifp->if_flags & XFS_IFBROOT) { cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); - cur->bc_private.b.firstblock = tp->t_firstblock; cur->bc_private.b.flags = 0; } @@ -5189,7 +5173,6 @@ __xfs_bunmapi( if (ifp->if_flags & XFS_IFBROOT) { ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); - cur->bc_private.b.firstblock = tp->t_firstblock; cur->bc_private.b.flags = 0; } else cur = NULL; @@ -5457,10 +5440,8 @@ error0: if (logflags) xfs_trans_log_inode(tp, ip, logflags); if (cur) { - if (!error) { - tp->t_firstblock = cur->bc_private.b.firstblock; + if (!error) cur->bc_private.b.allocated = 0; - } xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); } @@ -5676,7 +5657,6 @@ xfs_bmap_collapse_extents( if (ifp->if_flags & XFS_IFBROOT) { cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); - cur->bc_private.b.firstblock = tp->t_firstblock; cur->bc_private.b.flags = 0; } @@ -5796,7 +5776,6 @@ xfs_bmap_insert_extents( if (ifp->if_flags & XFS_IFBROOT) { cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); - cur->bc_private.b.firstblock = tp->t_firstblock; cur->bc_private.b.flags = 0; } @@ -5918,7 +5897,6 @@ xfs_bmap_split_extent_at( if (ifp->if_flags & XFS_IFBROOT) { cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); - cur->bc_private.b.firstblock = tp->t_firstblock; cur->bc_private.b.flags = 0; error = xfs_bmbt_lookup_eq(cur, &got, &i); if (error) diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index e8b01af09db5..8a9b98b11e34 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -175,7 +175,6 @@ xfs_bmbt_dup_cursor( * Copy the firstblock, dfops, and flags values, * since init cursor doesn't get them. */ - new->bc_private.b.firstblock = cur->bc_private.b.firstblock; new->bc_private.b.flags = cur->bc_private.b.flags; return new; @@ -186,11 +185,11 @@ xfs_bmbt_update_cursor( struct xfs_btree_cur *src, struct xfs_btree_cur *dst) { - ASSERT((dst->bc_private.b.firstblock != NULLFSBLOCK) || + ASSERT((dst->bc_tp->t_firstblock != NULLFSBLOCK) || (dst->bc_private.b.ip->i_d.di_flags & XFS_DIFLAG_REALTIME)); dst->bc_private.b.allocated += src->bc_private.b.allocated; - dst->bc_private.b.firstblock = src->bc_private.b.firstblock; + dst->bc_tp->t_firstblock = src->bc_tp->t_firstblock; src->bc_private.b.allocated = 0; } @@ -208,7 +207,7 @@ xfs_bmbt_alloc_block( memset(&args, 0, sizeof(args)); args.tp = cur->bc_tp; args.mp = cur->bc_mp; - args.fsbno = cur->bc_private.b.firstblock; + args.fsbno = cur->bc_tp->t_firstblock; args.firstblock = args.fsbno; xfs_rmap_ino_bmbt_owner(&args.oinfo, cur->bc_private.b.ip->i_ino, cur->bc_private.b.whichfork); @@ -263,7 +262,7 @@ xfs_bmbt_alloc_block( } ASSERT(args.len == 1); - cur->bc_private.b.firstblock = args.fsbno; + cur->bc_tp->t_firstblock = args.fsbno; cur->bc_private.b.allocated++; cur->bc_private.b.ip->i_d.di_nblocks++; xfs_trans_log_inode(args.tp, cur->bc_private.b.ip, XFS_ILOG_CORE); @@ -562,7 +561,6 @@ xfs_bmbt_init_cursor( cur->bc_private.b.forksize = XFS_IFORK_SIZE(ip, whichfork); cur->bc_private.b.ip = ip; - cur->bc_private.b.firstblock = NULLFSBLOCK; cur->bc_private.b.allocated = 0; cur->bc_private.b.flags = 0; cur->bc_private.b.whichfork = whichfork; diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index b986a8fc8d40..503615f4d729 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -214,7 +214,6 @@ typedef struct xfs_btree_cur } a; struct { /* needed for BMAP */ struct xfs_inode *ip; /* pointer to our inode */ - xfs_fsblock_t firstblock; /* 1st blk allocated */ int allocated; /* count of alloced */ short forksize; /* fork's inode space */ char whichfork; /* data or attr fork */ -- cgit v1.2.3 From 64396ff2c25b2cd8156948a64ae0da5ff962e3f2 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:30 -0700 Subject: xfs: remove xfs_alloc_arg firstblock field The xfs_alloc_arg.firstblock field is used to control the starting agno for an allocation. The structure already carries a pointer to the transaction, which carries the current firstblock value. Remove the field and access ->t_firstblock directly in the allocation code. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_alloc.c | 20 ++++++++++---------- fs/xfs/libxfs/xfs_alloc.h | 1 - fs/xfs/libxfs/xfs_bmap.c | 3 --- fs/xfs/libxfs/xfs_bmap_btree.c | 1 - fs/xfs/libxfs/xfs_refcount_btree.c | 1 - fs/xfs/xfs_trace.h | 2 +- 6 files changed, 11 insertions(+), 17 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 5b1607d76fe9..bd6d8aeea825 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -2783,16 +2783,16 @@ xfs_alloc_read_agf( */ int /* error */ xfs_alloc_vextent( - xfs_alloc_arg_t *args) /* allocation argument structure */ + struct xfs_alloc_arg *args) /* allocation argument structure */ { - xfs_agblock_t agsize; /* allocation group size */ - int error; - int flags; /* XFS_ALLOC_FLAG_... locking flags */ - xfs_mount_t *mp; /* mount structure pointer */ - xfs_agnumber_t sagno; /* starting allocation group number */ - xfs_alloctype_t type; /* input allocation type */ - int bump_rotor = 0; - xfs_agnumber_t rotorstep = xfs_rotorstep; /* inode32 agf stepper */ + xfs_agblock_t agsize; /* allocation group size */ + int error; + int flags; /* XFS_ALLOC_FLAG_... locking flags */ + struct xfs_mount *mp; /* mount structure pointer */ + xfs_agnumber_t sagno; /* starting allocation group number */ + xfs_alloctype_t type; /* input allocation type */ + int bump_rotor = 0; + xfs_agnumber_t rotorstep = xfs_rotorstep; /* inode32 agf stepper */ mp = args->mp; type = args->otype = args->type; @@ -2913,7 +2913,7 @@ xfs_alloc_vextent( * locking of AGF, which might cause deadlock. */ if (++(args->agno) == mp->m_sb.sb_agcount) { - if (args->firstblock != NULLFSBLOCK) + if (args->tp->t_firstblock != NULLFSBLOCK) args->agno = sagno; else args->agno = 0; diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index e716c993ac4c..00cd5ec4cb6b 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -74,7 +74,6 @@ typedef struct xfs_alloc_arg { int datatype; /* mask defining data type treatment */ char wasdel; /* set if allocation was prev delayed */ char wasfromfl; /* set if allocation is from freelist */ - xfs_fsblock_t firstblock; /* io first block allocated */ struct xfs_owner_info oinfo; /* owner of blocks being allocated */ enum xfs_ag_resv_type resv; /* block reservation to use */ } xfs_alloc_arg_t; diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 8a1e6890a64b..12be9ad888c3 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -697,7 +697,6 @@ xfs_bmap_extents_to_btree( args.tp = tp; args.mp = mp; xfs_rmap_ino_bmbt_owner(&args.oinfo, ip->i_ino, whichfork); - args.firstblock = tp->t_firstblock; if (tp->t_firstblock == NULLFSBLOCK) { args.type = XFS_ALLOCTYPE_START_BNO; args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); @@ -845,7 +844,6 @@ xfs_bmap_local_to_extents( args.tp = tp; args.mp = ip->i_mount; xfs_rmap_ino_owner(&args.oinfo, ip->i_ino, whichfork, 0); - args.firstblock = tp->t_firstblock; /* * Allocate a block. We know we need only one, since the * file currently fits in an inode. @@ -3445,7 +3443,6 @@ xfs_bmap_btalloc( /* Trim the allocation back to the maximum an AG can fit. */ args.maxlen = min(ap->length, mp->m_ag_max_usable); - args.firstblock = ap->tp->t_firstblock; blen = 0; if (nullfb) { /* diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 8a9b98b11e34..628ed82ca286 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -208,7 +208,6 @@ xfs_bmbt_alloc_block( args.tp = cur->bc_tp; args.mp = cur->bc_mp; args.fsbno = cur->bc_tp->t_firstblock; - args.firstblock = args.fsbno; xfs_rmap_ino_bmbt_owner(&args.oinfo, cur->bc_private.b.ip->i_ino, cur->bc_private.b.whichfork); diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index 393aa88f93db..26d2300ed865 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c @@ -70,7 +70,6 @@ xfs_refcountbt_alloc_block( args.type = XFS_ALLOCTYPE_NEAR_BNO; args.fsbno = XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_private.a.agno, xfs_refc_block(args.mp)); - args.firstblock = args.fsbno; xfs_rmap_ag_owner(&args.oinfo, XFS_RMAP_OWN_REFC); args.minlen = args.maxlen = args.prod = 1; args.resv = XFS_AG_RESV_METADATA; diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 7f4c7071e7ed..9d741571b61e 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -1590,7 +1590,7 @@ DECLARE_EVENT_CLASS(xfs_alloc_class, __entry->wasfromfl = args->wasfromfl; __entry->resv = args->resv; __entry->datatype = args->datatype; - __entry->firstblock = args->firstblock; + __entry->firstblock = args->tp->t_firstblock; ), TP_printk("dev %d:%d agno %u agbno %u minlen %u maxlen %u mod %u " "prod %u minleft %u total %u alignment %u minalignslop %u " -- cgit v1.2.3 From 058529c5f51cd680eddbc6c42f56d490e290dd78 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:30 -0700 Subject: xfs: use ->t_firstblock in dq alloc Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_dquot.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 84359eeb20f4..3b61b4d266b4 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -540,14 +540,13 @@ xfs_qm_dqread_alloc( struct xfs_trans *tp; struct xfs_defer_ops dfops; struct xfs_buf *bp; - xfs_fsblock_t firstblock; int error; error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_dqalloc, XFS_QM_DQALLOC_SPACE_RES(mp), 0, 0, &tp); if (error) goto err; - xfs_defer_init(tp, &dfops, &firstblock); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); error = xfs_dquot_disk_alloc(&tp, dqp, &bp); if (error) -- cgit v1.2.3 From fb91f4b5d6187996796f4a9989decdf6ead12851 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:31 -0700 Subject: xfs: replace no-op firstblock init with ->t_firstblock xfs_refcount_recover_cow_leftovers() has no need for a firstblock variable and so passes an unrelated xfs_fsblock_t to xfs_defer_init() to avoid declaring one. Replace this no-op initialization with ->t_firstblock. This will be optimized away by the removal of the xfs_defer_init() firstblock param. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_refcount.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index 8dc380574cd8..d81c17aac710 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -1691,7 +1691,7 @@ xfs_refcount_recover_cow_leftovers( trace_xfs_refcount_recover_extent(mp, agno, &rr->rr_rrec); /* Free the orphan record */ - xfs_defer_init(tp, &dfops, &fsb); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); agbno = rr->rr_rrec.rc_startblock - XFS_REFC_COW_START; fsb = XFS_AGB_TO_FSB(mp, agno, agbno); error = xfs_refcount_free_cow_extent(mp, tp->t_dfops, fsb, -- cgit v1.2.3 From 381d592848721cb1b82b4ea9f57b46cf4a4a6973 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:31 -0700 Subject: xfs: use ->t_firstblock in reflink cow block cancel Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_reflink.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 2972efeee5cc..891214242118 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -483,7 +483,6 @@ xfs_reflink_cancel_cow_blocks( struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK); struct xfs_bmbt_irec got, del; struct xfs_iext_cursor icur; - xfs_fsblock_t firstfsb; struct xfs_defer_ops dfops; struct xfs_defer_ops *odfops = (*tpp)->t_dfops; int error = 0; @@ -512,7 +511,7 @@ xfs_reflink_cancel_cow_blocks( if (error) break; } else if (del.br_state == XFS_EXT_UNWRITTEN || cancel_real) { - xfs_defer_init(*tpp, &dfops, &firstfsb); + xfs_defer_init(*tpp, &dfops, &(*tpp)->t_firstblock); /* Free the CoW orphan record. */ error = xfs_refcount_free_cow_extent(ip->i_mount, -- cgit v1.2.3 From f537538921872c772aa743d8b58b69e7729c73aa Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:32 -0700 Subject: xfs: use ->t_firstblock in extent swap Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_bmap_util.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index e9907bbe9529..765859843606 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1570,7 +1570,6 @@ xfs_swap_extent_rmap( xfs_fileoff_t offset_fsb; xfs_fileoff_t end_fsb; xfs_filblks_t count_fsb; - xfs_fsblock_t firstfsb; int error; xfs_filblks_t ilen; xfs_filblks_t rlen; @@ -1606,7 +1605,7 @@ xfs_swap_extent_rmap( /* Unmap the old blocks in the source file. */ while (tirec.br_blockcount) { - xfs_defer_init(tp, tp->t_dfops, &firstfsb); + xfs_defer_init(tp, tp->t_dfops, &tp->t_firstblock); trace_xfs_swap_extent_rmap_remap_piece(tip, &tirec); /* Read extent from the source file */ @@ -1848,7 +1847,6 @@ xfs_swap_extents( struct xfs_ifork *cowfp; uint64_t f; int resblks = 0; - xfs_fsblock_t firstfsb; /* * Lock the inodes against other IO, page faults and truncate to @@ -1911,7 +1909,7 @@ xfs_swap_extents( error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0, 0, &tp); if (error) goto out_unlock; - xfs_defer_init(tp, &dfops, &firstfsb); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); /* * Lock and join the inodes to the tansaction so that transaction commit -- cgit v1.2.3 From 9c3bf5da80efc1d502c7ef55ea5b77628e341510 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:32 -0700 Subject: xfs: use ->t_firstblock in inode inactivate Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_inode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 5e1eaa26435c..48d22134b06f 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1772,7 +1772,6 @@ xfs_inactive_ifree( struct xfs_inode *ip) { struct xfs_defer_ops dfops; - xfs_fsblock_t first_block; struct xfs_mount *mp = ip->i_mount; struct xfs_trans *tp; int error; @@ -1809,7 +1808,7 @@ xfs_inactive_ifree( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, 0); - xfs_defer_init(tp, &dfops, &first_block); + xfs_defer_init(tp, &dfops, &tp->t_firstblock); error = xfs_ifree(tp, ip); if (error) { /* -- cgit v1.2.3 From 5fdd97944ee5ae0fcdd88227224d0c2c87aa6db9 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:33 -0700 Subject: xfs: remove xfs_defer_init() firstblock param All but one caller of xfs_defer_init() passes in the ->t_firstblock of the associated transaction. The one outlier is xlog_recover_process_intents(), which simply passes a dummy value because a valid pointer is required. This firstblock variable can simply be removed. At this point we could remove the xfs_defer_init() firstblock parameter and initialize ->t_firstblock directly. Even that is not necessary, however, because ->t_firstblock is automatically reinitialized in the new transaction on a transaction roll. Since xfs_defer_init() should never occur more than once on a particular transaction (since the corresponding finish will roll it), replace the reinit from xfs_defer_init() with an assert that verifies the transaction has a NULLFSBLOCK firstblock. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr.c | 28 ++++++++++------------------ fs/xfs/libxfs/xfs_attr_remote.c | 9 +++------ fs/xfs/libxfs/xfs_bmap.c | 4 ++-- fs/xfs/libxfs/xfs_defer.c | 5 ++--- fs/xfs/libxfs/xfs_defer.h | 3 +-- fs/xfs/libxfs/xfs_refcount.c | 2 +- fs/xfs/xfs_bmap_util.c | 12 ++++++------ fs/xfs/xfs_dquot.c | 4 ++-- fs/xfs/xfs_inode.c | 12 ++++++------ fs/xfs/xfs_iomap.c | 6 +++--- fs/xfs/xfs_log_recover.c | 3 +-- fs/xfs/xfs_reflink.c | 8 ++++---- fs/xfs/xfs_rtalloc.c | 2 +- fs/xfs/xfs_symlink.c | 4 ++-- 14 files changed, 44 insertions(+), 58 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 153d2e29f872..927d4c968f9a 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -251,7 +251,7 @@ xfs_attr_set( rsvd ? XFS_TRANS_RESERVE : 0, &args.trans); if (error) return error; - xfs_defer_init(args.trans, &dfops, &args.trans->t_firstblock); + xfs_defer_init(args.trans, &dfops); xfs_ilock(dp, XFS_ILOCK_EXCL); error = xfs_trans_reserve_quota_nblks(args.trans, dp, args.total, 0, @@ -422,7 +422,7 @@ xfs_attr_remove( &args.trans); if (error) return error; - xfs_defer_init(args.trans, &dfops, &args.trans->t_firstblock); + xfs_defer_init(args.trans, &dfops); xfs_ilock(dp, XFS_ILOCK_EXCL); /* @@ -593,8 +593,7 @@ xfs_attr_leaf_addname( * Commit that transaction so that the node_addname() call * can manage its own transactions. */ - xfs_defer_init(args->trans, args->trans->t_dfops, - &args->trans->t_firstblock); + xfs_defer_init(args->trans, args->trans->t_dfops); error = xfs_attr3_leaf_to_node(args); if (error) goto out_defer_cancel; @@ -683,8 +682,7 @@ xfs_attr_leaf_addname( * If the result is small enough, shrink it all into the inode. */ if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { - xfs_defer_init(args->trans, args->trans->t_dfops, - &args->trans->t_firstblock); + xfs_defer_init(args->trans, args->trans->t_dfops); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (error) @@ -749,8 +747,7 @@ xfs_attr_leaf_removename( * If the result is small enough, shrink it all into the inode. */ if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { - xfs_defer_init(args->trans, args->trans->t_dfops, - &args->trans->t_firstblock); + xfs_defer_init(args->trans, args->trans->t_dfops); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (error) @@ -879,8 +876,7 @@ restart: */ xfs_da_state_free(state); state = NULL; - xfs_defer_init(args->trans, args->trans->t_dfops, - &args->trans->t_firstblock); + xfs_defer_init(args->trans, args->trans->t_dfops); error = xfs_attr3_leaf_to_node(args); if (error) goto out_defer_cancel; @@ -907,8 +903,7 @@ restart: * in the index/blkno/rmtblkno/rmtblkcnt fields and * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields. */ - xfs_defer_init(args->trans, args->trans->t_dfops, - &args->trans->t_firstblock); + xfs_defer_init(args->trans, args->trans->t_dfops); error = xfs_da3_split(state); if (error) goto out_defer_cancel; @@ -1006,8 +1001,7 @@ restart: * Check to see if the tree needs to be collapsed. */ if (retval && (state->path.active > 1)) { - xfs_defer_init(args->trans, args->trans->t_dfops, - &args->trans->t_firstblock); + xfs_defer_init(args->trans, args->trans->t_dfops); error = xfs_da3_join(state); if (error) goto out_defer_cancel; @@ -1132,8 +1126,7 @@ xfs_attr_node_removename( * Check to see if the tree needs to be collapsed. */ if (retval && (state->path.active > 1)) { - xfs_defer_init(args->trans, args->trans->t_dfops, - &args->trans->t_firstblock); + xfs_defer_init(args->trans, args->trans->t_dfops); error = xfs_da3_join(state); if (error) goto out_defer_cancel; @@ -1165,8 +1158,7 @@ xfs_attr_node_removename( goto out; if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { - xfs_defer_init(args->trans, args->trans->t_dfops, - &args->trans->t_firstblock); + xfs_defer_init(args->trans, args->trans->t_dfops); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (error) diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index f02c705965ff..7841e6255129 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -480,8 +480,7 @@ xfs_attr_rmtval_set( * extent and then crash then the block may not contain the * correct metadata after log recovery occurs. */ - xfs_defer_init(args->trans, args->trans->t_dfops, - &args->trans->t_firstblock); + xfs_defer_init(args->trans, args->trans->t_dfops); nmap = 1; error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)lblkno, blkcnt, XFS_BMAPI_ATTRFORK, args->total, &map, @@ -523,8 +522,7 @@ xfs_attr_rmtval_set( ASSERT(blkcnt > 0); - xfs_defer_init(args->trans, args->trans->t_dfops, - &args->trans->t_firstblock); + xfs_defer_init(args->trans, args->trans->t_dfops); nmap = 1; error = xfs_bmapi_read(dp, (xfs_fileoff_t)lblkno, blkcnt, &map, &nmap, @@ -628,8 +626,7 @@ xfs_attr_rmtval_remove( blkcnt = args->rmtblkcnt; done = 0; while (!done) { - xfs_defer_init(args->trans, args->trans->t_dfops, - &args->trans->t_firstblock); + xfs_defer_init(args->trans, args->trans->t_dfops); error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, XFS_BMAPI_ATTRFORK, 1, &done); if (error) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 12be9ad888c3..7b93b1e16ad9 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -1038,7 +1038,7 @@ xfs_bmap_add_attrfork( rsvd ? XFS_TRANS_RESERVE : 0, &tp); if (error) return error; - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); xfs_ilock(ip, XFS_ILOCK_EXCL); error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ? @@ -5968,7 +5968,7 @@ xfs_bmap_split_extent( XFS_DIOSTRAT_SPACE_RES(mp, 0), 0, 0, &tp); if (error) return error; - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index 6b25a9436829..2713e2d808a7 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -524,16 +524,15 @@ xfs_defer_init_op_type( void xfs_defer_init( struct xfs_trans *tp, - struct xfs_defer_ops *dop, - xfs_fsblock_t *fbp) + struct xfs_defer_ops *dop) { struct xfs_mount *mp = NULL; memset(dop, 0, sizeof(struct xfs_defer_ops)); - *fbp = NULLFSBLOCK; INIT_LIST_HEAD(&dop->dop_intake); INIT_LIST_HEAD(&dop->dop_pending); if (tp) { + ASSERT(tp->t_firstblock == NULLFSBLOCK); tp->t_dfops = dop; mp = tp->t_mountp; } diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index 56eaaac31df5..c17c9deda995 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h @@ -63,8 +63,7 @@ void xfs_defer_add(struct xfs_defer_ops *dop, enum xfs_defer_ops_type type, struct list_head *h); int xfs_defer_finish(struct xfs_trans **tp, struct xfs_defer_ops *dop); void xfs_defer_cancel(struct xfs_defer_ops *dop); -void xfs_defer_init(struct xfs_trans *tp, struct xfs_defer_ops *dop, - xfs_fsblock_t *fbp); +void xfs_defer_init(struct xfs_trans *tp, struct xfs_defer_ops *dop); bool xfs_defer_has_unfinished_work(struct xfs_defer_ops *dop); int xfs_defer_ijoin(struct xfs_defer_ops *dop, struct xfs_inode *ip); int xfs_defer_bjoin(struct xfs_defer_ops *dop, struct xfs_buf *bp); diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index d81c17aac710..2ecfb0518580 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -1691,7 +1691,7 @@ xfs_refcount_recover_cow_leftovers( trace_xfs_refcount_recover_extent(mp, agno, &rr->rr_rrec); /* Free the orphan record */ - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); agbno = rr->rr_rrec.rc_startblock - XFS_REFC_COW_START; fsb = XFS_AGB_TO_FSB(mp, agno, agbno); error = xfs_refcount_free_cow_extent(mp, tp->t_dfops, fsb, diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 765859843606..d3a314fd721f 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -971,7 +971,7 @@ xfs_alloc_file_space( xfs_trans_ijoin(tp, ip, 0); - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); error = xfs_bmapi_write(tp, ip, startoffset_fsb, allocatesize_fsb, alloc_type, resblks, imapp, &nimaps); @@ -1040,7 +1040,7 @@ xfs_unmap_extent( xfs_trans_ijoin(tp, ip, 0); - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); error = xfs_bunmapi(tp, ip, startoffset_fsb, len_fsb, 0, 2, done); if (error) goto out_bmap_cancel; @@ -1341,7 +1341,7 @@ xfs_collapse_file_space( goto out_trans_cancel; xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); error = xfs_bmap_collapse_extents(tp, ip, &next_fsb, shift_fsb, &done); if (error) @@ -1419,7 +1419,7 @@ xfs_insert_file_space( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); error = xfs_bmap_insert_extents(tp, ip, &next_fsb, shift_fsb, &done, stop_fsb); if (error) @@ -1605,7 +1605,7 @@ xfs_swap_extent_rmap( /* Unmap the old blocks in the source file. */ while (tirec.br_blockcount) { - xfs_defer_init(tp, tp->t_dfops, &tp->t_firstblock); + xfs_defer_init(tp, tp->t_dfops); trace_xfs_swap_extent_rmap_remap_piece(tip, &tirec); /* Read extent from the source file */ @@ -1909,7 +1909,7 @@ xfs_swap_extents( error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0, 0, &tp); if (error) goto out_unlock; - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); /* * Lock and join the inodes to the tansaction so that transaction commit diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 3b61b4d266b4..c53de34c9ae5 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -295,7 +295,7 @@ xfs_dquot_disk_alloc( trace_xfs_dqalloc(dqp); - xfs_defer_init(tp, tp->t_dfops, &tp->t_firstblock); + xfs_defer_init(tp, tp->t_dfops); xfs_ilock(quotip, XFS_ILOCK_EXCL); if (!xfs_this_quota_on(dqp->q_mount, dqp->dq_flags)) { @@ -546,7 +546,7 @@ xfs_qm_dqread_alloc( XFS_QM_DQALLOC_SPACE_RES(mp), 0, 0, &tp); if (error) goto err; - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); error = xfs_dquot_disk_alloc(&tp, dqp, &bp); if (error) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 48d22134b06f..7b2694d3901a 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1194,7 +1194,7 @@ xfs_create( xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); unlock_dp_on_error = true; - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); /* * Reserve disk quota and the inode. @@ -1448,7 +1448,7 @@ xfs_link( goto error_return; } - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); /* * Handle initial link state of O_TMPFILE inode @@ -1579,7 +1579,7 @@ xfs_itruncate_extents_flags( ASSERT(first_unmap_block < last_block); unmap_len = last_block - first_unmap_block + 1; while (!done) { - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); error = xfs_bunmapi(tp, ip, first_unmap_block, unmap_len, flags, XFS_ITRUNC_MAX_EXTENTS, &done); if (error) @@ -1808,7 +1808,7 @@ xfs_inactive_ifree( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, 0); - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); error = xfs_ifree(tp, ip); if (error) { /* @@ -2651,7 +2651,7 @@ xfs_remove( if (error) goto out_trans_cancel; - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); error = xfs_dir_removename(tp, dp, name, ip->i_ino, resblks); if (error) { ASSERT(error != -ENOENT); @@ -3008,7 +3008,7 @@ xfs_rename( goto out_trans_cancel; } - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); /* RENAME_EXCHANGE is unique from here on. */ if (flags & RENAME_EXCHANGE) diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 0ae822538a63..756694219f77 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -253,7 +253,7 @@ xfs_iomap_write_direct( * From this point onwards we overwrite the imap pointer that the * caller gave to us. */ - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); nimaps = 1; error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, bmapi_flags, resblks, imap, &nimaps); @@ -713,7 +713,7 @@ xfs_iomap_write_allocate( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, 0); - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); /* * it is possible that the extents have changed since @@ -872,7 +872,7 @@ xfs_iomap_write_unwritten( /* * Modify the unwritten extent state of the buffer. */ - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); nimaps = 1; error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, XFS_BMAPI_CONVERT, resblks, &imap, diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 940eb30e0271..8317023293a5 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4890,7 +4890,6 @@ xlog_recover_process_intents( struct xfs_ail_cursor cur; struct xfs_log_item *lip; struct xfs_ail *ailp; - xfs_fsblock_t firstfsb; int error = 0; #if defined(DEBUG) || defined(XFS_WARN) xfs_lsn_t last_lsn; @@ -4902,7 +4901,7 @@ xlog_recover_process_intents( #if defined(DEBUG) || defined(XFS_WARN) last_lsn = xlog_assign_lsn(log->l_curr_cycle, log->l_curr_block); #endif - xfs_defer_init(NULL, &dfops, &firstfsb); + xfs_defer_init(NULL, &dfops); while (lip != NULL) { /* * We're done when we see something other than an intent. diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 891214242118..3143889097f1 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -424,7 +424,7 @@ retry: xfs_trans_ijoin(tp, ip, 0); - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); nimaps = 1; /* Allocate the entire reservation as unwritten blocks. */ @@ -511,7 +511,7 @@ xfs_reflink_cancel_cow_blocks( if (error) break; } else if (del.br_state == XFS_EXT_UNWRITTEN || cancel_real) { - xfs_defer_init(*tpp, &dfops, &(*tpp)->t_firstblock); + xfs_defer_init(*tpp, &dfops); /* Free the CoW orphan record. */ error = xfs_refcount_free_cow_extent(ip->i_mount, @@ -693,7 +693,7 @@ xfs_reflink_end_cow( goto prev_extent; /* Unmap the old blocks in the data fork. */ - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); rlen = del.br_blockcount; error = __xfs_bunmapi(tp, ip, del.br_startoff, &rlen, 0, 1); if (error) @@ -1041,7 +1041,7 @@ xfs_reflink_remap_extent( /* Unmap the old blocks in the data fork. */ rlen = unmap_len; while (rlen) { - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); error = __xfs_bunmapi(tp, ip, destoff, &rlen, 0, 1); if (error) goto out_defer; diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index edd949376a51..bc471d42a968 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -786,7 +786,7 @@ xfs_growfs_rt_alloc( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); /* * Allocate blocks to the bitmap file. */ diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index a3dc552a5b97..d1ab0afa2723 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -245,7 +245,7 @@ xfs_symlink( * Initialize the bmap freelist prior to calling either * bmapi or the directory create code. */ - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); /* * Allocate an inode for the symlink. @@ -438,7 +438,7 @@ xfs_inactive_symlink_rmt( * Find the block(s) so we can inval and unmap them. */ done = 0; - xfs_defer_init(tp, &dfops, &tp->t_firstblock); + xfs_defer_init(tp, &dfops); nmaps = ARRAY_SIZE(mval); error = xfs_bmapi_read(ip, 0, xfs_symlink_blocks(mp, size), mval, &nmaps, 0); -- cgit v1.2.3 From eaebb515f1a4728565c482b13dfb17273dc4ddc8 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:34 -0700 Subject: xfs: refactor buffer submission into a common helper Sync and async buffer submission both do generally similar things with a couple odd exceptions. Refactor the core buffer submission code into a common helper to isolate buffer submission from completion handling of synchronous buffer I/O. This patch does not change behavior. It is a step towards support for using synchronous buffer I/O via synchronous delwri queue submission. Designed-by: Dave Chinner Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_buf.c | 85 ++++++++++++++++++++++++------------------------------ fs/xfs/xfs_trace.h | 1 - 2 files changed, 37 insertions(+), 49 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index e9c058e3761c..7b0f7c79cd62 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -1458,22 +1458,20 @@ _xfs_buf_ioapply( * a call to this function unless the caller holds an additional reference * itself. */ -void -xfs_buf_submit( +static int +__xfs_buf_submit( struct xfs_buf *bp) { trace_xfs_buf_submit(bp, _RET_IP_); ASSERT(!(bp->b_flags & _XBF_DELWRI_Q)); - ASSERT(bp->b_flags & XBF_ASYNC); /* on shutdown we stale and complete the buffer immediately */ if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) { xfs_buf_ioerror(bp, -EIO); bp->b_flags &= ~XBF_DONE; xfs_buf_stale(bp); - xfs_buf_ioend(bp); - return; + return -EIO; } if (bp->b_flags & XBF_WRITE) @@ -1482,23 +1480,14 @@ xfs_buf_submit( /* clear the internal error state to avoid spurious errors */ bp->b_io_error = 0; - /* - * The caller's reference is released during I/O completion. - * This occurs some time after the last b_io_remaining reference is - * released, so after we drop our Io reference we have to have some - * other reference to ensure the buffer doesn't go away from underneath - * us. Take a direct reference to ensure we have safe access to the - * buffer until we are finished with it. - */ - xfs_buf_hold(bp); - /* * Set the count to 1 initially, this will stop an I/O completion * callout which happens before we have started all the I/O from calling * xfs_buf_ioend too early. */ atomic_set(&bp->b_io_remaining, 1); - xfs_buf_ioacct_inc(bp); + if (bp->b_flags & XBF_ASYNC) + xfs_buf_ioacct_inc(bp); _xfs_buf_ioapply(bp); /* @@ -1507,14 +1496,39 @@ xfs_buf_submit( * that we don't return to the caller with completion still pending. */ if (atomic_dec_and_test(&bp->b_io_remaining) == 1) { - if (bp->b_error) + if (bp->b_error || !(bp->b_flags & XBF_ASYNC)) xfs_buf_ioend(bp); else xfs_buf_ioend_async(bp); } - xfs_buf_rele(bp); + return 0; +} + +void +xfs_buf_submit( + struct xfs_buf *bp) +{ + int error; + + ASSERT(bp->b_flags & XBF_ASYNC); + + /* + * The caller's reference is released during I/O completion. + * This occurs some time after the last b_io_remaining reference is + * released, so after we drop our Io reference we have to have some + * other reference to ensure the buffer doesn't go away from underneath + * us. Take a direct reference to ensure we have safe access to the + * buffer until we are finished with it. + */ + xfs_buf_hold(bp); + + error = __xfs_buf_submit(bp); + if (error) + xfs_buf_ioend(bp); + /* Note: it is not safe to reference bp now we've dropped our ref */ + xfs_buf_rele(bp); } /* @@ -1526,22 +1540,7 @@ xfs_buf_submit_wait( { int error; - trace_xfs_buf_submit_wait(bp, _RET_IP_); - - ASSERT(!(bp->b_flags & (_XBF_DELWRI_Q | XBF_ASYNC))); - - if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) { - xfs_buf_ioerror(bp, -EIO); - xfs_buf_stale(bp); - bp->b_flags &= ~XBF_DONE; - return -EIO; - } - - if (bp->b_flags & XBF_WRITE) - xfs_buf_wait_unpin(bp); - - /* clear the internal error state to avoid spurious errors */ - bp->b_io_error = 0; + ASSERT(!(bp->b_flags & XBF_ASYNC)); /* * For synchronous IO, the IO does not inherit the submitters reference @@ -1551,20 +1550,9 @@ xfs_buf_submit_wait( */ xfs_buf_hold(bp); - /* - * Set the count to 1 initially, this will stop an I/O completion - * callout which happens before we have started all the I/O from calling - * xfs_buf_ioend too early. - */ - atomic_set(&bp->b_io_remaining, 1); - _xfs_buf_ioapply(bp); - - /* - * make sure we run completion synchronously if it raced with us and is - * already complete. - */ - if (atomic_dec_and_test(&bp->b_io_remaining) == 1) - xfs_buf_ioend(bp); + error = __xfs_buf_submit(bp); + if (error) + goto out; /* wait for completion before gathering the error from the buffer */ trace_xfs_buf_iowait(bp, _RET_IP_); @@ -1572,6 +1560,7 @@ xfs_buf_submit_wait( trace_xfs_buf_iowait_done(bp, _RET_IP_); error = bp->b_error; +out: /* * all done now, we can release the hold that keeps the buffer * referenced for the entire IO. diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 9d741571b61e..b668fc127aa7 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -310,7 +310,6 @@ DEFINE_BUF_EVENT(xfs_buf_hold); DEFINE_BUF_EVENT(xfs_buf_rele); DEFINE_BUF_EVENT(xfs_buf_iodone); DEFINE_BUF_EVENT(xfs_buf_submit); -DEFINE_BUF_EVENT(xfs_buf_submit_wait); DEFINE_BUF_EVENT(xfs_buf_lock); DEFINE_BUF_EVENT(xfs_buf_lock_done); DEFINE_BUF_EVENT(xfs_buf_trylock_fail); -- cgit v1.2.3 From e339dd8d8b045399e918c6737b2cc435b21a451e Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:34 -0700 Subject: xfs: use sync buffer I/O for sync delwri queue submission If a delwri queue occurs of a buffer that sits on a delwri queue wait list, the queue sets _XBF_DELWRI_Q without changing the state of ->b_list. This occurs, for example, if another thread beats the current delwri waiter thread to the buffer lock after I/O completion. Once the waiter acquires the lock, it removes the buffer from the wait list and leaves a buffer with _XBF_DELWRI_Q set but not populated on a list. This results in a lost buffer submission and in turn can result in assert failures due to _XBF_DELWRI_Q being set on buffer reclaim or filesystem lockups if the buffer happens to cover an item in the AIL. This problem has been reproduced by repeated iterations of xfs/305 on high CPU count (28xcpu) systems with limited memory (~1GB). Dirty dquot reclaim races with an xfsaild push of a separate dquot backed by the same buffer such that the buffer sits on the reclaim wait list at the time xfsaild attempts to queue it. Since the latter dquot has been flush locked but the underlying buffer not submitted for I/O, the dquot pins the AIL and causes the filesystem to livelock. This race is essentially made possible by the buffer lock cycle involved with waiting on a synchronous delwri queue submission. Close the race by using synchronous buffer I/O for respective delwri queue submission. This means the buffer remains locked across the I/O and so is inaccessible from other contexts while in the intermediate wait list state. The sync buffer I/O wait mechanism is factored into a helper such that sync delwri buffer submission and serialization are batched operations. Designed-by: Dave Chinner Signed-off-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_buf.c | 80 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 41 insertions(+), 39 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 7b0f7c79cd62..ef234847b4e6 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -1531,6 +1531,20 @@ xfs_buf_submit( xfs_buf_rele(bp); } +/* + * Wait for I/O completion of a sync buffer and return the I/O error code. + */ +static int +xfs_buf_iowait( + struct xfs_buf *bp) +{ + trace_xfs_buf_iowait(bp, _RET_IP_); + wait_for_completion(&bp->b_iowait); + trace_xfs_buf_iowait_done(bp, _RET_IP_); + + return bp->b_error; +} + /* * Synchronous buffer IO submission path, read or write. */ @@ -1553,12 +1567,7 @@ xfs_buf_submit_wait( error = __xfs_buf_submit(bp); if (error) goto out; - - /* wait for completion before gathering the error from the buffer */ - trace_xfs_buf_iowait(bp, _RET_IP_); - wait_for_completion(&bp->b_iowait); - trace_xfs_buf_iowait_done(bp, _RET_IP_); - error = bp->b_error; + error = xfs_buf_iowait(bp); out: /* @@ -1961,16 +1970,11 @@ xfs_buf_cmp( } /* - * submit buffers for write. - * - * When we have a large buffer list, we do not want to hold all the buffers - * locked while we block on the request queue waiting for IO dispatch. To avoid - * this problem, we lock and submit buffers in groups of 50, thereby minimising - * the lock hold times for lists which may contain thousands of objects. - * - * To do this, we sort the buffer list before we walk the list to lock and - * submit buffers, and we plug and unplug around each group of buffers we - * submit. + * Submit buffers for write. If wait_list is specified, the buffers are + * submitted using sync I/O and placed on the wait list such that the caller can + * iowait each buffer. Otherwise async I/O is used and the buffers are released + * at I/O completion time. In either case, buffers remain locked until I/O + * completes and the buffer is released from the queue. */ static int xfs_buf_delwri_submit_buffers( @@ -2012,21 +2016,22 @@ xfs_buf_delwri_submit_buffers( trace_xfs_buf_delwri_split(bp, _RET_IP_); /* - * We do all IO submission async. This means if we need - * to wait for IO completion we need to take an extra - * reference so the buffer is still valid on the other - * side. We need to move the buffer onto the io_list - * at this point so the caller can still access it. + * If we have a wait list, each buffer (and associated delwri + * queue reference) transfers to it and is submitted + * synchronously. Otherwise, drop the buffer from the delwri + * queue and submit async. */ bp->b_flags &= ~(_XBF_DELWRI_Q | XBF_WRITE_FAIL); - bp->b_flags |= XBF_WRITE | XBF_ASYNC; + bp->b_flags |= XBF_WRITE; if (wait_list) { - xfs_buf_hold(bp); + bp->b_flags &= ~XBF_ASYNC; list_move_tail(&bp->b_list, wait_list); - } else + __xfs_buf_submit(bp); + } else { + bp->b_flags |= XBF_ASYNC; list_del_init(&bp->b_list); - - xfs_buf_submit(bp); + xfs_buf_submit(bp); + } } blk_finish_plug(&plug); @@ -2073,9 +2078,11 @@ xfs_buf_delwri_submit( list_del_init(&bp->b_list); - /* locking the buffer will wait for async IO completion. */ - xfs_buf_lock(bp); - error2 = bp->b_error; + /* + * Wait on the locked buffer, check for errors and unlock and + * release the delwri queue reference. + */ + error2 = xfs_buf_iowait(bp); xfs_buf_relse(bp); if (!error) error = error2; @@ -2121,23 +2128,18 @@ xfs_buf_delwri_pushbuf( /* * Delwri submission clears the DELWRI_Q buffer flag and returns with - * the buffer on the wait list with an associated reference. Rather than + * the buffer on the wait list with the original reference. Rather than * bounce the buffer from a local wait list back to the original list * after I/O completion, reuse the original list as the wait list. */ xfs_buf_delwri_submit_buffers(&submit_list, buffer_list); /* - * The buffer is now under I/O and wait listed as during typical delwri - * submission. Lock the buffer to wait for I/O completion. Rather than - * remove the buffer from the wait list and release the reference, we - * want to return with the buffer queued to the original list. The - * buffer already sits on the original list with a wait list reference, - * however. If we let the queue inherit that wait list reference, all we - * need to do is reset the DELWRI_Q flag. + * The buffer is now locked, under I/O and wait listed on the original + * delwri queue. Wait for I/O completion, restore the DELWRI_Q flag and + * return with the buffer unlocked and on the original queue. */ - xfs_buf_lock(bp); - error = bp->b_error; + error = xfs_buf_iowait(bp); bp->b_flags |= _XBF_DELWRI_Q; xfs_buf_unlock(bp); -- cgit v1.2.3 From 6af88cda007695af003a1cd41f077c826aa59b97 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:35 -0700 Subject: xfs: combine [a]sync buffer submission apis The buffer I/O submission path consists of separate function calls per type. The buffer I/O type is already controlled via buffer state (XBF_ASYNC), however, so there is no real need for separate submission functions. Combine the buffer submission functions into a single function that processes the buffer appropriately based on XBF_ASYNC. Retain an internal helper with a conditional wait parameter to continue to support batched !XBF_ASYNC submission/completion required by delwri queues. Suggested-by: Christoph Hellwig Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_buf.c | 72 ++++++++++++++++-------------------------------- fs/xfs/xfs_buf.h | 10 +++++-- fs/xfs/xfs_log_recover.c | 4 +-- 3 files changed, 33 insertions(+), 53 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index ef234847b4e6..be79dd25b8cf 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -757,11 +757,7 @@ _xfs_buf_read( bp->b_flags &= ~(XBF_WRITE | XBF_ASYNC | XBF_READ_AHEAD); bp->b_flags |= flags & (XBF_READ | XBF_ASYNC | XBF_READ_AHEAD); - if (flags & XBF_ASYNC) { - xfs_buf_submit(bp); - return 0; - } - return xfs_buf_submit_wait(bp); + return xfs_buf_submit(bp); } xfs_buf_t * @@ -846,7 +842,7 @@ xfs_buf_read_uncached( bp->b_flags |= XBF_READ; bp->b_ops = ops; - xfs_buf_submit_wait(bp); + xfs_buf_submit(bp); if (bp->b_error) { int error = bp->b_error; xfs_buf_relse(bp); @@ -1249,7 +1245,7 @@ xfs_bwrite( bp->b_flags &= ~(XBF_ASYNC | XBF_READ | _XBF_DELWRI_Q | XBF_WRITE_FAIL | XBF_DONE); - error = xfs_buf_submit_wait(bp); + error = xfs_buf_submit(bp); if (error) { xfs_force_shutdown(bp->b_target->bt_mount, SHUTDOWN_META_IO_ERROR); @@ -1459,7 +1455,7 @@ _xfs_buf_ioapply( * itself. */ static int -__xfs_buf_submit( +__xfs_buf_submit_common( struct xfs_buf *bp) { trace_xfs_buf_submit(bp, _RET_IP_); @@ -1505,32 +1501,6 @@ __xfs_buf_submit( return 0; } -void -xfs_buf_submit( - struct xfs_buf *bp) -{ - int error; - - ASSERT(bp->b_flags & XBF_ASYNC); - - /* - * The caller's reference is released during I/O completion. - * This occurs some time after the last b_io_remaining reference is - * released, so after we drop our Io reference we have to have some - * other reference to ensure the buffer doesn't go away from underneath - * us. Take a direct reference to ensure we have safe access to the - * buffer until we are finished with it. - */ - xfs_buf_hold(bp); - - error = __xfs_buf_submit(bp); - if (error) - xfs_buf_ioend(bp); - - /* Note: it is not safe to reference bp now we've dropped our ref */ - xfs_buf_rele(bp); -} - /* * Wait for I/O completion of a sync buffer and return the I/O error code. */ @@ -1538,6 +1508,8 @@ static int xfs_buf_iowait( struct xfs_buf *bp) { + ASSERT(!(bp->b_flags & XBF_ASYNC)); + trace_xfs_buf_iowait(bp, _RET_IP_); wait_for_completion(&bp->b_iowait); trace_xfs_buf_iowait_done(bp, _RET_IP_); @@ -1549,30 +1521,33 @@ xfs_buf_iowait( * Synchronous buffer IO submission path, read or write. */ int -xfs_buf_submit_wait( - struct xfs_buf *bp) +__xfs_buf_submit( + struct xfs_buf *bp, + bool wait) { int error; - ASSERT(!(bp->b_flags & XBF_ASYNC)); - /* - * For synchronous IO, the IO does not inherit the submitters reference - * count, nor the buffer lock. Hence we cannot release the reference we - * are about to take until we've waited for all IO completion to occur, - * including any xfs_buf_ioend_async() work that may be pending. + * Grab a reference so the buffer does not go away underneath us. For + * async buffers, I/O completion drops the callers reference, which + * could occur before submission returns. */ xfs_buf_hold(bp); - error = __xfs_buf_submit(bp); - if (error) + error = __xfs_buf_submit_common(bp); + if (error) { + if (bp->b_flags & XBF_ASYNC) + xfs_buf_ioend(bp); goto out; - error = xfs_buf_iowait(bp); + } + if (wait) + error = xfs_buf_iowait(bp); out: /* - * all done now, we can release the hold that keeps the buffer - * referenced for the entire IO. + * Release the hold that keeps the buffer referenced for the entire + * I/O. Note that if the buffer is async, it is not safe to reference + * after this release. */ xfs_buf_rele(bp); return error; @@ -2026,12 +2001,11 @@ xfs_buf_delwri_submit_buffers( if (wait_list) { bp->b_flags &= ~XBF_ASYNC; list_move_tail(&bp->b_list, wait_list); - __xfs_buf_submit(bp); } else { bp->b_flags |= XBF_ASYNC; list_del_init(&bp->b_list); - xfs_buf_submit(bp); } + __xfs_buf_submit(bp, false); } blk_finish_plug(&plug); diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index 6ddf1907fc7a..f04613181ca1 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -297,8 +297,14 @@ extern void __xfs_buf_ioerror(struct xfs_buf *bp, int error, xfs_failaddr_t failaddr); #define xfs_buf_ioerror(bp, err) __xfs_buf_ioerror((bp), (err), __this_address) extern void xfs_buf_ioerror_alert(struct xfs_buf *, const char *func); -extern void xfs_buf_submit(struct xfs_buf *bp); -extern int xfs_buf_submit_wait(struct xfs_buf *bp); + +extern int __xfs_buf_submit(struct xfs_buf *bp, bool); +static inline int xfs_buf_submit(struct xfs_buf *bp) +{ + bool wait = bp->b_flags & XBF_ASYNC ? false : true; + return __xfs_buf_submit(bp, wait); +} + extern void xfs_buf_iomove(xfs_buf_t *, size_t, size_t, void *, xfs_buf_rw_t); #define xfs_buf_zero(bp, off, len) \ diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 8317023293a5..cbac943896f4 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -196,7 +196,7 @@ xlog_bread_noalign( bp->b_io_length = nbblks; bp->b_error = 0; - error = xfs_buf_submit_wait(bp); + error = xfs_buf_submit(bp); if (error && !XFS_FORCED_SHUTDOWN(log->l_mp)) xfs_buf_ioerror_alert(bp, __func__); return error; @@ -5706,7 +5706,7 @@ xlog_do_recover( bp->b_flags |= XBF_READ; bp->b_ops = &xfs_sb_buf_ops; - error = xfs_buf_submit_wait(bp); + error = xfs_buf_submit(bp); if (error) { if (!XFS_FORCED_SHUTDOWN(mp)) { xfs_buf_ioerror_alert(bp, __func__); -- cgit v1.2.3 From bb00b6f1e2b9699f6140849ab3d6a252b130f44e Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 11 Jul 2018 22:26:35 -0700 Subject: xfs: kill __xfs_buf_submit_common() Now that there is only one caller, fold the common submission helper into __xfs_buf_submit(). Suggested-by: Christoph Hellwig Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_buf.c | 83 +++++++++++++++++++++++--------------------------------- 1 file changed, 34 insertions(+), 49 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index be79dd25b8cf..c641c7fa1a03 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -1449,15 +1449,34 @@ _xfs_buf_ioapply( } /* - * Asynchronous IO submission path. This transfers the buffer lock ownership and - * the current reference to the IO. It is not safe to reference the buffer after - * a call to this function unless the caller holds an additional reference - * itself. + * Wait for I/O completion of a sync buffer and return the I/O error code. */ static int -__xfs_buf_submit_common( +xfs_buf_iowait( struct xfs_buf *bp) { + ASSERT(!(bp->b_flags & XBF_ASYNC)); + + trace_xfs_buf_iowait(bp, _RET_IP_); + wait_for_completion(&bp->b_iowait); + trace_xfs_buf_iowait_done(bp, _RET_IP_); + + return bp->b_error; +} + +/* + * Buffer I/O submission path, read or write. Asynchronous submission transfers + * the buffer lock ownership and the current reference to the IO. It is not + * safe to reference the buffer after a call to this function unless the caller + * holds an additional reference itself. + */ +int +__xfs_buf_submit( + struct xfs_buf *bp, + bool wait) +{ + int error = 0; + trace_xfs_buf_submit(bp, _RET_IP_); ASSERT(!(bp->b_flags & _XBF_DELWRI_Q)); @@ -1467,9 +1486,18 @@ __xfs_buf_submit_common( xfs_buf_ioerror(bp, -EIO); bp->b_flags &= ~XBF_DONE; xfs_buf_stale(bp); + if (bp->b_flags & XBF_ASYNC) + xfs_buf_ioend(bp); return -EIO; } + /* + * Grab a reference so the buffer does not go away underneath us. For + * async buffers, I/O completion drops the callers reference, which + * could occur before submission returns. + */ + xfs_buf_hold(bp); + if (bp->b_flags & XBF_WRITE) xfs_buf_wait_unpin(bp); @@ -1498,52 +1526,9 @@ __xfs_buf_submit_common( xfs_buf_ioend_async(bp); } - return 0; -} - -/* - * Wait for I/O completion of a sync buffer and return the I/O error code. - */ -static int -xfs_buf_iowait( - struct xfs_buf *bp) -{ - ASSERT(!(bp->b_flags & XBF_ASYNC)); - - trace_xfs_buf_iowait(bp, _RET_IP_); - wait_for_completion(&bp->b_iowait); - trace_xfs_buf_iowait_done(bp, _RET_IP_); - - return bp->b_error; -} - -/* - * Synchronous buffer IO submission path, read or write. - */ -int -__xfs_buf_submit( - struct xfs_buf *bp, - bool wait) -{ - int error; - - /* - * Grab a reference so the buffer does not go away underneath us. For - * async buffers, I/O completion drops the callers reference, which - * could occur before submission returns. - */ - xfs_buf_hold(bp); - - error = __xfs_buf_submit_common(bp); - if (error) { - if (bp->b_flags & XBF_ASYNC) - xfs_buf_ioend(bp); - goto out; - } - if (wait) error = xfs_buf_iowait(bp); -out: + /* * Release the hold that keeps the buffer referenced for the entire * I/O. Note that if the buffer is async, it is not safe to reference -- cgit v1.2.3 From a4722a643fbb9e1466491fbe5a3c44591805dcc8 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Wed, 11 Jul 2018 22:26:36 -0700 Subject: xfs: remove unused iolock arg from xfs_break_dax_layouts Signed-off-by: Eric Sandeen Reviewed-by: Allison Henderson Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_file.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index a3e7767a5715..6b31f41eafa2 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -735,7 +735,6 @@ xfs_wait_dax_page( static int xfs_break_dax_layouts( struct inode *inode, - uint iolock, bool *did_unlock) { struct page *page; @@ -766,7 +765,7 @@ xfs_break_layouts( retry = false; switch (reason) { case BREAK_UNMAP: - error = xfs_break_dax_layouts(inode, *iolock, &retry); + error = xfs_break_dax_layouts(inode, &retry); if (error || retry) break; /* fall through */ -- cgit v1.2.3 From efe803277364a621348b679058222d644e113c9c Mon Sep 17 00:00:00 2001 From: Carlos Maiolino Date: Wed, 11 Jul 2018 22:26:36 -0700 Subject: xfs: Initialize variables in xfs_alloc_get_rec before using them Make sure we initialize *bno and *len, before jumping to out_bad_rec label, and risk calling xfs_warn() with uninitialized variables. Coverity: 100898 Coverity: 1437081 Coverity: 1437129 Coverity: 1437191 Coverity: 1437201 Coverity: 1437212 Coverity: 1437341 Signed-off-by: Carlos Maiolino Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_alloc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index bd6d8aeea825..3c3f2d5119ea 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -223,12 +223,13 @@ xfs_alloc_get_rec( error = xfs_btree_get_rec(cur, &rec, stat); if (error || !(*stat)) return error; - if (rec->alloc.ar_blockcount == 0) - goto out_bad_rec; *bno = be32_to_cpu(rec->alloc.ar_startblock); *len = be32_to_cpu(rec->alloc.ar_blockcount); + if (*len == 0) + goto out_bad_rec; + /* check for valid extent range, including overflow */ if (!xfs_verify_agbno(mp, agno, *bno)) goto out_bad_rec; -- cgit v1.2.3 From fa248de98a6beb9ceaec5059041d65f87ac438b4 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 17 Jul 2018 14:24:11 -0700 Subject: xfs: don't assume a left rmap when allocating a new rmap The original rmap code assumed that there would always be at least one rmap in the rmapbt (the AG sb/agf/agi) and so errored out if it didn't find one. This assumption isn't true for the rmapbt repair function (and it won't be true for realtime rmap either), so remove the check and just deal with the situation. Signed-off-by: Darrick J. Wong Reviewed-by: Allison Henderson --- fs/xfs/libxfs/xfs_rmap.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index d4460b0d2d81..8b2a2f81d110 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -753,19 +753,19 @@ xfs_rmap_map( &have_lt); if (error) goto out_error; - XFS_WANT_CORRUPTED_GOTO(mp, have_lt == 1, out_error); - - error = xfs_rmap_get_rec(cur, <rec, &have_lt); - if (error) - goto out_error; - XFS_WANT_CORRUPTED_GOTO(mp, have_lt == 1, out_error); - trace_xfs_rmap_lookup_le_range_result(cur->bc_mp, - cur->bc_private.a.agno, ltrec.rm_startblock, - ltrec.rm_blockcount, ltrec.rm_owner, - ltrec.rm_offset, ltrec.rm_flags); + if (have_lt) { + error = xfs_rmap_get_rec(cur, <rec, &have_lt); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(mp, have_lt == 1, out_error); + trace_xfs_rmap_lookup_le_range_result(cur->bc_mp, + cur->bc_private.a.agno, ltrec.rm_startblock, + ltrec.rm_blockcount, ltrec.rm_owner, + ltrec.rm_offset, ltrec.rm_flags); - if (!xfs_rmap_is_mergeable(<rec, owner, flags)) - have_lt = 0; + if (!xfs_rmap_is_mergeable(<rec, owner, flags)) + have_lt = 0; + } XFS_WANT_CORRUPTED_GOTO(mp, have_lt == 0 || -- cgit v1.2.3 From 1d5bebbafc73d82e5af003cdd2bf8ee5741cd1df Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Wed, 11 Jul 2018 22:26:38 -0700 Subject: xfs_attr_leaf: use swap macro in xfs_attr3_leaf_rebalance Make use of the swap macro and remove some unnecessary variables. This makes the code easier to read and maintain. Also, reduces the stack usage. This code was detected with the help of Coccinelle. Signed-off-by: Gustavo A. R. Silva Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr_leaf.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index 251304f3bc5d..8ff287979a8c 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -1566,17 +1566,10 @@ xfs_attr3_leaf_rebalance( */ swap = 0; if (xfs_attr3_leaf_order(blk1->bp, &ichdr1, blk2->bp, &ichdr2)) { - struct xfs_da_state_blk *tmp_blk; - struct xfs_attr3_icleaf_hdr tmp_ichdr; + swap(blk1, blk2); - tmp_blk = blk1; - blk1 = blk2; - blk2 = tmp_blk; - - /* struct copies to swap them rather than reconverting */ - tmp_ichdr = ichdr1; - ichdr1 = ichdr2; - ichdr2 = tmp_ichdr; + /* swap structures rather than reconverting them */ + swap(ichdr1, ichdr2); leaf1 = blk1->bp->b_addr; leaf2 = blk2->bp->b_addr; -- cgit v1.2.3 From 897992b7e3505659fda57887223bd6bfe163c12f Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Wed, 11 Jul 2018 22:26:38 -0700 Subject: xfs_bmap_util: use swap macro Make use of the swap macro and remove some unnecessary variables. This makes the code easier to read and maintain. Also, reduces the stack usage. This code was detected with the help of Coccinelle. Signed-off-by: Gustavo A. R. Silva Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_bmap_util.c | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index d3a314fd721f..1b78c20de7bd 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1688,7 +1688,6 @@ xfs_swap_extent_forks( int *src_log_flags, int *target_log_flags) { - struct xfs_ifork tempifp, *ifp, *tifp; xfs_filblks_t aforkblks = 0; xfs_filblks_t taforkblks = 0; xfs_extnum_t junk; @@ -1730,11 +1729,7 @@ xfs_swap_extent_forks( /* * Swap the data forks of the inodes */ - ifp = &ip->i_df; - tifp = &tip->i_df; - tempifp = *ifp; /* struct copy */ - *ifp = *tifp; /* struct copy */ - *tifp = tempifp; /* struct copy */ + swap(ip->i_df, tip->i_df); /* * Fix the on-disk inode values @@ -1743,13 +1738,8 @@ xfs_swap_extent_forks( ip->i_d.di_nblocks = tip->i_d.di_nblocks - taforkblks + aforkblks; tip->i_d.di_nblocks = tmp + taforkblks - aforkblks; - tmp = (uint64_t) ip->i_d.di_nextents; - ip->i_d.di_nextents = tip->i_d.di_nextents; - tip->i_d.di_nextents = tmp; - - tmp = (uint64_t) ip->i_d.di_format; - ip->i_d.di_format = tip->i_d.di_format; - tip->i_d.di_format = tmp; + swap(ip->i_d.di_nextents, tip->i_d.di_nextents); + swap(ip->i_d.di_format, tip->i_d.di_format); /* * The extents in the source inode could still contain speculative @@ -1844,7 +1834,6 @@ xfs_swap_extents( int src_log_flags, target_log_flags; int error = 0; int lock_flags; - struct xfs_ifork *cowfp; uint64_t f; int resblks = 0; @@ -1986,18 +1975,11 @@ xfs_swap_extents( /* Swap the cow forks. */ if (xfs_sb_version_hasreflink(&mp->m_sb)) { - xfs_extnum_t extnum; - ASSERT(ip->i_cformat == XFS_DINODE_FMT_EXTENTS); ASSERT(tip->i_cformat == XFS_DINODE_FMT_EXTENTS); - extnum = ip->i_cnextents; - ip->i_cnextents = tip->i_cnextents; - tip->i_cnextents = extnum; - - cowfp = ip->i_cowfp; - ip->i_cowfp = tip->i_cowfp; - tip->i_cowfp = cowfp; + swap(ip->i_cnextents, tip->i_cnextents); + swap(ip->i_cowfp, tip->i_cowfp); if (ip->i_cowfp && ip->i_cowfp->if_bytes) xfs_inode_set_cowblocks_tag(ip); -- cgit v1.2.3 From e4e542a683c16945533d700339a0aec261d39f34 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Tue, 17 Jul 2018 14:25:01 -0700 Subject: xfs: use swap macro in xfs_dir2_leafn_rebalance Make use of the swap macro and remove unnecessary variable *tmp*. This makes the code easier to read and maintain. Also, slightly refactor some code. This code was detected with the help of Coccinelle. Signed-off-by: Gustavo A. R. Silva Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_dir2_node.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 2daf874969ab..f1bb3434f51c 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -1012,7 +1012,7 @@ xfs_dir2_leafn_rebalance( int oldstale; /* old count of stale leaves */ #endif int oldsum; /* old total leaf count */ - int swap; /* swapped leaf blocks */ + int swap_blocks; /* swapped leaf blocks */ struct xfs_dir2_leaf_entry *ents1; struct xfs_dir2_leaf_entry *ents2; struct xfs_dir3_icleaf_hdr hdr1; @@ -1023,13 +1023,10 @@ xfs_dir2_leafn_rebalance( /* * If the block order is wrong, swap the arguments. */ - if ((swap = xfs_dir2_leafn_order(dp, blk1->bp, blk2->bp))) { - xfs_da_state_blk_t *tmp; /* temp for block swap */ + swap_blocks = xfs_dir2_leafn_order(dp, blk1->bp, blk2->bp); + if (swap_blocks) + swap(blk1, blk2); - tmp = blk1; - blk1 = blk2; - blk2 = tmp; - } leaf1 = blk1->bp->b_addr; leaf2 = blk2->bp->b_addr; dp->d_ops->leaf_hdr_from_disk(&hdr1, leaf1); @@ -1093,11 +1090,11 @@ xfs_dir2_leafn_rebalance( * Mark whether we're inserting into the old or new leaf. */ if (hdr1.count < hdr2.count) - state->inleaf = swap; + state->inleaf = swap_blocks; else if (hdr1.count > hdr2.count) - state->inleaf = !swap; + state->inleaf = !swap_blocks; else - state->inleaf = swap ^ (blk1->index <= hdr1.count); + state->inleaf = swap_blocks ^ (blk1->index <= hdr1.count); /* * Adjust the expected index for insertion. */ -- cgit v1.2.3 From 5089eafffba2ed444789e5d25c7c0dfd62595713 Mon Sep 17 00:00:00 2001 From: Carlos Maiolino Date: Tue, 17 Jul 2018 14:25:20 -0700 Subject: libxfs: Fix a couple of sparse complaintis No significant changes, just silence a couple of sparse errors. Using cpu_to_be32(NULLAGINO), the NULLAGINO constant will be encoded in BE as a constant, avoiding a BE -> CPU conversion every iteraction of the loop, if be32_to_cpu(agi->agi_unlinked[i]) was used instead. Signed-off-by: Carlos Maiolino Reviewed-by: Bill O'Donnell Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_ag_resv.h | 2 +- fs/xfs/libxfs/xfs_ialloc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_ag_resv.h b/fs/xfs/libxfs/xfs_ag_resv.h index 4619b554ee90..dc953fc84b2f 100644 --- a/fs/xfs/libxfs/xfs_ag_resv.h +++ b/fs/xfs/libxfs/xfs_ag_resv.h @@ -28,7 +28,7 @@ xfs_ag_resv_rmapbt_alloc( struct xfs_mount *mp, xfs_agnumber_t agno) { - struct xfs_alloc_arg args = {0}; + struct xfs_alloc_arg args = { NULL }; struct xfs_perag *pag; args.len = 1; diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index c38d14106b53..811d36afd024 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -2537,7 +2537,7 @@ xfs_agi_verify( return __this_address; for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) { - if (agi->agi_unlinked[i] == NULLAGINO) + if (agi->agi_unlinked[i] == cpu_to_be32(NULLAGINO)) continue; if (!xfs_verify_ino(mp, be32_to_cpu(agi->agi_unlinked[i]))) return __this_address; -- cgit v1.2.3 From 65cfcc3897d7715a878b9f59736e7527ca27514f Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 19 Jul 2018 12:24:55 -0700 Subject: xfs: check leaf attribute block freemap in verifier Check the leaf attribute freemap when we're verifying the block. Signed-off-by: Darrick J. Wong Reviewed-by: Carlos Maiolino Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_attr_leaf.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index 8ff287979a8c..088ffcd22fa2 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -244,6 +244,8 @@ xfs_attr3_leaf_verify( struct xfs_attr_leafblock *leaf = bp->b_addr; struct xfs_perag *pag = bp->b_pag; struct xfs_attr_leaf_entry *entries; + uint16_t end; + int i; xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf); @@ -289,6 +291,26 @@ xfs_attr3_leaf_verify( /* XXX: need to range check rest of attr header values */ /* XXX: hash order check? */ + /* + * Quickly check the freemap information. Attribute data has to be + * aligned to 4-byte boundaries, and likewise for the free space. + */ + for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { + if (ichdr.freemap[i].base > mp->m_attr_geo->blksize) + return __this_address; + if (ichdr.freemap[i].base & 0x3) + return __this_address; + if (ichdr.freemap[i].size > mp->m_attr_geo->blksize) + return __this_address; + if (ichdr.freemap[i].size & 0x3) + return __this_address; + end = ichdr.freemap[i].base + ichdr.freemap[i].size; + if (end < ichdr.freemap[i].base) + return __this_address; + if (end > mp->m_attr_geo->blksize) + return __this_address; + } + return NULL; } -- cgit v1.2.3 From 81b549aa626b650bbf00423c084c0fd5581169b9 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 19 Jul 2018 12:25:47 -0700 Subject: xfs: return from _defer_finish with a clean transaction The following assertion was seen on generic/051: XFS: Assertion failed: tp->t_firstblock == NULLFSBLOCK, file: fs/xfs/libxfs5 ------------[ cut here ]------------ kernel BUG at fs/xfs/xfs_message.c:102! invalid opcode: 0000 [#1] SMP PTI CPU: 2 PID: 20757 Comm: fsstress Not tainted 4.18.0-rc4+ #3969 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.11.1-1 04/01/4 RIP: 0010:assfail+0x23/0x30 Code: c3 66 0f 1f 44 00 00 48 89 f1 41 89 d0 48 c7 c6 88 e0 8c 82 48 89 fa RSP: 0018:ffff88012dc43c08 EFLAGS: 00010202 RAX: 0000000000000000 RBX: ffff88012dc43ca0 RCX: 0000000000000000 RDX: 00000000ffffffc0 RSI: 000000000000000a RDI: ffffffff828480eb RBP: ffff88012aa92758 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: f000000000000000 R12: 0000000000000000 R13: ffff88012dc43d48 R14: ffff88013092e7e8 R15: 0000000000000014 FS: 00007f8d689b8e80(0000) GS:ffff88013fd00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f8d689c7000 CR3: 000000012ba6a000 CR4: 00000000000006e0 Call Trace: xfs_defer_init+0xff/0x160 xfs_reflink_remap_extent+0x31b/0xa00 xfs_reflink_remap_blocks+0xec/0x4a0 xfs_reflink_remap_range+0x3a1/0x650 xfs_file_dedupe_range+0x39/0x50 vfs_dedupe_file_range+0x218/0x260 do_vfs_ioctl+0x262/0x6a0 ? __se_sys_newfstat+0x3c/0x60 ksys_ioctl+0x35/0x60 __x64_sys_ioctl+0x11/0x20 do_syscall_64+0x4b/0x190 entry_SYSCALL_64_after_hwframe+0x49/0xbe The root cause of the assertion failure is that xfs_defer_finish doesn't roll the transaction after processing all the deferred items. Therefore it returns a dirty transaction to the caller, which leaves the caller at risk of exceeding the transaction reservation if it logs more items. Brian Foster's patchset to move the defer_ops firstblock into the transaction requires t_firstblock == NULLFSBLOCK upon defer_ops initialization, which is how this was noticed at all. Reported-by: Christoph Hellwig Signed-off-by: Darrick J. Wong Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_defer.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index 2713e2d808a7..c4b0eaeb5190 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -424,6 +424,12 @@ xfs_defer_finish( cleanup_fn(*tp, state, error); } + /* + * Roll the transaction once more to avoid returning to the caller + * with a dirty transaction. + */ + if ((*tp)->t_flags & XFS_TRANS_DIRTY) + error = xfs_defer_trans_roll(tp, dop); out: (*tp)->t_dfops = orig_dop; if (error) -- cgit v1.2.3 From 0b04b6b875b32f2b32263ba46d54d001e05724f9 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 19 Jul 2018 12:26:31 -0700 Subject: xfs: trivial xfs_btree_del_cursor cleanups The error argument to xfs_btree_del_cursor already understands the "nonzero for error" semantics, so remove pointless error testing in the callers and pass it directly. Signed-off-by: Darrick J. Wong Reviewed-by: Brian Foster Reviewed-by: Carlos Maiolino Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_bmap.c | 24 ++++++++---------------- fs/xfs/libxfs/xfs_bmap_btree.c | 2 +- fs/xfs/libxfs/xfs_ialloc.c | 2 +- fs/xfs/libxfs/xfs_ialloc_btree.c | 2 +- fs/xfs/libxfs/xfs_refcount.c | 2 +- fs/xfs/libxfs/xfs_rmap.c | 18 +++--------------- fs/xfs/scrub/bmap.c | 5 ++--- fs/xfs/scrub/repair.c | 2 +- fs/xfs/xfs_discard.c | 2 +- fs/xfs/xfs_fsmap.c | 2 +- fs/xfs/xfs_itable.c | 6 ++---- fs/xfs/xfs_reflink.c | 2 +- 12 files changed, 23 insertions(+), 46 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 7b93b1e16ad9..6bc0cdff488e 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -961,8 +961,7 @@ xfs_bmap_add_attrfork_extents( XFS_DATA_FORK); if (cur) { cur->bc_private.b.allocated = 0; - xfs_btree_del_cursor(cur, - error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + xfs_btree_del_cursor(cur, error); } return error; } @@ -4447,8 +4446,7 @@ error0: xfs_trans_log_inode(tp, ip, bma.logflags); if (bma.cur) { - xfs_btree_del_cursor(bma.cur, - error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + xfs_btree_del_cursor(bma.cur, error); } if (!error) xfs_bmap_validate_ret(orig_bno, orig_len, orig_flags, orig_mval, @@ -4542,10 +4540,8 @@ error0: if (logflags) xfs_trans_log_inode(tp, ip, logflags); - if (cur) { - xfs_btree_del_cursor(cur, - error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); - } + if (cur) + xfs_btree_del_cursor(cur, error); return error; } @@ -5439,8 +5435,7 @@ error0: if (cur) { if (!error) cur->bc_private.b.allocated = 0; - xfs_btree_del_cursor(cur, - error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + xfs_btree_del_cursor(cur, error); } return error; } @@ -5700,8 +5695,7 @@ done: *next_fsb = got.br_startoff; del_cursor: if (cur) - xfs_btree_del_cursor(cur, - error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + xfs_btree_del_cursor(cur, error); if (logflags) xfs_trans_log_inode(tp, ip, logflags); return error; @@ -5828,8 +5822,7 @@ xfs_bmap_insert_extents( *next_fsb = got.br_startoff; del_cursor: if (cur) - xfs_btree_del_cursor(cur, - error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + xfs_btree_del_cursor(cur, error); if (logflags) xfs_trans_log_inode(tp, ip, logflags); return error; @@ -5945,8 +5938,7 @@ xfs_bmap_split_extent_at( del_cursor: if (cur) { cur->bc_private.b.allocated = 0; - xfs_btree_del_cursor(cur, - error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + xfs_btree_del_cursor(cur, error); } if (logflags) diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 628ed82ca286..01489714a253 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -639,7 +639,7 @@ xfs_bmbt_change_owner( cur->bc_private.b.flags |= XFS_BTCUR_BPRV_INVALID_OWNER; error = xfs_btree_change_owner(cur, new_owner, buffer_list); - xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + xfs_btree_del_cursor(cur, error); return error; } diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 811d36afd024..295304ad1bc1 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -2258,7 +2258,7 @@ xfs_imap_lookup( } xfs_trans_brelse(tp, agbp); - xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + xfs_btree_del_cursor(cur, error); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index a5237afec5ab..735a33252eb2 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -566,7 +566,7 @@ xfs_inobt_count_blocks( cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno, btnum); error = xfs_btree_count_blocks(cur, tree_blocks); - xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + xfs_btree_del_cursor(cur, error); xfs_buf_relse(agbp); return error; diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index 2ecfb0518580..a2dfae67ade1 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -1067,7 +1067,7 @@ xfs_refcount_finish_one_cleanup( if (rcur == NULL) return; agbp = rcur->bc_private.a.agbp; - xfs_btree_del_cursor(rcur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + xfs_btree_del_cursor(rcur, error); if (error) xfs_trans_brelse(tp, agbp); } diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index 8b2a2f81d110..fb266fa2cc45 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -670,14 +670,8 @@ xfs_rmap_free( cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno); error = xfs_rmap_unmap(cur, bno, len, false, oinfo); - if (error) - goto out_error; - xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); - return 0; - -out_error: - xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); + xfs_btree_del_cursor(cur, error); return error; } @@ -912,14 +906,8 @@ xfs_rmap_alloc( cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno); error = xfs_rmap_map(cur, bno, len, false, oinfo); - if (error) - goto out_error; - xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); - return 0; - -out_error: - xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); + xfs_btree_del_cursor(cur, error); return error; } @@ -2156,7 +2144,7 @@ xfs_rmap_finish_one_cleanup( if (rcur == NULL) return; agbp = rcur->bc_private.a.agbp; - xfs_btree_del_cursor(rcur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + xfs_btree_del_cursor(rcur, error); if (error) xfs_trans_brelse(tp, agbp); } diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c index 3d08589f5c60..ebbfab173e97 100644 --- a/fs/xfs/scrub/bmap.c +++ b/fs/xfs/scrub/bmap.c @@ -404,8 +404,7 @@ xfs_scrub_bmap_btree( cur = xfs_bmbt_init_cursor(mp, sc->tp, ip, whichfork); xfs_rmap_ino_bmbt_owner(&oinfo, ip->i_ino, whichfork); error = xfs_scrub_btree(sc, cur, xfs_scrub_bmapbt_rec, &oinfo, info); - xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : - XFS_BTREE_NOERROR); + xfs_btree_del_cursor(cur, error); return error; } @@ -514,7 +513,7 @@ xfs_scrub_bmap_check_ag_rmaps( if (error == XFS_BTREE_QUERY_RANGE_ABORT) error = 0; - xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + xfs_btree_del_cursor(cur, error); out_agf: xfs_trans_brelse(sc->tp, agf); return error; diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 326be4e8b71e..35c589a04fac 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -1009,7 +1009,7 @@ xfs_repair_find_ag_btree_roots( cur = xfs_rmapbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.agno); error = xfs_rmap_query_all(cur, xfs_repair_findroot_rmap, &ri); - xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + xfs_btree_del_cursor(cur, error); return error; } diff --git a/fs/xfs/xfs_discard.c b/fs/xfs/xfs_discard.c index 678a5fcd7576..93f07edafd81 100644 --- a/fs/xfs/xfs_discard.c +++ b/fs/xfs/xfs_discard.c @@ -128,7 +128,7 @@ next_extent: } out_del_cursor: - xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + xfs_btree_del_cursor(cur, error); xfs_buf_relse(agbp); out_put_perag: xfs_perag_put(pag); diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c index 297d7ce2901e..3d76a9e35870 100644 --- a/fs/xfs/xfs_fsmap.c +++ b/fs/xfs/xfs_fsmap.c @@ -219,7 +219,7 @@ xfs_getfsmap_is_shared( error = xfs_refcount_find_shared(cur, rec->rm_startblock, rec->rm_blockcount, &fbno, &flen, false); - xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + xfs_btree_del_cursor(cur, error); if (error) return error; diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 24f4f1c555b5..65810827a8d0 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -458,8 +458,7 @@ xfs_bulkstat( * pending error, then we are done. */ del_cursor: - xfs_btree_del_cursor(cur, error ? - XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + xfs_btree_del_cursor(cur, error); xfs_buf_relse(agbp); if (error) break; @@ -632,8 +631,7 @@ next_ag: kmem_free(buffer); if (cur) - xfs_btree_del_cursor(cur, (error ? XFS_BTREE_ERROR : - XFS_BTREE_NOERROR)); + xfs_btree_del_cursor(cur, error); if (agbp) xfs_buf_relse(agbp); diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 3143889097f1..406f79d44153 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -162,7 +162,7 @@ xfs_reflink_find_shared( error = xfs_refcount_find_shared(cur, agbno, aglen, fbno, flen, find_end_of_shared); - xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + xfs_btree_del_cursor(cur, error); xfs_trans_brelse(tp, agbp); return error; -- cgit v1.2.3 From ef97ef26d263fb65f0c7446a10cf93201dc0388c Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 19 Jul 2018 12:29:10 -0700 Subject: xfs: clean up xfs_btree_del_cursor callers Less trivial cleanups of the error argument to xfs_btree_del_cursor; these require some minor code refactoring. Signed-off-by: Darrick J. Wong Reviewed-by: Brian Foster Reviewed-by: Carlos Maiolino Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_refcount.c | 11 +++-------- fs/xfs/scrub/repair.c | 7 +++---- 2 files changed, 6 insertions(+), 12 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index a2dfae67ade1..9ef1f440a6f2 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -1675,11 +1675,11 @@ xfs_refcount_recover_cow_leftovers( high.rc.rc_startblock = -1U; error = xfs_btree_query_range(cur, &low, &high, xfs_refcount_recover_extent, &debris); - if (error) - goto out_cursor; - xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); + xfs_btree_del_cursor(cur, error); xfs_trans_brelse(tp, agbp); xfs_trans_cancel(tp); + if (error) + goto out_free; /* Now iterate the list to free the leftovers */ list_for_each_entry_safe(rr, n, &debris, rr_list) { @@ -1727,11 +1727,6 @@ out_free: kmem_free(rr); } return error; - -out_cursor: - xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); - xfs_trans_brelse(tp, agbp); - goto out_trans; } /* Is there a record covering a given extent? */ diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 35c589a04fac..ea39e2bdc96a 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -747,9 +747,9 @@ xfs_repair_dispose_btree_block( /* Can we find any other rmappings? */ error = xfs_rmap_has_other_keys(cur, agbno, 1, oinfo, &has_other_rmap); + xfs_btree_del_cursor(cur, error); if (error) - goto out_cur; - xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); + goto out_free; /* * If there are other rmappings, this block is cross linked and must @@ -779,8 +779,7 @@ xfs_repair_dispose_btree_block( return xfs_trans_roll_inode(&sc->tp, sc->ip); return xfs_repair_roll_ag_trans(sc); -out_cur: - xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); +out_free: if (agf_bp != sc->sa.agf_bp) xfs_trans_brelse(sc->tp, agf_bp); return error; -- cgit v1.2.3 From c517b3aa02cff1dd688aa783b748e06c8aee1285 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 19 Jul 2018 12:29:11 -0700 Subject: xfs: shorten xfs_scrub_ prefix Shorten all the metadata checking xfs_scrub_ prefixes to xchk_. After this, the only xfs_scrub* symbols are the ones that pertain to both scrub and repair. Whitespace damage will be fixed in a subsequent patch. There are no functional changes. Signed-off-by: Darrick J. Wong Reviewed-by: Brian Foster --- fs/xfs/scrub/agheader.c | 318 ++++++++++++++++++++++++------------------------ fs/xfs/scrub/alloc.c | 56 ++++----- fs/xfs/scrub/attr.c | 106 ++++++++-------- fs/xfs/scrub/bmap.c | 176 +++++++++++++-------------- fs/xfs/scrub/btree.c | 166 ++++++++++++------------- fs/xfs/scrub/btree.h | 22 ++-- fs/xfs/scrub/common.c | 172 +++++++++++++------------- fs/xfs/scrub/common.h | 102 ++++++++-------- fs/xfs/scrub/dabtree.c | 124 +++++++++---------- fs/xfs/scrub/dabtree.h | 14 +-- fs/xfs/scrub/dir.c | 170 +++++++++++++------------- fs/xfs/scrub/ialloc.c | 138 ++++++++++----------- fs/xfs/scrub/inode.c | 160 ++++++++++++------------ fs/xfs/scrub/parent.c | 62 +++++----- fs/xfs/scrub/quota.c | 64 +++++----- fs/xfs/scrub/refcount.c | 114 ++++++++--------- fs/xfs/scrub/repair.c | 4 +- fs/xfs/scrub/rmap.c | 78 ++++++------ fs/xfs/scrub/rtbitmap.c | 30 ++--- fs/xfs/scrub/scrub.c | 142 ++++++++++----------- fs/xfs/scrub/scrub.h | 82 ++++++------- fs/xfs/scrub/symlink.c | 14 +-- fs/xfs/scrub/trace.c | 2 +- fs/xfs/scrub/trace.h | 70 +++++------ 24 files changed, 1196 insertions(+), 1190 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/scrub/agheader.c b/fs/xfs/scrub/agheader.c index 9bb0745f1ad2..c0625ec16d63 100644 --- a/fs/xfs/scrub/agheader.c +++ b/fs/xfs/scrub/agheader.c @@ -28,7 +28,7 @@ /* Cross-reference with the other btrees. */ STATIC void -xfs_scrub_superblock_xref( +xchk_superblock_xref( struct xfs_scrub_context *sc, struct xfs_buf *bp) { @@ -43,15 +43,15 @@ xfs_scrub_superblock_xref( agbno = XFS_SB_BLOCK(mp); - error = xfs_scrub_ag_init(sc, agno, &sc->sa); - if (!xfs_scrub_xref_process_error(sc, agno, agbno, &error)) + error = xchk_ag_init(sc, agno, &sc->sa); + if (!xchk_xref_process_error(sc, agno, agbno, &error)) return; - xfs_scrub_xref_is_used_space(sc, agbno, 1); - xfs_scrub_xref_is_not_inode_chunk(sc, agbno, 1); + xchk_xref_is_used_space(sc, agbno, 1); + xchk_xref_is_not_inode_chunk(sc, agbno, 1); xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_FS); - xfs_scrub_xref_is_owned_by(sc, agbno, 1, &oinfo); - xfs_scrub_xref_is_not_shared(sc, agbno, 1); + xchk_xref_is_owned_by(sc, agbno, 1, &oinfo); + xchk_xref_is_not_shared(sc, agbno, 1); /* scrub teardown will take care of sc->sa for us */ } @@ -65,7 +65,7 @@ xfs_scrub_superblock_xref( * sb 0 is ok and we can use its information to check everything else. */ int -xfs_scrub_superblock( +xchk_superblock( struct xfs_scrub_context *sc) { struct xfs_mount *mp = sc->mp; @@ -98,7 +98,7 @@ xfs_scrub_superblock( default: break; } - if (!xfs_scrub_process_error(sc, agno, XFS_SB_BLOCK(mp), &error)) + if (!xchk_process_error(sc, agno, XFS_SB_BLOCK(mp), &error)) return error; sb = XFS_BUF_TO_SBP(bp); @@ -110,46 +110,46 @@ xfs_scrub_superblock( * checked. */ if (sb->sb_blocksize != cpu_to_be32(mp->m_sb.sb_blocksize)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_dblocks != cpu_to_be64(mp->m_sb.sb_dblocks)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_rblocks != cpu_to_be64(mp->m_sb.sb_rblocks)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_rextents != cpu_to_be64(mp->m_sb.sb_rextents)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (!uuid_equal(&sb->sb_uuid, &mp->m_sb.sb_uuid)) - xfs_scrub_block_set_preen(sc, bp); + xchk_block_set_preen(sc, bp); if (sb->sb_logstart != cpu_to_be64(mp->m_sb.sb_logstart)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_rootino != cpu_to_be64(mp->m_sb.sb_rootino)) - xfs_scrub_block_set_preen(sc, bp); + xchk_block_set_preen(sc, bp); if (sb->sb_rbmino != cpu_to_be64(mp->m_sb.sb_rbmino)) - xfs_scrub_block_set_preen(sc, bp); + xchk_block_set_preen(sc, bp); if (sb->sb_rsumino != cpu_to_be64(mp->m_sb.sb_rsumino)) - xfs_scrub_block_set_preen(sc, bp); + xchk_block_set_preen(sc, bp); if (sb->sb_rextsize != cpu_to_be32(mp->m_sb.sb_rextsize)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_agblocks != cpu_to_be32(mp->m_sb.sb_agblocks)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_agcount != cpu_to_be32(mp->m_sb.sb_agcount)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_rbmblocks != cpu_to_be32(mp->m_sb.sb_rbmblocks)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_logblocks != cpu_to_be32(mp->m_sb.sb_logblocks)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); /* Check sb_versionnum bits that are set at mkfs time. */ vernum_mask = cpu_to_be16(~XFS_SB_VERSION_OKBITS | @@ -163,7 +163,7 @@ xfs_scrub_superblock( XFS_SB_VERSION_DIRV2BIT); if ((sb->sb_versionnum & vernum_mask) != (cpu_to_be16(mp->m_sb.sb_versionnum) & vernum_mask)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); /* Check sb_versionnum bits that can be set after mkfs time. */ vernum_mask = cpu_to_be16(XFS_SB_VERSION_ATTRBIT | @@ -171,40 +171,40 @@ xfs_scrub_superblock( XFS_SB_VERSION_QUOTABIT); if ((sb->sb_versionnum & vernum_mask) != (cpu_to_be16(mp->m_sb.sb_versionnum) & vernum_mask)) - xfs_scrub_block_set_preen(sc, bp); + xchk_block_set_preen(sc, bp); if (sb->sb_sectsize != cpu_to_be16(mp->m_sb.sb_sectsize)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_inodesize != cpu_to_be16(mp->m_sb.sb_inodesize)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_inopblock != cpu_to_be16(mp->m_sb.sb_inopblock)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (memcmp(sb->sb_fname, mp->m_sb.sb_fname, sizeof(sb->sb_fname))) - xfs_scrub_block_set_preen(sc, bp); + xchk_block_set_preen(sc, bp); if (sb->sb_blocklog != mp->m_sb.sb_blocklog) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_sectlog != mp->m_sb.sb_sectlog) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_inodelog != mp->m_sb.sb_inodelog) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_inopblog != mp->m_sb.sb_inopblog) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_agblklog != mp->m_sb.sb_agblklog) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_rextslog != mp->m_sb.sb_rextslog) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_imax_pct != mp->m_sb.sb_imax_pct) - xfs_scrub_block_set_preen(sc, bp); + xchk_block_set_preen(sc, bp); /* * Skip the summary counters since we track them in memory anyway. @@ -212,10 +212,10 @@ xfs_scrub_superblock( */ if (sb->sb_uquotino != cpu_to_be64(mp->m_sb.sb_uquotino)) - xfs_scrub_block_set_preen(sc, bp); + xchk_block_set_preen(sc, bp); if (sb->sb_gquotino != cpu_to_be64(mp->m_sb.sb_gquotino)) - xfs_scrub_block_set_preen(sc, bp); + xchk_block_set_preen(sc, bp); /* * Skip the quota flags since repair will force quotacheck. @@ -223,46 +223,46 @@ xfs_scrub_superblock( */ if (sb->sb_flags != mp->m_sb.sb_flags) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_shared_vn != mp->m_sb.sb_shared_vn) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_inoalignmt != cpu_to_be32(mp->m_sb.sb_inoalignmt)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_unit != cpu_to_be32(mp->m_sb.sb_unit)) - xfs_scrub_block_set_preen(sc, bp); + xchk_block_set_preen(sc, bp); if (sb->sb_width != cpu_to_be32(mp->m_sb.sb_width)) - xfs_scrub_block_set_preen(sc, bp); + xchk_block_set_preen(sc, bp); if (sb->sb_dirblklog != mp->m_sb.sb_dirblklog) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_logsectlog != mp->m_sb.sb_logsectlog) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_logsectsize != cpu_to_be16(mp->m_sb.sb_logsectsize)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_logsunit != cpu_to_be32(mp->m_sb.sb_logsunit)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); /* Do we see any invalid bits in sb_features2? */ if (!xfs_sb_version_hasmorebits(&mp->m_sb)) { if (sb->sb_features2 != 0) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); } else { v2_ok = XFS_SB_VERSION2_OKBITS; if (XFS_SB_VERSION_NUM(&mp->m_sb) >= XFS_SB_VERSION_5) v2_ok |= XFS_SB_VERSION2_CRCBIT; if (!!(sb->sb_features2 & cpu_to_be32(~v2_ok))) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_features2 != sb->sb_bad_features2) - xfs_scrub_block_set_preen(sc, bp); + xchk_block_set_preen(sc, bp); } /* Check sb_features2 flags that are set at mkfs time. */ @@ -272,26 +272,26 @@ xfs_scrub_superblock( XFS_SB_VERSION2_FTYPE); if ((sb->sb_features2 & features_mask) != (cpu_to_be32(mp->m_sb.sb_features2) & features_mask)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); /* Check sb_features2 flags that can be set after mkfs time. */ features_mask = cpu_to_be32(XFS_SB_VERSION2_ATTR2BIT); if ((sb->sb_features2 & features_mask) != (cpu_to_be32(mp->m_sb.sb_features2) & features_mask)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (!xfs_sb_version_hascrc(&mp->m_sb)) { /* all v5 fields must be zero */ if (memchr_inv(&sb->sb_features_compat, 0, sizeof(struct xfs_dsb) - offsetof(struct xfs_dsb, sb_features_compat))) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); } else { /* Check compat flags; all are set at mkfs time. */ features_mask = cpu_to_be32(XFS_SB_FEAT_COMPAT_UNKNOWN); if ((sb->sb_features_compat & features_mask) != (cpu_to_be32(mp->m_sb.sb_features_compat) & features_mask)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); /* Check ro compat flags; all are set at mkfs time. */ features_mask = cpu_to_be32(XFS_SB_FEAT_RO_COMPAT_UNKNOWN | @@ -301,7 +301,7 @@ xfs_scrub_superblock( if ((sb->sb_features_ro_compat & features_mask) != (cpu_to_be32(mp->m_sb.sb_features_ro_compat) & features_mask)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); /* Check incompat flags; all are set at mkfs time. */ features_mask = cpu_to_be32(XFS_SB_FEAT_INCOMPAT_UNKNOWN | @@ -311,22 +311,22 @@ xfs_scrub_superblock( if ((sb->sb_features_incompat & features_mask) != (cpu_to_be32(mp->m_sb.sb_features_incompat) & features_mask)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); /* Check log incompat flags; all are set at mkfs time. */ features_mask = cpu_to_be32(XFS_SB_FEAT_INCOMPAT_LOG_UNKNOWN); if ((sb->sb_features_log_incompat & features_mask) != (cpu_to_be32(mp->m_sb.sb_features_log_incompat) & features_mask)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); /* Don't care about sb_crc */ if (sb->sb_spino_align != cpu_to_be32(mp->m_sb.sb_spino_align)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); if (sb->sb_pquotino != cpu_to_be64(mp->m_sb.sb_pquotino)) - xfs_scrub_block_set_preen(sc, bp); + xchk_block_set_preen(sc, bp); /* Don't care about sb_lsn */ } @@ -334,15 +334,15 @@ xfs_scrub_superblock( if (xfs_sb_version_hasmetauuid(&mp->m_sb)) { /* The metadata UUID must be the same for all supers */ if (!uuid_equal(&sb->sb_meta_uuid, &mp->m_sb.sb_meta_uuid)) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); } /* Everything else must be zero. */ if (memchr_inv(sb + 1, 0, BBTOB(bp->b_length) - sizeof(struct xfs_dsb))) - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); - xfs_scrub_superblock_xref(sc, bp); + xchk_superblock_xref(sc, bp); return error; } @@ -351,7 +351,7 @@ xfs_scrub_superblock( /* Tally freespace record lengths. */ STATIC int -xfs_scrub_agf_record_bno_lengths( +xchk_agf_record_bno_lengths( struct xfs_btree_cur *cur, struct xfs_alloc_rec_incore *rec, void *priv) @@ -364,7 +364,7 @@ xfs_scrub_agf_record_bno_lengths( /* Check agf_freeblks */ static inline void -xfs_scrub_agf_xref_freeblks( +xchk_agf_xref_freeblks( struct xfs_scrub_context *sc) { struct xfs_agf *agf = XFS_BUF_TO_AGF(sc->sa.agf_bp); @@ -375,16 +375,16 @@ xfs_scrub_agf_xref_freeblks( return; error = xfs_alloc_query_all(sc->sa.bno_cur, - xfs_scrub_agf_record_bno_lengths, &blocks); - if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.bno_cur)) + xchk_agf_record_bno_lengths, &blocks); + if (!xchk_should_check_xref(sc, &error, &sc->sa.bno_cur)) return; if (blocks != be32_to_cpu(agf->agf_freeblks)) - xfs_scrub_block_xref_set_corrupt(sc, sc->sa.agf_bp); + xchk_block_xref_set_corrupt(sc, sc->sa.agf_bp); } /* Cross reference the AGF with the cntbt (freespace by length btree) */ static inline void -xfs_scrub_agf_xref_cntbt( +xchk_agf_xref_cntbt( struct xfs_scrub_context *sc) { struct xfs_agf *agf = XFS_BUF_TO_AGF(sc->sa.agf_bp); @@ -398,25 +398,25 @@ xfs_scrub_agf_xref_cntbt( /* Any freespace at all? */ error = xfs_alloc_lookup_le(sc->sa.cnt_cur, 0, -1U, &have); - if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.cnt_cur)) + if (!xchk_should_check_xref(sc, &error, &sc->sa.cnt_cur)) return; if (!have) { if (agf->agf_freeblks != be32_to_cpu(0)) - xfs_scrub_block_xref_set_corrupt(sc, sc->sa.agf_bp); + xchk_block_xref_set_corrupt(sc, sc->sa.agf_bp); return; } /* Check agf_longest */ error = xfs_alloc_get_rec(sc->sa.cnt_cur, &agbno, &blocks, &have); - if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.cnt_cur)) + if (!xchk_should_check_xref(sc, &error, &sc->sa.cnt_cur)) return; if (!have || blocks != be32_to_cpu(agf->agf_longest)) - xfs_scrub_block_xref_set_corrupt(sc, sc->sa.agf_bp); + xchk_block_xref_set_corrupt(sc, sc->sa.agf_bp); } /* Check the btree block counts in the AGF against the btrees. */ STATIC void -xfs_scrub_agf_xref_btreeblks( +xchk_agf_xref_btreeblks( struct xfs_scrub_context *sc) { struct xfs_agf *agf = XFS_BUF_TO_AGF(sc->sa.agf_bp); @@ -428,11 +428,11 @@ xfs_scrub_agf_xref_btreeblks( /* Check agf_rmap_blocks; set up for agf_btreeblks check */ if (sc->sa.rmap_cur) { error = xfs_btree_count_blocks(sc->sa.rmap_cur, &blocks); - if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.rmap_cur)) + if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur)) return; btreeblks = blocks - 1; if (blocks != be32_to_cpu(agf->agf_rmap_blocks)) - xfs_scrub_block_xref_set_corrupt(sc, sc->sa.agf_bp); + xchk_block_xref_set_corrupt(sc, sc->sa.agf_bp); } else { btreeblks = 0; } @@ -447,22 +447,22 @@ xfs_scrub_agf_xref_btreeblks( /* Check agf_btreeblks */ error = xfs_btree_count_blocks(sc->sa.bno_cur, &blocks); - if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.bno_cur)) + if (!xchk_should_check_xref(sc, &error, &sc->sa.bno_cur)) return; btreeblks += blocks - 1; error = xfs_btree_count_blocks(sc->sa.cnt_cur, &blocks); - if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.cnt_cur)) + if (!xchk_should_check_xref(sc, &error, &sc->sa.cnt_cur)) return; btreeblks += blocks - 1; if (btreeblks != be32_to_cpu(agf->agf_btreeblks)) - xfs_scrub_block_xref_set_corrupt(sc, sc->sa.agf_bp); + xchk_block_xref_set_corrupt(sc, sc->sa.agf_bp); } /* Check agf_refcount_blocks against tree size */ static inline void -xfs_scrub_agf_xref_refcblks( +xchk_agf_xref_refcblks( struct xfs_scrub_context *sc) { struct xfs_agf *agf = XFS_BUF_TO_AGF(sc->sa.agf_bp); @@ -473,15 +473,15 @@ xfs_scrub_agf_xref_refcblks( return; error = xfs_btree_count_blocks(sc->sa.refc_cur, &blocks); - if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.refc_cur)) + if (!xchk_should_check_xref(sc, &error, &sc->sa.refc_cur)) return; if (blocks != be32_to_cpu(agf->agf_refcount_blocks)) - xfs_scrub_block_xref_set_corrupt(sc, sc->sa.agf_bp); + xchk_block_xref_set_corrupt(sc, sc->sa.agf_bp); } /* Cross-reference with the other btrees. */ STATIC void -xfs_scrub_agf_xref( +xchk_agf_xref( struct xfs_scrub_context *sc) { struct xfs_owner_info oinfo; @@ -494,26 +494,26 @@ xfs_scrub_agf_xref( agbno = XFS_AGF_BLOCK(mp); - error = xfs_scrub_ag_btcur_init(sc, &sc->sa); + error = xchk_ag_btcur_init(sc, &sc->sa); if (error) return; - xfs_scrub_xref_is_used_space(sc, agbno, 1); - xfs_scrub_agf_xref_freeblks(sc); - xfs_scrub_agf_xref_cntbt(sc); - xfs_scrub_xref_is_not_inode_chunk(sc, agbno, 1); + xchk_xref_is_used_space(sc, agbno, 1); + xchk_agf_xref_freeblks(sc); + xchk_agf_xref_cntbt(sc); + xchk_xref_is_not_inode_chunk(sc, agbno, 1); xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_FS); - xfs_scrub_xref_is_owned_by(sc, agbno, 1, &oinfo); - xfs_scrub_agf_xref_btreeblks(sc); - xfs_scrub_xref_is_not_shared(sc, agbno, 1); - xfs_scrub_agf_xref_refcblks(sc); + xchk_xref_is_owned_by(sc, agbno, 1, &oinfo); + xchk_agf_xref_btreeblks(sc); + xchk_xref_is_not_shared(sc, agbno, 1); + xchk_agf_xref_refcblks(sc); /* scrub teardown will take care of sc->sa for us */ } /* Scrub the AGF. */ int -xfs_scrub_agf( +xchk_agf( struct xfs_scrub_context *sc) { struct xfs_mount *mp = sc->mp; @@ -529,54 +529,54 @@ xfs_scrub_agf( int error = 0; agno = sc->sa.agno = sc->sm->sm_agno; - error = xfs_scrub_ag_read_headers(sc, agno, &sc->sa.agi_bp, + error = xchk_ag_read_headers(sc, agno, &sc->sa.agi_bp, &sc->sa.agf_bp, &sc->sa.agfl_bp); - if (!xfs_scrub_process_error(sc, agno, XFS_AGF_BLOCK(sc->mp), &error)) + if (!xchk_process_error(sc, agno, XFS_AGF_BLOCK(sc->mp), &error)) goto out; - xfs_scrub_buffer_recheck(sc, sc->sa.agf_bp); + xchk_buffer_recheck(sc, sc->sa.agf_bp); agf = XFS_BUF_TO_AGF(sc->sa.agf_bp); /* Check the AG length */ eoag = be32_to_cpu(agf->agf_length); if (eoag != xfs_ag_block_count(mp, agno)) - xfs_scrub_block_set_corrupt(sc, sc->sa.agf_bp); + xchk_block_set_corrupt(sc, sc->sa.agf_bp); /* Check the AGF btree roots and levels */ agbno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]); if (!xfs_verify_agbno(mp, agno, agbno)) - xfs_scrub_block_set_corrupt(sc, sc->sa.agf_bp); + xchk_block_set_corrupt(sc, sc->sa.agf_bp); agbno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]); if (!xfs_verify_agbno(mp, agno, agbno)) - xfs_scrub_block_set_corrupt(sc, sc->sa.agf_bp); + xchk_block_set_corrupt(sc, sc->sa.agf_bp); level = be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]); if (level <= 0 || level > XFS_BTREE_MAXLEVELS) - xfs_scrub_block_set_corrupt(sc, sc->sa.agf_bp); + xchk_block_set_corrupt(sc, sc->sa.agf_bp); level = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]); if (level <= 0 || level > XFS_BTREE_MAXLEVELS) - xfs_scrub_block_set_corrupt(sc, sc->sa.agf_bp); + xchk_block_set_corrupt(sc, sc->sa.agf_bp); if (xfs_sb_version_hasrmapbt(&mp->m_sb)) { agbno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_RMAP]); if (!xfs_verify_agbno(mp, agno, agbno)) - xfs_scrub_block_set_corrupt(sc, sc->sa.agf_bp); + xchk_block_set_corrupt(sc, sc->sa.agf_bp); level = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]); if (level <= 0 || level > XFS_BTREE_MAXLEVELS) - xfs_scrub_block_set_corrupt(sc, sc->sa.agf_bp); + xchk_block_set_corrupt(sc, sc->sa.agf_bp); } if (xfs_sb_version_hasreflink(&mp->m_sb)) { agbno = be32_to_cpu(agf->agf_refcount_root); if (!xfs_verify_agbno(mp, agno, agbno)) - xfs_scrub_block_set_corrupt(sc, sc->sa.agf_bp); + xchk_block_set_corrupt(sc, sc->sa.agf_bp); level = be32_to_cpu(agf->agf_refcount_level); if (level <= 0 || level > XFS_BTREE_MAXLEVELS) - xfs_scrub_block_set_corrupt(sc, sc->sa.agf_bp); + xchk_block_set_corrupt(sc, sc->sa.agf_bp); } /* Check the AGFL counters */ @@ -588,16 +588,16 @@ xfs_scrub_agf( else fl_count = xfs_agfl_size(mp) - agfl_first + agfl_last + 1; if (agfl_count != 0 && fl_count != agfl_count) - xfs_scrub_block_set_corrupt(sc, sc->sa.agf_bp); + xchk_block_set_corrupt(sc, sc->sa.agf_bp); - xfs_scrub_agf_xref(sc); + xchk_agf_xref(sc); out: return error; } /* AGFL */ -struct xfs_scrub_agfl_info { +struct xchk_agfl_info { struct xfs_owner_info oinfo; unsigned int sz_entries; unsigned int nr_entries; @@ -607,7 +607,7 @@ struct xfs_scrub_agfl_info { /* Cross-reference with the other btrees. */ STATIC void -xfs_scrub_agfl_block_xref( +xchk_agfl_block_xref( struct xfs_scrub_context *sc, xfs_agblock_t agbno, struct xfs_owner_info *oinfo) @@ -615,20 +615,20 @@ xfs_scrub_agfl_block_xref( if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) return; - xfs_scrub_xref_is_used_space(sc, agbno, 1); - xfs_scrub_xref_is_not_inode_chunk(sc, agbno, 1); - xfs_scrub_xref_is_owned_by(sc, agbno, 1, oinfo); - xfs_scrub_xref_is_not_shared(sc, agbno, 1); + xchk_xref_is_used_space(sc, agbno, 1); + xchk_xref_is_not_inode_chunk(sc, agbno, 1); + xchk_xref_is_owned_by(sc, agbno, 1, oinfo); + xchk_xref_is_not_shared(sc, agbno, 1); } /* Scrub an AGFL block. */ STATIC int -xfs_scrub_agfl_block( +xchk_agfl_block( struct xfs_mount *mp, xfs_agblock_t agbno, void *priv) { - struct xfs_scrub_agfl_info *sai = priv; + struct xchk_agfl_info *sai = priv; struct xfs_scrub_context *sc = sai->sc; xfs_agnumber_t agno = sc->sa.agno; @@ -636,9 +636,9 @@ xfs_scrub_agfl_block( sai->nr_entries < sai->sz_entries) sai->entries[sai->nr_entries++] = agbno; else - xfs_scrub_block_set_corrupt(sc, sc->sa.agfl_bp); + xchk_block_set_corrupt(sc, sc->sa.agfl_bp); - xfs_scrub_agfl_block_xref(sc, agbno, priv); + xchk_agfl_block_xref(sc, agbno, priv); if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) return XFS_BTREE_QUERY_RANGE_ABORT; @@ -647,7 +647,7 @@ xfs_scrub_agfl_block( } static int -xfs_scrub_agblock_cmp( +xchk_agblock_cmp( const void *pa, const void *pb) { @@ -659,7 +659,7 @@ xfs_scrub_agblock_cmp( /* Cross-reference with the other btrees. */ STATIC void -xfs_scrub_agfl_xref( +xchk_agfl_xref( struct xfs_scrub_context *sc) { struct xfs_owner_info oinfo; @@ -672,15 +672,15 @@ xfs_scrub_agfl_xref( agbno = XFS_AGFL_BLOCK(mp); - error = xfs_scrub_ag_btcur_init(sc, &sc->sa); + error = xchk_ag_btcur_init(sc, &sc->sa); if (error) return; - xfs_scrub_xref_is_used_space(sc, agbno, 1); - xfs_scrub_xref_is_not_inode_chunk(sc, agbno, 1); + xchk_xref_is_used_space(sc, agbno, 1); + xchk_xref_is_not_inode_chunk(sc, agbno, 1); xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_FS); - xfs_scrub_xref_is_owned_by(sc, agbno, 1, &oinfo); - xfs_scrub_xref_is_not_shared(sc, agbno, 1); + xchk_xref_is_owned_by(sc, agbno, 1, &oinfo); + xchk_xref_is_not_shared(sc, agbno, 1); /* * Scrub teardown will take care of sc->sa for us. Leave sc->sa @@ -690,10 +690,10 @@ xfs_scrub_agfl_xref( /* Scrub the AGFL. */ int -xfs_scrub_agfl( +xchk_agfl( struct xfs_scrub_context *sc) { - struct xfs_scrub_agfl_info sai; + struct xchk_agfl_info sai; struct xfs_agf *agf; xfs_agnumber_t agno; unsigned int agflcount; @@ -701,15 +701,15 @@ xfs_scrub_agfl( int error; agno = sc->sa.agno = sc->sm->sm_agno; - error = xfs_scrub_ag_read_headers(sc, agno, &sc->sa.agi_bp, + error = xchk_ag_read_headers(sc, agno, &sc->sa.agi_bp, &sc->sa.agf_bp, &sc->sa.agfl_bp); - if (!xfs_scrub_process_error(sc, agno, XFS_AGFL_BLOCK(sc->mp), &error)) + if (!xchk_process_error(sc, agno, XFS_AGFL_BLOCK(sc->mp), &error)) goto out; if (!sc->sa.agf_bp) return -EFSCORRUPTED; - xfs_scrub_buffer_recheck(sc, sc->sa.agfl_bp); + xchk_buffer_recheck(sc, sc->sa.agfl_bp); - xfs_scrub_agfl_xref(sc); + xchk_agfl_xref(sc); if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) goto out; @@ -718,7 +718,7 @@ xfs_scrub_agfl( agf = XFS_BUF_TO_AGF(sc->sa.agf_bp); agflcount = be32_to_cpu(agf->agf_flcount); if (agflcount > xfs_agfl_size(sc->mp)) { - xfs_scrub_block_set_corrupt(sc, sc->sa.agf_bp); + xchk_block_set_corrupt(sc, sc->sa.agf_bp); goto out; } memset(&sai, 0, sizeof(sai)); @@ -734,7 +734,7 @@ xfs_scrub_agfl( /* Check the blocks in the AGFL. */ xfs_rmap_ag_owner(&sai.oinfo, XFS_RMAP_OWN_AG); error = xfs_agfl_walk(sc->mp, XFS_BUF_TO_AGF(sc->sa.agf_bp), - sc->sa.agfl_bp, xfs_scrub_agfl_block, &sai); + sc->sa.agfl_bp, xchk_agfl_block, &sai); if (error == XFS_BTREE_QUERY_RANGE_ABORT) { error = 0; goto out_free; @@ -743,16 +743,16 @@ xfs_scrub_agfl( goto out_free; if (agflcount != sai.nr_entries) { - xfs_scrub_block_set_corrupt(sc, sc->sa.agf_bp); + xchk_block_set_corrupt(sc, sc->sa.agf_bp); goto out_free; } /* Sort entries, check for duplicates. */ sort(sai.entries, sai.nr_entries, sizeof(sai.entries[0]), - xfs_scrub_agblock_cmp, NULL); + xchk_agblock_cmp, NULL); for (i = 1; i < sai.nr_entries; i++) { if (sai.entries[i] == sai.entries[i - 1]) { - xfs_scrub_block_set_corrupt(sc, sc->sa.agf_bp); + xchk_block_set_corrupt(sc, sc->sa.agf_bp); break; } } @@ -767,7 +767,7 @@ out: /* Check agi_count/agi_freecount */ static inline void -xfs_scrub_agi_xref_icounts( +xchk_agi_xref_icounts( struct xfs_scrub_context *sc) { struct xfs_agi *agi = XFS_BUF_TO_AGI(sc->sa.agi_bp); @@ -779,16 +779,16 @@ xfs_scrub_agi_xref_icounts( return; error = xfs_ialloc_count_inodes(sc->sa.ino_cur, &icount, &freecount); - if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.ino_cur)) + if (!xchk_should_check_xref(sc, &error, &sc->sa.ino_cur)) return; if (be32_to_cpu(agi->agi_count) != icount || be32_to_cpu(agi->agi_freecount) != freecount) - xfs_scrub_block_xref_set_corrupt(sc, sc->sa.agi_bp); + xchk_block_xref_set_corrupt(sc, sc->sa.agi_bp); } /* Cross-reference with the other btrees. */ STATIC void -xfs_scrub_agi_xref( +xchk_agi_xref( struct xfs_scrub_context *sc) { struct xfs_owner_info oinfo; @@ -801,23 +801,23 @@ xfs_scrub_agi_xref( agbno = XFS_AGI_BLOCK(mp); - error = xfs_scrub_ag_btcur_init(sc, &sc->sa); + error = xchk_ag_btcur_init(sc, &sc->sa); if (error) return; - xfs_scrub_xref_is_used_space(sc, agbno, 1); - xfs_scrub_xref_is_not_inode_chunk(sc, agbno, 1); - xfs_scrub_agi_xref_icounts(sc); + xchk_xref_is_used_space(sc, agbno, 1); + xchk_xref_is_not_inode_chunk(sc, agbno, 1); + xchk_agi_xref_icounts(sc); xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_FS); - xfs_scrub_xref_is_owned_by(sc, agbno, 1, &oinfo); - xfs_scrub_xref_is_not_shared(sc, agbno, 1); + xchk_xref_is_owned_by(sc, agbno, 1, &oinfo); + xchk_xref_is_not_shared(sc, agbno, 1); /* scrub teardown will take care of sc->sa for us */ } /* Scrub the AGI. */ int -xfs_scrub_agi( +xchk_agi( struct xfs_scrub_context *sc) { struct xfs_mount *mp = sc->mp; @@ -834,36 +834,36 @@ xfs_scrub_agi( int error = 0; agno = sc->sa.agno = sc->sm->sm_agno; - error = xfs_scrub_ag_read_headers(sc, agno, &sc->sa.agi_bp, + error = xchk_ag_read_headers(sc, agno, &sc->sa.agi_bp, &sc->sa.agf_bp, &sc->sa.agfl_bp); - if (!xfs_scrub_process_error(sc, agno, XFS_AGI_BLOCK(sc->mp), &error)) + if (!xchk_process_error(sc, agno, XFS_AGI_BLOCK(sc->mp), &error)) goto out; - xfs_scrub_buffer_recheck(sc, sc->sa.agi_bp); + xchk_buffer_recheck(sc, sc->sa.agi_bp); agi = XFS_BUF_TO_AGI(sc->sa.agi_bp); /* Check the AG length */ eoag = be32_to_cpu(agi->agi_length); if (eoag != xfs_ag_block_count(mp, agno)) - xfs_scrub_block_set_corrupt(sc, sc->sa.agi_bp); + xchk_block_set_corrupt(sc, sc->sa.agi_bp); /* Check btree roots and levels */ agbno = be32_to_cpu(agi->agi_root); if (!xfs_verify_agbno(mp, agno, agbno)) - xfs_scrub_block_set_corrupt(sc, sc->sa.agi_bp); + xchk_block_set_corrupt(sc, sc->sa.agi_bp); level = be32_to_cpu(agi->agi_level); if (level <= 0 || level > XFS_BTREE_MAXLEVELS) - xfs_scrub_block_set_corrupt(sc, sc->sa.agi_bp); + xchk_block_set_corrupt(sc, sc->sa.agi_bp); if (xfs_sb_version_hasfinobt(&mp->m_sb)) { agbno = be32_to_cpu(agi->agi_free_root); if (!xfs_verify_agbno(mp, agno, agbno)) - xfs_scrub_block_set_corrupt(sc, sc->sa.agi_bp); + xchk_block_set_corrupt(sc, sc->sa.agi_bp); level = be32_to_cpu(agi->agi_free_level); if (level <= 0 || level > XFS_BTREE_MAXLEVELS) - xfs_scrub_block_set_corrupt(sc, sc->sa.agi_bp); + xchk_block_set_corrupt(sc, sc->sa.agi_bp); } /* Check inode counters */ @@ -871,16 +871,16 @@ xfs_scrub_agi( icount = be32_to_cpu(agi->agi_count); if (icount > last_agino - first_agino + 1 || icount < be32_to_cpu(agi->agi_freecount)) - xfs_scrub_block_set_corrupt(sc, sc->sa.agi_bp); + xchk_block_set_corrupt(sc, sc->sa.agi_bp); /* Check inode pointers */ agino = be32_to_cpu(agi->agi_newino); if (agino != NULLAGINO && !xfs_verify_agino(mp, agno, agino)) - xfs_scrub_block_set_corrupt(sc, sc->sa.agi_bp); + xchk_block_set_corrupt(sc, sc->sa.agi_bp); agino = be32_to_cpu(agi->agi_dirino); if (agino != NULLAGINO && !xfs_verify_agino(mp, agno, agino)) - xfs_scrub_block_set_corrupt(sc, sc->sa.agi_bp); + xchk_block_set_corrupt(sc, sc->sa.agi_bp); /* Check unlinked inode buckets */ for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) { @@ -888,13 +888,13 @@ xfs_scrub_agi( if (agino == NULLAGINO) continue; if (!xfs_verify_agino(mp, agno, agino)) - xfs_scrub_block_set_corrupt(sc, sc->sa.agi_bp); + xchk_block_set_corrupt(sc, sc->sa.agi_bp); } if (agi->agi_pad32 != cpu_to_be32(0)) - xfs_scrub_block_set_corrupt(sc, sc->sa.agi_bp); + xchk_block_set_corrupt(sc, sc->sa.agi_bp); - xfs_scrub_agi_xref(sc); + xchk_agi_xref(sc); out: return error; } diff --git a/fs/xfs/scrub/alloc.c b/fs/xfs/scrub/alloc.c index 50e4f7fa06f0..1f6e3a6a1fdd 100644 --- a/fs/xfs/scrub/alloc.c +++ b/fs/xfs/scrub/alloc.c @@ -28,11 +28,11 @@ * Set us up to scrub free space btrees. */ int -xfs_scrub_setup_ag_allocbt( +xchk_setup_ag_allocbt( struct xfs_scrub_context *sc, struct xfs_inode *ip) { - return xfs_scrub_setup_ag_btree(sc, ip, false); + return xchk_setup_ag_btree(sc, ip, false); } /* Free space btree scrubber. */ @@ -41,7 +41,7 @@ xfs_scrub_setup_ag_allocbt( * bnobt/cntbt record, respectively. */ STATIC void -xfs_scrub_allocbt_xref_other( +xchk_allocbt_xref_other( struct xfs_scrub_context *sc, xfs_agblock_t agbno, xfs_extlen_t len) @@ -56,32 +56,32 @@ xfs_scrub_allocbt_xref_other( pcur = &sc->sa.cnt_cur; else pcur = &sc->sa.bno_cur; - if (!*pcur || xfs_scrub_skip_xref(sc->sm)) + if (!*pcur || xchk_skip_xref(sc->sm)) return; error = xfs_alloc_lookup_le(*pcur, agbno, len, &has_otherrec); - if (!xfs_scrub_should_check_xref(sc, &error, pcur)) + if (!xchk_should_check_xref(sc, &error, pcur)) return; if (!has_otherrec) { - xfs_scrub_btree_xref_set_corrupt(sc, *pcur, 0); + xchk_btree_xref_set_corrupt(sc, *pcur, 0); return; } error = xfs_alloc_get_rec(*pcur, &fbno, &flen, &has_otherrec); - if (!xfs_scrub_should_check_xref(sc, &error, pcur)) + if (!xchk_should_check_xref(sc, &error, pcur)) return; if (!has_otherrec) { - xfs_scrub_btree_xref_set_corrupt(sc, *pcur, 0); + xchk_btree_xref_set_corrupt(sc, *pcur, 0); return; } if (fbno != agbno || flen != len) - xfs_scrub_btree_xref_set_corrupt(sc, *pcur, 0); + xchk_btree_xref_set_corrupt(sc, *pcur, 0); } /* Cross-reference with the other btrees. */ STATIC void -xfs_scrub_allocbt_xref( +xchk_allocbt_xref( struct xfs_scrub_context *sc, xfs_agblock_t agbno, xfs_extlen_t len) @@ -89,16 +89,16 @@ xfs_scrub_allocbt_xref( if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) return; - xfs_scrub_allocbt_xref_other(sc, agbno, len); - xfs_scrub_xref_is_not_inode_chunk(sc, agbno, len); - xfs_scrub_xref_has_no_owner(sc, agbno, len); - xfs_scrub_xref_is_not_shared(sc, agbno, len); + xchk_allocbt_xref_other(sc, agbno, len); + xchk_xref_is_not_inode_chunk(sc, agbno, len); + xchk_xref_has_no_owner(sc, agbno, len); + xchk_xref_is_not_shared(sc, agbno, len); } /* Scrub a bnobt/cntbt record. */ STATIC int -xfs_scrub_allocbt_rec( - struct xfs_scrub_btree *bs, +xchk_allocbt_rec( + struct xchk_btree *bs, union xfs_btree_rec *rec) { struct xfs_mount *mp = bs->cur->bc_mp; @@ -113,16 +113,16 @@ xfs_scrub_allocbt_rec( if (bno + len <= bno || !xfs_verify_agbno(mp, agno, bno) || !xfs_verify_agbno(mp, agno, bno + len - 1)) - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); - xfs_scrub_allocbt_xref(bs->sc, bno, len); + xchk_allocbt_xref(bs->sc, bno, len); return error; } /* Scrub the freespace btrees for some AG. */ STATIC int -xfs_scrub_allocbt( +xchk_allocbt( struct xfs_scrub_context *sc, xfs_btnum_t which) { @@ -131,26 +131,26 @@ xfs_scrub_allocbt( xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_AG); cur = which == XFS_BTNUM_BNO ? sc->sa.bno_cur : sc->sa.cnt_cur; - return xfs_scrub_btree(sc, cur, xfs_scrub_allocbt_rec, &oinfo, NULL); + return xchk_btree(sc, cur, xchk_allocbt_rec, &oinfo, NULL); } int -xfs_scrub_bnobt( +xchk_bnobt( struct xfs_scrub_context *sc) { - return xfs_scrub_allocbt(sc, XFS_BTNUM_BNO); + return xchk_allocbt(sc, XFS_BTNUM_BNO); } int -xfs_scrub_cntbt( +xchk_cntbt( struct xfs_scrub_context *sc) { - return xfs_scrub_allocbt(sc, XFS_BTNUM_CNT); + return xchk_allocbt(sc, XFS_BTNUM_CNT); } /* xref check that the extent is not free */ void -xfs_scrub_xref_is_used_space( +xchk_xref_is_used_space( struct xfs_scrub_context *sc, xfs_agblock_t agbno, xfs_extlen_t len) @@ -158,12 +158,12 @@ xfs_scrub_xref_is_used_space( bool is_freesp; int error; - if (!sc->sa.bno_cur || xfs_scrub_skip_xref(sc->sm)) + if (!sc->sa.bno_cur || xchk_skip_xref(sc->sm)) return; error = xfs_alloc_has_record(sc->sa.bno_cur, agbno, len, &is_freesp); - if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.bno_cur)) + if (!xchk_should_check_xref(sc, &error, &sc->sa.bno_cur)) return; if (is_freesp) - xfs_scrub_btree_xref_set_corrupt(sc, sc->sa.bno_cur, 0); + xchk_btree_xref_set_corrupt(sc, sc->sa.bno_cur, 0); } diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c index de51cf8a8516..0068bebddf3e 100644 --- a/fs/xfs/scrub/attr.c +++ b/fs/xfs/scrub/attr.c @@ -32,7 +32,7 @@ /* Set us up to scrub an inode's extended attributes. */ int -xfs_scrub_setup_xattr( +xchk_setup_xattr( struct xfs_scrub_context *sc, struct xfs_inode *ip) { @@ -50,12 +50,12 @@ xfs_scrub_setup_xattr( if (!sc->buf) return -ENOMEM; - return xfs_scrub_setup_inode_contents(sc, ip, 0); + return xchk_setup_inode_contents(sc, ip, 0); } /* Extended Attributes */ -struct xfs_scrub_xattr { +struct xchk_xattr { struct xfs_attr_list_context context; struct xfs_scrub_context *sc; }; @@ -69,22 +69,22 @@ struct xfs_scrub_xattr { * or if we get more or less data than we expected. */ static void -xfs_scrub_xattr_listent( +xchk_xattr_listent( struct xfs_attr_list_context *context, int flags, unsigned char *name, int namelen, int valuelen) { - struct xfs_scrub_xattr *sx; + struct xchk_xattr *sx; struct xfs_da_args args = { NULL }; int error = 0; - sx = container_of(context, struct xfs_scrub_xattr, context); + sx = container_of(context, struct xchk_xattr, context); if (flags & XFS_ATTR_INCOMPLETE) { /* Incomplete attr key, just mark the inode for preening. */ - xfs_scrub_ino_set_preen(sx->sc, context->dp->i_ino); + xchk_ino_set_preen(sx->sc, context->dp->i_ino); return; } @@ -106,11 +106,11 @@ xfs_scrub_xattr_listent( error = xfs_attr_get_ilocked(context->dp, &args); if (error == -EEXIST) error = 0; - if (!xfs_scrub_fblock_process_error(sx->sc, XFS_ATTR_FORK, args.blkno, + if (!xchk_fblock_process_error(sx->sc, XFS_ATTR_FORK, args.blkno, &error)) goto fail_xref; if (args.valuelen != valuelen) - xfs_scrub_fblock_set_corrupt(sx->sc, XFS_ATTR_FORK, + xchk_fblock_set_corrupt(sx->sc, XFS_ATTR_FORK, args.blkno); fail_xref: if (sx->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) @@ -126,7 +126,7 @@ fail_xref: * the smallest address */ STATIC bool -xfs_scrub_xattr_set_map( +xchk_xattr_set_map( struct xfs_scrub_context *sc, unsigned long *map, unsigned int start, @@ -154,7 +154,7 @@ xfs_scrub_xattr_set_map( * attr freemap has problems or points to used space. */ STATIC bool -xfs_scrub_xattr_check_freemap( +xchk_xattr_check_freemap( struct xfs_scrub_context *sc, unsigned long *map, struct xfs_attr3_icleaf_hdr *leafhdr) @@ -168,7 +168,7 @@ xfs_scrub_xattr_check_freemap( freemap = (unsigned long *)sc->buf + BITS_TO_LONGS(mapsize); bitmap_zero(freemap, mapsize); for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { - if (!xfs_scrub_xattr_set_map(sc, freemap, + if (!xchk_xattr_set_map(sc, freemap, leafhdr->freemap[i].base, leafhdr->freemap[i].size)) return false; @@ -184,8 +184,8 @@ xfs_scrub_xattr_check_freemap( * Returns the number of bytes used for the name/value data. */ STATIC void -xfs_scrub_xattr_entry( - struct xfs_scrub_da_btree *ds, +xchk_xattr_entry( + struct xchk_da_btree *ds, int level, char *buf_end, struct xfs_attr_leafblock *leaf, @@ -204,17 +204,17 @@ xfs_scrub_xattr_entry( unsigned int namesize; if (ent->pad2 != 0) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); /* Hash values in order? */ if (be32_to_cpu(ent->hashval) < *last_hashval) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); *last_hashval = be32_to_cpu(ent->hashval); nameidx = be16_to_cpu(ent->nameidx); if (nameidx < leafhdr->firstused || nameidx >= mp->m_attr_geo->blksize) { - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); return; } @@ -225,27 +225,27 @@ xfs_scrub_xattr_entry( be16_to_cpu(lentry->valuelen)); name_end = (char *)lentry + namesize; if (lentry->namelen == 0) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); } else { rentry = xfs_attr3_leaf_name_remote(leaf, idx); namesize = xfs_attr_leaf_entsize_remote(rentry->namelen); name_end = (char *)rentry + namesize; if (rentry->namelen == 0 || rentry->valueblk == 0) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); } if (name_end > buf_end) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); - if (!xfs_scrub_xattr_set_map(ds->sc, usedmap, nameidx, namesize)) - xfs_scrub_da_set_corrupt(ds, level); + if (!xchk_xattr_set_map(ds->sc, usedmap, nameidx, namesize)) + xchk_da_set_corrupt(ds, level); if (!(ds->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) *usedbytes += namesize; } /* Scrub an attribute leaf. */ STATIC int -xfs_scrub_xattr_block( - struct xfs_scrub_da_btree *ds, +xchk_xattr_block( + struct xchk_da_btree *ds, int level) { struct xfs_attr3_icleaf_hdr leafhdr; @@ -275,10 +275,10 @@ xfs_scrub_xattr_block( if (leaf->hdr.pad1 != 0 || leaf->hdr.pad2 != 0 || leaf->hdr.info.hdr.pad != 0) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); } else { if (leaf->hdr.pad1 != 0 || leaf->hdr.info.pad != 0) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); } /* Check the leaf header */ @@ -286,44 +286,44 @@ xfs_scrub_xattr_block( hdrsize = xfs_attr3_leaf_hdr_size(leaf); if (leafhdr.usedbytes > mp->m_attr_geo->blksize) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); if (leafhdr.firstused > mp->m_attr_geo->blksize) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); if (leafhdr.firstused < hdrsize) - xfs_scrub_da_set_corrupt(ds, level); - if (!xfs_scrub_xattr_set_map(ds->sc, usedmap, 0, hdrsize)) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); + if (!xchk_xattr_set_map(ds->sc, usedmap, 0, hdrsize)) + xchk_da_set_corrupt(ds, level); if (ds->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) goto out; entries = xfs_attr3_leaf_entryp(leaf); if ((char *)&entries[leafhdr.count] > (char *)leaf + leafhdr.firstused) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); buf_end = (char *)bp->b_addr + mp->m_attr_geo->blksize; for (i = 0, ent = entries; i < leafhdr.count; ent++, i++) { /* Mark the leaf entry itself. */ off = (char *)ent - (char *)leaf; - if (!xfs_scrub_xattr_set_map(ds->sc, usedmap, off, + if (!xchk_xattr_set_map(ds->sc, usedmap, off, sizeof(xfs_attr_leaf_entry_t))) { - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); goto out; } /* Check the entry and nameval. */ - xfs_scrub_xattr_entry(ds, level, buf_end, leaf, &leafhdr, + xchk_xattr_entry(ds, level, buf_end, leaf, &leafhdr, usedmap, ent, i, &usedbytes, &last_hashval); if (ds->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) goto out; } - if (!xfs_scrub_xattr_check_freemap(ds->sc, usedmap, &leafhdr)) - xfs_scrub_da_set_corrupt(ds, level); + if (!xchk_xattr_check_freemap(ds->sc, usedmap, &leafhdr)) + xchk_da_set_corrupt(ds, level); if (leafhdr.usedbytes != usedbytes) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); out: return 0; @@ -331,8 +331,8 @@ out: /* Scrub a attribute btree record. */ STATIC int -xfs_scrub_xattr_rec( - struct xfs_scrub_da_btree *ds, +xchk_xattr_rec( + struct xchk_da_btree *ds, int level, void *rec) { @@ -352,14 +352,14 @@ xfs_scrub_xattr_rec( blk = &ds->state->path.blk[level]; /* Check the whole block, if necessary. */ - error = xfs_scrub_xattr_block(ds, level); + error = xchk_xattr_block(ds, level); if (error) goto out; if (ds->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) goto out; /* Check the hash of the entry. */ - error = xfs_scrub_da_btree_hash(ds, level, &ent->hashval); + error = xchk_da_btree_hash(ds, level, &ent->hashval); if (error) goto out; @@ -368,7 +368,7 @@ xfs_scrub_xattr_rec( hdrsize = xfs_attr3_leaf_hdr_size(bp->b_addr); nameidx = be16_to_cpu(ent->nameidx); if (nameidx < hdrsize || nameidx >= mp->m_attr_geo->blksize) { - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); goto out; } @@ -377,12 +377,12 @@ xfs_scrub_xattr_rec( badflags = ~(XFS_ATTR_LOCAL | XFS_ATTR_ROOT | XFS_ATTR_SECURE | XFS_ATTR_INCOMPLETE); if ((ent->flags & badflags) != 0) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); if (ent->flags & XFS_ATTR_LOCAL) { lentry = (struct xfs_attr_leaf_name_local *) (((char *)bp->b_addr) + nameidx); if (lentry->namelen <= 0) { - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); goto out; } calc_hash = xfs_da_hashname(lentry->nameval, lentry->namelen); @@ -390,13 +390,13 @@ xfs_scrub_xattr_rec( rentry = (struct xfs_attr_leaf_name_remote *) (((char *)bp->b_addr) + nameidx); if (rentry->namelen <= 0) { - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); goto out; } calc_hash = xfs_da_hashname(rentry->name, rentry->namelen); } if (calc_hash != hash) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); out: return error; @@ -404,10 +404,10 @@ out: /* Scrub the extended attribute metadata. */ int -xfs_scrub_xattr( +xchk_xattr( struct xfs_scrub_context *sc) { - struct xfs_scrub_xattr sx; + struct xchk_xattr sx; struct attrlist_cursor_kern cursor = { 0 }; xfs_dablk_t last_checked = -1U; int error = 0; @@ -417,7 +417,7 @@ xfs_scrub_xattr( memset(&sx, 0, sizeof(sx)); /* Check attribute tree structure */ - error = xfs_scrub_da_btree(sc, XFS_ATTR_FORK, xfs_scrub_xattr_rec, + error = xchk_da_btree(sc, XFS_ATTR_FORK, xchk_xattr_rec, &last_checked); if (error) goto out; @@ -429,7 +429,7 @@ xfs_scrub_xattr( sx.context.dp = sc->ip; sx.context.cursor = &cursor; sx.context.resynch = 1; - sx.context.put_listent = xfs_scrub_xattr_listent; + sx.context.put_listent = xchk_xattr_listent; sx.context.tp = sc->tp; sx.context.flags = ATTR_INCOMPLETE; sx.sc = sc; @@ -438,7 +438,7 @@ xfs_scrub_xattr( * Look up every xattr in this file by name. * * Use the backend implementation of xfs_attr_list to call - * xfs_scrub_xattr_listent on every attribute key in this inode. + * xchk_xattr_listent on every attribute key in this inode. * In other words, we use the same iterator/callback mechanism * that listattr uses to scrub extended attributes, though in our * _listent function, we check the value of the attribute. @@ -451,7 +451,7 @@ xfs_scrub_xattr( * locking order. */ error = xfs_attr_list_int_ilocked(&sx.context); - if (!xfs_scrub_fblock_process_error(sc, XFS_ATTR_FORK, 0, &error)) + if (!xchk_fblock_process_error(sc, XFS_ATTR_FORK, 0, &error)) goto out; out: return error; diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c index ebbfab173e97..19cfbd3910a2 100644 --- a/fs/xfs/scrub/bmap.c +++ b/fs/xfs/scrub/bmap.c @@ -33,13 +33,13 @@ /* Set us up with an inode's bmap. */ int -xfs_scrub_setup_inode_bmap( +xchk_setup_inode_bmap( struct xfs_scrub_context *sc, struct xfs_inode *ip) { int error; - error = xfs_scrub_get_inode(sc, ip); + error = xchk_get_inode(sc, ip); if (error) goto out; @@ -60,7 +60,7 @@ xfs_scrub_setup_inode_bmap( } /* Got the inode, lock it and we're ready to go. */ - error = xfs_scrub_trans_alloc(sc, 0); + error = xchk_trans_alloc(sc, 0); if (error) goto out; sc->ilock_flags |= XFS_ILOCK_EXCL; @@ -78,7 +78,7 @@ out: * is in btree format. */ -struct xfs_scrub_bmap_info { +struct xchk_bmap_info { struct xfs_scrub_context *sc; xfs_fileoff_t lastoff; bool is_rt; @@ -88,8 +88,8 @@ struct xfs_scrub_bmap_info { /* Look for a corresponding rmap for this irec. */ static inline bool -xfs_scrub_bmap_get_rmap( - struct xfs_scrub_bmap_info *info, +xchk_bmap_get_rmap( + struct xchk_bmap_info *info, struct xfs_bmbt_irec *irec, xfs_agblock_t agbno, uint64_t owner, @@ -120,7 +120,7 @@ xfs_scrub_bmap_get_rmap( if (info->is_shared) { error = xfs_rmap_lookup_le_range(info->sc->sa.rmap_cur, agbno, owner, offset, rflags, rmap, &has_rmap); - if (!xfs_scrub_should_check_xref(info->sc, &error, + if (!xchk_should_check_xref(info->sc, &error, &info->sc->sa.rmap_cur)) return false; goto out; @@ -131,28 +131,28 @@ xfs_scrub_bmap_get_rmap( */ error = xfs_rmap_lookup_le(info->sc->sa.rmap_cur, agbno, 0, owner, offset, rflags, &has_rmap); - if (!xfs_scrub_should_check_xref(info->sc, &error, + if (!xchk_should_check_xref(info->sc, &error, &info->sc->sa.rmap_cur)) return false; if (!has_rmap) goto out; error = xfs_rmap_get_rec(info->sc->sa.rmap_cur, rmap, &has_rmap); - if (!xfs_scrub_should_check_xref(info->sc, &error, + if (!xchk_should_check_xref(info->sc, &error, &info->sc->sa.rmap_cur)) return false; out: if (!has_rmap) - xfs_scrub_fblock_xref_set_corrupt(info->sc, info->whichfork, + xchk_fblock_xref_set_corrupt(info->sc, info->whichfork, irec->br_startoff); return has_rmap; } /* Make sure that we have rmapbt records for this extent. */ STATIC void -xfs_scrub_bmap_xref_rmap( - struct xfs_scrub_bmap_info *info, +xchk_bmap_xref_rmap( + struct xchk_bmap_info *info, struct xfs_bmbt_irec *irec, xfs_agblock_t agbno) { @@ -160,7 +160,7 @@ xfs_scrub_bmap_xref_rmap( unsigned long long rmap_end; uint64_t owner; - if (!info->sc->sa.rmap_cur || xfs_scrub_skip_xref(info->sc->sm)) + if (!info->sc->sa.rmap_cur || xchk_skip_xref(info->sc->sm)) return; if (info->whichfork == XFS_COW_FORK) @@ -169,14 +169,14 @@ xfs_scrub_bmap_xref_rmap( owner = info->sc->ip->i_ino; /* Find the rmap record for this irec. */ - if (!xfs_scrub_bmap_get_rmap(info, irec, agbno, owner, &rmap)) + if (!xchk_bmap_get_rmap(info, irec, agbno, owner, &rmap)) return; /* Check the rmap. */ rmap_end = (unsigned long long)rmap.rm_startblock + rmap.rm_blockcount; if (rmap.rm_startblock > agbno || agbno + irec->br_blockcount > rmap_end) - xfs_scrub_fblock_xref_set_corrupt(info->sc, info->whichfork, + xchk_fblock_xref_set_corrupt(info->sc, info->whichfork, irec->br_startoff); /* @@ -189,12 +189,12 @@ xfs_scrub_bmap_xref_rmap( rmap.rm_blockcount; if (rmap.rm_offset > irec->br_startoff || irec->br_startoff + irec->br_blockcount > rmap_end) - xfs_scrub_fblock_xref_set_corrupt(info->sc, + xchk_fblock_xref_set_corrupt(info->sc, info->whichfork, irec->br_startoff); } if (rmap.rm_owner != owner) - xfs_scrub_fblock_xref_set_corrupt(info->sc, info->whichfork, + xchk_fblock_xref_set_corrupt(info->sc, info->whichfork, irec->br_startoff); /* @@ -207,22 +207,22 @@ xfs_scrub_bmap_xref_rmap( if (owner != XFS_RMAP_OWN_COW && irec->br_state == XFS_EXT_UNWRITTEN && !(rmap.rm_flags & XFS_RMAP_UNWRITTEN)) - xfs_scrub_fblock_xref_set_corrupt(info->sc, info->whichfork, + xchk_fblock_xref_set_corrupt(info->sc, info->whichfork, irec->br_startoff); if (info->whichfork == XFS_ATTR_FORK && !(rmap.rm_flags & XFS_RMAP_ATTR_FORK)) - xfs_scrub_fblock_xref_set_corrupt(info->sc, info->whichfork, + xchk_fblock_xref_set_corrupt(info->sc, info->whichfork, irec->br_startoff); if (rmap.rm_flags & XFS_RMAP_BMBT_BLOCK) - xfs_scrub_fblock_xref_set_corrupt(info->sc, info->whichfork, + xchk_fblock_xref_set_corrupt(info->sc, info->whichfork, irec->br_startoff); } /* Cross-reference a single rtdev extent record. */ STATIC void -xfs_scrub_bmap_rt_extent_xref( - struct xfs_scrub_bmap_info *info, +xchk_bmap_rt_extent_xref( + struct xchk_bmap_info *info, struct xfs_inode *ip, struct xfs_btree_cur *cur, struct xfs_bmbt_irec *irec) @@ -230,14 +230,14 @@ xfs_scrub_bmap_rt_extent_xref( if (info->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) return; - xfs_scrub_xref_is_used_rt_space(info->sc, irec->br_startblock, + xchk_xref_is_used_rt_space(info->sc, irec->br_startblock, irec->br_blockcount); } /* Cross-reference a single datadev extent record. */ STATIC void -xfs_scrub_bmap_extent_xref( - struct xfs_scrub_bmap_info *info, +xchk_bmap_extent_xref( + struct xchk_bmap_info *info, struct xfs_inode *ip, struct xfs_btree_cur *cur, struct xfs_bmbt_irec *irec) @@ -255,38 +255,38 @@ xfs_scrub_bmap_extent_xref( agbno = XFS_FSB_TO_AGBNO(mp, irec->br_startblock); len = irec->br_blockcount; - error = xfs_scrub_ag_init(info->sc, agno, &info->sc->sa); - if (!xfs_scrub_fblock_process_error(info->sc, info->whichfork, + error = xchk_ag_init(info->sc, agno, &info->sc->sa); + if (!xchk_fblock_process_error(info->sc, info->whichfork, irec->br_startoff, &error)) return; - xfs_scrub_xref_is_used_space(info->sc, agbno, len); - xfs_scrub_xref_is_not_inode_chunk(info->sc, agbno, len); - xfs_scrub_bmap_xref_rmap(info, irec, agbno); + xchk_xref_is_used_space(info->sc, agbno, len); + xchk_xref_is_not_inode_chunk(info->sc, agbno, len); + xchk_bmap_xref_rmap(info, irec, agbno); switch (info->whichfork) { case XFS_DATA_FORK: if (xfs_is_reflink_inode(info->sc->ip)) break; /* fall through */ case XFS_ATTR_FORK: - xfs_scrub_xref_is_not_shared(info->sc, agbno, + xchk_xref_is_not_shared(info->sc, agbno, irec->br_blockcount); break; case XFS_COW_FORK: - xfs_scrub_xref_is_cow_staging(info->sc, agbno, + xchk_xref_is_cow_staging(info->sc, agbno, irec->br_blockcount); break; } - xfs_scrub_ag_free(info->sc, &info->sc->sa); + xchk_ag_free(info->sc, &info->sc->sa); } /* Scrub a single extent record. */ STATIC int -xfs_scrub_bmap_extent( +xchk_bmap_extent( struct xfs_inode *ip, struct xfs_btree_cur *cur, - struct xfs_scrub_bmap_info *info, + struct xchk_bmap_info *info, struct xfs_bmbt_irec *irec) { struct xfs_mount *mp = info->sc->mp; @@ -302,12 +302,12 @@ xfs_scrub_bmap_extent( * from the incore list, for which there is no ordering check. */ if (irec->br_startoff < info->lastoff) - xfs_scrub_fblock_set_corrupt(info->sc, info->whichfork, + xchk_fblock_set_corrupt(info->sc, info->whichfork, irec->br_startoff); /* There should never be a "hole" extent in either extent list. */ if (irec->br_startblock == HOLESTARTBLOCK) - xfs_scrub_fblock_set_corrupt(info->sc, info->whichfork, + xchk_fblock_set_corrupt(info->sc, info->whichfork, irec->br_startoff); /* @@ -315,40 +315,40 @@ xfs_scrub_bmap_extent( * in-core extent scan, and we should never see these in the bmbt. */ if (isnullstartblock(irec->br_startblock)) - xfs_scrub_fblock_set_corrupt(info->sc, info->whichfork, + xchk_fblock_set_corrupt(info->sc, info->whichfork, irec->br_startoff); /* Make sure the extent points to a valid place. */ if (irec->br_blockcount > MAXEXTLEN) - xfs_scrub_fblock_set_corrupt(info->sc, info->whichfork, + xchk_fblock_set_corrupt(info->sc, info->whichfork, irec->br_startoff); if (irec->br_startblock + irec->br_blockcount <= irec->br_startblock) - xfs_scrub_fblock_set_corrupt(info->sc, info->whichfork, + xchk_fblock_set_corrupt(info->sc, info->whichfork, irec->br_startoff); end = irec->br_startblock + irec->br_blockcount - 1; if (info->is_rt && (!xfs_verify_rtbno(mp, irec->br_startblock) || !xfs_verify_rtbno(mp, end))) - xfs_scrub_fblock_set_corrupt(info->sc, info->whichfork, + xchk_fblock_set_corrupt(info->sc, info->whichfork, irec->br_startoff); if (!info->is_rt && (!xfs_verify_fsbno(mp, irec->br_startblock) || !xfs_verify_fsbno(mp, end) || XFS_FSB_TO_AGNO(mp, irec->br_startblock) != XFS_FSB_TO_AGNO(mp, end))) - xfs_scrub_fblock_set_corrupt(info->sc, info->whichfork, + xchk_fblock_set_corrupt(info->sc, info->whichfork, irec->br_startoff); /* We don't allow unwritten extents on attr forks. */ if (irec->br_state == XFS_EXT_UNWRITTEN && info->whichfork == XFS_ATTR_FORK) - xfs_scrub_fblock_set_corrupt(info->sc, info->whichfork, + xchk_fblock_set_corrupt(info->sc, info->whichfork, irec->br_startoff); if (info->is_rt) - xfs_scrub_bmap_rt_extent_xref(info, ip, cur, irec); + xchk_bmap_rt_extent_xref(info, ip, cur, irec); else - xfs_scrub_bmap_extent_xref(info, ip, cur, irec); + xchk_bmap_extent_xref(info, ip, cur, irec); info->lastoff = irec->br_startoff + irec->br_blockcount; return error; @@ -356,12 +356,12 @@ xfs_scrub_bmap_extent( /* Scrub a bmbt record. */ STATIC int -xfs_scrub_bmapbt_rec( - struct xfs_scrub_btree *bs, +xchk_bmapbt_rec( + struct xchk_btree *bs, union xfs_btree_rec *rec) { struct xfs_bmbt_irec irec; - struct xfs_scrub_bmap_info *info = bs->private; + struct xchk_bmap_info *info = bs->private; struct xfs_inode *ip = bs->cur->bc_private.b.ip; struct xfs_buf *bp = NULL; struct xfs_btree_block *block; @@ -378,22 +378,22 @@ xfs_scrub_bmapbt_rec( block = xfs_btree_get_block(bs->cur, i, &bp); owner = be64_to_cpu(block->bb_u.l.bb_owner); if (owner != ip->i_ino) - xfs_scrub_fblock_set_corrupt(bs->sc, + xchk_fblock_set_corrupt(bs->sc, info->whichfork, 0); } } /* Set up the in-core record and scrub it. */ xfs_bmbt_disk_get_all(&rec->bmbt, &irec); - return xfs_scrub_bmap_extent(ip, bs->cur, info, &irec); + return xchk_bmap_extent(ip, bs->cur, info, &irec); } /* Scan the btree records. */ STATIC int -xfs_scrub_bmap_btree( +xchk_bmap_btree( struct xfs_scrub_context *sc, int whichfork, - struct xfs_scrub_bmap_info *info) + struct xchk_bmap_info *info) { struct xfs_owner_info oinfo; struct xfs_mount *mp = sc->mp; @@ -403,12 +403,12 @@ xfs_scrub_bmap_btree( cur = xfs_bmbt_init_cursor(mp, sc->tp, ip, whichfork); xfs_rmap_ino_bmbt_owner(&oinfo, ip->i_ino, whichfork); - error = xfs_scrub_btree(sc, cur, xfs_scrub_bmapbt_rec, &oinfo, info); + error = xchk_btree(sc, cur, xchk_bmapbt_rec, &oinfo, info); xfs_btree_del_cursor(cur, error); return error; } -struct xfs_scrub_bmap_check_rmap_info { +struct xchk_bmap_check_rmap_info { struct xfs_scrub_context *sc; int whichfork; struct xfs_iext_cursor icur; @@ -416,13 +416,13 @@ struct xfs_scrub_bmap_check_rmap_info { /* Can we find bmaps that fit this rmap? */ STATIC int -xfs_scrub_bmap_check_rmap( +xchk_bmap_check_rmap( struct xfs_btree_cur *cur, struct xfs_rmap_irec *rec, void *priv) { struct xfs_bmbt_irec irec; - struct xfs_scrub_bmap_check_rmap_info *sbcri = priv; + struct xchk_bmap_check_rmap_info *sbcri = priv; struct xfs_ifork *ifp; struct xfs_scrub_context *sc = sbcri->sc; bool have_map; @@ -439,14 +439,14 @@ xfs_scrub_bmap_check_rmap( /* Now look up the bmbt record. */ ifp = XFS_IFORK_PTR(sc->ip, sbcri->whichfork); if (!ifp) { - xfs_scrub_fblock_set_corrupt(sc, sbcri->whichfork, + xchk_fblock_set_corrupt(sc, sbcri->whichfork, rec->rm_offset); goto out; } have_map = xfs_iext_lookup_extent(sc->ip, ifp, rec->rm_offset, &sbcri->icur, &irec); if (!have_map) - xfs_scrub_fblock_set_corrupt(sc, sbcri->whichfork, + xchk_fblock_set_corrupt(sc, sbcri->whichfork, rec->rm_offset); /* * bmap extent record lengths are constrained to 2^21 blocks in length @@ -457,14 +457,14 @@ xfs_scrub_bmap_check_rmap( */ while (have_map) { if (irec.br_startoff != rec->rm_offset) - xfs_scrub_fblock_set_corrupt(sc, sbcri->whichfork, + xchk_fblock_set_corrupt(sc, sbcri->whichfork, rec->rm_offset); if (irec.br_startblock != XFS_AGB_TO_FSB(sc->mp, cur->bc_private.a.agno, rec->rm_startblock)) - xfs_scrub_fblock_set_corrupt(sc, sbcri->whichfork, + xchk_fblock_set_corrupt(sc, sbcri->whichfork, rec->rm_offset); if (irec.br_blockcount > rec->rm_blockcount) - xfs_scrub_fblock_set_corrupt(sc, sbcri->whichfork, + xchk_fblock_set_corrupt(sc, sbcri->whichfork, rec->rm_offset); if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) break; @@ -475,7 +475,7 @@ xfs_scrub_bmap_check_rmap( break; have_map = xfs_iext_next_extent(ifp, &sbcri->icur, &irec); if (!have_map) - xfs_scrub_fblock_set_corrupt(sc, sbcri->whichfork, + xchk_fblock_set_corrupt(sc, sbcri->whichfork, rec->rm_offset); } @@ -487,12 +487,12 @@ out: /* Make sure each rmap has a corresponding bmbt entry. */ STATIC int -xfs_scrub_bmap_check_ag_rmaps( +xchk_bmap_check_ag_rmaps( struct xfs_scrub_context *sc, int whichfork, xfs_agnumber_t agno) { - struct xfs_scrub_bmap_check_rmap_info sbcri; + struct xchk_bmap_check_rmap_info sbcri; struct xfs_btree_cur *cur; struct xfs_buf *agf; int error; @@ -509,7 +509,7 @@ xfs_scrub_bmap_check_ag_rmaps( sbcri.sc = sc; sbcri.whichfork = whichfork; - error = xfs_rmap_query_all(cur, xfs_scrub_bmap_check_rmap, &sbcri); + error = xfs_rmap_query_all(cur, xchk_bmap_check_rmap, &sbcri); if (error == XFS_BTREE_QUERY_RANGE_ABORT) error = 0; @@ -521,7 +521,7 @@ out_agf: /* Make sure each rmap has a corresponding bmbt entry. */ STATIC int -xfs_scrub_bmap_check_rmaps( +xchk_bmap_check_rmaps( struct xfs_scrub_context *sc, int whichfork) { @@ -561,7 +561,7 @@ xfs_scrub_bmap_check_rmaps( return 0; for (agno = 0; agno < sc->mp->m_sb.sb_agcount; agno++) { - error = xfs_scrub_bmap_check_ag_rmaps(sc, whichfork, agno); + error = xchk_bmap_check_ag_rmaps(sc, whichfork, agno); if (error) return error; if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) @@ -578,12 +578,12 @@ xfs_scrub_bmap_check_rmaps( * Then we unconditionally scan the incore extent cache. */ STATIC int -xfs_scrub_bmap( +xchk_bmap( struct xfs_scrub_context *sc, int whichfork) { struct xfs_bmbt_irec irec; - struct xfs_scrub_bmap_info info = { NULL }; + struct xchk_bmap_info info = { NULL }; struct xfs_mount *mp = sc->mp; struct xfs_inode *ip = sc->ip; struct xfs_ifork *ifp; @@ -605,7 +605,7 @@ xfs_scrub_bmap( goto out; /* No CoW forks on non-reflink inodes/filesystems. */ if (!xfs_is_reflink_inode(ip)) { - xfs_scrub_ino_set_corrupt(sc, sc->ip->i_ino); + xchk_ino_set_corrupt(sc, sc->ip->i_ino); goto out; } break; @@ -614,7 +614,7 @@ xfs_scrub_bmap( goto out_check_rmap; if (!xfs_sb_version_hasattr(&mp->m_sb) && !xfs_sb_version_hasattr2(&mp->m_sb)) - xfs_scrub_ino_set_corrupt(sc, sc->ip->i_ino); + xchk_ino_set_corrupt(sc, sc->ip->i_ino); break; default: ASSERT(whichfork == XFS_DATA_FORK); @@ -630,22 +630,22 @@ xfs_scrub_bmap( goto out; case XFS_DINODE_FMT_EXTENTS: if (!(ifp->if_flags & XFS_IFEXTENTS)) { - xfs_scrub_fblock_set_corrupt(sc, whichfork, 0); + xchk_fblock_set_corrupt(sc, whichfork, 0); goto out; } break; case XFS_DINODE_FMT_BTREE: if (whichfork == XFS_COW_FORK) { - xfs_scrub_fblock_set_corrupt(sc, whichfork, 0); + xchk_fblock_set_corrupt(sc, whichfork, 0); goto out; } - error = xfs_scrub_bmap_btree(sc, whichfork, &info); + error = xchk_bmap_btree(sc, whichfork, &info); if (error) goto out; break; default: - xfs_scrub_fblock_set_corrupt(sc, whichfork, 0); + xchk_fblock_set_corrupt(sc, whichfork, 0); goto out; } @@ -655,37 +655,37 @@ xfs_scrub_bmap( /* Now try to scrub the in-memory extent list. */ if (!(ifp->if_flags & XFS_IFEXTENTS)) { error = xfs_iread_extents(sc->tp, ip, whichfork); - if (!xfs_scrub_fblock_process_error(sc, whichfork, 0, &error)) + if (!xchk_fblock_process_error(sc, whichfork, 0, &error)) goto out; } /* Find the offset of the last extent in the mapping. */ error = xfs_bmap_last_offset(ip, &endoff, whichfork); - if (!xfs_scrub_fblock_process_error(sc, whichfork, 0, &error)) + if (!xchk_fblock_process_error(sc, whichfork, 0, &error)) goto out; /* Scrub extent records. */ info.lastoff = 0; ifp = XFS_IFORK_PTR(ip, whichfork); for_each_xfs_iext(ifp, &icur, &irec) { - if (xfs_scrub_should_terminate(sc, &error) || + if (xchk_should_terminate(sc, &error) || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) break; if (isnullstartblock(irec.br_startblock)) continue; if (irec.br_startoff >= endoff) { - xfs_scrub_fblock_set_corrupt(sc, whichfork, + xchk_fblock_set_corrupt(sc, whichfork, irec.br_startoff); goto out; } - error = xfs_scrub_bmap_extent(ip, NULL, &info, &irec); + error = xchk_bmap_extent(ip, NULL, &info, &irec); if (error) goto out; } out_check_rmap: - error = xfs_scrub_bmap_check_rmaps(sc, whichfork); - if (!xfs_scrub_fblock_xref_process_error(sc, whichfork, 0, &error)) + error = xchk_bmap_check_rmaps(sc, whichfork); + if (!xchk_fblock_xref_process_error(sc, whichfork, 0, &error)) goto out; out: return error; @@ -693,27 +693,27 @@ out: /* Scrub an inode's data fork. */ int -xfs_scrub_bmap_data( +xchk_bmap_data( struct xfs_scrub_context *sc) { - return xfs_scrub_bmap(sc, XFS_DATA_FORK); + return xchk_bmap(sc, XFS_DATA_FORK); } /* Scrub an inode's attr fork. */ int -xfs_scrub_bmap_attr( +xchk_bmap_attr( struct xfs_scrub_context *sc) { - return xfs_scrub_bmap(sc, XFS_ATTR_FORK); + return xchk_bmap(sc, XFS_ATTR_FORK); } /* Scrub an inode's CoW fork. */ int -xfs_scrub_bmap_cow( +xchk_bmap_cow( struct xfs_scrub_context *sc) { if (!xfs_is_reflink_inode(sc->ip)) return -ENOENT; - return xfs_scrub_bmap(sc, XFS_COW_FORK); + return xchk_bmap(sc, XFS_COW_FORK); } diff --git a/fs/xfs/scrub/btree.c b/fs/xfs/scrub/btree.c index 5b472045f036..30fe9a147959 100644 --- a/fs/xfs/scrub/btree.c +++ b/fs/xfs/scrub/btree.c @@ -29,7 +29,7 @@ * operational errors in common.c. */ static bool -__xfs_scrub_btree_process_error( +__xchk_btree_process_error( struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, int level, @@ -43,7 +43,7 @@ __xfs_scrub_btree_process_error( switch (*error) { case -EDEADLOCK: /* Used to restart an op with deadlock avoidance. */ - trace_xfs_scrub_deadlock_retry(sc->ip, sc->sm, *error); + trace_xchk_deadlock_retry(sc->ip, sc->sm, *error); break; case -EFSBADCRC: case -EFSCORRUPTED: @@ -53,10 +53,10 @@ __xfs_scrub_btree_process_error( /* fall through */ default: if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) - trace_xfs_scrub_ifork_btree_op_error(sc, cur, level, + trace_xchk_ifork_btree_op_error(sc, cur, level, *error, ret_ip); else - trace_xfs_scrub_btree_op_error(sc, cur, level, + trace_xchk_btree_op_error(sc, cur, level, *error, ret_ip); break; } @@ -64,30 +64,30 @@ __xfs_scrub_btree_process_error( } bool -xfs_scrub_btree_process_error( +xchk_btree_process_error( struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, int level, int *error) { - return __xfs_scrub_btree_process_error(sc, cur, level, error, + return __xchk_btree_process_error(sc, cur, level, error, XFS_SCRUB_OFLAG_CORRUPT, __return_address); } bool -xfs_scrub_btree_xref_process_error( +xchk_btree_xref_process_error( struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, int level, int *error) { - return __xfs_scrub_btree_process_error(sc, cur, level, error, + return __xchk_btree_process_error(sc, cur, level, error, XFS_SCRUB_OFLAG_XFAIL, __return_address); } /* Record btree block corruption. */ static void -__xfs_scrub_btree_set_corrupt( +__xchk_btree_set_corrupt( struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, int level, @@ -97,30 +97,30 @@ __xfs_scrub_btree_set_corrupt( sc->sm->sm_flags |= errflag; if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) - trace_xfs_scrub_ifork_btree_error(sc, cur, level, + trace_xchk_ifork_btree_error(sc, cur, level, ret_ip); else - trace_xfs_scrub_btree_error(sc, cur, level, + trace_xchk_btree_error(sc, cur, level, ret_ip); } void -xfs_scrub_btree_set_corrupt( +xchk_btree_set_corrupt( struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, int level) { - __xfs_scrub_btree_set_corrupt(sc, cur, level, XFS_SCRUB_OFLAG_CORRUPT, + __xchk_btree_set_corrupt(sc, cur, level, XFS_SCRUB_OFLAG_CORRUPT, __return_address); } void -xfs_scrub_btree_xref_set_corrupt( +xchk_btree_xref_set_corrupt( struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, int level) { - __xfs_scrub_btree_set_corrupt(sc, cur, level, XFS_SCRUB_OFLAG_XCORRUPT, + __xchk_btree_set_corrupt(sc, cur, level, XFS_SCRUB_OFLAG_XCORRUPT, __return_address); } @@ -129,8 +129,8 @@ xfs_scrub_btree_xref_set_corrupt( * keys. */ STATIC void -xfs_scrub_btree_rec( - struct xfs_scrub_btree *bs) +xchk_btree_rec( + struct xchk_btree *bs) { struct xfs_btree_cur *cur = bs->cur; union xfs_btree_rec *rec; @@ -144,11 +144,11 @@ xfs_scrub_btree_rec( block = xfs_btree_get_block(cur, 0, &bp); rec = xfs_btree_rec_addr(cur, cur->bc_ptrs[0], block); - trace_xfs_scrub_btree_rec(bs->sc, cur, 0); + trace_xchk_btree_rec(bs->sc, cur, 0); /* If this isn't the first record, are they in order? */ if (!bs->firstrec && !cur->bc_ops->recs_inorder(cur, &bs->lastrec, rec)) - xfs_scrub_btree_set_corrupt(bs->sc, cur, 0); + xchk_btree_set_corrupt(bs->sc, cur, 0); bs->firstrec = false; memcpy(&bs->lastrec, rec, cur->bc_ops->rec_len); @@ -160,7 +160,7 @@ xfs_scrub_btree_rec( keyblock = xfs_btree_get_block(cur, 1, &bp); keyp = xfs_btree_key_addr(cur, cur->bc_ptrs[1], keyblock); if (cur->bc_ops->diff_two_keys(cur, &key, keyp) < 0) - xfs_scrub_btree_set_corrupt(bs->sc, cur, 1); + xchk_btree_set_corrupt(bs->sc, cur, 1); if (!(cur->bc_flags & XFS_BTREE_OVERLAPPING)) return; @@ -169,7 +169,7 @@ xfs_scrub_btree_rec( cur->bc_ops->init_high_key_from_rec(&hkey, rec); keyp = xfs_btree_high_key_addr(cur, cur->bc_ptrs[1], keyblock); if (cur->bc_ops->diff_two_keys(cur, keyp, &hkey) < 0) - xfs_scrub_btree_set_corrupt(bs->sc, cur, 1); + xchk_btree_set_corrupt(bs->sc, cur, 1); } /* @@ -177,8 +177,8 @@ xfs_scrub_btree_rec( * keys. */ STATIC void -xfs_scrub_btree_key( - struct xfs_scrub_btree *bs, +xchk_btree_key( + struct xchk_btree *bs, int level) { struct xfs_btree_cur *cur = bs->cur; @@ -191,12 +191,12 @@ xfs_scrub_btree_key( block = xfs_btree_get_block(cur, level, &bp); key = xfs_btree_key_addr(cur, cur->bc_ptrs[level], block); - trace_xfs_scrub_btree_key(bs->sc, cur, level); + trace_xchk_btree_key(bs->sc, cur, level); /* If this isn't the first key, are they in order? */ if (!bs->firstkey[level] && !cur->bc_ops->keys_inorder(cur, &bs->lastkey[level], key)) - xfs_scrub_btree_set_corrupt(bs->sc, cur, level); + xchk_btree_set_corrupt(bs->sc, cur, level); bs->firstkey[level] = false; memcpy(&bs->lastkey[level], key, cur->bc_ops->key_len); @@ -207,7 +207,7 @@ xfs_scrub_btree_key( keyblock = xfs_btree_get_block(cur, level + 1, &bp); keyp = xfs_btree_key_addr(cur, cur->bc_ptrs[level + 1], keyblock); if (cur->bc_ops->diff_two_keys(cur, key, keyp) < 0) - xfs_scrub_btree_set_corrupt(bs->sc, cur, level); + xchk_btree_set_corrupt(bs->sc, cur, level); if (!(cur->bc_flags & XFS_BTREE_OVERLAPPING)) return; @@ -216,7 +216,7 @@ xfs_scrub_btree_key( key = xfs_btree_high_key_addr(cur, cur->bc_ptrs[level], block); keyp = xfs_btree_high_key_addr(cur, cur->bc_ptrs[level + 1], keyblock); if (cur->bc_ops->diff_two_keys(cur, keyp, key) < 0) - xfs_scrub_btree_set_corrupt(bs->sc, cur, level); + xchk_btree_set_corrupt(bs->sc, cur, level); } /* @@ -224,8 +224,8 @@ xfs_scrub_btree_key( * Callers do not need to set the corrupt flag. */ static bool -xfs_scrub_btree_ptr_ok( - struct xfs_scrub_btree *bs, +xchk_btree_ptr_ok( + struct xchk_btree *bs, int level, union xfs_btree_ptr *ptr) { @@ -242,15 +242,15 @@ xfs_scrub_btree_ptr_ok( else res = xfs_btree_check_sptr(bs->cur, be32_to_cpu(ptr->s), level); if (!res) - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, level); + xchk_btree_set_corrupt(bs->sc, bs->cur, level); return res; } /* Check that a btree block's sibling matches what we expect it. */ STATIC int -xfs_scrub_btree_block_check_sibling( - struct xfs_scrub_btree *bs, +xchk_btree_block_check_sibling( + struct xchk_btree *bs, int level, int direction, union xfs_btree_ptr *sibling) @@ -264,7 +264,7 @@ xfs_scrub_btree_block_check_sibling( int error; error = xfs_btree_dup_cursor(cur, &ncur); - if (!xfs_scrub_btree_process_error(bs->sc, cur, level + 1, &error) || + if (!xchk_btree_process_error(bs->sc, cur, level + 1, &error) || !ncur) return error; @@ -278,7 +278,7 @@ xfs_scrub_btree_block_check_sibling( else error = xfs_btree_decrement(ncur, level + 1, &success); if (error == 0 && success) - xfs_scrub_btree_set_corrupt(bs->sc, cur, level); + xchk_btree_set_corrupt(bs->sc, cur, level); error = 0; goto out; } @@ -288,23 +288,23 @@ xfs_scrub_btree_block_check_sibling( error = xfs_btree_increment(ncur, level + 1, &success); else error = xfs_btree_decrement(ncur, level + 1, &success); - if (!xfs_scrub_btree_process_error(bs->sc, cur, level + 1, &error)) + if (!xchk_btree_process_error(bs->sc, cur, level + 1, &error)) goto out; if (!success) { - xfs_scrub_btree_set_corrupt(bs->sc, cur, level + 1); + xchk_btree_set_corrupt(bs->sc, cur, level + 1); goto out; } /* Compare upper level pointer to sibling pointer. */ pblock = xfs_btree_get_block(ncur, level + 1, &pbp); pp = xfs_btree_ptr_addr(ncur, ncur->bc_ptrs[level + 1], pblock); - if (!xfs_scrub_btree_ptr_ok(bs, level + 1, pp)) + if (!xchk_btree_ptr_ok(bs, level + 1, pp)) goto out; if (pbp) - xfs_scrub_buffer_recheck(bs->sc, pbp); + xchk_buffer_recheck(bs->sc, pbp); if (xfs_btree_diff_two_ptrs(cur, pp, sibling)) - xfs_scrub_btree_set_corrupt(bs->sc, cur, level); + xchk_btree_set_corrupt(bs->sc, cur, level); out: xfs_btree_del_cursor(ncur, XFS_BTREE_ERROR); return error; @@ -312,8 +312,8 @@ out: /* Check the siblings of a btree block. */ STATIC int -xfs_scrub_btree_block_check_siblings( - struct xfs_scrub_btree *bs, +xchk_btree_block_check_siblings( + struct xchk_btree *bs, struct xfs_btree_block *block) { struct xfs_btree_cur *cur = bs->cur; @@ -330,7 +330,7 @@ xfs_scrub_btree_block_check_siblings( if (level == cur->bc_nlevels - 1) { if (!xfs_btree_ptr_is_null(cur, &leftsib) || !xfs_btree_ptr_is_null(cur, &rightsib)) - xfs_scrub_btree_set_corrupt(bs->sc, cur, level); + xchk_btree_set_corrupt(bs->sc, cur, level); goto out; } @@ -339,10 +339,10 @@ xfs_scrub_btree_block_check_siblings( * parent level pointers? * (These function absorbs error codes for us.) */ - error = xfs_scrub_btree_block_check_sibling(bs, level, -1, &leftsib); + error = xchk_btree_block_check_sibling(bs, level, -1, &leftsib); if (error) return error; - error = xfs_scrub_btree_block_check_sibling(bs, level, 1, &rightsib); + error = xchk_btree_block_check_sibling(bs, level, 1, &rightsib); if (error) return error; out: @@ -360,8 +360,8 @@ struct check_owner { * an rmap record for it. */ STATIC int -xfs_scrub_btree_check_block_owner( - struct xfs_scrub_btree *bs, +xchk_btree_check_block_owner( + struct xchk_btree *bs, int level, xfs_daddr_t daddr) { @@ -380,13 +380,13 @@ xfs_scrub_btree_check_block_owner( init_sa = bs->cur->bc_flags & XFS_BTREE_LONG_PTRS; if (init_sa) { - error = xfs_scrub_ag_init(bs->sc, agno, &bs->sc->sa); - if (!xfs_scrub_btree_xref_process_error(bs->sc, bs->cur, + error = xchk_ag_init(bs->sc, agno, &bs->sc->sa); + if (!xchk_btree_xref_process_error(bs->sc, bs->cur, level, &error)) return error; } - xfs_scrub_xref_is_used_space(bs->sc, agbno, 1); + xchk_xref_is_used_space(bs->sc, agbno, 1); /* * The bnobt scrubber aliases bs->cur to bs->sc->sa.bno_cur, so we * have to nullify it (to shut down further block owner checks) if @@ -395,20 +395,20 @@ xfs_scrub_btree_check_block_owner( if (!bs->sc->sa.bno_cur && btnum == XFS_BTNUM_BNO) bs->cur = NULL; - xfs_scrub_xref_is_owned_by(bs->sc, agbno, 1, bs->oinfo); + xchk_xref_is_owned_by(bs->sc, agbno, 1, bs->oinfo); if (!bs->sc->sa.rmap_cur && btnum == XFS_BTNUM_RMAP) bs->cur = NULL; if (init_sa) - xfs_scrub_ag_free(bs->sc, &bs->sc->sa); + xchk_ag_free(bs->sc, &bs->sc->sa); return error; } /* Check the owner of a btree block. */ STATIC int -xfs_scrub_btree_check_owner( - struct xfs_scrub_btree *bs, +xchk_btree_check_owner( + struct xchk_btree *bs, int level, struct xfs_buf *bp) { @@ -437,7 +437,7 @@ xfs_scrub_btree_check_owner( return 0; } - return xfs_scrub_btree_check_block_owner(bs, level, XFS_BUF_ADDR(bp)); + return xchk_btree_check_block_owner(bs, level, XFS_BUF_ADDR(bp)); } /* @@ -445,8 +445,8 @@ xfs_scrub_btree_check_owner( * special blocks that don't require that. */ STATIC void -xfs_scrub_btree_check_minrecs( - struct xfs_scrub_btree *bs, +xchk_btree_check_minrecs( + struct xchk_btree *bs, int level, struct xfs_btree_block *block) { @@ -475,7 +475,7 @@ xfs_scrub_btree_check_minrecs( if (level >= ok_level) return; - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, level); + xchk_btree_set_corrupt(bs->sc, bs->cur, level); } /* @@ -483,8 +483,8 @@ xfs_scrub_btree_check_minrecs( * and buffer pointers (if applicable) if they're ok to use. */ STATIC int -xfs_scrub_btree_get_block( - struct xfs_scrub_btree *bs, +xchk_btree_get_block( + struct xchk_btree *bs, int level, union xfs_btree_ptr *pp, struct xfs_btree_block **pblock, @@ -497,7 +497,7 @@ xfs_scrub_btree_get_block( *pbp = NULL; error = xfs_btree_lookup_get_block(bs->cur, level, pp, pblock); - if (!xfs_scrub_btree_process_error(bs->sc, bs->cur, level, &error) || + if (!xchk_btree_process_error(bs->sc, bs->cur, level, &error) || !*pblock) return error; @@ -509,19 +509,19 @@ xfs_scrub_btree_get_block( failed_at = __xfs_btree_check_sblock(bs->cur, *pblock, level, *pbp); if (failed_at) { - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, level); + xchk_btree_set_corrupt(bs->sc, bs->cur, level); return 0; } if (*pbp) - xfs_scrub_buffer_recheck(bs->sc, *pbp); + xchk_buffer_recheck(bs->sc, *pbp); - xfs_scrub_btree_check_minrecs(bs, level, *pblock); + xchk_btree_check_minrecs(bs, level, *pblock); /* * Check the block's owner; this function absorbs error codes * for us. */ - error = xfs_scrub_btree_check_owner(bs, level, *pbp); + error = xchk_btree_check_owner(bs, level, *pbp); if (error) return error; @@ -529,7 +529,7 @@ xfs_scrub_btree_get_block( * Check the block's siblings; this function absorbs error codes * for us. */ - return xfs_scrub_btree_block_check_siblings(bs, *pblock); + return xchk_btree_block_check_siblings(bs, *pblock); } /* @@ -537,8 +537,8 @@ xfs_scrub_btree_get_block( * in the parent block. */ STATIC void -xfs_scrub_btree_block_keys( - struct xfs_scrub_btree *bs, +xchk_btree_block_keys( + struct xchk_btree *bs, int level, struct xfs_btree_block *block) { @@ -562,7 +562,7 @@ xfs_scrub_btree_block_keys( parent_block); if (cur->bc_ops->diff_two_keys(cur, &block_keys, parent_keys) != 0) - xfs_scrub_btree_set_corrupt(bs->sc, cur, 1); + xchk_btree_set_corrupt(bs->sc, cur, 1); if (!(cur->bc_flags & XFS_BTREE_OVERLAPPING)) return; @@ -573,7 +573,7 @@ xfs_scrub_btree_block_keys( parent_block); if (cur->bc_ops->diff_two_keys(cur, high_bk, high_pk) != 0) - xfs_scrub_btree_set_corrupt(bs->sc, cur, 1); + xchk_btree_set_corrupt(bs->sc, cur, 1); } /* @@ -582,14 +582,14 @@ xfs_scrub_btree_block_keys( * so that the caller can verify individual records. */ int -xfs_scrub_btree( +xchk_btree( struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, - xfs_scrub_btree_rec_fn scrub_fn, + xchk_btree_rec_fn scrub_fn, struct xfs_owner_info *oinfo, void *private) { - struct xfs_scrub_btree bs = { NULL }; + struct xchk_btree bs = { NULL }; union xfs_btree_ptr ptr; union xfs_btree_ptr *pp; union xfs_btree_rec *recp; @@ -614,7 +614,7 @@ xfs_scrub_btree( /* Don't try to check a tree with a height we can't handle. */ if (cur->bc_nlevels > XFS_BTREE_MAXLEVELS) { - xfs_scrub_btree_set_corrupt(sc, cur, 0); + xchk_btree_set_corrupt(sc, cur, 0); goto out; } @@ -624,9 +624,9 @@ xfs_scrub_btree( */ level = cur->bc_nlevels - 1; cur->bc_ops->init_ptr_from_cur(cur, &ptr); - if (!xfs_scrub_btree_ptr_ok(&bs, cur->bc_nlevels, &ptr)) + if (!xchk_btree_ptr_ok(&bs, cur->bc_nlevels, &ptr)) goto out; - error = xfs_scrub_btree_get_block(&bs, level, &ptr, &block, &bp); + error = xchk_btree_get_block(&bs, level, &ptr, &block, &bp); if (error || !block) goto out; @@ -639,7 +639,7 @@ xfs_scrub_btree( /* End of leaf, pop back towards the root. */ if (cur->bc_ptrs[level] > be16_to_cpu(block->bb_numrecs)) { - xfs_scrub_btree_block_keys(&bs, level, block); + xchk_btree_block_keys(&bs, level, block); if (level < cur->bc_nlevels - 1) cur->bc_ptrs[level + 1]++; level++; @@ -647,14 +647,14 @@ xfs_scrub_btree( } /* Records in order for scrub? */ - xfs_scrub_btree_rec(&bs); + xchk_btree_rec(&bs); /* Call out to the record checker. */ recp = xfs_btree_rec_addr(cur, cur->bc_ptrs[0], block); error = bs.scrub_rec(&bs, recp); if (error) break; - if (xfs_scrub_should_terminate(sc, &error) || + if (xchk_should_terminate(sc, &error) || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) break; @@ -664,7 +664,7 @@ xfs_scrub_btree( /* End of node, pop back towards the root. */ if (cur->bc_ptrs[level] > be16_to_cpu(block->bb_numrecs)) { - xfs_scrub_btree_block_keys(&bs, level, block); + xchk_btree_block_keys(&bs, level, block); if (level < cur->bc_nlevels - 1) cur->bc_ptrs[level + 1]++; level++; @@ -672,16 +672,16 @@ xfs_scrub_btree( } /* Keys in order for scrub? */ - xfs_scrub_btree_key(&bs, level); + xchk_btree_key(&bs, level); /* Drill another level deeper. */ pp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[level], block); - if (!xfs_scrub_btree_ptr_ok(&bs, level, pp)) { + if (!xchk_btree_ptr_ok(&bs, level, pp)) { cur->bc_ptrs[level]++; continue; } level--; - error = xfs_scrub_btree_get_block(&bs, level, pp, &block, &bp); + error = xchk_btree_get_block(&bs, level, pp, &block, &bp); if (error || !block) goto out; @@ -692,7 +692,7 @@ out: /* Process deferred owner checks on btree blocks. */ list_for_each_entry_safe(co, n, &bs.to_check, list) { if (!error && bs.cur) - error = xfs_scrub_btree_check_block_owner(&bs, + error = xchk_btree_check_block_owner(&bs, co->level, co->daddr); list_del(&co->list); kmem_free(co); diff --git a/fs/xfs/scrub/btree.h b/fs/xfs/scrub/btree.h index 956627500f2c..598ac04a6c3e 100644 --- a/fs/xfs/scrub/btree.h +++ b/fs/xfs/scrub/btree.h @@ -9,32 +9,32 @@ /* btree scrub */ /* Check for btree operation errors. */ -bool xfs_scrub_btree_process_error(struct xfs_scrub_context *sc, +bool xchk_btree_process_error(struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, int level, int *error); /* Check for btree xref operation errors. */ -bool xfs_scrub_btree_xref_process_error(struct xfs_scrub_context *sc, +bool xchk_btree_xref_process_error(struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, int level, int *error); /* Check for btree corruption. */ -void xfs_scrub_btree_set_corrupt(struct xfs_scrub_context *sc, +void xchk_btree_set_corrupt(struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, int level); /* Check for btree xref discrepancies. */ -void xfs_scrub_btree_xref_set_corrupt(struct xfs_scrub_context *sc, +void xchk_btree_xref_set_corrupt(struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, int level); -struct xfs_scrub_btree; -typedef int (*xfs_scrub_btree_rec_fn)( - struct xfs_scrub_btree *bs, +struct xchk_btree; +typedef int (*xchk_btree_rec_fn)( + struct xchk_btree *bs, union xfs_btree_rec *rec); -struct xfs_scrub_btree { +struct xchk_btree { /* caller-provided scrub state */ struct xfs_scrub_context *sc; struct xfs_btree_cur *cur; - xfs_scrub_btree_rec_fn scrub_rec; + xchk_btree_rec_fn scrub_rec; struct xfs_owner_info *oinfo; void *private; @@ -45,8 +45,8 @@ struct xfs_scrub_btree { bool firstkey[XFS_BTREE_MAXLEVELS]; struct list_head to_check; }; -int xfs_scrub_btree(struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, - xfs_scrub_btree_rec_fn scrub_fn, +int xchk_btree(struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, + xchk_btree_rec_fn scrub_fn, struct xfs_owner_info *oinfo, void *private); #endif /* __XFS_SCRUB_BTREE_H__ */ diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index 385fa5b9c878..5c3d4e7c6166 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -68,7 +68,7 @@ /* Check for operational errors. */ static bool -__xfs_scrub_process_error( +__xchk_process_error( struct xfs_scrub_context *sc, xfs_agnumber_t agno, xfs_agblock_t bno, @@ -81,7 +81,7 @@ __xfs_scrub_process_error( return true; case -EDEADLOCK: /* Used to restart an op with deadlock avoidance. */ - trace_xfs_scrub_deadlock_retry(sc->ip, sc->sm, *error); + trace_xchk_deadlock_retry(sc->ip, sc->sm, *error); break; case -EFSBADCRC: case -EFSCORRUPTED: @@ -90,7 +90,7 @@ __xfs_scrub_process_error( *error = 0; /* fall through */ default: - trace_xfs_scrub_op_error(sc, agno, bno, *error, + trace_xchk_op_error(sc, agno, bno, *error, ret_ip); break; } @@ -98,30 +98,30 @@ __xfs_scrub_process_error( } bool -xfs_scrub_process_error( +xchk_process_error( struct xfs_scrub_context *sc, xfs_agnumber_t agno, xfs_agblock_t bno, int *error) { - return __xfs_scrub_process_error(sc, agno, bno, error, + return __xchk_process_error(sc, agno, bno, error, XFS_SCRUB_OFLAG_CORRUPT, __return_address); } bool -xfs_scrub_xref_process_error( +xchk_xref_process_error( struct xfs_scrub_context *sc, xfs_agnumber_t agno, xfs_agblock_t bno, int *error) { - return __xfs_scrub_process_error(sc, agno, bno, error, + return __xchk_process_error(sc, agno, bno, error, XFS_SCRUB_OFLAG_XFAIL, __return_address); } /* Check for operational errors for a file offset. */ static bool -__xfs_scrub_fblock_process_error( +__xchk_fblock_process_error( struct xfs_scrub_context *sc, int whichfork, xfs_fileoff_t offset, @@ -134,7 +134,7 @@ __xfs_scrub_fblock_process_error( return true; case -EDEADLOCK: /* Used to restart an op with deadlock avoidance. */ - trace_xfs_scrub_deadlock_retry(sc->ip, sc->sm, *error); + trace_xchk_deadlock_retry(sc->ip, sc->sm, *error); break; case -EFSBADCRC: case -EFSCORRUPTED: @@ -143,7 +143,7 @@ __xfs_scrub_fblock_process_error( *error = 0; /* fall through */ default: - trace_xfs_scrub_file_op_error(sc, whichfork, offset, *error, + trace_xchk_file_op_error(sc, whichfork, offset, *error, ret_ip); break; } @@ -151,24 +151,24 @@ __xfs_scrub_fblock_process_error( } bool -xfs_scrub_fblock_process_error( +xchk_fblock_process_error( struct xfs_scrub_context *sc, int whichfork, xfs_fileoff_t offset, int *error) { - return __xfs_scrub_fblock_process_error(sc, whichfork, offset, error, + return __xchk_fblock_process_error(sc, whichfork, offset, error, XFS_SCRUB_OFLAG_CORRUPT, __return_address); } bool -xfs_scrub_fblock_xref_process_error( +xchk_fblock_xref_process_error( struct xfs_scrub_context *sc, int whichfork, xfs_fileoff_t offset, int *error) { - return __xfs_scrub_fblock_process_error(sc, whichfork, offset, error, + return __xchk_fblock_process_error(sc, whichfork, offset, error, XFS_SCRUB_OFLAG_XFAIL, __return_address); } @@ -186,12 +186,12 @@ xfs_scrub_fblock_xref_process_error( /* Record a block which could be optimized. */ void -xfs_scrub_block_set_preen( +xchk_block_set_preen( struct xfs_scrub_context *sc, struct xfs_buf *bp) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_PREEN; - trace_xfs_scrub_block_preen(sc, bp->b_bn, __return_address); + trace_xchk_block_preen(sc, bp->b_bn, __return_address); } /* @@ -200,32 +200,32 @@ xfs_scrub_block_set_preen( * the block location of the inode record itself. */ void -xfs_scrub_ino_set_preen( +xchk_ino_set_preen( struct xfs_scrub_context *sc, xfs_ino_t ino) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_PREEN; - trace_xfs_scrub_ino_preen(sc, ino, __return_address); + trace_xchk_ino_preen(sc, ino, __return_address); } /* Record a corrupt block. */ void -xfs_scrub_block_set_corrupt( +xchk_block_set_corrupt( struct xfs_scrub_context *sc, struct xfs_buf *bp) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT; - trace_xfs_scrub_block_error(sc, bp->b_bn, __return_address); + trace_xchk_block_error(sc, bp->b_bn, __return_address); } /* Record a corruption while cross-referencing. */ void -xfs_scrub_block_xref_set_corrupt( +xchk_block_xref_set_corrupt( struct xfs_scrub_context *sc, struct xfs_buf *bp) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XCORRUPT; - trace_xfs_scrub_block_error(sc, bp->b_bn, __return_address); + trace_xchk_block_error(sc, bp->b_bn, __return_address); } /* @@ -234,44 +234,44 @@ xfs_scrub_block_xref_set_corrupt( * inode record itself. */ void -xfs_scrub_ino_set_corrupt( +xchk_ino_set_corrupt( struct xfs_scrub_context *sc, xfs_ino_t ino) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT; - trace_xfs_scrub_ino_error(sc, ino, __return_address); + trace_xchk_ino_error(sc, ino, __return_address); } /* Record a corruption while cross-referencing with an inode. */ void -xfs_scrub_ino_xref_set_corrupt( +xchk_ino_xref_set_corrupt( struct xfs_scrub_context *sc, xfs_ino_t ino) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XCORRUPT; - trace_xfs_scrub_ino_error(sc, ino, __return_address); + trace_xchk_ino_error(sc, ino, __return_address); } /* Record corruption in a block indexed by a file fork. */ void -xfs_scrub_fblock_set_corrupt( +xchk_fblock_set_corrupt( struct xfs_scrub_context *sc, int whichfork, xfs_fileoff_t offset) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT; - trace_xfs_scrub_fblock_error(sc, whichfork, offset, __return_address); + trace_xchk_fblock_error(sc, whichfork, offset, __return_address); } /* Record a corruption while cross-referencing a fork block. */ void -xfs_scrub_fblock_xref_set_corrupt( +xchk_fblock_xref_set_corrupt( struct xfs_scrub_context *sc, int whichfork, xfs_fileoff_t offset) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XCORRUPT; - trace_xfs_scrub_fblock_error(sc, whichfork, offset, __return_address); + trace_xchk_fblock_error(sc, whichfork, offset, __return_address); } /* @@ -279,32 +279,32 @@ xfs_scrub_fblock_xref_set_corrupt( * incorrect. */ void -xfs_scrub_ino_set_warning( +xchk_ino_set_warning( struct xfs_scrub_context *sc, xfs_ino_t ino) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_WARNING; - trace_xfs_scrub_ino_warning(sc, ino, __return_address); + trace_xchk_ino_warning(sc, ino, __return_address); } /* Warn about a block indexed by a file fork that needs review. */ void -xfs_scrub_fblock_set_warning( +xchk_fblock_set_warning( struct xfs_scrub_context *sc, int whichfork, xfs_fileoff_t offset) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_WARNING; - trace_xfs_scrub_fblock_warning(sc, whichfork, offset, __return_address); + trace_xchk_fblock_warning(sc, whichfork, offset, __return_address); } /* Signal an incomplete scrub. */ void -xfs_scrub_set_incomplete( +xchk_set_incomplete( struct xfs_scrub_context *sc) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_INCOMPLETE; - trace_xfs_scrub_incomplete(sc, __return_address); + trace_xchk_incomplete(sc, __return_address); } /* @@ -312,18 +312,18 @@ xfs_scrub_set_incomplete( * at least according to the reverse mapping data. */ -struct xfs_scrub_rmap_ownedby_info { +struct xchk_rmap_ownedby_info { struct xfs_owner_info *oinfo; xfs_filblks_t *blocks; }; STATIC int -xfs_scrub_count_rmap_ownedby_irec( +xchk_count_rmap_ownedby_irec( struct xfs_btree_cur *cur, struct xfs_rmap_irec *rec, void *priv) { - struct xfs_scrub_rmap_ownedby_info *sroi = priv; + struct xchk_rmap_ownedby_info *sroi = priv; bool irec_attr; bool oinfo_attr; @@ -344,19 +344,19 @@ xfs_scrub_count_rmap_ownedby_irec( * The caller should pass us an rmapbt cursor. */ int -xfs_scrub_count_rmap_ownedby_ag( +xchk_count_rmap_ownedby_ag( struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, struct xfs_owner_info *oinfo, xfs_filblks_t *blocks) { - struct xfs_scrub_rmap_ownedby_info sroi; + struct xchk_rmap_ownedby_info sroi; sroi.oinfo = oinfo; *blocks = 0; sroi.blocks = blocks; - return xfs_rmap_query_all(cur, xfs_scrub_count_rmap_ownedby_irec, + return xfs_rmap_query_all(cur, xchk_count_rmap_ownedby_irec, &sroi); } @@ -392,12 +392,12 @@ want_ag_read_header_failure( /* * Grab all the headers for an AG. * - * The headers should be released by xfs_scrub_ag_free, but as a fail + * The headers should be released by xchk_ag_free, but as a fail * safe we attach all the buffers we grab to the scrub transaction so * they'll all be freed when we cancel it. */ int -xfs_scrub_ag_read_headers( +xchk_ag_read_headers( struct xfs_scrub_context *sc, xfs_agnumber_t agno, struct xfs_buf **agi, @@ -425,8 +425,8 @@ out: /* Release all the AG btree cursors. */ void -xfs_scrub_ag_btcur_free( - struct xfs_scrub_ag *sa) +xchk_ag_btcur_free( + struct xchk_ag *sa) { if (sa->refc_cur) xfs_btree_del_cursor(sa->refc_cur, XFS_BTREE_ERROR); @@ -451,9 +451,9 @@ xfs_scrub_ag_btcur_free( /* Initialize all the btree cursors for an AG. */ int -xfs_scrub_ag_btcur_init( +xchk_ag_btcur_init( struct xfs_scrub_context *sc, - struct xfs_scrub_ag *sa) + struct xchk_ag *sa) { struct xfs_mount *mp = sc->mp; xfs_agnumber_t agno = sa->agno; @@ -511,11 +511,11 @@ err: /* Release the AG header context and btree cursors. */ void -xfs_scrub_ag_free( +xchk_ag_free( struct xfs_scrub_context *sc, - struct xfs_scrub_ag *sa) + struct xchk_ag *sa) { - xfs_scrub_ag_btcur_free(sa); + xchk_ag_btcur_free(sa); if (sa->agfl_bp) { xfs_trans_brelse(sc->tp, sa->agfl_bp); sa->agfl_bp = NULL; @@ -543,30 +543,30 @@ xfs_scrub_ag_free( * transaction ourselves. */ int -xfs_scrub_ag_init( +xchk_ag_init( struct xfs_scrub_context *sc, xfs_agnumber_t agno, - struct xfs_scrub_ag *sa) + struct xchk_ag *sa) { int error; sa->agno = agno; - error = xfs_scrub_ag_read_headers(sc, agno, &sa->agi_bp, + error = xchk_ag_read_headers(sc, agno, &sa->agi_bp, &sa->agf_bp, &sa->agfl_bp); if (error) return error; - return xfs_scrub_ag_btcur_init(sc, sa); + return xchk_ag_btcur_init(sc, sa); } /* * Grab the per-ag structure if we haven't already gotten it. Teardown of the - * xfs_scrub_ag will release it for us. + * xchk_ag will release it for us. */ void -xfs_scrub_perag_get( +xchk_perag_get( struct xfs_mount *mp, - struct xfs_scrub_ag *sa) + struct xchk_ag *sa) { if (!sa->pag) sa->pag = xfs_perag_get(mp, sa->agno); @@ -585,7 +585,7 @@ xfs_scrub_perag_get( * the metadata object. */ int -xfs_scrub_trans_alloc( +xchk_trans_alloc( struct xfs_scrub_context *sc, uint resblks) { @@ -598,19 +598,19 @@ xfs_scrub_trans_alloc( /* Set us up with a transaction and an empty context. */ int -xfs_scrub_setup_fs( +xchk_setup_fs( struct xfs_scrub_context *sc, struct xfs_inode *ip) { uint resblks; resblks = xfs_repair_calc_ag_resblks(sc); - return xfs_scrub_trans_alloc(sc, resblks); + return xchk_trans_alloc(sc, resblks); } /* Set us up with AG headers and btree cursors. */ int -xfs_scrub_setup_ag_btree( +xchk_setup_ag_btree( struct xfs_scrub_context *sc, struct xfs_inode *ip, bool force_log) @@ -625,21 +625,21 @@ xfs_scrub_setup_ag_btree( * document why they need to do so. */ if (force_log) { - error = xfs_scrub_checkpoint_log(mp); + error = xchk_checkpoint_log(mp); if (error) return error; } - error = xfs_scrub_setup_fs(sc, ip); + error = xchk_setup_fs(sc, ip); if (error) return error; - return xfs_scrub_ag_init(sc, sc->sm->sm_agno, &sc->sa); + return xchk_ag_init(sc, sc->sm->sm_agno, &sc->sa); } /* Push everything out of the log onto disk. */ int -xfs_scrub_checkpoint_log( +xchk_checkpoint_log( struct xfs_mount *mp) { int error; @@ -657,7 +657,7 @@ xfs_scrub_checkpoint_log( * The inode is not locked. */ int -xfs_scrub_get_inode( +xchk_get_inode( struct xfs_scrub_context *sc, struct xfs_inode *ip_in) { @@ -704,7 +704,7 @@ xfs_scrub_get_inode( error = -EFSCORRUPTED; /* fall through */ default: - trace_xfs_scrub_op_error(sc, + trace_xchk_op_error(sc, XFS_INO_TO_AGNO(mp, sc->sm->sm_ino), XFS_INO_TO_AGBNO(mp, sc->sm->sm_ino), error, __return_address); @@ -721,21 +721,21 @@ xfs_scrub_get_inode( /* Set us up to scrub a file's contents. */ int -xfs_scrub_setup_inode_contents( +xchk_setup_inode_contents( struct xfs_scrub_context *sc, struct xfs_inode *ip, unsigned int resblks) { int error; - error = xfs_scrub_get_inode(sc, ip); + error = xchk_get_inode(sc, ip); if (error) return error; /* Got the inode, lock it and we're ready to go. */ sc->ilock_flags = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL; xfs_ilock(sc->ip, sc->ilock_flags); - error = xfs_scrub_trans_alloc(sc, resblks); + error = xchk_trans_alloc(sc, resblks); if (error) goto out; sc->ilock_flags |= XFS_ILOCK_EXCL; @@ -752,13 +752,13 @@ out: * the cursor and skip the check. */ bool -xfs_scrub_should_check_xref( +xchk_should_check_xref( struct xfs_scrub_context *sc, int *error, struct xfs_btree_cur **curpp) { /* No point in xref if we already know we're corrupt. */ - if (xfs_scrub_skip_xref(sc->sm)) + if (xchk_skip_xref(sc->sm)) return false; if (*error == 0) @@ -775,7 +775,7 @@ xfs_scrub_should_check_xref( } sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XFAIL; - trace_xfs_scrub_xref_error(sc, *error, __return_address); + trace_xchk_xref_error(sc, *error, __return_address); /* * Errors encountered during cross-referencing with another @@ -787,25 +787,25 @@ xfs_scrub_should_check_xref( /* Run the structure verifiers on in-memory buffers to detect bad memory. */ void -xfs_scrub_buffer_recheck( +xchk_buffer_recheck( struct xfs_scrub_context *sc, struct xfs_buf *bp) { xfs_failaddr_t fa; if (bp->b_ops == NULL) { - xfs_scrub_block_set_corrupt(sc, bp); + xchk_block_set_corrupt(sc, bp); return; } if (bp->b_ops->verify_struct == NULL) { - xfs_scrub_set_incomplete(sc); + xchk_set_incomplete(sc); return; } fa = bp->b_ops->verify_struct(bp); if (!fa) return; sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT; - trace_xfs_scrub_block_error(sc, bp->b_bn, fa); + trace_xchk_block_error(sc, bp->b_bn, fa); } /* @@ -813,7 +813,7 @@ xfs_scrub_buffer_recheck( * pointed to by sc->ip and the ILOCK must be held. */ int -xfs_scrub_metadata_inode_forks( +xchk_metadata_inode_forks( struct xfs_scrub_context *sc) { __u32 smtype; @@ -825,26 +825,26 @@ xfs_scrub_metadata_inode_forks( /* Metadata inodes don't live on the rt device. */ if (sc->ip->i_d.di_flags & XFS_DIFLAG_REALTIME) { - xfs_scrub_ino_set_corrupt(sc, sc->ip->i_ino); + xchk_ino_set_corrupt(sc, sc->ip->i_ino); return 0; } /* They should never participate in reflink. */ if (xfs_is_reflink_inode(sc->ip)) { - xfs_scrub_ino_set_corrupt(sc, sc->ip->i_ino); + xchk_ino_set_corrupt(sc, sc->ip->i_ino); return 0; } /* They also should never have extended attributes. */ if (xfs_inode_hasattr(sc->ip)) { - xfs_scrub_ino_set_corrupt(sc, sc->ip->i_ino); + xchk_ino_set_corrupt(sc, sc->ip->i_ino); return 0; } /* Invoke the data fork scrubber. */ smtype = sc->sm->sm_type; sc->sm->sm_type = XFS_SCRUB_TYPE_BMBTD; - error = xfs_scrub_bmap_data(sc); + error = xchk_bmap_data(sc); sc->sm->sm_type = smtype; if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) return error; @@ -853,11 +853,11 @@ xfs_scrub_metadata_inode_forks( if (xfs_sb_version_hasreflink(&sc->mp->m_sb)) { error = xfs_reflink_inode_has_shared_extents(sc->tp, sc->ip, &shared); - if (!xfs_scrub_fblock_process_error(sc, XFS_DATA_FORK, 0, + if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error)) return error; if (shared) - xfs_scrub_ino_set_corrupt(sc, sc->ip->i_ino); + xchk_ino_set_corrupt(sc, sc->ip->i_ino); } return error; @@ -871,7 +871,7 @@ xfs_scrub_metadata_inode_forks( * we can't. */ int -xfs_scrub_ilock_inverted( +xchk_ilock_inverted( struct xfs_inode *ip, uint lock_mode) { diff --git a/fs/xfs/scrub/common.h b/fs/xfs/scrub/common.h index 2172bd5361e2..5881cb2ecc26 100644 --- a/fs/xfs/scrub/common.h +++ b/fs/xfs/scrub/common.h @@ -12,7 +12,7 @@ * Note that we're careful not to make any judgements about *error. */ static inline bool -xfs_scrub_should_terminate( +xchk_should_terminate( struct xfs_scrub_context *sc, int *error) { @@ -24,121 +24,121 @@ xfs_scrub_should_terminate( return false; } -int xfs_scrub_trans_alloc(struct xfs_scrub_context *sc, uint resblks); -bool xfs_scrub_process_error(struct xfs_scrub_context *sc, xfs_agnumber_t agno, +int xchk_trans_alloc(struct xfs_scrub_context *sc, uint resblks); +bool xchk_process_error(struct xfs_scrub_context *sc, xfs_agnumber_t agno, xfs_agblock_t bno, int *error); -bool xfs_scrub_fblock_process_error(struct xfs_scrub_context *sc, int whichfork, +bool xchk_fblock_process_error(struct xfs_scrub_context *sc, int whichfork, xfs_fileoff_t offset, int *error); -bool xfs_scrub_xref_process_error(struct xfs_scrub_context *sc, +bool xchk_xref_process_error(struct xfs_scrub_context *sc, xfs_agnumber_t agno, xfs_agblock_t bno, int *error); -bool xfs_scrub_fblock_xref_process_error(struct xfs_scrub_context *sc, +bool xchk_fblock_xref_process_error(struct xfs_scrub_context *sc, int whichfork, xfs_fileoff_t offset, int *error); -void xfs_scrub_block_set_preen(struct xfs_scrub_context *sc, +void xchk_block_set_preen(struct xfs_scrub_context *sc, struct xfs_buf *bp); -void xfs_scrub_ino_set_preen(struct xfs_scrub_context *sc, xfs_ino_t ino); +void xchk_ino_set_preen(struct xfs_scrub_context *sc, xfs_ino_t ino); -void xfs_scrub_block_set_corrupt(struct xfs_scrub_context *sc, +void xchk_block_set_corrupt(struct xfs_scrub_context *sc, struct xfs_buf *bp); -void xfs_scrub_ino_set_corrupt(struct xfs_scrub_context *sc, xfs_ino_t ino); -void xfs_scrub_fblock_set_corrupt(struct xfs_scrub_context *sc, int whichfork, +void xchk_ino_set_corrupt(struct xfs_scrub_context *sc, xfs_ino_t ino); +void xchk_fblock_set_corrupt(struct xfs_scrub_context *sc, int whichfork, xfs_fileoff_t offset); -void xfs_scrub_block_xref_set_corrupt(struct xfs_scrub_context *sc, +void xchk_block_xref_set_corrupt(struct xfs_scrub_context *sc, struct xfs_buf *bp); -void xfs_scrub_ino_xref_set_corrupt(struct xfs_scrub_context *sc, +void xchk_ino_xref_set_corrupt(struct xfs_scrub_context *sc, xfs_ino_t ino); -void xfs_scrub_fblock_xref_set_corrupt(struct xfs_scrub_context *sc, +void xchk_fblock_xref_set_corrupt(struct xfs_scrub_context *sc, int whichfork, xfs_fileoff_t offset); -void xfs_scrub_ino_set_warning(struct xfs_scrub_context *sc, xfs_ino_t ino); -void xfs_scrub_fblock_set_warning(struct xfs_scrub_context *sc, int whichfork, +void xchk_ino_set_warning(struct xfs_scrub_context *sc, xfs_ino_t ino); +void xchk_fblock_set_warning(struct xfs_scrub_context *sc, int whichfork, xfs_fileoff_t offset); -void xfs_scrub_set_incomplete(struct xfs_scrub_context *sc); -int xfs_scrub_checkpoint_log(struct xfs_mount *mp); +void xchk_set_incomplete(struct xfs_scrub_context *sc); +int xchk_checkpoint_log(struct xfs_mount *mp); /* Are we set up for a cross-referencing check? */ -bool xfs_scrub_should_check_xref(struct xfs_scrub_context *sc, int *error, +bool xchk_should_check_xref(struct xfs_scrub_context *sc, int *error, struct xfs_btree_cur **curpp); /* Setup functions */ -int xfs_scrub_setup_fs(struct xfs_scrub_context *sc, struct xfs_inode *ip); -int xfs_scrub_setup_ag_allocbt(struct xfs_scrub_context *sc, +int xchk_setup_fs(struct xfs_scrub_context *sc, struct xfs_inode *ip); +int xchk_setup_ag_allocbt(struct xfs_scrub_context *sc, struct xfs_inode *ip); -int xfs_scrub_setup_ag_iallocbt(struct xfs_scrub_context *sc, +int xchk_setup_ag_iallocbt(struct xfs_scrub_context *sc, struct xfs_inode *ip); -int xfs_scrub_setup_ag_rmapbt(struct xfs_scrub_context *sc, +int xchk_setup_ag_rmapbt(struct xfs_scrub_context *sc, struct xfs_inode *ip); -int xfs_scrub_setup_ag_refcountbt(struct xfs_scrub_context *sc, +int xchk_setup_ag_refcountbt(struct xfs_scrub_context *sc, struct xfs_inode *ip); -int xfs_scrub_setup_inode(struct xfs_scrub_context *sc, +int xchk_setup_inode(struct xfs_scrub_context *sc, struct xfs_inode *ip); -int xfs_scrub_setup_inode_bmap(struct xfs_scrub_context *sc, +int xchk_setup_inode_bmap(struct xfs_scrub_context *sc, struct xfs_inode *ip); -int xfs_scrub_setup_inode_bmap_data(struct xfs_scrub_context *sc, +int xchk_setup_inode_bmap_data(struct xfs_scrub_context *sc, struct xfs_inode *ip); -int xfs_scrub_setup_directory(struct xfs_scrub_context *sc, +int xchk_setup_directory(struct xfs_scrub_context *sc, struct xfs_inode *ip); -int xfs_scrub_setup_xattr(struct xfs_scrub_context *sc, +int xchk_setup_xattr(struct xfs_scrub_context *sc, struct xfs_inode *ip); -int xfs_scrub_setup_symlink(struct xfs_scrub_context *sc, +int xchk_setup_symlink(struct xfs_scrub_context *sc, struct xfs_inode *ip); -int xfs_scrub_setup_parent(struct xfs_scrub_context *sc, +int xchk_setup_parent(struct xfs_scrub_context *sc, struct xfs_inode *ip); #ifdef CONFIG_XFS_RT -int xfs_scrub_setup_rt(struct xfs_scrub_context *sc, struct xfs_inode *ip); +int xchk_setup_rt(struct xfs_scrub_context *sc, struct xfs_inode *ip); #else static inline int -xfs_scrub_setup_rt(struct xfs_scrub_context *sc, struct xfs_inode *ip) +xchk_setup_rt(struct xfs_scrub_context *sc, struct xfs_inode *ip) { return -ENOENT; } #endif #ifdef CONFIG_XFS_QUOTA -int xfs_scrub_setup_quota(struct xfs_scrub_context *sc, struct xfs_inode *ip); +int xchk_setup_quota(struct xfs_scrub_context *sc, struct xfs_inode *ip); #else static inline int -xfs_scrub_setup_quota(struct xfs_scrub_context *sc, struct xfs_inode *ip) +xchk_setup_quota(struct xfs_scrub_context *sc, struct xfs_inode *ip) { return -ENOENT; } #endif -void xfs_scrub_ag_free(struct xfs_scrub_context *sc, struct xfs_scrub_ag *sa); -int xfs_scrub_ag_init(struct xfs_scrub_context *sc, xfs_agnumber_t agno, - struct xfs_scrub_ag *sa); -void xfs_scrub_perag_get(struct xfs_mount *mp, struct xfs_scrub_ag *sa); -int xfs_scrub_ag_read_headers(struct xfs_scrub_context *sc, xfs_agnumber_t agno, +void xchk_ag_free(struct xfs_scrub_context *sc, struct xchk_ag *sa); +int xchk_ag_init(struct xfs_scrub_context *sc, xfs_agnumber_t agno, + struct xchk_ag *sa); +void xchk_perag_get(struct xfs_mount *mp, struct xchk_ag *sa); +int xchk_ag_read_headers(struct xfs_scrub_context *sc, xfs_agnumber_t agno, struct xfs_buf **agi, struct xfs_buf **agf, struct xfs_buf **agfl); -void xfs_scrub_ag_btcur_free(struct xfs_scrub_ag *sa); -int xfs_scrub_ag_btcur_init(struct xfs_scrub_context *sc, - struct xfs_scrub_ag *sa); -int xfs_scrub_count_rmap_ownedby_ag(struct xfs_scrub_context *sc, +void xchk_ag_btcur_free(struct xchk_ag *sa); +int xchk_ag_btcur_init(struct xfs_scrub_context *sc, + struct xchk_ag *sa); +int xchk_count_rmap_ownedby_ag(struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, struct xfs_owner_info *oinfo, xfs_filblks_t *blocks); -int xfs_scrub_setup_ag_btree(struct xfs_scrub_context *sc, +int xchk_setup_ag_btree(struct xfs_scrub_context *sc, struct xfs_inode *ip, bool force_log); -int xfs_scrub_get_inode(struct xfs_scrub_context *sc, struct xfs_inode *ip_in); -int xfs_scrub_setup_inode_contents(struct xfs_scrub_context *sc, +int xchk_get_inode(struct xfs_scrub_context *sc, struct xfs_inode *ip_in); +int xchk_setup_inode_contents(struct xfs_scrub_context *sc, struct xfs_inode *ip, unsigned int resblks); -void xfs_scrub_buffer_recheck(struct xfs_scrub_context *sc, struct xfs_buf *bp); +void xchk_buffer_recheck(struct xfs_scrub_context *sc, struct xfs_buf *bp); /* * Don't bother cross-referencing if we already found corruption or cross * referencing discrepancies. */ -static inline bool xfs_scrub_skip_xref(struct xfs_scrub_metadata *sm) +static inline bool xchk_skip_xref(struct xfs_scrub_metadata *sm) { return sm->sm_flags & (XFS_SCRUB_OFLAG_CORRUPT | XFS_SCRUB_OFLAG_XCORRUPT); } -int xfs_scrub_metadata_inode_forks(struct xfs_scrub_context *sc); -int xfs_scrub_ilock_inverted(struct xfs_inode *ip, uint lock_mode); +int xchk_metadata_inode_forks(struct xfs_scrub_context *sc); +int xchk_ilock_inverted(struct xfs_inode *ip, uint lock_mode); #endif /* __XFS_SCRUB_COMMON_H__ */ diff --git a/fs/xfs/scrub/dabtree.c b/fs/xfs/scrub/dabtree.c index d700c4d4d4ef..fee80f6ddfd7 100644 --- a/fs/xfs/scrub/dabtree.c +++ b/fs/xfs/scrub/dabtree.c @@ -35,8 +35,8 @@ * operational errors in common.c. */ bool -xfs_scrub_da_process_error( - struct xfs_scrub_da_btree *ds, +xchk_da_process_error( + struct xchk_da_btree *ds, int level, int *error) { @@ -48,7 +48,7 @@ xfs_scrub_da_process_error( switch (*error) { case -EDEADLOCK: /* Used to restart an op with deadlock avoidance. */ - trace_xfs_scrub_deadlock_retry(sc->ip, sc->sm, *error); + trace_xchk_deadlock_retry(sc->ip, sc->sm, *error); break; case -EFSBADCRC: case -EFSCORRUPTED: @@ -57,7 +57,7 @@ xfs_scrub_da_process_error( *error = 0; /* fall through */ default: - trace_xfs_scrub_file_op_error(sc, ds->dargs.whichfork, + trace_xchk_file_op_error(sc, ds->dargs.whichfork, xfs_dir2_da_to_db(ds->dargs.geo, ds->state->path.blk[level].blkno), *error, __return_address); @@ -71,15 +71,15 @@ xfs_scrub_da_process_error( * operational errors in common.c. */ void -xfs_scrub_da_set_corrupt( - struct xfs_scrub_da_btree *ds, +xchk_da_set_corrupt( + struct xchk_da_btree *ds, int level) { struct xfs_scrub_context *sc = ds->sc; sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT; - trace_xfs_scrub_fblock_error(sc, ds->dargs.whichfork, + trace_xchk_fblock_error(sc, ds->dargs.whichfork, xfs_dir2_da_to_db(ds->dargs.geo, ds->state->path.blk[level].blkno), __return_address); @@ -87,8 +87,8 @@ xfs_scrub_da_set_corrupt( /* Find an entry at a certain level in a da btree. */ STATIC void * -xfs_scrub_da_btree_entry( - struct xfs_scrub_da_btree *ds, +xchk_da_btree_entry( + struct xchk_da_btree *ds, int level, int rec) { @@ -123,8 +123,8 @@ xfs_scrub_da_btree_entry( /* Scrub a da btree hash (key). */ int -xfs_scrub_da_btree_hash( - struct xfs_scrub_da_btree *ds, +xchk_da_btree_hash( + struct xchk_da_btree *ds, int level, __be32 *hashp) { @@ -136,7 +136,7 @@ xfs_scrub_da_btree_hash( /* Is this hash in order? */ hash = be32_to_cpu(*hashp); if (hash < ds->hashes[level]) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); ds->hashes[level] = hash; if (level == 0) @@ -144,10 +144,10 @@ xfs_scrub_da_btree_hash( /* Is this hash no larger than the parent hash? */ blks = ds->state->path.blk; - entry = xfs_scrub_da_btree_entry(ds, level - 1, blks[level - 1].index); + entry = xchk_da_btree_entry(ds, level - 1, blks[level - 1].index); parent_hash = be32_to_cpu(entry->hashval); if (parent_hash < hash) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); return 0; } @@ -157,13 +157,13 @@ xfs_scrub_da_btree_hash( * pointer. */ STATIC bool -xfs_scrub_da_btree_ptr_ok( - struct xfs_scrub_da_btree *ds, +xchk_da_btree_ptr_ok( + struct xchk_da_btree *ds, int level, xfs_dablk_t blkno) { if (blkno < ds->lowest || (ds->highest != 0 && blkno >= ds->highest)) { - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); return false; } @@ -176,7 +176,7 @@ xfs_scrub_da_btree_ptr_ok( * leaf1, we must multiplex the verifiers. */ static void -xfs_scrub_da_btree_read_verify( +xchk_da_btree_read_verify( struct xfs_buf *bp) { struct xfs_da_blkinfo *info = bp->b_addr; @@ -198,7 +198,7 @@ xfs_scrub_da_btree_read_verify( } } static void -xfs_scrub_da_btree_write_verify( +xchk_da_btree_write_verify( struct xfs_buf *bp) { struct xfs_da_blkinfo *info = bp->b_addr; @@ -220,7 +220,7 @@ xfs_scrub_da_btree_write_verify( } } static void * -xfs_scrub_da_btree_verify( +xchk_da_btree_verify( struct xfs_buf *bp) { struct xfs_da_blkinfo *info = bp->b_addr; @@ -236,17 +236,17 @@ xfs_scrub_da_btree_verify( } } -static const struct xfs_buf_ops xfs_scrub_da_btree_buf_ops = { - .name = "xfs_scrub_da_btree", - .verify_read = xfs_scrub_da_btree_read_verify, - .verify_write = xfs_scrub_da_btree_write_verify, - .verify_struct = xfs_scrub_da_btree_verify, +static const struct xfs_buf_ops xchk_da_btree_buf_ops = { + .name = "xchk_da_btree", + .verify_read = xchk_da_btree_read_verify, + .verify_write = xchk_da_btree_write_verify, + .verify_struct = xchk_da_btree_verify, }; /* Check a block's sibling. */ STATIC int -xfs_scrub_da_btree_block_check_sibling( - struct xfs_scrub_da_btree *ds, +xchk_da_btree_block_check_sibling( + struct xchk_da_btree *ds, int level, int direction, xfs_dablk_t sibling) @@ -265,7 +265,7 @@ xfs_scrub_da_btree_block_check_sibling( error = xfs_da3_path_shift(ds->state, &ds->state->altpath, direction, false, &retval); if (error == 0 && retval == 0) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); error = 0; goto out; } @@ -273,19 +273,19 @@ xfs_scrub_da_btree_block_check_sibling( /* Move the alternate cursor one block in the direction given. */ error = xfs_da3_path_shift(ds->state, &ds->state->altpath, direction, false, &retval); - if (!xfs_scrub_da_process_error(ds, level, &error)) + if (!xchk_da_process_error(ds, level, &error)) return error; if (retval) { - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); return error; } if (ds->state->altpath.blk[level].bp) - xfs_scrub_buffer_recheck(ds->sc, + xchk_buffer_recheck(ds->sc, ds->state->altpath.blk[level].bp); /* Compare upper level pointer to sibling pointer. */ if (ds->state->altpath.blk[level].blkno != sibling) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); xfs_trans_brelse(ds->dargs.trans, ds->state->altpath.blk[level].bp); out: return error; @@ -293,8 +293,8 @@ out: /* Check a block's sibling pointers. */ STATIC int -xfs_scrub_da_btree_block_check_siblings( - struct xfs_scrub_da_btree *ds, +xchk_da_btree_block_check_siblings( + struct xchk_da_btree *ds, int level, struct xfs_da_blkinfo *hdr) { @@ -308,7 +308,7 @@ xfs_scrub_da_btree_block_check_siblings( /* Top level blocks should not have sibling pointers. */ if (level == 0) { if (forw != 0 || back != 0) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); return 0; } @@ -316,10 +316,10 @@ xfs_scrub_da_btree_block_check_siblings( * Check back (left) and forw (right) pointers. These functions * absorb error codes for us. */ - error = xfs_scrub_da_btree_block_check_sibling(ds, level, 0, back); + error = xchk_da_btree_block_check_sibling(ds, level, 0, back); if (error) goto out; - error = xfs_scrub_da_btree_block_check_sibling(ds, level, 1, forw); + error = xchk_da_btree_block_check_sibling(ds, level, 1, forw); out: memset(&ds->state->altpath, 0, sizeof(ds->state->altpath)); @@ -328,8 +328,8 @@ out: /* Load a dir/attribute block from a btree. */ STATIC int -xfs_scrub_da_btree_block( - struct xfs_scrub_da_btree *ds, +xchk_da_btree_block( + struct xchk_da_btree *ds, int level, xfs_dablk_t blkno) { @@ -355,17 +355,17 @@ xfs_scrub_da_btree_block( /* Check the pointer. */ blk->blkno = blkno; - if (!xfs_scrub_da_btree_ptr_ok(ds, level, blkno)) + if (!xchk_da_btree_ptr_ok(ds, level, blkno)) goto out_nobuf; /* Read the buffer. */ error = xfs_da_read_buf(dargs->trans, dargs->dp, blk->blkno, -2, &blk->bp, dargs->whichfork, - &xfs_scrub_da_btree_buf_ops); - if (!xfs_scrub_da_process_error(ds, level, &error)) + &xchk_da_btree_buf_ops); + if (!xchk_da_process_error(ds, level, &error)) goto out_nobuf; if (blk->bp) - xfs_scrub_buffer_recheck(ds->sc, blk->bp); + xchk_buffer_recheck(ds->sc, blk->bp); /* * We didn't find a dir btree root block, which means that @@ -378,7 +378,7 @@ xfs_scrub_da_btree_block( /* It's /not/ ok for attr trees not to have a da btree. */ if (blk->bp == NULL) { - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); goto out_nobuf; } @@ -388,17 +388,17 @@ xfs_scrub_da_btree_block( /* We only started zeroing the header on v5 filesystems. */ if (xfs_sb_version_hascrc(&ds->sc->mp->m_sb) && hdr3->hdr.pad) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); /* Check the owner. */ if (xfs_sb_version_hascrc(&ip->i_mount->m_sb)) { owner = be64_to_cpu(hdr3->owner); if (owner != ip->i_ino) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); } /* Check the siblings. */ - error = xfs_scrub_da_btree_block_check_siblings(ds, level, &hdr3->hdr); + error = xchk_da_btree_block_check_siblings(ds, level, &hdr3->hdr); if (error) goto out; @@ -411,7 +411,7 @@ xfs_scrub_da_btree_block( blk->magic = XFS_ATTR_LEAF_MAGIC; blk->hashval = xfs_attr_leaf_lasthash(blk->bp, pmaxrecs); if (ds->tree_level != 0) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); break; case XFS_DIR2_LEAFN_MAGIC: case XFS_DIR3_LEAFN_MAGIC: @@ -420,7 +420,7 @@ xfs_scrub_da_btree_block( blk->magic = XFS_DIR2_LEAFN_MAGIC; blk->hashval = xfs_dir2_leaf_lasthash(ip, blk->bp, pmaxrecs); if (ds->tree_level != 0) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); break; case XFS_DIR2_LEAF1_MAGIC: case XFS_DIR3_LEAF1_MAGIC: @@ -429,7 +429,7 @@ xfs_scrub_da_btree_block( blk->magic = XFS_DIR2_LEAF1_MAGIC; blk->hashval = xfs_dir2_leaf_lasthash(ip, blk->bp, pmaxrecs); if (ds->tree_level != 0) - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); break; case XFS_DA_NODE_MAGIC: case XFS_DA3_NODE_MAGIC: @@ -443,13 +443,13 @@ xfs_scrub_da_btree_block( blk->hashval = be32_to_cpu(btree[*pmaxrecs - 1].hashval); if (level == 0) { if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH) { - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); goto out_freebp; } ds->tree_level = nodehdr.level; } else { if (ds->tree_level != nodehdr.level) { - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); goto out_freebp; } } @@ -457,7 +457,7 @@ xfs_scrub_da_btree_block( /* XXX: Check hdr3.pad32 once we know how to fix it. */ break; default: - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); goto out_freebp; } @@ -473,13 +473,13 @@ out_nobuf: /* Visit all nodes and leaves of a da btree. */ int -xfs_scrub_da_btree( +xchk_da_btree( struct xfs_scrub_context *sc, int whichfork, - xfs_scrub_da_btree_rec_fn scrub_fn, + xchk_da_btree_rec_fn scrub_fn, void *private) { - struct xfs_scrub_da_btree ds = {}; + struct xchk_da_btree ds = {}; struct xfs_mount *mp = sc->mp; struct xfs_da_state_blk *blks; struct xfs_da_node_entry *key; @@ -517,7 +517,7 @@ xfs_scrub_da_btree( /* Find the root of the da tree, if present. */ blks = ds.state->path.blk; - error = xfs_scrub_da_btree_block(&ds, level, blkno); + error = xchk_da_btree_block(&ds, level, blkno); if (error) goto out_state; /* @@ -542,12 +542,12 @@ xfs_scrub_da_btree( } /* Dispatch record scrubbing. */ - rec = xfs_scrub_da_btree_entry(&ds, level, + rec = xchk_da_btree_entry(&ds, level, blks[level].index); error = scrub_fn(&ds, level, rec); if (error) break; - if (xfs_scrub_should_terminate(sc, &error) || + if (xchk_should_terminate(sc, &error) || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) break; @@ -566,8 +566,8 @@ xfs_scrub_da_btree( } /* Hashes in order for scrub? */ - key = xfs_scrub_da_btree_entry(&ds, level, blks[level].index); - error = xfs_scrub_da_btree_hash(&ds, level, &key->hashval); + key = xchk_da_btree_entry(&ds, level, blks[level].index); + error = xchk_da_btree_hash(&ds, level, &key->hashval); if (error) goto out; @@ -575,7 +575,7 @@ xfs_scrub_da_btree( blkno = be32_to_cpu(key->before); level++; ds.tree_level--; - error = xfs_scrub_da_btree_block(&ds, level, blkno); + error = xchk_da_btree_block(&ds, level, blkno); if (error) goto out; if (blks[level].bp == NULL) diff --git a/fs/xfs/scrub/dabtree.h b/fs/xfs/scrub/dabtree.h index 365f9f0019e6..80e4af0e2589 100644 --- a/fs/xfs/scrub/dabtree.h +++ b/fs/xfs/scrub/dabtree.h @@ -8,7 +8,7 @@ /* dir/attr btree */ -struct xfs_scrub_da_btree { +struct xchk_da_btree { struct xfs_da_args dargs; xfs_dahash_t hashes[XFS_DA_NODE_MAXDEPTH]; int maxrecs[XFS_DA_NODE_MAXDEPTH]; @@ -28,18 +28,18 @@ struct xfs_scrub_da_btree { int tree_level; }; -typedef int (*xfs_scrub_da_btree_rec_fn)(struct xfs_scrub_da_btree *ds, +typedef int (*xchk_da_btree_rec_fn)(struct xchk_da_btree *ds, int level, void *rec); /* Check for da btree operation errors. */ -bool xfs_scrub_da_process_error(struct xfs_scrub_da_btree *ds, int level, int *error); +bool xchk_da_process_error(struct xchk_da_btree *ds, int level, int *error); /* Check for da btree corruption. */ -void xfs_scrub_da_set_corrupt(struct xfs_scrub_da_btree *ds, int level); +void xchk_da_set_corrupt(struct xchk_da_btree *ds, int level); -int xfs_scrub_da_btree_hash(struct xfs_scrub_da_btree *ds, int level, +int xchk_da_btree_hash(struct xchk_da_btree *ds, int level, __be32 *hashp); -int xfs_scrub_da_btree(struct xfs_scrub_context *sc, int whichfork, - xfs_scrub_da_btree_rec_fn scrub_fn, void *private); +int xchk_da_btree(struct xfs_scrub_context *sc, int whichfork, + xchk_da_btree_rec_fn scrub_fn, void *private); #endif /* __XFS_SCRUB_DABTREE_H__ */ diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c index 86324775fc9b..2ac07bb73478 100644 --- a/fs/xfs/scrub/dir.c +++ b/fs/xfs/scrub/dir.c @@ -31,18 +31,18 @@ /* Set us up to scrub directories. */ int -xfs_scrub_setup_directory( +xchk_setup_directory( struct xfs_scrub_context *sc, struct xfs_inode *ip) { - return xfs_scrub_setup_inode_contents(sc, ip, 0); + return xchk_setup_inode_contents(sc, ip, 0); } /* Directories */ /* Scrub a directory entry. */ -struct xfs_scrub_dir_ctx { +struct xchk_dir_ctx { /* VFS fill-directory iterator */ struct dir_context dir_iter; @@ -51,8 +51,8 @@ struct xfs_scrub_dir_ctx { /* Check that an inode's mode matches a given DT_ type. */ STATIC int -xfs_scrub_dir_check_ftype( - struct xfs_scrub_dir_ctx *sdc, +xchk_dir_check_ftype( + struct xchk_dir_ctx *sdc, xfs_fileoff_t offset, xfs_ino_t inum, int dtype) @@ -64,7 +64,7 @@ xfs_scrub_dir_check_ftype( if (!xfs_sb_version_hasftype(&mp->m_sb)) { if (dtype != DT_UNKNOWN && dtype != DT_DIR) - xfs_scrub_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, + xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, offset); goto out; } @@ -78,7 +78,7 @@ xfs_scrub_dir_check_ftype( * inodes can trigger immediate inactive cleanup of the inode. */ error = xfs_iget(mp, sdc->sc->tp, inum, 0, 0, &ip); - if (!xfs_scrub_fblock_xref_process_error(sdc->sc, XFS_DATA_FORK, offset, + if (!xchk_fblock_xref_process_error(sdc->sc, XFS_DATA_FORK, offset, &error)) goto out; @@ -86,7 +86,7 @@ xfs_scrub_dir_check_ftype( ino_dtype = xfs_dir3_get_dtype(mp, xfs_mode_to_ftype(VFS_I(ip)->i_mode)); if (ino_dtype != dtype) - xfs_scrub_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, offset); + xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, offset); iput(VFS_I(ip)); out: return error; @@ -101,7 +101,7 @@ out: * we can look up this filename. Finally, we check the ftype. */ STATIC int -xfs_scrub_dir_actor( +xchk_dir_actor( struct dir_context *dir_iter, const char *name, int namelen, @@ -111,13 +111,13 @@ xfs_scrub_dir_actor( { struct xfs_mount *mp; struct xfs_inode *ip; - struct xfs_scrub_dir_ctx *sdc; + struct xchk_dir_ctx *sdc; struct xfs_name xname; xfs_ino_t lookup_ino; xfs_dablk_t offset; int error = 0; - sdc = container_of(dir_iter, struct xfs_scrub_dir_ctx, dir_iter); + sdc = container_of(dir_iter, struct xchk_dir_ctx, dir_iter); ip = sdc->sc->ip; mp = ip->i_mount; offset = xfs_dir2_db_to_da(mp->m_dir_geo, @@ -125,17 +125,17 @@ xfs_scrub_dir_actor( /* Does this inode number make sense? */ if (!xfs_verify_dir_ino(mp, ino)) { - xfs_scrub_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, offset); + xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, offset); goto out; } if (!strncmp(".", name, namelen)) { /* If this is "." then check that the inum matches the dir. */ if (xfs_sb_version_hasftype(&mp->m_sb) && type != DT_DIR) - xfs_scrub_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, + xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, offset); if (ino != ip->i_ino) - xfs_scrub_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, + xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, offset); } else if (!strncmp("..", name, namelen)) { /* @@ -143,10 +143,10 @@ xfs_scrub_dir_actor( * matches this dir. */ if (xfs_sb_version_hasftype(&mp->m_sb) && type != DT_DIR) - xfs_scrub_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, + xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, offset); if (ip->i_ino == mp->m_sb.sb_rootino && ino != ip->i_ino) - xfs_scrub_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, + xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, offset); } @@ -156,23 +156,23 @@ xfs_scrub_dir_actor( xname.type = XFS_DIR3_FT_UNKNOWN; error = xfs_dir_lookup(sdc->sc->tp, ip, &xname, &lookup_ino, NULL); - if (!xfs_scrub_fblock_process_error(sdc->sc, XFS_DATA_FORK, offset, + if (!xchk_fblock_process_error(sdc->sc, XFS_DATA_FORK, offset, &error)) goto out; if (lookup_ino != ino) { - xfs_scrub_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, offset); + xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, offset); goto out; } /* Verify the file type. This function absorbs error codes. */ - error = xfs_scrub_dir_check_ftype(sdc, offset, lookup_ino, type); + error = xchk_dir_check_ftype(sdc, offset, lookup_ino, type); if (error) goto out; out: /* * A negative error code returned here is supposed to cause the * dir_emit caller (xfs_readdir) to abort the directory iteration - * and return zero to xfs_scrub_directory. + * and return zero to xchk_directory. */ if (error == 0 && sdc->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) return -EFSCORRUPTED; @@ -181,8 +181,8 @@ out: /* Scrub a directory btree record. */ STATIC int -xfs_scrub_dir_rec( - struct xfs_scrub_da_btree *ds, +xchk_dir_rec( + struct xchk_da_btree *ds, int level, void *rec) { @@ -203,7 +203,7 @@ xfs_scrub_dir_rec( int error; /* Check the hash of the entry. */ - error = xfs_scrub_da_btree_hash(ds, level, &ent->hashval); + error = xchk_da_btree_hash(ds, level, &ent->hashval); if (error) goto out; @@ -218,18 +218,18 @@ xfs_scrub_dir_rec( rec_bno = xfs_dir2_db_to_da(mp->m_dir_geo, db); if (rec_bno >= mp->m_dir_geo->leafblk) { - xfs_scrub_da_set_corrupt(ds, level); + xchk_da_set_corrupt(ds, level); goto out; } error = xfs_dir3_data_read(ds->dargs.trans, dp, rec_bno, -2, &bp); - if (!xfs_scrub_fblock_process_error(ds->sc, XFS_DATA_FORK, rec_bno, + if (!xchk_fblock_process_error(ds->sc, XFS_DATA_FORK, rec_bno, &error)) goto out; if (!bp) { - xfs_scrub_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); + xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); goto out; } - xfs_scrub_buffer_recheck(ds->sc, bp); + xchk_buffer_recheck(ds->sc, bp); if (ds->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) goto out_relse; @@ -240,7 +240,7 @@ xfs_scrub_dir_rec( p = (char *)mp->m_dir_inode_ops->data_entry_p(bp->b_addr); endp = xfs_dir3_data_endp(mp->m_dir_geo, bp->b_addr); if (!endp) { - xfs_scrub_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); + xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); goto out_relse; } while (p < endp) { @@ -258,7 +258,7 @@ xfs_scrub_dir_rec( p += mp->m_dir_inode_ops->data_entsize(dep->namelen); } if (p >= endp) { - xfs_scrub_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); + xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); goto out_relse; } @@ -267,14 +267,14 @@ xfs_scrub_dir_rec( hash = be32_to_cpu(ent->hashval); tag = be16_to_cpup(dp->d_ops->data_entry_tag_p(dent)); if (!xfs_verify_dir_ino(mp, ino) || tag != off) - xfs_scrub_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); + xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); if (dent->namelen == 0) { - xfs_scrub_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); + xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); goto out_relse; } calc_hash = xfs_da_hashname(dent->name, dent->namelen); if (calc_hash != hash) - xfs_scrub_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); + xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); out_relse: xfs_trans_brelse(ds->dargs.trans, bp); @@ -288,7 +288,7 @@ out: * shortest, and that there aren't any bogus entries. */ STATIC void -xfs_scrub_directory_check_free_entry( +xchk_directory_check_free_entry( struct xfs_scrub_context *sc, xfs_dablk_t lblk, struct xfs_dir2_data_free *bf, @@ -308,12 +308,12 @@ xfs_scrub_directory_check_free_entry( return; /* Unused entry should be in the bestfrees but wasn't found. */ - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); } /* Check free space info in a directory data block. */ STATIC int -xfs_scrub_directory_data_bestfree( +xchk_directory_data_bestfree( struct xfs_scrub_context *sc, xfs_dablk_t lblk, bool is_block) @@ -339,15 +339,15 @@ xfs_scrub_directory_data_bestfree( if (is_block) { /* dir block format */ if (lblk != XFS_B_TO_FSBT(mp, XFS_DIR2_DATA_OFFSET)) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); error = xfs_dir3_block_read(sc->tp, sc->ip, &bp); } else { /* dir data format */ error = xfs_dir3_data_read(sc->tp, sc->ip, lblk, -1, &bp); } - if (!xfs_scrub_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error)) + if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error)) goto out; - xfs_scrub_buffer_recheck(sc, bp); + xchk_buffer_recheck(sc, bp); /* XXX: Check xfs_dir3_data_hdr.pad is zero once we start setting it. */ @@ -362,7 +362,7 @@ xfs_scrub_directory_data_bestfree( if (offset == 0) continue; if (offset >= mp->m_dir_geo->blksize) { - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); goto out_buf; } dup = (struct xfs_dir2_data_unused *)(bp->b_addr + offset); @@ -372,13 +372,13 @@ xfs_scrub_directory_data_bestfree( if (dup->freetag != cpu_to_be16(XFS_DIR2_DATA_FREE_TAG) || be16_to_cpu(dup->length) != be16_to_cpu(dfp->length) || tag != ((char *)dup - (char *)bp->b_addr)) { - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); goto out_buf; } /* bestfree records should be ordered largest to smallest */ if (smallest_bestfree < be16_to_cpu(dfp->length)) { - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); goto out_buf; } @@ -400,7 +400,7 @@ xfs_scrub_directory_data_bestfree( dep = (struct xfs_dir2_data_entry *)ptr; newlen = d_ops->data_entsize(dep->namelen); if (newlen <= 0) { - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); goto out_buf; } @@ -411,7 +411,7 @@ xfs_scrub_directory_data_bestfree( /* Spot check this free entry */ tag = be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)); if (tag != ((char *)dup - (char *)bp->b_addr)) { - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); goto out_buf; } @@ -419,14 +419,14 @@ xfs_scrub_directory_data_bestfree( * Either this entry is a bestfree or it's smaller than * any of the bestfrees. */ - xfs_scrub_directory_check_free_entry(sc, lblk, bf, dup); + xchk_directory_check_free_entry(sc, lblk, bf, dup); if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) goto out_buf; /* Move on. */ newlen = be16_to_cpu(dup->length); if (newlen <= 0) { - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); goto out_buf; } ptr += newlen; @@ -436,11 +436,11 @@ xfs_scrub_directory_data_bestfree( /* We're required to fill all the space. */ if (ptr != endptr) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); /* Did we see at least as many free slots as there are bestfrees? */ if (nr_frees < nr_bestfrees) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); out_buf: xfs_trans_brelse(sc->tp, bp); out: @@ -454,7 +454,7 @@ out: * array is in order. */ STATIC void -xfs_scrub_directory_check_freesp( +xchk_directory_check_freesp( struct xfs_scrub_context *sc, xfs_dablk_t lblk, struct xfs_buf *dbp, @@ -465,15 +465,15 @@ xfs_scrub_directory_check_freesp( dfp = sc->ip->d_ops->data_bestfree_p(dbp->b_addr); if (len != be16_to_cpu(dfp->length)) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); if (len > 0 && be16_to_cpu(dfp->offset) == 0) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); } /* Check free space info in a directory leaf1 block. */ STATIC int -xfs_scrub_directory_leaf1_bestfree( +xchk_directory_leaf1_bestfree( struct xfs_scrub_context *sc, struct xfs_da_args *args, xfs_dablk_t lblk) @@ -497,9 +497,9 @@ xfs_scrub_directory_leaf1_bestfree( /* Read the free space block. */ error = xfs_dir3_leaf_read(sc->tp, sc->ip, lblk, -1, &bp); - if (!xfs_scrub_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error)) + if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error)) goto out; - xfs_scrub_buffer_recheck(sc, bp); + xchk_buffer_recheck(sc, bp); leaf = bp->b_addr; d_ops->leaf_hdr_from_disk(&leafhdr, leaf); @@ -512,7 +512,7 @@ xfs_scrub_directory_leaf1_bestfree( struct xfs_dir3_leaf_hdr *hdr3 = bp->b_addr; if (hdr3->pad != cpu_to_be32(0)) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); } /* @@ -520,19 +520,19 @@ xfs_scrub_directory_leaf1_bestfree( * blocks that can fit under i_size. */ if (bestcount != xfs_dir2_byte_to_db(geo, sc->ip->i_d.di_size)) { - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); goto out; } /* Is the leaf count even remotely sane? */ if (leafhdr.count > d_ops->leaf_max_ents(geo)) { - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); goto out; } /* Leaves and bests don't overlap in leaf format. */ if ((char *)&ents[leafhdr.count] > (char *)bestp) { - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); goto out; } @@ -540,13 +540,13 @@ xfs_scrub_directory_leaf1_bestfree( for (i = 0; i < leafhdr.count; i++) { hash = be32_to_cpu(ents[i].hashval); if (i > 0 && lasthash > hash) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); lasthash = hash; if (ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) stale++; } if (leafhdr.stale != stale) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) goto out; @@ -557,10 +557,10 @@ xfs_scrub_directory_leaf1_bestfree( continue; error = xfs_dir3_data_read(sc->tp, sc->ip, i * args->geo->fsbcount, -1, &dbp); - if (!xfs_scrub_fblock_process_error(sc, XFS_DATA_FORK, lblk, + if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error)) break; - xfs_scrub_directory_check_freesp(sc, lblk, dbp, best); + xchk_directory_check_freesp(sc, lblk, dbp, best); xfs_trans_brelse(sc->tp, dbp); if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) goto out; @@ -571,7 +571,7 @@ out: /* Check free space info in a directory freespace block. */ STATIC int -xfs_scrub_directory_free_bestfree( +xchk_directory_free_bestfree( struct xfs_scrub_context *sc, struct xfs_da_args *args, xfs_dablk_t lblk) @@ -587,15 +587,15 @@ xfs_scrub_directory_free_bestfree( /* Read the free space block */ error = xfs_dir2_free_read(sc->tp, sc->ip, lblk, &bp); - if (!xfs_scrub_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error)) + if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error)) goto out; - xfs_scrub_buffer_recheck(sc, bp); + xchk_buffer_recheck(sc, bp); if (xfs_sb_version_hascrc(&sc->mp->m_sb)) { struct xfs_dir3_free_hdr *hdr3 = bp->b_addr; if (hdr3->pad != cpu_to_be32(0)) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); } /* Check all the entries. */ @@ -610,22 +610,22 @@ xfs_scrub_directory_free_bestfree( error = xfs_dir3_data_read(sc->tp, sc->ip, (freehdr.firstdb + i) * args->geo->fsbcount, -1, &dbp); - if (!xfs_scrub_fblock_process_error(sc, XFS_DATA_FORK, lblk, + if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error)) break; - xfs_scrub_directory_check_freesp(sc, lblk, dbp, best); + xchk_directory_check_freesp(sc, lblk, dbp, best); xfs_trans_brelse(sc->tp, dbp); } if (freehdr.nused + stale != freehdr.nvalid) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); out: return error; } /* Check free space information in directories. */ STATIC int -xfs_scrub_directory_blocks( +xchk_directory_blocks( struct xfs_scrub_context *sc) { struct xfs_bmbt_irec got; @@ -656,7 +656,7 @@ xfs_scrub_directory_blocks( args.geo = mp->m_dir_geo; args.trans = sc->tp; error = xfs_dir2_isblock(&args, &is_block); - if (!xfs_scrub_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error)) + if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error)) goto out; /* Iterate all the data extents in the directory... */ @@ -666,7 +666,7 @@ xfs_scrub_directory_blocks( if (is_block && (got.br_startoff > 0 || got.br_blockcount != args.geo->fsbcount)) { - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, got.br_startoff); break; } @@ -690,7 +690,7 @@ xfs_scrub_directory_blocks( args.geo->fsbcount); lblk < got.br_startoff + got.br_blockcount; lblk += args.geo->fsbcount) { - error = xfs_scrub_directory_data_bestfree(sc, lblk, + error = xchk_directory_data_bestfree(sc, lblk, is_block); if (error) goto out; @@ -709,10 +709,10 @@ xfs_scrub_directory_blocks( got.br_blockcount == args.geo->fsbcount && !xfs_iext_next_extent(ifp, &icur, &got)) { if (is_block) { - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); goto out; } - error = xfs_scrub_directory_leaf1_bestfree(sc, &args, + error = xchk_directory_leaf1_bestfree(sc, &args, leaf_lblk); if (error) goto out; @@ -731,11 +731,11 @@ xfs_scrub_directory_blocks( */ lblk = got.br_startoff; if (lblk & ~0xFFFFFFFFULL) { - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); goto out; } if (is_block) { - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); goto out; } @@ -754,7 +754,7 @@ xfs_scrub_directory_blocks( args.geo->fsbcount); lblk < got.br_startoff + got.br_blockcount; lblk += args.geo->fsbcount) { - error = xfs_scrub_directory_free_bestfree(sc, &args, + error = xchk_directory_free_bestfree(sc, &args, lblk); if (error) goto out; @@ -769,11 +769,11 @@ out: /* Scrub a whole directory. */ int -xfs_scrub_directory( +xchk_directory( struct xfs_scrub_context *sc) { - struct xfs_scrub_dir_ctx sdc = { - .dir_iter.actor = xfs_scrub_dir_actor, + struct xchk_dir_ctx sdc = { + .dir_iter.actor = xchk_dir_actor, .dir_iter.pos = 0, .sc = sc, }; @@ -786,12 +786,12 @@ xfs_scrub_directory( /* Plausible size? */ if (sc->ip->i_d.di_size < xfs_dir2_sf_hdr_size(0)) { - xfs_scrub_ino_set_corrupt(sc, sc->ip->i_ino); + xchk_ino_set_corrupt(sc, sc->ip->i_ino); goto out; } /* Check directory tree structure */ - error = xfs_scrub_da_btree(sc, XFS_DATA_FORK, xfs_scrub_dir_rec, NULL); + error = xchk_da_btree(sc, XFS_DATA_FORK, xchk_dir_rec, NULL); if (error) return error; @@ -799,7 +799,7 @@ xfs_scrub_directory( return error; /* Check the freespace. */ - error = xfs_scrub_directory_blocks(sc); + error = xchk_directory_blocks(sc); if (error) return error; @@ -816,7 +816,7 @@ xfs_scrub_directory( /* * Look up every name in this directory by hash. * - * Use the xfs_readdir function to call xfs_scrub_dir_actor on + * Use the xfs_readdir function to call xchk_dir_actor on * every directory entry in this directory. In _actor, we check * the name, inode number, and ftype (if applicable) of the * entry. xfs_readdir uses the VFS filldir functions to provide @@ -834,7 +834,7 @@ xfs_scrub_directory( xfs_iunlock(sc->ip, XFS_ILOCK_EXCL); while (true) { error = xfs_readdir(sc->tp, sc->ip, &sdc.dir_iter, bufsize); - if (!xfs_scrub_fblock_process_error(sc, XFS_DATA_FORK, 0, + if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error)) goto out; if (oldpos == sdc.dir_iter.pos) diff --git a/fs/xfs/scrub/ialloc.c b/fs/xfs/scrub/ialloc.c index 13d43d108574..69d652b7299c 100644 --- a/fs/xfs/scrub/ialloc.c +++ b/fs/xfs/scrub/ialloc.c @@ -35,11 +35,11 @@ * try again after forcing logged inode cores out to disk. */ int -xfs_scrub_setup_ag_iallocbt( +xchk_setup_ag_iallocbt( struct xfs_scrub_context *sc, struct xfs_inode *ip) { - return xfs_scrub_setup_ag_btree(sc, ip, sc->try_harder); + return xchk_setup_ag_btree(sc, ip, sc->try_harder); } /* Inode btree scrubber. */ @@ -50,7 +50,7 @@ xfs_scrub_setup_ag_iallocbt( * we have a record or not depending on freecount. */ static inline void -xfs_scrub_iallocbt_chunk_xref_other( +xchk_iallocbt_chunk_xref_other( struct xfs_scrub_context *sc, struct xfs_inobt_rec_incore *irec, xfs_agino_t agino) @@ -66,16 +66,16 @@ xfs_scrub_iallocbt_chunk_xref_other( if (!(*pcur)) return; error = xfs_ialloc_has_inode_record(*pcur, agino, agino, &has_irec); - if (!xfs_scrub_should_check_xref(sc, &error, pcur)) + if (!xchk_should_check_xref(sc, &error, pcur)) return; if (((irec->ir_freecount > 0 && !has_irec) || (irec->ir_freecount == 0 && has_irec))) - xfs_scrub_btree_xref_set_corrupt(sc, *pcur, 0); + xchk_btree_xref_set_corrupt(sc, *pcur, 0); } /* Cross-reference with the other btrees. */ STATIC void -xfs_scrub_iallocbt_chunk_xref( +xchk_iallocbt_chunk_xref( struct xfs_scrub_context *sc, struct xfs_inobt_rec_incore *irec, xfs_agino_t agino, @@ -87,17 +87,17 @@ xfs_scrub_iallocbt_chunk_xref( if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) return; - xfs_scrub_xref_is_used_space(sc, agbno, len); - xfs_scrub_iallocbt_chunk_xref_other(sc, irec, agino); + xchk_xref_is_used_space(sc, agbno, len); + xchk_iallocbt_chunk_xref_other(sc, irec, agino); xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INODES); - xfs_scrub_xref_is_owned_by(sc, agbno, len, &oinfo); - xfs_scrub_xref_is_not_shared(sc, agbno, len); + xchk_xref_is_owned_by(sc, agbno, len, &oinfo); + xchk_xref_is_not_shared(sc, agbno, len); } /* Is this chunk worth checking? */ STATIC bool -xfs_scrub_iallocbt_chunk( - struct xfs_scrub_btree *bs, +xchk_iallocbt_chunk( + struct xchk_btree *bs, struct xfs_inobt_rec_incore *irec, xfs_agino_t agino, xfs_extlen_t len) @@ -110,16 +110,16 @@ xfs_scrub_iallocbt_chunk( if (bno + len <= bno || !xfs_verify_agbno(mp, agno, bno) || !xfs_verify_agbno(mp, agno, bno + len - 1)) - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); - xfs_scrub_iallocbt_chunk_xref(bs->sc, irec, agino, bno, len); + xchk_iallocbt_chunk_xref(bs->sc, irec, agino, bno, len); return true; } /* Count the number of free inodes. */ static unsigned int -xfs_scrub_iallocbt_freecount( +xchk_iallocbt_freecount( xfs_inofree_t freemask) { BUILD_BUG_ON(sizeof(freemask) != sizeof(__u64)); @@ -128,8 +128,8 @@ xfs_scrub_iallocbt_freecount( /* Check a particular inode with ir_free. */ STATIC int -xfs_scrub_iallocbt_check_cluster_freemask( - struct xfs_scrub_btree *bs, +xchk_iallocbt_check_cluster_freemask( + struct xchk_btree *bs, xfs_ino_t fsino, xfs_agino_t chunkino, xfs_agino_t clusterino, @@ -143,14 +143,14 @@ xfs_scrub_iallocbt_check_cluster_freemask( bool inuse; int error = 0; - if (xfs_scrub_should_terminate(bs->sc, &error)) + if (xchk_should_terminate(bs->sc, &error)) return error; dip = xfs_buf_offset(bp, clusterino * mp->m_sb.sb_inodesize); if (be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC || (dip->di_version >= 3 && be64_to_cpu(dip->di_ino) != fsino + clusterino)) { - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); goto out; } @@ -175,15 +175,15 @@ xfs_scrub_iallocbt_check_cluster_freemask( freemask_ok = inode_is_free ^ inuse; } if (!freemask_ok) - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); out: return 0; } /* Make sure the free mask is consistent with what the inodes think. */ STATIC int -xfs_scrub_iallocbt_check_freemask( - struct xfs_scrub_btree *bs, +xchk_iallocbt_check_freemask( + struct xchk_btree *bs, struct xfs_inobt_rec_incore *irec) { struct xfs_owner_info oinfo; @@ -223,18 +223,18 @@ xfs_scrub_iallocbt_check_freemask( /* The whole cluster must be a hole or not a hole. */ ir_holemask = (irec->ir_holemask & holemask); if (ir_holemask != holemask && ir_holemask != 0) { - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); continue; } /* If any part of this is a hole, skip it. */ if (ir_holemask) { - xfs_scrub_xref_is_not_owned_by(bs->sc, agbno, + xchk_xref_is_not_owned_by(bs->sc, agbno, blks_per_cluster, &oinfo); continue; } - xfs_scrub_xref_is_owned_by(bs->sc, agbno, blks_per_cluster, + xchk_xref_is_owned_by(bs->sc, agbno, blks_per_cluster, &oinfo); /* Grab the inode cluster buffer. */ @@ -245,13 +245,13 @@ xfs_scrub_iallocbt_check_freemask( error = xfs_imap_to_bp(mp, bs->cur->bc_tp, &imap, &dip, &bp, 0, 0); - if (!xfs_scrub_btree_xref_process_error(bs->sc, bs->cur, 0, + if (!xchk_btree_xref_process_error(bs->sc, bs->cur, 0, &error)) continue; /* Which inodes are free? */ for (clusterino = 0; clusterino < nr_inodes; clusterino++) { - error = xfs_scrub_iallocbt_check_cluster_freemask(bs, + error = xchk_iallocbt_check_cluster_freemask(bs, fsino, chunkino, clusterino, irec, bp); if (error) { xfs_trans_brelse(bs->cur->bc_tp, bp); @@ -267,8 +267,8 @@ xfs_scrub_iallocbt_check_freemask( /* Scrub an inobt/finobt record. */ STATIC int -xfs_scrub_iallocbt_rec( - struct xfs_scrub_btree *bs, +xchk_iallocbt_rec( + struct xchk_btree *bs, union xfs_btree_rec *rec) { struct xfs_mount *mp = bs->cur->bc_mp; @@ -289,18 +289,18 @@ xfs_scrub_iallocbt_rec( if (irec.ir_count > XFS_INODES_PER_CHUNK || irec.ir_freecount > XFS_INODES_PER_CHUNK) - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); real_freecount = irec.ir_freecount + (XFS_INODES_PER_CHUNK - irec.ir_count); - if (real_freecount != xfs_scrub_iallocbt_freecount(irec.ir_free)) - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + if (real_freecount != xchk_iallocbt_freecount(irec.ir_free)) + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); agino = irec.ir_startino; /* Record has to be properly aligned within the AG. */ if (!xfs_verify_agino(mp, agno, agino) || !xfs_verify_agino(mp, agno, agino + XFS_INODES_PER_CHUNK - 1)) { - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); goto out; } @@ -308,7 +308,7 @@ xfs_scrub_iallocbt_rec( agbno = XFS_AGINO_TO_AGBNO(mp, irec.ir_startino); if ((agbno & (xfs_ialloc_cluster_alignment(mp) - 1)) || (agbno & (xfs_icluster_size_fsb(mp) - 1))) - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); *inode_blocks += XFS_B_TO_FSB(mp, irec.ir_count * mp->m_sb.sb_inodesize); @@ -318,9 +318,9 @@ xfs_scrub_iallocbt_rec( len = XFS_B_TO_FSB(mp, XFS_INODES_PER_CHUNK * mp->m_sb.sb_inodesize); if (irec.ir_count != XFS_INODES_PER_CHUNK) - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); - if (!xfs_scrub_iallocbt_chunk(bs, &irec, agino, len)) + if (!xchk_iallocbt_chunk(bs, &irec, agino, len)) goto out; goto check_freemask; } @@ -333,12 +333,12 @@ xfs_scrub_iallocbt_rec( holes = ~xfs_inobt_irec_to_allocmask(&irec); if ((holes & irec.ir_free) != holes || irec.ir_freecount > irec.ir_count) - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); for (i = 0; i < XFS_INOBT_HOLEMASK_BITS; i++) { if (holemask & 1) holecount += XFS_INODES_PER_HOLEMASK_BIT; - else if (!xfs_scrub_iallocbt_chunk(bs, &irec, agino, len)) + else if (!xchk_iallocbt_chunk(bs, &irec, agino, len)) break; holemask >>= 1; agino += XFS_INODES_PER_HOLEMASK_BIT; @@ -346,10 +346,10 @@ xfs_scrub_iallocbt_rec( if (holecount > XFS_INODES_PER_CHUNK || holecount + irec.ir_count != XFS_INODES_PER_CHUNK) - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); check_freemask: - error = xfs_scrub_iallocbt_check_freemask(bs, &irec); + error = xchk_iallocbt_check_freemask(bs, &irec); if (error) goto out; @@ -362,7 +362,7 @@ out: * Don't bother if we're missing btree cursors, as we're already corrupt. */ STATIC void -xfs_scrub_iallocbt_xref_rmap_btreeblks( +xchk_iallocbt_xref_rmap_btreeblks( struct xfs_scrub_context *sc, int which) { @@ -374,27 +374,27 @@ xfs_scrub_iallocbt_xref_rmap_btreeblks( if (!sc->sa.ino_cur || !sc->sa.rmap_cur || (xfs_sb_version_hasfinobt(&sc->mp->m_sb) && !sc->sa.fino_cur) || - xfs_scrub_skip_xref(sc->sm)) + xchk_skip_xref(sc->sm)) return; /* Check that we saw as many inobt blocks as the rmap says. */ error = xfs_btree_count_blocks(sc->sa.ino_cur, &inobt_blocks); - if (!xfs_scrub_process_error(sc, 0, 0, &error)) + if (!xchk_process_error(sc, 0, 0, &error)) return; if (sc->sa.fino_cur) { error = xfs_btree_count_blocks(sc->sa.fino_cur, &finobt_blocks); - if (!xfs_scrub_process_error(sc, 0, 0, &error)) + if (!xchk_process_error(sc, 0, 0, &error)) return; } xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INOBT); - error = xfs_scrub_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur, &oinfo, + error = xchk_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur, &oinfo, &blocks); - if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.rmap_cur)) + if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur)) return; if (blocks != inobt_blocks + finobt_blocks) - xfs_scrub_btree_set_corrupt(sc, sc->sa.ino_cur, 0); + xchk_btree_set_corrupt(sc, sc->sa.ino_cur, 0); } /* @@ -402,7 +402,7 @@ xfs_scrub_iallocbt_xref_rmap_btreeblks( * the rmap says are owned by inodes. */ STATIC void -xfs_scrub_iallocbt_xref_rmap_inodes( +xchk_iallocbt_xref_rmap_inodes( struct xfs_scrub_context *sc, int which, xfs_filblks_t inode_blocks) @@ -411,22 +411,22 @@ xfs_scrub_iallocbt_xref_rmap_inodes( xfs_filblks_t blocks; int error; - if (!sc->sa.rmap_cur || xfs_scrub_skip_xref(sc->sm)) + if (!sc->sa.rmap_cur || xchk_skip_xref(sc->sm)) return; /* Check that we saw as many inode blocks as the rmap knows about. */ xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INODES); - error = xfs_scrub_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur, &oinfo, + error = xchk_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur, &oinfo, &blocks); - if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.rmap_cur)) + if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur)) return; if (blocks != inode_blocks) - xfs_scrub_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0); + xchk_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0); } /* Scrub the inode btrees for some AG. */ STATIC int -xfs_scrub_iallocbt( +xchk_iallocbt( struct xfs_scrub_context *sc, xfs_btnum_t which) { @@ -437,12 +437,12 @@ xfs_scrub_iallocbt( xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INOBT); cur = which == XFS_BTNUM_INO ? sc->sa.ino_cur : sc->sa.fino_cur; - error = xfs_scrub_btree(sc, cur, xfs_scrub_iallocbt_rec, &oinfo, + error = xchk_btree(sc, cur, xchk_iallocbt_rec, &oinfo, &inode_blocks); if (error) return error; - xfs_scrub_iallocbt_xref_rmap_btreeblks(sc, which); + xchk_iallocbt_xref_rmap_btreeblks(sc, which); /* * If we're scrubbing the inode btree, inode_blocks is the number of @@ -452,28 +452,28 @@ xfs_scrub_iallocbt( * to inode chunks with free inodes. */ if (which == XFS_BTNUM_INO) - xfs_scrub_iallocbt_xref_rmap_inodes(sc, which, inode_blocks); + xchk_iallocbt_xref_rmap_inodes(sc, which, inode_blocks); return error; } int -xfs_scrub_inobt( +xchk_inobt( struct xfs_scrub_context *sc) { - return xfs_scrub_iallocbt(sc, XFS_BTNUM_INO); + return xchk_iallocbt(sc, XFS_BTNUM_INO); } int -xfs_scrub_finobt( +xchk_finobt( struct xfs_scrub_context *sc) { - return xfs_scrub_iallocbt(sc, XFS_BTNUM_FINO); + return xchk_iallocbt(sc, XFS_BTNUM_FINO); } /* See if an inode btree has (or doesn't have) an inode chunk record. */ static inline void -xfs_scrub_xref_inode_check( +xchk_xref_inode_check( struct xfs_scrub_context *sc, xfs_agblock_t agbno, xfs_extlen_t len, @@ -483,33 +483,33 @@ xfs_scrub_xref_inode_check( bool has_inodes; int error; - if (!(*icur) || xfs_scrub_skip_xref(sc->sm)) + if (!(*icur) || xchk_skip_xref(sc->sm)) return; error = xfs_ialloc_has_inodes_at_extent(*icur, agbno, len, &has_inodes); - if (!xfs_scrub_should_check_xref(sc, &error, icur)) + if (!xchk_should_check_xref(sc, &error, icur)) return; if (has_inodes != should_have_inodes) - xfs_scrub_btree_xref_set_corrupt(sc, *icur, 0); + xchk_btree_xref_set_corrupt(sc, *icur, 0); } /* xref check that the extent is not covered by inodes */ void -xfs_scrub_xref_is_not_inode_chunk( +xchk_xref_is_not_inode_chunk( struct xfs_scrub_context *sc, xfs_agblock_t agbno, xfs_extlen_t len) { - xfs_scrub_xref_inode_check(sc, agbno, len, &sc->sa.ino_cur, false); - xfs_scrub_xref_inode_check(sc, agbno, len, &sc->sa.fino_cur, false); + xchk_xref_inode_check(sc, agbno, len, &sc->sa.ino_cur, false); + xchk_xref_inode_check(sc, agbno, len, &sc->sa.fino_cur, false); } /* xref check that the extent is covered by inodes */ void -xfs_scrub_xref_is_inode_chunk( +xchk_xref_is_inode_chunk( struct xfs_scrub_context *sc, xfs_agblock_t agbno, xfs_extlen_t len) { - xfs_scrub_xref_inode_check(sc, agbno, len, &sc->sa.ino_cur, true); + xchk_xref_inode_check(sc, agbno, len, &sc->sa.ino_cur, true); } diff --git a/fs/xfs/scrub/inode.c b/fs/xfs/scrub/inode.c index 7a6208505980..d85fbec39e52 100644 --- a/fs/xfs/scrub/inode.c +++ b/fs/xfs/scrub/inode.c @@ -37,7 +37,7 @@ * the goal. */ int -xfs_scrub_setup_inode( +xchk_setup_inode( struct xfs_scrub_context *sc, struct xfs_inode *ip) { @@ -47,13 +47,13 @@ xfs_scrub_setup_inode( * Try to get the inode. If the verifiers fail, we try again * in raw mode. */ - error = xfs_scrub_get_inode(sc, ip); + error = xchk_get_inode(sc, ip); switch (error) { case 0: break; case -EFSCORRUPTED: case -EFSBADCRC: - return xfs_scrub_trans_alloc(sc, 0); + return xchk_trans_alloc(sc, 0); default: return error; } @@ -61,7 +61,7 @@ xfs_scrub_setup_inode( /* Got the inode, lock it and we're ready to go. */ sc->ilock_flags = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL; xfs_ilock(sc->ip, sc->ilock_flags); - error = xfs_scrub_trans_alloc(sc, 0); + error = xchk_trans_alloc(sc, 0); if (error) goto out; sc->ilock_flags |= XFS_ILOCK_EXCL; @@ -76,7 +76,7 @@ out: /* Validate di_extsize hint. */ STATIC void -xfs_scrub_inode_extsize( +xchk_inode_extsize( struct xfs_scrub_context *sc, struct xfs_dinode *dip, xfs_ino_t ino, @@ -88,7 +88,7 @@ xfs_scrub_inode_extsize( fa = xfs_inode_validate_extsize(sc->mp, be32_to_cpu(dip->di_extsize), mode, flags); if (fa) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); } /* @@ -98,7 +98,7 @@ xfs_scrub_inode_extsize( * These functions must be kept in sync with each other. */ STATIC void -xfs_scrub_inode_cowextsize( +xchk_inode_cowextsize( struct xfs_scrub_context *sc, struct xfs_dinode *dip, xfs_ino_t ino, @@ -112,12 +112,12 @@ xfs_scrub_inode_cowextsize( be32_to_cpu(dip->di_cowextsize), mode, flags, flags2); if (fa) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); } /* Make sure the di_flags make sense for the inode. */ STATIC void -xfs_scrub_inode_flags( +xchk_inode_flags( struct xfs_scrub_context *sc, struct xfs_dinode *dip, xfs_ino_t ino, @@ -157,12 +157,12 @@ xfs_scrub_inode_flags( return; bad: - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); } /* Make sure the di_flags2 make sense for the inode. */ STATIC void -xfs_scrub_inode_flags2( +xchk_inode_flags2( struct xfs_scrub_context *sc, struct xfs_dinode *dip, xfs_ino_t ino, @@ -200,12 +200,12 @@ xfs_scrub_inode_flags2( return; bad: - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); } /* Scrub all the ondisk inode fields. */ STATIC void -xfs_scrub_dinode( +xchk_dinode( struct xfs_scrub_context *sc, struct xfs_dinode *dip, xfs_ino_t ino) @@ -237,7 +237,7 @@ xfs_scrub_dinode( /* mode is recognized */ break; default: - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); break; } @@ -248,22 +248,22 @@ xfs_scrub_dinode( * We autoconvert v1 inodes into v2 inodes on writeout, * so just mark this inode for preening. */ - xfs_scrub_ino_set_preen(sc, ino); + xchk_ino_set_preen(sc, ino); break; case 2: case 3: if (dip->di_onlink != 0) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); if (dip->di_mode == 0 && sc->ip) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); if (dip->di_projid_hi != 0 && !xfs_sb_version_hasprojid32bit(&mp->m_sb)) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); break; default: - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); return; } @@ -273,40 +273,40 @@ xfs_scrub_dinode( */ if (dip->di_uid == cpu_to_be32(-1U) || dip->di_gid == cpu_to_be32(-1U)) - xfs_scrub_ino_set_warning(sc, ino); + xchk_ino_set_warning(sc, ino); /* di_format */ switch (dip->di_format) { case XFS_DINODE_FMT_DEV: if (!S_ISCHR(mode) && !S_ISBLK(mode) && !S_ISFIFO(mode) && !S_ISSOCK(mode)) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); break; case XFS_DINODE_FMT_LOCAL: if (!S_ISDIR(mode) && !S_ISLNK(mode)) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); break; case XFS_DINODE_FMT_EXTENTS: if (!S_ISREG(mode) && !S_ISDIR(mode) && !S_ISLNK(mode)) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); break; case XFS_DINODE_FMT_BTREE: if (!S_ISREG(mode) && !S_ISDIR(mode)) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); break; case XFS_DINODE_FMT_UUID: default: - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); break; } /* di_[amc]time.nsec */ if (be32_to_cpu(dip->di_atime.t_nsec) >= NSEC_PER_SEC) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); if (be32_to_cpu(dip->di_mtime.t_nsec) >= NSEC_PER_SEC) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); if (be32_to_cpu(dip->di_ctime.t_nsec) >= NSEC_PER_SEC) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); /* * di_size. xfs_dinode_verify checks for things that screw up @@ -315,19 +315,19 @@ xfs_scrub_dinode( */ isize = be64_to_cpu(dip->di_size); if (isize & (1ULL << 63)) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); /* Devices, fifos, and sockets must have zero size */ if (!S_ISDIR(mode) && !S_ISREG(mode) && !S_ISLNK(mode) && isize != 0) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); /* Directories can't be larger than the data section size (32G) */ if (S_ISDIR(mode) && (isize == 0 || isize >= XFS_DIR2_SPACE_SIZE)) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); /* Symlinks can't be larger than SYMLINK_MAXLEN */ if (S_ISLNK(mode) && (isize == 0 || isize >= XFS_SYMLINK_MAXLEN)) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); /* * Warn if the running kernel can't handle the kinds of offsets @@ -336,7 +336,7 @@ xfs_scrub_dinode( * overly large offsets, flag the inode for admin review. */ if (isize >= mp->m_super->s_maxbytes) - xfs_scrub_ino_set_warning(sc, ino); + xchk_ino_set_warning(sc, ino); /* di_nblocks */ if (flags2 & XFS_DIFLAG2_REFLINK) { @@ -351,15 +351,15 @@ xfs_scrub_dinode( */ if (be64_to_cpu(dip->di_nblocks) >= mp->m_sb.sb_dblocks + mp->m_sb.sb_rblocks) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); } else { if (be64_to_cpu(dip->di_nblocks) >= mp->m_sb.sb_dblocks) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); } - xfs_scrub_inode_flags(sc, dip, ino, mode, flags); + xchk_inode_flags(sc, dip, ino, mode, flags); - xfs_scrub_inode_extsize(sc, dip, ino, mode, flags); + xchk_inode_extsize(sc, dip, ino, mode, flags); /* di_nextents */ nextents = be32_to_cpu(dip->di_nextents); @@ -367,31 +367,31 @@ xfs_scrub_dinode( switch (dip->di_format) { case XFS_DINODE_FMT_EXTENTS: if (nextents > fork_recs) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); break; case XFS_DINODE_FMT_BTREE: if (nextents <= fork_recs) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); break; default: if (nextents != 0) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); break; } /* di_forkoff */ if (XFS_DFORK_APTR(dip) >= (char *)dip + mp->m_sb.sb_inodesize) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); if (dip->di_anextents != 0 && dip->di_forkoff == 0) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); if (dip->di_forkoff == 0 && dip->di_aformat != XFS_DINODE_FMT_EXTENTS) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); /* di_aformat */ if (dip->di_aformat != XFS_DINODE_FMT_LOCAL && dip->di_aformat != XFS_DINODE_FMT_EXTENTS && dip->di_aformat != XFS_DINODE_FMT_BTREE) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); /* di_anextents */ nextents = be16_to_cpu(dip->di_anextents); @@ -399,22 +399,22 @@ xfs_scrub_dinode( switch (dip->di_aformat) { case XFS_DINODE_FMT_EXTENTS: if (nextents > fork_recs) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); break; case XFS_DINODE_FMT_BTREE: if (nextents <= fork_recs) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); break; default: if (nextents != 0) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); } if (dip->di_version >= 3) { if (be32_to_cpu(dip->di_crtime.t_nsec) >= NSEC_PER_SEC) - xfs_scrub_ino_set_corrupt(sc, ino); - xfs_scrub_inode_flags2(sc, dip, ino, mode, flags, flags2); - xfs_scrub_inode_cowextsize(sc, dip, ino, mode, flags, + xchk_ino_set_corrupt(sc, ino); + xchk_inode_flags2(sc, dip, ino, mode, flags, flags2); + xchk_inode_cowextsize(sc, dip, ino, mode, flags, flags2); } } @@ -425,7 +425,7 @@ xfs_scrub_dinode( * IGET_UNTRUSTED, which checks the inobt for us. */ static void -xfs_scrub_inode_xref_finobt( +xchk_inode_xref_finobt( struct xfs_scrub_context *sc, xfs_ino_t ino) { @@ -434,7 +434,7 @@ xfs_scrub_inode_xref_finobt( int has_record; int error; - if (!sc->sa.fino_cur || xfs_scrub_skip_xref(sc->sm)) + if (!sc->sa.fino_cur || xchk_skip_xref(sc->sm)) return; agino = XFS_INO_TO_AGINO(sc->mp, ino); @@ -445,12 +445,12 @@ xfs_scrub_inode_xref_finobt( */ error = xfs_inobt_lookup(sc->sa.fino_cur, agino, XFS_LOOKUP_LE, &has_record); - if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.fino_cur) || + if (!xchk_should_check_xref(sc, &error, &sc->sa.fino_cur) || !has_record) return; error = xfs_inobt_get_rec(sc->sa.fino_cur, &rec, &has_record); - if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.fino_cur) || + if (!xchk_should_check_xref(sc, &error, &sc->sa.fino_cur) || !has_record) return; @@ -463,12 +463,12 @@ xfs_scrub_inode_xref_finobt( return; if (rec.ir_free & XFS_INOBT_MASK(agino - rec.ir_startino)) - xfs_scrub_btree_xref_set_corrupt(sc, sc->sa.fino_cur, 0); + xchk_btree_xref_set_corrupt(sc, sc->sa.fino_cur, 0); } /* Cross reference the inode fields with the forks. */ STATIC void -xfs_scrub_inode_xref_bmap( +xchk_inode_xref_bmap( struct xfs_scrub_context *sc, struct xfs_dinode *dip) { @@ -477,32 +477,32 @@ xfs_scrub_inode_xref_bmap( xfs_filblks_t acount; int error; - if (xfs_scrub_skip_xref(sc->sm)) + if (xchk_skip_xref(sc->sm)) return; /* Walk all the extents to check nextents/naextents/nblocks. */ error = xfs_bmap_count_blocks(sc->tp, sc->ip, XFS_DATA_FORK, &nextents, &count); - if (!xfs_scrub_should_check_xref(sc, &error, NULL)) + if (!xchk_should_check_xref(sc, &error, NULL)) return; if (nextents < be32_to_cpu(dip->di_nextents)) - xfs_scrub_ino_xref_set_corrupt(sc, sc->ip->i_ino); + xchk_ino_xref_set_corrupt(sc, sc->ip->i_ino); error = xfs_bmap_count_blocks(sc->tp, sc->ip, XFS_ATTR_FORK, &nextents, &acount); - if (!xfs_scrub_should_check_xref(sc, &error, NULL)) + if (!xchk_should_check_xref(sc, &error, NULL)) return; if (nextents != be16_to_cpu(dip->di_anextents)) - xfs_scrub_ino_xref_set_corrupt(sc, sc->ip->i_ino); + xchk_ino_xref_set_corrupt(sc, sc->ip->i_ino); /* Check nblocks against the inode. */ if (count + acount != be64_to_cpu(dip->di_nblocks)) - xfs_scrub_ino_xref_set_corrupt(sc, sc->ip->i_ino); + xchk_ino_xref_set_corrupt(sc, sc->ip->i_ino); } /* Cross-reference with the other btrees. */ STATIC void -xfs_scrub_inode_xref( +xchk_inode_xref( struct xfs_scrub_context *sc, xfs_ino_t ino, struct xfs_dinode *dip) @@ -518,18 +518,18 @@ xfs_scrub_inode_xref( agno = XFS_INO_TO_AGNO(sc->mp, ino); agbno = XFS_INO_TO_AGBNO(sc->mp, ino); - error = xfs_scrub_ag_init(sc, agno, &sc->sa); - if (!xfs_scrub_xref_process_error(sc, agno, agbno, &error)) + error = xchk_ag_init(sc, agno, &sc->sa); + if (!xchk_xref_process_error(sc, agno, agbno, &error)) return; - xfs_scrub_xref_is_used_space(sc, agbno, 1); - xfs_scrub_inode_xref_finobt(sc, ino); + xchk_xref_is_used_space(sc, agbno, 1); + xchk_inode_xref_finobt(sc, ino); xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INODES); - xfs_scrub_xref_is_owned_by(sc, agbno, 1, &oinfo); - xfs_scrub_xref_is_not_shared(sc, agbno, 1); - xfs_scrub_inode_xref_bmap(sc, dip); + xchk_xref_is_owned_by(sc, agbno, 1, &oinfo); + xchk_xref_is_not_shared(sc, agbno, 1); + xchk_inode_xref_bmap(sc, dip); - xfs_scrub_ag_free(sc, &sc->sa); + xchk_ag_free(sc, &sc->sa); } /* @@ -539,7 +539,7 @@ xfs_scrub_inode_xref( * reflink filesystem. */ static void -xfs_scrub_inode_check_reflink_iflag( +xchk_inode_check_reflink_iflag( struct xfs_scrub_context *sc, xfs_ino_t ino) { @@ -552,18 +552,18 @@ xfs_scrub_inode_check_reflink_iflag( error = xfs_reflink_inode_has_shared_extents(sc->tp, sc->ip, &has_shared); - if (!xfs_scrub_xref_process_error(sc, XFS_INO_TO_AGNO(mp, ino), + if (!xchk_xref_process_error(sc, XFS_INO_TO_AGNO(mp, ino), XFS_INO_TO_AGBNO(mp, ino), &error)) return; if (xfs_is_reflink_inode(sc->ip) && !has_shared) - xfs_scrub_ino_set_preen(sc, ino); + xchk_ino_set_preen(sc, ino); else if (!xfs_is_reflink_inode(sc->ip) && has_shared) - xfs_scrub_ino_set_corrupt(sc, ino); + xchk_ino_set_corrupt(sc, ino); } /* Scrub an inode. */ int -xfs_scrub_inode( +xchk_inode( struct xfs_scrub_context *sc) { struct xfs_dinode di; @@ -575,13 +575,13 @@ xfs_scrub_inode( * and a NULL inode, so flag the corruption error and return. */ if (!sc->ip) { - xfs_scrub_ino_set_corrupt(sc, sc->sm->sm_ino); + xchk_ino_set_corrupt(sc, sc->sm->sm_ino); return 0; } /* Scrub the inode core. */ xfs_inode_to_disk(sc->ip, &di, 0); - xfs_scrub_dinode(sc, &di, sc->ip->i_ino); + xchk_dinode(sc, &di, sc->ip->i_ino); if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) goto out; @@ -591,9 +591,9 @@ xfs_scrub_inode( * we scrubbed the dinode. */ if (S_ISREG(VFS_I(sc->ip)->i_mode)) - xfs_scrub_inode_check_reflink_iflag(sc, sc->ip->i_ino); + xchk_inode_check_reflink_iflag(sc, sc->ip->i_ino); - xfs_scrub_inode_xref(sc, sc->ip->i_ino, &di); + xchk_inode_xref(sc, sc->ip->i_ino, &di); out: return error; } diff --git a/fs/xfs/scrub/parent.c b/fs/xfs/scrub/parent.c index e2bda58c32f0..0a78d8411f23 100644 --- a/fs/xfs/scrub/parent.c +++ b/fs/xfs/scrub/parent.c @@ -27,18 +27,18 @@ /* Set us up to scrub parents. */ int -xfs_scrub_setup_parent( +xchk_setup_parent( struct xfs_scrub_context *sc, struct xfs_inode *ip) { - return xfs_scrub_setup_inode_contents(sc, ip, 0); + return xchk_setup_inode_contents(sc, ip, 0); } /* Parent pointers */ /* Look for an entry in a parent pointing to this inode. */ -struct xfs_scrub_parent_ctx { +struct xchk_parent_ctx { struct dir_context dc; xfs_ino_t ino; xfs_nlink_t nlink; @@ -46,7 +46,7 @@ struct xfs_scrub_parent_ctx { /* Look for a single entry in a directory pointing to an inode. */ STATIC int -xfs_scrub_parent_actor( +xchk_parent_actor( struct dir_context *dc, const char *name, int namelen, @@ -54,9 +54,9 @@ xfs_scrub_parent_actor( u64 ino, unsigned type) { - struct xfs_scrub_parent_ctx *spc; + struct xchk_parent_ctx *spc; - spc = container_of(dc, struct xfs_scrub_parent_ctx, dc); + spc = container_of(dc, struct xchk_parent_ctx, dc); if (spc->ino == ino) spc->nlink++; return 0; @@ -64,13 +64,13 @@ xfs_scrub_parent_actor( /* Count the number of dentries in the parent dir that point to this inode. */ STATIC int -xfs_scrub_parent_count_parent_dentries( +xchk_parent_count_parent_dentries( struct xfs_scrub_context *sc, struct xfs_inode *parent, xfs_nlink_t *nlink) { - struct xfs_scrub_parent_ctx spc = { - .dc.actor = xfs_scrub_parent_actor, + struct xchk_parent_ctx spc = { + .dc.actor = xchk_parent_actor, .dc.pos = 0, .ino = sc->ip->i_ino, .nlink = 0, @@ -120,7 +120,7 @@ out: * entry pointing back to the inode being scrubbed. */ STATIC int -xfs_scrub_parent_validate( +xchk_parent_validate( struct xfs_scrub_context *sc, xfs_ino_t dnum, bool *try_again) @@ -138,7 +138,7 @@ xfs_scrub_parent_validate( /* '..' must not point to ourselves. */ if (sc->ip->i_ino == dnum) { - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); goto out; } @@ -165,13 +165,13 @@ xfs_scrub_parent_validate( error = xfs_iget(mp, sc->tp, dnum, XFS_IGET_UNTRUSTED, 0, &dp); if (error == -EINVAL) { error = -EFSCORRUPTED; - xfs_scrub_fblock_process_error(sc, XFS_DATA_FORK, 0, &error); + xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error); goto out; } - if (!xfs_scrub_fblock_xref_process_error(sc, XFS_DATA_FORK, 0, &error)) + if (!xchk_fblock_xref_process_error(sc, XFS_DATA_FORK, 0, &error)) goto out; if (dp == sc->ip || !S_ISDIR(VFS_I(dp)->i_mode)) { - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); goto out_rele; } @@ -183,12 +183,12 @@ xfs_scrub_parent_validate( * the child inodes. */ if (xfs_ilock_nowait(dp, XFS_IOLOCK_SHARED)) { - error = xfs_scrub_parent_count_parent_dentries(sc, dp, &nlink); - if (!xfs_scrub_fblock_xref_process_error(sc, XFS_DATA_FORK, 0, + error = xchk_parent_count_parent_dentries(sc, dp, &nlink); + if (!xchk_fblock_xref_process_error(sc, XFS_DATA_FORK, 0, &error)) goto out_unlock; if (nlink != expected_nlink) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); goto out_unlock; } @@ -200,18 +200,18 @@ xfs_scrub_parent_validate( */ xfs_iunlock(sc->ip, sc->ilock_flags); sc->ilock_flags = 0; - error = xfs_scrub_ilock_inverted(dp, XFS_IOLOCK_SHARED); + error = xchk_ilock_inverted(dp, XFS_IOLOCK_SHARED); if (error) goto out_rele; /* Go looking for our dentry. */ - error = xfs_scrub_parent_count_parent_dentries(sc, dp, &nlink); - if (!xfs_scrub_fblock_xref_process_error(sc, XFS_DATA_FORK, 0, &error)) + error = xchk_parent_count_parent_dentries(sc, dp, &nlink); + if (!xchk_fblock_xref_process_error(sc, XFS_DATA_FORK, 0, &error)) goto out_unlock; /* Drop the parent lock, relock this inode. */ xfs_iunlock(dp, XFS_IOLOCK_SHARED); - error = xfs_scrub_ilock_inverted(sc->ip, XFS_IOLOCK_EXCL); + error = xchk_ilock_inverted(sc->ip, XFS_IOLOCK_EXCL); if (error) goto out_rele; sc->ilock_flags = XFS_IOLOCK_EXCL; @@ -225,7 +225,7 @@ xfs_scrub_parent_validate( /* Look up '..' to see if the inode changed. */ error = xfs_dir_lookup(sc->tp, sc->ip, &xfs_name_dotdot, &dnum, NULL); - if (!xfs_scrub_fblock_process_error(sc, XFS_DATA_FORK, 0, &error)) + if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error)) goto out_rele; /* Drat, parent changed. Try again! */ @@ -241,7 +241,7 @@ xfs_scrub_parent_validate( * for us in the parent. */ if (nlink != expected_nlink) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); return error; out_unlock: @@ -254,7 +254,7 @@ out: /* Scrub a parent pointer. */ int -xfs_scrub_parent( +xchk_parent( struct xfs_scrub_context *sc) { struct xfs_mount *mp = sc->mp; @@ -272,7 +272,7 @@ xfs_scrub_parent( /* We're not a special inode, are we? */ if (!xfs_verify_dir_ino(mp, sc->ip->i_ino)) { - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); goto out; } @@ -288,10 +288,10 @@ xfs_scrub_parent( /* Look up '..' */ error = xfs_dir_lookup(sc->tp, sc->ip, &xfs_name_dotdot, &dnum, NULL); - if (!xfs_scrub_fblock_process_error(sc, XFS_DATA_FORK, 0, &error)) + if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error)) goto out; if (!xfs_verify_dir_ino(mp, dnum)) { - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); goto out; } @@ -299,12 +299,12 @@ xfs_scrub_parent( if (sc->ip == mp->m_rootip) { if (sc->ip->i_ino != mp->m_sb.sb_rootino || sc->ip->i_ino != dnum) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); goto out; } do { - error = xfs_scrub_parent_validate(sc, dnum, &try_again); + error = xchk_parent_validate(sc, dnum, &try_again); if (error) goto out; } while (try_again && ++tries < 20); @@ -314,7 +314,7 @@ xfs_scrub_parent( * incomplete. Userspace can decide if it wants to try again. */ if (try_again && tries == 20) - xfs_scrub_set_incomplete(sc); + xchk_set_incomplete(sc); out: /* * If we failed to lock the parent inode even after a retry, just mark @@ -322,7 +322,7 @@ out: */ if (sc->try_harder && error == -EDEADLOCK) { error = 0; - xfs_scrub_set_incomplete(sc); + xchk_set_incomplete(sc); } return error; } diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c index 6ff906aa0a3b..d1b52dd7efcd 100644 --- a/fs/xfs/scrub/quota.c +++ b/fs/xfs/scrub/quota.c @@ -30,7 +30,7 @@ /* Convert a scrub type code to a DQ flag, or return 0 if error. */ static inline uint -xfs_scrub_quota_to_dqtype( +xchk_quota_to_dqtype( struct xfs_scrub_context *sc) { switch (sc->sm->sm_type) { @@ -47,7 +47,7 @@ xfs_scrub_quota_to_dqtype( /* Set us up to scrub a quota. */ int -xfs_scrub_setup_quota( +xchk_setup_quota( struct xfs_scrub_context *sc, struct xfs_inode *ip) { @@ -57,14 +57,14 @@ xfs_scrub_setup_quota( if (!XFS_IS_QUOTA_RUNNING(sc->mp) || !XFS_IS_QUOTA_ON(sc->mp)) return -ENOENT; - dqtype = xfs_scrub_quota_to_dqtype(sc); + dqtype = xchk_quota_to_dqtype(sc); if (dqtype == 0) return -EINVAL; sc->has_quotaofflock = true; mutex_lock(&sc->mp->m_quotainfo->qi_quotaofflock); if (!xfs_this_quota_on(sc->mp, dqtype)) return -ENOENT; - error = xfs_scrub_setup_fs(sc, ip); + error = xchk_setup_fs(sc, ip); if (error) return error; sc->ip = xfs_quota_inode(sc->mp, dqtype); @@ -75,19 +75,19 @@ xfs_scrub_setup_quota( /* Quotas. */ -struct xfs_scrub_quota_info { +struct xchk_quota_info { struct xfs_scrub_context *sc; xfs_dqid_t last_id; }; /* Scrub the fields in an individual quota item. */ STATIC int -xfs_scrub_quota_item( +xchk_quota_item( struct xfs_dquot *dq, uint dqtype, void *priv) { - struct xfs_scrub_quota_info *sqi = priv; + struct xchk_quota_info *sqi = priv; struct xfs_scrub_context *sc = sqi->sc; struct xfs_mount *mp = sc->mp; struct xfs_disk_dquot *d = &dq->q_core; @@ -111,16 +111,16 @@ xfs_scrub_quota_item( */ offset = id / qi->qi_dqperchunk; if (id && id <= sqi->last_id) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); sqi->last_id = id; /* Did we get the dquot type we wanted? */ if (dqtype != (d->d_flags & XFS_DQ_ALLTYPES)) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0)) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); /* Check the limits. */ bhard = be64_to_cpu(d->d_blk_hardlimit); @@ -140,19 +140,19 @@ xfs_scrub_quota_item( * the hard limit. */ if (bhard > mp->m_sb.sb_dblocks) - xfs_scrub_fblock_set_warning(sc, XFS_DATA_FORK, offset); + xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); if (bsoft > bhard) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); if (ihard > mp->m_maxicount) - xfs_scrub_fblock_set_warning(sc, XFS_DATA_FORK, offset); + xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); if (isoft > ihard) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); if (rhard > mp->m_sb.sb_rblocks) - xfs_scrub_fblock_set_warning(sc, XFS_DATA_FORK, offset); + xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); if (rsoft > rhard) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); /* Check the resource counts. */ bcount = be64_to_cpu(d->d_bcount); @@ -167,15 +167,15 @@ xfs_scrub_quota_item( */ if (xfs_sb_version_hasreflink(&mp->m_sb)) { if (mp->m_sb.sb_dblocks < bcount) - xfs_scrub_fblock_set_warning(sc, XFS_DATA_FORK, + xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); } else { if (mp->m_sb.sb_dblocks < bcount) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); } if (icount > fs_icount || rcount > mp->m_sb.sb_rblocks) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset); /* * We can violate the hard limits if the admin suddenly sets a @@ -183,18 +183,18 @@ xfs_scrub_quota_item( * admin review. */ if (id != 0 && bhard != 0 && bcount > bhard) - xfs_scrub_fblock_set_warning(sc, XFS_DATA_FORK, offset); + xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); if (id != 0 && ihard != 0 && icount > ihard) - xfs_scrub_fblock_set_warning(sc, XFS_DATA_FORK, offset); + xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); if (id != 0 && rhard != 0 && rcount > rhard) - xfs_scrub_fblock_set_warning(sc, XFS_DATA_FORK, offset); + xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); return 0; } /* Check the quota's data fork. */ STATIC int -xfs_scrub_quota_data_fork( +xchk_quota_data_fork( struct xfs_scrub_context *sc) { struct xfs_bmbt_irec irec = { 0 }; @@ -205,7 +205,7 @@ xfs_scrub_quota_data_fork( int error = 0; /* Invoke the fork scrubber. */ - error = xfs_scrub_metadata_inode_forks(sc); + error = xchk_metadata_inode_forks(sc); if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) return error; @@ -213,7 +213,7 @@ xfs_scrub_quota_data_fork( max_dqid_off = ((xfs_dqid_t)-1) / qi->qi_dqperchunk; ifp = XFS_IFORK_PTR(sc->ip, XFS_DATA_FORK); for_each_xfs_iext(ifp, &icur, &irec) { - if (xfs_scrub_should_terminate(sc, &error)) + if (xchk_should_terminate(sc, &error)) break; /* * delalloc extents or blocks mapped above the highest @@ -222,7 +222,7 @@ xfs_scrub_quota_data_fork( if (isnullstartblock(irec.br_startblock) || irec.br_startoff > max_dqid_off || irec.br_startoff + irec.br_blockcount - 1 > max_dqid_off) { - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, irec.br_startoff); break; } @@ -233,19 +233,19 @@ xfs_scrub_quota_data_fork( /* Scrub all of a quota type's items. */ int -xfs_scrub_quota( +xchk_quota( struct xfs_scrub_context *sc) { - struct xfs_scrub_quota_info sqi; + struct xchk_quota_info sqi; struct xfs_mount *mp = sc->mp; struct xfs_quotainfo *qi = mp->m_quotainfo; uint dqtype; int error = 0; - dqtype = xfs_scrub_quota_to_dqtype(sc); + dqtype = xchk_quota_to_dqtype(sc); /* Look for problem extents. */ - error = xfs_scrub_quota_data_fork(sc); + error = xchk_quota_data_fork(sc); if (error) goto out; if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) @@ -260,10 +260,10 @@ xfs_scrub_quota( sc->ilock_flags = 0; sqi.sc = sc; sqi.last_id = 0; - error = xfs_qm_dqiterate(mp, dqtype, xfs_scrub_quota_item, &sqi); + error = xfs_qm_dqiterate(mp, dqtype, xchk_quota_item, &sqi); sc->ilock_flags = XFS_ILOCK_EXCL; xfs_ilock(sc->ip, sc->ilock_flags); - if (!xfs_scrub_fblock_process_error(sc, XFS_DATA_FORK, + if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, sqi.last_id * qi->qi_dqperchunk, &error)) goto out; diff --git a/fs/xfs/scrub/refcount.c b/fs/xfs/scrub/refcount.c index 607a9faa8ecc..274febc49b23 100644 --- a/fs/xfs/scrub/refcount.c +++ b/fs/xfs/scrub/refcount.c @@ -28,11 +28,11 @@ * Set us up to scrub reference count btrees. */ int -xfs_scrub_setup_ag_refcountbt( +xchk_setup_ag_refcountbt( struct xfs_scrub_context *sc, struct xfs_inode *ip) { - return xfs_scrub_setup_ag_btree(sc, ip, false); + return xchk_setup_ag_btree(sc, ip, false); } /* Reference count btree scrubber. */ @@ -73,12 +73,12 @@ xfs_scrub_setup_ag_refcountbt( * If the refcount is correct, all the check conditions in the algorithm * should always hold true. If not, the refcount is incorrect. */ -struct xfs_scrub_refcnt_frag { +struct xchk_refcnt_frag { struct list_head list; struct xfs_rmap_irec rm; }; -struct xfs_scrub_refcnt_check { +struct xchk_refcnt_check { struct xfs_scrub_context *sc; struct list_head fragments; @@ -99,18 +99,18 @@ struct xfs_scrub_refcnt_check { * fragments as the refcountbt says we should have. */ STATIC int -xfs_scrub_refcountbt_rmap_check( +xchk_refcountbt_rmap_check( struct xfs_btree_cur *cur, struct xfs_rmap_irec *rec, void *priv) { - struct xfs_scrub_refcnt_check *refchk = priv; - struct xfs_scrub_refcnt_frag *frag; + struct xchk_refcnt_check *refchk = priv; + struct xchk_refcnt_frag *frag; xfs_agblock_t rm_last; xfs_agblock_t rc_last; int error = 0; - if (xfs_scrub_should_terminate(refchk->sc, &error)) + if (xchk_should_terminate(refchk->sc, &error)) return error; rm_last = rec->rm_startblock + rec->rm_blockcount - 1; @@ -118,7 +118,7 @@ xfs_scrub_refcountbt_rmap_check( /* Confirm that a single-owner refc extent is a CoW stage. */ if (refchk->refcount == 1 && rec->rm_owner != XFS_RMAP_OWN_COW) { - xfs_scrub_btree_xref_set_corrupt(refchk->sc, cur, 0); + xchk_btree_xref_set_corrupt(refchk->sc, cur, 0); return 0; } @@ -135,7 +135,7 @@ xfs_scrub_refcountbt_rmap_check( * is healthy each rmap_irec we see will be in agbno order * so we don't need insertion sort here. */ - frag = kmem_alloc(sizeof(struct xfs_scrub_refcnt_frag), + frag = kmem_alloc(sizeof(struct xchk_refcnt_frag), KM_MAYFAIL); if (!frag) return -ENOMEM; @@ -154,12 +154,12 @@ xfs_scrub_refcountbt_rmap_check( * we have a refcountbt error. */ STATIC void -xfs_scrub_refcountbt_process_rmap_fragments( - struct xfs_scrub_refcnt_check *refchk) +xchk_refcountbt_process_rmap_fragments( + struct xchk_refcnt_check *refchk) { struct list_head worklist; - struct xfs_scrub_refcnt_frag *frag; - struct xfs_scrub_refcnt_frag *n; + struct xchk_refcnt_frag *frag; + struct xchk_refcnt_frag *n; xfs_agblock_t bno; xfs_agblock_t rbno; xfs_agblock_t next_rbno; @@ -277,13 +277,13 @@ done: /* Use the rmap entries covering this extent to verify the refcount. */ STATIC void -xfs_scrub_refcountbt_xref_rmap( +xchk_refcountbt_xref_rmap( struct xfs_scrub_context *sc, xfs_agblock_t bno, xfs_extlen_t len, xfs_nlink_t refcount) { - struct xfs_scrub_refcnt_check refchk = { + struct xchk_refcnt_check refchk = { .sc = sc, .bno = bno, .len = len, @@ -292,11 +292,11 @@ xfs_scrub_refcountbt_xref_rmap( }; struct xfs_rmap_irec low; struct xfs_rmap_irec high; - struct xfs_scrub_refcnt_frag *frag; - struct xfs_scrub_refcnt_frag *n; + struct xchk_refcnt_frag *frag; + struct xchk_refcnt_frag *n; int error; - if (!sc->sa.rmap_cur || xfs_scrub_skip_xref(sc->sm)) + if (!sc->sa.rmap_cur || xchk_skip_xref(sc->sm)) return; /* Cross-reference with the rmapbt to confirm the refcount. */ @@ -307,13 +307,13 @@ xfs_scrub_refcountbt_xref_rmap( INIT_LIST_HEAD(&refchk.fragments); error = xfs_rmap_query_range(sc->sa.rmap_cur, &low, &high, - &xfs_scrub_refcountbt_rmap_check, &refchk); - if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.rmap_cur)) + &xchk_refcountbt_rmap_check, &refchk); + if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur)) goto out_free; - xfs_scrub_refcountbt_process_rmap_fragments(&refchk); + xchk_refcountbt_process_rmap_fragments(&refchk); if (refcount != refchk.seen) - xfs_scrub_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0); + xchk_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0); out_free: list_for_each_entry_safe(frag, n, &refchk.fragments, list) { @@ -324,7 +324,7 @@ out_free: /* Cross-reference with the other btrees. */ STATIC void -xfs_scrub_refcountbt_xref( +xchk_refcountbt_xref( struct xfs_scrub_context *sc, xfs_agblock_t agbno, xfs_extlen_t len, @@ -333,15 +333,15 @@ xfs_scrub_refcountbt_xref( if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) return; - xfs_scrub_xref_is_used_space(sc, agbno, len); - xfs_scrub_xref_is_not_inode_chunk(sc, agbno, len); - xfs_scrub_refcountbt_xref_rmap(sc, agbno, len, refcount); + xchk_xref_is_used_space(sc, agbno, len); + xchk_xref_is_not_inode_chunk(sc, agbno, len); + xchk_refcountbt_xref_rmap(sc, agbno, len, refcount); } /* Scrub a refcountbt record. */ STATIC int -xfs_scrub_refcountbt_rec( - struct xfs_scrub_btree *bs, +xchk_refcountbt_rec( + struct xchk_btree *bs, union xfs_btree_rec *rec) { struct xfs_mount *mp = bs->cur->bc_mp; @@ -360,7 +360,7 @@ xfs_scrub_refcountbt_rec( /* Only CoW records can have refcount == 1. */ has_cowflag = (bno & XFS_REFC_COW_START); if ((refcount == 1 && !has_cowflag) || (refcount != 1 && has_cowflag)) - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); if (has_cowflag) (*cow_blocks) += len; @@ -369,19 +369,19 @@ xfs_scrub_refcountbt_rec( if (bno + len <= bno || !xfs_verify_agbno(mp, agno, bno) || !xfs_verify_agbno(mp, agno, bno + len - 1)) - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); if (refcount == 0) - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); - xfs_scrub_refcountbt_xref(bs->sc, bno, len, refcount); + xchk_refcountbt_xref(bs->sc, bno, len, refcount); return error; } /* Make sure we have as many refc blocks as the rmap says. */ STATIC void -xfs_scrub_refcount_xref_rmap( +xchk_refcount_xref_rmap( struct xfs_scrub_context *sc, struct xfs_owner_info *oinfo, xfs_filblks_t cow_blocks) @@ -390,33 +390,33 @@ xfs_scrub_refcount_xref_rmap( xfs_filblks_t blocks; int error; - if (!sc->sa.rmap_cur || xfs_scrub_skip_xref(sc->sm)) + if (!sc->sa.rmap_cur || xchk_skip_xref(sc->sm)) return; /* Check that we saw as many refcbt blocks as the rmap knows about. */ error = xfs_btree_count_blocks(sc->sa.refc_cur, &refcbt_blocks); - if (!xfs_scrub_btree_process_error(sc, sc->sa.refc_cur, 0, &error)) + if (!xchk_btree_process_error(sc, sc->sa.refc_cur, 0, &error)) return; - error = xfs_scrub_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur, oinfo, + error = xchk_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur, oinfo, &blocks); - if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.rmap_cur)) + if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur)) return; if (blocks != refcbt_blocks) - xfs_scrub_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0); + xchk_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0); /* Check that we saw as many cow blocks as the rmap knows about. */ xfs_rmap_ag_owner(oinfo, XFS_RMAP_OWN_COW); - error = xfs_scrub_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur, oinfo, + error = xchk_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur, oinfo, &blocks); - if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.rmap_cur)) + if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur)) return; if (blocks != cow_blocks) - xfs_scrub_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0); + xchk_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0); } /* Scrub the refcount btree for some AG. */ int -xfs_scrub_refcountbt( +xchk_refcountbt( struct xfs_scrub_context *sc) { struct xfs_owner_info oinfo; @@ -424,19 +424,19 @@ xfs_scrub_refcountbt( int error; xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_REFC); - error = xfs_scrub_btree(sc, sc->sa.refc_cur, xfs_scrub_refcountbt_rec, + error = xchk_btree(sc, sc->sa.refc_cur, xchk_refcountbt_rec, &oinfo, &cow_blocks); if (error) return error; - xfs_scrub_refcount_xref_rmap(sc, &oinfo, cow_blocks); + xchk_refcount_xref_rmap(sc, &oinfo, cow_blocks); return 0; } /* xref check that a cow staging extent is marked in the refcountbt. */ void -xfs_scrub_xref_is_cow_staging( +xchk_xref_is_cow_staging( struct xfs_scrub_context *sc, xfs_agblock_t agbno, xfs_extlen_t len) @@ -446,35 +446,35 @@ xfs_scrub_xref_is_cow_staging( int has_refcount; int error; - if (!sc->sa.refc_cur || xfs_scrub_skip_xref(sc->sm)) + if (!sc->sa.refc_cur || xchk_skip_xref(sc->sm)) return; /* Find the CoW staging extent. */ error = xfs_refcount_lookup_le(sc->sa.refc_cur, agbno + XFS_REFC_COW_START, &has_refcount); - if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.refc_cur)) + if (!xchk_should_check_xref(sc, &error, &sc->sa.refc_cur)) return; if (!has_refcount) { - xfs_scrub_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0); + xchk_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0); return; } error = xfs_refcount_get_rec(sc->sa.refc_cur, &rc, &has_refcount); - if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.refc_cur)) + if (!xchk_should_check_xref(sc, &error, &sc->sa.refc_cur)) return; if (!has_refcount) { - xfs_scrub_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0); + xchk_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0); return; } /* CoW flag must be set, refcount must be 1. */ has_cowflag = (rc.rc_startblock & XFS_REFC_COW_START); if (!has_cowflag || rc.rc_refcount != 1) - xfs_scrub_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0); + xchk_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0); /* Must be at least as long as what was passed in */ if (rc.rc_blockcount < len) - xfs_scrub_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0); + xchk_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0); } /* @@ -482,7 +482,7 @@ xfs_scrub_xref_is_cow_staging( * can have multiple owners. */ void -xfs_scrub_xref_is_not_shared( +xchk_xref_is_not_shared( struct xfs_scrub_context *sc, xfs_agblock_t agbno, xfs_extlen_t len) @@ -490,12 +490,12 @@ xfs_scrub_xref_is_not_shared( bool shared; int error; - if (!sc->sa.refc_cur || xfs_scrub_skip_xref(sc->sm)) + if (!sc->sa.refc_cur || xchk_skip_xref(sc->sm)) return; error = xfs_refcount_has_record(sc->sa.refc_cur, agbno, len, &shared); - if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.refc_cur)) + if (!xchk_should_check_xref(sc, &error, &sc->sa.refc_cur)) return; if (shared) - xfs_scrub_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0); + xchk_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0); } diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index ea39e2bdc96a..5eccd89c64a8 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -50,7 +50,7 @@ xfs_repair_attempt( trace_xfs_repair_attempt(ip, sc->sm, error); - xfs_scrub_ag_btcur_free(&sc->sa); + xchk_ag_btcur_free(&sc->sa); /* Repair whatever's broken. */ ASSERT(sc->ops->repair); @@ -110,7 +110,7 @@ xfs_repair_probe( { int error = 0; - if (xfs_scrub_should_terminate(sc, &error)) + if (xchk_should_terminate(sc, &error)) return error; return 0; diff --git a/fs/xfs/scrub/rmap.c b/fs/xfs/scrub/rmap.c index c6d763236ba7..4b75fc2f31f3 100644 --- a/fs/xfs/scrub/rmap.c +++ b/fs/xfs/scrub/rmap.c @@ -29,18 +29,18 @@ * Set us up to scrub reverse mapping btrees. */ int -xfs_scrub_setup_ag_rmapbt( +xchk_setup_ag_rmapbt( struct xfs_scrub_context *sc, struct xfs_inode *ip) { - return xfs_scrub_setup_ag_btree(sc, ip, false); + return xchk_setup_ag_btree(sc, ip, false); } /* Reverse-mapping scrubber. */ /* Cross-reference a rmap against the refcount btree. */ STATIC void -xfs_scrub_rmapbt_xref_refc( +xchk_rmapbt_xref_refc( struct xfs_scrub_context *sc, struct xfs_rmap_irec *irec) { @@ -52,7 +52,7 @@ xfs_scrub_rmapbt_xref_refc( bool is_unwritten; int error; - if (!sc->sa.refc_cur || xfs_scrub_skip_xref(sc->sm)) + if (!sc->sa.refc_cur || xchk_skip_xref(sc->sm)) return; non_inode = XFS_RMAP_NON_INODE_OWNER(irec->rm_owner); @@ -63,15 +63,15 @@ xfs_scrub_rmapbt_xref_refc( /* If this is shared, must be a data fork extent. */ error = xfs_refcount_find_shared(sc->sa.refc_cur, irec->rm_startblock, irec->rm_blockcount, &fbno, &flen, false); - if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.refc_cur)) + if (!xchk_should_check_xref(sc, &error, &sc->sa.refc_cur)) return; if (flen != 0 && (non_inode || is_attr || is_bmbt || is_unwritten)) - xfs_scrub_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0); + xchk_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0); } /* Cross-reference with the other btrees. */ STATIC void -xfs_scrub_rmapbt_xref( +xchk_rmapbt_xref( struct xfs_scrub_context *sc, struct xfs_rmap_irec *irec) { @@ -81,22 +81,22 @@ xfs_scrub_rmapbt_xref( if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) return; - xfs_scrub_xref_is_used_space(sc, agbno, len); + xchk_xref_is_used_space(sc, agbno, len); if (irec->rm_owner == XFS_RMAP_OWN_INODES) - xfs_scrub_xref_is_inode_chunk(sc, agbno, len); + xchk_xref_is_inode_chunk(sc, agbno, len); else - xfs_scrub_xref_is_not_inode_chunk(sc, agbno, len); + xchk_xref_is_not_inode_chunk(sc, agbno, len); if (irec->rm_owner == XFS_RMAP_OWN_COW) - xfs_scrub_xref_is_cow_staging(sc, irec->rm_startblock, + xchk_xref_is_cow_staging(sc, irec->rm_startblock, irec->rm_blockcount); else - xfs_scrub_rmapbt_xref_refc(sc, irec); + xchk_rmapbt_xref_refc(sc, irec); } /* Scrub an rmapbt record. */ STATIC int -xfs_scrub_rmapbt_rec( - struct xfs_scrub_btree *bs, +xchk_rmapbt_rec( + struct xchk_btree *bs, union xfs_btree_rec *rec) { struct xfs_mount *mp = bs->cur->bc_mp; @@ -109,12 +109,12 @@ xfs_scrub_rmapbt_rec( int error; error = xfs_rmap_btrec_to_irec(rec, &irec); - if (!xfs_scrub_btree_process_error(bs->sc, bs->cur, 0, &error)) + if (!xchk_btree_process_error(bs->sc, bs->cur, 0, &error)) goto out; /* Check extent. */ if (irec.rm_startblock + irec.rm_blockcount <= irec.rm_startblock) - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); if (irec.rm_owner == XFS_RMAP_OWN_FS) { /* @@ -124,7 +124,7 @@ xfs_scrub_rmapbt_rec( */ if (irec.rm_startblock != 0 || irec.rm_blockcount != XFS_AGFL_BLOCK(mp) + 1) - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); } else { /* * Otherwise we must point somewhere past the static metadata @@ -133,7 +133,7 @@ xfs_scrub_rmapbt_rec( if (!xfs_verify_agbno(mp, agno, irec.rm_startblock) || !xfs_verify_agbno(mp, agno, irec.rm_startblock + irec.rm_blockcount - 1)) - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); } /* Check flags. */ @@ -143,47 +143,47 @@ xfs_scrub_rmapbt_rec( is_unwritten = irec.rm_flags & XFS_RMAP_UNWRITTEN; if (is_bmbt && irec.rm_offset != 0) - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); if (non_inode && irec.rm_offset != 0) - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); if (is_unwritten && (is_bmbt || non_inode || is_attr)) - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); if (non_inode && (is_bmbt || is_unwritten || is_attr)) - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); if (!non_inode) { if (!xfs_verify_ino(mp, irec.rm_owner)) - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); } else { /* Non-inode owner within the magic values? */ if (irec.rm_owner <= XFS_RMAP_OWN_MIN || irec.rm_owner > XFS_RMAP_OWN_FS) - xfs_scrub_btree_set_corrupt(bs->sc, bs->cur, 0); + xchk_btree_set_corrupt(bs->sc, bs->cur, 0); } - xfs_scrub_rmapbt_xref(bs->sc, &irec); + xchk_rmapbt_xref(bs->sc, &irec); out: return error; } /* Scrub the rmap btree for some AG. */ int -xfs_scrub_rmapbt( +xchk_rmapbt( struct xfs_scrub_context *sc) { struct xfs_owner_info oinfo; xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_AG); - return xfs_scrub_btree(sc, sc->sa.rmap_cur, xfs_scrub_rmapbt_rec, + return xchk_btree(sc, sc->sa.rmap_cur, xchk_rmapbt_rec, &oinfo, NULL); } /* xref check that the extent is owned by a given owner */ static inline void -xfs_scrub_xref_check_owner( +xchk_xref_check_owner( struct xfs_scrub_context *sc, xfs_agblock_t bno, xfs_extlen_t len, @@ -193,42 +193,42 @@ xfs_scrub_xref_check_owner( bool has_rmap; int error; - if (!sc->sa.rmap_cur || xfs_scrub_skip_xref(sc->sm)) + if (!sc->sa.rmap_cur || xchk_skip_xref(sc->sm)) return; error = xfs_rmap_record_exists(sc->sa.rmap_cur, bno, len, oinfo, &has_rmap); - if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.rmap_cur)) + if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur)) return; if (has_rmap != should_have_rmap) - xfs_scrub_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0); + xchk_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0); } /* xref check that the extent is owned by a given owner */ void -xfs_scrub_xref_is_owned_by( +xchk_xref_is_owned_by( struct xfs_scrub_context *sc, xfs_agblock_t bno, xfs_extlen_t len, struct xfs_owner_info *oinfo) { - xfs_scrub_xref_check_owner(sc, bno, len, oinfo, true); + xchk_xref_check_owner(sc, bno, len, oinfo, true); } /* xref check that the extent is not owned by a given owner */ void -xfs_scrub_xref_is_not_owned_by( +xchk_xref_is_not_owned_by( struct xfs_scrub_context *sc, xfs_agblock_t bno, xfs_extlen_t len, struct xfs_owner_info *oinfo) { - xfs_scrub_xref_check_owner(sc, bno, len, oinfo, false); + xchk_xref_check_owner(sc, bno, len, oinfo, false); } /* xref check that the extent has no reverse mapping at all */ void -xfs_scrub_xref_has_no_owner( +xchk_xref_has_no_owner( struct xfs_scrub_context *sc, xfs_agblock_t bno, xfs_extlen_t len) @@ -236,12 +236,12 @@ xfs_scrub_xref_has_no_owner( bool has_rmap; int error; - if (!sc->sa.rmap_cur || xfs_scrub_skip_xref(sc->sm)) + if (!sc->sa.rmap_cur || xchk_skip_xref(sc->sm)) return; error = xfs_rmap_has_record(sc->sa.rmap_cur, bno, len, &has_rmap); - if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.rmap_cur)) + if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur)) return; if (has_rmap) - xfs_scrub_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0); + xchk_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0); } diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c index 1f86e02a07ca..3f0fc83562ae 100644 --- a/fs/xfs/scrub/rtbitmap.c +++ b/fs/xfs/scrub/rtbitmap.c @@ -25,13 +25,13 @@ /* Set us up with the realtime metadata locked. */ int -xfs_scrub_setup_rt( +xchk_setup_rt( struct xfs_scrub_context *sc, struct xfs_inode *ip) { int error; - error = xfs_scrub_setup_fs(sc, ip); + error = xchk_setup_fs(sc, ip); if (error) return error; @@ -46,7 +46,7 @@ xfs_scrub_setup_rt( /* Scrub a free extent record from the realtime bitmap. */ STATIC int -xfs_scrub_rtbitmap_rec( +xchk_rtbitmap_rec( struct xfs_trans *tp, struct xfs_rtalloc_rec *rec, void *priv) @@ -61,24 +61,24 @@ xfs_scrub_rtbitmap_rec( if (startblock + blockcount <= startblock || !xfs_verify_rtbno(sc->mp, startblock) || !xfs_verify_rtbno(sc->mp, startblock + blockcount - 1)) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); return 0; } /* Scrub the realtime bitmap. */ int -xfs_scrub_rtbitmap( +xchk_rtbitmap( struct xfs_scrub_context *sc) { int error; /* Invoke the fork scrubber. */ - error = xfs_scrub_metadata_inode_forks(sc); + error = xchk_metadata_inode_forks(sc); if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) return error; - error = xfs_rtalloc_query_all(sc->tp, xfs_scrub_rtbitmap_rec, sc); - if (!xfs_scrub_fblock_process_error(sc, XFS_DATA_FORK, 0, &error)) + error = xfs_rtalloc_query_all(sc->tp, xchk_rtbitmap_rec, sc); + if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error)) goto out; out: @@ -87,7 +87,7 @@ out: /* Scrub the realtime summary. */ int -xfs_scrub_rtsummary( +xchk_rtsummary( struct xfs_scrub_context *sc) { struct xfs_inode *rsumip = sc->mp->m_rsumip; @@ -107,12 +107,12 @@ xfs_scrub_rtsummary( xfs_ilock(sc->ip, sc->ilock_flags); /* Invoke the fork scrubber. */ - error = xfs_scrub_metadata_inode_forks(sc); + error = xchk_metadata_inode_forks(sc); if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) goto out; /* XXX: implement this some day */ - xfs_scrub_set_incomplete(sc); + xchk_set_incomplete(sc); out: /* Switch back to the rtbitmap inode and lock flags. */ xfs_iunlock(sc->ip, sc->ilock_flags); @@ -124,7 +124,7 @@ out: /* xref check that the extent is not free in the rtbitmap */ void -xfs_scrub_xref_is_used_rt_space( +xchk_xref_is_used_rt_space( struct xfs_scrub_context *sc, xfs_rtblock_t fsbno, xfs_extlen_t len) @@ -135,7 +135,7 @@ xfs_scrub_xref_is_used_rt_space( bool is_free; int error; - if (xfs_scrub_skip_xref(sc->sm)) + if (xchk_skip_xref(sc->sm)) return; startext = fsbno; @@ -147,10 +147,10 @@ xfs_scrub_xref_is_used_rt_space( xfs_ilock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP); error = xfs_rtalloc_extent_is_free(sc->mp, sc->tp, startext, extcount, &is_free); - if (!xfs_scrub_should_check_xref(sc, &error, NULL)) + if (!xchk_should_check_xref(sc, &error, NULL)) goto out_unlock; if (is_free) - xfs_scrub_ino_xref_set_corrupt(sc, sc->mp->m_rbmip->i_ino); + xchk_ino_xref_set_corrupt(sc, sc->mp->m_rbmip->i_ino); out_unlock: xfs_iunlock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP); } diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c index 58ae76b3a421..ead97ab91a3c 100644 --- a/fs/xfs/scrub/scrub.c +++ b/fs/xfs/scrub/scrub.c @@ -131,6 +131,12 @@ * optimize the structure so that the rebuild knows what to do. The * second check evaluates the completeness of the repair; that is what * is reported to userspace. + * + * A quick note on symbol prefixes: + * - "xfs_" are general XFS symbols. + * - "xchk_" are symbols related to metadata checking. + * - "xrep_" are symbols related to metadata repair. + * - "xfs_scrub_" are symbols that tie online fsck to the rest of XFS. */ /* @@ -144,12 +150,12 @@ * supported by the running kernel. */ static int -xfs_scrub_probe( +xchk_probe( struct xfs_scrub_context *sc) { int error = 0; - if (xfs_scrub_should_terminate(sc, &error)) + if (xchk_should_terminate(sc, &error)) return error; return 0; @@ -159,12 +165,12 @@ xfs_scrub_probe( /* Free all the resources and finish the transactions. */ STATIC int -xfs_scrub_teardown( +xchk_teardown( struct xfs_scrub_context *sc, struct xfs_inode *ip_in, int error) { - xfs_scrub_ag_free(sc, &sc->sa); + xchk_ag_free(sc, &sc->sa); if (sc->tp) { if (error == 0 && (sc->sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR)) error = xfs_trans_commit(sc->tp); @@ -191,165 +197,165 @@ xfs_scrub_teardown( /* Scrubbing dispatch. */ -static const struct xfs_scrub_meta_ops meta_scrub_ops[] = { +static const struct xchk_meta_ops meta_scrub_ops[] = { [XFS_SCRUB_TYPE_PROBE] = { /* ioctl presence test */ .type = ST_NONE, - .setup = xfs_scrub_setup_fs, - .scrub = xfs_scrub_probe, + .setup = xchk_setup_fs, + .scrub = xchk_probe, .repair = xfs_repair_probe, }, [XFS_SCRUB_TYPE_SB] = { /* superblock */ .type = ST_PERAG, - .setup = xfs_scrub_setup_fs, - .scrub = xfs_scrub_superblock, + .setup = xchk_setup_fs, + .scrub = xchk_superblock, .repair = xfs_repair_superblock, }, [XFS_SCRUB_TYPE_AGF] = { /* agf */ .type = ST_PERAG, - .setup = xfs_scrub_setup_fs, - .scrub = xfs_scrub_agf, + .setup = xchk_setup_fs, + .scrub = xchk_agf, .repair = xfs_repair_notsupported, }, [XFS_SCRUB_TYPE_AGFL]= { /* agfl */ .type = ST_PERAG, - .setup = xfs_scrub_setup_fs, - .scrub = xfs_scrub_agfl, + .setup = xchk_setup_fs, + .scrub = xchk_agfl, .repair = xfs_repair_notsupported, }, [XFS_SCRUB_TYPE_AGI] = { /* agi */ .type = ST_PERAG, - .setup = xfs_scrub_setup_fs, - .scrub = xfs_scrub_agi, + .setup = xchk_setup_fs, + .scrub = xchk_agi, .repair = xfs_repair_notsupported, }, [XFS_SCRUB_TYPE_BNOBT] = { /* bnobt */ .type = ST_PERAG, - .setup = xfs_scrub_setup_ag_allocbt, - .scrub = xfs_scrub_bnobt, + .setup = xchk_setup_ag_allocbt, + .scrub = xchk_bnobt, .repair = xfs_repair_notsupported, }, [XFS_SCRUB_TYPE_CNTBT] = { /* cntbt */ .type = ST_PERAG, - .setup = xfs_scrub_setup_ag_allocbt, - .scrub = xfs_scrub_cntbt, + .setup = xchk_setup_ag_allocbt, + .scrub = xchk_cntbt, .repair = xfs_repair_notsupported, }, [XFS_SCRUB_TYPE_INOBT] = { /* inobt */ .type = ST_PERAG, - .setup = xfs_scrub_setup_ag_iallocbt, - .scrub = xfs_scrub_inobt, + .setup = xchk_setup_ag_iallocbt, + .scrub = xchk_inobt, .repair = xfs_repair_notsupported, }, [XFS_SCRUB_TYPE_FINOBT] = { /* finobt */ .type = ST_PERAG, - .setup = xfs_scrub_setup_ag_iallocbt, - .scrub = xfs_scrub_finobt, + .setup = xchk_setup_ag_iallocbt, + .scrub = xchk_finobt, .has = xfs_sb_version_hasfinobt, .repair = xfs_repair_notsupported, }, [XFS_SCRUB_TYPE_RMAPBT] = { /* rmapbt */ .type = ST_PERAG, - .setup = xfs_scrub_setup_ag_rmapbt, - .scrub = xfs_scrub_rmapbt, + .setup = xchk_setup_ag_rmapbt, + .scrub = xchk_rmapbt, .has = xfs_sb_version_hasrmapbt, .repair = xfs_repair_notsupported, }, [XFS_SCRUB_TYPE_REFCNTBT] = { /* refcountbt */ .type = ST_PERAG, - .setup = xfs_scrub_setup_ag_refcountbt, - .scrub = xfs_scrub_refcountbt, + .setup = xchk_setup_ag_refcountbt, + .scrub = xchk_refcountbt, .has = xfs_sb_version_hasreflink, .repair = xfs_repair_notsupported, }, [XFS_SCRUB_TYPE_INODE] = { /* inode record */ .type = ST_INODE, - .setup = xfs_scrub_setup_inode, - .scrub = xfs_scrub_inode, + .setup = xchk_setup_inode, + .scrub = xchk_inode, .repair = xfs_repair_notsupported, }, [XFS_SCRUB_TYPE_BMBTD] = { /* inode data fork */ .type = ST_INODE, - .setup = xfs_scrub_setup_inode_bmap, - .scrub = xfs_scrub_bmap_data, + .setup = xchk_setup_inode_bmap, + .scrub = xchk_bmap_data, .repair = xfs_repair_notsupported, }, [XFS_SCRUB_TYPE_BMBTA] = { /* inode attr fork */ .type = ST_INODE, - .setup = xfs_scrub_setup_inode_bmap, - .scrub = xfs_scrub_bmap_attr, + .setup = xchk_setup_inode_bmap, + .scrub = xchk_bmap_attr, .repair = xfs_repair_notsupported, }, [XFS_SCRUB_TYPE_BMBTC] = { /* inode CoW fork */ .type = ST_INODE, - .setup = xfs_scrub_setup_inode_bmap, - .scrub = xfs_scrub_bmap_cow, + .setup = xchk_setup_inode_bmap, + .scrub = xchk_bmap_cow, .repair = xfs_repair_notsupported, }, [XFS_SCRUB_TYPE_DIR] = { /* directory */ .type = ST_INODE, - .setup = xfs_scrub_setup_directory, - .scrub = xfs_scrub_directory, + .setup = xchk_setup_directory, + .scrub = xchk_directory, .repair = xfs_repair_notsupported, }, [XFS_SCRUB_TYPE_XATTR] = { /* extended attributes */ .type = ST_INODE, - .setup = xfs_scrub_setup_xattr, - .scrub = xfs_scrub_xattr, + .setup = xchk_setup_xattr, + .scrub = xchk_xattr, .repair = xfs_repair_notsupported, }, [XFS_SCRUB_TYPE_SYMLINK] = { /* symbolic link */ .type = ST_INODE, - .setup = xfs_scrub_setup_symlink, - .scrub = xfs_scrub_symlink, + .setup = xchk_setup_symlink, + .scrub = xchk_symlink, .repair = xfs_repair_notsupported, }, [XFS_SCRUB_TYPE_PARENT] = { /* parent pointers */ .type = ST_INODE, - .setup = xfs_scrub_setup_parent, - .scrub = xfs_scrub_parent, + .setup = xchk_setup_parent, + .scrub = xchk_parent, .repair = xfs_repair_notsupported, }, [XFS_SCRUB_TYPE_RTBITMAP] = { /* realtime bitmap */ .type = ST_FS, - .setup = xfs_scrub_setup_rt, - .scrub = xfs_scrub_rtbitmap, + .setup = xchk_setup_rt, + .scrub = xchk_rtbitmap, .has = xfs_sb_version_hasrealtime, .repair = xfs_repair_notsupported, }, [XFS_SCRUB_TYPE_RTSUM] = { /* realtime summary */ .type = ST_FS, - .setup = xfs_scrub_setup_rt, - .scrub = xfs_scrub_rtsummary, + .setup = xchk_setup_rt, + .scrub = xchk_rtsummary, .has = xfs_sb_version_hasrealtime, .repair = xfs_repair_notsupported, }, [XFS_SCRUB_TYPE_UQUOTA] = { /* user quota */ .type = ST_FS, - .setup = xfs_scrub_setup_quota, - .scrub = xfs_scrub_quota, + .setup = xchk_setup_quota, + .scrub = xchk_quota, .repair = xfs_repair_notsupported, }, [XFS_SCRUB_TYPE_GQUOTA] = { /* group quota */ .type = ST_FS, - .setup = xfs_scrub_setup_quota, - .scrub = xfs_scrub_quota, + .setup = xchk_setup_quota, + .scrub = xchk_quota, .repair = xfs_repair_notsupported, }, [XFS_SCRUB_TYPE_PQUOTA] = { /* project quota */ .type = ST_FS, - .setup = xfs_scrub_setup_quota, - .scrub = xfs_scrub_quota, + .setup = xchk_setup_quota, + .scrub = xchk_quota, .repair = xfs_repair_notsupported, }, }; /* This isn't a stable feature, warn once per day. */ static inline void -xfs_scrub_experimental_warning( +xchk_experimental_warning( struct xfs_mount *mp) { static struct ratelimit_state scrub_warning = RATELIMIT_STATE_INIT( - "xfs_scrub_warning", 86400 * HZ, 1); + "xchk_warning", 86400 * HZ, 1); ratelimit_set_flags(&scrub_warning, RATELIMIT_MSG_ON_RELEASE); if (__ratelimit(&scrub_warning)) @@ -358,12 +364,12 @@ xfs_scrub_experimental_warning( } static int -xfs_scrub_validate_inputs( +xchk_validate_inputs( struct xfs_mount *mp, struct xfs_scrub_metadata *sm) { int error; - const struct xfs_scrub_meta_ops *ops; + const struct xchk_meta_ops *ops; error = -EINVAL; /* Check our inputs. */ @@ -441,7 +447,7 @@ out: } #ifdef CONFIG_XFS_ONLINE_REPAIR -static inline void xfs_scrub_postmortem(struct xfs_scrub_context *sc) +static inline void xchk_postmortem(struct xfs_scrub_context *sc) { /* * Userspace asked us to repair something, we repaired it, rescanned @@ -454,7 +460,7 @@ static inline void xfs_scrub_postmortem(struct xfs_scrub_context *sc) xfs_repair_failure(sc->mp); } #else -static inline void xfs_scrub_postmortem(struct xfs_scrub_context *sc) +static inline void xchk_postmortem(struct xfs_scrub_context *sc) { /* * Userspace asked us to scrub something, it's broken, and we have no @@ -480,9 +486,9 @@ xfs_scrub_metadata( int error = 0; BUILD_BUG_ON(sizeof(meta_scrub_ops) != - (sizeof(struct xfs_scrub_meta_ops) * XFS_SCRUB_TYPE_NR)); + (sizeof(struct xchk_meta_ops) * XFS_SCRUB_TYPE_NR)); - trace_xfs_scrub_start(ip, sm, error); + trace_xchk_start(ip, sm, error); /* Forbidden if we are shut down or mounted norecovery. */ error = -ESHUTDOWN; @@ -492,11 +498,11 @@ xfs_scrub_metadata( if (mp->m_flags & XFS_MOUNT_NORECOVERY) goto out; - error = xfs_scrub_validate_inputs(mp, sm); + error = xchk_validate_inputs(mp, sm); if (error) goto out; - xfs_scrub_experimental_warning(mp); + xchk_experimental_warning(mp); retry_op: /* Set up for the operation. */ @@ -518,7 +524,7 @@ retry_op: * Tear down everything we hold, then set up again with * preparation for worst-case scenarios. */ - error = xfs_scrub_teardown(&sc, ip, 0); + error = xchk_teardown(&sc, ip, 0); if (error) goto out; try_harder = true; @@ -553,7 +559,7 @@ retry_op: if (error == -EAGAIN) { if (sc.try_harder) try_harder = true; - error = xfs_scrub_teardown(&sc, ip, 0); + error = xchk_teardown(&sc, ip, 0); if (error) { xfs_repair_failure(mp); goto out; @@ -563,11 +569,11 @@ retry_op: } out_nofix: - xfs_scrub_postmortem(&sc); + xchk_postmortem(&sc); out_teardown: - error = xfs_scrub_teardown(&sc, ip, error); + error = xchk_teardown(&sc, ip, error); out: - trace_xfs_scrub_done(ip, sm, error); + trace_xchk_done(ip, sm, error); if (error == -EFSCORRUPTED || error == -EFSBADCRC) { sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT; error = 0; diff --git a/fs/xfs/scrub/scrub.h b/fs/xfs/scrub/scrub.h index b295edd5fc0e..0f59a47c4bb0 100644 --- a/fs/xfs/scrub/scrub.h +++ b/fs/xfs/scrub/scrub.h @@ -9,14 +9,14 @@ struct xfs_scrub_context; /* Type info and names for the scrub types. */ -enum xfs_scrub_type { +enum xchk_type { ST_NONE = 1, /* disabled */ ST_PERAG, /* per-AG metadata */ ST_FS, /* per-FS metadata */ ST_INODE, /* per-inode metadata */ }; -struct xfs_scrub_meta_ops { +struct xchk_meta_ops { /* Acquire whatever resources are needed for the operation. */ int (*setup)(struct xfs_scrub_context *, struct xfs_inode *); @@ -31,11 +31,11 @@ struct xfs_scrub_meta_ops { bool (*has)(struct xfs_sb *); /* type describing required/allowed inputs */ - enum xfs_scrub_type type; + enum xchk_type type; }; /* Buffer pointers and btree cursors for an entire AG. */ -struct xfs_scrub_ag { +struct xchk_ag { xfs_agnumber_t agno; struct xfs_perag *pag; @@ -57,7 +57,7 @@ struct xfs_scrub_context { /* General scrub state. */ struct xfs_mount *mp; struct xfs_scrub_metadata *sm; - const struct xfs_scrub_meta_ops *ops; + const struct xchk_meta_ops *ops; struct xfs_trans *tp; struct xfs_inode *ip; void *buf; @@ -66,78 +66,78 @@ struct xfs_scrub_context { bool has_quotaofflock; /* State tracking for single-AG operations. */ - struct xfs_scrub_ag sa; + struct xchk_ag sa; }; /* Metadata scrubbers */ -int xfs_scrub_tester(struct xfs_scrub_context *sc); -int xfs_scrub_superblock(struct xfs_scrub_context *sc); -int xfs_scrub_agf(struct xfs_scrub_context *sc); -int xfs_scrub_agfl(struct xfs_scrub_context *sc); -int xfs_scrub_agi(struct xfs_scrub_context *sc); -int xfs_scrub_bnobt(struct xfs_scrub_context *sc); -int xfs_scrub_cntbt(struct xfs_scrub_context *sc); -int xfs_scrub_inobt(struct xfs_scrub_context *sc); -int xfs_scrub_finobt(struct xfs_scrub_context *sc); -int xfs_scrub_rmapbt(struct xfs_scrub_context *sc); -int xfs_scrub_refcountbt(struct xfs_scrub_context *sc); -int xfs_scrub_inode(struct xfs_scrub_context *sc); -int xfs_scrub_bmap_data(struct xfs_scrub_context *sc); -int xfs_scrub_bmap_attr(struct xfs_scrub_context *sc); -int xfs_scrub_bmap_cow(struct xfs_scrub_context *sc); -int xfs_scrub_directory(struct xfs_scrub_context *sc); -int xfs_scrub_xattr(struct xfs_scrub_context *sc); -int xfs_scrub_symlink(struct xfs_scrub_context *sc); -int xfs_scrub_parent(struct xfs_scrub_context *sc); +int xchk_tester(struct xfs_scrub_context *sc); +int xchk_superblock(struct xfs_scrub_context *sc); +int xchk_agf(struct xfs_scrub_context *sc); +int xchk_agfl(struct xfs_scrub_context *sc); +int xchk_agi(struct xfs_scrub_context *sc); +int xchk_bnobt(struct xfs_scrub_context *sc); +int xchk_cntbt(struct xfs_scrub_context *sc); +int xchk_inobt(struct xfs_scrub_context *sc); +int xchk_finobt(struct xfs_scrub_context *sc); +int xchk_rmapbt(struct xfs_scrub_context *sc); +int xchk_refcountbt(struct xfs_scrub_context *sc); +int xchk_inode(struct xfs_scrub_context *sc); +int xchk_bmap_data(struct xfs_scrub_context *sc); +int xchk_bmap_attr(struct xfs_scrub_context *sc); +int xchk_bmap_cow(struct xfs_scrub_context *sc); +int xchk_directory(struct xfs_scrub_context *sc); +int xchk_xattr(struct xfs_scrub_context *sc); +int xchk_symlink(struct xfs_scrub_context *sc); +int xchk_parent(struct xfs_scrub_context *sc); #ifdef CONFIG_XFS_RT -int xfs_scrub_rtbitmap(struct xfs_scrub_context *sc); -int xfs_scrub_rtsummary(struct xfs_scrub_context *sc); +int xchk_rtbitmap(struct xfs_scrub_context *sc); +int xchk_rtsummary(struct xfs_scrub_context *sc); #else static inline int -xfs_scrub_rtbitmap(struct xfs_scrub_context *sc) +xchk_rtbitmap(struct xfs_scrub_context *sc) { return -ENOENT; } static inline int -xfs_scrub_rtsummary(struct xfs_scrub_context *sc) +xchk_rtsummary(struct xfs_scrub_context *sc) { return -ENOENT; } #endif #ifdef CONFIG_XFS_QUOTA -int xfs_scrub_quota(struct xfs_scrub_context *sc); +int xchk_quota(struct xfs_scrub_context *sc); #else static inline int -xfs_scrub_quota(struct xfs_scrub_context *sc) +xchk_quota(struct xfs_scrub_context *sc) { return -ENOENT; } #endif /* cross-referencing helpers */ -void xfs_scrub_xref_is_used_space(struct xfs_scrub_context *sc, +void xchk_xref_is_used_space(struct xfs_scrub_context *sc, xfs_agblock_t agbno, xfs_extlen_t len); -void xfs_scrub_xref_is_not_inode_chunk(struct xfs_scrub_context *sc, +void xchk_xref_is_not_inode_chunk(struct xfs_scrub_context *sc, xfs_agblock_t agbno, xfs_extlen_t len); -void xfs_scrub_xref_is_inode_chunk(struct xfs_scrub_context *sc, +void xchk_xref_is_inode_chunk(struct xfs_scrub_context *sc, xfs_agblock_t agbno, xfs_extlen_t len); -void xfs_scrub_xref_is_owned_by(struct xfs_scrub_context *sc, +void xchk_xref_is_owned_by(struct xfs_scrub_context *sc, xfs_agblock_t agbno, xfs_extlen_t len, struct xfs_owner_info *oinfo); -void xfs_scrub_xref_is_not_owned_by(struct xfs_scrub_context *sc, +void xchk_xref_is_not_owned_by(struct xfs_scrub_context *sc, xfs_agblock_t agbno, xfs_extlen_t len, struct xfs_owner_info *oinfo); -void xfs_scrub_xref_has_no_owner(struct xfs_scrub_context *sc, +void xchk_xref_has_no_owner(struct xfs_scrub_context *sc, xfs_agblock_t agbno, xfs_extlen_t len); -void xfs_scrub_xref_is_cow_staging(struct xfs_scrub_context *sc, +void xchk_xref_is_cow_staging(struct xfs_scrub_context *sc, xfs_agblock_t bno, xfs_extlen_t len); -void xfs_scrub_xref_is_not_shared(struct xfs_scrub_context *sc, +void xchk_xref_is_not_shared(struct xfs_scrub_context *sc, xfs_agblock_t bno, xfs_extlen_t len); #ifdef CONFIG_XFS_RT -void xfs_scrub_xref_is_used_rt_space(struct xfs_scrub_context *sc, +void xchk_xref_is_used_rt_space(struct xfs_scrub_context *sc, xfs_rtblock_t rtbno, xfs_extlen_t len); #else -# define xfs_scrub_xref_is_used_rt_space(sc, rtbno, len) do { } while (0) +# define xchk_xref_is_used_rt_space(sc, rtbno, len) do { } while (0) #endif #endif /* __XFS_SCRUB_SCRUB_H__ */ diff --git a/fs/xfs/scrub/symlink.c b/fs/xfs/scrub/symlink.c index 570a89812116..e2a288e34337 100644 --- a/fs/xfs/scrub/symlink.c +++ b/fs/xfs/scrub/symlink.c @@ -25,7 +25,7 @@ /* Set us up to scrub a symbolic link. */ int -xfs_scrub_setup_symlink( +xchk_setup_symlink( struct xfs_scrub_context *sc, struct xfs_inode *ip) { @@ -34,13 +34,13 @@ xfs_scrub_setup_symlink( if (!sc->buf) return -ENOMEM; - return xfs_scrub_setup_inode_contents(sc, ip, 0); + return xchk_setup_inode_contents(sc, ip, 0); } /* Symbolic links. */ int -xfs_scrub_symlink( +xchk_symlink( struct xfs_scrub_context *sc) { struct xfs_inode *ip = sc->ip; @@ -55,7 +55,7 @@ xfs_scrub_symlink( /* Plausible size? */ if (len > XFS_SYMLINK_MAXLEN || len <= 0) { - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); goto out; } @@ -63,16 +63,16 @@ xfs_scrub_symlink( if (ifp->if_flags & XFS_IFINLINE) { if (len > XFS_IFORK_DSIZE(ip) || len > strnlen(ifp->if_u1.if_data, XFS_IFORK_DSIZE(ip))) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); goto out; } /* Remote symlink; must read the contents. */ error = xfs_readlink_bmap_ilocked(sc->ip, sc->buf); - if (!xfs_scrub_fblock_process_error(sc, XFS_DATA_FORK, 0, &error)) + if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error)) goto out; if (strnlen(sc->buf, XFS_SYMLINK_MAXLEN) < len) - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); + xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); out: return error; } diff --git a/fs/xfs/scrub/trace.c b/fs/xfs/scrub/trace.c index 7c76d8b5cb05..1ef1202a1e45 100644 --- a/fs/xfs/scrub/trace.c +++ b/fs/xfs/scrub/trace.c @@ -22,7 +22,7 @@ /* Figure out which block the btree cursor was pointing to. */ static inline xfs_fsblock_t -xfs_scrub_btree_cur_fsbno( +xchk_btree_cur_fsbno( struct xfs_btree_cur *cur, int level) { diff --git a/fs/xfs/scrub/trace.h b/fs/xfs/scrub/trace.h index cec3e5ece5a1..11967d3942ac 100644 --- a/fs/xfs/scrub/trace.h +++ b/fs/xfs/scrub/trace.h @@ -12,7 +12,7 @@ #include #include "xfs_bit.h" -DECLARE_EVENT_CLASS(xfs_scrub_class, +DECLARE_EVENT_CLASS(xchk_class, TP_PROTO(struct xfs_inode *ip, struct xfs_scrub_metadata *sm, int error), TP_ARGS(ip, sm, error), @@ -47,18 +47,18 @@ DECLARE_EVENT_CLASS(xfs_scrub_class, __entry->error) ) #define DEFINE_SCRUB_EVENT(name) \ -DEFINE_EVENT(xfs_scrub_class, name, \ +DEFINE_EVENT(xchk_class, name, \ TP_PROTO(struct xfs_inode *ip, struct xfs_scrub_metadata *sm, \ int error), \ TP_ARGS(ip, sm, error)) -DEFINE_SCRUB_EVENT(xfs_scrub_start); -DEFINE_SCRUB_EVENT(xfs_scrub_done); -DEFINE_SCRUB_EVENT(xfs_scrub_deadlock_retry); +DEFINE_SCRUB_EVENT(xchk_start); +DEFINE_SCRUB_EVENT(xchk_done); +DEFINE_SCRUB_EVENT(xchk_deadlock_retry); DEFINE_SCRUB_EVENT(xfs_repair_attempt); DEFINE_SCRUB_EVENT(xfs_repair_done); -TRACE_EVENT(xfs_scrub_op_error, +TRACE_EVENT(xchk_op_error, TP_PROTO(struct xfs_scrub_context *sc, xfs_agnumber_t agno, xfs_agblock_t bno, int error, void *ret_ip), TP_ARGS(sc, agno, bno, error, ret_ip), @@ -87,7 +87,7 @@ TRACE_EVENT(xfs_scrub_op_error, __entry->ret_ip) ); -TRACE_EVENT(xfs_scrub_file_op_error, +TRACE_EVENT(xchk_file_op_error, TP_PROTO(struct xfs_scrub_context *sc, int whichfork, xfs_fileoff_t offset, int error, void *ret_ip), TP_ARGS(sc, whichfork, offset, error, ret_ip), @@ -119,7 +119,7 @@ TRACE_EVENT(xfs_scrub_file_op_error, __entry->ret_ip) ); -DECLARE_EVENT_CLASS(xfs_scrub_block_error_class, +DECLARE_EVENT_CLASS(xchk_block_error_class, TP_PROTO(struct xfs_scrub_context *sc, xfs_daddr_t daddr, void *ret_ip), TP_ARGS(sc, daddr, ret_ip), TP_STRUCT__entry( @@ -153,15 +153,15 @@ DECLARE_EVENT_CLASS(xfs_scrub_block_error_class, ) #define DEFINE_SCRUB_BLOCK_ERROR_EVENT(name) \ -DEFINE_EVENT(xfs_scrub_block_error_class, name, \ +DEFINE_EVENT(xchk_block_error_class, name, \ TP_PROTO(struct xfs_scrub_context *sc, xfs_daddr_t daddr, \ void *ret_ip), \ TP_ARGS(sc, daddr, ret_ip)) -DEFINE_SCRUB_BLOCK_ERROR_EVENT(xfs_scrub_block_error); -DEFINE_SCRUB_BLOCK_ERROR_EVENT(xfs_scrub_block_preen); +DEFINE_SCRUB_BLOCK_ERROR_EVENT(xchk_block_error); +DEFINE_SCRUB_BLOCK_ERROR_EVENT(xchk_block_preen); -DECLARE_EVENT_CLASS(xfs_scrub_ino_error_class, +DECLARE_EVENT_CLASS(xchk_ino_error_class, TP_PROTO(struct xfs_scrub_context *sc, xfs_ino_t ino, void *ret_ip), TP_ARGS(sc, ino, ret_ip), TP_STRUCT__entry( @@ -184,16 +184,16 @@ DECLARE_EVENT_CLASS(xfs_scrub_ino_error_class, ) #define DEFINE_SCRUB_INO_ERROR_EVENT(name) \ -DEFINE_EVENT(xfs_scrub_ino_error_class, name, \ +DEFINE_EVENT(xchk_ino_error_class, name, \ TP_PROTO(struct xfs_scrub_context *sc, xfs_ino_t ino, \ void *ret_ip), \ TP_ARGS(sc, ino, ret_ip)) -DEFINE_SCRUB_INO_ERROR_EVENT(xfs_scrub_ino_error); -DEFINE_SCRUB_INO_ERROR_EVENT(xfs_scrub_ino_preen); -DEFINE_SCRUB_INO_ERROR_EVENT(xfs_scrub_ino_warning); +DEFINE_SCRUB_INO_ERROR_EVENT(xchk_ino_error); +DEFINE_SCRUB_INO_ERROR_EVENT(xchk_ino_preen); +DEFINE_SCRUB_INO_ERROR_EVENT(xchk_ino_warning); -DECLARE_EVENT_CLASS(xfs_scrub_fblock_error_class, +DECLARE_EVENT_CLASS(xchk_fblock_error_class, TP_PROTO(struct xfs_scrub_context *sc, int whichfork, xfs_fileoff_t offset, void *ret_ip), TP_ARGS(sc, whichfork, offset, ret_ip), @@ -223,15 +223,15 @@ DECLARE_EVENT_CLASS(xfs_scrub_fblock_error_class, ); #define DEFINE_SCRUB_FBLOCK_ERROR_EVENT(name) \ -DEFINE_EVENT(xfs_scrub_fblock_error_class, name, \ +DEFINE_EVENT(xchk_fblock_error_class, name, \ TP_PROTO(struct xfs_scrub_context *sc, int whichfork, \ xfs_fileoff_t offset, void *ret_ip), \ TP_ARGS(sc, whichfork, offset, ret_ip)) -DEFINE_SCRUB_FBLOCK_ERROR_EVENT(xfs_scrub_fblock_error); -DEFINE_SCRUB_FBLOCK_ERROR_EVENT(xfs_scrub_fblock_warning); +DEFINE_SCRUB_FBLOCK_ERROR_EVENT(xchk_fblock_error); +DEFINE_SCRUB_FBLOCK_ERROR_EVENT(xchk_fblock_warning); -TRACE_EVENT(xfs_scrub_incomplete, +TRACE_EVENT(xchk_incomplete, TP_PROTO(struct xfs_scrub_context *sc, void *ret_ip), TP_ARGS(sc, ret_ip), TP_STRUCT__entry( @@ -250,7 +250,7 @@ TRACE_EVENT(xfs_scrub_incomplete, __entry->ret_ip) ); -TRACE_EVENT(xfs_scrub_btree_op_error, +TRACE_EVENT(xchk_btree_op_error, TP_PROTO(struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, int level, int error, void *ret_ip), TP_ARGS(sc, cur, level, error, ret_ip), @@ -266,7 +266,7 @@ TRACE_EVENT(xfs_scrub_btree_op_error, __field(void *, ret_ip) ), TP_fast_assign( - xfs_fsblock_t fsbno = xfs_scrub_btree_cur_fsbno(cur, level); + xfs_fsblock_t fsbno = xchk_btree_cur_fsbno(cur, level); __entry->dev = sc->mp->m_super->s_dev; __entry->type = sc->sm->sm_type; @@ -290,7 +290,7 @@ TRACE_EVENT(xfs_scrub_btree_op_error, __entry->ret_ip) ); -TRACE_EVENT(xfs_scrub_ifork_btree_op_error, +TRACE_EVENT(xchk_ifork_btree_op_error, TP_PROTO(struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, int level, int error, void *ret_ip), TP_ARGS(sc, cur, level, error, ret_ip), @@ -308,7 +308,7 @@ TRACE_EVENT(xfs_scrub_ifork_btree_op_error, __field(void *, ret_ip) ), TP_fast_assign( - xfs_fsblock_t fsbno = xfs_scrub_btree_cur_fsbno(cur, level); + xfs_fsblock_t fsbno = xchk_btree_cur_fsbno(cur, level); __entry->dev = sc->mp->m_super->s_dev; __entry->ino = sc->ip->i_ino; __entry->whichfork = cur->bc_private.b.whichfork; @@ -335,7 +335,7 @@ TRACE_EVENT(xfs_scrub_ifork_btree_op_error, __entry->ret_ip) ); -TRACE_EVENT(xfs_scrub_btree_error, +TRACE_EVENT(xchk_btree_error, TP_PROTO(struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, int level, void *ret_ip), TP_ARGS(sc, cur, level, ret_ip), @@ -350,7 +350,7 @@ TRACE_EVENT(xfs_scrub_btree_error, __field(void *, ret_ip) ), TP_fast_assign( - xfs_fsblock_t fsbno = xfs_scrub_btree_cur_fsbno(cur, level); + xfs_fsblock_t fsbno = xchk_btree_cur_fsbno(cur, level); __entry->dev = sc->mp->m_super->s_dev; __entry->type = sc->sm->sm_type; __entry->btnum = cur->bc_btnum; @@ -371,7 +371,7 @@ TRACE_EVENT(xfs_scrub_btree_error, __entry->ret_ip) ); -TRACE_EVENT(xfs_scrub_ifork_btree_error, +TRACE_EVENT(xchk_ifork_btree_error, TP_PROTO(struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, int level, void *ret_ip), TP_ARGS(sc, cur, level, ret_ip), @@ -388,7 +388,7 @@ TRACE_EVENT(xfs_scrub_ifork_btree_error, __field(void *, ret_ip) ), TP_fast_assign( - xfs_fsblock_t fsbno = xfs_scrub_btree_cur_fsbno(cur, level); + xfs_fsblock_t fsbno = xchk_btree_cur_fsbno(cur, level); __entry->dev = sc->mp->m_super->s_dev; __entry->ino = sc->ip->i_ino; __entry->whichfork = cur->bc_private.b.whichfork; @@ -413,7 +413,7 @@ TRACE_EVENT(xfs_scrub_ifork_btree_error, __entry->ret_ip) ); -DECLARE_EVENT_CLASS(xfs_scrub_sbtree_class, +DECLARE_EVENT_CLASS(xchk_sbtree_class, TP_PROTO(struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, int level), TP_ARGS(sc, cur, level), @@ -428,7 +428,7 @@ DECLARE_EVENT_CLASS(xfs_scrub_sbtree_class, __field(int, ptr) ), TP_fast_assign( - xfs_fsblock_t fsbno = xfs_scrub_btree_cur_fsbno(cur, level); + xfs_fsblock_t fsbno = xchk_btree_cur_fsbno(cur, level); __entry->dev = sc->mp->m_super->s_dev; __entry->type = sc->sm->sm_type; @@ -450,15 +450,15 @@ DECLARE_EVENT_CLASS(xfs_scrub_sbtree_class, __entry->ptr) ) #define DEFINE_SCRUB_SBTREE_EVENT(name) \ -DEFINE_EVENT(xfs_scrub_sbtree_class, name, \ +DEFINE_EVENT(xchk_sbtree_class, name, \ TP_PROTO(struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, \ int level), \ TP_ARGS(sc, cur, level)) -DEFINE_SCRUB_SBTREE_EVENT(xfs_scrub_btree_rec); -DEFINE_SCRUB_SBTREE_EVENT(xfs_scrub_btree_key); +DEFINE_SCRUB_SBTREE_EVENT(xchk_btree_rec); +DEFINE_SCRUB_SBTREE_EVENT(xchk_btree_key); -TRACE_EVENT(xfs_scrub_xref_error, +TRACE_EVENT(xchk_xref_error, TP_PROTO(struct xfs_scrub_context *sc, int error, void *ret_ip), TP_ARGS(sc, error, ret_ip), TP_STRUCT__entry( -- cgit v1.2.3 From b5e2196e9c7217387bab2ab4231ad9f4585f55c5 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 19 Jul 2018 12:29:11 -0700 Subject: xfs: shorten xfs_repair_ prefix to xrep_ Shorten all the metadata repair xfs_repair_* symbols to xrep_. Whitespace damage will be fixed by a subsequent patch. There are no functional changes. Signed-off-by: Darrick J. Wong Reviewed-by: Brian Foster --- fs/xfs/scrub/agheader_repair.c | 2 +- fs/xfs/scrub/common.c | 2 +- fs/xfs/scrub/repair.c | 164 ++++++++++++++++++++--------------------- fs/xfs/scrub/repair.h | 74 +++++++++---------- fs/xfs/scrub/scrub.c | 54 +++++++------- fs/xfs/scrub/trace.h | 40 +++++----- 6 files changed, 168 insertions(+), 168 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/scrub/agheader_repair.c b/fs/xfs/scrub/agheader_repair.c index 117eedac53df..631940f3ca4d 100644 --- a/fs/xfs/scrub/agheader_repair.c +++ b/fs/xfs/scrub/agheader_repair.c @@ -28,7 +28,7 @@ /* Repair the superblock. */ int -xfs_repair_superblock( +xrep_superblock( struct xfs_scrub_context *sc) { struct xfs_mount *mp = sc->mp; diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index 5c3d4e7c6166..d40bba9e7596 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -604,7 +604,7 @@ xchk_setup_fs( { uint resblks; - resblks = xfs_repair_calc_ag_resblks(sc); + resblks = xrep_calc_ag_resblks(sc); return xchk_trans_alloc(sc, resblks); } diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 5eccd89c64a8..7e6a56a5f59d 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -41,21 +41,21 @@ * and will set *fixed to true if it thinks it repaired anything. */ int -xfs_repair_attempt( +xrep_attempt( struct xfs_inode *ip, struct xfs_scrub_context *sc, bool *fixed) { int error = 0; - trace_xfs_repair_attempt(ip, sc->sm, error); + trace_xrep_attempt(ip, sc->sm, error); xchk_ag_btcur_free(&sc->sa); /* Repair whatever's broken. */ ASSERT(sc->ops->repair); error = sc->ops->repair(sc); - trace_xfs_repair_done(ip, sc->sm, error); + trace_xrep_done(ip, sc->sm, error); switch (error) { case 0: /* @@ -93,7 +93,7 @@ xfs_repair_attempt( * structure to track rate limiting information. */ void -xfs_repair_failure( +xrep_failure( struct xfs_mount *mp) { xfs_alert_ratelimited(mp, @@ -105,7 +105,7 @@ xfs_repair_failure( * given mountpoint. */ int -xfs_repair_probe( +xrep_probe( struct xfs_scrub_context *sc) { int error = 0; @@ -121,7 +121,7 @@ xfs_repair_probe( * the btree cursors. */ int -xfs_repair_roll_ag_trans( +xrep_roll_ag_trans( struct xfs_scrub_context *sc) { int error; @@ -162,7 +162,7 @@ out_release: * in AG reservations) to construct a whole btree. */ bool -xfs_repair_ag_has_space( +xrep_ag_has_space( struct xfs_perag *pag, xfs_extlen_t nr_blocks, enum xfs_ag_resv_type type) @@ -178,7 +178,7 @@ xfs_repair_ag_has_space( * any type of per-AG btree. */ xfs_extlen_t -xfs_repair_calc_ag_resblks( +xrep_calc_ag_resblks( struct xfs_scrub_context *sc) { struct xfs_mount *mp = sc->mp; @@ -231,7 +231,7 @@ xfs_repair_calc_ag_resblks( } xfs_perag_put(pag); - trace_xfs_repair_calc_ag_resblks(mp, sm->sm_agno, icount, aglen, + trace_xrep_calc_ag_resblks(mp, sm->sm_agno, icount, aglen, freelen, usedlen); /* @@ -270,7 +270,7 @@ xfs_repair_calc_ag_resblks( rmapbt_sz = 0; } - trace_xfs_repair_calc_ag_resblks_btsize(mp, sm->sm_agno, bnobt_sz, + trace_xrep_calc_ag_resblks_btsize(mp, sm->sm_agno, bnobt_sz, inobt_sz, rmapbt_sz, refcbt_sz); return max(max(bnobt_sz, inobt_sz), max(rmapbt_sz, refcbt_sz)); @@ -278,7 +278,7 @@ xfs_repair_calc_ag_resblks( /* Allocate a block in an AG. */ int -xfs_repair_alloc_ag_block( +xrep_alloc_ag_block( struct xfs_scrub_context *sc, struct xfs_owner_info *oinfo, xfs_fsblock_t *fsbno, @@ -329,7 +329,7 @@ xfs_repair_alloc_ag_block( /* Initialize a new AG btree root block with zero entries. */ int -xfs_repair_init_btblock( +xrep_init_btblock( struct xfs_scrub_context *sc, xfs_fsblock_t fsb, struct xfs_buf **bpp, @@ -340,7 +340,7 @@ xfs_repair_init_btblock( struct xfs_mount *mp = sc->mp; struct xfs_buf *bp; - trace_xfs_repair_init_btblock(mp, XFS_FSB_TO_AGNO(mp, fsb), + trace_xrep_init_btblock(mp, XFS_FSB_TO_AGNO(mp, fsb), XFS_FSB_TO_AGBNO(mp, fsb), btnum); ASSERT(XFS_FSB_TO_AGNO(mp, fsb) == sc->sa.agno); @@ -384,19 +384,19 @@ xfs_repair_init_btblock( /* Collect a dead btree extent for later disposal. */ int -xfs_repair_collect_btree_extent( +xrep_collect_btree_extent( struct xfs_scrub_context *sc, - struct xfs_repair_extent_list *exlist, + struct xrep_extent_list *exlist, xfs_fsblock_t fsbno, xfs_extlen_t len) { - struct xfs_repair_extent *rex; + struct xrep_extent *rex; - trace_xfs_repair_collect_btree_extent(sc->mp, + trace_xrep_collect_btree_extent(sc->mp, XFS_FSB_TO_AGNO(sc->mp, fsbno), XFS_FSB_TO_AGBNO(sc->mp, fsbno), len); - rex = kmem_alloc(sizeof(struct xfs_repair_extent), KM_MAYFAIL); + rex = kmem_alloc(sizeof(struct xrep_extent), KM_MAYFAIL); if (!rex) return -ENOMEM; @@ -414,14 +414,14 @@ xfs_repair_collect_btree_extent( * Therefore, free all the memory associated with the list so we can die. */ void -xfs_repair_cancel_btree_extents( +xrep_cancel_btree_extents( struct xfs_scrub_context *sc, - struct xfs_repair_extent_list *exlist) + struct xrep_extent_list *exlist) { - struct xfs_repair_extent *rex; - struct xfs_repair_extent *n; + struct xrep_extent *rex; + struct xrep_extent *n; - for_each_xfs_repair_extent_safe(rex, n, exlist) { + for_each_xrep_extent_safe(rex, n, exlist) { list_del(&rex->list); kmem_free(rex); } @@ -429,16 +429,16 @@ xfs_repair_cancel_btree_extents( /* Compare two btree extents. */ static int -xfs_repair_btree_extent_cmp( +xrep_btree_extent_cmp( void *priv, struct list_head *a, struct list_head *b) { - struct xfs_repair_extent *ap; - struct xfs_repair_extent *bp; + struct xrep_extent *ap; + struct xrep_extent *bp; - ap = container_of(a, struct xfs_repair_extent, list); - bp = container_of(b, struct xfs_repair_extent, list); + ap = container_of(a, struct xrep_extent, list); + bp = container_of(b, struct xrep_extent, list); if (ap->fsbno > bp->fsbno) return 1; @@ -462,15 +462,15 @@ xfs_repair_btree_extent_cmp( #define LEFT_ALIGNED (1 << 0) #define RIGHT_ALIGNED (1 << 1) int -xfs_repair_subtract_extents( +xrep_subtract_extents( struct xfs_scrub_context *sc, - struct xfs_repair_extent_list *exlist, - struct xfs_repair_extent_list *sublist) + struct xrep_extent_list *exlist, + struct xrep_extent_list *sublist) { struct list_head *lp; - struct xfs_repair_extent *ex; - struct xfs_repair_extent *newex; - struct xfs_repair_extent *subex; + struct xrep_extent *ex; + struct xrep_extent *newex; + struct xrep_extent *subex; xfs_fsblock_t sub_fsb; xfs_extlen_t sub_len; int state; @@ -480,8 +480,8 @@ xfs_repair_subtract_extents( return 0; ASSERT(!list_empty(&sublist->list)); - list_sort(NULL, &exlist->list, xfs_repair_btree_extent_cmp); - list_sort(NULL, &sublist->list, xfs_repair_btree_extent_cmp); + list_sort(NULL, &exlist->list, xrep_btree_extent_cmp); + list_sort(NULL, &sublist->list, xrep_btree_extent_cmp); /* * Now that we've sorted both lists, we iterate exlist once, rolling @@ -491,11 +491,11 @@ xfs_repair_subtract_extents( * list traversal is similar to merge sort, but we're deleting * instead. In this manner we avoid O(n^2) operations. */ - subex = list_first_entry(&sublist->list, struct xfs_repair_extent, + subex = list_first_entry(&sublist->list, struct xrep_extent, list); lp = exlist->list.next; while (lp != &exlist->list) { - ex = list_entry(lp, struct xfs_repair_extent, list); + ex = list_entry(lp, struct xrep_extent, list); /* * Advance subex and/or ex until we find a pair that @@ -548,7 +548,7 @@ xfs_repair_subtract_extents( * Deleting from the middle: add the new right extent * and then shrink the left extent. */ - newex = kmem_alloc(sizeof(struct xfs_repair_extent), + newex = kmem_alloc(sizeof(struct xrep_extent), KM_MAYFAIL); if (!newex) { error = -ENOMEM; @@ -619,12 +619,12 @@ out: * is not intended for use with file data repairs; we have bunmapi for that. */ int -xfs_repair_invalidate_blocks( +xrep_invalidate_blocks( struct xfs_scrub_context *sc, - struct xfs_repair_extent_list *exlist) + struct xrep_extent_list *exlist) { - struct xfs_repair_extent *rex; - struct xfs_repair_extent *n; + struct xrep_extent *rex; + struct xrep_extent *n; struct xfs_buf *bp; xfs_fsblock_t fsbno; xfs_agblock_t i; @@ -637,7 +637,7 @@ xfs_repair_invalidate_blocks( * because we never own those; and if we can't TRYLOCK the buffer we * assume it's owned by someone else. */ - for_each_xfs_repair_extent_safe(rex, n, exlist) { + for_each_xrep_extent_safe(rex, n, exlist) { for (fsbno = rex->fsbno, i = rex->len; i > 0; fsbno++, i--) { /* Skip AG headers and post-EOFS blocks */ if (!xfs_verify_fsbno(sc->mp, fsbno)) @@ -657,7 +657,7 @@ xfs_repair_invalidate_blocks( /* Ensure the freelist is the correct size. */ int -xfs_repair_fix_freelist( +xrep_fix_freelist( struct xfs_scrub_context *sc, bool can_shrink) { @@ -677,7 +677,7 @@ xfs_repair_fix_freelist( * Put a block back on the AGFL. */ STATIC int -xfs_repair_put_freelist( +xrep_put_freelist( struct xfs_scrub_context *sc, xfs_agblock_t agbno) { @@ -685,7 +685,7 @@ xfs_repair_put_freelist( int error; /* Make sure there's space on the freelist. */ - error = xfs_repair_fix_freelist(sc, true); + error = xrep_fix_freelist(sc, true); if (error) return error; @@ -713,7 +713,7 @@ xfs_repair_put_freelist( /* Dispose of a single metadata block. */ STATIC int -xfs_repair_dispose_btree_block( +xrep_dispose_btree_block( struct xfs_scrub_context *sc, xfs_fsblock_t fsbno, struct xfs_owner_info *oinfo, @@ -767,7 +767,7 @@ xfs_repair_dispose_btree_block( if (has_other_rmap) error = xfs_rmap_free(sc->tp, agf_bp, agno, agbno, 1, oinfo); else if (resv == XFS_AG_RESV_AGFL) - error = xfs_repair_put_freelist(sc, agbno); + error = xrep_put_freelist(sc, agbno); else error = xfs_free_extent(sc->tp, fsbno, 1, oinfo, resv); if (agf_bp != sc->sa.agf_bp) @@ -777,7 +777,7 @@ xfs_repair_dispose_btree_block( if (sc->ip) return xfs_trans_roll_inode(&sc->tp, sc->ip); - return xfs_repair_roll_ag_trans(sc); + return xrep_roll_ag_trans(sc); out_free: if (agf_bp != sc->sa.agf_bp) @@ -787,29 +787,29 @@ out_free: /* Dispose of btree blocks from an old per-AG btree. */ int -xfs_repair_reap_btree_extents( +xrep_reap_btree_extents( struct xfs_scrub_context *sc, - struct xfs_repair_extent_list *exlist, + struct xrep_extent_list *exlist, struct xfs_owner_info *oinfo, enum xfs_ag_resv_type type) { - struct xfs_repair_extent *rex; - struct xfs_repair_extent *n; + struct xrep_extent *rex; + struct xrep_extent *n; int error = 0; ASSERT(xfs_sb_version_hasrmapbt(&sc->mp->m_sb)); /* Dispose of every block from the old btree. */ - for_each_xfs_repair_extent_safe(rex, n, exlist) { + for_each_xrep_extent_safe(rex, n, exlist) { ASSERT(sc->ip != NULL || XFS_FSB_TO_AGNO(sc->mp, rex->fsbno) == sc->sa.agno); - trace_xfs_repair_dispose_btree_extent(sc->mp, + trace_xrep_dispose_btree_extent(sc->mp, XFS_FSB_TO_AGNO(sc->mp, rex->fsbno), XFS_FSB_TO_AGBNO(sc->mp, rex->fsbno), rex->len); for (; rex->len > 0; rex->len--, rex->fsbno++) { - error = xfs_repair_dispose_btree_block(sc, rex->fsbno, + error = xrep_dispose_btree_block(sc, rex->fsbno, oinfo, type); if (error) goto out; @@ -819,7 +819,7 @@ xfs_repair_reap_btree_extents( } out: - xfs_repair_cancel_btree_extents(sc, exlist); + xrep_cancel_btree_extents(sc, exlist); return error; } @@ -831,12 +831,12 @@ out: * btree roots. This is not guaranteed to work if the AG is heavily damaged * or the rmap data are corrupt. * - * Callers of xfs_repair_find_ag_btree_roots must lock the AGF and AGFL + * Callers of xrep_find_ag_btree_roots must lock the AGF and AGFL * buffers if the AGF is being rebuilt; or the AGF and AGI buffers if the * AGI is being rebuilt. It must maintain these locks until it's safe for * other threads to change the btrees' shapes. The caller provides * information about the btrees to look for by passing in an array of - * xfs_repair_find_ag_btree with the (rmap owner, buf_ops, magic) fields set. + * xrep_find_ag_btree with the (rmap owner, buf_ops, magic) fields set. * The (root, height) fields will be set on return if anything is found. The * last element of the array should have a NULL buf_ops to mark the end of the * array. @@ -850,16 +850,16 @@ out: * should be the roots. */ -struct xfs_repair_findroot { +struct xrep_findroot { struct xfs_scrub_context *sc; struct xfs_buf *agfl_bp; struct xfs_agf *agf; - struct xfs_repair_find_ag_btree *btree_info; + struct xrep_find_ag_btree *btree_info; }; /* See if our block is in the AGFL. */ STATIC int -xfs_repair_findroot_agfl_walk( +xrep_findroot_agfl_walk( struct xfs_mount *mp, xfs_agblock_t bno, void *priv) @@ -871,9 +871,9 @@ xfs_repair_findroot_agfl_walk( /* Does this block match the btree information passed in? */ STATIC int -xfs_repair_findroot_block( - struct xfs_repair_findroot *ri, - struct xfs_repair_find_ag_btree *fab, +xrep_findroot_block( + struct xrep_findroot *ri, + struct xrep_find_ag_btree *fab, uint64_t owner, xfs_agblock_t agbno, bool *found_it) @@ -894,7 +894,7 @@ xfs_repair_findroot_block( */ if (owner == XFS_RMAP_OWN_AG) { error = xfs_agfl_walk(mp, ri->agf, ri->agfl_bp, - xfs_repair_findroot_agfl_walk, &agbno); + xrep_findroot_agfl_walk, &agbno); if (error == XFS_BTREE_QUERY_RANGE_ABORT) return 0; if (error) @@ -932,7 +932,7 @@ xfs_repair_findroot_block( fab->height = xfs_btree_get_level(btblock) + 1; *found_it = true; - trace_xfs_repair_findroot_block(mp, ri->sc->sa.agno, agbno, + trace_xrep_findroot_block(mp, ri->sc->sa.agno, agbno, be32_to_cpu(btblock->bb_magic), fab->height - 1); out: xfs_trans_brelse(ri->sc->tp, bp); @@ -944,13 +944,13 @@ out: * looking for? */ STATIC int -xfs_repair_findroot_rmap( +xrep_findroot_rmap( struct xfs_btree_cur *cur, struct xfs_rmap_irec *rec, void *priv) { - struct xfs_repair_findroot *ri = priv; - struct xfs_repair_find_ag_btree *fab; + struct xrep_findroot *ri = priv; + struct xrep_find_ag_btree *fab; xfs_agblock_t b; bool found_it; int error = 0; @@ -965,7 +965,7 @@ xfs_repair_findroot_rmap( for (fab = ri->btree_info; fab->buf_ops; fab++) { if (rec->rm_owner != fab->rmap_owner) continue; - error = xfs_repair_findroot_block(ri, fab, + error = xrep_findroot_block(ri, fab, rec->rm_owner, rec->rm_startblock + b, &found_it); if (error) @@ -980,15 +980,15 @@ xfs_repair_findroot_rmap( /* Find the roots of the per-AG btrees described in btree_info. */ int -xfs_repair_find_ag_btree_roots( +xrep_find_ag_btree_roots( struct xfs_scrub_context *sc, struct xfs_buf *agf_bp, - struct xfs_repair_find_ag_btree *btree_info, + struct xrep_find_ag_btree *btree_info, struct xfs_buf *agfl_bp) { struct xfs_mount *mp = sc->mp; - struct xfs_repair_findroot ri; - struct xfs_repair_find_ag_btree *fab; + struct xrep_findroot ri; + struct xrep_find_ag_btree *fab; struct xfs_btree_cur *cur; int error; @@ -1007,7 +1007,7 @@ xfs_repair_find_ag_btree_roots( } cur = xfs_rmapbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.agno); - error = xfs_rmap_query_all(cur, xfs_repair_findroot_rmap, &ri); + error = xfs_rmap_query_all(cur, xrep_findroot_rmap, &ri); xfs_btree_del_cursor(cur, error); return error; @@ -1015,7 +1015,7 @@ xfs_repair_find_ag_btree_roots( /* Force a quotacheck the next time we mount. */ void -xfs_repair_force_quotacheck( +xrep_force_quotacheck( struct xfs_scrub_context *sc, uint dqtype) { @@ -1043,7 +1043,7 @@ xfs_repair_force_quotacheck( * repair corruptions in the quota metadata. */ int -xfs_repair_ino_dqattach( +xrep_ino_dqattach( struct xfs_scrub_context *sc) { int error; @@ -1057,11 +1057,11 @@ xfs_repair_ino_dqattach( "inode %llu repair encountered quota error %d, quotacheck forced.", (unsigned long long)sc->ip->i_ino, error); if (XFS_IS_UQUOTA_ON(sc->mp) && !sc->ip->i_udquot) - xfs_repair_force_quotacheck(sc, XFS_DQ_USER); + xrep_force_quotacheck(sc, XFS_DQ_USER); if (XFS_IS_GQUOTA_ON(sc->mp) && !sc->ip->i_gdquot) - xfs_repair_force_quotacheck(sc, XFS_DQ_GROUP); + xrep_force_quotacheck(sc, XFS_DQ_GROUP); if (XFS_IS_PQUOTA_ON(sc->mp) && !sc->ip->i_pdquot) - xfs_repair_force_quotacheck(sc, XFS_DQ_PROJ); + xrep_force_quotacheck(sc, XFS_DQ_PROJ); /* fall through */ case -ESRCH: error = 0; diff --git a/fs/xfs/scrub/repair.h b/fs/xfs/scrub/repair.h index ef47826b6725..60d81294797b 100644 --- a/fs/xfs/scrub/repair.h +++ b/fs/xfs/scrub/repair.h @@ -6,7 +6,7 @@ #ifndef __XFS_SCRUB_REPAIR_H__ #define __XFS_SCRUB_REPAIR_H__ -static inline int xfs_repair_notsupported(struct xfs_scrub_context *sc) +static inline int xrep_notsupported(struct xfs_scrub_context *sc) { return -EOPNOTSUPP; } @@ -15,55 +15,55 @@ static inline int xfs_repair_notsupported(struct xfs_scrub_context *sc) /* Repair helpers */ -int xfs_repair_attempt(struct xfs_inode *ip, struct xfs_scrub_context *sc, +int xrep_attempt(struct xfs_inode *ip, struct xfs_scrub_context *sc, bool *fixed); -void xfs_repair_failure(struct xfs_mount *mp); -int xfs_repair_roll_ag_trans(struct xfs_scrub_context *sc); -bool xfs_repair_ag_has_space(struct xfs_perag *pag, xfs_extlen_t nr_blocks, +void xrep_failure(struct xfs_mount *mp); +int xrep_roll_ag_trans(struct xfs_scrub_context *sc); +bool xrep_ag_has_space(struct xfs_perag *pag, xfs_extlen_t nr_blocks, enum xfs_ag_resv_type type); -xfs_extlen_t xfs_repair_calc_ag_resblks(struct xfs_scrub_context *sc); -int xfs_repair_alloc_ag_block(struct xfs_scrub_context *sc, +xfs_extlen_t xrep_calc_ag_resblks(struct xfs_scrub_context *sc); +int xrep_alloc_ag_block(struct xfs_scrub_context *sc, struct xfs_owner_info *oinfo, xfs_fsblock_t *fsbno, enum xfs_ag_resv_type resv); -int xfs_repair_init_btblock(struct xfs_scrub_context *sc, xfs_fsblock_t fsb, +int xrep_init_btblock(struct xfs_scrub_context *sc, xfs_fsblock_t fsb, struct xfs_buf **bpp, xfs_btnum_t btnum, const struct xfs_buf_ops *ops); -struct xfs_repair_extent { +struct xrep_extent { struct list_head list; xfs_fsblock_t fsbno; xfs_extlen_t len; }; -struct xfs_repair_extent_list { +struct xrep_extent_list { struct list_head list; }; static inline void -xfs_repair_init_extent_list( - struct xfs_repair_extent_list *exlist) +xrep_init_extent_list( + struct xrep_extent_list *exlist) { INIT_LIST_HEAD(&exlist->list); } -#define for_each_xfs_repair_extent_safe(rbe, n, exlist) \ +#define for_each_xrep_extent_safe(rbe, n, exlist) \ list_for_each_entry_safe((rbe), (n), &(exlist)->list, list) -int xfs_repair_collect_btree_extent(struct xfs_scrub_context *sc, - struct xfs_repair_extent_list *btlist, xfs_fsblock_t fsbno, +int xrep_collect_btree_extent(struct xfs_scrub_context *sc, + struct xrep_extent_list *btlist, xfs_fsblock_t fsbno, xfs_extlen_t len); -void xfs_repair_cancel_btree_extents(struct xfs_scrub_context *sc, - struct xfs_repair_extent_list *btlist); -int xfs_repair_subtract_extents(struct xfs_scrub_context *sc, - struct xfs_repair_extent_list *exlist, - struct xfs_repair_extent_list *sublist); -int xfs_repair_fix_freelist(struct xfs_scrub_context *sc, bool can_shrink); -int xfs_repair_invalidate_blocks(struct xfs_scrub_context *sc, - struct xfs_repair_extent_list *btlist); -int xfs_repair_reap_btree_extents(struct xfs_scrub_context *sc, - struct xfs_repair_extent_list *exlist, +void xrep_cancel_btree_extents(struct xfs_scrub_context *sc, + struct xrep_extent_list *btlist); +int xrep_subtract_extents(struct xfs_scrub_context *sc, + struct xrep_extent_list *exlist, + struct xrep_extent_list *sublist); +int xrep_fix_freelist(struct xfs_scrub_context *sc, bool can_shrink); +int xrep_invalidate_blocks(struct xfs_scrub_context *sc, + struct xrep_extent_list *btlist); +int xrep_reap_btree_extents(struct xfs_scrub_context *sc, + struct xrep_extent_list *exlist, struct xfs_owner_info *oinfo, enum xfs_ag_resv_type type); -struct xfs_repair_find_ag_btree { +struct xrep_find_ag_btree { /* in: rmap owner of the btree we're looking for */ uint64_t rmap_owner; @@ -78,21 +78,21 @@ struct xfs_repair_find_ag_btree { unsigned int height; }; -int xfs_repair_find_ag_btree_roots(struct xfs_scrub_context *sc, +int xrep_find_ag_btree_roots(struct xfs_scrub_context *sc, struct xfs_buf *agf_bp, - struct xfs_repair_find_ag_btree *btree_info, + struct xrep_find_ag_btree *btree_info, struct xfs_buf *agfl_bp); -void xfs_repair_force_quotacheck(struct xfs_scrub_context *sc, uint dqtype); -int xfs_repair_ino_dqattach(struct xfs_scrub_context *sc); +void xrep_force_quotacheck(struct xfs_scrub_context *sc, uint dqtype); +int xrep_ino_dqattach(struct xfs_scrub_context *sc); /* Metadata repairers */ -int xfs_repair_probe(struct xfs_scrub_context *sc); -int xfs_repair_superblock(struct xfs_scrub_context *sc); +int xrep_probe(struct xfs_scrub_context *sc); +int xrep_superblock(struct xfs_scrub_context *sc); #else -static inline int xfs_repair_attempt( +static inline int xrep_attempt( struct xfs_inode *ip, struct xfs_scrub_context *sc, bool *fixed) @@ -100,18 +100,18 @@ static inline int xfs_repair_attempt( return -EOPNOTSUPP; } -static inline void xfs_repair_failure(struct xfs_mount *mp) {} +static inline void xrep_failure(struct xfs_mount *mp) {} static inline xfs_extlen_t -xfs_repair_calc_ag_resblks( +xrep_calc_ag_resblks( struct xfs_scrub_context *sc) { ASSERT(!(sc->sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR)); return 0; } -#define xfs_repair_probe xfs_repair_notsupported -#define xfs_repair_superblock xfs_repair_notsupported +#define xrep_probe xrep_notsupported +#define xrep_superblock xrep_notsupported #endif /* CONFIG_XFS_ONLINE_REPAIR */ diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c index ead97ab91a3c..a6efede6e430 100644 --- a/fs/xfs/scrub/scrub.c +++ b/fs/xfs/scrub/scrub.c @@ -202,150 +202,150 @@ static const struct xchk_meta_ops meta_scrub_ops[] = { .type = ST_NONE, .setup = xchk_setup_fs, .scrub = xchk_probe, - .repair = xfs_repair_probe, + .repair = xrep_probe, }, [XFS_SCRUB_TYPE_SB] = { /* superblock */ .type = ST_PERAG, .setup = xchk_setup_fs, .scrub = xchk_superblock, - .repair = xfs_repair_superblock, + .repair = xrep_superblock, }, [XFS_SCRUB_TYPE_AGF] = { /* agf */ .type = ST_PERAG, .setup = xchk_setup_fs, .scrub = xchk_agf, - .repair = xfs_repair_notsupported, + .repair = xrep_notsupported, }, [XFS_SCRUB_TYPE_AGFL]= { /* agfl */ .type = ST_PERAG, .setup = xchk_setup_fs, .scrub = xchk_agfl, - .repair = xfs_repair_notsupported, + .repair = xrep_notsupported, }, [XFS_SCRUB_TYPE_AGI] = { /* agi */ .type = ST_PERAG, .setup = xchk_setup_fs, .scrub = xchk_agi, - .repair = xfs_repair_notsupported, + .repair = xrep_notsupported, }, [XFS_SCRUB_TYPE_BNOBT] = { /* bnobt */ .type = ST_PERAG, .setup = xchk_setup_ag_allocbt, .scrub = xchk_bnobt, - .repair = xfs_repair_notsupported, + .repair = xrep_notsupported, }, [XFS_SCRUB_TYPE_CNTBT] = { /* cntbt */ .type = ST_PERAG, .setup = xchk_setup_ag_allocbt, .scrub = xchk_cntbt, - .repair = xfs_repair_notsupported, + .repair = xrep_notsupported, }, [XFS_SCRUB_TYPE_INOBT] = { /* inobt */ .type = ST_PERAG, .setup = xchk_setup_ag_iallocbt, .scrub = xchk_inobt, - .repair = xfs_repair_notsupported, + .repair = xrep_notsupported, }, [XFS_SCRUB_TYPE_FINOBT] = { /* finobt */ .type = ST_PERAG, .setup = xchk_setup_ag_iallocbt, .scrub = xchk_finobt, .has = xfs_sb_version_hasfinobt, - .repair = xfs_repair_notsupported, + .repair = xrep_notsupported, }, [XFS_SCRUB_TYPE_RMAPBT] = { /* rmapbt */ .type = ST_PERAG, .setup = xchk_setup_ag_rmapbt, .scrub = xchk_rmapbt, .has = xfs_sb_version_hasrmapbt, - .repair = xfs_repair_notsupported, + .repair = xrep_notsupported, }, [XFS_SCRUB_TYPE_REFCNTBT] = { /* refcountbt */ .type = ST_PERAG, .setup = xchk_setup_ag_refcountbt, .scrub = xchk_refcountbt, .has = xfs_sb_version_hasreflink, - .repair = xfs_repair_notsupported, + .repair = xrep_notsupported, }, [XFS_SCRUB_TYPE_INODE] = { /* inode record */ .type = ST_INODE, .setup = xchk_setup_inode, .scrub = xchk_inode, - .repair = xfs_repair_notsupported, + .repair = xrep_notsupported, }, [XFS_SCRUB_TYPE_BMBTD] = { /* inode data fork */ .type = ST_INODE, .setup = xchk_setup_inode_bmap, .scrub = xchk_bmap_data, - .repair = xfs_repair_notsupported, + .repair = xrep_notsupported, }, [XFS_SCRUB_TYPE_BMBTA] = { /* inode attr fork */ .type = ST_INODE, .setup = xchk_setup_inode_bmap, .scrub = xchk_bmap_attr, - .repair = xfs_repair_notsupported, + .repair = xrep_notsupported, }, [XFS_SCRUB_TYPE_BMBTC] = { /* inode CoW fork */ .type = ST_INODE, .setup = xchk_setup_inode_bmap, .scrub = xchk_bmap_cow, - .repair = xfs_repair_notsupported, + .repair = xrep_notsupported, }, [XFS_SCRUB_TYPE_DIR] = { /* directory */ .type = ST_INODE, .setup = xchk_setup_directory, .scrub = xchk_directory, - .repair = xfs_repair_notsupported, + .repair = xrep_notsupported, }, [XFS_SCRUB_TYPE_XATTR] = { /* extended attributes */ .type = ST_INODE, .setup = xchk_setup_xattr, .scrub = xchk_xattr, - .repair = xfs_repair_notsupported, + .repair = xrep_notsupported, }, [XFS_SCRUB_TYPE_SYMLINK] = { /* symbolic link */ .type = ST_INODE, .setup = xchk_setup_symlink, .scrub = xchk_symlink, - .repair = xfs_repair_notsupported, + .repair = xrep_notsupported, }, [XFS_SCRUB_TYPE_PARENT] = { /* parent pointers */ .type = ST_INODE, .setup = xchk_setup_parent, .scrub = xchk_parent, - .repair = xfs_repair_notsupported, + .repair = xrep_notsupported, }, [XFS_SCRUB_TYPE_RTBITMAP] = { /* realtime bitmap */ .type = ST_FS, .setup = xchk_setup_rt, .scrub = xchk_rtbitmap, .has = xfs_sb_version_hasrealtime, - .repair = xfs_repair_notsupported, + .repair = xrep_notsupported, }, [XFS_SCRUB_TYPE_RTSUM] = { /* realtime summary */ .type = ST_FS, .setup = xchk_setup_rt, .scrub = xchk_rtsummary, .has = xfs_sb_version_hasrealtime, - .repair = xfs_repair_notsupported, + .repair = xrep_notsupported, }, [XFS_SCRUB_TYPE_UQUOTA] = { /* user quota */ .type = ST_FS, .setup = xchk_setup_quota, .scrub = xchk_quota, - .repair = xfs_repair_notsupported, + .repair = xrep_notsupported, }, [XFS_SCRUB_TYPE_GQUOTA] = { /* group quota */ .type = ST_FS, .setup = xchk_setup_quota, .scrub = xchk_quota, - .repair = xfs_repair_notsupported, + .repair = xrep_notsupported, }, [XFS_SCRUB_TYPE_PQUOTA] = { /* project quota */ .type = ST_FS, .setup = xchk_setup_quota, .scrub = xchk_quota, - .repair = xfs_repair_notsupported, + .repair = xrep_notsupported, }, }; @@ -457,7 +457,7 @@ static inline void xchk_postmortem(struct xfs_scrub_context *sc) if ((sc->sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR) && (sc->sm->sm_flags & (XFS_SCRUB_OFLAG_CORRUPT | XFS_SCRUB_OFLAG_XCORRUPT))) - xfs_repair_failure(sc->mp); + xrep_failure(sc->mp); } #else static inline void xchk_postmortem(struct xfs_scrub_context *sc) @@ -555,13 +555,13 @@ retry_op: * If it's broken, userspace wants us to fix it, and we haven't * already tried to fix it, then attempt a repair. */ - error = xfs_repair_attempt(ip, &sc, &already_fixed); + error = xrep_attempt(ip, &sc, &already_fixed); if (error == -EAGAIN) { if (sc.try_harder) try_harder = true; error = xchk_teardown(&sc, ip, 0); if (error) { - xfs_repair_failure(mp); + xrep_failure(mp); goto out; } goto retry_op; diff --git a/fs/xfs/scrub/trace.h b/fs/xfs/scrub/trace.h index 11967d3942ac..96f3edda3e91 100644 --- a/fs/xfs/scrub/trace.h +++ b/fs/xfs/scrub/trace.h @@ -55,8 +55,8 @@ DEFINE_EVENT(xchk_class, name, \ DEFINE_SCRUB_EVENT(xchk_start); DEFINE_SCRUB_EVENT(xchk_done); DEFINE_SCRUB_EVENT(xchk_deadlock_retry); -DEFINE_SCRUB_EVENT(xfs_repair_attempt); -DEFINE_SCRUB_EVENT(xfs_repair_done); +DEFINE_SCRUB_EVENT(xrep_attempt); +DEFINE_SCRUB_EVENT(xrep_done); TRACE_EVENT(xchk_op_error, TP_PROTO(struct xfs_scrub_context *sc, xfs_agnumber_t agno, @@ -483,7 +483,7 @@ TRACE_EVENT(xchk_xref_error, /* repair tracepoints */ #if IS_ENABLED(CONFIG_XFS_ONLINE_REPAIR) -DECLARE_EVENT_CLASS(xfs_repair_extent_class, +DECLARE_EVENT_CLASS(xrep_extent_class, TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len), TP_ARGS(mp, agno, agbno, len), @@ -506,15 +506,15 @@ DECLARE_EVENT_CLASS(xfs_repair_extent_class, __entry->len) ); #define DEFINE_REPAIR_EXTENT_EVENT(name) \ -DEFINE_EVENT(xfs_repair_extent_class, name, \ +DEFINE_EVENT(xrep_extent_class, name, \ TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, \ xfs_agblock_t agbno, xfs_extlen_t len), \ TP_ARGS(mp, agno, agbno, len)) -DEFINE_REPAIR_EXTENT_EVENT(xfs_repair_dispose_btree_extent); -DEFINE_REPAIR_EXTENT_EVENT(xfs_repair_collect_btree_extent); -DEFINE_REPAIR_EXTENT_EVENT(xfs_repair_agfl_insert); +DEFINE_REPAIR_EXTENT_EVENT(xrep_dispose_btree_extent); +DEFINE_REPAIR_EXTENT_EVENT(xrep_collect_btree_extent); +DEFINE_REPAIR_EXTENT_EVENT(xrep_agfl_insert); -DECLARE_EVENT_CLASS(xfs_repair_rmap_class, +DECLARE_EVENT_CLASS(xrep_rmap_class, TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, uint64_t owner, uint64_t offset, unsigned int flags), @@ -547,17 +547,17 @@ DECLARE_EVENT_CLASS(xfs_repair_rmap_class, __entry->flags) ); #define DEFINE_REPAIR_RMAP_EVENT(name) \ -DEFINE_EVENT(xfs_repair_rmap_class, name, \ +DEFINE_EVENT(xrep_rmap_class, name, \ TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, \ xfs_agblock_t agbno, xfs_extlen_t len, \ uint64_t owner, uint64_t offset, unsigned int flags), \ TP_ARGS(mp, agno, agbno, len, owner, offset, flags)) -DEFINE_REPAIR_RMAP_EVENT(xfs_repair_alloc_extent_fn); -DEFINE_REPAIR_RMAP_EVENT(xfs_repair_ialloc_extent_fn); -DEFINE_REPAIR_RMAP_EVENT(xfs_repair_rmap_extent_fn); -DEFINE_REPAIR_RMAP_EVENT(xfs_repair_bmap_extent_fn); +DEFINE_REPAIR_RMAP_EVENT(xrep_alloc_extent_fn); +DEFINE_REPAIR_RMAP_EVENT(xrep_ialloc_extent_fn); +DEFINE_REPAIR_RMAP_EVENT(xrep_rmap_extent_fn); +DEFINE_REPAIR_RMAP_EVENT(xrep_bmap_extent_fn); -TRACE_EVENT(xfs_repair_refcount_extent_fn, +TRACE_EVENT(xrep_refcount_extent_fn, TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, struct xfs_refcount_irec *irec), TP_ARGS(mp, agno, irec), @@ -583,7 +583,7 @@ TRACE_EVENT(xfs_repair_refcount_extent_fn, __entry->refcount) ) -TRACE_EVENT(xfs_repair_init_btblock, +TRACE_EVENT(xrep_init_btblock, TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_btnum_t btnum), TP_ARGS(mp, agno, agbno, btnum), @@ -605,7 +605,7 @@ TRACE_EVENT(xfs_repair_init_btblock, __entry->agbno, __entry->btnum) ) -TRACE_EVENT(xfs_repair_findroot_block, +TRACE_EVENT(xrep_findroot_block, TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agblock_t agbno, uint32_t magic, uint16_t level), TP_ARGS(mp, agno, agbno, magic, level), @@ -630,7 +630,7 @@ TRACE_EVENT(xfs_repair_findroot_block, __entry->magic, __entry->level) ) -TRACE_EVENT(xfs_repair_calc_ag_resblks, +TRACE_EVENT(xrep_calc_ag_resblks, TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agino_t icount, xfs_agblock_t aglen, xfs_agblock_t freelen, xfs_agblock_t usedlen), @@ -659,7 +659,7 @@ TRACE_EVENT(xfs_repair_calc_ag_resblks, __entry->freelen, __entry->usedlen) ) -TRACE_EVENT(xfs_repair_calc_ag_resblks_btsize, +TRACE_EVENT(xrep_calc_ag_resblks_btsize, TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agblock_t bnobt_sz, xfs_agblock_t inobt_sz, xfs_agblock_t rmapbt_sz, xfs_agblock_t refcbt_sz), @@ -688,7 +688,7 @@ TRACE_EVENT(xfs_repair_calc_ag_resblks_btsize, __entry->rmapbt_sz, __entry->refcbt_sz) ) -TRACE_EVENT(xfs_repair_reset_counters, +TRACE_EVENT(xrep_reset_counters, TP_PROTO(struct xfs_mount *mp), TP_ARGS(mp), TP_STRUCT__entry( @@ -701,7 +701,7 @@ TRACE_EVENT(xfs_repair_reset_counters, MAJOR(__entry->dev), MINOR(__entry->dev)) ) -TRACE_EVENT(xfs_repair_ialloc_insert, +TRACE_EVENT(xrep_ialloc_insert, TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agino_t startino, uint16_t holemask, uint8_t count, uint8_t freecount, uint64_t freemask), -- cgit v1.2.3 From 1d8a748a8aa94a7da8f3d4fac1892037890d3cff Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 19 Jul 2018 12:29:12 -0700 Subject: xfs: shorten struct xfs_scrub_context to struct xfs_scrub Shorten the name of the online fsck context structure. Whitespace damage will be fixed by a subsequent patch. There are no functional changes. Signed-off-by: Darrick J. Wong Reviewed-by: Brian Foster --- fs/xfs/scrub/agheader.c | 32 +++++++-------- fs/xfs/scrub/agheader_repair.c | 2 +- fs/xfs/scrub/alloc.c | 14 +++---- fs/xfs/scrub/attr.c | 10 ++--- fs/xfs/scrub/bmap.c | 22 +++++------ fs/xfs/scrub/btree.c | 14 +++---- fs/xfs/scrub/btree.h | 12 +++--- fs/xfs/scrub/common.c | 62 ++++++++++++++--------------- fs/xfs/scrub/common.h | 88 +++++++++++++++++++++--------------------- fs/xfs/scrub/dabtree.c | 6 +-- fs/xfs/scrub/dabtree.h | 4 +- fs/xfs/scrub/dir.c | 18 ++++----- fs/xfs/scrub/ialloc.c | 22 +++++------ fs/xfs/scrub/inode.c | 22 +++++------ fs/xfs/scrub/parent.c | 8 ++-- fs/xfs/scrub/quota.c | 12 +++--- fs/xfs/scrub/refcount.c | 16 ++++---- fs/xfs/scrub/repair.c | 36 ++++++++--------- fs/xfs/scrub/repair.h | 38 +++++++++--------- fs/xfs/scrub/rmap.c | 16 ++++---- fs/xfs/scrub/rtbitmap.c | 10 ++--- fs/xfs/scrub/scrub.c | 10 ++--- fs/xfs/scrub/scrub.h | 78 ++++++++++++++++++------------------- fs/xfs/scrub/symlink.c | 4 +- fs/xfs/scrub/trace.h | 32 +++++++-------- 25 files changed, 294 insertions(+), 294 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/scrub/agheader.c b/fs/xfs/scrub/agheader.c index c0625ec16d63..14ba4189ae8f 100644 --- a/fs/xfs/scrub/agheader.c +++ b/fs/xfs/scrub/agheader.c @@ -29,7 +29,7 @@ /* Cross-reference with the other btrees. */ STATIC void xchk_superblock_xref( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_buf *bp) { struct xfs_owner_info oinfo; @@ -66,7 +66,7 @@ xchk_superblock_xref( */ int xchk_superblock( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xfs_mount *mp = sc->mp; struct xfs_buf *bp; @@ -365,7 +365,7 @@ xchk_agf_record_bno_lengths( /* Check agf_freeblks */ static inline void xchk_agf_xref_freeblks( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xfs_agf *agf = XFS_BUF_TO_AGF(sc->sa.agf_bp); xfs_extlen_t blocks = 0; @@ -385,7 +385,7 @@ xchk_agf_xref_freeblks( /* Cross reference the AGF with the cntbt (freespace by length btree) */ static inline void xchk_agf_xref_cntbt( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xfs_agf *agf = XFS_BUF_TO_AGF(sc->sa.agf_bp); xfs_agblock_t agbno; @@ -417,7 +417,7 @@ xchk_agf_xref_cntbt( /* Check the btree block counts in the AGF against the btrees. */ STATIC void xchk_agf_xref_btreeblks( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xfs_agf *agf = XFS_BUF_TO_AGF(sc->sa.agf_bp); struct xfs_mount *mp = sc->mp; @@ -463,7 +463,7 @@ xchk_agf_xref_btreeblks( /* Check agf_refcount_blocks against tree size */ static inline void xchk_agf_xref_refcblks( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xfs_agf *agf = XFS_BUF_TO_AGF(sc->sa.agf_bp); xfs_agblock_t blocks; @@ -482,7 +482,7 @@ xchk_agf_xref_refcblks( /* Cross-reference with the other btrees. */ STATIC void xchk_agf_xref( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xfs_owner_info oinfo; struct xfs_mount *mp = sc->mp; @@ -514,7 +514,7 @@ xchk_agf_xref( /* Scrub the AGF. */ int xchk_agf( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xfs_mount *mp = sc->mp; struct xfs_agf *agf; @@ -602,13 +602,13 @@ struct xchk_agfl_info { unsigned int sz_entries; unsigned int nr_entries; xfs_agblock_t *entries; - struct xfs_scrub_context *sc; + struct xfs_scrub *sc; }; /* Cross-reference with the other btrees. */ STATIC void xchk_agfl_block_xref( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_agblock_t agbno, struct xfs_owner_info *oinfo) { @@ -629,7 +629,7 @@ xchk_agfl_block( void *priv) { struct xchk_agfl_info *sai = priv; - struct xfs_scrub_context *sc = sai->sc; + struct xfs_scrub *sc = sai->sc; xfs_agnumber_t agno = sc->sa.agno; if (xfs_verify_agbno(mp, agno, agbno) && @@ -660,7 +660,7 @@ xchk_agblock_cmp( /* Cross-reference with the other btrees. */ STATIC void xchk_agfl_xref( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xfs_owner_info oinfo; struct xfs_mount *mp = sc->mp; @@ -691,7 +691,7 @@ xchk_agfl_xref( /* Scrub the AGFL. */ int xchk_agfl( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xchk_agfl_info sai; struct xfs_agf *agf; @@ -768,7 +768,7 @@ out: /* Check agi_count/agi_freecount */ static inline void xchk_agi_xref_icounts( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xfs_agi *agi = XFS_BUF_TO_AGI(sc->sa.agi_bp); xfs_agino_t icount; @@ -789,7 +789,7 @@ xchk_agi_xref_icounts( /* Cross-reference with the other btrees. */ STATIC void xchk_agi_xref( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xfs_owner_info oinfo; struct xfs_mount *mp = sc->mp; @@ -818,7 +818,7 @@ xchk_agi_xref( /* Scrub the AGI. */ int xchk_agi( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xfs_mount *mp = sc->mp; struct xfs_agi *agi; diff --git a/fs/xfs/scrub/agheader_repair.c b/fs/xfs/scrub/agheader_repair.c index 631940f3ca4d..2457968482f8 100644 --- a/fs/xfs/scrub/agheader_repair.c +++ b/fs/xfs/scrub/agheader_repair.c @@ -29,7 +29,7 @@ /* Repair the superblock. */ int xrep_superblock( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xfs_mount *mp = sc->mp; struct xfs_buf *bp; diff --git a/fs/xfs/scrub/alloc.c b/fs/xfs/scrub/alloc.c index 1f6e3a6a1fdd..653d80b3aa39 100644 --- a/fs/xfs/scrub/alloc.c +++ b/fs/xfs/scrub/alloc.c @@ -29,7 +29,7 @@ */ int xchk_setup_ag_allocbt( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_inode *ip) { return xchk_setup_ag_btree(sc, ip, false); @@ -42,7 +42,7 @@ xchk_setup_ag_allocbt( */ STATIC void xchk_allocbt_xref_other( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_agblock_t agbno, xfs_extlen_t len) { @@ -82,7 +82,7 @@ xchk_allocbt_xref_other( /* Cross-reference with the other btrees. */ STATIC void xchk_allocbt_xref( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_agblock_t agbno, xfs_extlen_t len) { @@ -123,7 +123,7 @@ xchk_allocbt_rec( /* Scrub the freespace btrees for some AG. */ STATIC int xchk_allocbt( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_btnum_t which) { struct xfs_owner_info oinfo; @@ -136,14 +136,14 @@ xchk_allocbt( int xchk_bnobt( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { return xchk_allocbt(sc, XFS_BTNUM_BNO); } int xchk_cntbt( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { return xchk_allocbt(sc, XFS_BTNUM_CNT); } @@ -151,7 +151,7 @@ xchk_cntbt( /* xref check that the extent is not free */ void xchk_xref_is_used_space( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_agblock_t agbno, xfs_extlen_t len) { diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c index 0068bebddf3e..6650fb3010b6 100644 --- a/fs/xfs/scrub/attr.c +++ b/fs/xfs/scrub/attr.c @@ -33,7 +33,7 @@ /* Set us up to scrub an inode's extended attributes. */ int xchk_setup_xattr( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_inode *ip) { size_t sz; @@ -57,7 +57,7 @@ xchk_setup_xattr( struct xchk_xattr { struct xfs_attr_list_context context; - struct xfs_scrub_context *sc; + struct xfs_scrub *sc; }; /* @@ -127,7 +127,7 @@ fail_xref: */ STATIC bool xchk_xattr_set_map( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, unsigned long *map, unsigned int start, unsigned int len) @@ -155,7 +155,7 @@ xchk_xattr_set_map( */ STATIC bool xchk_xattr_check_freemap( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, unsigned long *map, struct xfs_attr3_icleaf_hdr *leafhdr) { @@ -405,7 +405,7 @@ out: /* Scrub the extended attribute metadata. */ int xchk_xattr( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xchk_xattr sx; struct attrlist_cursor_kern cursor = { 0 }; diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c index 19cfbd3910a2..0e5166232b15 100644 --- a/fs/xfs/scrub/bmap.c +++ b/fs/xfs/scrub/bmap.c @@ -34,7 +34,7 @@ /* Set us up with an inode's bmap. */ int xchk_setup_inode_bmap( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_inode *ip) { int error; @@ -79,7 +79,7 @@ out: */ struct xchk_bmap_info { - struct xfs_scrub_context *sc; + struct xfs_scrub *sc; xfs_fileoff_t lastoff; bool is_rt; bool is_shared; @@ -391,7 +391,7 @@ xchk_bmapbt_rec( /* Scan the btree records. */ STATIC int xchk_bmap_btree( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, int whichfork, struct xchk_bmap_info *info) { @@ -409,7 +409,7 @@ xchk_bmap_btree( } struct xchk_bmap_check_rmap_info { - struct xfs_scrub_context *sc; + struct xfs_scrub *sc; int whichfork; struct xfs_iext_cursor icur; }; @@ -424,7 +424,7 @@ xchk_bmap_check_rmap( struct xfs_bmbt_irec irec; struct xchk_bmap_check_rmap_info *sbcri = priv; struct xfs_ifork *ifp; - struct xfs_scrub_context *sc = sbcri->sc; + struct xfs_scrub *sc = sbcri->sc; bool have_map; /* Is this even the right fork? */ @@ -488,7 +488,7 @@ out: /* Make sure each rmap has a corresponding bmbt entry. */ STATIC int xchk_bmap_check_ag_rmaps( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, int whichfork, xfs_agnumber_t agno) { @@ -522,7 +522,7 @@ out_agf: /* Make sure each rmap has a corresponding bmbt entry. */ STATIC int xchk_bmap_check_rmaps( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, int whichfork) { loff_t size; @@ -579,7 +579,7 @@ xchk_bmap_check_rmaps( */ STATIC int xchk_bmap( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, int whichfork) { struct xfs_bmbt_irec irec; @@ -694,7 +694,7 @@ out: /* Scrub an inode's data fork. */ int xchk_bmap_data( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { return xchk_bmap(sc, XFS_DATA_FORK); } @@ -702,7 +702,7 @@ xchk_bmap_data( /* Scrub an inode's attr fork. */ int xchk_bmap_attr( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { return xchk_bmap(sc, XFS_ATTR_FORK); } @@ -710,7 +710,7 @@ xchk_bmap_attr( /* Scrub an inode's CoW fork. */ int xchk_bmap_cow( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { if (!xfs_is_reflink_inode(sc->ip)) return -ENOENT; diff --git a/fs/xfs/scrub/btree.c b/fs/xfs/scrub/btree.c index 30fe9a147959..c4e1dce8c5b3 100644 --- a/fs/xfs/scrub/btree.c +++ b/fs/xfs/scrub/btree.c @@ -30,7 +30,7 @@ */ static bool __xchk_btree_process_error( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_btree_cur *cur, int level, int *error, @@ -65,7 +65,7 @@ __xchk_btree_process_error( bool xchk_btree_process_error( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_btree_cur *cur, int level, int *error) @@ -76,7 +76,7 @@ xchk_btree_process_error( bool xchk_btree_xref_process_error( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_btree_cur *cur, int level, int *error) @@ -88,7 +88,7 @@ xchk_btree_xref_process_error( /* Record btree block corruption. */ static void __xchk_btree_set_corrupt( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_btree_cur *cur, int level, __u32 errflag, @@ -106,7 +106,7 @@ __xchk_btree_set_corrupt( void xchk_btree_set_corrupt( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_btree_cur *cur, int level) { @@ -116,7 +116,7 @@ xchk_btree_set_corrupt( void xchk_btree_xref_set_corrupt( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_btree_cur *cur, int level) { @@ -583,7 +583,7 @@ xchk_btree_block_keys( */ int xchk_btree( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_btree_cur *cur, xchk_btree_rec_fn scrub_fn, struct xfs_owner_info *oinfo, diff --git a/fs/xfs/scrub/btree.h b/fs/xfs/scrub/btree.h index 598ac04a6c3e..a0b74b515b9b 100644 --- a/fs/xfs/scrub/btree.h +++ b/fs/xfs/scrub/btree.h @@ -9,20 +9,20 @@ /* btree scrub */ /* Check for btree operation errors. */ -bool xchk_btree_process_error(struct xfs_scrub_context *sc, +bool xchk_btree_process_error(struct xfs_scrub *sc, struct xfs_btree_cur *cur, int level, int *error); /* Check for btree xref operation errors. */ -bool xchk_btree_xref_process_error(struct xfs_scrub_context *sc, +bool xchk_btree_xref_process_error(struct xfs_scrub *sc, struct xfs_btree_cur *cur, int level, int *error); /* Check for btree corruption. */ -void xchk_btree_set_corrupt(struct xfs_scrub_context *sc, +void xchk_btree_set_corrupt(struct xfs_scrub *sc, struct xfs_btree_cur *cur, int level); /* Check for btree xref discrepancies. */ -void xchk_btree_xref_set_corrupt(struct xfs_scrub_context *sc, +void xchk_btree_xref_set_corrupt(struct xfs_scrub *sc, struct xfs_btree_cur *cur, int level); struct xchk_btree; @@ -32,7 +32,7 @@ typedef int (*xchk_btree_rec_fn)( struct xchk_btree { /* caller-provided scrub state */ - struct xfs_scrub_context *sc; + struct xfs_scrub *sc; struct xfs_btree_cur *cur; xchk_btree_rec_fn scrub_rec; struct xfs_owner_info *oinfo; @@ -45,7 +45,7 @@ struct xchk_btree { bool firstkey[XFS_BTREE_MAXLEVELS]; struct list_head to_check; }; -int xchk_btree(struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, +int xchk_btree(struct xfs_scrub *sc, struct xfs_btree_cur *cur, xchk_btree_rec_fn scrub_fn, struct xfs_owner_info *oinfo, void *private); diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index d40bba9e7596..ed9195116556 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -69,7 +69,7 @@ /* Check for operational errors. */ static bool __xchk_process_error( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_agnumber_t agno, xfs_agblock_t bno, int *error, @@ -99,7 +99,7 @@ __xchk_process_error( bool xchk_process_error( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_agnumber_t agno, xfs_agblock_t bno, int *error) @@ -110,7 +110,7 @@ xchk_process_error( bool xchk_xref_process_error( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_agnumber_t agno, xfs_agblock_t bno, int *error) @@ -122,7 +122,7 @@ xchk_xref_process_error( /* Check for operational errors for a file offset. */ static bool __xchk_fblock_process_error( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, int whichfork, xfs_fileoff_t offset, int *error, @@ -152,7 +152,7 @@ __xchk_fblock_process_error( bool xchk_fblock_process_error( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, int whichfork, xfs_fileoff_t offset, int *error) @@ -163,7 +163,7 @@ xchk_fblock_process_error( bool xchk_fblock_xref_process_error( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, int whichfork, xfs_fileoff_t offset, int *error) @@ -187,7 +187,7 @@ xchk_fblock_xref_process_error( /* Record a block which could be optimized. */ void xchk_block_set_preen( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_buf *bp) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_PREEN; @@ -201,7 +201,7 @@ xchk_block_set_preen( */ void xchk_ino_set_preen( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_ino_t ino) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_PREEN; @@ -211,7 +211,7 @@ xchk_ino_set_preen( /* Record a corrupt block. */ void xchk_block_set_corrupt( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_buf *bp) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT; @@ -221,7 +221,7 @@ xchk_block_set_corrupt( /* Record a corruption while cross-referencing. */ void xchk_block_xref_set_corrupt( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_buf *bp) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XCORRUPT; @@ -235,7 +235,7 @@ xchk_block_xref_set_corrupt( */ void xchk_ino_set_corrupt( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_ino_t ino) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT; @@ -245,7 +245,7 @@ xchk_ino_set_corrupt( /* Record a corruption while cross-referencing with an inode. */ void xchk_ino_xref_set_corrupt( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_ino_t ino) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XCORRUPT; @@ -255,7 +255,7 @@ xchk_ino_xref_set_corrupt( /* Record corruption in a block indexed by a file fork. */ void xchk_fblock_set_corrupt( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, int whichfork, xfs_fileoff_t offset) { @@ -266,7 +266,7 @@ xchk_fblock_set_corrupt( /* Record a corruption while cross-referencing a fork block. */ void xchk_fblock_xref_set_corrupt( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, int whichfork, xfs_fileoff_t offset) { @@ -280,7 +280,7 @@ xchk_fblock_xref_set_corrupt( */ void xchk_ino_set_warning( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_ino_t ino) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_WARNING; @@ -290,7 +290,7 @@ xchk_ino_set_warning( /* Warn about a block indexed by a file fork that needs review. */ void xchk_fblock_set_warning( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, int whichfork, xfs_fileoff_t offset) { @@ -301,7 +301,7 @@ xchk_fblock_set_warning( /* Signal an incomplete scrub. */ void xchk_set_incomplete( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_INCOMPLETE; trace_xchk_incomplete(sc, __return_address); @@ -345,7 +345,7 @@ xchk_count_rmap_ownedby_irec( */ int xchk_count_rmap_ownedby_ag( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_btree_cur *cur, struct xfs_owner_info *oinfo, xfs_filblks_t *blocks) @@ -371,7 +371,7 @@ xchk_count_rmap_ownedby_ag( /* Decide if we want to return an AG header read failure. */ static inline bool want_ag_read_header_failure( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, unsigned int type) { /* Return all AG header read failures when scanning btrees. */ @@ -398,7 +398,7 @@ want_ag_read_header_failure( */ int xchk_ag_read_headers( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_agnumber_t agno, struct xfs_buf **agi, struct xfs_buf **agf, @@ -452,7 +452,7 @@ xchk_ag_btcur_free( /* Initialize all the btree cursors for an AG. */ int xchk_ag_btcur_init( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xchk_ag *sa) { struct xfs_mount *mp = sc->mp; @@ -512,7 +512,7 @@ err: /* Release the AG header context and btree cursors. */ void xchk_ag_free( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xchk_ag *sa) { xchk_ag_btcur_free(sa); @@ -544,7 +544,7 @@ xchk_ag_free( */ int xchk_ag_init( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_agnumber_t agno, struct xchk_ag *sa) { @@ -586,7 +586,7 @@ xchk_perag_get( */ int xchk_trans_alloc( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, uint resblks) { if (sc->sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR) @@ -599,7 +599,7 @@ xchk_trans_alloc( /* Set us up with a transaction and an empty context. */ int xchk_setup_fs( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_inode *ip) { uint resblks; @@ -611,7 +611,7 @@ xchk_setup_fs( /* Set us up with AG headers and btree cursors. */ int xchk_setup_ag_btree( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_inode *ip, bool force_log) { @@ -658,7 +658,7 @@ xchk_checkpoint_log( */ int xchk_get_inode( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_inode *ip_in) { struct xfs_imap imap; @@ -722,7 +722,7 @@ xchk_get_inode( /* Set us up to scrub a file's contents. */ int xchk_setup_inode_contents( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_inode *ip, unsigned int resblks) { @@ -753,7 +753,7 @@ out: */ bool xchk_should_check_xref( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, int *error, struct xfs_btree_cur **curpp) { @@ -788,7 +788,7 @@ xchk_should_check_xref( /* Run the structure verifiers on in-memory buffers to detect bad memory. */ void xchk_buffer_recheck( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_buf *bp) { xfs_failaddr_t fa; @@ -814,7 +814,7 @@ xchk_buffer_recheck( */ int xchk_metadata_inode_forks( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { __u32 smtype; bool shared; diff --git a/fs/xfs/scrub/common.h b/fs/xfs/scrub/common.h index 5881cb2ecc26..c321230d32dc 100644 --- a/fs/xfs/scrub/common.h +++ b/fs/xfs/scrub/common.h @@ -13,7 +13,7 @@ */ static inline bool xchk_should_terminate( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, int *error) { if (fatal_signal_pending(current)) { @@ -24,109 +24,109 @@ xchk_should_terminate( return false; } -int xchk_trans_alloc(struct xfs_scrub_context *sc, uint resblks); -bool xchk_process_error(struct xfs_scrub_context *sc, xfs_agnumber_t agno, +int xchk_trans_alloc(struct xfs_scrub *sc, uint resblks); +bool xchk_process_error(struct xfs_scrub *sc, xfs_agnumber_t agno, xfs_agblock_t bno, int *error); -bool xchk_fblock_process_error(struct xfs_scrub_context *sc, int whichfork, +bool xchk_fblock_process_error(struct xfs_scrub *sc, int whichfork, xfs_fileoff_t offset, int *error); -bool xchk_xref_process_error(struct xfs_scrub_context *sc, +bool xchk_xref_process_error(struct xfs_scrub *sc, xfs_agnumber_t agno, xfs_agblock_t bno, int *error); -bool xchk_fblock_xref_process_error(struct xfs_scrub_context *sc, +bool xchk_fblock_xref_process_error(struct xfs_scrub *sc, int whichfork, xfs_fileoff_t offset, int *error); -void xchk_block_set_preen(struct xfs_scrub_context *sc, +void xchk_block_set_preen(struct xfs_scrub *sc, struct xfs_buf *bp); -void xchk_ino_set_preen(struct xfs_scrub_context *sc, xfs_ino_t ino); +void xchk_ino_set_preen(struct xfs_scrub *sc, xfs_ino_t ino); -void xchk_block_set_corrupt(struct xfs_scrub_context *sc, +void xchk_block_set_corrupt(struct xfs_scrub *sc, struct xfs_buf *bp); -void xchk_ino_set_corrupt(struct xfs_scrub_context *sc, xfs_ino_t ino); -void xchk_fblock_set_corrupt(struct xfs_scrub_context *sc, int whichfork, +void xchk_ino_set_corrupt(struct xfs_scrub *sc, xfs_ino_t ino); +void xchk_fblock_set_corrupt(struct xfs_scrub *sc, int whichfork, xfs_fileoff_t offset); -void xchk_block_xref_set_corrupt(struct xfs_scrub_context *sc, +void xchk_block_xref_set_corrupt(struct xfs_scrub *sc, struct xfs_buf *bp); -void xchk_ino_xref_set_corrupt(struct xfs_scrub_context *sc, +void xchk_ino_xref_set_corrupt(struct xfs_scrub *sc, xfs_ino_t ino); -void xchk_fblock_xref_set_corrupt(struct xfs_scrub_context *sc, +void xchk_fblock_xref_set_corrupt(struct xfs_scrub *sc, int whichfork, xfs_fileoff_t offset); -void xchk_ino_set_warning(struct xfs_scrub_context *sc, xfs_ino_t ino); -void xchk_fblock_set_warning(struct xfs_scrub_context *sc, int whichfork, +void xchk_ino_set_warning(struct xfs_scrub *sc, xfs_ino_t ino); +void xchk_fblock_set_warning(struct xfs_scrub *sc, int whichfork, xfs_fileoff_t offset); -void xchk_set_incomplete(struct xfs_scrub_context *sc); +void xchk_set_incomplete(struct xfs_scrub *sc); int xchk_checkpoint_log(struct xfs_mount *mp); /* Are we set up for a cross-referencing check? */ -bool xchk_should_check_xref(struct xfs_scrub_context *sc, int *error, +bool xchk_should_check_xref(struct xfs_scrub *sc, int *error, struct xfs_btree_cur **curpp); /* Setup functions */ -int xchk_setup_fs(struct xfs_scrub_context *sc, struct xfs_inode *ip); -int xchk_setup_ag_allocbt(struct xfs_scrub_context *sc, +int xchk_setup_fs(struct xfs_scrub *sc, struct xfs_inode *ip); +int xchk_setup_ag_allocbt(struct xfs_scrub *sc, struct xfs_inode *ip); -int xchk_setup_ag_iallocbt(struct xfs_scrub_context *sc, +int xchk_setup_ag_iallocbt(struct xfs_scrub *sc, struct xfs_inode *ip); -int xchk_setup_ag_rmapbt(struct xfs_scrub_context *sc, +int xchk_setup_ag_rmapbt(struct xfs_scrub *sc, struct xfs_inode *ip); -int xchk_setup_ag_refcountbt(struct xfs_scrub_context *sc, +int xchk_setup_ag_refcountbt(struct xfs_scrub *sc, struct xfs_inode *ip); -int xchk_setup_inode(struct xfs_scrub_context *sc, +int xchk_setup_inode(struct xfs_scrub *sc, struct xfs_inode *ip); -int xchk_setup_inode_bmap(struct xfs_scrub_context *sc, +int xchk_setup_inode_bmap(struct xfs_scrub *sc, struct xfs_inode *ip); -int xchk_setup_inode_bmap_data(struct xfs_scrub_context *sc, +int xchk_setup_inode_bmap_data(struct xfs_scrub *sc, struct xfs_inode *ip); -int xchk_setup_directory(struct xfs_scrub_context *sc, +int xchk_setup_directory(struct xfs_scrub *sc, struct xfs_inode *ip); -int xchk_setup_xattr(struct xfs_scrub_context *sc, +int xchk_setup_xattr(struct xfs_scrub *sc, struct xfs_inode *ip); -int xchk_setup_symlink(struct xfs_scrub_context *sc, +int xchk_setup_symlink(struct xfs_scrub *sc, struct xfs_inode *ip); -int xchk_setup_parent(struct xfs_scrub_context *sc, +int xchk_setup_parent(struct xfs_scrub *sc, struct xfs_inode *ip); #ifdef CONFIG_XFS_RT -int xchk_setup_rt(struct xfs_scrub_context *sc, struct xfs_inode *ip); +int xchk_setup_rt(struct xfs_scrub *sc, struct xfs_inode *ip); #else static inline int -xchk_setup_rt(struct xfs_scrub_context *sc, struct xfs_inode *ip) +xchk_setup_rt(struct xfs_scrub *sc, struct xfs_inode *ip) { return -ENOENT; } #endif #ifdef CONFIG_XFS_QUOTA -int xchk_setup_quota(struct xfs_scrub_context *sc, struct xfs_inode *ip); +int xchk_setup_quota(struct xfs_scrub *sc, struct xfs_inode *ip); #else static inline int -xchk_setup_quota(struct xfs_scrub_context *sc, struct xfs_inode *ip) +xchk_setup_quota(struct xfs_scrub *sc, struct xfs_inode *ip) { return -ENOENT; } #endif -void xchk_ag_free(struct xfs_scrub_context *sc, struct xchk_ag *sa); -int xchk_ag_init(struct xfs_scrub_context *sc, xfs_agnumber_t agno, +void xchk_ag_free(struct xfs_scrub *sc, struct xchk_ag *sa); +int xchk_ag_init(struct xfs_scrub *sc, xfs_agnumber_t agno, struct xchk_ag *sa); void xchk_perag_get(struct xfs_mount *mp, struct xchk_ag *sa); -int xchk_ag_read_headers(struct xfs_scrub_context *sc, xfs_agnumber_t agno, +int xchk_ag_read_headers(struct xfs_scrub *sc, xfs_agnumber_t agno, struct xfs_buf **agi, struct xfs_buf **agf, struct xfs_buf **agfl); void xchk_ag_btcur_free(struct xchk_ag *sa); -int xchk_ag_btcur_init(struct xfs_scrub_context *sc, +int xchk_ag_btcur_init(struct xfs_scrub *sc, struct xchk_ag *sa); -int xchk_count_rmap_ownedby_ag(struct xfs_scrub_context *sc, +int xchk_count_rmap_ownedby_ag(struct xfs_scrub *sc, struct xfs_btree_cur *cur, struct xfs_owner_info *oinfo, xfs_filblks_t *blocks); -int xchk_setup_ag_btree(struct xfs_scrub_context *sc, +int xchk_setup_ag_btree(struct xfs_scrub *sc, struct xfs_inode *ip, bool force_log); -int xchk_get_inode(struct xfs_scrub_context *sc, struct xfs_inode *ip_in); -int xchk_setup_inode_contents(struct xfs_scrub_context *sc, +int xchk_get_inode(struct xfs_scrub *sc, struct xfs_inode *ip_in); +int xchk_setup_inode_contents(struct xfs_scrub *sc, struct xfs_inode *ip, unsigned int resblks); -void xchk_buffer_recheck(struct xfs_scrub_context *sc, struct xfs_buf *bp); +void xchk_buffer_recheck(struct xfs_scrub *sc, struct xfs_buf *bp); /* * Don't bother cross-referencing if we already found corruption or cross @@ -138,7 +138,7 @@ static inline bool xchk_skip_xref(struct xfs_scrub_metadata *sm) XFS_SCRUB_OFLAG_XCORRUPT); } -int xchk_metadata_inode_forks(struct xfs_scrub_context *sc); +int xchk_metadata_inode_forks(struct xfs_scrub *sc); int xchk_ilock_inverted(struct xfs_inode *ip, uint lock_mode); #endif /* __XFS_SCRUB_COMMON_H__ */ diff --git a/fs/xfs/scrub/dabtree.c b/fs/xfs/scrub/dabtree.c index fee80f6ddfd7..7fc12d540ea6 100644 --- a/fs/xfs/scrub/dabtree.c +++ b/fs/xfs/scrub/dabtree.c @@ -40,7 +40,7 @@ xchk_da_process_error( int level, int *error) { - struct xfs_scrub_context *sc = ds->sc; + struct xfs_scrub *sc = ds->sc; if (*error == 0) return true; @@ -75,7 +75,7 @@ xchk_da_set_corrupt( struct xchk_da_btree *ds, int level) { - struct xfs_scrub_context *sc = ds->sc; + struct xfs_scrub *sc = ds->sc; sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT; @@ -474,7 +474,7 @@ out_nobuf: /* Visit all nodes and leaves of a da btree. */ int xchk_da_btree( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, int whichfork, xchk_da_btree_rec_fn scrub_fn, void *private) diff --git a/fs/xfs/scrub/dabtree.h b/fs/xfs/scrub/dabtree.h index 80e4af0e2589..a15c03389e8f 100644 --- a/fs/xfs/scrub/dabtree.h +++ b/fs/xfs/scrub/dabtree.h @@ -13,7 +13,7 @@ struct xchk_da_btree { xfs_dahash_t hashes[XFS_DA_NODE_MAXDEPTH]; int maxrecs[XFS_DA_NODE_MAXDEPTH]; struct xfs_da_state *state; - struct xfs_scrub_context *sc; + struct xfs_scrub *sc; void *private; /* @@ -39,7 +39,7 @@ void xchk_da_set_corrupt(struct xchk_da_btree *ds, int level); int xchk_da_btree_hash(struct xchk_da_btree *ds, int level, __be32 *hashp); -int xchk_da_btree(struct xfs_scrub_context *sc, int whichfork, +int xchk_da_btree(struct xfs_scrub *sc, int whichfork, xchk_da_btree_rec_fn scrub_fn, void *private); #endif /* __XFS_SCRUB_DABTREE_H__ */ diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c index 2ac07bb73478..194a3ef69a9f 100644 --- a/fs/xfs/scrub/dir.c +++ b/fs/xfs/scrub/dir.c @@ -32,7 +32,7 @@ /* Set us up to scrub directories. */ int xchk_setup_directory( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_inode *ip) { return xchk_setup_inode_contents(sc, ip, 0); @@ -46,7 +46,7 @@ struct xchk_dir_ctx { /* VFS fill-directory iterator */ struct dir_context dir_iter; - struct xfs_scrub_context *sc; + struct xfs_scrub *sc; }; /* Check that an inode's mode matches a given DT_ type. */ @@ -289,7 +289,7 @@ out: */ STATIC void xchk_directory_check_free_entry( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_dablk_t lblk, struct xfs_dir2_data_free *bf, struct xfs_dir2_data_unused *dup) @@ -314,7 +314,7 @@ xchk_directory_check_free_entry( /* Check free space info in a directory data block. */ STATIC int xchk_directory_data_bestfree( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_dablk_t lblk, bool is_block) { @@ -455,7 +455,7 @@ out: */ STATIC void xchk_directory_check_freesp( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_dablk_t lblk, struct xfs_buf *dbp, unsigned int len) @@ -474,7 +474,7 @@ xchk_directory_check_freesp( /* Check free space info in a directory leaf1 block. */ STATIC int xchk_directory_leaf1_bestfree( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_da_args *args, xfs_dablk_t lblk) { @@ -572,7 +572,7 @@ out: /* Check free space info in a directory freespace block. */ STATIC int xchk_directory_free_bestfree( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_da_args *args, xfs_dablk_t lblk) { @@ -626,7 +626,7 @@ out: /* Check free space information in directories. */ STATIC int xchk_directory_blocks( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xfs_bmbt_irec got; struct xfs_da_args args; @@ -770,7 +770,7 @@ out: /* Scrub a whole directory. */ int xchk_directory( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xchk_dir_ctx sdc = { .dir_iter.actor = xchk_dir_actor, diff --git a/fs/xfs/scrub/ialloc.c b/fs/xfs/scrub/ialloc.c index 69d652b7299c..6df8eba9f52b 100644 --- a/fs/xfs/scrub/ialloc.c +++ b/fs/xfs/scrub/ialloc.c @@ -36,7 +36,7 @@ */ int xchk_setup_ag_iallocbt( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_inode *ip) { return xchk_setup_ag_btree(sc, ip, sc->try_harder); @@ -51,7 +51,7 @@ xchk_setup_ag_iallocbt( */ static inline void xchk_iallocbt_chunk_xref_other( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_inobt_rec_incore *irec, xfs_agino_t agino) { @@ -76,7 +76,7 @@ xchk_iallocbt_chunk_xref_other( /* Cross-reference with the other btrees. */ STATIC void xchk_iallocbt_chunk_xref( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_inobt_rec_incore *irec, xfs_agino_t agino, xfs_agblock_t agbno, @@ -363,7 +363,7 @@ out: */ STATIC void xchk_iallocbt_xref_rmap_btreeblks( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, int which) { struct xfs_owner_info oinfo; @@ -403,7 +403,7 @@ xchk_iallocbt_xref_rmap_btreeblks( */ STATIC void xchk_iallocbt_xref_rmap_inodes( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, int which, xfs_filblks_t inode_blocks) { @@ -427,7 +427,7 @@ xchk_iallocbt_xref_rmap_inodes( /* Scrub the inode btrees for some AG. */ STATIC int xchk_iallocbt( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_btnum_t which) { struct xfs_btree_cur *cur; @@ -459,14 +459,14 @@ xchk_iallocbt( int xchk_inobt( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { return xchk_iallocbt(sc, XFS_BTNUM_INO); } int xchk_finobt( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { return xchk_iallocbt(sc, XFS_BTNUM_FINO); } @@ -474,7 +474,7 @@ xchk_finobt( /* See if an inode btree has (or doesn't have) an inode chunk record. */ static inline void xchk_xref_inode_check( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_agblock_t agbno, xfs_extlen_t len, struct xfs_btree_cur **icur, @@ -496,7 +496,7 @@ xchk_xref_inode_check( /* xref check that the extent is not covered by inodes */ void xchk_xref_is_not_inode_chunk( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_agblock_t agbno, xfs_extlen_t len) { @@ -507,7 +507,7 @@ xchk_xref_is_not_inode_chunk( /* xref check that the extent is covered by inodes */ void xchk_xref_is_inode_chunk( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_agblock_t agbno, xfs_extlen_t len) { diff --git a/fs/xfs/scrub/inode.c b/fs/xfs/scrub/inode.c index d85fbec39e52..6cc027983c13 100644 --- a/fs/xfs/scrub/inode.c +++ b/fs/xfs/scrub/inode.c @@ -38,7 +38,7 @@ */ int xchk_setup_inode( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_inode *ip) { int error; @@ -77,7 +77,7 @@ out: /* Validate di_extsize hint. */ STATIC void xchk_inode_extsize( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_dinode *dip, xfs_ino_t ino, uint16_t mode, @@ -99,7 +99,7 @@ xchk_inode_extsize( */ STATIC void xchk_inode_cowextsize( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_dinode *dip, xfs_ino_t ino, uint16_t mode, @@ -118,7 +118,7 @@ xchk_inode_cowextsize( /* Make sure the di_flags make sense for the inode. */ STATIC void xchk_inode_flags( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_dinode *dip, xfs_ino_t ino, uint16_t mode, @@ -163,7 +163,7 @@ bad: /* Make sure the di_flags2 make sense for the inode. */ STATIC void xchk_inode_flags2( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_dinode *dip, xfs_ino_t ino, uint16_t mode, @@ -206,7 +206,7 @@ bad: /* Scrub all the ondisk inode fields. */ STATIC void xchk_dinode( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_dinode *dip, xfs_ino_t ino) { @@ -426,7 +426,7 @@ xchk_dinode( */ static void xchk_inode_xref_finobt( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_ino_t ino) { struct xfs_inobt_rec_incore rec; @@ -469,7 +469,7 @@ xchk_inode_xref_finobt( /* Cross reference the inode fields with the forks. */ STATIC void xchk_inode_xref_bmap( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_dinode *dip) { xfs_extnum_t nextents; @@ -503,7 +503,7 @@ xchk_inode_xref_bmap( /* Cross-reference with the other btrees. */ STATIC void xchk_inode_xref( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_ino_t ino, struct xfs_dinode *dip) { @@ -540,7 +540,7 @@ xchk_inode_xref( */ static void xchk_inode_check_reflink_iflag( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_ino_t ino) { struct xfs_mount *mp = sc->mp; @@ -564,7 +564,7 @@ xchk_inode_check_reflink_iflag( /* Scrub an inode. */ int xchk_inode( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xfs_dinode di; int error = 0; diff --git a/fs/xfs/scrub/parent.c b/fs/xfs/scrub/parent.c index 0a78d8411f23..808459ad0c35 100644 --- a/fs/xfs/scrub/parent.c +++ b/fs/xfs/scrub/parent.c @@ -28,7 +28,7 @@ /* Set us up to scrub parents. */ int xchk_setup_parent( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_inode *ip) { return xchk_setup_inode_contents(sc, ip, 0); @@ -65,7 +65,7 @@ xchk_parent_actor( /* Count the number of dentries in the parent dir that point to this inode. */ STATIC int xchk_parent_count_parent_dentries( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_inode *parent, xfs_nlink_t *nlink) { @@ -121,7 +121,7 @@ out: */ STATIC int xchk_parent_validate( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_ino_t dnum, bool *try_again) { @@ -255,7 +255,7 @@ out: /* Scrub a parent pointer. */ int xchk_parent( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xfs_mount *mp = sc->mp; xfs_ino_t dnum; diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c index d1b52dd7efcd..309ebeecfa5d 100644 --- a/fs/xfs/scrub/quota.c +++ b/fs/xfs/scrub/quota.c @@ -31,7 +31,7 @@ /* Convert a scrub type code to a DQ flag, or return 0 if error. */ static inline uint xchk_quota_to_dqtype( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { switch (sc->sm->sm_type) { case XFS_SCRUB_TYPE_UQUOTA: @@ -48,7 +48,7 @@ xchk_quota_to_dqtype( /* Set us up to scrub a quota. */ int xchk_setup_quota( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_inode *ip) { uint dqtype; @@ -76,7 +76,7 @@ xchk_setup_quota( /* Quotas. */ struct xchk_quota_info { - struct xfs_scrub_context *sc; + struct xfs_scrub *sc; xfs_dqid_t last_id; }; @@ -88,7 +88,7 @@ xchk_quota_item( void *priv) { struct xchk_quota_info *sqi = priv; - struct xfs_scrub_context *sc = sqi->sc; + struct xfs_scrub *sc = sqi->sc; struct xfs_mount *mp = sc->mp; struct xfs_disk_dquot *d = &dq->q_core; struct xfs_quotainfo *qi = mp->m_quotainfo; @@ -195,7 +195,7 @@ xchk_quota_item( /* Check the quota's data fork. */ STATIC int xchk_quota_data_fork( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xfs_bmbt_irec irec = { 0 }; struct xfs_iext_cursor icur; @@ -234,7 +234,7 @@ xchk_quota_data_fork( /* Scrub all of a quota type's items. */ int xchk_quota( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xchk_quota_info sqi; struct xfs_mount *mp = sc->mp; diff --git a/fs/xfs/scrub/refcount.c b/fs/xfs/scrub/refcount.c index 274febc49b23..c1162d408987 100644 --- a/fs/xfs/scrub/refcount.c +++ b/fs/xfs/scrub/refcount.c @@ -29,7 +29,7 @@ */ int xchk_setup_ag_refcountbt( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_inode *ip) { return xchk_setup_ag_btree(sc, ip, false); @@ -79,7 +79,7 @@ struct xchk_refcnt_frag { }; struct xchk_refcnt_check { - struct xfs_scrub_context *sc; + struct xfs_scrub *sc; struct list_head fragments; /* refcount extent we're examining */ @@ -278,7 +278,7 @@ done: /* Use the rmap entries covering this extent to verify the refcount. */ STATIC void xchk_refcountbt_xref_rmap( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_agblock_t bno, xfs_extlen_t len, xfs_nlink_t refcount) @@ -325,7 +325,7 @@ out_free: /* Cross-reference with the other btrees. */ STATIC void xchk_refcountbt_xref( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_agblock_t agbno, xfs_extlen_t len, xfs_nlink_t refcount) @@ -382,7 +382,7 @@ xchk_refcountbt_rec( /* Make sure we have as many refc blocks as the rmap says. */ STATIC void xchk_refcount_xref_rmap( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_owner_info *oinfo, xfs_filblks_t cow_blocks) { @@ -417,7 +417,7 @@ xchk_refcount_xref_rmap( /* Scrub the refcount btree for some AG. */ int xchk_refcountbt( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xfs_owner_info oinfo; xfs_agblock_t cow_blocks = 0; @@ -437,7 +437,7 @@ xchk_refcountbt( /* xref check that a cow staging extent is marked in the refcountbt. */ void xchk_xref_is_cow_staging( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_agblock_t agbno, xfs_extlen_t len) { @@ -483,7 +483,7 @@ xchk_xref_is_cow_staging( */ void xchk_xref_is_not_shared( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_agblock_t agbno, xfs_extlen_t len) { diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 7e6a56a5f59d..29debd5649ac 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -43,7 +43,7 @@ int xrep_attempt( struct xfs_inode *ip, - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, bool *fixed) { int error = 0; @@ -106,7 +106,7 @@ xrep_failure( */ int xrep_probe( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { int error = 0; @@ -122,7 +122,7 @@ xrep_probe( */ int xrep_roll_ag_trans( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { int error; @@ -179,7 +179,7 @@ xrep_ag_has_space( */ xfs_extlen_t xrep_calc_ag_resblks( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xfs_mount *mp = sc->mp; struct xfs_scrub_metadata *sm = sc->sm; @@ -279,7 +279,7 @@ xrep_calc_ag_resblks( /* Allocate a block in an AG. */ int xrep_alloc_ag_block( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_owner_info *oinfo, xfs_fsblock_t *fsbno, enum xfs_ag_resv_type resv) @@ -330,7 +330,7 @@ xrep_alloc_ag_block( /* Initialize a new AG btree root block with zero entries. */ int xrep_init_btblock( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_fsblock_t fsb, struct xfs_buf **bpp, xfs_btnum_t btnum, @@ -385,7 +385,7 @@ xrep_init_btblock( /* Collect a dead btree extent for later disposal. */ int xrep_collect_btree_extent( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xrep_extent_list *exlist, xfs_fsblock_t fsbno, xfs_extlen_t len) @@ -415,7 +415,7 @@ xrep_collect_btree_extent( */ void xrep_cancel_btree_extents( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xrep_extent_list *exlist) { struct xrep_extent *rex; @@ -463,7 +463,7 @@ xrep_btree_extent_cmp( #define RIGHT_ALIGNED (1 << 1) int xrep_subtract_extents( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xrep_extent_list *exlist, struct xrep_extent_list *sublist) { @@ -620,7 +620,7 @@ out: */ int xrep_invalidate_blocks( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xrep_extent_list *exlist) { struct xrep_extent *rex; @@ -658,7 +658,7 @@ xrep_invalidate_blocks( /* Ensure the freelist is the correct size. */ int xrep_fix_freelist( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, bool can_shrink) { struct xfs_alloc_arg args = {0}; @@ -678,7 +678,7 @@ xrep_fix_freelist( */ STATIC int xrep_put_freelist( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_agblock_t agbno) { struct xfs_owner_info oinfo; @@ -714,7 +714,7 @@ xrep_put_freelist( /* Dispose of a single metadata block. */ STATIC int xrep_dispose_btree_block( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_fsblock_t fsbno, struct xfs_owner_info *oinfo, enum xfs_ag_resv_type resv) @@ -788,7 +788,7 @@ out_free: /* Dispose of btree blocks from an old per-AG btree. */ int xrep_reap_btree_extents( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xrep_extent_list *exlist, struct xfs_owner_info *oinfo, enum xfs_ag_resv_type type) @@ -851,7 +851,7 @@ out: */ struct xrep_findroot { - struct xfs_scrub_context *sc; + struct xfs_scrub *sc; struct xfs_buf *agfl_bp; struct xfs_agf *agf; struct xrep_find_ag_btree *btree_info; @@ -981,7 +981,7 @@ xrep_findroot_rmap( /* Find the roots of the per-AG btrees described in btree_info. */ int xrep_find_ag_btree_roots( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_buf *agf_bp, struct xrep_find_ag_btree *btree_info, struct xfs_buf *agfl_bp) @@ -1016,7 +1016,7 @@ xrep_find_ag_btree_roots( /* Force a quotacheck the next time we mount. */ void xrep_force_quotacheck( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, uint dqtype) { uint flag; @@ -1044,7 +1044,7 @@ xrep_force_quotacheck( */ int xrep_ino_dqattach( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { int error; diff --git a/fs/xfs/scrub/repair.h b/fs/xfs/scrub/repair.h index 60d81294797b..677f4b73b5ec 100644 --- a/fs/xfs/scrub/repair.h +++ b/fs/xfs/scrub/repair.h @@ -6,7 +6,7 @@ #ifndef __XFS_SCRUB_REPAIR_H__ #define __XFS_SCRUB_REPAIR_H__ -static inline int xrep_notsupported(struct xfs_scrub_context *sc) +static inline int xrep_notsupported(struct xfs_scrub *sc) { return -EOPNOTSUPP; } @@ -15,17 +15,17 @@ static inline int xrep_notsupported(struct xfs_scrub_context *sc) /* Repair helpers */ -int xrep_attempt(struct xfs_inode *ip, struct xfs_scrub_context *sc, +int xrep_attempt(struct xfs_inode *ip, struct xfs_scrub *sc, bool *fixed); void xrep_failure(struct xfs_mount *mp); -int xrep_roll_ag_trans(struct xfs_scrub_context *sc); +int xrep_roll_ag_trans(struct xfs_scrub *sc); bool xrep_ag_has_space(struct xfs_perag *pag, xfs_extlen_t nr_blocks, enum xfs_ag_resv_type type); -xfs_extlen_t xrep_calc_ag_resblks(struct xfs_scrub_context *sc); -int xrep_alloc_ag_block(struct xfs_scrub_context *sc, +xfs_extlen_t xrep_calc_ag_resblks(struct xfs_scrub *sc); +int xrep_alloc_ag_block(struct xfs_scrub *sc, struct xfs_owner_info *oinfo, xfs_fsblock_t *fsbno, enum xfs_ag_resv_type resv); -int xrep_init_btblock(struct xfs_scrub_context *sc, xfs_fsblock_t fsb, +int xrep_init_btblock(struct xfs_scrub *sc, xfs_fsblock_t fsb, struct xfs_buf **bpp, xfs_btnum_t btnum, const struct xfs_buf_ops *ops); @@ -48,18 +48,18 @@ xrep_init_extent_list( #define for_each_xrep_extent_safe(rbe, n, exlist) \ list_for_each_entry_safe((rbe), (n), &(exlist)->list, list) -int xrep_collect_btree_extent(struct xfs_scrub_context *sc, +int xrep_collect_btree_extent(struct xfs_scrub *sc, struct xrep_extent_list *btlist, xfs_fsblock_t fsbno, xfs_extlen_t len); -void xrep_cancel_btree_extents(struct xfs_scrub_context *sc, +void xrep_cancel_btree_extents(struct xfs_scrub *sc, struct xrep_extent_list *btlist); -int xrep_subtract_extents(struct xfs_scrub_context *sc, +int xrep_subtract_extents(struct xfs_scrub *sc, struct xrep_extent_list *exlist, struct xrep_extent_list *sublist); -int xrep_fix_freelist(struct xfs_scrub_context *sc, bool can_shrink); -int xrep_invalidate_blocks(struct xfs_scrub_context *sc, +int xrep_fix_freelist(struct xfs_scrub *sc, bool can_shrink); +int xrep_invalidate_blocks(struct xfs_scrub *sc, struct xrep_extent_list *btlist); -int xrep_reap_btree_extents(struct xfs_scrub_context *sc, +int xrep_reap_btree_extents(struct xfs_scrub *sc, struct xrep_extent_list *exlist, struct xfs_owner_info *oinfo, enum xfs_ag_resv_type type); @@ -78,23 +78,23 @@ struct xrep_find_ag_btree { unsigned int height; }; -int xrep_find_ag_btree_roots(struct xfs_scrub_context *sc, +int xrep_find_ag_btree_roots(struct xfs_scrub *sc, struct xfs_buf *agf_bp, struct xrep_find_ag_btree *btree_info, struct xfs_buf *agfl_bp); -void xrep_force_quotacheck(struct xfs_scrub_context *sc, uint dqtype); -int xrep_ino_dqattach(struct xfs_scrub_context *sc); +void xrep_force_quotacheck(struct xfs_scrub *sc, uint dqtype); +int xrep_ino_dqattach(struct xfs_scrub *sc); /* Metadata repairers */ -int xrep_probe(struct xfs_scrub_context *sc); -int xrep_superblock(struct xfs_scrub_context *sc); +int xrep_probe(struct xfs_scrub *sc); +int xrep_superblock(struct xfs_scrub *sc); #else static inline int xrep_attempt( struct xfs_inode *ip, - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, bool *fixed) { return -EOPNOTSUPP; @@ -104,7 +104,7 @@ static inline void xrep_failure(struct xfs_mount *mp) {} static inline xfs_extlen_t xrep_calc_ag_resblks( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { ASSERT(!(sc->sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR)); return 0; diff --git a/fs/xfs/scrub/rmap.c b/fs/xfs/scrub/rmap.c index 4b75fc2f31f3..dc9c91a706ff 100644 --- a/fs/xfs/scrub/rmap.c +++ b/fs/xfs/scrub/rmap.c @@ -30,7 +30,7 @@ */ int xchk_setup_ag_rmapbt( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_inode *ip) { return xchk_setup_ag_btree(sc, ip, false); @@ -41,7 +41,7 @@ xchk_setup_ag_rmapbt( /* Cross-reference a rmap against the refcount btree. */ STATIC void xchk_rmapbt_xref_refc( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_rmap_irec *irec) { xfs_agblock_t fbno; @@ -72,7 +72,7 @@ xchk_rmapbt_xref_refc( /* Cross-reference with the other btrees. */ STATIC void xchk_rmapbt_xref( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_rmap_irec *irec) { xfs_agblock_t agbno = irec->rm_startblock; @@ -172,7 +172,7 @@ out: /* Scrub the rmap btree for some AG. */ int xchk_rmapbt( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xfs_owner_info oinfo; @@ -184,7 +184,7 @@ xchk_rmapbt( /* xref check that the extent is owned by a given owner */ static inline void xchk_xref_check_owner( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_agblock_t bno, xfs_extlen_t len, struct xfs_owner_info *oinfo, @@ -207,7 +207,7 @@ xchk_xref_check_owner( /* xref check that the extent is owned by a given owner */ void xchk_xref_is_owned_by( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_agblock_t bno, xfs_extlen_t len, struct xfs_owner_info *oinfo) @@ -218,7 +218,7 @@ xchk_xref_is_owned_by( /* xref check that the extent is not owned by a given owner */ void xchk_xref_is_not_owned_by( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_agblock_t bno, xfs_extlen_t len, struct xfs_owner_info *oinfo) @@ -229,7 +229,7 @@ xchk_xref_is_not_owned_by( /* xref check that the extent has no reverse mapping at all */ void xchk_xref_has_no_owner( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_agblock_t bno, xfs_extlen_t len) { diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c index 3f0fc83562ae..653a809bba34 100644 --- a/fs/xfs/scrub/rtbitmap.c +++ b/fs/xfs/scrub/rtbitmap.c @@ -26,7 +26,7 @@ /* Set us up with the realtime metadata locked. */ int xchk_setup_rt( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_inode *ip) { int error; @@ -51,7 +51,7 @@ xchk_rtbitmap_rec( struct xfs_rtalloc_rec *rec, void *priv) { - struct xfs_scrub_context *sc = priv; + struct xfs_scrub *sc = priv; xfs_rtblock_t startblock; xfs_rtblock_t blockcount; @@ -68,7 +68,7 @@ xchk_rtbitmap_rec( /* Scrub the realtime bitmap. */ int xchk_rtbitmap( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { int error; @@ -88,7 +88,7 @@ out: /* Scrub the realtime summary. */ int xchk_rtsummary( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xfs_inode *rsumip = sc->mp->m_rsumip; struct xfs_inode *old_ip = sc->ip; @@ -125,7 +125,7 @@ out: /* xref check that the extent is not free in the rtbitmap */ void xchk_xref_is_used_rt_space( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, xfs_rtblock_t fsbno, xfs_extlen_t len) { diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c index a6efede6e430..b3c6420ccae5 100644 --- a/fs/xfs/scrub/scrub.c +++ b/fs/xfs/scrub/scrub.c @@ -151,7 +151,7 @@ */ static int xchk_probe( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { int error = 0; @@ -166,7 +166,7 @@ xchk_probe( /* Free all the resources and finish the transactions. */ STATIC int xchk_teardown( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_inode *ip_in, int error) { @@ -447,7 +447,7 @@ out: } #ifdef CONFIG_XFS_ONLINE_REPAIR -static inline void xchk_postmortem(struct xfs_scrub_context *sc) +static inline void xchk_postmortem(struct xfs_scrub *sc) { /* * Userspace asked us to repair something, we repaired it, rescanned @@ -460,7 +460,7 @@ static inline void xchk_postmortem(struct xfs_scrub_context *sc) xrep_failure(sc->mp); } #else -static inline void xchk_postmortem(struct xfs_scrub_context *sc) +static inline void xchk_postmortem(struct xfs_scrub *sc) { /* * Userspace asked us to scrub something, it's broken, and we have no @@ -479,7 +479,7 @@ xfs_scrub_metadata( struct xfs_inode *ip, struct xfs_scrub_metadata *sm) { - struct xfs_scrub_context sc; + struct xfs_scrub sc; struct xfs_mount *mp = ip->i_mount; bool try_harder = false; bool already_fixed = false; diff --git a/fs/xfs/scrub/scrub.h b/fs/xfs/scrub/scrub.h index 0f59a47c4bb0..47c75d2f28da 100644 --- a/fs/xfs/scrub/scrub.h +++ b/fs/xfs/scrub/scrub.h @@ -6,7 +6,7 @@ #ifndef __XFS_SCRUB_SCRUB_H__ #define __XFS_SCRUB_SCRUB_H__ -struct xfs_scrub_context; +struct xfs_scrub; /* Type info and names for the scrub types. */ enum xchk_type { @@ -18,14 +18,14 @@ enum xchk_type { struct xchk_meta_ops { /* Acquire whatever resources are needed for the operation. */ - int (*setup)(struct xfs_scrub_context *, + int (*setup)(struct xfs_scrub *, struct xfs_inode *); /* Examine metadata for errors. */ - int (*scrub)(struct xfs_scrub_context *); + int (*scrub)(struct xfs_scrub *); /* Repair or optimize the metadata. */ - int (*repair)(struct xfs_scrub_context *); + int (*repair)(struct xfs_scrub *); /* Decide if we even have this piece of metadata. */ bool (*has)(struct xfs_sb *); @@ -53,7 +53,7 @@ struct xchk_ag { struct xfs_btree_cur *refc_cur; }; -struct xfs_scrub_context { +struct xfs_scrub { /* General scrub state. */ struct xfs_mount *mp; struct xfs_scrub_metadata *sm; @@ -70,71 +70,71 @@ struct xfs_scrub_context { }; /* Metadata scrubbers */ -int xchk_tester(struct xfs_scrub_context *sc); -int xchk_superblock(struct xfs_scrub_context *sc); -int xchk_agf(struct xfs_scrub_context *sc); -int xchk_agfl(struct xfs_scrub_context *sc); -int xchk_agi(struct xfs_scrub_context *sc); -int xchk_bnobt(struct xfs_scrub_context *sc); -int xchk_cntbt(struct xfs_scrub_context *sc); -int xchk_inobt(struct xfs_scrub_context *sc); -int xchk_finobt(struct xfs_scrub_context *sc); -int xchk_rmapbt(struct xfs_scrub_context *sc); -int xchk_refcountbt(struct xfs_scrub_context *sc); -int xchk_inode(struct xfs_scrub_context *sc); -int xchk_bmap_data(struct xfs_scrub_context *sc); -int xchk_bmap_attr(struct xfs_scrub_context *sc); -int xchk_bmap_cow(struct xfs_scrub_context *sc); -int xchk_directory(struct xfs_scrub_context *sc); -int xchk_xattr(struct xfs_scrub_context *sc); -int xchk_symlink(struct xfs_scrub_context *sc); -int xchk_parent(struct xfs_scrub_context *sc); +int xchk_tester(struct xfs_scrub *sc); +int xchk_superblock(struct xfs_scrub *sc); +int xchk_agf(struct xfs_scrub *sc); +int xchk_agfl(struct xfs_scrub *sc); +int xchk_agi(struct xfs_scrub *sc); +int xchk_bnobt(struct xfs_scrub *sc); +int xchk_cntbt(struct xfs_scrub *sc); +int xchk_inobt(struct xfs_scrub *sc); +int xchk_finobt(struct xfs_scrub *sc); +int xchk_rmapbt(struct xfs_scrub *sc); +int xchk_refcountbt(struct xfs_scrub *sc); +int xchk_inode(struct xfs_scrub *sc); +int xchk_bmap_data(struct xfs_scrub *sc); +int xchk_bmap_attr(struct xfs_scrub *sc); +int xchk_bmap_cow(struct xfs_scrub *sc); +int xchk_directory(struct xfs_scrub *sc); +int xchk_xattr(struct xfs_scrub *sc); +int xchk_symlink(struct xfs_scrub *sc); +int xchk_parent(struct xfs_scrub *sc); #ifdef CONFIG_XFS_RT -int xchk_rtbitmap(struct xfs_scrub_context *sc); -int xchk_rtsummary(struct xfs_scrub_context *sc); +int xchk_rtbitmap(struct xfs_scrub *sc); +int xchk_rtsummary(struct xfs_scrub *sc); #else static inline int -xchk_rtbitmap(struct xfs_scrub_context *sc) +xchk_rtbitmap(struct xfs_scrub *sc) { return -ENOENT; } static inline int -xchk_rtsummary(struct xfs_scrub_context *sc) +xchk_rtsummary(struct xfs_scrub *sc) { return -ENOENT; } #endif #ifdef CONFIG_XFS_QUOTA -int xchk_quota(struct xfs_scrub_context *sc); +int xchk_quota(struct xfs_scrub *sc); #else static inline int -xchk_quota(struct xfs_scrub_context *sc) +xchk_quota(struct xfs_scrub *sc) { return -ENOENT; } #endif /* cross-referencing helpers */ -void xchk_xref_is_used_space(struct xfs_scrub_context *sc, +void xchk_xref_is_used_space(struct xfs_scrub *sc, xfs_agblock_t agbno, xfs_extlen_t len); -void xchk_xref_is_not_inode_chunk(struct xfs_scrub_context *sc, +void xchk_xref_is_not_inode_chunk(struct xfs_scrub *sc, xfs_agblock_t agbno, xfs_extlen_t len); -void xchk_xref_is_inode_chunk(struct xfs_scrub_context *sc, +void xchk_xref_is_inode_chunk(struct xfs_scrub *sc, xfs_agblock_t agbno, xfs_extlen_t len); -void xchk_xref_is_owned_by(struct xfs_scrub_context *sc, +void xchk_xref_is_owned_by(struct xfs_scrub *sc, xfs_agblock_t agbno, xfs_extlen_t len, struct xfs_owner_info *oinfo); -void xchk_xref_is_not_owned_by(struct xfs_scrub_context *sc, +void xchk_xref_is_not_owned_by(struct xfs_scrub *sc, xfs_agblock_t agbno, xfs_extlen_t len, struct xfs_owner_info *oinfo); -void xchk_xref_has_no_owner(struct xfs_scrub_context *sc, +void xchk_xref_has_no_owner(struct xfs_scrub *sc, xfs_agblock_t agbno, xfs_extlen_t len); -void xchk_xref_is_cow_staging(struct xfs_scrub_context *sc, +void xchk_xref_is_cow_staging(struct xfs_scrub *sc, xfs_agblock_t bno, xfs_extlen_t len); -void xchk_xref_is_not_shared(struct xfs_scrub_context *sc, +void xchk_xref_is_not_shared(struct xfs_scrub *sc, xfs_agblock_t bno, xfs_extlen_t len); #ifdef CONFIG_XFS_RT -void xchk_xref_is_used_rt_space(struct xfs_scrub_context *sc, +void xchk_xref_is_used_rt_space(struct xfs_scrub *sc, xfs_rtblock_t rtbno, xfs_extlen_t len); #else # define xchk_xref_is_used_rt_space(sc, rtbno, len) do { } while (0) diff --git a/fs/xfs/scrub/symlink.c b/fs/xfs/scrub/symlink.c index e2a288e34337..56c6347e9482 100644 --- a/fs/xfs/scrub/symlink.c +++ b/fs/xfs/scrub/symlink.c @@ -26,7 +26,7 @@ /* Set us up to scrub a symbolic link. */ int xchk_setup_symlink( - struct xfs_scrub_context *sc, + struct xfs_scrub *sc, struct xfs_inode *ip) { /* Allocate the buffer without the inode lock held. */ @@ -41,7 +41,7 @@ xchk_setup_symlink( int xchk_symlink( - struct xfs_scrub_context *sc) + struct xfs_scrub *sc) { struct xfs_inode *ip = sc->ip; struct xfs_ifork *ifp; diff --git a/fs/xfs/scrub/trace.h b/fs/xfs/scrub/trace.h index 96f3edda3e91..93db22c39b51 100644 --- a/fs/xfs/scrub/trace.h +++ b/fs/xfs/scrub/trace.h @@ -59,7 +59,7 @@ DEFINE_SCRUB_EVENT(xrep_attempt); DEFINE_SCRUB_EVENT(xrep_done); TRACE_EVENT(xchk_op_error, - TP_PROTO(struct xfs_scrub_context *sc, xfs_agnumber_t agno, + TP_PROTO(struct xfs_scrub *sc, xfs_agnumber_t agno, xfs_agblock_t bno, int error, void *ret_ip), TP_ARGS(sc, agno, bno, error, ret_ip), TP_STRUCT__entry( @@ -88,7 +88,7 @@ TRACE_EVENT(xchk_op_error, ); TRACE_EVENT(xchk_file_op_error, - TP_PROTO(struct xfs_scrub_context *sc, int whichfork, + TP_PROTO(struct xfs_scrub *sc, int whichfork, xfs_fileoff_t offset, int error, void *ret_ip), TP_ARGS(sc, whichfork, offset, error, ret_ip), TP_STRUCT__entry( @@ -120,7 +120,7 @@ TRACE_EVENT(xchk_file_op_error, ); DECLARE_EVENT_CLASS(xchk_block_error_class, - TP_PROTO(struct xfs_scrub_context *sc, xfs_daddr_t daddr, void *ret_ip), + TP_PROTO(struct xfs_scrub *sc, xfs_daddr_t daddr, void *ret_ip), TP_ARGS(sc, daddr, ret_ip), TP_STRUCT__entry( __field(dev_t, dev) @@ -154,7 +154,7 @@ DECLARE_EVENT_CLASS(xchk_block_error_class, #define DEFINE_SCRUB_BLOCK_ERROR_EVENT(name) \ DEFINE_EVENT(xchk_block_error_class, name, \ - TP_PROTO(struct xfs_scrub_context *sc, xfs_daddr_t daddr, \ + TP_PROTO(struct xfs_scrub *sc, xfs_daddr_t daddr, \ void *ret_ip), \ TP_ARGS(sc, daddr, ret_ip)) @@ -162,7 +162,7 @@ DEFINE_SCRUB_BLOCK_ERROR_EVENT(xchk_block_error); DEFINE_SCRUB_BLOCK_ERROR_EVENT(xchk_block_preen); DECLARE_EVENT_CLASS(xchk_ino_error_class, - TP_PROTO(struct xfs_scrub_context *sc, xfs_ino_t ino, void *ret_ip), + TP_PROTO(struct xfs_scrub *sc, xfs_ino_t ino, void *ret_ip), TP_ARGS(sc, ino, ret_ip), TP_STRUCT__entry( __field(dev_t, dev) @@ -185,7 +185,7 @@ DECLARE_EVENT_CLASS(xchk_ino_error_class, #define DEFINE_SCRUB_INO_ERROR_EVENT(name) \ DEFINE_EVENT(xchk_ino_error_class, name, \ - TP_PROTO(struct xfs_scrub_context *sc, xfs_ino_t ino, \ + TP_PROTO(struct xfs_scrub *sc, xfs_ino_t ino, \ void *ret_ip), \ TP_ARGS(sc, ino, ret_ip)) @@ -194,7 +194,7 @@ DEFINE_SCRUB_INO_ERROR_EVENT(xchk_ino_preen); DEFINE_SCRUB_INO_ERROR_EVENT(xchk_ino_warning); DECLARE_EVENT_CLASS(xchk_fblock_error_class, - TP_PROTO(struct xfs_scrub_context *sc, int whichfork, + TP_PROTO(struct xfs_scrub *sc, int whichfork, xfs_fileoff_t offset, void *ret_ip), TP_ARGS(sc, whichfork, offset, ret_ip), TP_STRUCT__entry( @@ -224,7 +224,7 @@ DECLARE_EVENT_CLASS(xchk_fblock_error_class, #define DEFINE_SCRUB_FBLOCK_ERROR_EVENT(name) \ DEFINE_EVENT(xchk_fblock_error_class, name, \ - TP_PROTO(struct xfs_scrub_context *sc, int whichfork, \ + TP_PROTO(struct xfs_scrub *sc, int whichfork, \ xfs_fileoff_t offset, void *ret_ip), \ TP_ARGS(sc, whichfork, offset, ret_ip)) @@ -232,7 +232,7 @@ DEFINE_SCRUB_FBLOCK_ERROR_EVENT(xchk_fblock_error); DEFINE_SCRUB_FBLOCK_ERROR_EVENT(xchk_fblock_warning); TRACE_EVENT(xchk_incomplete, - TP_PROTO(struct xfs_scrub_context *sc, void *ret_ip), + TP_PROTO(struct xfs_scrub *sc, void *ret_ip), TP_ARGS(sc, ret_ip), TP_STRUCT__entry( __field(dev_t, dev) @@ -251,7 +251,7 @@ TRACE_EVENT(xchk_incomplete, ); TRACE_EVENT(xchk_btree_op_error, - TP_PROTO(struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, + TP_PROTO(struct xfs_scrub *sc, struct xfs_btree_cur *cur, int level, int error, void *ret_ip), TP_ARGS(sc, cur, level, error, ret_ip), TP_STRUCT__entry( @@ -291,7 +291,7 @@ TRACE_EVENT(xchk_btree_op_error, ); TRACE_EVENT(xchk_ifork_btree_op_error, - TP_PROTO(struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, + TP_PROTO(struct xfs_scrub *sc, struct xfs_btree_cur *cur, int level, int error, void *ret_ip), TP_ARGS(sc, cur, level, error, ret_ip), TP_STRUCT__entry( @@ -336,7 +336,7 @@ TRACE_EVENT(xchk_ifork_btree_op_error, ); TRACE_EVENT(xchk_btree_error, - TP_PROTO(struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, + TP_PROTO(struct xfs_scrub *sc, struct xfs_btree_cur *cur, int level, void *ret_ip), TP_ARGS(sc, cur, level, ret_ip), TP_STRUCT__entry( @@ -372,7 +372,7 @@ TRACE_EVENT(xchk_btree_error, ); TRACE_EVENT(xchk_ifork_btree_error, - TP_PROTO(struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, + TP_PROTO(struct xfs_scrub *sc, struct xfs_btree_cur *cur, int level, void *ret_ip), TP_ARGS(sc, cur, level, ret_ip), TP_STRUCT__entry( @@ -414,7 +414,7 @@ TRACE_EVENT(xchk_ifork_btree_error, ); DECLARE_EVENT_CLASS(xchk_sbtree_class, - TP_PROTO(struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, + TP_PROTO(struct xfs_scrub *sc, struct xfs_btree_cur *cur, int level), TP_ARGS(sc, cur, level), TP_STRUCT__entry( @@ -451,7 +451,7 @@ DECLARE_EVENT_CLASS(xchk_sbtree_class, ) #define DEFINE_SCRUB_SBTREE_EVENT(name) \ DEFINE_EVENT(xchk_sbtree_class, name, \ - TP_PROTO(struct xfs_scrub_context *sc, struct xfs_btree_cur *cur, \ + TP_PROTO(struct xfs_scrub *sc, struct xfs_btree_cur *cur, \ int level), \ TP_ARGS(sc, cur, level)) @@ -459,7 +459,7 @@ DEFINE_SCRUB_SBTREE_EVENT(xchk_btree_rec); DEFINE_SCRUB_SBTREE_EVENT(xchk_btree_key); TRACE_EVENT(xchk_xref_error, - TP_PROTO(struct xfs_scrub_context *sc, int error, void *ret_ip), + TP_PROTO(struct xfs_scrub *sc, int error, void *ret_ip), TP_ARGS(sc, error, ret_ip), TP_STRUCT__entry( __field(dev_t, dev) -- cgit v1.2.3 From 032d91f9820f6d241dc5584c27a668cfd377aaf0 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 19 Jul 2018 12:29:12 -0700 Subject: xfs: fix indentation and other whitespace problems in scrub/repair Now that we've shortened everything, fix up all the indentation and whitespace problems. There are no functional changes. Signed-off-by: Darrick J. Wong Reviewed-by: Brian Foster --- fs/xfs/scrub/agheader.c | 172 ++++++++++++++++++++--------------------- fs/xfs/scrub/agheader_repair.c | 8 +- fs/xfs/scrub/alloc.c | 48 ++++++------ fs/xfs/scrub/attr.c | 20 ++--- fs/xfs/scrub/bmap.c | 150 +++++++++++++++++------------------ fs/xfs/scrub/btree.c | 172 ++++++++++++++++++++--------------------- fs/xfs/scrub/btree.h | 25 +++--- fs/xfs/scrub/common.c | 158 ++++++++++++++++++------------------- fs/xfs/scrub/common.h | 23 +++--- fs/xfs/scrub/dabtree.c | 56 +++++++------- fs/xfs/scrub/dabtree.h | 21 +++-- fs/xfs/scrub/dir.c | 88 ++++++++++----------- fs/xfs/scrub/ialloc.c | 58 +++++++------- fs/xfs/scrub/inode.c | 102 ++++++++++++------------ fs/xfs/scrub/parent.c | 60 +++++++------- fs/xfs/scrub/quota.c | 68 ++++++++-------- fs/xfs/scrub/refcount.c | 70 ++++++++--------- fs/xfs/scrub/repair.c | 148 +++++++++++++++++------------------ fs/xfs/scrub/repair.h | 28 +++---- fs/xfs/scrub/rmap.c | 78 +++++++++---------- fs/xfs/scrub/rtbitmap.c | 38 ++++----- fs/xfs/scrub/scrub.c | 8 +- fs/xfs/scrub/scrub.h | 62 +++++++-------- fs/xfs/scrub/symlink.c | 10 +-- fs/xfs/scrub/trace.c | 4 +- 25 files changed, 832 insertions(+), 843 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/scrub/agheader.c b/fs/xfs/scrub/agheader.c index 14ba4189ae8f..3068a9382feb 100644 --- a/fs/xfs/scrub/agheader.c +++ b/fs/xfs/scrub/agheader.c @@ -30,13 +30,13 @@ STATIC void xchk_superblock_xref( struct xfs_scrub *sc, - struct xfs_buf *bp) + struct xfs_buf *bp) { - struct xfs_owner_info oinfo; - struct xfs_mount *mp = sc->mp; - xfs_agnumber_t agno = sc->sm->sm_agno; - xfs_agblock_t agbno; - int error; + struct xfs_owner_info oinfo; + struct xfs_mount *mp = sc->mp; + xfs_agnumber_t agno = sc->sm->sm_agno; + xfs_agblock_t agbno; + int error; if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) return; @@ -68,14 +68,14 @@ int xchk_superblock( struct xfs_scrub *sc) { - struct xfs_mount *mp = sc->mp; - struct xfs_buf *bp; - struct xfs_dsb *sb; - xfs_agnumber_t agno; - uint32_t v2_ok; - __be32 features_mask; - int error; - __be16 vernum_mask; + struct xfs_mount *mp = sc->mp; + struct xfs_buf *bp; + struct xfs_dsb *sb; + xfs_agnumber_t agno; + uint32_t v2_ok; + __be32 features_mask; + int error; + __be16 vernum_mask; agno = sc->sm->sm_agno; if (agno == 0) @@ -367,9 +367,9 @@ static inline void xchk_agf_xref_freeblks( struct xfs_scrub *sc) { - struct xfs_agf *agf = XFS_BUF_TO_AGF(sc->sa.agf_bp); - xfs_extlen_t blocks = 0; - int error; + struct xfs_agf *agf = XFS_BUF_TO_AGF(sc->sa.agf_bp); + xfs_extlen_t blocks = 0; + int error; if (!sc->sa.bno_cur) return; @@ -387,11 +387,11 @@ static inline void xchk_agf_xref_cntbt( struct xfs_scrub *sc) { - struct xfs_agf *agf = XFS_BUF_TO_AGF(sc->sa.agf_bp); - xfs_agblock_t agbno; - xfs_extlen_t blocks; - int have; - int error; + struct xfs_agf *agf = XFS_BUF_TO_AGF(sc->sa.agf_bp); + xfs_agblock_t agbno; + xfs_extlen_t blocks; + int have; + int error; if (!sc->sa.cnt_cur) return; @@ -419,11 +419,11 @@ STATIC void xchk_agf_xref_btreeblks( struct xfs_scrub *sc) { - struct xfs_agf *agf = XFS_BUF_TO_AGF(sc->sa.agf_bp); - struct xfs_mount *mp = sc->mp; - xfs_agblock_t blocks; - xfs_agblock_t btreeblks; - int error; + struct xfs_agf *agf = XFS_BUF_TO_AGF(sc->sa.agf_bp); + struct xfs_mount *mp = sc->mp; + xfs_agblock_t blocks; + xfs_agblock_t btreeblks; + int error; /* Check agf_rmap_blocks; set up for agf_btreeblks check */ if (sc->sa.rmap_cur) { @@ -465,9 +465,9 @@ static inline void xchk_agf_xref_refcblks( struct xfs_scrub *sc) { - struct xfs_agf *agf = XFS_BUF_TO_AGF(sc->sa.agf_bp); - xfs_agblock_t blocks; - int error; + struct xfs_agf *agf = XFS_BUF_TO_AGF(sc->sa.agf_bp); + xfs_agblock_t blocks; + int error; if (!sc->sa.refc_cur) return; @@ -484,10 +484,10 @@ STATIC void xchk_agf_xref( struct xfs_scrub *sc) { - struct xfs_owner_info oinfo; - struct xfs_mount *mp = sc->mp; - xfs_agblock_t agbno; - int error; + struct xfs_owner_info oinfo; + struct xfs_mount *mp = sc->mp; + xfs_agblock_t agbno; + int error; if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) return; @@ -516,17 +516,17 @@ int xchk_agf( struct xfs_scrub *sc) { - struct xfs_mount *mp = sc->mp; - struct xfs_agf *agf; - xfs_agnumber_t agno; - xfs_agblock_t agbno; - xfs_agblock_t eoag; - xfs_agblock_t agfl_first; - xfs_agblock_t agfl_last; - xfs_agblock_t agfl_count; - xfs_agblock_t fl_count; - int level; - int error = 0; + struct xfs_mount *mp = sc->mp; + struct xfs_agf *agf; + xfs_agnumber_t agno; + xfs_agblock_t agbno; + xfs_agblock_t eoag; + xfs_agblock_t agfl_first; + xfs_agblock_t agfl_last; + xfs_agblock_t agfl_count; + xfs_agblock_t fl_count; + int level; + int error = 0; agno = sc->sa.agno = sc->sm->sm_agno; error = xchk_ag_read_headers(sc, agno, &sc->sa.agi_bp, @@ -598,10 +598,10 @@ out: /* AGFL */ struct xchk_agfl_info { - struct xfs_owner_info oinfo; - unsigned int sz_entries; - unsigned int nr_entries; - xfs_agblock_t *entries; + struct xfs_owner_info oinfo; + unsigned int sz_entries; + unsigned int nr_entries; + xfs_agblock_t *entries; struct xfs_scrub *sc; }; @@ -609,8 +609,8 @@ struct xchk_agfl_info { STATIC void xchk_agfl_block_xref( struct xfs_scrub *sc, - xfs_agblock_t agbno, - struct xfs_owner_info *oinfo) + xfs_agblock_t agbno, + struct xfs_owner_info *oinfo) { if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) return; @@ -624,13 +624,13 @@ xchk_agfl_block_xref( /* Scrub an AGFL block. */ STATIC int xchk_agfl_block( - struct xfs_mount *mp, - xfs_agblock_t agbno, - void *priv) + struct xfs_mount *mp, + xfs_agblock_t agbno, + void *priv) { - struct xchk_agfl_info *sai = priv; + struct xchk_agfl_info *sai = priv; struct xfs_scrub *sc = sai->sc; - xfs_agnumber_t agno = sc->sa.agno; + xfs_agnumber_t agno = sc->sa.agno; if (xfs_verify_agbno(mp, agno, agbno) && sai->nr_entries < sai->sz_entries) @@ -662,10 +662,10 @@ STATIC void xchk_agfl_xref( struct xfs_scrub *sc) { - struct xfs_owner_info oinfo; - struct xfs_mount *mp = sc->mp; - xfs_agblock_t agbno; - int error; + struct xfs_owner_info oinfo; + struct xfs_mount *mp = sc->mp; + xfs_agblock_t agbno; + int error; if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) return; @@ -693,12 +693,12 @@ int xchk_agfl( struct xfs_scrub *sc) { - struct xchk_agfl_info sai; - struct xfs_agf *agf; - xfs_agnumber_t agno; - unsigned int agflcount; - unsigned int i; - int error; + struct xchk_agfl_info sai; + struct xfs_agf *agf; + xfs_agnumber_t agno; + unsigned int agflcount; + unsigned int i; + int error; agno = sc->sa.agno = sc->sm->sm_agno; error = xchk_ag_read_headers(sc, agno, &sc->sa.agi_bp, @@ -770,10 +770,10 @@ static inline void xchk_agi_xref_icounts( struct xfs_scrub *sc) { - struct xfs_agi *agi = XFS_BUF_TO_AGI(sc->sa.agi_bp); - xfs_agino_t icount; - xfs_agino_t freecount; - int error; + struct xfs_agi *agi = XFS_BUF_TO_AGI(sc->sa.agi_bp); + xfs_agino_t icount; + xfs_agino_t freecount; + int error; if (!sc->sa.ino_cur) return; @@ -791,10 +791,10 @@ STATIC void xchk_agi_xref( struct xfs_scrub *sc) { - struct xfs_owner_info oinfo; - struct xfs_mount *mp = sc->mp; - xfs_agblock_t agbno; - int error; + struct xfs_owner_info oinfo; + struct xfs_mount *mp = sc->mp; + xfs_agblock_t agbno; + int error; if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) return; @@ -820,18 +820,18 @@ int xchk_agi( struct xfs_scrub *sc) { - struct xfs_mount *mp = sc->mp; - struct xfs_agi *agi; - xfs_agnumber_t agno; - xfs_agblock_t agbno; - xfs_agblock_t eoag; - xfs_agino_t agino; - xfs_agino_t first_agino; - xfs_agino_t last_agino; - xfs_agino_t icount; - int i; - int level; - int error = 0; + struct xfs_mount *mp = sc->mp; + struct xfs_agi *agi; + xfs_agnumber_t agno; + xfs_agblock_t agbno; + xfs_agblock_t eoag; + xfs_agino_t agino; + xfs_agino_t first_agino; + xfs_agino_t last_agino; + xfs_agino_t icount; + int i; + int level; + int error = 0; agno = sc->sa.agno = sc->sm->sm_agno; error = xchk_ag_read_headers(sc, agno, &sc->sa.agi_bp, diff --git a/fs/xfs/scrub/agheader_repair.c b/fs/xfs/scrub/agheader_repair.c index 2457968482f8..1e96621ece3a 100644 --- a/fs/xfs/scrub/agheader_repair.c +++ b/fs/xfs/scrub/agheader_repair.c @@ -31,10 +31,10 @@ int xrep_superblock( struct xfs_scrub *sc) { - struct xfs_mount *mp = sc->mp; - struct xfs_buf *bp; - xfs_agnumber_t agno; - int error; + struct xfs_mount *mp = sc->mp; + struct xfs_buf *bp; + xfs_agnumber_t agno; + int error; /* Don't try to repair AG 0's sb; let xfs_repair deal with it. */ agno = sc->sm->sm_agno; diff --git a/fs/xfs/scrub/alloc.c b/fs/xfs/scrub/alloc.c index 653d80b3aa39..036b5c7021eb 100644 --- a/fs/xfs/scrub/alloc.c +++ b/fs/xfs/scrub/alloc.c @@ -30,7 +30,7 @@ int xchk_setup_ag_allocbt( struct xfs_scrub *sc, - struct xfs_inode *ip) + struct xfs_inode *ip) { return xchk_setup_ag_btree(sc, ip, false); } @@ -43,14 +43,14 @@ xchk_setup_ag_allocbt( STATIC void xchk_allocbt_xref_other( struct xfs_scrub *sc, - xfs_agblock_t agbno, - xfs_extlen_t len) + xfs_agblock_t agbno, + xfs_extlen_t len) { - struct xfs_btree_cur **pcur; - xfs_agblock_t fbno; - xfs_extlen_t flen; - int has_otherrec; - int error; + struct xfs_btree_cur **pcur; + xfs_agblock_t fbno; + xfs_extlen_t flen; + int has_otherrec; + int error; if (sc->sm->sm_type == XFS_SCRUB_TYPE_BNOBT) pcur = &sc->sa.cnt_cur; @@ -83,8 +83,8 @@ xchk_allocbt_xref_other( STATIC void xchk_allocbt_xref( struct xfs_scrub *sc, - xfs_agblock_t agbno, - xfs_extlen_t len) + xfs_agblock_t agbno, + xfs_extlen_t len) { if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) return; @@ -98,14 +98,14 @@ xchk_allocbt_xref( /* Scrub a bnobt/cntbt record. */ STATIC int xchk_allocbt_rec( - struct xchk_btree *bs, - union xfs_btree_rec *rec) + struct xchk_btree *bs, + union xfs_btree_rec *rec) { - struct xfs_mount *mp = bs->cur->bc_mp; - xfs_agnumber_t agno = bs->cur->bc_private.a.agno; - xfs_agblock_t bno; - xfs_extlen_t len; - int error = 0; + struct xfs_mount *mp = bs->cur->bc_mp; + xfs_agnumber_t agno = bs->cur->bc_private.a.agno; + xfs_agblock_t bno; + xfs_extlen_t len; + int error = 0; bno = be32_to_cpu(rec->alloc.ar_startblock); len = be32_to_cpu(rec->alloc.ar_blockcount); @@ -124,10 +124,10 @@ xchk_allocbt_rec( STATIC int xchk_allocbt( struct xfs_scrub *sc, - xfs_btnum_t which) + xfs_btnum_t which) { - struct xfs_owner_info oinfo; - struct xfs_btree_cur *cur; + struct xfs_owner_info oinfo; + struct xfs_btree_cur *cur; xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_AG); cur = which == XFS_BTNUM_BNO ? sc->sa.bno_cur : sc->sa.cnt_cur; @@ -152,11 +152,11 @@ xchk_cntbt( void xchk_xref_is_used_space( struct xfs_scrub *sc, - xfs_agblock_t agbno, - xfs_extlen_t len) + xfs_agblock_t agbno, + xfs_extlen_t len) { - bool is_freesp; - int error; + bool is_freesp; + int error; if (!sc->sa.bno_cur || xchk_skip_xref(sc->sm)) return; diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c index 6650fb3010b6..81d5e90547a1 100644 --- a/fs/xfs/scrub/attr.c +++ b/fs/xfs/scrub/attr.c @@ -34,9 +34,9 @@ int xchk_setup_xattr( struct xfs_scrub *sc, - struct xfs_inode *ip) + struct xfs_inode *ip) { - size_t sz; + size_t sz; /* * Allocate the buffer without the inode lock held. We need enough @@ -57,7 +57,7 @@ xchk_setup_xattr( struct xchk_xattr { struct xfs_attr_list_context context; - struct xfs_scrub *sc; + struct xfs_scrub *sc; }; /* @@ -128,12 +128,12 @@ fail_xref: STATIC bool xchk_xattr_set_map( struct xfs_scrub *sc, - unsigned long *map, - unsigned int start, - unsigned int len) + unsigned long *map, + unsigned int start, + unsigned int len) { - unsigned int mapsize = sc->mp->m_attr_geo->blksize; - bool ret = true; + unsigned int mapsize = sc->mp->m_attr_geo->blksize; + bool ret = true; if (start >= mapsize) return false; @@ -155,7 +155,7 @@ xchk_xattr_set_map( */ STATIC bool xchk_xattr_check_freemap( - struct xfs_scrub *sc, + struct xfs_scrub *sc, unsigned long *map, struct xfs_attr3_icleaf_hdr *leafhdr) { @@ -405,7 +405,7 @@ out: /* Scrub the extended attribute metadata. */ int xchk_xattr( - struct xfs_scrub *sc) + struct xfs_scrub *sc) { struct xchk_xattr sx; struct attrlist_cursor_kern cursor = { 0 }; diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c index 0e5166232b15..e1d11f3223e3 100644 --- a/fs/xfs/scrub/bmap.c +++ b/fs/xfs/scrub/bmap.c @@ -35,9 +35,9 @@ int xchk_setup_inode_bmap( struct xfs_scrub *sc, - struct xfs_inode *ip) + struct xfs_inode *ip) { - int error; + int error; error = xchk_get_inode(sc, ip); if (error) @@ -80,25 +80,25 @@ out: struct xchk_bmap_info { struct xfs_scrub *sc; - xfs_fileoff_t lastoff; - bool is_rt; - bool is_shared; - int whichfork; + xfs_fileoff_t lastoff; + bool is_rt; + bool is_shared; + int whichfork; }; /* Look for a corresponding rmap for this irec. */ static inline bool xchk_bmap_get_rmap( - struct xchk_bmap_info *info, - struct xfs_bmbt_irec *irec, - xfs_agblock_t agbno, - uint64_t owner, - struct xfs_rmap_irec *rmap) + struct xchk_bmap_info *info, + struct xfs_bmbt_irec *irec, + xfs_agblock_t agbno, + uint64_t owner, + struct xfs_rmap_irec *rmap) { - xfs_fileoff_t offset; - unsigned int rflags = 0; - int has_rmap; - int error; + xfs_fileoff_t offset; + unsigned int rflags = 0; + int has_rmap; + int error; if (info->whichfork == XFS_ATTR_FORK) rflags |= XFS_RMAP_ATTR_FORK; @@ -152,13 +152,13 @@ out: /* Make sure that we have rmapbt records for this extent. */ STATIC void xchk_bmap_xref_rmap( - struct xchk_bmap_info *info, - struct xfs_bmbt_irec *irec, - xfs_agblock_t agbno) + struct xchk_bmap_info *info, + struct xfs_bmbt_irec *irec, + xfs_agblock_t agbno) { - struct xfs_rmap_irec rmap; - unsigned long long rmap_end; - uint64_t owner; + struct xfs_rmap_irec rmap; + unsigned long long rmap_end; + uint64_t owner; if (!info->sc->sa.rmap_cur || xchk_skip_xref(info->sc->sm)) return; @@ -222,10 +222,10 @@ xchk_bmap_xref_rmap( /* Cross-reference a single rtdev extent record. */ STATIC void xchk_bmap_rt_extent_xref( - struct xchk_bmap_info *info, - struct xfs_inode *ip, - struct xfs_btree_cur *cur, - struct xfs_bmbt_irec *irec) + struct xchk_bmap_info *info, + struct xfs_inode *ip, + struct xfs_btree_cur *cur, + struct xfs_bmbt_irec *irec) { if (info->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) return; @@ -237,16 +237,16 @@ xchk_bmap_rt_extent_xref( /* Cross-reference a single datadev extent record. */ STATIC void xchk_bmap_extent_xref( - struct xchk_bmap_info *info, - struct xfs_inode *ip, - struct xfs_btree_cur *cur, - struct xfs_bmbt_irec *irec) + struct xchk_bmap_info *info, + struct xfs_inode *ip, + struct xfs_btree_cur *cur, + struct xfs_bmbt_irec *irec) { - struct xfs_mount *mp = info->sc->mp; - xfs_agnumber_t agno; - xfs_agblock_t agbno; - xfs_extlen_t len; - int error; + struct xfs_mount *mp = info->sc->mp; + xfs_agnumber_t agno; + xfs_agblock_t agbno; + xfs_extlen_t len; + int error; if (info->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) return; @@ -284,15 +284,15 @@ xchk_bmap_extent_xref( /* Scrub a single extent record. */ STATIC int xchk_bmap_extent( - struct xfs_inode *ip, - struct xfs_btree_cur *cur, - struct xchk_bmap_info *info, - struct xfs_bmbt_irec *irec) + struct xfs_inode *ip, + struct xfs_btree_cur *cur, + struct xchk_bmap_info *info, + struct xfs_bmbt_irec *irec) { - struct xfs_mount *mp = info->sc->mp; - struct xfs_buf *bp = NULL; - xfs_filblks_t end; - int error = 0; + struct xfs_mount *mp = info->sc->mp; + struct xfs_buf *bp = NULL; + xfs_filblks_t end; + int error = 0; if (cur) xfs_btree_get_block(cur, 0, &bp); @@ -357,16 +357,16 @@ xchk_bmap_extent( /* Scrub a bmbt record. */ STATIC int xchk_bmapbt_rec( - struct xchk_btree *bs, - union xfs_btree_rec *rec) + struct xchk_btree *bs, + union xfs_btree_rec *rec) { - struct xfs_bmbt_irec irec; - struct xchk_bmap_info *info = bs->private; - struct xfs_inode *ip = bs->cur->bc_private.b.ip; - struct xfs_buf *bp = NULL; - struct xfs_btree_block *block; - uint64_t owner; - int i; + struct xfs_bmbt_irec irec; + struct xchk_bmap_info *info = bs->private; + struct xfs_inode *ip = bs->cur->bc_private.b.ip; + struct xfs_buf *bp = NULL; + struct xfs_btree_block *block; + uint64_t owner; + int i; /* * Check the owners of the btree blocks up to the level below @@ -392,14 +392,14 @@ xchk_bmapbt_rec( STATIC int xchk_bmap_btree( struct xfs_scrub *sc, - int whichfork, - struct xchk_bmap_info *info) + int whichfork, + struct xchk_bmap_info *info) { - struct xfs_owner_info oinfo; - struct xfs_mount *mp = sc->mp; - struct xfs_inode *ip = sc->ip; - struct xfs_btree_cur *cur; - int error; + struct xfs_owner_info oinfo; + struct xfs_mount *mp = sc->mp; + struct xfs_inode *ip = sc->ip; + struct xfs_btree_cur *cur; + int error; cur = xfs_bmbt_init_cursor(mp, sc->tp, ip, whichfork); xfs_rmap_ino_bmbt_owner(&oinfo, ip->i_ino, whichfork); @@ -410,8 +410,8 @@ xchk_bmap_btree( struct xchk_bmap_check_rmap_info { struct xfs_scrub *sc; - int whichfork; - struct xfs_iext_cursor icur; + int whichfork; + struct xfs_iext_cursor icur; }; /* Can we find bmaps that fit this rmap? */ @@ -424,7 +424,7 @@ xchk_bmap_check_rmap( struct xfs_bmbt_irec irec; struct xchk_bmap_check_rmap_info *sbcri = priv; struct xfs_ifork *ifp; - struct xfs_scrub *sc = sbcri->sc; + struct xfs_scrub *sc = sbcri->sc; bool have_map; /* Is this even the right fork? */ @@ -488,7 +488,7 @@ out: /* Make sure each rmap has a corresponding bmbt entry. */ STATIC int xchk_bmap_check_ag_rmaps( - struct xfs_scrub *sc, + struct xfs_scrub *sc, int whichfork, xfs_agnumber_t agno) { @@ -523,11 +523,11 @@ out_agf: STATIC int xchk_bmap_check_rmaps( struct xfs_scrub *sc, - int whichfork) + int whichfork) { - loff_t size; - xfs_agnumber_t agno; - int error; + loff_t size; + xfs_agnumber_t agno; + int error; if (!xfs_sb_version_hasrmapbt(&sc->mp->m_sb) || whichfork == XFS_COW_FORK || @@ -580,16 +580,16 @@ xchk_bmap_check_rmaps( STATIC int xchk_bmap( struct xfs_scrub *sc, - int whichfork) + int whichfork) { - struct xfs_bmbt_irec irec; - struct xchk_bmap_info info = { NULL }; - struct xfs_mount *mp = sc->mp; - struct xfs_inode *ip = sc->ip; - struct xfs_ifork *ifp; - xfs_fileoff_t endoff; - struct xfs_iext_cursor icur; - int error = 0; + struct xfs_bmbt_irec irec; + struct xchk_bmap_info info = { NULL }; + struct xfs_mount *mp = sc->mp; + struct xfs_inode *ip = sc->ip; + struct xfs_ifork *ifp; + xfs_fileoff_t endoff; + struct xfs_iext_cursor icur; + int error = 0; ifp = XFS_IFORK_PTR(ip, whichfork); diff --git a/fs/xfs/scrub/btree.c b/fs/xfs/scrub/btree.c index c4e1dce8c5b3..4ae959f7ad2c 100644 --- a/fs/xfs/scrub/btree.c +++ b/fs/xfs/scrub/btree.c @@ -31,11 +31,11 @@ static bool __xchk_btree_process_error( struct xfs_scrub *sc, - struct xfs_btree_cur *cur, - int level, - int *error, - __u32 errflag, - void *ret_ip) + struct xfs_btree_cur *cur, + int level, + int *error, + __u32 errflag, + void *ret_ip) { if (*error == 0) return true; @@ -66,9 +66,9 @@ __xchk_btree_process_error( bool xchk_btree_process_error( struct xfs_scrub *sc, - struct xfs_btree_cur *cur, - int level, - int *error) + struct xfs_btree_cur *cur, + int level, + int *error) { return __xchk_btree_process_error(sc, cur, level, error, XFS_SCRUB_OFLAG_CORRUPT, __return_address); @@ -77,9 +77,9 @@ xchk_btree_process_error( bool xchk_btree_xref_process_error( struct xfs_scrub *sc, - struct xfs_btree_cur *cur, - int level, - int *error) + struct xfs_btree_cur *cur, + int level, + int *error) { return __xchk_btree_process_error(sc, cur, level, error, XFS_SCRUB_OFLAG_XFAIL, __return_address); @@ -89,10 +89,10 @@ xchk_btree_xref_process_error( static void __xchk_btree_set_corrupt( struct xfs_scrub *sc, - struct xfs_btree_cur *cur, - int level, - __u32 errflag, - void *ret_ip) + struct xfs_btree_cur *cur, + int level, + __u32 errflag, + void *ret_ip) { sc->sm->sm_flags |= errflag; @@ -107,8 +107,8 @@ __xchk_btree_set_corrupt( void xchk_btree_set_corrupt( struct xfs_scrub *sc, - struct xfs_btree_cur *cur, - int level) + struct xfs_btree_cur *cur, + int level) { __xchk_btree_set_corrupt(sc, cur, level, XFS_SCRUB_OFLAG_CORRUPT, __return_address); @@ -117,8 +117,8 @@ xchk_btree_set_corrupt( void xchk_btree_xref_set_corrupt( struct xfs_scrub *sc, - struct xfs_btree_cur *cur, - int level) + struct xfs_btree_cur *cur, + int level) { __xchk_btree_set_corrupt(sc, cur, level, XFS_SCRUB_OFLAG_XCORRUPT, __return_address); @@ -225,11 +225,11 @@ xchk_btree_key( */ static bool xchk_btree_ptr_ok( - struct xchk_btree *bs, - int level, - union xfs_btree_ptr *ptr) + struct xchk_btree *bs, + int level, + union xfs_btree_ptr *ptr) { - bool res; + bool res; /* A btree rooted in an inode has no block pointer to the root. */ if ((bs->cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) && @@ -250,18 +250,18 @@ xchk_btree_ptr_ok( /* Check that a btree block's sibling matches what we expect it. */ STATIC int xchk_btree_block_check_sibling( - struct xchk_btree *bs, - int level, - int direction, - union xfs_btree_ptr *sibling) + struct xchk_btree *bs, + int level, + int direction, + union xfs_btree_ptr *sibling) { - struct xfs_btree_cur *cur = bs->cur; - struct xfs_btree_block *pblock; - struct xfs_buf *pbp; - struct xfs_btree_cur *ncur = NULL; - union xfs_btree_ptr *pp; - int success; - int error; + struct xfs_btree_cur *cur = bs->cur; + struct xfs_btree_block *pblock; + struct xfs_buf *pbp; + struct xfs_btree_cur *ncur = NULL; + union xfs_btree_ptr *pp; + int success; + int error; error = xfs_btree_dup_cursor(cur, &ncur); if (!xchk_btree_process_error(bs->sc, cur, level + 1, &error) || @@ -313,14 +313,14 @@ out: /* Check the siblings of a btree block. */ STATIC int xchk_btree_block_check_siblings( - struct xchk_btree *bs, - struct xfs_btree_block *block) + struct xchk_btree *bs, + struct xfs_btree_block *block) { - struct xfs_btree_cur *cur = bs->cur; - union xfs_btree_ptr leftsib; - union xfs_btree_ptr rightsib; - int level; - int error = 0; + struct xfs_btree_cur *cur = bs->cur; + union xfs_btree_ptr leftsib; + union xfs_btree_ptr rightsib; + int level; + int error = 0; xfs_btree_get_sibling(cur, block, &leftsib, XFS_BB_LEFTSIB); xfs_btree_get_sibling(cur, block, &rightsib, XFS_BB_RIGHTSIB); @@ -361,15 +361,15 @@ struct check_owner { */ STATIC int xchk_btree_check_block_owner( - struct xchk_btree *bs, - int level, - xfs_daddr_t daddr) + struct xchk_btree *bs, + int level, + xfs_daddr_t daddr) { - xfs_agnumber_t agno; - xfs_agblock_t agbno; - xfs_btnum_t btnum; - bool init_sa; - int error = 0; + xfs_agnumber_t agno; + xfs_agblock_t agbno; + xfs_btnum_t btnum; + bool init_sa; + int error = 0; if (!bs->cur) return 0; @@ -408,12 +408,12 @@ xchk_btree_check_block_owner( /* Check the owner of a btree block. */ STATIC int xchk_btree_check_owner( - struct xchk_btree *bs, - int level, - struct xfs_buf *bp) + struct xchk_btree *bs, + int level, + struct xfs_buf *bp) { - struct xfs_btree_cur *cur = bs->cur; - struct check_owner *co; + struct xfs_btree_cur *cur = bs->cur; + struct check_owner *co; if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) && bp == NULL) return 0; @@ -484,14 +484,14 @@ xchk_btree_check_minrecs( */ STATIC int xchk_btree_get_block( - struct xchk_btree *bs, - int level, - union xfs_btree_ptr *pp, - struct xfs_btree_block **pblock, - struct xfs_buf **pbp) + struct xchk_btree *bs, + int level, + union xfs_btree_ptr *pp, + struct xfs_btree_block **pblock, + struct xfs_buf **pbp) { - void *failed_at; - int error; + xfs_failaddr_t failed_at; + int error; *pblock = NULL; *pbp = NULL; @@ -538,17 +538,17 @@ xchk_btree_get_block( */ STATIC void xchk_btree_block_keys( - struct xchk_btree *bs, - int level, - struct xfs_btree_block *block) + struct xchk_btree *bs, + int level, + struct xfs_btree_block *block) { - union xfs_btree_key block_keys; - struct xfs_btree_cur *cur = bs->cur; - union xfs_btree_key *high_bk; - union xfs_btree_key *parent_keys; - union xfs_btree_key *high_pk; - struct xfs_btree_block *parent_block; - struct xfs_buf *bp; + union xfs_btree_key block_keys; + struct xfs_btree_cur *cur = bs->cur; + union xfs_btree_key *high_bk; + union xfs_btree_key *parent_keys; + union xfs_btree_key *high_pk; + struct xfs_btree_block *parent_block; + struct xfs_buf *bp; if (level >= cur->bc_nlevels - 1) return; @@ -584,22 +584,22 @@ xchk_btree_block_keys( int xchk_btree( struct xfs_scrub *sc, - struct xfs_btree_cur *cur, - xchk_btree_rec_fn scrub_fn, - struct xfs_owner_info *oinfo, - void *private) + struct xfs_btree_cur *cur, + xchk_btree_rec_fn scrub_fn, + struct xfs_owner_info *oinfo, + void *private) { - struct xchk_btree bs = { NULL }; - union xfs_btree_ptr ptr; - union xfs_btree_ptr *pp; - union xfs_btree_rec *recp; - struct xfs_btree_block *block; - int level; - struct xfs_buf *bp; - struct check_owner *co; - struct check_owner *n; - int i; - int error = 0; + struct xchk_btree bs = { NULL }; + union xfs_btree_ptr ptr; + union xfs_btree_ptr *pp; + union xfs_btree_rec *recp; + struct xfs_btree_block *block; + int level; + struct xfs_buf *bp; + struct check_owner *co; + struct check_owner *n; + int i; + int error = 0; /* Initialize scrub state */ bs.cur = cur; diff --git a/fs/xfs/scrub/btree.h b/fs/xfs/scrub/btree.h index a0b74b515b9b..aada763cd006 100644 --- a/fs/xfs/scrub/btree.h +++ b/fs/xfs/scrub/btree.h @@ -14,8 +14,7 @@ bool xchk_btree_process_error(struct xfs_scrub *sc, /* Check for btree xref operation errors. */ bool xchk_btree_xref_process_error(struct xfs_scrub *sc, - struct xfs_btree_cur *cur, int level, - int *error); + struct xfs_btree_cur *cur, int level, int *error); /* Check for btree corruption. */ void xchk_btree_set_corrupt(struct xfs_scrub *sc, @@ -33,20 +32,20 @@ typedef int (*xchk_btree_rec_fn)( struct xchk_btree { /* caller-provided scrub state */ struct xfs_scrub *sc; - struct xfs_btree_cur *cur; - xchk_btree_rec_fn scrub_rec; - struct xfs_owner_info *oinfo; - void *private; + struct xfs_btree_cur *cur; + xchk_btree_rec_fn scrub_rec; + struct xfs_owner_info *oinfo; + void *private; /* internal scrub state */ - union xfs_btree_rec lastrec; - bool firstrec; - union xfs_btree_key lastkey[XFS_BTREE_MAXLEVELS]; - bool firstkey[XFS_BTREE_MAXLEVELS]; - struct list_head to_check; + union xfs_btree_rec lastrec; + bool firstrec; + union xfs_btree_key lastkey[XFS_BTREE_MAXLEVELS]; + bool firstkey[XFS_BTREE_MAXLEVELS]; + struct list_head to_check; }; int xchk_btree(struct xfs_scrub *sc, struct xfs_btree_cur *cur, - xchk_btree_rec_fn scrub_fn, - struct xfs_owner_info *oinfo, void *private); + xchk_btree_rec_fn scrub_fn, struct xfs_owner_info *oinfo, + void *private); #endif /* __XFS_SCRUB_BTREE_H__ */ diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index ed9195116556..baac08304a5a 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -70,11 +70,11 @@ static bool __xchk_process_error( struct xfs_scrub *sc, - xfs_agnumber_t agno, - xfs_agblock_t bno, - int *error, - __u32 errflag, - void *ret_ip) + xfs_agnumber_t agno, + xfs_agblock_t bno, + int *error, + __u32 errflag, + void *ret_ip) { switch (*error) { case 0: @@ -100,9 +100,9 @@ __xchk_process_error( bool xchk_process_error( struct xfs_scrub *sc, - xfs_agnumber_t agno, - xfs_agblock_t bno, - int *error) + xfs_agnumber_t agno, + xfs_agblock_t bno, + int *error) { return __xchk_process_error(sc, agno, bno, error, XFS_SCRUB_OFLAG_CORRUPT, __return_address); @@ -111,9 +111,9 @@ xchk_process_error( bool xchk_xref_process_error( struct xfs_scrub *sc, - xfs_agnumber_t agno, - xfs_agblock_t bno, - int *error) + xfs_agnumber_t agno, + xfs_agblock_t bno, + int *error) { return __xchk_process_error(sc, agno, bno, error, XFS_SCRUB_OFLAG_XFAIL, __return_address); @@ -123,11 +123,11 @@ xchk_xref_process_error( static bool __xchk_fblock_process_error( struct xfs_scrub *sc, - int whichfork, - xfs_fileoff_t offset, - int *error, - __u32 errflag, - void *ret_ip) + int whichfork, + xfs_fileoff_t offset, + int *error, + __u32 errflag, + void *ret_ip) { switch (*error) { case 0: @@ -153,9 +153,9 @@ __xchk_fblock_process_error( bool xchk_fblock_process_error( struct xfs_scrub *sc, - int whichfork, - xfs_fileoff_t offset, - int *error) + int whichfork, + xfs_fileoff_t offset, + int *error) { return __xchk_fblock_process_error(sc, whichfork, offset, error, XFS_SCRUB_OFLAG_CORRUPT, __return_address); @@ -164,9 +164,9 @@ xchk_fblock_process_error( bool xchk_fblock_xref_process_error( struct xfs_scrub *sc, - int whichfork, - xfs_fileoff_t offset, - int *error) + int whichfork, + xfs_fileoff_t offset, + int *error) { return __xchk_fblock_process_error(sc, whichfork, offset, error, XFS_SCRUB_OFLAG_XFAIL, __return_address); @@ -188,7 +188,7 @@ xchk_fblock_xref_process_error( void xchk_block_set_preen( struct xfs_scrub *sc, - struct xfs_buf *bp) + struct xfs_buf *bp) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_PREEN; trace_xchk_block_preen(sc, bp->b_bn, __return_address); @@ -202,7 +202,7 @@ xchk_block_set_preen( void xchk_ino_set_preen( struct xfs_scrub *sc, - xfs_ino_t ino) + xfs_ino_t ino) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_PREEN; trace_xchk_ino_preen(sc, ino, __return_address); @@ -212,7 +212,7 @@ xchk_ino_set_preen( void xchk_block_set_corrupt( struct xfs_scrub *sc, - struct xfs_buf *bp) + struct xfs_buf *bp) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT; trace_xchk_block_error(sc, bp->b_bn, __return_address); @@ -222,7 +222,7 @@ xchk_block_set_corrupt( void xchk_block_xref_set_corrupt( struct xfs_scrub *sc, - struct xfs_buf *bp) + struct xfs_buf *bp) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XCORRUPT; trace_xchk_block_error(sc, bp->b_bn, __return_address); @@ -236,7 +236,7 @@ xchk_block_xref_set_corrupt( void xchk_ino_set_corrupt( struct xfs_scrub *sc, - xfs_ino_t ino) + xfs_ino_t ino) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT; trace_xchk_ino_error(sc, ino, __return_address); @@ -246,7 +246,7 @@ xchk_ino_set_corrupt( void xchk_ino_xref_set_corrupt( struct xfs_scrub *sc, - xfs_ino_t ino) + xfs_ino_t ino) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XCORRUPT; trace_xchk_ino_error(sc, ino, __return_address); @@ -256,8 +256,8 @@ xchk_ino_xref_set_corrupt( void xchk_fblock_set_corrupt( struct xfs_scrub *sc, - int whichfork, - xfs_fileoff_t offset) + int whichfork, + xfs_fileoff_t offset) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT; trace_xchk_fblock_error(sc, whichfork, offset, __return_address); @@ -267,8 +267,8 @@ xchk_fblock_set_corrupt( void xchk_fblock_xref_set_corrupt( struct xfs_scrub *sc, - int whichfork, - xfs_fileoff_t offset) + int whichfork, + xfs_fileoff_t offset) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XCORRUPT; trace_xchk_fblock_error(sc, whichfork, offset, __return_address); @@ -281,7 +281,7 @@ xchk_fblock_xref_set_corrupt( void xchk_ino_set_warning( struct xfs_scrub *sc, - xfs_ino_t ino) + xfs_ino_t ino) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_WARNING; trace_xchk_ino_warning(sc, ino, __return_address); @@ -291,8 +291,8 @@ xchk_ino_set_warning( void xchk_fblock_set_warning( struct xfs_scrub *sc, - int whichfork, - xfs_fileoff_t offset) + int whichfork, + xfs_fileoff_t offset) { sc->sm->sm_flags |= XFS_SCRUB_OFLAG_WARNING; trace_xchk_fblock_warning(sc, whichfork, offset, __return_address); @@ -319,13 +319,13 @@ struct xchk_rmap_ownedby_info { STATIC int xchk_count_rmap_ownedby_irec( - struct xfs_btree_cur *cur, - struct xfs_rmap_irec *rec, - void *priv) + struct xfs_btree_cur *cur, + struct xfs_rmap_irec *rec, + void *priv) { - struct xchk_rmap_ownedby_info *sroi = priv; - bool irec_attr; - bool oinfo_attr; + struct xchk_rmap_ownedby_info *sroi = priv; + bool irec_attr; + bool oinfo_attr; irec_attr = rec->rm_flags & XFS_RMAP_ATTR_FORK; oinfo_attr = sroi->oinfo->oi_flags & XFS_OWNER_INFO_ATTR_FORK; @@ -346,11 +346,11 @@ xchk_count_rmap_ownedby_irec( int xchk_count_rmap_ownedby_ag( struct xfs_scrub *sc, - struct xfs_btree_cur *cur, - struct xfs_owner_info *oinfo, - xfs_filblks_t *blocks) + struct xfs_btree_cur *cur, + struct xfs_owner_info *oinfo, + xfs_filblks_t *blocks) { - struct xchk_rmap_ownedby_info sroi; + struct xchk_rmap_ownedby_info sroi; sroi.oinfo = oinfo; *blocks = 0; @@ -372,7 +372,7 @@ xchk_count_rmap_ownedby_ag( static inline bool want_ag_read_header_failure( struct xfs_scrub *sc, - unsigned int type) + unsigned int type) { /* Return all AG header read failures when scanning btrees. */ if (sc->sm->sm_type != XFS_SCRUB_TYPE_AGF && @@ -399,13 +399,13 @@ want_ag_read_header_failure( int xchk_ag_read_headers( struct xfs_scrub *sc, - xfs_agnumber_t agno, - struct xfs_buf **agi, - struct xfs_buf **agf, - struct xfs_buf **agfl) + xfs_agnumber_t agno, + struct xfs_buf **agi, + struct xfs_buf **agf, + struct xfs_buf **agfl) { - struct xfs_mount *mp = sc->mp; - int error; + struct xfs_mount *mp = sc->mp; + int error; error = xfs_ialloc_read_agi(mp, sc->tp, agno, agi); if (error && want_ag_read_header_failure(sc, XFS_SCRUB_TYPE_AGI)) @@ -455,8 +455,8 @@ xchk_ag_btcur_init( struct xfs_scrub *sc, struct xchk_ag *sa) { - struct xfs_mount *mp = sc->mp; - xfs_agnumber_t agno = sa->agno; + struct xfs_mount *mp = sc->mp; + xfs_agnumber_t agno = sa->agno; if (sa->agf_bp) { /* Set up a bnobt cursor for cross-referencing. */ @@ -545,10 +545,10 @@ xchk_ag_free( int xchk_ag_init( struct xfs_scrub *sc, - xfs_agnumber_t agno, + xfs_agnumber_t agno, struct xchk_ag *sa) { - int error; + int error; sa->agno = agno; error = xchk_ag_read_headers(sc, agno, &sa->agi_bp, @@ -566,7 +566,7 @@ xchk_ag_init( void xchk_perag_get( struct xfs_mount *mp, - struct xchk_ag *sa) + struct xchk_ag *sa) { if (!sa->pag) sa->pag = xfs_perag_get(mp, sa->agno); @@ -587,7 +587,7 @@ xchk_perag_get( int xchk_trans_alloc( struct xfs_scrub *sc, - uint resblks) + uint resblks) { if (sc->sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR) return xfs_trans_alloc(sc->mp, &M_RES(sc->mp)->tr_itruncate, @@ -600,9 +600,9 @@ xchk_trans_alloc( int xchk_setup_fs( struct xfs_scrub *sc, - struct xfs_inode *ip) + struct xfs_inode *ip) { - uint resblks; + uint resblks; resblks = xrep_calc_ag_resblks(sc); return xchk_trans_alloc(sc, resblks); @@ -612,11 +612,11 @@ xchk_setup_fs( int xchk_setup_ag_btree( struct xfs_scrub *sc, - struct xfs_inode *ip, - bool force_log) + struct xfs_inode *ip, + bool force_log) { - struct xfs_mount *mp = sc->mp; - int error; + struct xfs_mount *mp = sc->mp; + int error; /* * If the caller asks us to checkpont the log, do so. This @@ -659,12 +659,12 @@ xchk_checkpoint_log( int xchk_get_inode( struct xfs_scrub *sc, - struct xfs_inode *ip_in) + struct xfs_inode *ip_in) { - struct xfs_imap imap; - struct xfs_mount *mp = sc->mp; - struct xfs_inode *ip = NULL; - int error; + struct xfs_imap imap; + struct xfs_mount *mp = sc->mp; + struct xfs_inode *ip = NULL; + int error; /* We want to scan the inode we already had opened. */ if (sc->sm->sm_ino == 0 || sc->sm->sm_ino == ip_in->i_ino) { @@ -723,10 +723,10 @@ xchk_get_inode( int xchk_setup_inode_contents( struct xfs_scrub *sc, - struct xfs_inode *ip, - unsigned int resblks) + struct xfs_inode *ip, + unsigned int resblks) { - int error; + int error; error = xchk_get_inode(sc, ip); if (error) @@ -754,8 +754,8 @@ out: bool xchk_should_check_xref( struct xfs_scrub *sc, - int *error, - struct xfs_btree_cur **curpp) + int *error, + struct xfs_btree_cur **curpp) { /* No point in xref if we already know we're corrupt. */ if (xchk_skip_xref(sc->sm)) @@ -789,9 +789,9 @@ xchk_should_check_xref( void xchk_buffer_recheck( struct xfs_scrub *sc, - struct xfs_buf *bp) + struct xfs_buf *bp) { - xfs_failaddr_t fa; + xfs_failaddr_t fa; if (bp->b_ops == NULL) { xchk_block_set_corrupt(sc, bp); @@ -816,9 +816,9 @@ int xchk_metadata_inode_forks( struct xfs_scrub *sc) { - __u32 smtype; - bool shared; - int error; + __u32 smtype; + bool shared; + int error; if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) return 0; diff --git a/fs/xfs/scrub/common.h b/fs/xfs/scrub/common.h index c321230d32dc..2d4324d12f9a 100644 --- a/fs/xfs/scrub/common.h +++ b/fs/xfs/scrub/common.h @@ -108,24 +108,21 @@ xchk_setup_quota(struct xfs_scrub *sc, struct xfs_inode *ip) void xchk_ag_free(struct xfs_scrub *sc, struct xchk_ag *sa); int xchk_ag_init(struct xfs_scrub *sc, xfs_agnumber_t agno, - struct xchk_ag *sa); + struct xchk_ag *sa); void xchk_perag_get(struct xfs_mount *mp, struct xchk_ag *sa); int xchk_ag_read_headers(struct xfs_scrub *sc, xfs_agnumber_t agno, - struct xfs_buf **agi, struct xfs_buf **agf, - struct xfs_buf **agfl); + struct xfs_buf **agi, struct xfs_buf **agf, + struct xfs_buf **agfl); void xchk_ag_btcur_free(struct xchk_ag *sa); -int xchk_ag_btcur_init(struct xfs_scrub *sc, - struct xchk_ag *sa); -int xchk_count_rmap_ownedby_ag(struct xfs_scrub *sc, - struct xfs_btree_cur *cur, - struct xfs_owner_info *oinfo, - xfs_filblks_t *blocks); +int xchk_ag_btcur_init(struct xfs_scrub *sc, struct xchk_ag *sa); +int xchk_count_rmap_ownedby_ag(struct xfs_scrub *sc, struct xfs_btree_cur *cur, + struct xfs_owner_info *oinfo, xfs_filblks_t *blocks); -int xchk_setup_ag_btree(struct xfs_scrub *sc, - struct xfs_inode *ip, bool force_log); +int xchk_setup_ag_btree(struct xfs_scrub *sc, struct xfs_inode *ip, + bool force_log); int xchk_get_inode(struct xfs_scrub *sc, struct xfs_inode *ip_in); -int xchk_setup_inode_contents(struct xfs_scrub *sc, - struct xfs_inode *ip, unsigned int resblks); +int xchk_setup_inode_contents(struct xfs_scrub *sc, struct xfs_inode *ip, + unsigned int resblks); void xchk_buffer_recheck(struct xfs_scrub *sc, struct xfs_buf *bp); /* diff --git a/fs/xfs/scrub/dabtree.c b/fs/xfs/scrub/dabtree.c index 7fc12d540ea6..f1260b4bfdee 100644 --- a/fs/xfs/scrub/dabtree.c +++ b/fs/xfs/scrub/dabtree.c @@ -36,9 +36,9 @@ */ bool xchk_da_process_error( - struct xchk_da_btree *ds, - int level, - int *error) + struct xchk_da_btree *ds, + int level, + int *error) { struct xfs_scrub *sc = ds->sc; @@ -72,8 +72,8 @@ xchk_da_process_error( */ void xchk_da_set_corrupt( - struct xchk_da_btree *ds, - int level) + struct xchk_da_btree *ds, + int level) { struct xfs_scrub *sc = ds->sc; @@ -88,13 +88,13 @@ xchk_da_set_corrupt( /* Find an entry at a certain level in a da btree. */ STATIC void * xchk_da_btree_entry( - struct xchk_da_btree *ds, - int level, - int rec) + struct xchk_da_btree *ds, + int level, + int rec) { - char *ents; - struct xfs_da_state_blk *blk; - void *baddr; + char *ents; + struct xfs_da_state_blk *blk; + void *baddr; /* Dispatch the entry finding function. */ blk = &ds->state->path.blk[level]; @@ -158,9 +158,9 @@ xchk_da_btree_hash( */ STATIC bool xchk_da_btree_ptr_ok( - struct xchk_da_btree *ds, - int level, - xfs_dablk_t blkno) + struct xchk_da_btree *ds, + int level, + xfs_dablk_t blkno) { if (blkno < ds->lowest || (ds->highest != 0 && blkno >= ds->highest)) { xchk_da_set_corrupt(ds, level); @@ -246,13 +246,13 @@ static const struct xfs_buf_ops xchk_da_btree_buf_ops = { /* Check a block's sibling. */ STATIC int xchk_da_btree_block_check_sibling( - struct xchk_da_btree *ds, - int level, - int direction, - xfs_dablk_t sibling) + struct xchk_da_btree *ds, + int level, + int direction, + xfs_dablk_t sibling) { - int retval; - int error; + int retval; + int error; memcpy(&ds->state->altpath, &ds->state->path, sizeof(ds->state->altpath)); @@ -294,13 +294,13 @@ out: /* Check a block's sibling pointers. */ STATIC int xchk_da_btree_block_check_siblings( - struct xchk_da_btree *ds, - int level, - struct xfs_da_blkinfo *hdr) + struct xchk_da_btree *ds, + int level, + struct xfs_da_blkinfo *hdr) { - xfs_dablk_t forw; - xfs_dablk_t back; - int error = 0; + xfs_dablk_t forw; + xfs_dablk_t back; + int error = 0; forw = be32_to_cpu(hdr->forw); back = be32_to_cpu(hdr->back); @@ -474,9 +474,9 @@ out_nobuf: /* Visit all nodes and leaves of a da btree. */ int xchk_da_btree( - struct xfs_scrub *sc, + struct xfs_scrub *sc, int whichfork, - xchk_da_btree_rec_fn scrub_fn, + xchk_da_btree_rec_fn scrub_fn, void *private) { struct xchk_da_btree ds = {}; diff --git a/fs/xfs/scrub/dabtree.h b/fs/xfs/scrub/dabtree.h index a15c03389e8f..cb3f0003245b 100644 --- a/fs/xfs/scrub/dabtree.h +++ b/fs/xfs/scrub/dabtree.h @@ -9,12 +9,12 @@ /* dir/attr btree */ struct xchk_da_btree { - struct xfs_da_args dargs; - xfs_dahash_t hashes[XFS_DA_NODE_MAXDEPTH]; - int maxrecs[XFS_DA_NODE_MAXDEPTH]; - struct xfs_da_state *state; + struct xfs_da_args dargs; + xfs_dahash_t hashes[XFS_DA_NODE_MAXDEPTH]; + int maxrecs[XFS_DA_NODE_MAXDEPTH]; + struct xfs_da_state *state; struct xfs_scrub *sc; - void *private; + void *private; /* * Lowest and highest directory block address in which we expect @@ -22,10 +22,10 @@ struct xchk_da_btree { * (presumably) means between LEAF_OFFSET and FREE_OFFSET; for * attributes there is no limit. */ - xfs_dablk_t lowest; - xfs_dablk_t highest; + xfs_dablk_t lowest; + xfs_dablk_t highest; - int tree_level; + int tree_level; }; typedef int (*xchk_da_btree_rec_fn)(struct xchk_da_btree *ds, @@ -37,9 +37,8 @@ bool xchk_da_process_error(struct xchk_da_btree *ds, int level, int *error); /* Check for da btree corruption. */ void xchk_da_set_corrupt(struct xchk_da_btree *ds, int level); -int xchk_da_btree_hash(struct xchk_da_btree *ds, int level, - __be32 *hashp); +int xchk_da_btree_hash(struct xchk_da_btree *ds, int level, __be32 *hashp); int xchk_da_btree(struct xfs_scrub *sc, int whichfork, - xchk_da_btree_rec_fn scrub_fn, void *private); + xchk_da_btree_rec_fn scrub_fn, void *private); #endif /* __XFS_SCRUB_DABTREE_H__ */ diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c index 194a3ef69a9f..f58709052b03 100644 --- a/fs/xfs/scrub/dir.c +++ b/fs/xfs/scrub/dir.c @@ -33,7 +33,7 @@ int xchk_setup_directory( struct xfs_scrub *sc, - struct xfs_inode *ip) + struct xfs_inode *ip) { return xchk_setup_inode_contents(sc, ip, 0); } @@ -44,7 +44,7 @@ xchk_setup_directory( struct xchk_dir_ctx { /* VFS fill-directory iterator */ - struct dir_context dir_iter; + struct dir_context dir_iter; struct xfs_scrub *sc; }; @@ -52,15 +52,15 @@ struct xchk_dir_ctx { /* Check that an inode's mode matches a given DT_ type. */ STATIC int xchk_dir_check_ftype( - struct xchk_dir_ctx *sdc, - xfs_fileoff_t offset, - xfs_ino_t inum, - int dtype) + struct xchk_dir_ctx *sdc, + xfs_fileoff_t offset, + xfs_ino_t inum, + int dtype) { - struct xfs_mount *mp = sdc->sc->mp; - struct xfs_inode *ip; - int ino_dtype; - int error = 0; + struct xfs_mount *mp = sdc->sc->mp; + struct xfs_inode *ip; + int ino_dtype; + int error = 0; if (!xfs_sb_version_hasftype(&mp->m_sb)) { if (dtype != DT_UNKNOWN && dtype != DT_DIR) @@ -102,20 +102,20 @@ out: */ STATIC int xchk_dir_actor( - struct dir_context *dir_iter, - const char *name, - int namelen, - loff_t pos, - u64 ino, - unsigned type) + struct dir_context *dir_iter, + const char *name, + int namelen, + loff_t pos, + u64 ino, + unsigned type) { - struct xfs_mount *mp; - struct xfs_inode *ip; - struct xchk_dir_ctx *sdc; - struct xfs_name xname; - xfs_ino_t lookup_ino; - xfs_dablk_t offset; - int error = 0; + struct xfs_mount *mp; + struct xfs_inode *ip; + struct xchk_dir_ctx *sdc; + struct xfs_name xname; + xfs_ino_t lookup_ino; + xfs_dablk_t offset; + int error = 0; sdc = container_of(dir_iter, struct xchk_dir_ctx, dir_iter); ip = sdc->sc->ip; @@ -289,7 +289,7 @@ out: */ STATIC void xchk_directory_check_free_entry( - struct xfs_scrub *sc, + struct xfs_scrub *sc, xfs_dablk_t lblk, struct xfs_dir2_data_free *bf, struct xfs_dir2_data_unused *dup) @@ -314,7 +314,7 @@ xchk_directory_check_free_entry( /* Check free space info in a directory data block. */ STATIC int xchk_directory_data_bestfree( - struct xfs_scrub *sc, + struct xfs_scrub *sc, xfs_dablk_t lblk, bool is_block) { @@ -455,7 +455,7 @@ out: */ STATIC void xchk_directory_check_freesp( - struct xfs_scrub *sc, + struct xfs_scrub *sc, xfs_dablk_t lblk, struct xfs_buf *dbp, unsigned int len) @@ -474,7 +474,7 @@ xchk_directory_check_freesp( /* Check free space info in a directory leaf1 block. */ STATIC int xchk_directory_leaf1_bestfree( - struct xfs_scrub *sc, + struct xfs_scrub *sc, struct xfs_da_args *args, xfs_dablk_t lblk) { @@ -572,7 +572,7 @@ out: /* Check free space info in a directory freespace block. */ STATIC int xchk_directory_free_bestfree( - struct xfs_scrub *sc, + struct xfs_scrub *sc, struct xfs_da_args *args, xfs_dablk_t lblk) { @@ -628,18 +628,18 @@ STATIC int xchk_directory_blocks( struct xfs_scrub *sc) { - struct xfs_bmbt_irec got; - struct xfs_da_args args; - struct xfs_ifork *ifp; - struct xfs_mount *mp = sc->mp; - xfs_fileoff_t leaf_lblk; - xfs_fileoff_t free_lblk; - xfs_fileoff_t lblk; - struct xfs_iext_cursor icur; - xfs_dablk_t dabno; - bool found; - int is_block = 0; - int error; + struct xfs_bmbt_irec got; + struct xfs_da_args args; + struct xfs_ifork *ifp; + struct xfs_mount *mp = sc->mp; + xfs_fileoff_t leaf_lblk; + xfs_fileoff_t free_lblk; + xfs_fileoff_t lblk; + struct xfs_iext_cursor icur; + xfs_dablk_t dabno; + bool found; + int is_block = 0; + int error; /* Ignore local format directories. */ if (sc->ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS && @@ -772,14 +772,14 @@ int xchk_directory( struct xfs_scrub *sc) { - struct xchk_dir_ctx sdc = { + struct xchk_dir_ctx sdc = { .dir_iter.actor = xchk_dir_actor, .dir_iter.pos = 0, .sc = sc, }; - size_t bufsize; - loff_t oldpos; - int error = 0; + size_t bufsize; + loff_t oldpos; + int error = 0; if (!S_ISDIR(VFS_I(sc->ip)->i_mode)) return -ENOENT; diff --git a/fs/xfs/scrub/ialloc.c b/fs/xfs/scrub/ialloc.c index 6df8eba9f52b..224dba937492 100644 --- a/fs/xfs/scrub/ialloc.c +++ b/fs/xfs/scrub/ialloc.c @@ -37,7 +37,7 @@ int xchk_setup_ag_iallocbt( struct xfs_scrub *sc, - struct xfs_inode *ip) + struct xfs_inode *ip) { return xchk_setup_ag_btree(sc, ip, sc->try_harder); } @@ -51,7 +51,7 @@ xchk_setup_ag_iallocbt( */ static inline void xchk_iallocbt_chunk_xref_other( - struct xfs_scrub *sc, + struct xfs_scrub *sc, struct xfs_inobt_rec_incore *irec, xfs_agino_t agino) { @@ -76,7 +76,7 @@ xchk_iallocbt_chunk_xref_other( /* Cross-reference with the other btrees. */ STATIC void xchk_iallocbt_chunk_xref( - struct xfs_scrub *sc, + struct xfs_scrub *sc, struct xfs_inobt_rec_incore *irec, xfs_agino_t agino, xfs_agblock_t agbno, @@ -364,13 +364,13 @@ out: STATIC void xchk_iallocbt_xref_rmap_btreeblks( struct xfs_scrub *sc, - int which) + int which) { - struct xfs_owner_info oinfo; - xfs_filblks_t blocks; - xfs_extlen_t inobt_blocks = 0; - xfs_extlen_t finobt_blocks = 0; - int error; + struct xfs_owner_info oinfo; + xfs_filblks_t blocks; + xfs_extlen_t inobt_blocks = 0; + xfs_extlen_t finobt_blocks = 0; + int error; if (!sc->sa.ino_cur || !sc->sa.rmap_cur || (xfs_sb_version_hasfinobt(&sc->mp->m_sb) && !sc->sa.fino_cur) || @@ -404,12 +404,12 @@ xchk_iallocbt_xref_rmap_btreeblks( STATIC void xchk_iallocbt_xref_rmap_inodes( struct xfs_scrub *sc, - int which, - xfs_filblks_t inode_blocks) + int which, + xfs_filblks_t inode_blocks) { - struct xfs_owner_info oinfo; - xfs_filblks_t blocks; - int error; + struct xfs_owner_info oinfo; + xfs_filblks_t blocks; + int error; if (!sc->sa.rmap_cur || xchk_skip_xref(sc->sm)) return; @@ -428,12 +428,12 @@ xchk_iallocbt_xref_rmap_inodes( STATIC int xchk_iallocbt( struct xfs_scrub *sc, - xfs_btnum_t which) + xfs_btnum_t which) { - struct xfs_btree_cur *cur; - struct xfs_owner_info oinfo; - xfs_filblks_t inode_blocks = 0; - int error; + struct xfs_btree_cur *cur; + struct xfs_owner_info oinfo; + xfs_filblks_t inode_blocks = 0; + int error; xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INOBT); cur = which == XFS_BTNUM_INO ? sc->sa.ino_cur : sc->sa.fino_cur; @@ -475,13 +475,13 @@ xchk_finobt( static inline void xchk_xref_inode_check( struct xfs_scrub *sc, - xfs_agblock_t agbno, - xfs_extlen_t len, - struct xfs_btree_cur **icur, - bool should_have_inodes) + xfs_agblock_t agbno, + xfs_extlen_t len, + struct xfs_btree_cur **icur, + bool should_have_inodes) { - bool has_inodes; - int error; + bool has_inodes; + int error; if (!(*icur) || xchk_skip_xref(sc->sm)) return; @@ -497,8 +497,8 @@ xchk_xref_inode_check( void xchk_xref_is_not_inode_chunk( struct xfs_scrub *sc, - xfs_agblock_t agbno, - xfs_extlen_t len) + xfs_agblock_t agbno, + xfs_extlen_t len) { xchk_xref_inode_check(sc, agbno, len, &sc->sa.ino_cur, false); xchk_xref_inode_check(sc, agbno, len, &sc->sa.fino_cur, false); @@ -508,8 +508,8 @@ xchk_xref_is_not_inode_chunk( void xchk_xref_is_inode_chunk( struct xfs_scrub *sc, - xfs_agblock_t agbno, - xfs_extlen_t len) + xfs_agblock_t agbno, + xfs_extlen_t len) { xchk_xref_inode_check(sc, agbno, len, &sc->sa.ino_cur, true); } diff --git a/fs/xfs/scrub/inode.c b/fs/xfs/scrub/inode.c index 6cc027983c13..5b3b177c0fc9 100644 --- a/fs/xfs/scrub/inode.c +++ b/fs/xfs/scrub/inode.c @@ -39,9 +39,9 @@ int xchk_setup_inode( struct xfs_scrub *sc, - struct xfs_inode *ip) + struct xfs_inode *ip) { - int error; + int error; /* * Try to get the inode. If the verifiers fail, we try again @@ -78,12 +78,12 @@ out: STATIC void xchk_inode_extsize( struct xfs_scrub *sc, - struct xfs_dinode *dip, - xfs_ino_t ino, - uint16_t mode, - uint16_t flags) + struct xfs_dinode *dip, + xfs_ino_t ino, + uint16_t mode, + uint16_t flags) { - xfs_failaddr_t fa; + xfs_failaddr_t fa; fa = xfs_inode_validate_extsize(sc->mp, be32_to_cpu(dip->di_extsize), mode, flags); @@ -100,13 +100,13 @@ xchk_inode_extsize( STATIC void xchk_inode_cowextsize( struct xfs_scrub *sc, - struct xfs_dinode *dip, - xfs_ino_t ino, - uint16_t mode, - uint16_t flags, - uint64_t flags2) + struct xfs_dinode *dip, + xfs_ino_t ino, + uint16_t mode, + uint16_t flags, + uint64_t flags2) { - xfs_failaddr_t fa; + xfs_failaddr_t fa; fa = xfs_inode_validate_cowextsize(sc->mp, be32_to_cpu(dip->di_cowextsize), mode, flags, @@ -119,12 +119,12 @@ xchk_inode_cowextsize( STATIC void xchk_inode_flags( struct xfs_scrub *sc, - struct xfs_dinode *dip, - xfs_ino_t ino, - uint16_t mode, - uint16_t flags) + struct xfs_dinode *dip, + xfs_ino_t ino, + uint16_t mode, + uint16_t flags) { - struct xfs_mount *mp = sc->mp; + struct xfs_mount *mp = sc->mp; if (flags & ~XFS_DIFLAG_ANY) goto bad; @@ -164,13 +164,13 @@ bad: STATIC void xchk_inode_flags2( struct xfs_scrub *sc, - struct xfs_dinode *dip, - xfs_ino_t ino, - uint16_t mode, - uint16_t flags, - uint64_t flags2) + struct xfs_dinode *dip, + xfs_ino_t ino, + uint16_t mode, + uint16_t flags, + uint64_t flags2) { - struct xfs_mount *mp = sc->mp; + struct xfs_mount *mp = sc->mp; if (flags2 & ~XFS_DIFLAG2_ANY) goto bad; @@ -207,16 +207,16 @@ bad: STATIC void xchk_dinode( struct xfs_scrub *sc, - struct xfs_dinode *dip, - xfs_ino_t ino) + struct xfs_dinode *dip, + xfs_ino_t ino) { - struct xfs_mount *mp = sc->mp; - size_t fork_recs; - unsigned long long isize; - uint64_t flags2; - uint32_t nextents; - uint16_t flags; - uint16_t mode; + struct xfs_mount *mp = sc->mp; + size_t fork_recs; + unsigned long long isize; + uint64_t flags2; + uint32_t nextents; + uint16_t flags; + uint16_t mode; flags = be16_to_cpu(dip->di_flags); if (dip->di_version >= 3) @@ -426,7 +426,7 @@ xchk_dinode( */ static void xchk_inode_xref_finobt( - struct xfs_scrub *sc, + struct xfs_scrub *sc, xfs_ino_t ino) { struct xfs_inobt_rec_incore rec; @@ -470,12 +470,12 @@ xchk_inode_xref_finobt( STATIC void xchk_inode_xref_bmap( struct xfs_scrub *sc, - struct xfs_dinode *dip) + struct xfs_dinode *dip) { - xfs_extnum_t nextents; - xfs_filblks_t count; - xfs_filblks_t acount; - int error; + xfs_extnum_t nextents; + xfs_filblks_t count; + xfs_filblks_t acount; + int error; if (xchk_skip_xref(sc->sm)) return; @@ -504,13 +504,13 @@ xchk_inode_xref_bmap( STATIC void xchk_inode_xref( struct xfs_scrub *sc, - xfs_ino_t ino, - struct xfs_dinode *dip) + xfs_ino_t ino, + struct xfs_dinode *dip) { - struct xfs_owner_info oinfo; - xfs_agnumber_t agno; - xfs_agblock_t agbno; - int error; + struct xfs_owner_info oinfo; + xfs_agnumber_t agno; + xfs_agblock_t agbno; + int error; if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) return; @@ -541,11 +541,11 @@ xchk_inode_xref( static void xchk_inode_check_reflink_iflag( struct xfs_scrub *sc, - xfs_ino_t ino) + xfs_ino_t ino) { - struct xfs_mount *mp = sc->mp; - bool has_shared; - int error; + struct xfs_mount *mp = sc->mp; + bool has_shared; + int error; if (!xfs_sb_version_hasreflink(&mp->m_sb)) return; @@ -566,8 +566,8 @@ int xchk_inode( struct xfs_scrub *sc) { - struct xfs_dinode di; - int error = 0; + struct xfs_dinode di; + int error = 0; /* * If sc->ip is NULL, that means that the setup function called diff --git a/fs/xfs/scrub/parent.c b/fs/xfs/scrub/parent.c index 808459ad0c35..aacb0284c48a 100644 --- a/fs/xfs/scrub/parent.c +++ b/fs/xfs/scrub/parent.c @@ -29,7 +29,7 @@ int xchk_setup_parent( struct xfs_scrub *sc, - struct xfs_inode *ip) + struct xfs_inode *ip) { return xchk_setup_inode_contents(sc, ip, 0); } @@ -39,22 +39,22 @@ xchk_setup_parent( /* Look for an entry in a parent pointing to this inode. */ struct xchk_parent_ctx { - struct dir_context dc; - xfs_ino_t ino; - xfs_nlink_t nlink; + struct dir_context dc; + xfs_ino_t ino; + xfs_nlink_t nlink; }; /* Look for a single entry in a directory pointing to an inode. */ STATIC int xchk_parent_actor( - struct dir_context *dc, - const char *name, - int namelen, - loff_t pos, - u64 ino, - unsigned type) + struct dir_context *dc, + const char *name, + int namelen, + loff_t pos, + u64 ino, + unsigned type) { - struct xchk_parent_ctx *spc; + struct xchk_parent_ctx *spc; spc = container_of(dc, struct xchk_parent_ctx, dc); if (spc->ino == ino) @@ -66,19 +66,19 @@ xchk_parent_actor( STATIC int xchk_parent_count_parent_dentries( struct xfs_scrub *sc, - struct xfs_inode *parent, - xfs_nlink_t *nlink) + struct xfs_inode *parent, + xfs_nlink_t *nlink) { - struct xchk_parent_ctx spc = { + struct xchk_parent_ctx spc = { .dc.actor = xchk_parent_actor, .dc.pos = 0, .ino = sc->ip->i_ino, .nlink = 0, }; - size_t bufsize; - loff_t oldpos; - uint lock_mode; - int error = 0; + size_t bufsize; + loff_t oldpos; + uint lock_mode; + int error = 0; /* * If there are any blocks, read-ahead block 0 as we're almost @@ -122,14 +122,14 @@ out: STATIC int xchk_parent_validate( struct xfs_scrub *sc, - xfs_ino_t dnum, - bool *try_again) + xfs_ino_t dnum, + bool *try_again) { - struct xfs_mount *mp = sc->mp; - struct xfs_inode *dp = NULL; - xfs_nlink_t expected_nlink; - xfs_nlink_t nlink; - int error = 0; + struct xfs_mount *mp = sc->mp; + struct xfs_inode *dp = NULL; + xfs_nlink_t expected_nlink; + xfs_nlink_t nlink; + int error = 0; *try_again = false; @@ -257,11 +257,11 @@ int xchk_parent( struct xfs_scrub *sc) { - struct xfs_mount *mp = sc->mp; - xfs_ino_t dnum; - bool try_again; - int tries = 0; - int error = 0; + struct xfs_mount *mp = sc->mp; + xfs_ino_t dnum; + bool try_again; + int tries = 0; + int error = 0; /* * If we're a directory, check that the '..' link points up to diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c index 309ebeecfa5d..782d582d3edd 100644 --- a/fs/xfs/scrub/quota.c +++ b/fs/xfs/scrub/quota.c @@ -49,10 +49,10 @@ xchk_quota_to_dqtype( int xchk_setup_quota( struct xfs_scrub *sc, - struct xfs_inode *ip) + struct xfs_inode *ip) { - uint dqtype; - int error; + uint dqtype; + int error; if (!XFS_IS_QUOTA_RUNNING(sc->mp) || !XFS_IS_QUOTA_ON(sc->mp)) return -ENOENT; @@ -77,33 +77,33 @@ xchk_setup_quota( struct xchk_quota_info { struct xfs_scrub *sc; - xfs_dqid_t last_id; + xfs_dqid_t last_id; }; /* Scrub the fields in an individual quota item. */ STATIC int xchk_quota_item( - struct xfs_dquot *dq, - uint dqtype, - void *priv) + struct xfs_dquot *dq, + uint dqtype, + void *priv) { - struct xchk_quota_info *sqi = priv; + struct xchk_quota_info *sqi = priv; struct xfs_scrub *sc = sqi->sc; - struct xfs_mount *mp = sc->mp; - struct xfs_disk_dquot *d = &dq->q_core; - struct xfs_quotainfo *qi = mp->m_quotainfo; - xfs_fileoff_t offset; - unsigned long long bsoft; - unsigned long long isoft; - unsigned long long rsoft; - unsigned long long bhard; - unsigned long long ihard; - unsigned long long rhard; - unsigned long long bcount; - unsigned long long icount; - unsigned long long rcount; - xfs_ino_t fs_icount; - xfs_dqid_t id = be32_to_cpu(d->d_id); + struct xfs_mount *mp = sc->mp; + struct xfs_disk_dquot *d = &dq->q_core; + struct xfs_quotainfo *qi = mp->m_quotainfo; + xfs_fileoff_t offset; + unsigned long long bsoft; + unsigned long long isoft; + unsigned long long rsoft; + unsigned long long bhard; + unsigned long long ihard; + unsigned long long rhard; + unsigned long long bcount; + unsigned long long icount; + unsigned long long rcount; + xfs_ino_t fs_icount; + xfs_dqid_t id = be32_to_cpu(d->d_id); /* * Except for the root dquot, the actual dquot we got must either have @@ -197,12 +197,12 @@ STATIC int xchk_quota_data_fork( struct xfs_scrub *sc) { - struct xfs_bmbt_irec irec = { 0 }; - struct xfs_iext_cursor icur; - struct xfs_quotainfo *qi = sc->mp->m_quotainfo; - struct xfs_ifork *ifp; - xfs_fileoff_t max_dqid_off; - int error = 0; + struct xfs_bmbt_irec irec = { 0 }; + struct xfs_iext_cursor icur; + struct xfs_quotainfo *qi = sc->mp->m_quotainfo; + struct xfs_ifork *ifp; + xfs_fileoff_t max_dqid_off; + int error = 0; /* Invoke the fork scrubber. */ error = xchk_metadata_inode_forks(sc); @@ -236,11 +236,11 @@ int xchk_quota( struct xfs_scrub *sc) { - struct xchk_quota_info sqi; - struct xfs_mount *mp = sc->mp; - struct xfs_quotainfo *qi = mp->m_quotainfo; - uint dqtype; - int error = 0; + struct xchk_quota_info sqi; + struct xfs_mount *mp = sc->mp; + struct xfs_quotainfo *qi = mp->m_quotainfo; + uint dqtype; + int error = 0; dqtype = xchk_quota_to_dqtype(sc); diff --git a/fs/xfs/scrub/refcount.c b/fs/xfs/scrub/refcount.c index c1162d408987..e8c82b026083 100644 --- a/fs/xfs/scrub/refcount.c +++ b/fs/xfs/scrub/refcount.c @@ -30,7 +30,7 @@ int xchk_setup_ag_refcountbt( struct xfs_scrub *sc, - struct xfs_inode *ip) + struct xfs_inode *ip) { return xchk_setup_ag_btree(sc, ip, false); } @@ -74,21 +74,21 @@ xchk_setup_ag_refcountbt( * should always hold true. If not, the refcount is incorrect. */ struct xchk_refcnt_frag { - struct list_head list; - struct xfs_rmap_irec rm; + struct list_head list; + struct xfs_rmap_irec rm; }; struct xchk_refcnt_check { struct xfs_scrub *sc; - struct list_head fragments; + struct list_head fragments; /* refcount extent we're examining */ - xfs_agblock_t bno; - xfs_extlen_t len; - xfs_nlink_t refcount; + xfs_agblock_t bno; + xfs_extlen_t len; + xfs_nlink_t refcount; /* number of owners seen */ - xfs_nlink_t seen; + xfs_nlink_t seen; }; /* @@ -278,7 +278,7 @@ done: /* Use the rmap entries covering this extent to verify the refcount. */ STATIC void xchk_refcountbt_xref_rmap( - struct xfs_scrub *sc, + struct xfs_scrub *sc, xfs_agblock_t bno, xfs_extlen_t len, xfs_nlink_t refcount) @@ -326,9 +326,9 @@ out_free: STATIC void xchk_refcountbt_xref( struct xfs_scrub *sc, - xfs_agblock_t agbno, - xfs_extlen_t len, - xfs_nlink_t refcount) + xfs_agblock_t agbno, + xfs_extlen_t len, + xfs_nlink_t refcount) { if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) return; @@ -341,17 +341,17 @@ xchk_refcountbt_xref( /* Scrub a refcountbt record. */ STATIC int xchk_refcountbt_rec( - struct xchk_btree *bs, - union xfs_btree_rec *rec) + struct xchk_btree *bs, + union xfs_btree_rec *rec) { - struct xfs_mount *mp = bs->cur->bc_mp; - xfs_agblock_t *cow_blocks = bs->private; - xfs_agnumber_t agno = bs->cur->bc_private.a.agno; - xfs_agblock_t bno; - xfs_extlen_t len; - xfs_nlink_t refcount; - bool has_cowflag; - int error = 0; + struct xfs_mount *mp = bs->cur->bc_mp; + xfs_agblock_t *cow_blocks = bs->private; + xfs_agnumber_t agno = bs->cur->bc_private.a.agno; + xfs_agblock_t bno; + xfs_extlen_t len; + xfs_nlink_t refcount; + bool has_cowflag; + int error = 0; bno = be32_to_cpu(rec->refc.rc_startblock); len = be32_to_cpu(rec->refc.rc_blockcount); @@ -383,12 +383,12 @@ xchk_refcountbt_rec( STATIC void xchk_refcount_xref_rmap( struct xfs_scrub *sc, - struct xfs_owner_info *oinfo, - xfs_filblks_t cow_blocks) + struct xfs_owner_info *oinfo, + xfs_filblks_t cow_blocks) { - xfs_extlen_t refcbt_blocks = 0; - xfs_filblks_t blocks; - int error; + xfs_extlen_t refcbt_blocks = 0; + xfs_filblks_t blocks; + int error; if (!sc->sa.rmap_cur || xchk_skip_xref(sc->sm)) return; @@ -419,9 +419,9 @@ int xchk_refcountbt( struct xfs_scrub *sc) { - struct xfs_owner_info oinfo; - xfs_agblock_t cow_blocks = 0; - int error; + struct xfs_owner_info oinfo; + xfs_agblock_t cow_blocks = 0; + int error; xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_REFC); error = xchk_btree(sc, sc->sa.refc_cur, xchk_refcountbt_rec, @@ -437,7 +437,7 @@ xchk_refcountbt( /* xref check that a cow staging extent is marked in the refcountbt. */ void xchk_xref_is_cow_staging( - struct xfs_scrub *sc, + struct xfs_scrub *sc, xfs_agblock_t agbno, xfs_extlen_t len) { @@ -484,11 +484,11 @@ xchk_xref_is_cow_staging( void xchk_xref_is_not_shared( struct xfs_scrub *sc, - xfs_agblock_t agbno, - xfs_extlen_t len) + xfs_agblock_t agbno, + xfs_extlen_t len) { - bool shared; - int error; + bool shared; + int error; if (!sc->sa.refc_cur || xchk_skip_xref(sc->sm)) return; diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 29debd5649ac..5de1cac424ec 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -42,11 +42,11 @@ */ int xrep_attempt( - struct xfs_inode *ip, + struct xfs_inode *ip, struct xfs_scrub *sc, - bool *fixed) + bool *fixed) { - int error = 0; + int error = 0; trace_xrep_attempt(ip, sc->sm, error); @@ -94,7 +94,7 @@ xrep_attempt( */ void xrep_failure( - struct xfs_mount *mp) + struct xfs_mount *mp) { xfs_alert_ratelimited(mp, "Corruption not fixed during online repair. Unmount and run xfs_repair."); @@ -108,7 +108,7 @@ int xrep_probe( struct xfs_scrub *sc) { - int error = 0; + int error = 0; if (xchk_should_terminate(sc, &error)) return error; @@ -124,7 +124,7 @@ int xrep_roll_ag_trans( struct xfs_scrub *sc) { - int error; + int error; /* Keep the AG header buffers locked so we can keep going. */ xfs_trans_bhold(sc->tp, sc->sa.agi_bp); @@ -163,9 +163,9 @@ out_release: */ bool xrep_ag_has_space( - struct xfs_perag *pag, - xfs_extlen_t nr_blocks, - enum xfs_ag_resv_type type) + struct xfs_perag *pag, + xfs_extlen_t nr_blocks, + enum xfs_ag_resv_type type) { return !xfs_ag_resv_critical(pag, XFS_AG_RESV_RMAPBT) && !xfs_ag_resv_critical(pag, XFS_AG_RESV_METADATA) && @@ -179,7 +179,7 @@ xrep_ag_has_space( */ xfs_extlen_t xrep_calc_ag_resblks( - struct xfs_scrub *sc) + struct xfs_scrub *sc) { struct xfs_mount *mp = sc->mp; struct xfs_scrub_metadata *sm = sc->sm; @@ -280,13 +280,13 @@ xrep_calc_ag_resblks( int xrep_alloc_ag_block( struct xfs_scrub *sc, - struct xfs_owner_info *oinfo, - xfs_fsblock_t *fsbno, - enum xfs_ag_resv_type resv) + struct xfs_owner_info *oinfo, + xfs_fsblock_t *fsbno, + enum xfs_ag_resv_type resv) { - struct xfs_alloc_arg args = {0}; - xfs_agblock_t bno; - int error; + struct xfs_alloc_arg args = {0}; + xfs_agblock_t bno; + int error; switch (resv) { case XFS_AG_RESV_AGFL: @@ -330,7 +330,7 @@ xrep_alloc_ag_block( /* Initialize a new AG btree root block with zero entries. */ int xrep_init_btblock( - struct xfs_scrub *sc, + struct xfs_scrub *sc, xfs_fsblock_t fsb, struct xfs_buf **bpp, xfs_btnum_t btnum, @@ -386,11 +386,11 @@ xrep_init_btblock( int xrep_collect_btree_extent( struct xfs_scrub *sc, - struct xrep_extent_list *exlist, - xfs_fsblock_t fsbno, - xfs_extlen_t len) + struct xrep_extent_list *exlist, + xfs_fsblock_t fsbno, + xfs_extlen_t len) { - struct xrep_extent *rex; + struct xrep_extent *rex; trace_xrep_collect_btree_extent(sc->mp, XFS_FSB_TO_AGNO(sc->mp, fsbno), @@ -416,10 +416,10 @@ xrep_collect_btree_extent( void xrep_cancel_btree_extents( struct xfs_scrub *sc, - struct xrep_extent_list *exlist) + struct xrep_extent_list *exlist) { - struct xrep_extent *rex; - struct xrep_extent *n; + struct xrep_extent *rex; + struct xrep_extent *n; for_each_xrep_extent_safe(rex, n, exlist) { list_del(&rex->list); @@ -430,12 +430,12 @@ xrep_cancel_btree_extents( /* Compare two btree extents. */ static int xrep_btree_extent_cmp( - void *priv, - struct list_head *a, - struct list_head *b) + void *priv, + struct list_head *a, + struct list_head *b) { - struct xrep_extent *ap; - struct xrep_extent *bp; + struct xrep_extent *ap; + struct xrep_extent *bp; ap = container_of(a, struct xrep_extent, list); bp = container_of(b, struct xrep_extent, list); @@ -464,17 +464,17 @@ xrep_btree_extent_cmp( int xrep_subtract_extents( struct xfs_scrub *sc, - struct xrep_extent_list *exlist, - struct xrep_extent_list *sublist) + struct xrep_extent_list *exlist, + struct xrep_extent_list *sublist) { - struct list_head *lp; - struct xrep_extent *ex; - struct xrep_extent *newex; - struct xrep_extent *subex; - xfs_fsblock_t sub_fsb; - xfs_extlen_t sub_len; - int state; - int error = 0; + struct list_head *lp; + struct xrep_extent *ex; + struct xrep_extent *newex; + struct xrep_extent *subex; + xfs_fsblock_t sub_fsb; + xfs_extlen_t sub_len; + int state; + int error = 0; if (list_empty(&exlist->list) || list_empty(&sublist->list)) return 0; @@ -621,13 +621,13 @@ out: int xrep_invalidate_blocks( struct xfs_scrub *sc, - struct xrep_extent_list *exlist) + struct xrep_extent_list *exlist) { - struct xrep_extent *rex; - struct xrep_extent *n; - struct xfs_buf *bp; - xfs_fsblock_t fsbno; - xfs_agblock_t i; + struct xrep_extent *rex; + struct xrep_extent *n; + struct xfs_buf *bp; + xfs_fsblock_t fsbno; + xfs_agblock_t i; /* * For each block in each extent, see if there's an incore buffer for @@ -659,9 +659,9 @@ xrep_invalidate_blocks( int xrep_fix_freelist( struct xfs_scrub *sc, - bool can_shrink) + bool can_shrink) { - struct xfs_alloc_arg args = {0}; + struct xfs_alloc_arg args = {0}; args.mp = sc->mp; args.tp = sc->tp; @@ -679,10 +679,10 @@ xrep_fix_freelist( STATIC int xrep_put_freelist( struct xfs_scrub *sc, - xfs_agblock_t agbno) + xfs_agblock_t agbno) { - struct xfs_owner_info oinfo; - int error; + struct xfs_owner_info oinfo; + int error; /* Make sure there's space on the freelist. */ error = xrep_fix_freelist(sc, true); @@ -715,16 +715,16 @@ xrep_put_freelist( STATIC int xrep_dispose_btree_block( struct xfs_scrub *sc, - xfs_fsblock_t fsbno, - struct xfs_owner_info *oinfo, - enum xfs_ag_resv_type resv) + xfs_fsblock_t fsbno, + struct xfs_owner_info *oinfo, + enum xfs_ag_resv_type resv) { - struct xfs_btree_cur *cur; - struct xfs_buf *agf_bp = NULL; - xfs_agnumber_t agno; - xfs_agblock_t agbno; - bool has_other_rmap; - int error; + struct xfs_btree_cur *cur; + struct xfs_buf *agf_bp = NULL; + xfs_agnumber_t agno; + xfs_agblock_t agbno; + bool has_other_rmap; + int error; agno = XFS_FSB_TO_AGNO(sc->mp, fsbno); agbno = XFS_FSB_TO_AGBNO(sc->mp, fsbno); @@ -789,13 +789,13 @@ out_free: int xrep_reap_btree_extents( struct xfs_scrub *sc, - struct xrep_extent_list *exlist, - struct xfs_owner_info *oinfo, - enum xfs_ag_resv_type type) + struct xrep_extent_list *exlist, + struct xfs_owner_info *oinfo, + enum xfs_ag_resv_type type) { - struct xrep_extent *rex; - struct xrep_extent *n; - int error = 0; + struct xrep_extent *rex; + struct xrep_extent *n; + int error = 0; ASSERT(xfs_sb_version_hasrmapbt(&sc->mp->m_sb)); @@ -851,7 +851,7 @@ out: */ struct xrep_findroot { - struct xfs_scrub *sc; + struct xfs_scrub *sc; struct xfs_buf *agfl_bp; struct xfs_agf *agf; struct xrep_find_ag_btree *btree_info; @@ -860,11 +860,11 @@ struct xrep_findroot { /* See if our block is in the AGFL. */ STATIC int xrep_findroot_agfl_walk( - struct xfs_mount *mp, - xfs_agblock_t bno, - void *priv) + struct xfs_mount *mp, + xfs_agblock_t bno, + void *priv) { - xfs_agblock_t *agbno = priv; + xfs_agblock_t *agbno = priv; return (*agbno == bno) ? XFS_BTREE_QUERY_RANGE_ABORT : 0; } @@ -981,7 +981,7 @@ xrep_findroot_rmap( /* Find the roots of the per-AG btrees described in btree_info. */ int xrep_find_ag_btree_roots( - struct xfs_scrub *sc, + struct xfs_scrub *sc, struct xfs_buf *agf_bp, struct xrep_find_ag_btree *btree_info, struct xfs_buf *agfl_bp) @@ -1017,9 +1017,9 @@ xrep_find_ag_btree_roots( void xrep_force_quotacheck( struct xfs_scrub *sc, - uint dqtype) + uint dqtype) { - uint flag; + uint flag; flag = xfs_quota_chkd_flag(dqtype); if (!(flag & sc->mp->m_qflags)) @@ -1046,7 +1046,7 @@ int xrep_ino_dqattach( struct xfs_scrub *sc) { - int error; + int error; error = xfs_qm_dqattach_locked(sc->ip, false); switch (error) { diff --git a/fs/xfs/scrub/repair.h b/fs/xfs/scrub/repair.h index 677f4b73b5ec..91355f6b0087 100644 --- a/fs/xfs/scrub/repair.h +++ b/fs/xfs/scrub/repair.h @@ -15,33 +15,31 @@ static inline int xrep_notsupported(struct xfs_scrub *sc) /* Repair helpers */ -int xrep_attempt(struct xfs_inode *ip, struct xfs_scrub *sc, - bool *fixed); +int xrep_attempt(struct xfs_inode *ip, struct xfs_scrub *sc, bool *fixed); void xrep_failure(struct xfs_mount *mp); int xrep_roll_ag_trans(struct xfs_scrub *sc); bool xrep_ag_has_space(struct xfs_perag *pag, xfs_extlen_t nr_blocks, enum xfs_ag_resv_type type); xfs_extlen_t xrep_calc_ag_resblks(struct xfs_scrub *sc); -int xrep_alloc_ag_block(struct xfs_scrub *sc, - struct xfs_owner_info *oinfo, xfs_fsblock_t *fsbno, - enum xfs_ag_resv_type resv); +int xrep_alloc_ag_block(struct xfs_scrub *sc, struct xfs_owner_info *oinfo, + xfs_fsblock_t *fsbno, enum xfs_ag_resv_type resv); int xrep_init_btblock(struct xfs_scrub *sc, xfs_fsblock_t fsb, struct xfs_buf **bpp, xfs_btnum_t btnum, const struct xfs_buf_ops *ops); struct xrep_extent { - struct list_head list; - xfs_fsblock_t fsbno; - xfs_extlen_t len; + struct list_head list; + xfs_fsblock_t fsbno; + xfs_extlen_t len; }; struct xrep_extent_list { - struct list_head list; + struct list_head list; }; static inline void xrep_init_extent_list( - struct xrep_extent_list *exlist) + struct xrep_extent_list *exlist) { INIT_LIST_HEAD(&exlist->list); } @@ -78,10 +76,8 @@ struct xrep_find_ag_btree { unsigned int height; }; -int xrep_find_ag_btree_roots(struct xfs_scrub *sc, - struct xfs_buf *agf_bp, - struct xrep_find_ag_btree *btree_info, - struct xfs_buf *agfl_bp); +int xrep_find_ag_btree_roots(struct xfs_scrub *sc, struct xfs_buf *agf_bp, + struct xrep_find_ag_btree *btree_info, struct xfs_buf *agfl_bp); void xrep_force_quotacheck(struct xfs_scrub *sc, uint dqtype); int xrep_ino_dqattach(struct xfs_scrub *sc); @@ -93,9 +89,9 @@ int xrep_superblock(struct xfs_scrub *sc); #else static inline int xrep_attempt( - struct xfs_inode *ip, + struct xfs_inode *ip, struct xfs_scrub *sc, - bool *fixed) + bool *fixed) { return -EOPNOTSUPP; } diff --git a/fs/xfs/scrub/rmap.c b/fs/xfs/scrub/rmap.c index dc9c91a706ff..5e293c129813 100644 --- a/fs/xfs/scrub/rmap.c +++ b/fs/xfs/scrub/rmap.c @@ -31,7 +31,7 @@ int xchk_setup_ag_rmapbt( struct xfs_scrub *sc, - struct xfs_inode *ip) + struct xfs_inode *ip) { return xchk_setup_ag_btree(sc, ip, false); } @@ -42,15 +42,15 @@ xchk_setup_ag_rmapbt( STATIC void xchk_rmapbt_xref_refc( struct xfs_scrub *sc, - struct xfs_rmap_irec *irec) + struct xfs_rmap_irec *irec) { - xfs_agblock_t fbno; - xfs_extlen_t flen; - bool non_inode; - bool is_bmbt; - bool is_attr; - bool is_unwritten; - int error; + xfs_agblock_t fbno; + xfs_extlen_t flen; + bool non_inode; + bool is_bmbt; + bool is_attr; + bool is_unwritten; + int error; if (!sc->sa.refc_cur || xchk_skip_xref(sc->sm)) return; @@ -73,10 +73,10 @@ xchk_rmapbt_xref_refc( STATIC void xchk_rmapbt_xref( struct xfs_scrub *sc, - struct xfs_rmap_irec *irec) + struct xfs_rmap_irec *irec) { - xfs_agblock_t agbno = irec->rm_startblock; - xfs_extlen_t len = irec->rm_blockcount; + xfs_agblock_t agbno = irec->rm_startblock; + xfs_extlen_t len = irec->rm_blockcount; if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) return; @@ -96,17 +96,17 @@ xchk_rmapbt_xref( /* Scrub an rmapbt record. */ STATIC int xchk_rmapbt_rec( - struct xchk_btree *bs, - union xfs_btree_rec *rec) + struct xchk_btree *bs, + union xfs_btree_rec *rec) { - struct xfs_mount *mp = bs->cur->bc_mp; - struct xfs_rmap_irec irec; - xfs_agnumber_t agno = bs->cur->bc_private.a.agno; - bool non_inode; - bool is_unwritten; - bool is_bmbt; - bool is_attr; - int error; + struct xfs_mount *mp = bs->cur->bc_mp; + struct xfs_rmap_irec irec; + xfs_agnumber_t agno = bs->cur->bc_private.a.agno; + bool non_inode; + bool is_unwritten; + bool is_bmbt; + bool is_attr; + int error; error = xfs_rmap_btrec_to_irec(rec, &irec); if (!xchk_btree_process_error(bs->sc, bs->cur, 0, &error)) @@ -174,7 +174,7 @@ int xchk_rmapbt( struct xfs_scrub *sc) { - struct xfs_owner_info oinfo; + struct xfs_owner_info oinfo; xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_AG); return xchk_btree(sc, sc->sa.rmap_cur, xchk_rmapbt_rec, @@ -185,13 +185,13 @@ xchk_rmapbt( static inline void xchk_xref_check_owner( struct xfs_scrub *sc, - xfs_agblock_t bno, - xfs_extlen_t len, - struct xfs_owner_info *oinfo, - bool should_have_rmap) + xfs_agblock_t bno, + xfs_extlen_t len, + struct xfs_owner_info *oinfo, + bool should_have_rmap) { - bool has_rmap; - int error; + bool has_rmap; + int error; if (!sc->sa.rmap_cur || xchk_skip_xref(sc->sm)) return; @@ -208,9 +208,9 @@ xchk_xref_check_owner( void xchk_xref_is_owned_by( struct xfs_scrub *sc, - xfs_agblock_t bno, - xfs_extlen_t len, - struct xfs_owner_info *oinfo) + xfs_agblock_t bno, + xfs_extlen_t len, + struct xfs_owner_info *oinfo) { xchk_xref_check_owner(sc, bno, len, oinfo, true); } @@ -219,9 +219,9 @@ xchk_xref_is_owned_by( void xchk_xref_is_not_owned_by( struct xfs_scrub *sc, - xfs_agblock_t bno, - xfs_extlen_t len, - struct xfs_owner_info *oinfo) + xfs_agblock_t bno, + xfs_extlen_t len, + struct xfs_owner_info *oinfo) { xchk_xref_check_owner(sc, bno, len, oinfo, false); } @@ -230,11 +230,11 @@ xchk_xref_is_not_owned_by( void xchk_xref_has_no_owner( struct xfs_scrub *sc, - xfs_agblock_t bno, - xfs_extlen_t len) + xfs_agblock_t bno, + xfs_extlen_t len) { - bool has_rmap; - int error; + bool has_rmap; + int error; if (!sc->sa.rmap_cur || xchk_skip_xref(sc->sm)) return; diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c index 653a809bba34..665d4bbb17cc 100644 --- a/fs/xfs/scrub/rtbitmap.c +++ b/fs/xfs/scrub/rtbitmap.c @@ -27,9 +27,9 @@ int xchk_setup_rt( struct xfs_scrub *sc, - struct xfs_inode *ip) + struct xfs_inode *ip) { - int error; + int error; error = xchk_setup_fs(sc, ip); if (error) @@ -47,13 +47,13 @@ xchk_setup_rt( /* Scrub a free extent record from the realtime bitmap. */ STATIC int xchk_rtbitmap_rec( - struct xfs_trans *tp, - struct xfs_rtalloc_rec *rec, - void *priv) + struct xfs_trans *tp, + struct xfs_rtalloc_rec *rec, + void *priv) { struct xfs_scrub *sc = priv; - xfs_rtblock_t startblock; - xfs_rtblock_t blockcount; + xfs_rtblock_t startblock; + xfs_rtblock_t blockcount; startblock = rec->ar_startext * tp->t_mountp->m_sb.sb_rextsize; blockcount = rec->ar_extcount * tp->t_mountp->m_sb.sb_rextsize; @@ -70,7 +70,7 @@ int xchk_rtbitmap( struct xfs_scrub *sc) { - int error; + int error; /* Invoke the fork scrubber. */ error = xchk_metadata_inode_forks(sc); @@ -90,10 +90,10 @@ int xchk_rtsummary( struct xfs_scrub *sc) { - struct xfs_inode *rsumip = sc->mp->m_rsumip; - struct xfs_inode *old_ip = sc->ip; - uint old_ilock_flags = sc->ilock_flags; - int error = 0; + struct xfs_inode *rsumip = sc->mp->m_rsumip; + struct xfs_inode *old_ip = sc->ip; + uint old_ilock_flags = sc->ilock_flags; + int error = 0; /* * We ILOCK'd the rt bitmap ip in the setup routine, now lock the @@ -126,14 +126,14 @@ out: void xchk_xref_is_used_rt_space( struct xfs_scrub *sc, - xfs_rtblock_t fsbno, - xfs_extlen_t len) + xfs_rtblock_t fsbno, + xfs_extlen_t len) { - xfs_rtblock_t startext; - xfs_rtblock_t endext; - xfs_rtblock_t extcount; - bool is_free; - int error; + xfs_rtblock_t startext; + xfs_rtblock_t endext; + xfs_rtblock_t extcount; + bool is_free; + int error; if (xchk_skip_xref(sc->sm)) return; diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c index b3c6420ccae5..5956b8073e2f 100644 --- a/fs/xfs/scrub/scrub.c +++ b/fs/xfs/scrub/scrub.c @@ -153,7 +153,7 @@ static int xchk_probe( struct xfs_scrub *sc) { - int error = 0; + int error = 0; if (xchk_should_terminate(sc, &error)) return error; @@ -167,8 +167,8 @@ xchk_probe( STATIC int xchk_teardown( struct xfs_scrub *sc, - struct xfs_inode *ip_in, - int error) + struct xfs_inode *ip_in, + int error) { xchk_ag_free(sc, &sc->sa); if (sc->tp) { @@ -479,7 +479,7 @@ xfs_scrub_metadata( struct xfs_inode *ip, struct xfs_scrub_metadata *sm) { - struct xfs_scrub sc; + struct xfs_scrub sc; struct xfs_mount *mp = ip->i_mount; bool try_harder = false; bool already_fixed = false; diff --git a/fs/xfs/scrub/scrub.h b/fs/xfs/scrub/scrub.h index 47c75d2f28da..af323b229c4b 100644 --- a/fs/xfs/scrub/scrub.h +++ b/fs/xfs/scrub/scrub.h @@ -36,21 +36,21 @@ struct xchk_meta_ops { /* Buffer pointers and btree cursors for an entire AG. */ struct xchk_ag { - xfs_agnumber_t agno; - struct xfs_perag *pag; + xfs_agnumber_t agno; + struct xfs_perag *pag; /* AG btree roots */ - struct xfs_buf *agf_bp; - struct xfs_buf *agfl_bp; - struct xfs_buf *agi_bp; + struct xfs_buf *agf_bp; + struct xfs_buf *agfl_bp; + struct xfs_buf *agi_bp; /* AG btrees */ - struct xfs_btree_cur *bno_cur; - struct xfs_btree_cur *cnt_cur; - struct xfs_btree_cur *ino_cur; - struct xfs_btree_cur *fino_cur; - struct xfs_btree_cur *rmap_cur; - struct xfs_btree_cur *refc_cur; + struct xfs_btree_cur *bno_cur; + struct xfs_btree_cur *cnt_cur; + struct xfs_btree_cur *ino_cur; + struct xfs_btree_cur *fino_cur; + struct xfs_btree_cur *rmap_cur; + struct xfs_btree_cur *refc_cur; }; struct xfs_scrub { @@ -66,7 +66,7 @@ struct xfs_scrub { bool has_quotaofflock; /* State tracking for single-AG operations. */ - struct xchk_ag sa; + struct xchk_ag sa; }; /* Metadata scrubbers */ @@ -115,27 +115,25 @@ xchk_quota(struct xfs_scrub *sc) #endif /* cross-referencing helpers */ -void xchk_xref_is_used_space(struct xfs_scrub *sc, - xfs_agblock_t agbno, xfs_extlen_t len); -void xchk_xref_is_not_inode_chunk(struct xfs_scrub *sc, - xfs_agblock_t agbno, xfs_extlen_t len); -void xchk_xref_is_inode_chunk(struct xfs_scrub *sc, - xfs_agblock_t agbno, xfs_extlen_t len); -void xchk_xref_is_owned_by(struct xfs_scrub *sc, - xfs_agblock_t agbno, xfs_extlen_t len, - struct xfs_owner_info *oinfo); -void xchk_xref_is_not_owned_by(struct xfs_scrub *sc, - xfs_agblock_t agbno, xfs_extlen_t len, - struct xfs_owner_info *oinfo); -void xchk_xref_has_no_owner(struct xfs_scrub *sc, - xfs_agblock_t agbno, xfs_extlen_t len); -void xchk_xref_is_cow_staging(struct xfs_scrub *sc, - xfs_agblock_t bno, xfs_extlen_t len); -void xchk_xref_is_not_shared(struct xfs_scrub *sc, - xfs_agblock_t bno, xfs_extlen_t len); +void xchk_xref_is_used_space(struct xfs_scrub *sc, xfs_agblock_t agbno, + xfs_extlen_t len); +void xchk_xref_is_not_inode_chunk(struct xfs_scrub *sc, xfs_agblock_t agbno, + xfs_extlen_t len); +void xchk_xref_is_inode_chunk(struct xfs_scrub *sc, xfs_agblock_t agbno, + xfs_extlen_t len); +void xchk_xref_is_owned_by(struct xfs_scrub *sc, xfs_agblock_t agbno, + xfs_extlen_t len, struct xfs_owner_info *oinfo); +void xchk_xref_is_not_owned_by(struct xfs_scrub *sc, xfs_agblock_t agbno, + xfs_extlen_t len, struct xfs_owner_info *oinfo); +void xchk_xref_has_no_owner(struct xfs_scrub *sc, xfs_agblock_t agbno, + xfs_extlen_t len); +void xchk_xref_is_cow_staging(struct xfs_scrub *sc, xfs_agblock_t bno, + xfs_extlen_t len); +void xchk_xref_is_not_shared(struct xfs_scrub *sc, xfs_agblock_t bno, + xfs_extlen_t len); #ifdef CONFIG_XFS_RT -void xchk_xref_is_used_rt_space(struct xfs_scrub *sc, - xfs_rtblock_t rtbno, xfs_extlen_t len); +void xchk_xref_is_used_rt_space(struct xfs_scrub *sc, xfs_rtblock_t rtbno, + xfs_extlen_t len); #else # define xchk_xref_is_used_rt_space(sc, rtbno, len) do { } while (0) #endif diff --git a/fs/xfs/scrub/symlink.c b/fs/xfs/scrub/symlink.c index 56c6347e9482..f7ebaa946999 100644 --- a/fs/xfs/scrub/symlink.c +++ b/fs/xfs/scrub/symlink.c @@ -27,7 +27,7 @@ int xchk_setup_symlink( struct xfs_scrub *sc, - struct xfs_inode *ip) + struct xfs_inode *ip) { /* Allocate the buffer without the inode lock held. */ sc->buf = kmem_zalloc_large(XFS_SYMLINK_MAXLEN + 1, KM_SLEEP); @@ -43,10 +43,10 @@ int xchk_symlink( struct xfs_scrub *sc) { - struct xfs_inode *ip = sc->ip; - struct xfs_ifork *ifp; - loff_t len; - int error = 0; + struct xfs_inode *ip = sc->ip; + struct xfs_ifork *ifp; + loff_t len; + int error = 0; if (!S_ISLNK(VFS_I(ip)->i_mode)) return -ENOENT; diff --git a/fs/xfs/scrub/trace.c b/fs/xfs/scrub/trace.c index 1ef1202a1e45..96feaf8dcdec 100644 --- a/fs/xfs/scrub/trace.c +++ b/fs/xfs/scrub/trace.c @@ -23,8 +23,8 @@ /* Figure out which block the btree cursor was pointing to. */ static inline xfs_fsblock_t xchk_btree_cur_fsbno( - struct xfs_btree_cur *cur, - int level) + struct xfs_btree_cur *cur, + int level) { if (level < cur->bc_nlevels && cur->bc_bufs[level]) return XFS_DADDR_TO_FSB(cur->bc_mp, cur->bc_bufs[level]->b_bn); -- cgit v1.2.3 From 2e9e6481e2a78de3a85083beccfbf6eda2689922 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 19 Jul 2018 12:29:13 -0700 Subject: xfs: detect and fix bad summary counts at mount Filippo Giunchedi complained that xfs doesn't even perform basic sanity checks of the fs summary counters at mount time. Therefore, recalculate the summary counters from the AGFs after log recovery if the counts were bad (or we had to recover the fs). Enhance the recalculation routine to fail the mount entirely if the new values are also obviously incorrect. We use a mount state flag to record the "bad summary count" state so that the (subsequent) online fsck patches can detect subtlely incorrect counts and set the flag; clear it userspace asks for a repair; or force a recalculation at the next mount if nobody fixes it by unmount time. Reported-by: Filippo Giunchedi Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_sb.c | 21 +++++++++++-- fs/xfs/xfs_mount.c | 80 ++++++++++++++++++++++++++++++++++---------------- fs/xfs/xfs_mount.h | 1 + 3 files changed, 73 insertions(+), 29 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index 350119eeaecb..b3ad15956366 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -804,6 +804,7 @@ xfs_initialize_perag_data( uint64_t bfree = 0; uint64_t bfreelst = 0; uint64_t btree = 0; + uint64_t fdblocks; int error; for (index = 0; index < agcount; index++) { @@ -827,17 +828,31 @@ xfs_initialize_perag_data( btree += pag->pagf_btreeblks; xfs_perag_put(pag); } + fdblocks = bfree + bfreelst + btree; + + /* + * If the new summary counts are obviously incorrect, fail the + * mount operation because that implies the AGFs are also corrupt. + * Clear BAD_SUMMARY so that we don't unmount with a dirty log, which + * will prevent xfs_repair from fixing anything. + */ + if (fdblocks > sbp->sb_dblocks || ifree > ialloc) { + xfs_alert(mp, "AGF corruption. Please run xfs_repair."); + error = -EFSCORRUPTED; + goto out; + } /* Overwrite incore superblock counters with just-read data */ spin_lock(&mp->m_sb_lock); sbp->sb_ifree = ifree; sbp->sb_icount = ialloc; - sbp->sb_fdblocks = bfree + bfreelst + btree; + sbp->sb_fdblocks = fdblocks; spin_unlock(&mp->m_sb_lock); xfs_reinit_percpu_counters(mp); - - return 0; +out: + mp->m_flags &= ~XFS_MOUNT_BAD_SUMMARY; + return error; } /* diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index a3378252baa1..60462c35ad4b 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -606,6 +606,56 @@ xfs_default_resblks(xfs_mount_t *mp) return resblks; } +/* Ensure the summary counts are correct. */ +STATIC int +xfs_check_summary_counts( + struct xfs_mount *mp) +{ + /* + * The AG0 superblock verifier rejects in-progress filesystems, + * so we should never see the flag set this far into mounting. + */ + if (mp->m_sb.sb_inprogress) { + xfs_err(mp, "sb_inprogress set after log recovery??"); + WARN_ON(1); + return -EFSCORRUPTED; + } + + /* + * Now the log is mounted, we know if it was an unclean shutdown or + * not. If it was, with the first phase of recovery has completed, we + * have consistent AG blocks on disk. We have not recovered EFIs yet, + * but they are recovered transactionally in the second recovery phase + * later. + * + * If the log was clean when we mounted, we can check the summary + * counters. If any of them are obviously incorrect, we can recompute + * them from the AGF headers in the next step. + */ + if (XFS_LAST_UNMOUNT_WAS_CLEAN(mp) && + (mp->m_sb.sb_fdblocks > mp->m_sb.sb_dblocks || + mp->m_sb.sb_ifree > mp->m_sb.sb_icount)) + mp->m_flags |= XFS_MOUNT_BAD_SUMMARY; + + /* + * We can safely re-initialise incore superblock counters from the + * per-ag data. These may not be correct if the filesystem was not + * cleanly unmounted, so we waited for recovery to finish before doing + * this. + * + * If the filesystem was cleanly unmounted or the previous check did + * not flag anything weird, then we can trust the values in the + * superblock to be correct and we don't need to do anything here. + * Otherwise, recalculate the summary counters. + */ + if ((!xfs_sb_version_haslazysbcount(&mp->m_sb) || + XFS_LAST_UNMOUNT_WAS_CLEAN(mp)) && + !(mp->m_flags & XFS_MOUNT_BAD_SUMMARY)) + return 0; + + return xfs_initialize_perag_data(mp, mp->m_sb.sb_agcount); +} + /* * This function does the following on an initial mount of a file system: * - reads the superblock from disk and init the mount struct @@ -831,32 +881,10 @@ xfs_mountfs( goto out_fail_wait; } - /* - * Now the log is mounted, we know if it was an unclean shutdown or - * not. If it was, with the first phase of recovery has completed, we - * have consistent AG blocks on disk. We have not recovered EFIs yet, - * but they are recovered transactionally in the second recovery phase - * later. - * - * Hence we can safely re-initialise incore superblock counters from - * the per-ag data. These may not be correct if the filesystem was not - * cleanly unmounted, so we need to wait for recovery to finish before - * doing this. - * - * If the filesystem was cleanly unmounted, then we can trust the - * values in the superblock to be correct and we don't need to do - * anything here. - * - * If we are currently making the filesystem, the initialisation will - * fail as the perag data is in an undefined state. - */ - if (xfs_sb_version_haslazysbcount(&mp->m_sb) && - !XFS_LAST_UNMOUNT_WAS_CLEAN(mp) && - !mp->m_sb.sb_inprogress) { - error = xfs_initialize_perag_data(mp, sbp->sb_agcount); - if (error) - goto out_log_dealloc; - } + /* Make sure the summary counts are ok. */ + error = xfs_check_summary_counts(mp); + if (error) + goto out_log_dealloc; /* * Get and sanity-check the root inode. diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 245349d1e23f..f08907db9c61 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -202,6 +202,7 @@ typedef struct xfs_mount { must be synchronous except for space allocations */ #define XFS_MOUNT_UNMOUNTING (1ULL << 1) /* filesystem is unmounting */ +#define XFS_MOUNT_BAD_SUMMARY (1ULL << 2) /* summary counters are bad */ #define XFS_MOUNT_WAS_CLEAN (1ULL << 3) #define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem operations, typically for -- cgit v1.2.3 From 53235f22151ea7229e1251e46e68098bcf74922d Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 20 Jul 2018 09:28:39 -0700 Subject: xfs: refactor unmount record write Refactor the writing of the unmount record into a separate helper. No functionality changes. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_log_format.h | 13 ++++ fs/xfs/xfs_log.c | 131 ++++++++++++++++++++++------------------- 2 files changed, 82 insertions(+), 62 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h index 79bb79853c9f..e5f97c69b320 100644 --- a/fs/xfs/libxfs/xfs_log_format.h +++ b/fs/xfs/libxfs/xfs_log_format.h @@ -77,6 +77,19 @@ static inline uint xlog_get_cycle(char *ptr) #define XLOG_UNMOUNT_TYPE 0x556e /* Un for Unmount */ +/* + * Log item for unmount records. + * + * The unmount record used to have a string "Unmount filesystem--" in the + * data section where the "Un" was really a magic number (XLOG_UNMOUNT_TYPE). + * We just write the magic number now; see xfs_log_unmount_write. + */ +struct xfs_unmount_log_format { + uint16_t magic; /* XLOG_UNMOUNT_TYPE */ + uint16_t pad1; + uint32_t pad2; /* may as well make it 64 bits */ +}; + /* Region types for iovec's i_type */ #define XLOG_REG_TYPE_BFORMAT 1 #define XLOG_REG_TYPE_BCHUNK 2 diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 5e56f3b93d4b..bac586cbc54e 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -826,6 +826,74 @@ xfs_log_mount_cancel( * deallocation must not be done until source-end. */ +/* Actually write the unmount record to disk. */ +static void +xfs_log_write_unmount_record( + struct xfs_mount *mp) +{ + /* the data section must be 32 bit size aligned */ + struct xfs_unmount_log_format magic = { + .magic = XLOG_UNMOUNT_TYPE, + }; + struct xfs_log_iovec reg = { + .i_addr = &magic, + .i_len = sizeof(magic), + .i_type = XLOG_REG_TYPE_UNMOUNT, + }; + struct xfs_log_vec vec = { + .lv_niovecs = 1, + .lv_iovecp = ®, + }; + struct xlog *log = mp->m_log; + struct xlog_in_core *iclog; + struct xlog_ticket *tic = NULL; + xfs_lsn_t lsn; + int error; + + error = xfs_log_reserve(mp, 600, 1, &tic, XFS_LOG, 0); + if (error) + goto out_err; + + /* remove inited flag, and account for space used */ + tic->t_flags = 0; + tic->t_curr_res -= sizeof(magic); + error = xlog_write(log, &vec, tic, &lsn, NULL, XLOG_UNMOUNT_TRANS); + /* + * At this point, we're umounting anyway, so there's no point in + * transitioning log state to IOERROR. Just continue... + */ +out_err: + if (error) + xfs_alert(mp, "%s: unmount record failed", __func__); + + spin_lock(&log->l_icloglock); + iclog = log->l_iclog; + atomic_inc(&iclog->ic_refcnt); + xlog_state_want_sync(log, iclog); + spin_unlock(&log->l_icloglock); + error = xlog_state_release_iclog(log, iclog); + + spin_lock(&log->l_icloglock); + switch (iclog->ic_state) { + default: + if (!XLOG_FORCED_SHUTDOWN(log)) { + xlog_wait(&iclog->ic_force_wait, &log->l_icloglock); + break; + } + /* fall through */ + case XLOG_STATE_ACTIVE: + case XLOG_STATE_DIRTY: + spin_unlock(&log->l_icloglock); + break; + } + + if (tic) { + trace_xfs_log_umount_write(log, tic); + xlog_ungrant_log_space(log, tic); + xfs_log_ticket_put(tic); + } +} + /* * Unmount record used to have a string "Unmount filesystem--" in the * data section where the "Un" was really a magic number (XLOG_UNMOUNT_TYPE). @@ -842,8 +910,6 @@ xfs_log_unmount_write(xfs_mount_t *mp) #ifdef DEBUG xlog_in_core_t *first_iclog; #endif - xlog_ticket_t *tic = NULL; - xfs_lsn_t lsn; int error; /* @@ -870,66 +936,7 @@ xfs_log_unmount_write(xfs_mount_t *mp) } while (iclog != first_iclog); #endif if (! (XLOG_FORCED_SHUTDOWN(log))) { - error = xfs_log_reserve(mp, 600, 1, &tic, XFS_LOG, 0); - if (!error) { - /* the data section must be 32 bit size aligned */ - struct { - uint16_t magic; - uint16_t pad1; - uint32_t pad2; /* may as well make it 64 bits */ - } magic = { - .magic = XLOG_UNMOUNT_TYPE, - }; - struct xfs_log_iovec reg = { - .i_addr = &magic, - .i_len = sizeof(magic), - .i_type = XLOG_REG_TYPE_UNMOUNT, - }; - struct xfs_log_vec vec = { - .lv_niovecs = 1, - .lv_iovecp = ®, - }; - - /* remove inited flag, and account for space used */ - tic->t_flags = 0; - tic->t_curr_res -= sizeof(magic); - error = xlog_write(log, &vec, tic, &lsn, - NULL, XLOG_UNMOUNT_TRANS); - /* - * At this point, we're umounting anyway, - * so there's no point in transitioning log state - * to IOERROR. Just continue... - */ - } - - if (error) - xfs_alert(mp, "%s: unmount record failed", __func__); - - - spin_lock(&log->l_icloglock); - iclog = log->l_iclog; - atomic_inc(&iclog->ic_refcnt); - xlog_state_want_sync(log, iclog); - spin_unlock(&log->l_icloglock); - error = xlog_state_release_iclog(log, iclog); - - spin_lock(&log->l_icloglock); - if (!(iclog->ic_state == XLOG_STATE_ACTIVE || - iclog->ic_state == XLOG_STATE_DIRTY)) { - if (!XLOG_FORCED_SHUTDOWN(log)) { - xlog_wait(&iclog->ic_force_wait, - &log->l_icloglock); - } else { - spin_unlock(&log->l_icloglock); - } - } else { - spin_unlock(&log->l_icloglock); - } - if (tic) { - trace_xfs_log_umount_write(log, tic); - xlog_ungrant_log_space(log, tic); - xfs_log_ticket_put(tic); - } + xfs_log_write_unmount_record(mp); } else { /* * We're already in forced_shutdown mode, couldn't -- cgit v1.2.3 From f467cad95f5e3814fda408dea76eb962ab19685d Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 20 Jul 2018 09:28:40 -0700 Subject: xfs: force summary counter recalc at next mount Use the "bad summary count" mount flag from the previous patch to skip writing the unmount record to force log recovery at the next mount, which will recalculate the summary counters for us. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_errortag.h | 4 +++- fs/xfs/xfs_error.c | 3 +++ fs/xfs/xfs_log.c | 16 +++++++++++++++- fs/xfs/xfs_mount.c | 13 +++++++++++++ fs/xfs/xfs_mount.h | 1 + 5 files changed, 35 insertions(+), 2 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_errortag.h b/fs/xfs/libxfs/xfs_errortag.h index b9974e7a8e6e..66077a105cbb 100644 --- a/fs/xfs/libxfs/xfs_errortag.h +++ b/fs/xfs/libxfs/xfs_errortag.h @@ -53,7 +53,8 @@ #define XFS_ERRTAG_LOG_ITEM_PIN 30 #define XFS_ERRTAG_BUF_LRU_REF 31 #define XFS_ERRTAG_FORCE_SCRUB_REPAIR 32 -#define XFS_ERRTAG_MAX 33 +#define XFS_ERRTAG_FORCE_SUMMARY_RECALC 33 +#define XFS_ERRTAG_MAX 34 /* * Random factors for above tags, 1 means always, 2 means 1/2 time, etc. @@ -91,5 +92,6 @@ #define XFS_RANDOM_LOG_ITEM_PIN 1 #define XFS_RANDOM_BUF_LRU_REF 2 #define XFS_RANDOM_FORCE_SCRUB_REPAIR 1 +#define XFS_RANDOM_FORCE_SUMMARY_RECALC 1 #endif /* __XFS_ERRORTAG_H_ */ diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c index 0470114a8d80..9866f542e77b 100644 --- a/fs/xfs/xfs_error.c +++ b/fs/xfs/xfs_error.c @@ -50,6 +50,7 @@ static unsigned int xfs_errortag_random_default[] = { XFS_RANDOM_LOG_ITEM_PIN, XFS_RANDOM_BUF_LRU_REF, XFS_RANDOM_FORCE_SCRUB_REPAIR, + XFS_RANDOM_FORCE_SUMMARY_RECALC, }; struct xfs_errortag_attr { @@ -157,6 +158,7 @@ XFS_ERRORTAG_ATTR_RW(log_bad_crc, XFS_ERRTAG_LOG_BAD_CRC); XFS_ERRORTAG_ATTR_RW(log_item_pin, XFS_ERRTAG_LOG_ITEM_PIN); XFS_ERRORTAG_ATTR_RW(buf_lru_ref, XFS_ERRTAG_BUF_LRU_REF); XFS_ERRORTAG_ATTR_RW(force_repair, XFS_ERRTAG_FORCE_SCRUB_REPAIR); +XFS_ERRORTAG_ATTR_RW(bad_summary, XFS_ERRTAG_FORCE_SUMMARY_RECALC); static struct attribute *xfs_errortag_attrs[] = { XFS_ERRORTAG_ATTR_LIST(noerror), @@ -192,6 +194,7 @@ static struct attribute *xfs_errortag_attrs[] = { XFS_ERRORTAG_ATTR_LIST(log_item_pin), XFS_ERRORTAG_ATTR_LIST(buf_lru_ref), XFS_ERRORTAG_ATTR_LIST(force_repair), + XFS_ERRORTAG_ATTR_LIST(bad_summary), NULL, }; diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index bac586cbc54e..fd10b1426382 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -848,16 +848,30 @@ xfs_log_write_unmount_record( struct xlog_in_core *iclog; struct xlog_ticket *tic = NULL; xfs_lsn_t lsn; + uint flags = XLOG_UNMOUNT_TRANS; int error; error = xfs_log_reserve(mp, 600, 1, &tic, XFS_LOG, 0); if (error) goto out_err; + /* + * If we think the summary counters are bad, clear the unmount header + * flag in the unmount record so that the summary counters will be + * recalculated during log recovery at next mount. Refer to + * xlog_check_unmount_rec for more details. + */ + if (XFS_TEST_ERROR((mp->m_flags & XFS_MOUNT_BAD_SUMMARY), mp, + XFS_ERRTAG_FORCE_SUMMARY_RECALC)) { + xfs_alert(mp, "%s: will fix summary counters at next mount", + __func__); + flags &= ~XLOG_UNMOUNT_TRANS; + } + /* remove inited flag, and account for space used */ tic->t_flags = 0; tic->t_curr_res -= sizeof(magic); - error = xlog_write(log, &vec, tic, &lsn, NULL, XLOG_UNMOUNT_TRANS); + error = xlog_write(log, &vec, tic, &lsn, NULL, flags); /* * At this point, we're umounting anyway, so there's no point in * transitioning log state to IOERROR. Just continue... diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 60462c35ad4b..4fb361cde32a 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -1423,3 +1423,16 @@ xfs_dev_is_read_only( } return 0; } + +/* Force the summary counters to be recalculated at next mount. */ +void +xfs_force_summary_recalc( + struct xfs_mount *mp) +{ + if (!xfs_sb_version_haslazysbcount(&mp->m_sb)) + return; + + spin_lock(&mp->m_sb_lock); + mp->m_flags |= XFS_MOUNT_BAD_SUMMARY; + spin_unlock(&mp->m_sb_lock); +} diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index f08907db9c61..540353a51478 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -435,5 +435,6 @@ int xfs_zero_extent(struct xfs_inode *ip, xfs_fsblock_t start_fsb, struct xfs_error_cfg * xfs_error_get_cfg(struct xfs_mount *mp, int error_class, int error); +void xfs_force_summary_recalc(struct xfs_mount *mp); #endif /* __XFS_MOUNT_H__ */ -- cgit v1.2.3 From 02dff7bf81685b6770a082243060e0b5aac348cf Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Tue, 24 Jul 2018 13:43:07 -0700 Subject: xfs: pull up dfops from xfs_itruncate_extents() xfs_itruncate_extents[_flags]() uses a local dfops with a transaction provided by the caller. It uses hacky ->t_dfops replacement logic to avoid stomping over an already populated ->t_dfops. The latter never occurs for current callers and the logic itself is not really appropriate. Clean this up by updating all callers to initialize a dfops and to use that down in xfs_itruncate_extents(). This more closely resembles the upcoming logic where dfops will be embedded within the transaction. We can also replace the xfs_defer_init() in the xfs_itruncate_extents_flags() loop with an assert. Both dfops and firstblock should be in a valid state after xfs_defer_finish() and the inode joined to the dfops is fixed throughout the loop. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Bill O'Donnell Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_attr_inactive.c | 3 +++ fs/xfs/xfs_bmap_util.c | 2 ++ fs/xfs/xfs_inode.c | 8 +++----- fs/xfs/xfs_iops.c | 3 +++ fs/xfs/xfs_qm_syscalls.c | 3 +++ 5 files changed, 14 insertions(+), 5 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c index 7ce10055f275..d3055972d3a6 100644 --- a/fs/xfs/xfs_attr_inactive.c +++ b/fs/xfs/xfs_attr_inactive.c @@ -26,6 +26,7 @@ #include "xfs_quota.h" #include "xfs_trace.h" #include "xfs_dir2.h" +#include "xfs_defer.h" /* * Look at all the extents for this logical region, @@ -381,6 +382,7 @@ xfs_attr_inactive( { struct xfs_trans *trans; struct xfs_mount *mp; + struct xfs_defer_ops dfops; int lock_mode = XFS_ILOCK_SHARED; int error = 0; @@ -397,6 +399,7 @@ xfs_attr_inactive( error = xfs_trans_alloc(mp, &M_RES(mp)->tr_attrinval, 0, 0, 0, &trans); if (error) goto out_destroy_fork; + xfs_defer_init(trans, &dfops); lock_mode = XFS_ILOCK_EXCL; xfs_ilock(dp, lock_mode); diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 1b78c20de7bd..1a4617c74c6a 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -792,6 +792,7 @@ xfs_free_eofblocks( int nimaps; struct xfs_bmbt_irec imap; struct xfs_mount *mp = ip->i_mount; + struct xfs_defer_ops dfops; /* * Figure out if there are any blocks beyond the end @@ -831,6 +832,7 @@ xfs_free_eofblocks( ASSERT(XFS_FORCED_SHUTDOWN(mp)); return error; } + xfs_defer_init(tp, &dfops); xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, 0); diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 7b2694d3901a..7d7d7e95fa17 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1541,8 +1541,6 @@ xfs_itruncate_extents_flags( { struct xfs_mount *mp = ip->i_mount; struct xfs_trans *tp = *tpp; - struct xfs_defer_ops *odfops = tp->t_dfops; - struct xfs_defer_ops dfops; xfs_fileoff_t first_unmap_block; xfs_fileoff_t last_block; xfs_filblks_t unmap_len; @@ -1579,7 +1577,7 @@ xfs_itruncate_extents_flags( ASSERT(first_unmap_block < last_block); unmap_len = last_block - first_unmap_block + 1; while (!done) { - xfs_defer_init(tp, &dfops); + ASSERT(tp->t_firstblock == NULLFSBLOCK); error = xfs_bunmapi(tp, ip, first_unmap_block, unmap_len, flags, XFS_ITRUNC_MAX_EXTENTS, &done); if (error) @@ -1618,8 +1616,6 @@ xfs_itruncate_extents_flags( trace_xfs_itruncate_extents_end(ip, new_size); out: - /* ->t_dfops points to local stack, don't leak it! */ - tp->t_dfops = odfops; *tpp = tp; return error; out_bmap_cancel: @@ -1723,6 +1719,7 @@ xfs_inactive_truncate( { struct xfs_mount *mp = ip->i_mount; struct xfs_trans *tp; + struct xfs_defer_ops dfops; int error; error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp); @@ -1730,6 +1727,7 @@ xfs_inactive_truncate( ASSERT(XFS_FORCED_SHUTDOWN(mp)); return error; } + xfs_defer_init(tp, &dfops); xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, 0); diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 0fa29f39d658..704b57a8b99e 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -26,6 +26,7 @@ #include "xfs_dir2.h" #include "xfs_trans_space.h" #include "xfs_iomap.h" +#include "xfs_defer.h" #include #include @@ -812,6 +813,7 @@ xfs_setattr_size( struct inode *inode = VFS_I(ip); xfs_off_t oldsize, newsize; struct xfs_trans *tp; + struct xfs_defer_ops dfops; int error; uint lock_flags = 0; bool did_zeroing = false; @@ -915,6 +917,7 @@ xfs_setattr_size( error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp); if (error) return error; + xfs_defer_init(tp, &dfops); lock_flags |= XFS_ILOCK_EXCL; xfs_ilock(ip, XFS_ILOCK_EXCL); diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index abc8a21e3a82..df0783303887 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -22,6 +22,7 @@ #include "xfs_qm.h" #include "xfs_trace.h" #include "xfs_icache.h" +#include "xfs_defer.h" STATIC int xfs_qm_log_quotaoff(xfs_mount_t *, xfs_qoff_logitem_t **, uint); STATIC int xfs_qm_log_quotaoff_end(xfs_mount_t *, xfs_qoff_logitem_t *, @@ -213,6 +214,7 @@ xfs_qm_scall_trunc_qfile( { struct xfs_inode *ip; struct xfs_trans *tp; + struct xfs_defer_ops dfops; int error; if (ino == NULLFSINO) @@ -229,6 +231,7 @@ xfs_qm_scall_trunc_qfile( xfs_iunlock(ip, XFS_IOLOCK_EXCL); goto out_put; } + xfs_defer_init(tp, &dfops); xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, 0); -- cgit v1.2.3 From a61acc3c78df14bb9b7bfefb2cc771fcda15b8fe Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Tue, 24 Jul 2018 13:43:08 -0700 Subject: xfs: use ->t_dfops in log recovery intent processing xlog_finish_defer_ops() processes the deferred operations collected over the entire intent recovery sequence. We can't xfs_defer_init() here because the dfops is already populated. Attach it manually and eliminate the last caller of xfs_defer_finish() that doesn't pass ->t_dfops. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Bill O'Donnell Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_log_recover.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index cbac943896f4..3289811eb076 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4854,6 +4854,8 @@ xlog_finish_defer_ops( 0, XFS_TRANS_RESERVE, &tp); if (error) return error; + /* dfops is already populated so assign it manually */ + tp->t_dfops = dfops; error = xfs_defer_finish(&tp, dfops); if (error) -- cgit v1.2.3 From dcbd44f79986e55691600b969c14db004d741883 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Tue, 24 Jul 2018 13:43:08 -0700 Subject: xfs: fix transaction leak on remote attr set/remove failure The xattr remote value set/remove handlers both clear args.trans in the error path without having cancelled the transaction. This leaks the transaction, causes warnings around returning to userspace with locks held and leads to system lockups or other general problems. The higher level xfs_attr_[set|remove]() functions already detect and cancel args.trans when set in the error path. Drop the NULL assignments from the rmtval handlers and allow the callers to clean up the transaction correctly. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Bill O'Donnell Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr_remote.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index 7841e6255129..829ab20f0cd7 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -558,7 +558,6 @@ xfs_attr_rmtval_set( return 0; out_defer_cancel: xfs_defer_cancel(args->trans->t_dfops); - args->trans = NULL; return error; } @@ -646,6 +645,5 @@ xfs_attr_rmtval_remove( return 0; out_defer_cancel: xfs_defer_cancel(args->trans->t_dfops); - args->trans = NULL; return error; } -- cgit v1.2.3 From 03f4e4b26cd5f6eed728f82d90039a19d1b51ce3 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Tue, 24 Jul 2018 13:43:09 -0700 Subject: xfs: make deferred processing safe for embedded dfops xfs_defer_finish() has a couple quirks that are not safe with respect to the upcoming internal dfops functionality. First, xfs_defer_finish() attaches the passed in dfops structure to ->t_dfops and caches and restores the original value. Second, it continues to use the initial dfops reference before and after the transaction roll. These behaviors assume that dop is an independent memory allocation from the transaction itself, which may not always be true once transactions begin to use an embedded dfops structure. In the latter model, dfops processing creates a new xfs_defer_ops structure with each transaction and the associated state is migrated across to the new transaction. Fix up xfs_defer_finish() to handle the possibility of the current dfops changing after a transaction roll. Since ->t_dfops is used unconditionally in this path, it is no longer necessary to attach/restore ->t_dfops and pass it explicitly down to xfs_defer_trans_roll(). Update dop in the latter function and the caller to ensure that it always refers to the current dfops structure. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Bill O'Donnell Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_defer.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index c4b0eaeb5190..ee734a8b3fa9 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -225,9 +225,9 @@ xfs_defer_trans_abort( /* Roll a transaction so we can do some deferred op processing. */ STATIC int xfs_defer_trans_roll( - struct xfs_trans **tp, - struct xfs_defer_ops *dop) + struct xfs_trans **tp) { + struct xfs_defer_ops *dop = (*tp)->t_dfops; int i; int error; @@ -243,6 +243,7 @@ xfs_defer_trans_roll( /* Roll the transaction. */ error = xfs_trans_roll(tp); + dop = (*tp)->t_dfops; if (error) { trace_xfs_defer_trans_roll_error((*tp)->t_mountp, dop, error); xfs_defer_trans_abort(*tp, dop, error); @@ -338,31 +339,25 @@ xfs_defer_finish( void *state; int error = 0; void (*cleanup_fn)(struct xfs_trans *, void *, int); - struct xfs_defer_ops *orig_dop; ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES); + ASSERT((*tp)->t_dfops == dop); trace_xfs_defer_finish((*tp)->t_mountp, dop, _RET_IP_); - /* - * Attach dfops to the transaction during deferred ops processing. This - * explicitly causes calls into the allocator to defer AGFL block frees. - * Note that this code can go away once all dfops users attach to the - * associated tp. - */ - ASSERT(!(*tp)->t_dfops || ((*tp)->t_dfops == dop)); - orig_dop = (*tp)->t_dfops; - (*tp)->t_dfops = dop; - /* Until we run out of pending work to finish... */ while (xfs_defer_has_unfinished_work(dop)) { /* Log intents for work items sitting in the intake. */ xfs_defer_intake_work(*tp, dop); - /* Roll the transaction. */ - error = xfs_defer_trans_roll(tp, dop); + /* + * Roll the transaction and update dop in case dfops was + * embedded in the transaction. + */ + error = xfs_defer_trans_roll(tp); if (error) goto out; + dop = (*tp)->t_dfops; /* Log an intent-done item for the first pending item. */ dfp = list_first_entry(&dop->dop_pending, @@ -428,10 +423,11 @@ xfs_defer_finish( * Roll the transaction once more to avoid returning to the caller * with a dirty transaction. */ - if ((*tp)->t_flags & XFS_TRANS_DIRTY) - error = xfs_defer_trans_roll(tp, dop); + if ((*tp)->t_flags & XFS_TRANS_DIRTY) { + error = xfs_defer_trans_roll(tp); + dop = (*tp)->t_dfops; + } out: - (*tp)->t_dfops = orig_dop; if (error) trace_xfs_defer_finish_error((*tp)->t_mountp, dop, error); else -- cgit v1.2.3 From 83200bfac6082a46cc962366478d050052e50450 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Tue, 24 Jul 2018 13:43:09 -0700 Subject: xfs: remove unused deferred ops committed field dop_committed is set when deferred item processing rolls the transaction at least once, but is only ever accessed in tracepoints. The transaction roll/commit events are already available via independent tracepoints, so remove the otherwise unused field. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Bill O'Donnell Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_defer.c | 1 - fs/xfs/libxfs/xfs_defer.h | 1 - fs/xfs/xfs_trace.h | 8 ++------ 3 files changed, 2 insertions(+), 8 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index ee734a8b3fa9..0df09c094e42 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -249,7 +249,6 @@ xfs_defer_trans_roll( xfs_defer_trans_abort(*tp, dop, error); return error; } - dop->dop_committed = true; /* Rejoin the joined inodes. */ for (i = 0; i < XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++) diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index c17c9deda995..58c979c9f3fa 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h @@ -49,7 +49,6 @@ enum xfs_defer_ops_type { #define XFS_DEFER_OPS_NR_BUFS 2 /* join up to two buffers */ struct xfs_defer_ops { - bool dop_committed; /* did any trans commit? */ bool dop_low; /* alloc in low mode */ struct list_head dop_intake; /* unlogged pending work */ struct list_head dop_pending; /* logged pending work */ diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index b668fc127aa7..cc6995cfce66 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -2229,14 +2229,12 @@ DECLARE_EVENT_CLASS(xfs_defer_class, TP_fast_assign( __entry->dev = mp ? mp->m_super->s_dev : 0; __entry->dop = dop; - __entry->committed = dop->dop_committed; __entry->low = dop->dop_low; __entry->caller_ip = caller_ip; ), - TP_printk("dev %d:%d ops %p committed %d low %d, caller %pS", + TP_printk("dev %d:%d ops %p low %d, caller %pS", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->dop, - __entry->committed, __entry->low, (char *)__entry->caller_ip) ) @@ -2259,14 +2257,12 @@ DECLARE_EVENT_CLASS(xfs_defer_error_class, TP_fast_assign( __entry->dev = mp ? mp->m_super->s_dev : 0; __entry->dop = dop; - __entry->committed = dop->dop_committed; __entry->low = dop->dop_low; __entry->error = error; ), - TP_printk("dev %d:%d ops %p committed %d low %d err %d", + TP_printk("dev %d:%d ops %p low %d err %d", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->dop, - __entry->committed, __entry->low, __entry->error) ) -- cgit v1.2.3 From 509308b413c9e4e3140b4bc524522255d126787e Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Tue, 24 Jul 2018 13:43:10 -0700 Subject: xfs: reset dfops to initial state after finish xfs_defer_init() is currently used in two particular situations. The first and most obvious case is raw initialization of an xfs_defer_ops struct. The other case is partial reinit of xfs_defer_ops on reuse due to iteration. Most instances of the first case will be replaced by a single init of a dfops embedded in the transaction. Init calls are still technically required for the second case because the dfops may have low space mode enabled or have joined items that need to be reset before the dfops should be reused. Since the current dfops usage expects either a final transaction commit after xfs_defer_finish() or xfs_defer_init() if dfops is to be reused, we can shift some of the init logic into xfs_defer_finish() such that the latter returns with a reinitialized dfops. This eliminates the second dependency noted above such that a dfops is immediately ready for reuse after an xfs_defer_finish() without the need to change any calling code. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Bill O'Donnell Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_defer.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index 0df09c094e42..23f2a52b088e 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -319,6 +319,19 @@ xfs_defer_bjoin( return -EFSCORRUPTED; } +/* + * Reset an already used dfops after finish. + */ +static void +xfs_defer_reset( + struct xfs_defer_ops *dop) +{ + ASSERT(!xfs_defer_has_unfinished_work(dop)); + dop->dop_low = false; + memset(dop->dop_inodes, 0, sizeof(dop->dop_inodes)); + memset(dop->dop_bufs, 0, sizeof(dop->dop_bufs)); +} + /* * Finish all the pending work. This involves logging intent items for * any work items that wandered in since the last transaction roll (if @@ -427,10 +440,13 @@ xfs_defer_finish( dop = (*tp)->t_dfops; } out: - if (error) + if (error) { trace_xfs_defer_finish_error((*tp)->t_mountp, dop, error); - else + } else { trace_xfs_defer_finish_done((*tp)->t_mountp, dop, _RET_IP_); + xfs_defer_reset(dop); + } + return error; } -- cgit v1.2.3 From 44fd294681de73990da656294e3dacaa7878f577 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Tue, 24 Jul 2018 13:43:11 -0700 Subject: xfs: pack holes in xfs_defer_ops and xfs_trans Both structures have holes due to member alignment. Move dop_low to the end of xfs_defer ops to sanitize the cache line alignment and move t_flags to save 8 bytes in xfs_trans. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Bill O'Donnell Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_defer.h | 3 ++- fs/xfs/xfs_trans.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index 58c979c9f3fa..8f58f217fdff 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h @@ -49,13 +49,14 @@ enum xfs_defer_ops_type { #define XFS_DEFER_OPS_NR_BUFS 2 /* join up to two buffers */ struct xfs_defer_ops { - bool dop_low; /* alloc in low mode */ struct list_head dop_intake; /* unlogged pending work */ struct list_head dop_pending; /* logged pending work */ /* relog these with each roll */ struct xfs_inode *dop_inodes[XFS_DEFER_OPS_NR_INODES]; struct xfs_buf *dop_bufs[XFS_DEFER_OPS_NR_BUFS]; + + bool dop_low; /* alloc in low mode */ }; void xfs_defer_add(struct xfs_defer_ops *dop, enum xfs_defer_ops_type type, diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 37fdacc690c7..6f857af61455 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -102,12 +102,12 @@ typedef struct xfs_trans { unsigned int t_blk_res_used; /* # of resvd blocks used */ unsigned int t_rtx_res; /* # of rt extents resvd */ unsigned int t_rtx_res_used; /* # of resvd rt extents used */ + unsigned int t_flags; /* misc flags */ xfs_fsblock_t t_firstblock; /* first block allocated */ struct xlog_ticket *t_ticket; /* log mgr ticket */ struct xfs_mount *t_mountp; /* ptr to fs mount struct */ struct xfs_dquot_acct *t_dqinfo; /* acctg info for dquots */ struct xfs_defer_ops *t_dfops; /* dfops reference */ - unsigned int t_flags; /* misc flags */ int64_t t_icount_delta; /* superblock icount change */ int64_t t_ifree_delta; /* superblock ifree change */ int64_t t_fdblocks_delta; /* superblock fdblocks chg */ -- cgit v1.2.3 From e021a2e5fc520d930f949f303e7307038e258645 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Tue, 24 Jul 2018 13:43:11 -0700 Subject: xfs: support embedded dfops in transaction The dfops structure used by multi-transaction operations is typically stored on the stack and carried around by the associated transaction. The lifecycle of dfops does not quite match that of the transaction, but they are tightly related in that the former depends on the latter. The relationship of these objects is tight enough that we can avoid the cumbersome boilerplate code required in most cases to manage them separately by just embedding an xfs_defer_ops in the transaction itself. This means that a transaction allocation returns with an initialized dfops, a transaction commit finishes pending deferred items before the tx commit, a transaction cancel cancels the dfops before the transaction and a transaction dup operation transfers the current dfops state to the new transaction. The dup operation is slightly complicated by the fact that we can no longer just copy a dfops pointer from the old transaction to the new transaction. This is solved through a dfops move helper that transfers the pending items and other dfops state across the transactions. This also requires that transaction rolling code always refer to the transaction for the current dfops reference. Finally, to facilitate incremental conversion to the internal dfops and continue to support the current external dfops mode of operation, create the new ->t_dfops_internal field with a layer of indirection. On allocation, ->t_dfops points to the internal dfops. This state is overridden by callers who re-init a local dfops on the transaction. Once ->t_dfops is overridden, the external dfops reference is maintained as the transaction rolls. This patch adds the fundamental ability to support an internal dfops. All codepaths that perform deferred processing continue to override the internal dfops until they are converted over in subsequent patches. Signed-off-by: Brian Foster Reviewed-by: Bill O'Donnell Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_defer.c | 22 ++++++++++++++++++++++ fs/xfs/libxfs/xfs_defer.h | 16 ++-------------- fs/xfs/xfs_trans.c | 30 ++++++++++++++++++++++++++---- fs/xfs/xfs_trans.h | 17 ++++++++++++++++- 4 files changed, 66 insertions(+), 19 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index 23f2a52b088e..b63cc9e730da 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -555,3 +555,25 @@ xfs_defer_init( } trace_xfs_defer_init(mp, dop, _RET_IP_); } + +/* + * Move state from one xfs_defer_ops to another and reset the source to initial + * state. This is primarily used to carry state forward across transaction rolls + * with internal dfops. + */ +void +xfs_defer_move( + struct xfs_defer_ops *dst, + struct xfs_defer_ops *src) +{ + ASSERT(dst != src); + + list_splice_init(&src->dop_intake, &dst->dop_intake); + list_splice_init(&src->dop_pending, &dst->dop_pending); + + memcpy(dst->dop_inodes, src->dop_inodes, sizeof(dst->dop_inodes)); + memcpy(dst->dop_bufs, src->dop_bufs, sizeof(dst->dop_bufs)); + dst->dop_low = src->dop_low; + + xfs_defer_reset(src); +} diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index 8f58f217fdff..35507ca9a148 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h @@ -7,6 +7,7 @@ #define __XFS_DEFER_H__ struct xfs_defer_op_type; +struct xfs_defer_ops; /* * Save a log intent item and a list of extents, so that we can replay @@ -45,20 +46,6 @@ enum xfs_defer_ops_type { XFS_DEFER_OPS_TYPE_MAX, }; -#define XFS_DEFER_OPS_NR_INODES 2 /* join up to two inodes */ -#define XFS_DEFER_OPS_NR_BUFS 2 /* join up to two buffers */ - -struct xfs_defer_ops { - struct list_head dop_intake; /* unlogged pending work */ - struct list_head dop_pending; /* logged pending work */ - - /* relog these with each roll */ - struct xfs_inode *dop_inodes[XFS_DEFER_OPS_NR_INODES]; - struct xfs_buf *dop_bufs[XFS_DEFER_OPS_NR_BUFS]; - - bool dop_low; /* alloc in low mode */ -}; - void xfs_defer_add(struct xfs_defer_ops *dop, enum xfs_defer_ops_type type, struct list_head *h); int xfs_defer_finish(struct xfs_trans **tp, struct xfs_defer_ops *dop); @@ -67,6 +54,7 @@ void xfs_defer_init(struct xfs_trans *tp, struct xfs_defer_ops *dop); bool xfs_defer_has_unfinished_work(struct xfs_defer_ops *dop); int xfs_defer_ijoin(struct xfs_defer_ops *dop, struct xfs_inode *ip); int xfs_defer_bjoin(struct xfs_defer_ops *dop, struct xfs_buf *bp); +void xfs_defer_move(struct xfs_defer_ops *dst, struct xfs_defer_ops *src); /* Description of a deferred type. */ struct xfs_defer_op_type { diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index de00f79ff698..412c8d236c71 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -119,7 +119,13 @@ xfs_trans_dup( ntp->t_rtx_res = tp->t_rtx_res - tp->t_rtx_res_used; tp->t_rtx_res = tp->t_rtx_res_used; ntp->t_pflags = tp->t_pflags; - ntp->t_dfops = tp->t_dfops; + + /* copy the dfops pointer if it's external, otherwise move it */ + xfs_defer_init(ntp, &ntp->t_dfops_internal); + if (tp->t_dfops != &tp->t_dfops_internal) + ntp->t_dfops = tp->t_dfops; + else + xfs_defer_move(ntp->t_dfops, tp->t_dfops); xfs_trans_dup_dqinfo(tp, ntp); @@ -275,6 +281,13 @@ xfs_trans_alloc( INIT_LIST_HEAD(&tp->t_items); INIT_LIST_HEAD(&tp->t_busy); tp->t_firstblock = NULLFSBLOCK; + /* + * We only roll transactions with permanent log reservation. Don't init + * ->t_dfops to skip attempts to finish or cancel an empty dfops with a + * non-permanent res. + */ + if (resp->tr_logflags & XFS_TRANS_PERM_LOG_RES) + xfs_defer_init(tp, &tp->t_dfops_internal); error = xfs_trans_reserve(tp, resp, blocks, rtextents); if (error) { @@ -916,11 +929,17 @@ __xfs_trans_commit( int error = 0; int sync = tp->t_flags & XFS_TRANS_SYNC; - ASSERT(!tp->t_dfops || - !xfs_defer_has_unfinished_work(tp->t_dfops) || regrant); - trace_xfs_trans_commit(tp, _RET_IP_); + /* finish deferred items on final commit */ + if (!regrant && tp->t_dfops) { + error = xfs_defer_finish(&tp, tp->t_dfops); + if (error) { + xfs_defer_cancel(tp->t_dfops); + goto out_unreserve; + } + } + /* * If there is nothing to be logged by the transaction, * then unlock all of the items associated with the @@ -1010,6 +1029,9 @@ xfs_trans_cancel( trace_xfs_trans_cancel(tp, _RET_IP_); + if (tp->t_dfops) + xfs_defer_cancel(tp->t_dfops); + /* * See if the caller is relying on us to shut down the * filesystem. This happens in paths where we detect diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 6f857af61455..dc79e3c1d3e8 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -24,7 +24,6 @@ struct xfs_rui_log_item; struct xfs_btree_cur; struct xfs_cui_log_item; struct xfs_cud_log_item; -struct xfs_defer_ops; struct xfs_bui_log_item; struct xfs_bud_log_item; @@ -90,6 +89,21 @@ void xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item, #define XFS_ITEM_LOCKED 2 #define XFS_ITEM_FLUSHING 3 +/* + * Deferred operations tracking structure. + */ +#define XFS_DEFER_OPS_NR_INODES 2 /* join up to two inodes */ +#define XFS_DEFER_OPS_NR_BUFS 2 /* join up to two buffers */ +struct xfs_defer_ops { + struct list_head dop_intake; /* unlogged pending work */ + struct list_head dop_pending; /* logged pending work */ + + /* relog these with each roll */ + struct xfs_inode *dop_inodes[XFS_DEFER_OPS_NR_INODES]; + struct xfs_buf *dop_bufs[XFS_DEFER_OPS_NR_BUFS]; + + bool dop_low; /* alloc in low mode */ +}; /* * This is the structure maintained for every active transaction. @@ -130,6 +144,7 @@ typedef struct xfs_trans { struct list_head t_items; /* log item descriptors */ struct list_head t_busy; /* list of busy extents */ unsigned long t_pflags; /* saved process flags state */ + struct xfs_defer_ops t_dfops_internal; } xfs_trans_t; /* -- cgit v1.2.3 From 1e5ae1995a44f2b7a03f08a10504568a96040a8c Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Tue, 24 Jul 2018 13:43:12 -0700 Subject: xfs: use internal dfops in cow blocks cancel All callers either explicitly initialize a dfops or pass a transaction with an internal dfops. Drop the hacky old dfops replacement logic and use the one associated with the transaction. Signed-off-by: Brian Foster Reviewed-by: Bill O'Donnell Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_reflink.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 406f79d44153..04c25ee6b6f8 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -483,8 +483,6 @@ xfs_reflink_cancel_cow_blocks( struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK); struct xfs_bmbt_irec got, del; struct xfs_iext_cursor icur; - struct xfs_defer_ops dfops; - struct xfs_defer_ops *odfops = (*tpp)->t_dfops; int error = 0; if (!xfs_is_reflink_inode(ip)) @@ -511,7 +509,8 @@ xfs_reflink_cancel_cow_blocks( if (error) break; } else if (del.br_state == XFS_EXT_UNWRITTEN || cancel_real) { - xfs_defer_init(*tpp, &dfops); + ASSERT((*tpp)->t_dfops); + ASSERT((*tpp)->t_firstblock == NULLFSBLOCK); /* Free the CoW orphan record. */ error = xfs_refcount_free_cow_extent(ip->i_mount, @@ -553,7 +552,6 @@ next_extent: /* clear tag if cow fork is emptied */ if (!ifp->if_bytes) xfs_inode_clear_cowblocks_tag(ip); - (*tpp)->t_dfops = odfops; return error; } -- cgit v1.2.3 From 9c6bb0cf7ba318767107328f39aac880344ddd2e Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Tue, 24 Jul 2018 13:43:12 -0700 Subject: xfs: use internal dfops in attr code Remove the unnecessary on-stack dfops structure and use the internal transaction dfops instead. The lower level xattr code already appropriately accesses ->t_dfops throughout. Signed-off-by: Brian Foster Reviewed-by: Bill O'Donnell Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 927d4c968f9a..66a22c80a0db 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -202,7 +202,6 @@ xfs_attr_set( struct xfs_mount *mp = dp->i_mount; struct xfs_buf *leaf_bp = NULL; struct xfs_da_args args; - struct xfs_defer_ops dfops; struct xfs_trans_res tres; int rsvd = (flags & ATTR_ROOT) != 0; int error, err2, local; @@ -251,7 +250,6 @@ xfs_attr_set( rsvd ? XFS_TRANS_RESERVE : 0, &args.trans); if (error) return error; - xfs_defer_init(args.trans, &dfops); xfs_ilock(dp, XFS_ILOCK_EXCL); error = xfs_trans_reserve_quota_nblks(args.trans, dp, args.total, 0, @@ -315,18 +313,18 @@ xfs_attr_set( */ error = xfs_attr_shortform_to_leaf(&args, &leaf_bp); if (error) - goto out_defer_cancel; + goto out; /* * Prevent the leaf buffer from being unlocked so that a * concurrent AIL push cannot grab the half-baked leaf * buffer and run into problems with the write verifier. */ xfs_trans_bhold(args.trans, leaf_bp); - xfs_defer_bjoin(&dfops, leaf_bp); - xfs_defer_ijoin(&dfops, dp); - error = xfs_defer_finish(&args.trans, &dfops); + xfs_defer_bjoin(args.trans->t_dfops, leaf_bp); + xfs_defer_ijoin(args.trans->t_dfops, dp); + error = xfs_defer_finish(&args.trans, args.trans->t_dfops); if (error) - goto out_defer_cancel; + goto out; /* * Commit the leaf transformation. We'll need another (linked) @@ -366,8 +364,6 @@ xfs_attr_set( return error; -out_defer_cancel: - xfs_defer_cancel(&dfops); out: if (leaf_bp) xfs_trans_brelse(args.trans, leaf_bp); @@ -389,7 +385,6 @@ xfs_attr_remove( { struct xfs_mount *mp = dp->i_mount; struct xfs_da_args args; - struct xfs_defer_ops dfops; int error; XFS_STATS_INC(mp, xs_attr_remove); @@ -422,7 +417,6 @@ xfs_attr_remove( &args.trans); if (error) return error; - xfs_defer_init(args.trans, &dfops); xfs_ilock(dp, XFS_ILOCK_EXCL); /* -- cgit v1.2.3 From 91ef75b6572498face47746c253926e733a4da3b Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Tue, 24 Jul 2018 13:43:13 -0700 Subject: xfs: use internal dfops during [b|c]ui recovery bmap and refcount intent processing associates a dfops from the caller with a local transaction to collect all deferred items for post-processing. Use the internal dfops in both of these functions and move the deferred items to the parent dfops before the transaction commits. Signed-off-by: Brian Foster Reviewed-by: Bill O'Donnell Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_bmap_item.c | 21 +++++++++++---------- fs/xfs/xfs_log_recover.c | 6 +++--- fs/xfs/xfs_refcount_item.c | 30 ++++++++++++++++-------------- 3 files changed, 30 insertions(+), 27 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c index 478bfc798861..bc5eb2e0ab0c 100644 --- a/fs/xfs/xfs_bmap_item.c +++ b/fs/xfs/xfs_bmap_item.c @@ -441,7 +441,12 @@ xfs_bui_recover( XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK), 0, 0, &tp); if (error) return error; - tp->t_dfops = dfops; + /* + * Recovery stashes all deferred ops during intent processing and + * finishes them on completion. Transfer current dfops state to this + * transaction and transfer the result back before we return. + */ + xfs_defer_move(tp->t_dfops, dfops); budp = xfs_trans_get_bud(tp, buip); /* Grab the inode. */ @@ -470,7 +475,7 @@ xfs_bui_recover( xfs_trans_ijoin(tp, ip, 0); count = bmap->me_len; - error = xfs_trans_log_finish_bmap_update(tp, budp, dfops, type, + error = xfs_trans_log_finish_bmap_update(tp, budp, tp->t_dfops, type, ip, whichfork, bmap->me_startoff, bmap->me_startblock, &count, state); if (error) @@ -482,18 +487,14 @@ xfs_bui_recover( irec.br_blockcount = count; irec.br_startoff = bmap->me_startoff; irec.br_state = state; - error = xfs_bmap_unmap_extent(tp->t_mountp, dfops, ip, &irec); + error = xfs_bmap_unmap_extent(tp->t_mountp, tp->t_dfops, ip, + &irec); if (error) goto err_inode; } set_bit(XFS_BUI_RECOVERED, &buip->bui_flags); - /* - * Recovery finishes all deferred ops once intent processing is - * complete. Reset the trans reference because commit expects a finished - * dfops or none at all. - */ - tp->t_dfops = NULL; + xfs_defer_move(dfops, tp->t_dfops); error = xfs_trans_commit(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); IRELE(ip); @@ -501,7 +502,7 @@ xfs_bui_recover( return error; err_inode: - tp->t_dfops = NULL; + xfs_defer_move(dfops, tp->t_dfops); xfs_trans_cancel(tp); if (ip) { xfs_iunlock(ip, XFS_ILOCK_EXCL); diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 3289811eb076..958e9b96dc6a 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4854,10 +4854,10 @@ xlog_finish_defer_ops( 0, XFS_TRANS_RESERVE, &tp); if (error) return error; - /* dfops is already populated so assign it manually */ - tp->t_dfops = dfops; + /* transfer all collected dfops to this transaction */ + xfs_defer_move(tp->t_dfops, dfops); - error = xfs_defer_finish(&tp, dfops); + error = xfs_defer_finish(&tp, tp->t_dfops); if (error) goto out_cancel; diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c index 2064c689bc72..d3582a06626f 100644 --- a/fs/xfs/xfs_refcount_item.c +++ b/fs/xfs/xfs_refcount_item.c @@ -452,7 +452,12 @@ xfs_cui_recover( mp->m_refc_maxlevels * 2, 0, XFS_TRANS_RESERVE, &tp); if (error) return error; - tp->t_dfops = dfops; + /* + * Recovery stashes all deferred ops during intent processing and + * finishes them on completion. Transfer current dfops state to this + * transaction and transfer the result back before we return. + */ + xfs_defer_move(tp->t_dfops, dfops); cudp = xfs_trans_get_cud(tp, cuip); for (i = 0; i < cuip->cui_format.cui_nextents; i++) { @@ -474,8 +479,8 @@ xfs_cui_recover( new_len = refc->pe_len; } else error = xfs_trans_log_finish_refcount_update(tp, cudp, - dfops, type, refc->pe_startblock, refc->pe_len, - &new_fsb, &new_len, &rcur); + tp->t_dfops, type, refc->pe_startblock, + refc->pe_len, &new_fsb, &new_len, &rcur); if (error) goto abort_error; @@ -486,21 +491,23 @@ xfs_cui_recover( switch (type) { case XFS_REFCOUNT_INCREASE: error = xfs_refcount_increase_extent( - tp->t_mountp, dfops, &irec); + tp->t_mountp, tp->t_dfops, + &irec); break; case XFS_REFCOUNT_DECREASE: error = xfs_refcount_decrease_extent( - tp->t_mountp, dfops, &irec); + tp->t_mountp, tp->t_dfops, + &irec); break; case XFS_REFCOUNT_ALLOC_COW: error = xfs_refcount_alloc_cow_extent( - tp->t_mountp, dfops, + tp->t_mountp, tp->t_dfops, irec.br_startblock, irec.br_blockcount); break; case XFS_REFCOUNT_FREE_COW: error = xfs_refcount_free_cow_extent( - tp->t_mountp, dfops, + tp->t_mountp, tp->t_dfops, irec.br_startblock, irec.br_blockcount); break; @@ -515,18 +522,13 @@ xfs_cui_recover( xfs_refcount_finish_one_cleanup(tp, rcur, error); set_bit(XFS_CUI_RECOVERED, &cuip->cui_flags); - /* - * Recovery finishes all deferred ops once intent processing is - * complete. Reset the trans reference because commit expects a finished - * dfops or none at all. - */ - tp->t_dfops = NULL; + xfs_defer_move(dfops, tp->t_dfops); error = xfs_trans_commit(tp); return error; abort_error: xfs_refcount_finish_one_cleanup(tp, rcur, error); - tp->t_dfops = NULL; + xfs_defer_move(dfops, tp->t_dfops); xfs_trans_cancel(tp); return error; } -- cgit v1.2.3 From c8eac49ef798a7d00240847f63902caa1388241a Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Tue, 24 Jul 2018 13:43:13 -0700 Subject: xfs: remove all boilerplate defer init/finish code At this point, the transaction subsystem completely manages deferred items internally such that the common and boilerplate xfs_trans_alloc() -> xfs_defer_init() -> xfs_defer_finish() -> xfs_trans_commit() sequence can be replaced with a simple transaction allocation and commit. Remove all such boilerplate deferred ops code. In doing so, we change each case over to use the dfops in the transaction and specifically eliminate: - The on-stack dfops and associated xfs_defer_init() call, as the internal dfops is initialized on transaction allocation. - xfs_bmap_finish() calls that precede a final xfs_trans_commit() of a transaction. - xfs_defer_cancel() calls in error handlers that precede a transaction cancel. The only deferred ops calls that remain are those that are non-deterministic with respect to the final commit of the associated transaction or are open-coded due to special handling. Signed-off-by: Brian Foster Reviewed-by: Bill O'Donnell Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 16 +-------- fs/xfs/libxfs/xfs_refcount.c | 10 +----- fs/xfs/xfs_attr_inactive.c | 2 -- fs/xfs/xfs_bmap_util.c | 43 ++++-------------------- fs/xfs/xfs_dquot.c | 4 --- fs/xfs/xfs_inode.c | 79 ++++++++------------------------------------ fs/xfs/xfs_iomap.c | 26 ++------------- fs/xfs/xfs_iops.c | 2 -- fs/xfs/xfs_log_recover.c | 8 ----- fs/xfs/xfs_qm_syscalls.c | 2 -- fs/xfs/xfs_reflink.c | 37 +++++++-------------- fs/xfs/xfs_rtalloc.c | 9 +---- fs/xfs/xfs_symlink.c | 38 +++++---------------- 13 files changed, 44 insertions(+), 232 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 6bc0cdff488e..92cd064a2589 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -1018,7 +1018,6 @@ xfs_bmap_add_attrfork( int size, /* space new attribute needs */ int rsvd) /* xact may use reserved blks */ { - struct xfs_defer_ops dfops; /* freed extent records */ xfs_mount_t *mp; /* mount structure */ xfs_trans_t *tp; /* transaction pointer */ int blks; /* space reservation */ @@ -1037,7 +1036,6 @@ xfs_bmap_add_attrfork( rsvd ? XFS_TRANS_RESERVE : 0, &tp); if (error) return error; - xfs_defer_init(tp, &dfops); xfs_ilock(ip, XFS_ILOCK_EXCL); error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ? @@ -1102,7 +1100,7 @@ xfs_bmap_add_attrfork( if (logflags) xfs_trans_log_inode(tp, ip, logflags); if (error) - goto bmap_cancel; + goto trans_cancel; if (!xfs_sb_version_hasattr(&mp->m_sb) || (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2)) { bool log_sb = false; @@ -1121,15 +1119,10 @@ xfs_bmap_add_attrfork( xfs_log_sb(tp); } - error = xfs_defer_finish(&tp, &dfops); - if (error) - goto bmap_cancel; error = xfs_trans_commit(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); return error; -bmap_cancel: - xfs_defer_cancel(&dfops); trans_cancel: xfs_trans_cancel(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); @@ -5953,14 +5946,12 @@ xfs_bmap_split_extent( { struct xfs_mount *mp = ip->i_mount; struct xfs_trans *tp; - struct xfs_defer_ops dfops; int error; error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, XFS_DIOSTRAT_SPACE_RES(mp, 0), 0, 0, &tp); if (error) return error; - xfs_defer_init(tp, &dfops); xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); @@ -5969,14 +5960,9 @@ xfs_bmap_split_extent( if (error) goto out; - error = xfs_defer_finish(&tp, &dfops); - if (error) - goto out; - return xfs_trans_commit(tp); out: - xfs_defer_cancel(&dfops); xfs_trans_cancel(tp); return error; } diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index 9ef1f440a6f2..4cbc2efb099e 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -1635,7 +1635,6 @@ xfs_refcount_recover_cow_leftovers( struct list_head debris; union xfs_btree_irec low; union xfs_btree_irec high; - struct xfs_defer_ops dfops; xfs_fsblock_t fsb; xfs_agblock_t agbno; int error; @@ -1691,22 +1690,17 @@ xfs_refcount_recover_cow_leftovers( trace_xfs_refcount_recover_extent(mp, agno, &rr->rr_rrec); /* Free the orphan record */ - xfs_defer_init(tp, &dfops); agbno = rr->rr_rrec.rc_startblock - XFS_REFC_COW_START; fsb = XFS_AGB_TO_FSB(mp, agno, agbno); error = xfs_refcount_free_cow_extent(mp, tp->t_dfops, fsb, rr->rr_rrec.rc_blockcount); if (error) - goto out_defer; + goto out_trans; /* Free the block. */ xfs_bmap_add_free(mp, tp->t_dfops, fsb, rr->rr_rrec.rc_blockcount, NULL); - error = xfs_defer_finish(&tp, tp->t_dfops); - if (error) - goto out_defer; - error = xfs_trans_commit(tp); if (error) goto out_free; @@ -1716,8 +1710,6 @@ xfs_refcount_recover_cow_leftovers( } return error; -out_defer: - xfs_defer_cancel(tp->t_dfops); out_trans: xfs_trans_cancel(tp); out_free: diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c index d3055972d3a6..228821b2ebe0 100644 --- a/fs/xfs/xfs_attr_inactive.c +++ b/fs/xfs/xfs_attr_inactive.c @@ -382,7 +382,6 @@ xfs_attr_inactive( { struct xfs_trans *trans; struct xfs_mount *mp; - struct xfs_defer_ops dfops; int lock_mode = XFS_ILOCK_SHARED; int error = 0; @@ -399,7 +398,6 @@ xfs_attr_inactive( error = xfs_trans_alloc(mp, &M_RES(mp)->tr_attrinval, 0, 0, 0, &trans); if (error) goto out_destroy_fork; - xfs_defer_init(trans, &dfops); lock_mode = XFS_ILOCK_EXCL; xfs_ilock(dp, lock_mode); diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 1a4617c74c6a..ddb5f1200d3d 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -792,7 +792,6 @@ xfs_free_eofblocks( int nimaps; struct xfs_bmbt_irec imap; struct xfs_mount *mp = ip->i_mount; - struct xfs_defer_ops dfops; /* * Figure out if there are any blocks beyond the end @@ -832,7 +831,6 @@ xfs_free_eofblocks( ASSERT(XFS_FORCED_SHUTDOWN(mp)); return error; } - xfs_defer_init(tp, &dfops); xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, 0); @@ -880,7 +878,6 @@ xfs_alloc_file_space( int rt; xfs_trans_t *tp; xfs_bmbt_irec_t imaps[1], *imapp; - struct xfs_defer_ops dfops; uint qblocks, resblks, resrtextents; int error; @@ -973,7 +970,6 @@ xfs_alloc_file_space( xfs_trans_ijoin(tp, ip, 0); - xfs_defer_init(tp, &dfops); error = xfs_bmapi_write(tp, ip, startoffset_fsb, allocatesize_fsb, alloc_type, resblks, imapp, &nimaps); @@ -983,10 +979,6 @@ xfs_alloc_file_space( /* * Complete the transaction */ - error = xfs_defer_finish(&tp, tp->t_dfops); - if (error) - goto error0; - error = xfs_trans_commit(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); if (error) @@ -1005,8 +997,7 @@ xfs_alloc_file_space( return error; -error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */ - xfs_defer_cancel(&dfops); +error0: /* unlock inode, unreserve quota blocks, cancel trans */ xfs_trans_unreserve_quota_nblks(tp, ip, (long)qblocks, 0, quota_flag); error1: /* Just cancel transaction */ @@ -1024,7 +1015,6 @@ xfs_unmap_extent( { struct xfs_mount *mp = ip->i_mount; struct xfs_trans *tp; - struct xfs_defer_ops dfops; uint resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0); int error; @@ -1042,23 +1032,17 @@ xfs_unmap_extent( xfs_trans_ijoin(tp, ip, 0); - xfs_defer_init(tp, &dfops); error = xfs_bunmapi(tp, ip, startoffset_fsb, len_fsb, 0, 2, done); if (error) - goto out_bmap_cancel; + goto out_trans_cancel; xfs_defer_ijoin(tp->t_dfops, ip); - error = xfs_defer_finish(&tp, tp->t_dfops); - if (error) - goto out_bmap_cancel; error = xfs_trans_commit(tp); out_unlock: xfs_iunlock(ip, XFS_ILOCK_EXCL); return error; -out_bmap_cancel: - xfs_defer_cancel(tp->t_dfops); out_trans_cancel: xfs_trans_cancel(tp); goto out_unlock; @@ -1310,7 +1294,6 @@ xfs_collapse_file_space( struct xfs_mount *mp = ip->i_mount; struct xfs_trans *tp; int error; - struct xfs_defer_ops dfops; xfs_fileoff_t next_fsb = XFS_B_TO_FSB(mp, offset + len); xfs_fileoff_t shift_fsb = XFS_B_TO_FSB(mp, len); uint resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0); @@ -1343,22 +1326,16 @@ xfs_collapse_file_space( goto out_trans_cancel; xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); - xfs_defer_init(tp, &dfops); error = xfs_bmap_collapse_extents(tp, ip, &next_fsb, shift_fsb, &done); if (error) - goto out_bmap_cancel; + goto out_trans_cancel; - error = xfs_defer_finish(&tp, tp->t_dfops); - if (error) - goto out_bmap_cancel; error = xfs_trans_commit(tp); } return error; -out_bmap_cancel: - xfs_defer_cancel(tp->t_dfops); out_trans_cancel: xfs_trans_cancel(tp); return error; @@ -1385,7 +1362,6 @@ xfs_insert_file_space( struct xfs_mount *mp = ip->i_mount; struct xfs_trans *tp; int error; - struct xfs_defer_ops dfops; xfs_fileoff_t stop_fsb = XFS_B_TO_FSB(mp, offset); xfs_fileoff_t next_fsb = NULLFSBLOCK; xfs_fileoff_t shift_fsb = XFS_B_TO_FSB(mp, len); @@ -1421,22 +1397,17 @@ xfs_insert_file_space( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); - xfs_defer_init(tp, &dfops); error = xfs_bmap_insert_extents(tp, ip, &next_fsb, shift_fsb, &done, stop_fsb); if (error) - goto out_bmap_cancel; + goto out_trans_cancel; - error = xfs_defer_finish(&tp, tp->t_dfops); - if (error) - goto out_bmap_cancel; error = xfs_trans_commit(tp); } return error; -out_bmap_cancel: - xfs_defer_cancel(tp->t_dfops); +out_trans_cancel: xfs_trans_cancel(tp); return error; } @@ -1607,7 +1578,7 @@ xfs_swap_extent_rmap( /* Unmap the old blocks in the source file. */ while (tirec.br_blockcount) { - xfs_defer_init(tp, tp->t_dfops); + ASSERT(tp->t_firstblock == NULLFSBLOCK); trace_xfs_swap_extent_rmap_remap_piece(tip, &tirec); /* Read extent from the source file */ @@ -1831,7 +1802,6 @@ xfs_swap_extents( { struct xfs_mount *mp = ip->i_mount; struct xfs_trans *tp; - struct xfs_defer_ops dfops; struct xfs_bstat *sbp = &sxp->sx_stat; int src_log_flags, target_log_flags; int error = 0; @@ -1900,7 +1870,6 @@ xfs_swap_extents( error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0, 0, &tp); if (error) goto out_unlock; - xfs_defer_init(tp, &dfops); /* * Lock and join the inodes to the tansaction so that transaction commit diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index c53de34c9ae5..a57d5e8c3118 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -295,8 +295,6 @@ xfs_dquot_disk_alloc( trace_xfs_dqalloc(dqp); - xfs_defer_init(tp, tp->t_dfops); - xfs_ilock(quotip, XFS_ILOCK_EXCL); if (!xfs_this_quota_on(dqp->q_mount, dqp->dq_flags)) { /* @@ -538,7 +536,6 @@ xfs_qm_dqread_alloc( struct xfs_buf **bpp) { struct xfs_trans *tp; - struct xfs_defer_ops dfops; struct xfs_buf *bp; int error; @@ -546,7 +543,6 @@ xfs_qm_dqread_alloc( XFS_QM_DQALLOC_SPACE_RES(mp), 0, 0, &tp); if (error) goto err; - xfs_defer_init(tp, &dfops); error = xfs_dquot_disk_alloc(&tp, dqp, &bp); if (error) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 7d7d7e95fa17..c47183a2f167 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1142,7 +1142,6 @@ xfs_create( struct xfs_inode *ip = NULL; struct xfs_trans *tp = NULL; int error; - struct xfs_defer_ops dfops; bool unlock_dp_on_error = false; prid_t prid; struct xfs_dquot *udqp = NULL; @@ -1194,8 +1193,6 @@ xfs_create( xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); unlock_dp_on_error = true; - xfs_defer_init(tp, &dfops); - /* * Reserve disk quota and the inode. */ @@ -1236,11 +1233,11 @@ xfs_create( if (is_dir) { error = xfs_dir_init(tp, ip, dp); if (error) - goto out_bmap_cancel; + goto out_trans_cancel; error = xfs_bumplink(tp, dp); if (error) - goto out_bmap_cancel; + goto out_trans_cancel; } /* @@ -1258,10 +1255,6 @@ xfs_create( */ xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp); - error = xfs_defer_finish(&tp, &dfops); - if (error) - goto out_bmap_cancel; - error = xfs_trans_commit(tp); if (error) goto out_release_inode; @@ -1273,8 +1266,6 @@ xfs_create( *ipp = ip; return 0; - out_bmap_cancel: - xfs_defer_cancel(&dfops); out_trans_cancel: xfs_trans_cancel(tp); out_release_inode: @@ -1399,7 +1390,6 @@ xfs_link( xfs_mount_t *mp = tdp->i_mount; xfs_trans_t *tp; int error; - struct xfs_defer_ops dfops; int resblks; trace_xfs_link(tdp, target_name); @@ -1448,8 +1438,6 @@ xfs_link( goto error_return; } - xfs_defer_init(tp, &dfops); - /* * Handle initial link state of O_TMPFILE inode */ @@ -1478,12 +1466,6 @@ xfs_link( if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) xfs_trans_set_sync(tp); - error = xfs_defer_finish(&tp, &dfops); - if (error) { - xfs_defer_cancel(&dfops); - goto error_return; - } - return xfs_trans_commit(tp); error_return: @@ -1719,7 +1701,6 @@ xfs_inactive_truncate( { struct xfs_mount *mp = ip->i_mount; struct xfs_trans *tp; - struct xfs_defer_ops dfops; int error; error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp); @@ -1727,8 +1708,6 @@ xfs_inactive_truncate( ASSERT(XFS_FORCED_SHUTDOWN(mp)); return error; } - xfs_defer_init(tp, &dfops); - xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, 0); @@ -1769,7 +1748,6 @@ STATIC int xfs_inactive_ifree( struct xfs_inode *ip) { - struct xfs_defer_ops dfops; struct xfs_mount *mp = ip->i_mount; struct xfs_trans *tp; int error; @@ -1806,7 +1784,6 @@ xfs_inactive_ifree( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, 0); - xfs_defer_init(tp, &dfops); error = xfs_ifree(tp, ip); if (error) { /* @@ -1833,12 +1810,6 @@ xfs_inactive_ifree( * Just ignore errors at this point. There is nothing we can do except * to try to keep going. Make sure it's not a silent error. */ - error = xfs_defer_finish(&tp, &dfops); - if (error) { - xfs_notice(mp, "%s: xfs_defer_finish returned error %d", - __func__, error); - xfs_defer_cancel(&dfops); - } error = xfs_trans_commit(tp); if (error) xfs_notice(mp, "%s: xfs_trans_commit returned error %d", @@ -2569,7 +2540,6 @@ xfs_remove( xfs_trans_t *tp = NULL; int is_dir = S_ISDIR(VFS_I(ip)->i_mode); int error = 0; - struct xfs_defer_ops dfops; uint resblks; trace_xfs_remove(dp, name); @@ -2649,11 +2619,10 @@ xfs_remove( if (error) goto out_trans_cancel; - xfs_defer_init(tp, &dfops); error = xfs_dir_removename(tp, dp, name, ip->i_ino, resblks); if (error) { ASSERT(error != -ENOENT); - goto out_bmap_cancel; + goto out_trans_cancel; } /* @@ -2664,10 +2633,6 @@ xfs_remove( if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) xfs_trans_set_sync(tp); - error = xfs_defer_finish(&tp, &dfops); - if (error) - goto out_bmap_cancel; - error = xfs_trans_commit(tp); if (error) goto std_return; @@ -2677,8 +2642,6 @@ xfs_remove( return 0; - out_bmap_cancel: - xfs_defer_cancel(&dfops); out_trans_cancel: xfs_trans_cancel(tp); std_return: @@ -2740,9 +2703,6 @@ static int xfs_finish_rename( struct xfs_trans *tp) { - struct xfs_defer_ops *dfops = tp->t_dfops; - int error; - /* * If this is a synchronous mount, make sure that the rename transaction * goes to disk before returning to the user. @@ -2750,13 +2710,6 @@ xfs_finish_rename( if (tp->t_mountp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) xfs_trans_set_sync(tp); - error = xfs_defer_finish(&tp, dfops); - if (error) { - xfs_defer_cancel(dfops); - xfs_trans_cancel(tp); - return error; - } - return xfs_trans_commit(tp); } @@ -2869,7 +2822,6 @@ xfs_cross_rename( return xfs_finish_rename(tp); out_trans_abort: - xfs_defer_cancel(tp->t_dfops); xfs_trans_cancel(tp); return error; } @@ -2924,7 +2876,6 @@ xfs_rename( { struct xfs_mount *mp = src_dp->i_mount; struct xfs_trans *tp; - struct xfs_defer_ops dfops; struct xfs_inode *wip = NULL; /* whiteout inode */ struct xfs_inode *inodes[__XFS_SORT_INODES]; int num_inodes = __XFS_SORT_INODES; @@ -3006,8 +2957,6 @@ xfs_rename( goto out_trans_cancel; } - xfs_defer_init(tp, &dfops); - /* RENAME_EXCHANGE is unique from here on. */ if (flags & RENAME_EXCHANGE) return xfs_cross_rename(tp, src_dp, src_name, src_ip, @@ -3035,7 +2984,7 @@ xfs_rename( error = xfs_dir_createname(tp, target_dp, target_name, src_ip->i_ino, spaceres); if (error) - goto out_bmap_cancel; + goto out_trans_cancel; xfs_trans_ichgtime(tp, target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); @@ -3043,7 +2992,7 @@ xfs_rename( if (new_parent && src_is_directory) { error = xfs_bumplink(tp, target_dp); if (error) - goto out_bmap_cancel; + goto out_trans_cancel; } } else { /* target_ip != NULL */ /* @@ -3074,7 +3023,7 @@ xfs_rename( error = xfs_dir_replace(tp, target_dp, target_name, src_ip->i_ino, spaceres); if (error) - goto out_bmap_cancel; + goto out_trans_cancel; xfs_trans_ichgtime(tp, target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); @@ -3085,7 +3034,7 @@ xfs_rename( */ error = xfs_droplink(tp, target_ip); if (error) - goto out_bmap_cancel; + goto out_trans_cancel; if (src_is_directory) { /* @@ -3093,7 +3042,7 @@ xfs_rename( */ error = xfs_droplink(tp, target_ip); if (error) - goto out_bmap_cancel; + goto out_trans_cancel; } } /* target_ip != NULL */ @@ -3109,7 +3058,7 @@ xfs_rename( target_dp->i_ino, spaceres); ASSERT(error != -EEXIST); if (error) - goto out_bmap_cancel; + goto out_trans_cancel; } /* @@ -3135,7 +3084,7 @@ xfs_rename( */ error = xfs_droplink(tp, src_dp); if (error) - goto out_bmap_cancel; + goto out_trans_cancel; } /* @@ -3150,7 +3099,7 @@ xfs_rename( error = xfs_dir_removename(tp, src_dp, src_name, src_ip->i_ino, spaceres); if (error) - goto out_bmap_cancel; + goto out_trans_cancel; /* * For whiteouts, we need to bump the link count on the whiteout inode. @@ -3164,10 +3113,10 @@ xfs_rename( ASSERT(VFS_I(wip)->i_nlink == 0); error = xfs_bumplink(tp, wip); if (error) - goto out_bmap_cancel; + goto out_trans_cancel; error = xfs_iunlink_remove(tp, wip); if (error) - goto out_bmap_cancel; + goto out_trans_cancel; xfs_trans_log_inode(tp, wip, XFS_ILOG_CORE); /* @@ -3188,8 +3137,6 @@ xfs_rename( IRELE(wip); return error; -out_bmap_cancel: - xfs_defer_cancel(&dfops); out_trans_cancel: xfs_trans_cancel(tp); out_release_wip: diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 756694219f77..8e8ca9f03f0e 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -157,7 +157,6 @@ xfs_iomap_write_direct( int quota_flag; int rt; xfs_trans_t *tp; - struct xfs_defer_ops dfops; uint qblocks, resblks, resrtextents; int error; int lockmode; @@ -253,20 +252,15 @@ xfs_iomap_write_direct( * From this point onwards we overwrite the imap pointer that the * caller gave to us. */ - xfs_defer_init(tp, &dfops); nimaps = 1; error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, bmapi_flags, resblks, imap, &nimaps); if (error) - goto out_bmap_cancel; + goto out_res_cancel; /* * Complete the transaction */ - error = xfs_defer_finish(&tp, tp->t_dfops); - if (error) - goto out_bmap_cancel; - error = xfs_trans_commit(tp); if (error) goto out_unlock; @@ -286,8 +280,7 @@ out_unlock: xfs_iunlock(ip, lockmode); return error; -out_bmap_cancel: - xfs_defer_cancel(tp->t_dfops); +out_res_cancel: xfs_trans_unreserve_quota_nblks(tp, ip, (long)qblocks, 0, quota_flag); out_trans_cancel: xfs_trans_cancel(tp); @@ -663,7 +656,6 @@ xfs_iomap_write_allocate( xfs_mount_t *mp = ip->i_mount; xfs_fileoff_t offset_fsb, last_block; xfs_fileoff_t end_fsb, map_start_fsb; - struct xfs_defer_ops dfops; xfs_filblks_t count_fsb; xfs_trans_t *tp; int nimaps; @@ -713,8 +705,6 @@ xfs_iomap_write_allocate( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, 0); - xfs_defer_init(tp, &dfops); - /* * it is possible that the extents have changed since * we did the read call as we dropped the ilock for a @@ -772,10 +762,6 @@ xfs_iomap_write_allocate( if (error) goto trans_cancel; - error = xfs_defer_finish(&tp, tp->t_dfops); - if (error) - goto trans_cancel; - error = xfs_trans_commit(tp); if (error) goto error0; @@ -806,7 +792,6 @@ xfs_iomap_write_allocate( } trans_cancel: - xfs_defer_cancel(tp->t_dfops); xfs_trans_cancel(tp); error0: xfs_iunlock(ip, XFS_ILOCK_EXCL); @@ -827,7 +812,6 @@ xfs_iomap_write_unwritten( int nimaps; xfs_trans_t *tp; xfs_bmbt_irec_t imap; - struct xfs_defer_ops dfops; struct inode *inode = VFS_I(ip); xfs_fsize_t i_size; uint resblks; @@ -872,7 +856,6 @@ xfs_iomap_write_unwritten( /* * Modify the unwritten extent state of the buffer. */ - xfs_defer_init(tp, &dfops); nimaps = 1; error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, XFS_BMAPI_CONVERT, resblks, &imap, @@ -896,10 +879,6 @@ xfs_iomap_write_unwritten( xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); } - error = xfs_defer_finish(&tp, tp->t_dfops); - if (error) - goto error_on_bmapi_transaction; - error = xfs_trans_commit(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); if (error) @@ -923,7 +902,6 @@ xfs_iomap_write_unwritten( return 0; error_on_bmapi_transaction: - xfs_defer_cancel(tp->t_dfops); xfs_trans_cancel(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); return error; diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 704b57a8b99e..2eac22bfad6a 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -813,7 +813,6 @@ xfs_setattr_size( struct inode *inode = VFS_I(ip); xfs_off_t oldsize, newsize; struct xfs_trans *tp; - struct xfs_defer_ops dfops; int error; uint lock_flags = 0; bool did_zeroing = false; @@ -917,7 +916,6 @@ xfs_setattr_size( error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp); if (error) return error; - xfs_defer_init(tp, &dfops); lock_flags |= XFS_ILOCK_EXCL; xfs_ilock(ip, XFS_ILOCK_EXCL); diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 958e9b96dc6a..265e1f561157 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4857,15 +4857,7 @@ xlog_finish_defer_ops( /* transfer all collected dfops to this transaction */ xfs_defer_move(tp->t_dfops, dfops); - error = xfs_defer_finish(&tp, tp->t_dfops); - if (error) - goto out_cancel; - return xfs_trans_commit(tp); - -out_cancel: - xfs_trans_cancel(tp); - return error; } /* diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index df0783303887..c07c5a39d516 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -214,7 +214,6 @@ xfs_qm_scall_trunc_qfile( { struct xfs_inode *ip; struct xfs_trans *tp; - struct xfs_defer_ops dfops; int error; if (ino == NULLFSINO) @@ -231,7 +230,6 @@ xfs_qm_scall_trunc_qfile( xfs_iunlock(ip, XFS_IOLOCK_EXCL); goto out_put; } - xfs_defer_init(tp, &dfops); xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, 0); diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 04c25ee6b6f8..a653739c9fb2 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -364,7 +364,6 @@ xfs_reflink_allocate_cow( xfs_fileoff_t offset_fsb = imap->br_startoff; xfs_filblks_t count_fsb = imap->br_blockcount; struct xfs_bmbt_irec got; - struct xfs_defer_ops dfops; struct xfs_trans *tp = NULL; int nimaps, error = 0; bool trimmed; @@ -424,7 +423,6 @@ retry: xfs_trans_ijoin(tp, ip, 0); - xfs_defer_init(tp, &dfops); nimaps = 1; /* Allocate the entire reservation as unwritten blocks. */ @@ -432,15 +430,11 @@ retry: XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC, resblks, imap, &nimaps); if (error) - goto out_bmap_cancel; + goto out_trans_cancel; xfs_inode_set_cowblocks_tag(ip); /* Finish up. */ - error = xfs_defer_finish(&tp, tp->t_dfops); - if (error) - goto out_bmap_cancel; - error = xfs_trans_commit(tp); if (error) return error; @@ -453,8 +447,7 @@ retry: return -ENOSPC; convert: return xfs_reflink_convert_cow_extent(ip, imap, offset_fsb, count_fsb); -out_bmap_cancel: - xfs_defer_cancel(tp->t_dfops); +out_trans_cancel: xfs_trans_unreserve_quota_nblks(tp, ip, (long)resblks, 0, XFS_QMOPT_RES_REGBLKS); out: @@ -624,7 +617,6 @@ xfs_reflink_end_cow( struct xfs_trans *tp; xfs_fileoff_t offset_fsb; xfs_fileoff_t end_fsb; - struct xfs_defer_ops dfops; int error; unsigned int resblks; xfs_filblks_t rlen; @@ -691,11 +683,11 @@ xfs_reflink_end_cow( goto prev_extent; /* Unmap the old blocks in the data fork. */ - xfs_defer_init(tp, &dfops); + ASSERT(tp->t_dfops && tp->t_firstblock == NULLFSBLOCK); rlen = del.br_blockcount; error = __xfs_bunmapi(tp, ip, del.br_startoff, &rlen, 0, 1); if (error) - goto out_defer; + goto out_cancel; /* Trim the extent to whatever got unmapped. */ if (rlen) { @@ -708,13 +700,13 @@ xfs_reflink_end_cow( error = xfs_refcount_free_cow_extent(tp->t_mountp, tp->t_dfops, del.br_startblock, del.br_blockcount); if (error) - goto out_defer; + goto out_cancel; /* Map the new blocks into the data fork. */ error = xfs_bmap_map_extent(tp->t_mountp, tp->t_dfops, ip, &del); if (error) - goto out_defer; + goto out_cancel; /* Charge this new data fork mapping to the on-disk quota. */ xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_DELBCOUNT, @@ -726,7 +718,7 @@ xfs_reflink_end_cow( xfs_defer_ijoin(tp->t_dfops, ip); error = xfs_defer_finish(&tp, tp->t_dfops); if (error) - goto out_defer; + goto out_cancel; if (!xfs_iext_get_extent(ifp, &icur, &got)) break; continue; @@ -741,8 +733,6 @@ prev_extent: goto out; return 0; -out_defer: - xfs_defer_cancel(tp->t_dfops); out_cancel: xfs_trans_cancel(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); @@ -998,7 +988,6 @@ xfs_reflink_remap_extent( bool real_extent = xfs_bmap_is_real_extent(irec); struct xfs_trans *tp; unsigned int resblks; - struct xfs_defer_ops dfops; struct xfs_bmbt_irec uirec; xfs_filblks_t rlen; xfs_filblks_t unmap_len; @@ -1039,10 +1028,10 @@ xfs_reflink_remap_extent( /* Unmap the old blocks in the data fork. */ rlen = unmap_len; while (rlen) { - xfs_defer_init(tp, &dfops); + ASSERT(tp->t_dfops && tp->t_firstblock == NULLFSBLOCK); error = __xfs_bunmapi(tp, ip, destoff, &rlen, 0, 1); if (error) - goto out_defer; + goto out_cancel; /* * Trim the extent to whatever got unmapped. @@ -1063,12 +1052,12 @@ xfs_reflink_remap_extent( /* Update the refcount tree */ error = xfs_refcount_increase_extent(mp, tp->t_dfops, &uirec); if (error) - goto out_defer; + goto out_cancel; /* Map the new blocks into the data fork. */ error = xfs_bmap_map_extent(mp, tp->t_dfops, ip, &uirec); if (error) - goto out_defer; + goto out_cancel; /* Update quota accounting. */ xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, @@ -1090,7 +1079,7 @@ next_extent: xfs_defer_ijoin(tp->t_dfops, ip); error = xfs_defer_finish(&tp, tp->t_dfops); if (error) - goto out_defer; + goto out_cancel; } error = xfs_trans_commit(tp); @@ -1099,8 +1088,6 @@ next_extent: goto out; return 0; -out_defer: - xfs_defer_cancel(tp->t_dfops); out_cancel: xfs_trans_cancel(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index bc471d42a968..86d7d2f76226 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -761,7 +761,6 @@ xfs_growfs_rt_alloc( struct xfs_buf *bp; /* temporary buffer for zeroing */ xfs_daddr_t d; /* disk block address */ int error; /* error return value */ - struct xfs_defer_ops dfops; /* list of freed blocks */ xfs_fsblock_t fsbno; /* filesystem block for bno */ struct xfs_bmbt_irec map; /* block map output */ int nmap; /* number of block maps */ @@ -786,7 +785,6 @@ xfs_growfs_rt_alloc( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); - xfs_defer_init(tp, &dfops); /* * Allocate blocks to the bitmap file. */ @@ -797,13 +795,10 @@ xfs_growfs_rt_alloc( if (!error && nmap < 1) error = -ENOSPC; if (error) - goto out_bmap_cancel; + goto out_trans_cancel; /* * Free any blocks freed up in the transaction, then commit. */ - error = xfs_defer_finish(&tp, tp->t_dfops); - if (error) - goto out_bmap_cancel; error = xfs_trans_commit(tp); if (error) return error; @@ -853,8 +848,6 @@ xfs_growfs_rt_alloc( return 0; -out_bmap_cancel: - xfs_defer_cancel(tp->t_dfops); out_trans_cancel: xfs_trans_cancel(tp); return error; diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index d1ab0afa2723..ce801aedbcdc 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -163,7 +163,6 @@ xfs_symlink( struct xfs_inode *ip = NULL; int error = 0; int pathlen; - struct xfs_defer_ops dfops; bool unlock_dp_on_error = false; xfs_fileoff_t first_fsb; xfs_filblks_t fs_blocks; @@ -241,12 +240,6 @@ xfs_symlink( if (error) goto out_trans_cancel; - /* - * Initialize the bmap freelist prior to calling either - * bmapi or the directory create code. - */ - xfs_defer_init(tp, &dfops); - /* * Allocate an inode for the symlink. */ @@ -290,7 +283,7 @@ xfs_symlink( error = xfs_bmapi_write(tp, ip, first_fsb, fs_blocks, XFS_BMAPI_METADATA, resblks, mval, &nmaps); if (error) - goto out_bmap_cancel; + goto out_trans_cancel; if (resblks) resblks -= fs_blocks; @@ -308,7 +301,7 @@ xfs_symlink( BTOBB(byte_cnt), 0); if (!bp) { error = -ENOMEM; - goto out_bmap_cancel; + goto out_trans_cancel; } bp->b_ops = &xfs_symlink_buf_ops; @@ -337,7 +330,7 @@ xfs_symlink( */ error = xfs_dir_createname(tp, dp, link_name, ip->i_ino, resblks); if (error) - goto out_bmap_cancel; + goto out_trans_cancel; xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); @@ -350,10 +343,6 @@ xfs_symlink( xfs_trans_set_sync(tp); } - error = xfs_defer_finish(&tp, tp->t_dfops); - if (error) - goto out_bmap_cancel; - error = xfs_trans_commit(tp); if (error) goto out_release_inode; @@ -365,8 +354,6 @@ xfs_symlink( *ipp = ip; return 0; -out_bmap_cancel: - xfs_defer_cancel(tp->t_dfops); out_trans_cancel: xfs_trans_cancel(tp); out_release_inode: @@ -399,7 +386,6 @@ xfs_inactive_symlink_rmt( xfs_buf_t *bp; int done; int error; - struct xfs_defer_ops dfops; int i; xfs_mount_t *mp; xfs_bmbt_irec_t mval[XFS_SYMLINK_MAPS]; @@ -438,7 +424,6 @@ xfs_inactive_symlink_rmt( * Find the block(s) so we can inval and unmap them. */ done = 0; - xfs_defer_init(tp, &dfops); nmaps = ARRAY_SIZE(mval); error = xfs_bmapi_read(ip, 0, xfs_symlink_blocks(mp, size), mval, &nmaps, 0); @@ -453,7 +438,7 @@ xfs_inactive_symlink_rmt( XFS_FSB_TO_BB(mp, mval[i].br_blockcount), 0); if (!bp) { error = -ENOMEM; - goto error_bmap_cancel; + goto error_trans_cancel; } xfs_trans_binval(tp, bp); } @@ -462,19 +447,14 @@ xfs_inactive_symlink_rmt( */ error = xfs_bunmapi(tp, ip, 0, size, 0, nmaps, &done); if (error) - goto error_bmap_cancel; + goto error_trans_cancel; ASSERT(done); - /* - * Commit the first transaction. This logs the EFI and the inode. - */ - xfs_defer_ijoin(tp->t_dfops, ip); - error = xfs_defer_finish(&tp, tp->t_dfops); - if (error) - goto error_bmap_cancel; /* - * Commit the transaction containing extent freeing and EFDs. + * Commit the transaction. This first logs the EFI and the inode, then + * rolls and commits the transaction that frees the extents. */ + xfs_defer_ijoin(tp->t_dfops, ip); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); error = xfs_trans_commit(tp); if (error) { @@ -492,8 +472,6 @@ xfs_inactive_symlink_rmt( xfs_iunlock(ip, XFS_ILOCK_EXCL); return 0; -error_bmap_cancel: - xfs_defer_cancel(tp->t_dfops); error_trans_cancel: xfs_trans_cancel(tp); error_unlock: -- cgit v1.2.3 From d5cca7eb244d276177a57e42494d479742bbba37 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Tue, 24 Jul 2018 13:43:14 -0700 Subject: xfs: remove unnecessary dfops init calls in xattr code Each xfs_defer_init() call in the xattr code uses the internal dfops reference. In addition, a successful xfs_defer_finish() always returns with a reset xfs_defer_ops structure. Given that along with the fact that every xfs_defer_init() call in the xattr code is followed up by an xfs_defer_finish(), the former calls are no longer necessary and can be removed. Note that the xfs_defer_init() call in the remote value copy loop of xfs_attr_rmtval_set() is not followed by a finish, but the dfops is unused in this instance. Signed-off-by: Brian Foster Reviewed-by: Bill O'Donnell Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr.c | 8 -------- fs/xfs/libxfs/xfs_attr_remote.c | 3 --- 2 files changed, 11 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 66a22c80a0db..3e98f0af389c 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -587,7 +587,6 @@ xfs_attr_leaf_addname( * Commit that transaction so that the node_addname() call * can manage its own transactions. */ - xfs_defer_init(args->trans, args->trans->t_dfops); error = xfs_attr3_leaf_to_node(args); if (error) goto out_defer_cancel; @@ -676,7 +675,6 @@ xfs_attr_leaf_addname( * If the result is small enough, shrink it all into the inode. */ if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { - xfs_defer_init(args->trans, args->trans->t_dfops); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (error) @@ -741,7 +739,6 @@ xfs_attr_leaf_removename( * If the result is small enough, shrink it all into the inode. */ if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { - xfs_defer_init(args->trans, args->trans->t_dfops); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (error) @@ -870,7 +867,6 @@ restart: */ xfs_da_state_free(state); state = NULL; - xfs_defer_init(args->trans, args->trans->t_dfops); error = xfs_attr3_leaf_to_node(args); if (error) goto out_defer_cancel; @@ -897,7 +893,6 @@ restart: * in the index/blkno/rmtblkno/rmtblkcnt fields and * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields. */ - xfs_defer_init(args->trans, args->trans->t_dfops); error = xfs_da3_split(state); if (error) goto out_defer_cancel; @@ -995,7 +990,6 @@ restart: * Check to see if the tree needs to be collapsed. */ if (retval && (state->path.active > 1)) { - xfs_defer_init(args->trans, args->trans->t_dfops); error = xfs_da3_join(state); if (error) goto out_defer_cancel; @@ -1120,7 +1114,6 @@ xfs_attr_node_removename( * Check to see if the tree needs to be collapsed. */ if (retval && (state->path.active > 1)) { - xfs_defer_init(args->trans, args->trans->t_dfops); error = xfs_da3_join(state); if (error) goto out_defer_cancel; @@ -1152,7 +1145,6 @@ xfs_attr_node_removename( goto out; if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { - xfs_defer_init(args->trans, args->trans->t_dfops); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (error) diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index 829ab20f0cd7..0fbfb740949e 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -480,7 +480,6 @@ xfs_attr_rmtval_set( * extent and then crash then the block may not contain the * correct metadata after log recovery occurs. */ - xfs_defer_init(args->trans, args->trans->t_dfops); nmap = 1; error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)lblkno, blkcnt, XFS_BMAPI_ATTRFORK, args->total, &map, @@ -522,7 +521,6 @@ xfs_attr_rmtval_set( ASSERT(blkcnt > 0); - xfs_defer_init(args->trans, args->trans->t_dfops); nmap = 1; error = xfs_bmapi_read(dp, (xfs_fileoff_t)lblkno, blkcnt, &map, &nmap, @@ -625,7 +623,6 @@ xfs_attr_rmtval_remove( blkcnt = args->rmtblkcnt; done = 0; while (!done) { - xfs_defer_init(args->trans, args->trans->t_dfops); error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, XFS_BMAPI_ATTRFORK, 1, &done); if (error) -- cgit v1.2.3 From 9e28a242be65b8274742425ca5d146f366205a90 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Tue, 24 Jul 2018 13:43:15 -0700 Subject: xfs: drop unnecessary xfs_defer_finish() dfops parameter Every caller of xfs_defer_finish() now passes the transaction and its associated ->t_dfops. The xfs_defer_ops parameter is therefore no longer necessary and can be removed. Since most xfs_defer_finish() callers also have to consider xfs_defer_cancel() on error, update the latter to also receive the transaction for consistency. The log recovery code contains an outlier case that cancels a dfops directly without an available transaction. Retain an internal wrapper to support this outlier case for the time being. Signed-off-by: Brian Foster Reviewed-by: Bill O'Donnell Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr.c | 27 +++++++++++++-------------- fs/xfs/libxfs/xfs_attr_remote.c | 8 ++++---- fs/xfs/libxfs/xfs_defer.c | 7 +++---- fs/xfs/libxfs/xfs_defer.h | 4 ++-- fs/xfs/xfs_bmap_util.c | 4 ++-- fs/xfs/xfs_dquot.c | 4 ++-- fs/xfs/xfs_inode.c | 4 ++-- fs/xfs/xfs_log_recover.c | 2 +- fs/xfs/xfs_reflink.c | 8 ++++---- fs/xfs/xfs_trans.c | 13 ++++++++++--- fs/xfs/xfs_trans.h | 3 +++ 11 files changed, 46 insertions(+), 38 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 3e98f0af389c..3deb5cdadf08 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -322,7 +322,7 @@ xfs_attr_set( xfs_trans_bhold(args.trans, leaf_bp); xfs_defer_bjoin(args.trans->t_dfops, leaf_bp); xfs_defer_ijoin(args.trans->t_dfops, dp); - error = xfs_defer_finish(&args.trans, args.trans->t_dfops); + error = xfs_defer_finish(&args.trans); if (error) goto out; @@ -591,7 +591,7 @@ xfs_attr_leaf_addname( if (error) goto out_defer_cancel; xfs_defer_ijoin(args->trans->t_dfops, dp); - error = xfs_defer_finish(&args->trans, args->trans->t_dfops); + error = xfs_defer_finish(&args->trans); if (error) goto out_defer_cancel; @@ -680,7 +680,7 @@ xfs_attr_leaf_addname( if (error) goto out_defer_cancel; xfs_defer_ijoin(args->trans->t_dfops, dp); - error = xfs_defer_finish(&args->trans, args->trans->t_dfops); + error = xfs_defer_finish(&args->trans); if (error) goto out_defer_cancel; } @@ -698,7 +698,7 @@ xfs_attr_leaf_addname( } return error; out_defer_cancel: - xfs_defer_cancel(args->trans->t_dfops); + xfs_defer_cancel(args->trans); return error; } @@ -744,13 +744,13 @@ xfs_attr_leaf_removename( if (error) goto out_defer_cancel; xfs_defer_ijoin(args->trans->t_dfops, dp); - error = xfs_defer_finish(&args->trans, args->trans->t_dfops); + error = xfs_defer_finish(&args->trans); if (error) goto out_defer_cancel; } return 0; out_defer_cancel: - xfs_defer_cancel(args->trans->t_dfops); + xfs_defer_cancel(args->trans); return error; } @@ -871,8 +871,7 @@ restart: if (error) goto out_defer_cancel; xfs_defer_ijoin(args->trans->t_dfops, dp); - error = xfs_defer_finish(&args->trans, - args->trans->t_dfops); + error = xfs_defer_finish(&args->trans); if (error) goto out_defer_cancel; @@ -897,7 +896,7 @@ restart: if (error) goto out_defer_cancel; xfs_defer_ijoin(args->trans->t_dfops, dp); - error = xfs_defer_finish(&args->trans, args->trans->t_dfops); + error = xfs_defer_finish(&args->trans); if (error) goto out_defer_cancel; } else { @@ -994,7 +993,7 @@ restart: if (error) goto out_defer_cancel; xfs_defer_ijoin(args->trans->t_dfops, dp); - error = xfs_defer_finish(&args->trans, args->trans->t_dfops); + error = xfs_defer_finish(&args->trans); if (error) goto out_defer_cancel; } @@ -1023,7 +1022,7 @@ out: return error; return retval; out_defer_cancel: - xfs_defer_cancel(args->trans->t_dfops); + xfs_defer_cancel(args->trans); goto out; } @@ -1118,7 +1117,7 @@ xfs_attr_node_removename( if (error) goto out_defer_cancel; xfs_defer_ijoin(args->trans->t_dfops, dp); - error = xfs_defer_finish(&args->trans, args->trans->t_dfops); + error = xfs_defer_finish(&args->trans); if (error) goto out_defer_cancel; /* @@ -1150,7 +1149,7 @@ xfs_attr_node_removename( if (error) goto out_defer_cancel; xfs_defer_ijoin(args->trans->t_dfops, dp); - error = xfs_defer_finish(&args->trans, args->trans->t_dfops); + error = xfs_defer_finish(&args->trans); if (error) goto out_defer_cancel; } else @@ -1162,7 +1161,7 @@ out: xfs_da_state_free(state); return error; out_defer_cancel: - xfs_defer_cancel(args->trans->t_dfops); + xfs_defer_cancel(args->trans); goto out; } diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index 0fbfb740949e..77ca38586913 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -487,7 +487,7 @@ xfs_attr_rmtval_set( if (error) goto out_defer_cancel; xfs_defer_ijoin(args->trans->t_dfops, dp); - error = xfs_defer_finish(&args->trans, args->trans->t_dfops); + error = xfs_defer_finish(&args->trans); if (error) goto out_defer_cancel; @@ -555,7 +555,7 @@ xfs_attr_rmtval_set( ASSERT(valuelen == 0); return 0; out_defer_cancel: - xfs_defer_cancel(args->trans->t_dfops); + xfs_defer_cancel(args->trans); return error; } @@ -628,7 +628,7 @@ xfs_attr_rmtval_remove( if (error) goto out_defer_cancel; xfs_defer_ijoin(args->trans->t_dfops, args->dp); - error = xfs_defer_finish(&args->trans, args->trans->t_dfops); + error = xfs_defer_finish(&args->trans); if (error) goto out_defer_cancel; @@ -641,6 +641,6 @@ xfs_attr_rmtval_remove( } return 0; out_defer_cancel: - xfs_defer_cancel(args->trans->t_dfops); + xfs_defer_cancel(args->trans); return error; } diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index b63cc9e730da..cbee0a86c978 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -342,9 +342,9 @@ xfs_defer_reset( */ int xfs_defer_finish( - struct xfs_trans **tp, - struct xfs_defer_ops *dop) + struct xfs_trans **tp) { + struct xfs_defer_ops *dop = (*tp)->t_dfops; struct xfs_defer_pending *dfp; struct list_head *li; struct list_head *n; @@ -353,7 +353,6 @@ xfs_defer_finish( void (*cleanup_fn)(struct xfs_trans *, void *, int); ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES); - ASSERT((*tp)->t_dfops == dop); trace_xfs_defer_finish((*tp)->t_mountp, dop, _RET_IP_); @@ -454,7 +453,7 @@ out: * Free up any items left in the list. */ void -xfs_defer_cancel( +__xfs_defer_cancel( struct xfs_defer_ops *dop) { struct xfs_defer_pending *dfp; diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index 35507ca9a148..56f927803940 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h @@ -48,8 +48,8 @@ enum xfs_defer_ops_type { void xfs_defer_add(struct xfs_defer_ops *dop, enum xfs_defer_ops_type type, struct list_head *h); -int xfs_defer_finish(struct xfs_trans **tp, struct xfs_defer_ops *dop); -void xfs_defer_cancel(struct xfs_defer_ops *dop); +int xfs_defer_finish(struct xfs_trans **tp); +void __xfs_defer_cancel(struct xfs_defer_ops *dop); void xfs_defer_init(struct xfs_trans *tp, struct xfs_defer_ops *dop); bool xfs_defer_has_unfinished_work(struct xfs_defer_ops *dop); int xfs_defer_ijoin(struct xfs_defer_ops *dop, struct xfs_inode *ip); diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index ddb5f1200d3d..c32ec17048f5 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1624,7 +1624,7 @@ xfs_swap_extent_rmap( goto out_defer; xfs_defer_ijoin(tp->t_dfops, ip); - error = xfs_defer_finish(tpp, tp->t_dfops); + error = xfs_defer_finish(tpp); tp = *tpp; if (error) goto out_defer; @@ -1645,7 +1645,7 @@ xfs_swap_extent_rmap( return 0; out_defer: - xfs_defer_cancel(tp->t_dfops); + xfs_defer_cancel(tp); out: trace_xfs_swap_extent_rmap_error(ip, error, _RET_IP_); tip->i_d.di_flags2 = tip_flags2; diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index a57d5e8c3118..da5c55cec966 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -368,7 +368,7 @@ xfs_dquot_disk_alloc( xfs_trans_brelse(tp, bp); goto error1; } - error = xfs_defer_finish(tpp, tp->t_dfops); + error = xfs_defer_finish(tpp); tp = *tpp; if (error) { xfs_buf_relse(bp); @@ -378,7 +378,7 @@ xfs_dquot_disk_alloc( return 0; error1: - xfs_defer_cancel(tp->t_dfops); + xfs_defer_cancel(tp); error0: return error; } diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index c47183a2f167..0e4bd559a6a7 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1570,7 +1570,7 @@ xfs_itruncate_extents_flags( * reservation and commit the old transaction. */ xfs_defer_ijoin(tp->t_dfops, ip); - error = xfs_defer_finish(&tp, tp->t_dfops); + error = xfs_defer_finish(&tp); if (error) goto out_bmap_cancel; @@ -1606,7 +1606,7 @@ out_bmap_cancel: * the transaction can be properly aborted. We just need to make sure * we're not holding any resources that we were not when we came in. */ - xfs_defer_cancel(tp->t_dfops); + xfs_defer_cancel(tp); goto out; } diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 265e1f561157..94908a4019e1 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4946,7 +4946,7 @@ out: xfs_trans_ail_cursor_done(&cur); spin_unlock(&ailp->ail_lock); if (error) - xfs_defer_cancel(&dfops); + __xfs_defer_cancel(&dfops); else error = xlog_finish_defer_ops(log->l_mp, &dfops); diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index a653739c9fb2..68b6921dc3f6 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -518,9 +518,9 @@ xfs_reflink_cancel_cow_blocks( /* Roll the transaction */ xfs_defer_ijoin((*tpp)->t_dfops, ip); - error = xfs_defer_finish(tpp, (*tpp)->t_dfops); + error = xfs_defer_finish(tpp); if (error) { - xfs_defer_cancel((*tpp)->t_dfops); + xfs_defer_cancel(*tpp); break; } @@ -716,7 +716,7 @@ xfs_reflink_end_cow( xfs_bmap_del_extent_cow(ip, &icur, &got, &del); xfs_defer_ijoin(tp->t_dfops, ip); - error = xfs_defer_finish(&tp, tp->t_dfops); + error = xfs_defer_finish(&tp); if (error) goto out_cancel; if (!xfs_iext_get_extent(ifp, &icur, &got)) @@ -1077,7 +1077,7 @@ xfs_reflink_remap_extent( next_extent: /* Process all the deferred stuff. */ xfs_defer_ijoin(tp->t_dfops, ip); - error = xfs_defer_finish(&tp, tp->t_dfops); + error = xfs_defer_finish(&tp); if (error) goto out_cancel; } diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 412c8d236c71..cd553aa9ecb0 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -933,9 +933,9 @@ __xfs_trans_commit( /* finish deferred items on final commit */ if (!regrant && tp->t_dfops) { - error = xfs_defer_finish(&tp, tp->t_dfops); + error = xfs_defer_finish(&tp); if (error) { - xfs_defer_cancel(tp->t_dfops); + xfs_defer_cancel(tp); goto out_unreserve; } } @@ -1030,7 +1030,7 @@ xfs_trans_cancel( trace_xfs_trans_cancel(tp, _RET_IP_); if (tp->t_dfops) - xfs_defer_cancel(tp->t_dfops); + xfs_defer_cancel(tp); /* * See if the caller is relying on us to shut down the @@ -1111,3 +1111,10 @@ xfs_trans_roll( tres.tr_logflags = XFS_TRANS_PERM_LOG_RES; return xfs_trans_reserve(*tpp, &tres, 0, 0); } + +void +xfs_defer_cancel( + struct xfs_trans *tp) +{ + __xfs_defer_cancel(tp->t_dfops); +} diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index dc79e3c1d3e8..5170e89bec02 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -214,6 +214,9 @@ xfs_trans_read_buf( flags, bpp, ops); } +/* cancel dfops associated with a transaction */ +void xfs_defer_cancel(struct xfs_trans *); + struct xfs_buf *xfs_trans_getsb(xfs_trans_t *, struct xfs_mount *, int); void xfs_trans_brelse(xfs_trans_t *, struct xfs_buf *); -- cgit v1.2.3 From b277c37f43dd387f7430a2186deda0e58c943087 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Tue, 24 Jul 2018 13:43:15 -0700 Subject: xfs: bypass final dfops roll in trans commit path Once xfs_defer_finish() has completed all deferred operations, it checks the dirty state of the transaction and rolls it once more to return a clean transaction for the caller. This primarily to cover the case where repeated xfs_defer_finish() calls are made in a loop and we need to make sure that the caller starts the next iteration with a clean transaction. Otherwise we risk transaction reservation overrun. This final transaction roll is not required in the transaction commit path, however, because the transaction is immediately committed and freed after dfops completion. Refactor the final roll into a separate helper such that we can avoid it in the transaction commit path. Lift the dfops reset as well so dfops remains valid until after the last call to xfs_defer_trans_roll(). The reset is also unnecessary in the transaction commit path because the transaction is about to complete. This eliminates unnecessary regrants of transactions where the associated transaction roll can be replaced by a transaction commit. Signed-off-by: Brian Foster Reviewed-by: Bill O'Donnell Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_defer.c | 38 +++++++++++++++++++++++++------------- fs/xfs/libxfs/xfs_defer.h | 1 + fs/xfs/xfs_trans.c | 2 +- 3 files changed, 27 insertions(+), 14 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index cbee0a86c978..a5f7dc18a62f 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -341,7 +341,7 @@ xfs_defer_reset( * If an inode is provided, relog it to the new transaction. */ int -xfs_defer_finish( +xfs_defer_finish_noroll( struct xfs_trans **tp) { struct xfs_defer_ops *dop = (*tp)->t_dfops; @@ -430,25 +430,37 @@ xfs_defer_finish( cleanup_fn(*tp, state, error); } - /* - * Roll the transaction once more to avoid returning to the caller - * with a dirty transaction. - */ - if ((*tp)->t_flags & XFS_TRANS_DIRTY) { - error = xfs_defer_trans_roll(tp); - dop = (*tp)->t_dfops; - } out: - if (error) { + if (error) trace_xfs_defer_finish_error((*tp)->t_mountp, dop, error); - } else { + else trace_xfs_defer_finish_done((*tp)->t_mountp, dop, _RET_IP_); - xfs_defer_reset(dop); - } return error; } +int +xfs_defer_finish( + struct xfs_trans **tp) +{ + int error; + + /* + * Finish and roll the transaction once more to avoid returning to the + * caller with a dirty transaction. + */ + error = xfs_defer_finish_noroll(tp); + if (error) + return error; + if ((*tp)->t_flags & XFS_TRANS_DIRTY) { + error = xfs_defer_trans_roll(tp); + if (error) + return error; + } + xfs_defer_reset((*tp)->t_dfops); + return 0; +} + /* * Free up any items left in the list. */ diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index 56f927803940..85c41fe4dbae 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h @@ -48,6 +48,7 @@ enum xfs_defer_ops_type { void xfs_defer_add(struct xfs_defer_ops *dop, enum xfs_defer_ops_type type, struct list_head *h); +int xfs_defer_finish_noroll(struct xfs_trans **tp); int xfs_defer_finish(struct xfs_trans **tp); void __xfs_defer_cancel(struct xfs_defer_ops *dop); void xfs_defer_init(struct xfs_trans *tp, struct xfs_defer_ops *dop); diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index cd553aa9ecb0..7bf5c1202719 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -933,7 +933,7 @@ __xfs_trans_commit( /* finish deferred items on final commit */ if (!regrant && tp->t_dfops) { - error = xfs_defer_finish(&tp); + error = xfs_defer_finish_noroll(&tp); if (error) { xfs_defer_cancel(tp); goto out_unreserve; -- cgit v1.2.3 From 89c3e8cf3c266d61347abcc412b9330d81da794b Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 25 Jul 2018 12:51:48 -0700 Subject: xfs: kill IHOLD Nobody uses this macro, get rid of it. Signed-off-by: Darrick J. Wong Reviewed-by: Carlos Maiolino --- fs/xfs/xfs_inode.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index b1f0e8394f3b..c43abf4ea3fc 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -483,13 +483,6 @@ static inline void xfs_setup_existing_inode(struct xfs_inode *ip) xfs_finish_inode_setup(ip); } -#define IHOLD(ip) \ -do { \ - ASSERT(atomic_read(&VFS_I(ip)->i_count) > 0) ; \ - ihold(VFS_I(ip)); \ - trace_xfs_ihold(ip, _THIS_IP_); \ -} while (0) - #define IRELE(ip) \ do { \ trace_xfs_irele(ip, _THIS_IP_); \ -- cgit v1.2.3 From 44a8736bd20a08e1adbf479d11f8198a1243958d Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 25 Jul 2018 12:52:32 -0700 Subject: xfs: clean up IRELE/iput callsites Replace the IRELE macro with a proper function so that we can do proper typechecking and so that we can stop open-coding iput in scrub, which means that we'll be able to ftrace inode lifetimes going through scrub correctly. Signed-off-by: Darrick J. Wong Reviewed-by: Carlos Maiolino Reviewed-by: Brian Foster --- fs/xfs/scrub/common.c | 2 +- fs/xfs/scrub/dir.c | 2 +- fs/xfs/scrub/parent.c | 6 +++--- fs/xfs/scrub/scrub.c | 2 +- fs/xfs/xfs_bmap_item.c | 4 ++-- fs/xfs/xfs_export.c | 2 +- fs/xfs/xfs_filestream.c | 4 ++-- fs/xfs/xfs_icache.c | 4 ++-- fs/xfs/xfs_inode.c | 17 +++++++++++++---- fs/xfs/xfs_inode.h | 6 +----- fs/xfs/xfs_iops.c | 4 ++-- fs/xfs/xfs_itable.c | 2 +- fs/xfs/xfs_log_recover.c | 4 ++-- fs/xfs/xfs_mount.c | 4 ++-- fs/xfs/xfs_qm.c | 22 +++++++++++----------- fs/xfs/xfs_qm_syscalls.c | 8 ++++---- fs/xfs/xfs_quotaops.c | 2 +- fs/xfs/xfs_rtalloc.c | 6 +++--- fs/xfs/xfs_symlink.c | 2 +- 19 files changed, 54 insertions(+), 49 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index baac08304a5a..346b02abccf7 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -711,7 +711,7 @@ xchk_get_inode( return error; } if (VFS_I(ip)->i_generation != sc->sm->sm_gen) { - iput(VFS_I(ip)); + xfs_irele(ip); return -ENOENT; } diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c index f58709052b03..cd3e4d768a18 100644 --- a/fs/xfs/scrub/dir.c +++ b/fs/xfs/scrub/dir.c @@ -87,7 +87,7 @@ xchk_dir_check_ftype( xfs_mode_to_ftype(VFS_I(ip)->i_mode)); if (ino_dtype != dtype) xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, offset); - iput(VFS_I(ip)); + xfs_irele(ip); out: return error; } diff --git a/fs/xfs/scrub/parent.c b/fs/xfs/scrub/parent.c index aacb0284c48a..1c9d7c7f64f5 100644 --- a/fs/xfs/scrub/parent.c +++ b/fs/xfs/scrub/parent.c @@ -230,11 +230,11 @@ xchk_parent_validate( /* Drat, parent changed. Try again! */ if (dnum != dp->i_ino) { - iput(VFS_I(dp)); + xfs_irele(dp); *try_again = true; return 0; } - iput(VFS_I(dp)); + xfs_irele(dp); /* * '..' didn't change, so check that there was only one entry @@ -247,7 +247,7 @@ xchk_parent_validate( out_unlock: xfs_iunlock(dp, XFS_IOLOCK_SHARED); out_rele: - iput(VFS_I(dp)); + xfs_irele(dp); out: return error; } diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c index 5956b8073e2f..6efb926f3cf8 100644 --- a/fs/xfs/scrub/scrub.c +++ b/fs/xfs/scrub/scrub.c @@ -183,7 +183,7 @@ xchk_teardown( xfs_iunlock(sc->ip, sc->ilock_flags); if (sc->ip != ip_in && !xfs_internal_inum(sc->mp, sc->ip->i_ino)) - iput(VFS_I(sc->ip)); + xfs_irele(sc->ip); sc->ip = NULL; } if (sc->has_quotaofflock) diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c index bc5eb2e0ab0c..e1d6c127b07d 100644 --- a/fs/xfs/xfs_bmap_item.c +++ b/fs/xfs/xfs_bmap_item.c @@ -497,7 +497,7 @@ xfs_bui_recover( xfs_defer_move(dfops, tp->t_dfops); error = xfs_trans_commit(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); - IRELE(ip); + xfs_irele(ip); return error; @@ -506,7 +506,7 @@ err_inode: xfs_trans_cancel(tp); if (ip) { xfs_iunlock(ip, XFS_ILOCK_EXCL); - IRELE(ip); + xfs_irele(ip); } return error; } diff --git a/fs/xfs/xfs_export.c b/fs/xfs/xfs_export.c index 3cf4682e2510..f2284ceb129f 100644 --- a/fs/xfs/xfs_export.c +++ b/fs/xfs/xfs_export.c @@ -150,7 +150,7 @@ xfs_nfs_get_inode( } if (VFS_I(ip)->i_generation != generation) { - IRELE(ip); + xfs_irele(ip); return ERR_PTR(-ESTALE); } diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index 56a3999cefae..212173c62588 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -340,7 +340,7 @@ xfs_filestream_lookup_ag( if (xfs_filestream_pick_ag(pip, startag, &ag, 0, 0)) ag = NULLAGNUMBER; out: - IRELE(pip); + xfs_irele(pip); return ag; } @@ -389,7 +389,7 @@ xfs_filestream_new_ag( if (mru) xfs_fstrm_free_func(mp, mru); - IRELE(pip); + xfs_irele(pip); exit: if (*agp == NULLAGNUMBER) *agp = 0; diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 47f417d20a30..8de94ecd73ae 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -716,7 +716,7 @@ xfs_icache_inode_is_allocated( return error; *inuse = !!(VFS_I(ip)->i_mode); - IRELE(ip); + xfs_irele(ip); return 0; } @@ -856,7 +856,7 @@ restart: xfs_iflags_test(batch[i], XFS_INEW)) xfs_inew_wait(batch[i]); error = execute(batch[i], flags, args); - IRELE(batch[i]); + xfs_irele(batch[i]); if (error == -EAGAIN) { skipped++; continue; diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 0e4bd559a6a7..64c694d2b2a5 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1276,7 +1276,7 @@ xfs_create( */ if (ip) { xfs_finish_inode_setup(ip); - IRELE(ip); + xfs_irele(ip); } xfs_qm_dqrele(udqp); @@ -1371,7 +1371,7 @@ xfs_create_tmpfile( */ if (ip) { xfs_finish_inode_setup(ip); - IRELE(ip); + xfs_irele(ip); } xfs_qm_dqrele(udqp); @@ -3134,14 +3134,14 @@ xfs_rename( error = xfs_finish_rename(tp); if (wip) - IRELE(wip); + xfs_irele(wip); return error; out_trans_cancel: xfs_trans_cancel(tp); out_release_wip: if (wip) - IRELE(wip); + xfs_irele(wip); return error; } @@ -3597,3 +3597,12 @@ xfs_iflush_int( corrupt_out: return -EFSCORRUPTED; } + +/* Release an inode. */ +void +xfs_irele( + struct xfs_inode *ip) +{ + trace_xfs_irele(ip, _RET_IP_); + iput(VFS_I(ip)); +} diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index c43abf4ea3fc..8db34d6f2835 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -483,11 +483,7 @@ static inline void xfs_setup_existing_inode(struct xfs_inode *ip) xfs_finish_inode_setup(ip); } -#define IRELE(ip) \ -do { \ - trace_xfs_irele(ip, _THIS_IP_); \ - iput(VFS_I(ip)); \ -} while (0) +void xfs_irele(struct xfs_inode *ip); extern struct kmem_zone *xfs_inode_zone; diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 2eac22bfad6a..0ef5ad7fb851 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -209,7 +209,7 @@ xfs_generic_create( xfs_finish_inode_setup(ip); if (!tmpfile) xfs_cleanup_inode(dir, inode, dentry); - iput(inode); + xfs_irele(ip); goto out_free_acl; } @@ -391,7 +391,7 @@ xfs_vn_symlink( out_cleanup_inode: xfs_finish_inode_setup(cip); xfs_cleanup_inode(dir, inode, dentry); - iput(inode); + xfs_irele(cip); out: return error; } diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 65810827a8d0..e9508ba01ed1 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -114,7 +114,7 @@ xfs_bulkstat_one_int( break; } xfs_iunlock(ip, XFS_ILOCK_SHARED); - IRELE(ip); + xfs_irele(ip); error = formatter(buffer, ubsize, ubused, buf); if (!error) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 94908a4019e1..7776fde9430c 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -5087,11 +5087,11 @@ xlog_recover_process_one_iunlink( */ ip->i_d.di_dmevmask = 0; - IRELE(ip); + xfs_irele(ip); return agino; fail_iput: - IRELE(ip); + xfs_irele(ip); fail: /* * We can't read in the inode this bucket points to, or this inode diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 4fb361cde32a..8f739e4d0d1c 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -1039,7 +1039,7 @@ xfs_mountfs( out_rtunmount: xfs_rtunmount_inodes(mp); out_rele_rip: - IRELE(rip); + xfs_irele(rip); /* Clean out dquots that might be in memory after quotacheck. */ xfs_qm_unmount(mp); /* @@ -1095,7 +1095,7 @@ xfs_unmountfs( xfs_fs_unreserve_ag_blocks(mp); xfs_qm_unmount_quotas(mp); xfs_rtunmount_inodes(mp); - IRELE(mp->m_rootip); + xfs_irele(mp->m_rootip); /* * We can potentially deadlock here if we have an inode cluster diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 9ceb85cce33a..52ed7904df10 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -231,15 +231,15 @@ xfs_qm_unmount_quotas( */ if (mp->m_quotainfo) { if (mp->m_quotainfo->qi_uquotaip) { - IRELE(mp->m_quotainfo->qi_uquotaip); + xfs_irele(mp->m_quotainfo->qi_uquotaip); mp->m_quotainfo->qi_uquotaip = NULL; } if (mp->m_quotainfo->qi_gquotaip) { - IRELE(mp->m_quotainfo->qi_gquotaip); + xfs_irele(mp->m_quotainfo->qi_gquotaip); mp->m_quotainfo->qi_gquotaip = NULL; } if (mp->m_quotainfo->qi_pquotaip) { - IRELE(mp->m_quotainfo->qi_pquotaip); + xfs_irele(mp->m_quotainfo->qi_pquotaip); mp->m_quotainfo->qi_pquotaip = NULL; } } @@ -1200,12 +1200,12 @@ xfs_qm_dqusage_adjust( goto error0; } - IRELE(ip); + xfs_irele(ip); *res = BULKSTAT_RV_DIDONE; return 0; error0: - IRELE(ip); + xfs_irele(ip); *res = BULKSTAT_RV_GIVEUP; return error; } @@ -1575,11 +1575,11 @@ xfs_qm_init_quotainos( error_rele: if (uip) - IRELE(uip); + xfs_irele(uip); if (gip) - IRELE(gip); + xfs_irele(gip); if (pip) - IRELE(pip); + xfs_irele(pip); return error; } @@ -1588,15 +1588,15 @@ xfs_qm_destroy_quotainos( xfs_quotainfo_t *qi) { if (qi->qi_uquotaip) { - IRELE(qi->qi_uquotaip); + xfs_irele(qi->qi_uquotaip); qi->qi_uquotaip = NULL; /* paranoia */ } if (qi->qi_gquotaip) { - IRELE(qi->qi_gquotaip); + xfs_irele(qi->qi_gquotaip); qi->qi_gquotaip = NULL; } if (qi->qi_pquotaip) { - IRELE(qi->qi_pquotaip); + xfs_irele(qi->qi_pquotaip); qi->qi_pquotaip = NULL; } } diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index c07c5a39d516..b3190890f096 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -190,15 +190,15 @@ xfs_qm_scall_quotaoff( * Release our quotainode references if we don't need them anymore. */ if ((dqtype & XFS_QMOPT_UQUOTA) && q->qi_uquotaip) { - IRELE(q->qi_uquotaip); + xfs_irele(q->qi_uquotaip); q->qi_uquotaip = NULL; } if ((dqtype & XFS_QMOPT_GQUOTA) && q->qi_gquotaip) { - IRELE(q->qi_gquotaip); + xfs_irele(q->qi_gquotaip); q->qi_gquotaip = NULL; } if ((dqtype & XFS_QMOPT_PQUOTA) && q->qi_pquotaip) { - IRELE(q->qi_pquotaip); + xfs_irele(q->qi_pquotaip); q->qi_pquotaip = NULL; } @@ -251,7 +251,7 @@ xfs_qm_scall_trunc_qfile( out_unlock: xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); out_put: - IRELE(ip); + xfs_irele(ip); return error; } diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c index 205fbb2a77e4..a7c0c657dfaf 100644 --- a/fs/xfs/xfs_quotaops.c +++ b/fs/xfs/xfs_quotaops.c @@ -45,7 +45,7 @@ xfs_qm_fill_state( tstate->ino_warnlimit = q->qi_iwarnlimit; tstate->rt_spc_warnlimit = q->qi_rtbwarnlimit; if (tempqip) - IRELE(ip); + xfs_irele(ip); } /* diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 86d7d2f76226..926ed314ffba 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -1207,7 +1207,7 @@ xfs_rtmount_inodes( ASSERT(sbp->sb_rsumino != NULLFSINO); error = xfs_iget(mp, NULL, sbp->sb_rsumino, 0, 0, &mp->m_rsumip); if (error) { - IRELE(mp->m_rbmip); + xfs_irele(mp->m_rbmip); return error; } ASSERT(mp->m_rsumip != NULL); @@ -1219,9 +1219,9 @@ xfs_rtunmount_inodes( struct xfs_mount *mp) { if (mp->m_rbmip) - IRELE(mp->m_rbmip); + xfs_irele(mp->m_rbmip); if (mp->m_rsumip) - IRELE(mp->m_rsumip); + xfs_irele(mp->m_rsumip); } /* diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index ce801aedbcdc..2bfe7fbbedb2 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -364,7 +364,7 @@ out_release_inode: */ if (ip) { xfs_finish_inode_setup(ip); - IRELE(ip); + xfs_irele(ip); } xfs_qm_dqrele(udqp); -- cgit v1.2.3 From 1c02d502c20809a2a5f71ec16a930a61ed779b81 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Thu, 26 Jul 2018 09:11:27 -0700 Subject: xfs: remove deprecated barrier/nobarrier mount The barrier mount options have been no-ops and deprecated since 4cf4573 xfs: deprecate barrier/nobarrier mount option i.e. kernel 4.10 / December 2016, with a stated deprecation schedule after v4.15. Should be fair game to remove them now. Signed-off-by: Eric Sandeen Reviewed-by: Carlos Maiolino Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_mount.h | 1 - fs/xfs/xfs_super.c | 34 ++++------------------------------ 2 files changed, 4 insertions(+), 31 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 540353a51478..7964513c3128 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -217,7 +217,6 @@ typedef struct xfs_mount { #define XFS_MOUNT_SMALL_INUMS (1ULL << 14) /* user wants 32bit inodes */ #define XFS_MOUNT_32BITINODES (1ULL << 15) /* inode32 allocator active */ #define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */ -#define XFS_MOUNT_BARRIER (1ULL << 17) #define XFS_MOUNT_IKEEP (1ULL << 18) /* keep empty inode clusters*/ #define XFS_MOUNT_SWALLOC (1ULL << 19) /* turn on stripe width * allocation */ diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index f9f8dc490d3d..d2ebacd5975c 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -65,11 +65,10 @@ enum { Opt_logbufs, Opt_logbsize, Opt_logdev, Opt_rtdev, Opt_biosize, Opt_wsync, Opt_noalign, Opt_swalloc, Opt_sunit, Opt_swidth, Opt_nouuid, Opt_mtpt, Opt_grpid, Opt_nogrpid, Opt_bsdgroups, Opt_sysvgroups, - Opt_allocsize, Opt_norecovery, Opt_barrier, Opt_nobarrier, - Opt_inode64, Opt_inode32, Opt_ikeep, Opt_noikeep, - Opt_largeio, Opt_nolargeio, Opt_attr2, Opt_noattr2, Opt_filestreams, - Opt_quota, Opt_noquota, Opt_usrquota, Opt_grpquota, Opt_prjquota, - Opt_uquota, Opt_gquota, Opt_pquota, + Opt_allocsize, Opt_norecovery, Opt_inode64, Opt_inode32, Opt_ikeep, + Opt_noikeep, Opt_largeio, Opt_nolargeio, Opt_attr2, Opt_noattr2, + Opt_filestreams, Opt_quota, Opt_noquota, Opt_usrquota, Opt_grpquota, + Opt_prjquota, Opt_uquota, Opt_gquota, Opt_pquota, Opt_uqnoenforce, Opt_gqnoenforce, Opt_pqnoenforce, Opt_qnoenforce, Opt_discard, Opt_nodiscard, Opt_dax, Opt_err, }; @@ -118,14 +117,7 @@ static const match_table_t tokens = { {Opt_qnoenforce, "qnoenforce"}, /* same as uqnoenforce */ {Opt_discard, "discard"}, /* Discard unused blocks */ {Opt_nodiscard, "nodiscard"}, /* Do not discard unused blocks */ - {Opt_dax, "dax"}, /* Enable direct access to bdev pages */ - - /* Deprecated mount options scheduled for removal */ - {Opt_barrier, "barrier"}, /* use writer barriers for log write and - * unwritten extent conversion */ - {Opt_nobarrier, "nobarrier"}, /* .. disable */ - {Opt_err, NULL}, }; @@ -209,7 +201,6 @@ xfs_parseargs( * Set some default flags that could be cleared by the mount option * parsing. */ - mp->m_flags |= XFS_MOUNT_BARRIER; mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; /* @@ -362,14 +353,6 @@ xfs_parseargs( mp->m_flags |= XFS_MOUNT_DAX; break; #endif - case Opt_barrier: - xfs_warn(mp, "%s option is deprecated, ignoring.", p); - mp->m_flags |= XFS_MOUNT_BARRIER; - break; - case Opt_nobarrier: - xfs_warn(mp, "%s option is deprecated, ignoring.", p); - mp->m_flags &= ~XFS_MOUNT_BARRIER; - break; default: xfs_warn(mp, "unknown mount option [%s].", p); return -EINVAL; @@ -487,7 +470,6 @@ xfs_showargs( static struct proc_xfs_info xfs_info_unset[] = { /* the few simple ones we can get from the mount struct */ { XFS_MOUNT_COMPAT_IOSIZE, ",largeio" }, - { XFS_MOUNT_BARRIER, ",nobarrier" }, { XFS_MOUNT_SMALL_INUMS, ",inode64" }, { 0, NULL } }; @@ -1278,14 +1260,6 @@ xfs_fs_remount( token = match_token(p, tokens, args); switch (token) { - case Opt_barrier: - xfs_warn(mp, "%s option is deprecated, ignoring.", p); - mp->m_flags |= XFS_MOUNT_BARRIER; - break; - case Opt_nobarrier: - xfs_warn(mp, "%s option is deprecated, ignoring.", p); - mp->m_flags &= ~XFS_MOUNT_BARRIER; - break; case Opt_inode64: mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS; mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount); -- cgit v1.2.3 From ebcbef3a61a6081ffe20b0b684f18ebbf23f1dfb Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Sun, 29 Jul 2018 22:37:08 -0700 Subject: xfs: pass transaction lock while setting up agresv on cyclic metadata Pass a tranaction pointer through to all helpers that calculate the per-AG block reservation. Online repair will use this to reinitialize per-ag reservations while it still holds all the AG headers locked to the repair transaction. Signed-off-by: Darrick J. Wong Reviewed-by: Brian Foster --- fs/xfs/libxfs/xfs_ag_resv.c | 13 +++++++------ fs/xfs/libxfs/xfs_ag_resv.h | 2 +- fs/xfs/libxfs/xfs_ialloc_btree.c | 10 ++++++---- fs/xfs/libxfs/xfs_ialloc_btree.h | 4 ++-- fs/xfs/libxfs/xfs_refcount_btree.c | 5 +++-- fs/xfs/libxfs/xfs_refcount_btree.h | 3 ++- fs/xfs/libxfs/xfs_rmap_btree.c | 5 +++-- fs/xfs/libxfs/xfs_rmap_btree.h | 2 +- fs/xfs/xfs_fsops.c | 2 +- 9 files changed, 26 insertions(+), 20 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_ag_resv.c b/fs/xfs/libxfs/xfs_ag_resv.c index fecd187fcf2c..e701ebc36c06 100644 --- a/fs/xfs/libxfs/xfs_ag_resv.c +++ b/fs/xfs/libxfs/xfs_ag_resv.c @@ -248,7 +248,8 @@ __xfs_ag_resv_init( /* Create a per-AG block reservation. */ int xfs_ag_resv_init( - struct xfs_perag *pag) + struct xfs_perag *pag, + struct xfs_trans *tp) { struct xfs_mount *mp = pag->pag_mount; xfs_agnumber_t agno = pag->pag_agno; @@ -260,11 +261,11 @@ xfs_ag_resv_init( if (pag->pag_meta_resv.ar_asked == 0) { ask = used = 0; - error = xfs_refcountbt_calc_reserves(mp, agno, &ask, &used); + error = xfs_refcountbt_calc_reserves(mp, tp, agno, &ask, &used); if (error) goto out; - error = xfs_finobt_calc_reserves(mp, agno, &ask, &used); + error = xfs_finobt_calc_reserves(mp, tp, agno, &ask, &used); if (error) goto out; @@ -282,7 +283,7 @@ xfs_ag_resv_init( mp->m_inotbt_nores = true; - error = xfs_refcountbt_calc_reserves(mp, agno, &ask, + error = xfs_refcountbt_calc_reserves(mp, tp, agno, &ask, &used); if (error) goto out; @@ -298,7 +299,7 @@ xfs_ag_resv_init( if (pag->pag_rmapbt_resv.ar_asked == 0) { ask = used = 0; - error = xfs_rmapbt_calc_reserves(mp, agno, &ask, &used); + error = xfs_rmapbt_calc_reserves(mp, tp, agno, &ask, &used); if (error) goto out; @@ -309,7 +310,7 @@ xfs_ag_resv_init( #ifdef DEBUG /* need to read in the AGF for the ASSERT below to work */ - error = xfs_alloc_pagf_init(pag->pag_mount, NULL, pag->pag_agno, 0); + error = xfs_alloc_pagf_init(pag->pag_mount, tp, pag->pag_agno, 0); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_ag_resv.h b/fs/xfs/libxfs/xfs_ag_resv.h index dc953fc84b2f..c0352edc8e41 100644 --- a/fs/xfs/libxfs/xfs_ag_resv.h +++ b/fs/xfs/libxfs/xfs_ag_resv.h @@ -7,7 +7,7 @@ #define __XFS_AG_RESV_H__ int xfs_ag_resv_free(struct xfs_perag *pag); -int xfs_ag_resv_init(struct xfs_perag *pag); +int xfs_ag_resv_init(struct xfs_perag *pag, struct xfs_trans *tp); bool xfs_ag_resv_critical(struct xfs_perag *pag, enum xfs_ag_resv_type type); xfs_extlen_t xfs_ag_resv_needed(struct xfs_perag *pag, diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index 735a33252eb2..86c50208a143 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -552,6 +552,7 @@ xfs_inobt_max_size( static int xfs_inobt_count_blocks( struct xfs_mount *mp, + struct xfs_trans *tp, xfs_agnumber_t agno, xfs_btnum_t btnum, xfs_extlen_t *tree_blocks) @@ -560,14 +561,14 @@ xfs_inobt_count_blocks( struct xfs_btree_cur *cur; int error; - error = xfs_ialloc_read_agi(mp, NULL, agno, &agbp); + error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); if (error) return error; - cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno, btnum); + cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, btnum); error = xfs_btree_count_blocks(cur, tree_blocks); xfs_btree_del_cursor(cur, error); - xfs_buf_relse(agbp); + xfs_trans_brelse(tp, agbp); return error; } @@ -578,6 +579,7 @@ xfs_inobt_count_blocks( int xfs_finobt_calc_reserves( struct xfs_mount *mp, + struct xfs_trans *tp, xfs_agnumber_t agno, xfs_extlen_t *ask, xfs_extlen_t *used) @@ -588,7 +590,7 @@ xfs_finobt_calc_reserves( if (!xfs_sb_version_hasfinobt(&mp->m_sb)) return 0; - error = xfs_inobt_count_blocks(mp, agno, XFS_BTNUM_FINO, &tree_len); + error = xfs_inobt_count_blocks(mp, tp, agno, XFS_BTNUM_FINO, &tree_len); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.h b/fs/xfs/libxfs/xfs_ialloc_btree.h index bf8f0c405e7d..ebdd0c6b8766 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.h +++ b/fs/xfs/libxfs/xfs_ialloc_btree.h @@ -60,8 +60,8 @@ int xfs_inobt_rec_check_count(struct xfs_mount *, #define xfs_inobt_rec_check_count(mp, rec) 0 #endif /* DEBUG */ -int xfs_finobt_calc_reserves(struct xfs_mount *mp, xfs_agnumber_t agno, - xfs_extlen_t *ask, xfs_extlen_t *used); +int xfs_finobt_calc_reserves(struct xfs_mount *mp, struct xfs_trans *tp, + xfs_agnumber_t agno, xfs_extlen_t *ask, xfs_extlen_t *used); extern xfs_extlen_t xfs_iallocbt_calc_size(struct xfs_mount *mp, unsigned long long len); diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index 26d2300ed865..1aaa01c97517 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c @@ -404,6 +404,7 @@ xfs_refcountbt_max_size( int xfs_refcountbt_calc_reserves( struct xfs_mount *mp, + struct xfs_trans *tp, xfs_agnumber_t agno, xfs_extlen_t *ask, xfs_extlen_t *used) @@ -418,14 +419,14 @@ xfs_refcountbt_calc_reserves( return 0; - error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp); + error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp); if (error) return error; agf = XFS_BUF_TO_AGF(agbp); agblocks = be32_to_cpu(agf->agf_length); tree_len = be32_to_cpu(agf->agf_refcount_blocks); - xfs_buf_relse(agbp); + xfs_trans_brelse(tp, agbp); *ask += xfs_refcountbt_max_size(mp, agblocks); *used += tree_len; diff --git a/fs/xfs/libxfs/xfs_refcount_btree.h b/fs/xfs/libxfs/xfs_refcount_btree.h index 801c2c7732fd..ba416f71c824 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.h +++ b/fs/xfs/libxfs/xfs_refcount_btree.h @@ -55,6 +55,7 @@ extern xfs_extlen_t xfs_refcountbt_max_size(struct xfs_mount *mp, xfs_agblock_t agblocks); extern int xfs_refcountbt_calc_reserves(struct xfs_mount *mp, - xfs_agnumber_t agno, xfs_extlen_t *ask, xfs_extlen_t *used); + struct xfs_trans *tp, xfs_agnumber_t agno, xfs_extlen_t *ask, + xfs_extlen_t *used); #endif /* __XFS_REFCOUNT_BTREE_H__ */ diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index 221a88ea60bb..f79cf040d745 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c @@ -554,6 +554,7 @@ xfs_rmapbt_max_size( int xfs_rmapbt_calc_reserves( struct xfs_mount *mp, + struct xfs_trans *tp, xfs_agnumber_t agno, xfs_extlen_t *ask, xfs_extlen_t *used) @@ -567,14 +568,14 @@ xfs_rmapbt_calc_reserves( if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) return 0; - error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp); + error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp); if (error) return error; agf = XFS_BUF_TO_AGF(agbp); agblocks = be32_to_cpu(agf->agf_length); tree_len = be32_to_cpu(agf->agf_rmap_blocks); - xfs_buf_relse(agbp); + xfs_trans_brelse(tp, agbp); /* Reserve 1% of the AG or enough for 1 block per record. */ *ask += max(agblocks / 100, xfs_rmapbt_max_size(mp, agblocks)); diff --git a/fs/xfs/libxfs/xfs_rmap_btree.h b/fs/xfs/libxfs/xfs_rmap_btree.h index 50198b6c3bb2..820d668b063d 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.h +++ b/fs/xfs/libxfs/xfs_rmap_btree.h @@ -51,7 +51,7 @@ extern xfs_extlen_t xfs_rmapbt_calc_size(struct xfs_mount *mp, extern xfs_extlen_t xfs_rmapbt_max_size(struct xfs_mount *mp, xfs_agblock_t agblocks); -extern int xfs_rmapbt_calc_reserves(struct xfs_mount *mp, +extern int xfs_rmapbt_calc_reserves(struct xfs_mount *mp, struct xfs_trans *tp, xfs_agnumber_t agno, xfs_extlen_t *ask, xfs_extlen_t *used); #endif /* __XFS_RMAP_BTREE_H__ */ diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 3f2bd6032cf8..7c00b8bedfe3 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -536,7 +536,7 @@ xfs_fs_reserve_ag_blocks( for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { pag = xfs_perag_get(mp, agno); - err2 = xfs_ag_resv_init(pag); + err2 = xfs_ag_resv_init(pag, NULL); xfs_perag_put(pag); if (err2 && !error) error = err2; -- cgit v1.2.3 From bc270b53e6aa3b9723e26a548fa1a1688ea61361 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Sun, 29 Jul 2018 22:37:09 -0700 Subject: xfs: move the repair extent list into its own file Move the xrep_extent_list code into a separate file. Logically, this data structure is really just a clumsy bitmap, and in the next patch we'll make this more obvious. No functional changes. Signed-off-by: Darrick J. Wong Reviewed-by: Brian Foster --- fs/xfs/Makefile | 1 + fs/xfs/scrub/bitmap.c | 208 ++++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/scrub/bitmap.h | 37 +++++++++ fs/xfs/scrub/repair.c | 194 +--------------------------------------------- fs/xfs/scrub/repair.h | 27 +------ 5 files changed, 248 insertions(+), 219 deletions(-) create mode 100644 fs/xfs/scrub/bitmap.c create mode 100644 fs/xfs/scrub/bitmap.h (limited to 'fs/xfs') diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 2f3f75a7f180..7f96bdadc372 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -158,6 +158,7 @@ xfs-$(CONFIG_XFS_QUOTA) += scrub/quota.o ifeq ($(CONFIG_XFS_ONLINE_REPAIR),y) xfs-y += $(addprefix scrub/, \ agheader_repair.o \ + bitmap.o \ repair.o \ ) endif diff --git a/fs/xfs/scrub/bitmap.c b/fs/xfs/scrub/bitmap.c new file mode 100644 index 000000000000..a7c2f4773f98 --- /dev/null +++ b/fs/xfs/scrub/bitmap.c @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Oracle. All Rights Reserved. + * Author: Darrick J. Wong + */ +#include "xfs.h" +#include "xfs_fs.h" +#include "xfs_shared.h" +#include "xfs_format.h" +#include "xfs_trans_resv.h" +#include "xfs_mount.h" +#include "scrub/xfs_scrub.h" +#include "scrub/scrub.h" +#include "scrub/common.h" +#include "scrub/trace.h" +#include "scrub/repair.h" +#include "scrub/bitmap.h" + +/* Collect a dead btree extent for later disposal. */ +int +xrep_collect_btree_extent( + struct xfs_scrub *sc, + struct xrep_extent_list *exlist, + xfs_fsblock_t fsbno, + xfs_extlen_t len) +{ + struct xrep_extent *rex; + + trace_xrep_collect_btree_extent(sc->mp, + XFS_FSB_TO_AGNO(sc->mp, fsbno), + XFS_FSB_TO_AGBNO(sc->mp, fsbno), len); + + rex = kmem_alloc(sizeof(struct xrep_extent), KM_MAYFAIL); + if (!rex) + return -ENOMEM; + + INIT_LIST_HEAD(&rex->list); + rex->fsbno = fsbno; + rex->len = len; + list_add_tail(&rex->list, &exlist->list); + + return 0; +} + +/* + * An error happened during the rebuild so the transaction will be cancelled. + * The fs will shut down, and the administrator has to unmount and run repair. + * Therefore, free all the memory associated with the list so we can die. + */ +void +xrep_cancel_btree_extents( + struct xfs_scrub *sc, + struct xrep_extent_list *exlist) +{ + struct xrep_extent *rex; + struct xrep_extent *n; + + for_each_xrep_extent_safe(rex, n, exlist) { + list_del(&rex->list); + kmem_free(rex); + } +} + +/* Compare two btree extents. */ +static int +xrep_btree_extent_cmp( + void *priv, + struct list_head *a, + struct list_head *b) +{ + struct xrep_extent *ap; + struct xrep_extent *bp; + + ap = container_of(a, struct xrep_extent, list); + bp = container_of(b, struct xrep_extent, list); + + if (ap->fsbno > bp->fsbno) + return 1; + if (ap->fsbno < bp->fsbno) + return -1; + return 0; +} + +/* + * Remove all the blocks mentioned in @sublist from the extents in @exlist. + * + * The intent is that callers will iterate the rmapbt for all of its records + * for a given owner to generate @exlist; and iterate all the blocks of the + * metadata structures that are not being rebuilt and have the same rmapbt + * owner to generate @sublist. This routine subtracts all the extents + * mentioned in sublist from all the extents linked in @exlist, which leaves + * @exlist as the list of blocks that are not accounted for, which we assume + * are the dead blocks of the old metadata structure. The blocks mentioned in + * @exlist can be reaped. + */ +#define LEFT_ALIGNED (1 << 0) +#define RIGHT_ALIGNED (1 << 1) +int +xrep_subtract_extents( + struct xfs_scrub *sc, + struct xrep_extent_list *exlist, + struct xrep_extent_list *sublist) +{ + struct list_head *lp; + struct xrep_extent *ex; + struct xrep_extent *newex; + struct xrep_extent *subex; + xfs_fsblock_t sub_fsb; + xfs_extlen_t sub_len; + int state; + int error = 0; + + if (list_empty(&exlist->list) || list_empty(&sublist->list)) + return 0; + ASSERT(!list_empty(&sublist->list)); + + list_sort(NULL, &exlist->list, xrep_btree_extent_cmp); + list_sort(NULL, &sublist->list, xrep_btree_extent_cmp); + + /* + * Now that we've sorted both lists, we iterate exlist once, rolling + * forward through sublist and/or exlist as necessary until we find an + * overlap or reach the end of either list. We do not reset lp to the + * head of exlist nor do we reset subex to the head of sublist. The + * list traversal is similar to merge sort, but we're deleting + * instead. In this manner we avoid O(n^2) operations. + */ + subex = list_first_entry(&sublist->list, struct xrep_extent, + list); + lp = exlist->list.next; + while (lp != &exlist->list) { + ex = list_entry(lp, struct xrep_extent, list); + + /* + * Advance subex and/or ex until we find a pair that + * intersect or we run out of extents. + */ + while (subex->fsbno + subex->len <= ex->fsbno) { + if (list_is_last(&subex->list, &sublist->list)) + goto out; + subex = list_next_entry(subex, list); + } + if (subex->fsbno >= ex->fsbno + ex->len) { + lp = lp->next; + continue; + } + + /* trim subex to fit the extent we have */ + sub_fsb = subex->fsbno; + sub_len = subex->len; + if (subex->fsbno < ex->fsbno) { + sub_len -= ex->fsbno - subex->fsbno; + sub_fsb = ex->fsbno; + } + if (sub_len > ex->len) + sub_len = ex->len; + + state = 0; + if (sub_fsb == ex->fsbno) + state |= LEFT_ALIGNED; + if (sub_fsb + sub_len == ex->fsbno + ex->len) + state |= RIGHT_ALIGNED; + switch (state) { + case LEFT_ALIGNED: + /* Coincides with only the left. */ + ex->fsbno += sub_len; + ex->len -= sub_len; + break; + case RIGHT_ALIGNED: + /* Coincides with only the right. */ + ex->len -= sub_len; + lp = lp->next; + break; + case LEFT_ALIGNED | RIGHT_ALIGNED: + /* Total overlap, just delete ex. */ + lp = lp->next; + list_del(&ex->list); + kmem_free(ex); + break; + case 0: + /* + * Deleting from the middle: add the new right extent + * and then shrink the left extent. + */ + newex = kmem_alloc(sizeof(struct xrep_extent), + KM_MAYFAIL); + if (!newex) { + error = -ENOMEM; + goto out; + } + INIT_LIST_HEAD(&newex->list); + newex->fsbno = sub_fsb + sub_len; + newex->len = ex->fsbno + ex->len - newex->fsbno; + list_add(&newex->list, &ex->list); + ex->len = sub_fsb - ex->fsbno; + lp = lp->next; + break; + default: + ASSERT(0); + break; + } + } + +out: + return error; +} +#undef LEFT_ALIGNED +#undef RIGHT_ALIGNED diff --git a/fs/xfs/scrub/bitmap.h b/fs/xfs/scrub/bitmap.h new file mode 100644 index 000000000000..1038157695a8 --- /dev/null +++ b/fs/xfs/scrub/bitmap.h @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Oracle. All Rights Reserved. + * Author: Darrick J. Wong + */ +#ifndef __XFS_SCRUB_BITMAP_H__ +#define __XFS_SCRUB_BITMAP_H__ + +struct xrep_extent { + struct list_head list; + xfs_fsblock_t fsbno; + xfs_extlen_t len; +}; + +struct xrep_extent_list { + struct list_head list; +}; + +static inline void +xrep_init_extent_list( + struct xrep_extent_list *exlist) +{ + INIT_LIST_HEAD(&exlist->list); +} + +#define for_each_xrep_extent_safe(rbe, n, exlist) \ + list_for_each_entry_safe((rbe), (n), &(exlist)->list, list) +int xrep_collect_btree_extent(struct xfs_scrub *sc, + struct xrep_extent_list *btlist, xfs_fsblock_t fsbno, + xfs_extlen_t len); +void xrep_cancel_btree_extents(struct xfs_scrub *sc, + struct xrep_extent_list *btlist); +int xrep_subtract_extents(struct xfs_scrub *sc, + struct xrep_extent_list *exlist, + struct xrep_extent_list *sublist); + +#endif /* __XFS_SCRUB_BITMAP_H__ */ diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 5de1cac424ec..27a904ef6189 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -34,6 +34,7 @@ #include "scrub/common.h" #include "scrub/trace.h" #include "scrub/repair.h" +#include "scrub/bitmap.h" /* * Attempt to repair some metadata, if the metadata is corrupt and userspace @@ -380,200 +381,7 @@ xrep_init_btblock( * sublist. As with the other btrees we subtract sublist from exlist, and the * result (since the rmapbt lives in the free space) are the blocks from the * old rmapbt. - */ - -/* Collect a dead btree extent for later disposal. */ -int -xrep_collect_btree_extent( - struct xfs_scrub *sc, - struct xrep_extent_list *exlist, - xfs_fsblock_t fsbno, - xfs_extlen_t len) -{ - struct xrep_extent *rex; - - trace_xrep_collect_btree_extent(sc->mp, - XFS_FSB_TO_AGNO(sc->mp, fsbno), - XFS_FSB_TO_AGBNO(sc->mp, fsbno), len); - - rex = kmem_alloc(sizeof(struct xrep_extent), KM_MAYFAIL); - if (!rex) - return -ENOMEM; - - INIT_LIST_HEAD(&rex->list); - rex->fsbno = fsbno; - rex->len = len; - list_add_tail(&rex->list, &exlist->list); - - return 0; -} - -/* - * An error happened during the rebuild so the transaction will be cancelled. - * The fs will shut down, and the administrator has to unmount and run repair. - * Therefore, free all the memory associated with the list so we can die. - */ -void -xrep_cancel_btree_extents( - struct xfs_scrub *sc, - struct xrep_extent_list *exlist) -{ - struct xrep_extent *rex; - struct xrep_extent *n; - - for_each_xrep_extent_safe(rex, n, exlist) { - list_del(&rex->list); - kmem_free(rex); - } -} - -/* Compare two btree extents. */ -static int -xrep_btree_extent_cmp( - void *priv, - struct list_head *a, - struct list_head *b) -{ - struct xrep_extent *ap; - struct xrep_extent *bp; - - ap = container_of(a, struct xrep_extent, list); - bp = container_of(b, struct xrep_extent, list); - - if (ap->fsbno > bp->fsbno) - return 1; - if (ap->fsbno < bp->fsbno) - return -1; - return 0; -} - -/* - * Remove all the blocks mentioned in @sublist from the extents in @exlist. * - * The intent is that callers will iterate the rmapbt for all of its records - * for a given owner to generate @exlist; and iterate all the blocks of the - * metadata structures that are not being rebuilt and have the same rmapbt - * owner to generate @sublist. This routine subtracts all the extents - * mentioned in sublist from all the extents linked in @exlist, which leaves - * @exlist as the list of blocks that are not accounted for, which we assume - * are the dead blocks of the old metadata structure. The blocks mentioned in - * @exlist can be reaped. - */ -#define LEFT_ALIGNED (1 << 0) -#define RIGHT_ALIGNED (1 << 1) -int -xrep_subtract_extents( - struct xfs_scrub *sc, - struct xrep_extent_list *exlist, - struct xrep_extent_list *sublist) -{ - struct list_head *lp; - struct xrep_extent *ex; - struct xrep_extent *newex; - struct xrep_extent *subex; - xfs_fsblock_t sub_fsb; - xfs_extlen_t sub_len; - int state; - int error = 0; - - if (list_empty(&exlist->list) || list_empty(&sublist->list)) - return 0; - ASSERT(!list_empty(&sublist->list)); - - list_sort(NULL, &exlist->list, xrep_btree_extent_cmp); - list_sort(NULL, &sublist->list, xrep_btree_extent_cmp); - - /* - * Now that we've sorted both lists, we iterate exlist once, rolling - * forward through sublist and/or exlist as necessary until we find an - * overlap or reach the end of either list. We do not reset lp to the - * head of exlist nor do we reset subex to the head of sublist. The - * list traversal is similar to merge sort, but we're deleting - * instead. In this manner we avoid O(n^2) operations. - */ - subex = list_first_entry(&sublist->list, struct xrep_extent, - list); - lp = exlist->list.next; - while (lp != &exlist->list) { - ex = list_entry(lp, struct xrep_extent, list); - - /* - * Advance subex and/or ex until we find a pair that - * intersect or we run out of extents. - */ - while (subex->fsbno + subex->len <= ex->fsbno) { - if (list_is_last(&subex->list, &sublist->list)) - goto out; - subex = list_next_entry(subex, list); - } - if (subex->fsbno >= ex->fsbno + ex->len) { - lp = lp->next; - continue; - } - - /* trim subex to fit the extent we have */ - sub_fsb = subex->fsbno; - sub_len = subex->len; - if (subex->fsbno < ex->fsbno) { - sub_len -= ex->fsbno - subex->fsbno; - sub_fsb = ex->fsbno; - } - if (sub_len > ex->len) - sub_len = ex->len; - - state = 0; - if (sub_fsb == ex->fsbno) - state |= LEFT_ALIGNED; - if (sub_fsb + sub_len == ex->fsbno + ex->len) - state |= RIGHT_ALIGNED; - switch (state) { - case LEFT_ALIGNED: - /* Coincides with only the left. */ - ex->fsbno += sub_len; - ex->len -= sub_len; - break; - case RIGHT_ALIGNED: - /* Coincides with only the right. */ - ex->len -= sub_len; - lp = lp->next; - break; - case LEFT_ALIGNED | RIGHT_ALIGNED: - /* Total overlap, just delete ex. */ - lp = lp->next; - list_del(&ex->list); - kmem_free(ex); - break; - case 0: - /* - * Deleting from the middle: add the new right extent - * and then shrink the left extent. - */ - newex = kmem_alloc(sizeof(struct xrep_extent), - KM_MAYFAIL); - if (!newex) { - error = -ENOMEM; - goto out; - } - INIT_LIST_HEAD(&newex->list); - newex->fsbno = sub_fsb + sub_len; - newex->len = ex->fsbno + ex->len - newex->fsbno; - list_add(&newex->list, &ex->list); - ex->len = sub_fsb - ex->fsbno; - lp = lp->next; - break; - default: - ASSERT(0); - break; - } - } - -out: - return error; -} -#undef LEFT_ALIGNED -#undef RIGHT_ALIGNED - -/* * Disposal of Blocks from Old per-AG Btrees * * Now that we've constructed a new btree to replace the damaged one, we want diff --git a/fs/xfs/scrub/repair.h b/fs/xfs/scrub/repair.h index 91355f6b0087..a3d491a438f4 100644 --- a/fs/xfs/scrub/repair.h +++ b/fs/xfs/scrub/repair.h @@ -27,33 +27,8 @@ int xrep_init_btblock(struct xfs_scrub *sc, xfs_fsblock_t fsb, struct xfs_buf **bpp, xfs_btnum_t btnum, const struct xfs_buf_ops *ops); -struct xrep_extent { - struct list_head list; - xfs_fsblock_t fsbno; - xfs_extlen_t len; -}; - -struct xrep_extent_list { - struct list_head list; -}; - -static inline void -xrep_init_extent_list( - struct xrep_extent_list *exlist) -{ - INIT_LIST_HEAD(&exlist->list); -} +struct xrep_extent_list; -#define for_each_xrep_extent_safe(rbe, n, exlist) \ - list_for_each_entry_safe((rbe), (n), &(exlist)->list, list) -int xrep_collect_btree_extent(struct xfs_scrub *sc, - struct xrep_extent_list *btlist, xfs_fsblock_t fsbno, - xfs_extlen_t len); -void xrep_cancel_btree_extents(struct xfs_scrub *sc, - struct xrep_extent_list *btlist); -int xrep_subtract_extents(struct xfs_scrub *sc, - struct xrep_extent_list *exlist, - struct xrep_extent_list *sublist); int xrep_fix_freelist(struct xfs_scrub *sc, bool can_shrink); int xrep_invalidate_blocks(struct xfs_scrub *sc, struct xrep_extent_list *btlist); -- cgit v1.2.3 From fcacbc3f511338842dd177e2d53d457f9741543b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 17 Jul 2018 16:51:50 -0700 Subject: xfs: remove if_real_bytes The field is only used for asserts, and to track if we really need to do realloc when growing the inode fork data. But the krealloc function already performs this check internally, so there is no need to keep track of the real allocation size. This will free space in the inode fork for keeping a sequence counter of changes to the extent list. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_inode_fork.c | 19 ++++--------------- fs/xfs/libxfs/xfs_inode_fork.h | 1 - fs/xfs/xfs_inode.c | 3 +-- fs/xfs/xfs_inode_item.c | 4 ---- 4 files changed, 5 insertions(+), 22 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 183ec0cb8921..dee85b0f8846 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -158,7 +158,6 @@ xfs_init_local_fork( } ifp->if_bytes = size; - ifp->if_real_bytes = real_size; ifp->if_flags &= ~(XFS_IFEXTENTS | XFS_IFBROOT); ifp->if_flags |= XFS_IFINLINE; } @@ -226,7 +225,6 @@ xfs_iformat_extents( return -EFSCORRUPTED; } - ifp->if_real_bytes = 0; ifp->if_bytes = 0; ifp->if_u1.if_root = NULL; ifp->if_height = 0; @@ -317,7 +315,6 @@ xfs_iformat_btree( ifp->if_flags &= ~XFS_IFEXTENTS; ifp->if_flags |= XFS_IFBROOT; - ifp->if_real_bytes = 0; ifp->if_bytes = 0; ifp->if_u1.if_root = NULL; ifp->if_height = 0; @@ -501,7 +498,6 @@ xfs_idata_realloc( */ real_size = roundup(new_size, 4); if (ifp->if_u1.if_data == NULL) { - ASSERT(ifp->if_real_bytes == 0); ifp->if_u1.if_data = kmem_alloc(real_size, KM_SLEEP | KM_NOFS); } else { @@ -509,15 +505,12 @@ xfs_idata_realloc( * Only do the realloc if the underlying size * is really changing. */ - if (ifp->if_real_bytes != real_size) { - ifp->if_u1.if_data = - kmem_realloc(ifp->if_u1.if_data, - real_size, - KM_SLEEP | KM_NOFS); - } + ifp->if_u1.if_data = + kmem_realloc(ifp->if_u1.if_data, + real_size, + KM_SLEEP | KM_NOFS); } } - ifp->if_real_bytes = real_size; ifp->if_bytes = new_size; ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); } @@ -543,17 +536,13 @@ xfs_idestroy_fork( */ if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { if (ifp->if_u1.if_data != NULL) { - ASSERT(ifp->if_real_bytes != 0); kmem_free(ifp->if_u1.if_data); ifp->if_u1.if_data = NULL; - ifp->if_real_bytes = 0; } } else if ((ifp->if_flags & XFS_IFEXTENTS) && ifp->if_height) { xfs_iext_destroy(ifp); } - ASSERT(ifp->if_real_bytes == 0); - if (whichfork == XFS_ATTR_FORK) { kmem_zone_free(xfs_ifork_zone, ip->i_afp); ip->i_afp = NULL; diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h index 781b1603df5e..46242052aad0 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.h +++ b/fs/xfs/libxfs/xfs_inode_fork.h @@ -14,7 +14,6 @@ struct xfs_dinode; */ typedef struct xfs_ifork { int if_bytes; /* bytes in if_u1 */ - int if_real_bytes; /* bytes allocated in if_u1 */ struct xfs_btree_block *if_broot; /* file's incore btree root */ short if_broot_bytes; /* bytes allocated for root */ unsigned char if_flags; /* per-fork flags */ diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 64c694d2b2a5..54fcfdfc748c 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -927,7 +927,7 @@ xfs_ialloc( case S_IFLNK: ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS; ip->i_df.if_flags = XFS_IFEXTENTS; - ip->i_df.if_bytes = ip->i_df.if_real_bytes = 0; + ip->i_df.if_bytes = 0; ip->i_df.if_u1.if_root = NULL; break; default: @@ -1841,7 +1841,6 @@ xfs_inactive( * to clean up here. */ if (VFS_I(ip)->i_mode == 0) { - ASSERT(ip->i_df.if_real_bytes == 0); ASSERT(ip->i_df.if_broot_bytes == 0); return; } diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 2389c34c172d..fa1c4fe2ffbf 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -194,8 +194,6 @@ xfs_inode_item_format_data_fork( * to be there by xfs_idata_realloc(). */ data_bytes = roundup(ip->i_df.if_bytes, 4); - ASSERT(ip->i_df.if_real_bytes == 0 || - ip->i_df.if_real_bytes >= data_bytes); ASSERT(ip->i_df.if_u1.if_data != NULL); ASSERT(ip->i_d.di_size > 0); xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_ILOCAL, @@ -280,8 +278,6 @@ xfs_inode_item_format_attr_fork( * to be there by xfs_idata_realloc(). */ data_bytes = roundup(ip->i_afp->if_bytes, 4); - ASSERT(ip->i_afp->if_real_bytes == 0 || - ip->i_afp->if_real_bytes >= data_bytes); ASSERT(ip->i_afp->if_u1.if_data != NULL); xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_LOCAL, ip->i_afp->if_u1.if_data, -- cgit v1.2.3 From 1216b58b353fbf5529454b442cebb3c8f14d93da Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 17 Jul 2018 16:51:50 -0700 Subject: xfs: simplify xfs_idata_realloc Streamline the code and take advantage of the fact that kmem_realloc through krealloc will be have like a normal allocation if passing in a NULL old pointer. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_inode_fork.c | 55 +++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 36 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index dee85b0f8846..a0e3fb804605 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -468,51 +468,34 @@ xfs_iroot_realloc( */ void xfs_idata_realloc( - xfs_inode_t *ip, - int byte_diff, - int whichfork) + struct xfs_inode *ip, + int byte_diff, + int whichfork) { - xfs_ifork_t *ifp; - int new_size; - int real_size; - - if (byte_diff == 0) { - return; - } + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); + int new_size = (int)ifp->if_bytes + byte_diff; - ifp = XFS_IFORK_PTR(ip, whichfork); - new_size = (int)ifp->if_bytes + byte_diff; ASSERT(new_size >= 0); + ASSERT(new_size <= XFS_IFORK_SIZE(ip, whichfork)); + + if (byte_diff == 0) + return; if (new_size == 0) { kmem_free(ifp->if_u1.if_data); ifp->if_u1.if_data = NULL; - real_size = 0; - } else { - /* - * Stuck with malloc/realloc. - * For inline data, the underlying buffer must be - * a multiple of 4 bytes in size so that it can be - * logged and stay on word boundaries. We enforce - * that here. - */ - real_size = roundup(new_size, 4); - if (ifp->if_u1.if_data == NULL) { - ifp->if_u1.if_data = kmem_alloc(real_size, - KM_SLEEP | KM_NOFS); - } else { - /* - * Only do the realloc if the underlying size - * is really changing. - */ - ifp->if_u1.if_data = - kmem_realloc(ifp->if_u1.if_data, - real_size, - KM_SLEEP | KM_NOFS); - } + ifp->if_bytes = 0; + return; } + + /* + * For inline data, the underlying buffer must be a multiple of 4 bytes + * in size so that it can be logged and stay on word boundaries. + * We enforce that here. + */ + ifp->if_u1.if_data = kmem_realloc(ifp->if_u1.if_data, + roundup(new_size, 4), KM_SLEEP | KM_NOFS); ifp->if_bytes = new_size; - ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); } void -- cgit v1.2.3 From 3ba738df25239f877f6a98ce1cc925fa7e924cd3 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 17 Jul 2018 16:51:50 -0700 Subject: xfs: remove the xfs_ifork_t typedef We only have a few more callers left, so seize the opportunity and kill it off. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr_leaf.c | 6 +++--- fs/xfs/libxfs/xfs_bmap.c | 18 +++++++++--------- fs/xfs/libxfs/xfs_inode_fork.c | 8 ++++---- fs/xfs/libxfs/xfs_inode_fork.h | 4 ++-- fs/xfs/xfs_icache.c | 2 +- fs/xfs/xfs_inode.h | 6 +++--- fs/xfs/xfs_super.c | 2 +- 7 files changed, 23 insertions(+), 23 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index 088ffcd22fa2..4e7ef79a83c7 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -528,7 +528,7 @@ xfs_attr_shortform_create(xfs_da_args_t *args) { xfs_attr_sf_hdr_t *hdr; xfs_inode_t *dp; - xfs_ifork_t *ifp; + struct xfs_ifork *ifp; trace_xfs_attr_sf_create(args); @@ -563,7 +563,7 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff) int i, offset, size; xfs_mount_t *mp; xfs_inode_t *dp; - xfs_ifork_t *ifp; + struct xfs_ifork *ifp; trace_xfs_attr_sf_add(args); @@ -704,7 +704,7 @@ xfs_attr_shortform_lookup(xfs_da_args_t *args) xfs_attr_shortform_t *sf; xfs_attr_sf_entry_t *sfe; int i; - xfs_ifork_t *ifp; + struct xfs_ifork *ifp; trace_xfs_attr_sf_lookup(args); diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 92cd064a2589..a85c0445b38f 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -326,7 +326,7 @@ xfs_bmap_check_leaf_extents( xfs_buf_t *bp; /* buffer for "block" */ int error; /* error return value */ xfs_extnum_t i=0, j; /* index into the extents list */ - xfs_ifork_t *ifp; /* fork structure */ + struct xfs_ifork *ifp; /* fork structure */ int level; /* btree level, for checking */ xfs_mount_t *mp; /* file system mount structure */ __be64 *pp; /* pointer to block address */ @@ -594,7 +594,7 @@ xfs_bmap_btree_to_extents( xfs_fsblock_t cbno; /* child block number */ xfs_buf_t *cbp; /* child block's buffer */ int error; /* error return value */ - xfs_ifork_t *ifp; /* inode fork data */ + struct xfs_ifork *ifp; /* inode fork data */ xfs_mount_t *mp; /* mount point structure */ __be64 *pp; /* ptr to block address */ struct xfs_btree_block *rblock;/* root btree block */ @@ -817,7 +817,7 @@ xfs_bmap_local_to_extents( { int error = 0; int flags; /* logging flags returned */ - xfs_ifork_t *ifp; /* inode fork pointer */ + struct xfs_ifork *ifp; /* inode fork pointer */ xfs_alloc_arg_t args; /* allocation arguments */ xfs_buf_t *bp; /* buffer for extent block */ struct xfs_bmbt_irec rec; @@ -1471,7 +1471,7 @@ xfs_bmap_one_block( xfs_inode_t *ip, /* incore inode */ int whichfork) /* data or attr fork */ { - xfs_ifork_t *ifp; /* inode fork pointer */ + struct xfs_ifork *ifp; /* inode fork pointer */ int rval; /* return value */ xfs_bmbt_irec_t s; /* internal version of extent */ struct xfs_iext_cursor icur; @@ -1509,7 +1509,7 @@ xfs_bmap_add_extent_delay_real( struct xfs_bmbt_irec *new = &bma->got; int error; /* error return value */ int i; /* temp state */ - xfs_ifork_t *ifp; /* inode fork pointer */ + struct xfs_ifork *ifp; /* inode fork pointer */ xfs_fileoff_t new_endoff; /* end offset of new entry */ xfs_bmbt_irec_t r[3]; /* neighbor extent entries */ /* left is 0, right is 1, prev is 2 */ @@ -2018,7 +2018,7 @@ xfs_bmap_add_extent_unwritten_real( xfs_btree_cur_t *cur; /* btree cursor */ int error; /* error return value */ int i; /* temp state */ - xfs_ifork_t *ifp; /* inode fork pointer */ + struct xfs_ifork *ifp; /* inode fork pointer */ xfs_fileoff_t new_endoff; /* end offset of new entry */ xfs_bmbt_irec_t r[3]; /* neighbor extent entries */ /* left is 0, right is 1, prev is 2 */ @@ -2486,7 +2486,7 @@ xfs_bmap_add_extent_hole_delay( struct xfs_iext_cursor *icur, xfs_bmbt_irec_t *new) /* new data to add to file extents */ { - xfs_ifork_t *ifp; /* inode fork pointer */ + struct xfs_ifork *ifp; /* inode fork pointer */ xfs_bmbt_irec_t left; /* left neighbor extent entry */ xfs_filblks_t newlen=0; /* new indirect size */ xfs_filblks_t oldlen=0; /* old indirect size */ @@ -4844,7 +4844,7 @@ xfs_bmap_del_extent_real( struct xfs_bmbt_irec got; /* current extent entry */ xfs_fileoff_t got_endoff; /* first offset past got */ int i; /* temp state */ - xfs_ifork_t *ifp; /* inode fork pointer */ + struct xfs_ifork *ifp; /* inode fork pointer */ xfs_mount_t *mp; /* mount structure */ xfs_filblks_t nblks; /* quota/sb block count */ xfs_bmbt_irec_t new; /* new record to be inserted */ @@ -5092,7 +5092,7 @@ __xfs_bunmapi( int error; /* error return value */ xfs_extnum_t extno; /* extent number in list */ struct xfs_bmbt_irec got; /* current extent record */ - xfs_ifork_t *ifp; /* inode fork pointer */ + struct xfs_ifork *ifp; /* inode fork pointer */ int isrt; /* freeing in rt area */ int logflags; /* transaction logging flags */ xfs_extlen_t mod; /* rt extent offset */ diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index a0e3fb804605..f9acf1d436f6 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -269,7 +269,7 @@ xfs_iformat_btree( { struct xfs_mount *mp = ip->i_mount; xfs_bmdr_block_t *dfp; - xfs_ifork_t *ifp; + struct xfs_ifork *ifp; /* REFERENCED */ int nrecs; int size; @@ -347,7 +347,7 @@ xfs_iroot_realloc( { struct xfs_mount *mp = ip->i_mount; int cur_max; - xfs_ifork_t *ifp; + struct xfs_ifork *ifp; struct xfs_btree_block *new_broot; int new_max; size_t new_size; @@ -503,7 +503,7 @@ xfs_idestroy_fork( xfs_inode_t *ip, int whichfork) { - xfs_ifork_t *ifp; + struct xfs_ifork *ifp; ifp = XFS_IFORK_PTR(ip, whichfork); if (ifp->if_broot != NULL) { @@ -592,7 +592,7 @@ xfs_iflush_fork( int whichfork) { char *cp; - xfs_ifork_t *ifp; + struct xfs_ifork *ifp; xfs_mount_t *mp; static const short brootflag[2] = { XFS_ILOG_DBROOT, XFS_ILOG_ABROOT }; diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h index 46242052aad0..1492143371f3 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.h +++ b/fs/xfs/libxfs/xfs_inode_fork.h @@ -12,7 +12,7 @@ struct xfs_dinode; /* * File incore extent information, present for each of data & attr forks. */ -typedef struct xfs_ifork { +struct xfs_ifork { int if_bytes; /* bytes in if_u1 */ struct xfs_btree_block *if_broot; /* file's incore btree root */ short if_broot_bytes; /* bytes allocated for root */ @@ -22,7 +22,7 @@ typedef struct xfs_ifork { void *if_root; /* extent tree root */ char *if_data; /* inline file data */ } if_u1; -} xfs_ifork_t; +}; /* * Per-fork incore inode flags. diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 8de94ecd73ae..e5591f5ebe15 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -66,7 +66,7 @@ xfs_inode_alloc( ip->i_cowfp = NULL; ip->i_cnextents = 0; ip->i_cformat = XFS_DINODE_FMT_EXTENTS; - memset(&ip->i_df, 0, sizeof(xfs_ifork_t)); + memset(&ip->i_df, 0, sizeof(ip->i_df)); ip->i_flags = 0; ip->i_delayed_blks = 0; memset(&ip->i_d, 0, sizeof(ip->i_d)); diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 8db34d6f2835..a67efdac70a6 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -34,9 +34,9 @@ typedef struct xfs_inode { struct xfs_imap i_imap; /* location for xfs_imap() */ /* Extent information. */ - xfs_ifork_t *i_afp; /* attribute fork pointer */ - xfs_ifork_t *i_cowfp; /* copy on write extents */ - xfs_ifork_t i_df; /* data fork */ + struct xfs_ifork *i_afp; /* attribute fork pointer */ + struct xfs_ifork *i_cowfp; /* copy on write extents */ + struct xfs_ifork i_df; /* data fork */ /* operations vectors */ const struct xfs_dir_ops *d_ops; /* directory ops vector */ diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index d2ebacd5975c..207ee302b1bb 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1860,7 +1860,7 @@ xfs_init_zones(void) if (!xfs_da_state_zone) goto out_destroy_btree_cur_zone; - xfs_ifork_zone = kmem_zone_init(sizeof(xfs_ifork_t), "xfs_ifork"); + xfs_ifork_zone = kmem_zone_init(sizeof(struct xfs_ifork), "xfs_ifork"); if (!xfs_ifork_zone) goto out_destroy_da_state_zone; -- cgit v1.2.3 From 51d626903083f7bd651d38b031775740ed41758c Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 17 Jul 2018 16:51:51 -0700 Subject: xfs: introduce a new xfs_inode_has_cow_data helper We have a few places that already check if an inode has actual data in the COW fork to avoid work on reflink inodes that do not actually have outstanding COW blocks. There are a few more places that can avoid working if doing the same check, so add a documented helper for this condition and use it in all places where it makes sense. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 4 ++-- fs/xfs/xfs_bmap_util.c | 2 +- fs/xfs/xfs_icache.c | 10 ++++------ fs/xfs/xfs_inode.c | 3 +-- fs/xfs/xfs_inode.h | 9 +++++++++ fs/xfs/xfs_reflink.c | 2 +- 6 files changed, 18 insertions(+), 12 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index f4d3252236c1..814100d27343 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -338,7 +338,7 @@ xfs_map_blocks( imap_valid = offset_fsb >= wpc->imap.br_startoff && offset_fsb < wpc->imap.br_startoff + wpc->imap.br_blockcount; if (imap_valid && - (!xfs_is_reflink_inode(ip) || wpc->io_type == XFS_IO_COW)) + (!xfs_inode_has_cow_data(ip) || wpc->io_type == XFS_IO_COW)) return 0; if (XFS_FORCED_SHUTDOWN(mp)) @@ -363,7 +363,7 @@ xfs_map_blocks( * Check if this is offset is covered by a COW extents, and if yes use * it directly instead of looking up anything in the data fork. */ - if (xfs_is_reflink_inode(ip) && + if (xfs_inode_has_cow_data(ip) && xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, &imap) && imap.br_startoff <= offset_fsb) { xfs_iunlock(ip, XFS_ILOCK_SHARED); diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index c32ec17048f5..412dc58ae54d 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1263,7 +1263,7 @@ xfs_prepare_shift( * we've flushed all the dirty data out to disk to avoid having * CoW extents at the wrong offsets. */ - if (xfs_is_reflink_inode(ip)) { + if (xfs_inode_has_cow_data(ip)) { error = xfs_reflink_cancel_cow_range(ip, offset, NULLFILEOFF, true); if (error) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index e5591f5ebe15..245483cc282b 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -1697,14 +1697,13 @@ xfs_inode_clear_eofblocks_tag( */ static bool xfs_prep_free_cowblocks( - struct xfs_inode *ip, - struct xfs_ifork *ifp) + struct xfs_inode *ip) { /* * Just clear the tag if we have an empty cow fork or none at all. It's * possible the inode was fully unshared since it was originally tagged. */ - if (!xfs_is_reflink_inode(ip) || !ifp->if_bytes) { + if (!xfs_inode_has_cow_data(ip)) { trace_xfs_inode_free_cowblocks_invalid(ip); xfs_inode_clear_cowblocks_tag(ip); return false; @@ -1742,11 +1741,10 @@ xfs_inode_free_cowblocks( void *args) { struct xfs_eofblocks *eofb = args; - struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK); int match; int ret = 0; - if (!xfs_prep_free_cowblocks(ip, ifp)) + if (!xfs_prep_free_cowblocks(ip)) return 0; if (eofb) { @@ -1771,7 +1769,7 @@ xfs_inode_free_cowblocks( * Check again, nobody else should be able to dirty blocks or change * the reflink iflag now that we have the first two locks held. */ - if (xfs_prep_free_cowblocks(ip, ifp)) + if (xfs_prep_free_cowblocks(ip)) ret = xfs_reflink_cancel_cow_range(ip, 0, NULLFILEOFF, false); xfs_iunlock(ip, XFS_MMAPLOCK_EXCL); diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 54fcfdfc748c..5fc1815c2b62 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1832,7 +1832,6 @@ xfs_inactive( xfs_inode_t *ip) { struct xfs_mount *mp; - struct xfs_ifork *cow_ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK); int error; int truncate = 0; @@ -1853,7 +1852,7 @@ xfs_inactive( return; /* Try to clean out the cow blocks if there are any. */ - if (xfs_is_reflink_inode(ip) && cow_ifp->if_bytes > 0) + if (xfs_inode_has_cow_data(ip)) xfs_reflink_cancel_cow_range(ip, 0, NULLFILEOFF, true); if (VFS_I(ip)->i_nlink != 0) { diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index a67efdac70a6..79a3e61a6991 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -198,6 +198,15 @@ static inline bool xfs_is_reflink_inode(struct xfs_inode *ip) return ip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK; } +/* + * Check if an inode has any data in the COW fork. This might be often false + * even for inodes with the reflink flag when there is no pending COW operation. + */ +static inline bool xfs_inode_has_cow_data(struct xfs_inode *ip) +{ + return ip->i_cowfp && ip->i_cowfp->if_bytes; +} + /* * In-core inode flags. */ diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 68b6921dc3f6..9a0a56526266 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -478,7 +478,7 @@ xfs_reflink_cancel_cow_blocks( struct xfs_iext_cursor icur; int error = 0; - if (!xfs_is_reflink_inode(ip)) + if (!xfs_inode_has_cow_data(ip)) return 0; if (!xfs_iext_lookup_extent_before(ip, ifp, &end_fsb, &icur, &got)) return 0; -- cgit v1.2.3 From 86d969b425d7ecf774799b70142b957dc267575b Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 30 Jul 2018 11:18:13 -0700 Subject: xfs: refactor the xrep_extent_list into xfs_bitmap As mentioned previously, the xrep_extent_list basically implements a bitmap with two functions: set and disjoint union. Rename all these functions to xfs_bitmap to shorten the name and make it more obvious what we're doing. Signed-off-by: Darrick J. Wong Reviewed-by: Brian Foster --- fs/xfs/scrub/bitmap.c | 183 +++++++++++++++++++++++++------------------------- fs/xfs/scrub/bitmap.h | 35 +++++----- fs/xfs/scrub/repair.c | 85 +++++++++++------------ fs/xfs/scrub/repair.h | 8 +-- fs/xfs/scrub/trace.h | 1 - 5 files changed, 149 insertions(+), 163 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/scrub/bitmap.c b/fs/xfs/scrub/bitmap.c index a7c2f4773f98..c770e2d0b6aa 100644 --- a/fs/xfs/scrub/bitmap.c +++ b/fs/xfs/scrub/bitmap.c @@ -16,183 +16,186 @@ #include "scrub/repair.h" #include "scrub/bitmap.h" -/* Collect a dead btree extent for later disposal. */ +/* + * Set a range of this bitmap. Caller must ensure the range is not set. + * + * This is the logical equivalent of bitmap |= mask(start, len). + */ int -xrep_collect_btree_extent( - struct xfs_scrub *sc, - struct xrep_extent_list *exlist, - xfs_fsblock_t fsbno, - xfs_extlen_t len) +xfs_bitmap_set( + struct xfs_bitmap *bitmap, + uint64_t start, + uint64_t len) { - struct xrep_extent *rex; + struct xfs_bitmap_range *bmr; - trace_xrep_collect_btree_extent(sc->mp, - XFS_FSB_TO_AGNO(sc->mp, fsbno), - XFS_FSB_TO_AGBNO(sc->mp, fsbno), len); - - rex = kmem_alloc(sizeof(struct xrep_extent), KM_MAYFAIL); - if (!rex) + bmr = kmem_alloc(sizeof(struct xfs_bitmap_range), KM_MAYFAIL); + if (!bmr) return -ENOMEM; - INIT_LIST_HEAD(&rex->list); - rex->fsbno = fsbno; - rex->len = len; - list_add_tail(&rex->list, &exlist->list); + INIT_LIST_HEAD(&bmr->list); + bmr->start = start; + bmr->len = len; + list_add_tail(&bmr->list, &bitmap->list); return 0; } -/* - * An error happened during the rebuild so the transaction will be cancelled. - * The fs will shut down, and the administrator has to unmount and run repair. - * Therefore, free all the memory associated with the list so we can die. - */ +/* Free everything related to this bitmap. */ void -xrep_cancel_btree_extents( - struct xfs_scrub *sc, - struct xrep_extent_list *exlist) +xfs_bitmap_destroy( + struct xfs_bitmap *bitmap) { - struct xrep_extent *rex; - struct xrep_extent *n; + struct xfs_bitmap_range *bmr; + struct xfs_bitmap_range *n; - for_each_xrep_extent_safe(rex, n, exlist) { - list_del(&rex->list); - kmem_free(rex); + for_each_xfs_bitmap_extent(bmr, n, bitmap) { + list_del(&bmr->list); + kmem_free(bmr); } } +/* Set up a per-AG block bitmap. */ +void +xfs_bitmap_init( + struct xfs_bitmap *bitmap) +{ + INIT_LIST_HEAD(&bitmap->list); +} + /* Compare two btree extents. */ static int -xrep_btree_extent_cmp( +xfs_bitmap_range_cmp( void *priv, struct list_head *a, struct list_head *b) { - struct xrep_extent *ap; - struct xrep_extent *bp; + struct xfs_bitmap_range *ap; + struct xfs_bitmap_range *bp; - ap = container_of(a, struct xrep_extent, list); - bp = container_of(b, struct xrep_extent, list); + ap = container_of(a, struct xfs_bitmap_range, list); + bp = container_of(b, struct xfs_bitmap_range, list); - if (ap->fsbno > bp->fsbno) + if (ap->start > bp->start) return 1; - if (ap->fsbno < bp->fsbno) + if (ap->start < bp->start) return -1; return 0; } /* - * Remove all the blocks mentioned in @sublist from the extents in @exlist. + * Remove all the blocks mentioned in @sub from the extents in @bitmap. * * The intent is that callers will iterate the rmapbt for all of its records - * for a given owner to generate @exlist; and iterate all the blocks of the + * for a given owner to generate @bitmap; and iterate all the blocks of the * metadata structures that are not being rebuilt and have the same rmapbt - * owner to generate @sublist. This routine subtracts all the extents - * mentioned in sublist from all the extents linked in @exlist, which leaves - * @exlist as the list of blocks that are not accounted for, which we assume + * owner to generate @sub. This routine subtracts all the extents + * mentioned in sub from all the extents linked in @bitmap, which leaves + * @bitmap as the list of blocks that are not accounted for, which we assume * are the dead blocks of the old metadata structure. The blocks mentioned in - * @exlist can be reaped. + * @bitmap can be reaped. + * + * This is the logical equivalent of bitmap &= ~sub. */ #define LEFT_ALIGNED (1 << 0) #define RIGHT_ALIGNED (1 << 1) int -xrep_subtract_extents( - struct xfs_scrub *sc, - struct xrep_extent_list *exlist, - struct xrep_extent_list *sublist) +xfs_bitmap_disunion( + struct xfs_bitmap *bitmap, + struct xfs_bitmap *sub) { struct list_head *lp; - struct xrep_extent *ex; - struct xrep_extent *newex; - struct xrep_extent *subex; - xfs_fsblock_t sub_fsb; - xfs_extlen_t sub_len; + struct xfs_bitmap_range *br; + struct xfs_bitmap_range *new_br; + struct xfs_bitmap_range *sub_br; + uint64_t sub_start; + uint64_t sub_len; int state; int error = 0; - if (list_empty(&exlist->list) || list_empty(&sublist->list)) + if (list_empty(&bitmap->list) || list_empty(&sub->list)) return 0; - ASSERT(!list_empty(&sublist->list)); + ASSERT(!list_empty(&sub->list)); - list_sort(NULL, &exlist->list, xrep_btree_extent_cmp); - list_sort(NULL, &sublist->list, xrep_btree_extent_cmp); + list_sort(NULL, &bitmap->list, xfs_bitmap_range_cmp); + list_sort(NULL, &sub->list, xfs_bitmap_range_cmp); /* - * Now that we've sorted both lists, we iterate exlist once, rolling - * forward through sublist and/or exlist as necessary until we find an + * Now that we've sorted both lists, we iterate bitmap once, rolling + * forward through sub and/or bitmap as necessary until we find an * overlap or reach the end of either list. We do not reset lp to the - * head of exlist nor do we reset subex to the head of sublist. The + * head of bitmap nor do we reset sub_br to the head of sub. The * list traversal is similar to merge sort, but we're deleting * instead. In this manner we avoid O(n^2) operations. */ - subex = list_first_entry(&sublist->list, struct xrep_extent, + sub_br = list_first_entry(&sub->list, struct xfs_bitmap_range, list); - lp = exlist->list.next; - while (lp != &exlist->list) { - ex = list_entry(lp, struct xrep_extent, list); + lp = bitmap->list.next; + while (lp != &bitmap->list) { + br = list_entry(lp, struct xfs_bitmap_range, list); /* - * Advance subex and/or ex until we find a pair that + * Advance sub_br and/or br until we find a pair that * intersect or we run out of extents. */ - while (subex->fsbno + subex->len <= ex->fsbno) { - if (list_is_last(&subex->list, &sublist->list)) + while (sub_br->start + sub_br->len <= br->start) { + if (list_is_last(&sub_br->list, &sub->list)) goto out; - subex = list_next_entry(subex, list); + sub_br = list_next_entry(sub_br, list); } - if (subex->fsbno >= ex->fsbno + ex->len) { + if (sub_br->start >= br->start + br->len) { lp = lp->next; continue; } - /* trim subex to fit the extent we have */ - sub_fsb = subex->fsbno; - sub_len = subex->len; - if (subex->fsbno < ex->fsbno) { - sub_len -= ex->fsbno - subex->fsbno; - sub_fsb = ex->fsbno; + /* trim sub_br to fit the extent we have */ + sub_start = sub_br->start; + sub_len = sub_br->len; + if (sub_br->start < br->start) { + sub_len -= br->start - sub_br->start; + sub_start = br->start; } - if (sub_len > ex->len) - sub_len = ex->len; + if (sub_len > br->len) + sub_len = br->len; state = 0; - if (sub_fsb == ex->fsbno) + if (sub_start == br->start) state |= LEFT_ALIGNED; - if (sub_fsb + sub_len == ex->fsbno + ex->len) + if (sub_start + sub_len == br->start + br->len) state |= RIGHT_ALIGNED; switch (state) { case LEFT_ALIGNED: /* Coincides with only the left. */ - ex->fsbno += sub_len; - ex->len -= sub_len; + br->start += sub_len; + br->len -= sub_len; break; case RIGHT_ALIGNED: /* Coincides with only the right. */ - ex->len -= sub_len; + br->len -= sub_len; lp = lp->next; break; case LEFT_ALIGNED | RIGHT_ALIGNED: /* Total overlap, just delete ex. */ lp = lp->next; - list_del(&ex->list); - kmem_free(ex); + list_del(&br->list); + kmem_free(br); break; case 0: /* * Deleting from the middle: add the new right extent * and then shrink the left extent. */ - newex = kmem_alloc(sizeof(struct xrep_extent), + new_br = kmem_alloc(sizeof(struct xfs_bitmap_range), KM_MAYFAIL); - if (!newex) { + if (!new_br) { error = -ENOMEM; goto out; } - INIT_LIST_HEAD(&newex->list); - newex->fsbno = sub_fsb + sub_len; - newex->len = ex->fsbno + ex->len - newex->fsbno; - list_add(&newex->list, &ex->list); - ex->len = sub_fsb - ex->fsbno; + INIT_LIST_HEAD(&new_br->list); + new_br->start = sub_start + sub_len; + new_br->len = br->start + br->len - new_br->start; + list_add(&new_br->list, &br->list); + br->len = sub_start - br->start; lp = lp->next; break; default: diff --git a/fs/xfs/scrub/bitmap.h b/fs/xfs/scrub/bitmap.h index 1038157695a8..dad652ee9177 100644 --- a/fs/xfs/scrub/bitmap.h +++ b/fs/xfs/scrub/bitmap.h @@ -6,32 +6,27 @@ #ifndef __XFS_SCRUB_BITMAP_H__ #define __XFS_SCRUB_BITMAP_H__ -struct xrep_extent { +struct xfs_bitmap_range { struct list_head list; - xfs_fsblock_t fsbno; - xfs_extlen_t len; + uint64_t start; + uint64_t len; }; -struct xrep_extent_list { +struct xfs_bitmap { struct list_head list; }; -static inline void -xrep_init_extent_list( - struct xrep_extent_list *exlist) -{ - INIT_LIST_HEAD(&exlist->list); -} +void xfs_bitmap_init(struct xfs_bitmap *bitmap); +void xfs_bitmap_destroy(struct xfs_bitmap *bitmap); -#define for_each_xrep_extent_safe(rbe, n, exlist) \ - list_for_each_entry_safe((rbe), (n), &(exlist)->list, list) -int xrep_collect_btree_extent(struct xfs_scrub *sc, - struct xrep_extent_list *btlist, xfs_fsblock_t fsbno, - xfs_extlen_t len); -void xrep_cancel_btree_extents(struct xfs_scrub *sc, - struct xrep_extent_list *btlist); -int xrep_subtract_extents(struct xfs_scrub *sc, - struct xrep_extent_list *exlist, - struct xrep_extent_list *sublist); +#define for_each_xfs_bitmap_extent(bex, n, bitmap) \ + list_for_each_entry_safe((bex), (n), &(bitmap)->list, list) + +#define for_each_xfs_bitmap_block(b, bex, n, bitmap) \ + list_for_each_entry_safe((bex), (n), &(bitmap)->list, list) \ + for ((b) = bex->start; (b) < bex->start + bex->len; (b)++) + +int xfs_bitmap_set(struct xfs_bitmap *bitmap, uint64_t start, uint64_t len); +int xfs_bitmap_disunion(struct xfs_bitmap *bitmap, struct xfs_bitmap *sub); #endif /* __XFS_SCRUB_BITMAP_H__ */ diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 27a904ef6189..85b048b341a0 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -368,17 +368,17 @@ xrep_init_btblock( * * However, that leaves the matter of removing all the metadata describing the * old broken structure. For primary metadata we use the rmap data to collect - * every extent with a matching rmap owner (exlist); we then iterate all other + * every extent with a matching rmap owner (bitmap); we then iterate all other * metadata structures with the same rmap owner to collect the extents that - * cannot be removed (sublist). We then subtract sublist from exlist to + * cannot be removed (sublist). We then subtract sublist from bitmap to * derive the blocks that were used by the old btree. These blocks can be * reaped. * * For rmapbt reconstructions we must use different tactics for extent * collection. First we iterate all primary metadata (this excludes the old * rmapbt, obviously) to generate new rmap records. The gaps in the rmap - * records are collected as exlist. The bnobt records are collected as - * sublist. As with the other btrees we subtract sublist from exlist, and the + * records are collected as bitmap. The bnobt records are collected as + * sublist. As with the other btrees we subtract sublist from bitmap, and the * result (since the rmapbt lives in the free space) are the blocks from the * old rmapbt. * @@ -386,11 +386,11 @@ xrep_init_btblock( * * Now that we've constructed a new btree to replace the damaged one, we want * to dispose of the blocks that (we think) the old btree was using. - * Previously, we used the rmapbt to collect the extents (exlist) with the + * Previously, we used the rmapbt to collect the extents (bitmap) with the * rmap owner corresponding to the tree we rebuilt, collected extents for any * blocks with the same rmap owner that are owned by another data structure - * (sublist), and subtracted sublist from exlist. In theory the extents - * remaining in exlist are the old btree's blocks. + * (sublist), and subtracted sublist from bitmap. In theory the extents + * remaining in bitmap are the old btree's blocks. * * Unfortunately, it's possible that the btree was crosslinked with other * blocks on disk. The rmap data can tell us if there are multiple owners, so @@ -406,7 +406,7 @@ xrep_init_btblock( * If there are no rmap records at all, we also free the block. If the btree * being rebuilt lives in the free space (bnobt/cntbt/rmapbt) then there isn't * supposed to be a rmap record and everything is ok. For other btrees there - * had to have been an rmap entry for the block to have ended up on @exlist, + * had to have been an rmap entry for the block to have ended up on @bitmap, * so if it's gone now there's something wrong and the fs will shut down. * * Note: If there are multiple rmap records with only the same rmap owner as @@ -419,7 +419,7 @@ xrep_init_btblock( * The caller is responsible for locking the AG headers for the entire rebuild * operation so that nothing else can sneak in and change the AG state while * we're not looking. We also assume that the caller already invalidated any - * buffers associated with @exlist. + * buffers associated with @bitmap. */ /* @@ -429,13 +429,12 @@ xrep_init_btblock( int xrep_invalidate_blocks( struct xfs_scrub *sc, - struct xrep_extent_list *exlist) + struct xfs_bitmap *bitmap) { - struct xrep_extent *rex; - struct xrep_extent *n; + struct xfs_bitmap_range *bmr; + struct xfs_bitmap_range *n; struct xfs_buf *bp; xfs_fsblock_t fsbno; - xfs_agblock_t i; /* * For each block in each extent, see if there's an incore buffer for @@ -445,18 +444,16 @@ xrep_invalidate_blocks( * because we never own those; and if we can't TRYLOCK the buffer we * assume it's owned by someone else. */ - for_each_xrep_extent_safe(rex, n, exlist) { - for (fsbno = rex->fsbno, i = rex->len; i > 0; fsbno++, i--) { - /* Skip AG headers and post-EOFS blocks */ - if (!xfs_verify_fsbno(sc->mp, fsbno)) - continue; - bp = xfs_buf_incore(sc->mp->m_ddev_targp, - XFS_FSB_TO_DADDR(sc->mp, fsbno), - XFS_FSB_TO_BB(sc->mp, 1), XBF_TRYLOCK); - if (bp) { - xfs_trans_bjoin(sc->tp, bp); - xfs_trans_binval(sc->tp, bp); - } + for_each_xfs_bitmap_block(fsbno, bmr, n, bitmap) { + /* Skip AG headers and post-EOFS blocks */ + if (!xfs_verify_fsbno(sc->mp, fsbno)) + continue; + bp = xfs_buf_incore(sc->mp->m_ddev_targp, + XFS_FSB_TO_DADDR(sc->mp, fsbno), + XFS_FSB_TO_BB(sc->mp, 1), XBF_TRYLOCK); + if (bp) { + xfs_trans_bjoin(sc->tp, bp); + xfs_trans_binval(sc->tp, bp); } } @@ -519,9 +516,9 @@ xrep_put_freelist( return 0; } -/* Dispose of a single metadata block. */ +/* Dispose of a single block. */ STATIC int -xrep_dispose_btree_block( +xrep_reap_block( struct xfs_scrub *sc, xfs_fsblock_t fsbno, struct xfs_owner_info *oinfo, @@ -593,41 +590,35 @@ out_free: return error; } -/* Dispose of btree blocks from an old per-AG btree. */ +/* Dispose of every block of every extent in the bitmap. */ int -xrep_reap_btree_extents( +xrep_reap_extents( struct xfs_scrub *sc, - struct xrep_extent_list *exlist, + struct xfs_bitmap *bitmap, struct xfs_owner_info *oinfo, enum xfs_ag_resv_type type) { - struct xrep_extent *rex; - struct xrep_extent *n; + struct xfs_bitmap_range *bmr; + struct xfs_bitmap_range *n; + xfs_fsblock_t fsbno; int error = 0; ASSERT(xfs_sb_version_hasrmapbt(&sc->mp->m_sb)); - /* Dispose of every block from the old btree. */ - for_each_xrep_extent_safe(rex, n, exlist) { + for_each_xfs_bitmap_block(fsbno, bmr, n, bitmap) { ASSERT(sc->ip != NULL || - XFS_FSB_TO_AGNO(sc->mp, rex->fsbno) == sc->sa.agno); - + XFS_FSB_TO_AGNO(sc->mp, fsbno) == sc->sa.agno); trace_xrep_dispose_btree_extent(sc->mp, - XFS_FSB_TO_AGNO(sc->mp, rex->fsbno), - XFS_FSB_TO_AGBNO(sc->mp, rex->fsbno), rex->len); + XFS_FSB_TO_AGNO(sc->mp, fsbno), + XFS_FSB_TO_AGBNO(sc->mp, fsbno), 1); - for (; rex->len > 0; rex->len--, rex->fsbno++) { - error = xrep_dispose_btree_block(sc, rex->fsbno, - oinfo, type); - if (error) - goto out; - } - list_del(&rex->list); - kmem_free(rex); + error = xrep_reap_block(sc, fsbno, oinfo, type); + if (error) + goto out; } out: - xrep_cancel_btree_extents(sc, exlist); + xfs_bitmap_destroy(bitmap); return error; } diff --git a/fs/xfs/scrub/repair.h b/fs/xfs/scrub/repair.h index a3d491a438f4..5a4e92221916 100644 --- a/fs/xfs/scrub/repair.h +++ b/fs/xfs/scrub/repair.h @@ -27,13 +27,11 @@ int xrep_init_btblock(struct xfs_scrub *sc, xfs_fsblock_t fsb, struct xfs_buf **bpp, xfs_btnum_t btnum, const struct xfs_buf_ops *ops); -struct xrep_extent_list; +struct xfs_bitmap; int xrep_fix_freelist(struct xfs_scrub *sc, bool can_shrink); -int xrep_invalidate_blocks(struct xfs_scrub *sc, - struct xrep_extent_list *btlist); -int xrep_reap_btree_extents(struct xfs_scrub *sc, - struct xrep_extent_list *exlist, +int xrep_invalidate_blocks(struct xfs_scrub *sc, struct xfs_bitmap *btlist); +int xrep_reap_extents(struct xfs_scrub *sc, struct xfs_bitmap *exlist, struct xfs_owner_info *oinfo, enum xfs_ag_resv_type type); struct xrep_find_ag_btree { diff --git a/fs/xfs/scrub/trace.h b/fs/xfs/scrub/trace.h index 93db22c39b51..4e20f0e48232 100644 --- a/fs/xfs/scrub/trace.h +++ b/fs/xfs/scrub/trace.h @@ -511,7 +511,6 @@ DEFINE_EVENT(xrep_extent_class, name, \ xfs_agblock_t agbno, xfs_extlen_t len), \ TP_ARGS(mp, agno, agbno, len)) DEFINE_REPAIR_EXTENT_EVENT(xrep_dispose_btree_extent); -DEFINE_REPAIR_EXTENT_EVENT(xrep_collect_btree_extent); DEFINE_REPAIR_EXTENT_EVENT(xrep_agfl_insert); DECLARE_EVENT_CLASS(xrep_rmap_class, -- cgit v1.2.3 From eca383fcd63b452cf533505154135da2a1f70227 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Sun, 29 Jul 2018 13:10:44 -0700 Subject: xfs: refactor superblock verifiers Split the superblock verifier into the common checks, the read-time checks, and the write-time check functions. No functional changes, but we're setting up to add more write-only checks. Signed-off-by: Darrick J. Wong Reviewed-by: Eric Sandeen --- fs/xfs/libxfs/xfs_sb.c | 205 ++++++++++++++++++++++++++----------------------- 1 file changed, 111 insertions(+), 94 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index b3ad15956366..f3835e923893 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -96,80 +96,94 @@ xfs_perag_put( trace_xfs_perag_put(pag->pag_mount, pag->pag_agno, ref, _RET_IP_); } -/* - * Check the validity of the SB found. - */ +/* Check all the superblock fields we care about when reading one in. */ STATIC int -xfs_mount_validate_sb( - xfs_mount_t *mp, - xfs_sb_t *sbp, - bool check_inprogress, - bool check_version) +xfs_validate_sb_read( + struct xfs_mount *mp, + struct xfs_sb *sbp) { - uint32_t agcount = 0; - uint32_t rem; - - if (sbp->sb_magicnum != XFS_SB_MAGIC) { - xfs_warn(mp, "bad magic number"); - return -EWRONGFS; - } - - - if (!xfs_sb_good_version(sbp)) { - xfs_warn(mp, "bad version"); - return -EWRONGFS; - } + if (XFS_SB_VERSION_NUM(sbp) != XFS_SB_VERSION_5) + return 0; /* - * Version 5 superblock feature mask validation. Reject combinations the - * kernel cannot support up front before checking anything else. For - * write validation, we don't need to check feature masks. + * Version 5 superblock feature mask validation. Reject combinations + * the kernel cannot support up front before checking anything else. */ - if (check_version && XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) { - if (xfs_sb_has_compat_feature(sbp, - XFS_SB_FEAT_COMPAT_UNKNOWN)) { - xfs_warn(mp, + if (xfs_sb_has_compat_feature(sbp, XFS_SB_FEAT_COMPAT_UNKNOWN)) { + xfs_warn(mp, "Superblock has unknown compatible features (0x%x) enabled.", - (sbp->sb_features_compat & - XFS_SB_FEAT_COMPAT_UNKNOWN)); - xfs_warn(mp, + (sbp->sb_features_compat & XFS_SB_FEAT_COMPAT_UNKNOWN)); + xfs_warn(mp, "Using a more recent kernel is recommended."); - } + } - if (xfs_sb_has_ro_compat_feature(sbp, - XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) { - xfs_alert(mp, + if (xfs_sb_has_ro_compat_feature(sbp, XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) { + xfs_alert(mp, "Superblock has unknown read-only compatible features (0x%x) enabled.", - (sbp->sb_features_ro_compat & - XFS_SB_FEAT_RO_COMPAT_UNKNOWN)); - if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { - xfs_warn(mp, + (sbp->sb_features_ro_compat & + XFS_SB_FEAT_RO_COMPAT_UNKNOWN)); + if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { + xfs_warn(mp, "Attempted to mount read-only compatible filesystem read-write."); - xfs_warn(mp, + xfs_warn(mp, "Filesystem can only be safely mounted read only."); - return -EINVAL; - } - } - if (xfs_sb_has_incompat_feature(sbp, - XFS_SB_FEAT_INCOMPAT_UNKNOWN)) { - xfs_warn(mp, -"Superblock has unknown incompatible features (0x%x) enabled.", - (sbp->sb_features_incompat & - XFS_SB_FEAT_INCOMPAT_UNKNOWN)); - xfs_warn(mp, -"Filesystem can not be safely mounted by this kernel."); return -EINVAL; } - } else if (xfs_sb_version_hascrc(sbp)) { - /* - * We can't read verify the sb LSN because the read verifier is - * called before the log is allocated and processed. We know the - * log is set up before write verifier (!check_version) calls, - * so just check it here. - */ - if (!xfs_log_check_lsn(mp, sbp->sb_lsn)) - return -EFSCORRUPTED; + } + if (xfs_sb_has_incompat_feature(sbp, XFS_SB_FEAT_INCOMPAT_UNKNOWN)) { + xfs_warn(mp, +"Superblock has unknown incompatible features (0x%x) enabled.", + (sbp->sb_features_incompat & + XFS_SB_FEAT_INCOMPAT_UNKNOWN)); + xfs_warn(mp, +"Filesystem cannot be safely mounted by this kernel."); + return -EINVAL; + } + + return 0; +} + +/* Check all the superblock fields we care about when writing one out. */ +STATIC int +xfs_validate_sb_write( + struct xfs_mount *mp, + struct xfs_sb *sbp) +{ + if (XFS_SB_VERSION_NUM(sbp) != XFS_SB_VERSION_5) + return 0; + + /* XXX: For write validation, we don't need to check feature masks?? */ + + /* + * We can't read verify the sb LSN because the read verifier is called + * before the log is allocated and processed. We know the log is set up + * before write verifier calls, so check it here. + */ + if (!xfs_log_check_lsn(mp, sbp->sb_lsn)) + return -EFSCORRUPTED; + + return 0; +} + +/* Check the validity of the SB. */ +STATIC int +xfs_validate_sb_common( + struct xfs_mount *mp, + struct xfs_buf *bp, + struct xfs_sb *sbp) +{ + uint32_t agcount = 0; + uint32_t rem; + + if (sbp->sb_magicnum != XFS_SB_MAGIC) { + xfs_warn(mp, "bad magic number"); + return -EWRONGFS; + } + + if (!xfs_sb_good_version(sbp)) { + xfs_warn(mp, "bad version"); + return -EWRONGFS; } if (xfs_sb_version_has_pquotino(sbp)) { @@ -321,7 +335,12 @@ xfs_mount_validate_sb( return -EFBIG; } - if (check_inprogress && sbp->sb_inprogress) { + /* + * Don't touch the filesystem if a user tool thinks it owns the primary + * superblock. mkfs doesn't clear the flag from secondary supers, so + * we don't check them at all. + */ + if (XFS_BUF_ADDR(bp) == XFS_SB_DADDR && sbp->sb_inprogress) { xfs_warn(mp, "Offline file system operation in progress!"); return -EFSCORRUPTED; } @@ -596,29 +615,6 @@ xfs_sb_to_disk( } } -static int -xfs_sb_verify( - struct xfs_buf *bp, - bool check_version) -{ - struct xfs_mount *mp = bp->b_target->bt_mount; - struct xfs_sb sb; - - /* - * Use call variant which doesn't convert quota flags from disk - * format, because xfs_mount_validate_sb checks the on-disk flags. - */ - __xfs_sb_from_disk(&sb, XFS_BUF_TO_SBP(bp), false); - - /* - * Only check the in progress field for the primary superblock as - * mkfs.xfs doesn't clear it from secondary superblocks. - */ - return xfs_mount_validate_sb(mp, &sb, - bp->b_maps[0].bm_bn == XFS_SB_DADDR, - check_version); -} - /* * If the superblock has the CRC feature bit set or the CRC field is non-null, * check that the CRC is valid. We check the CRC field is non-null because a @@ -633,11 +629,12 @@ xfs_sb_verify( */ static void xfs_sb_read_verify( - struct xfs_buf *bp) + struct xfs_buf *bp) { - struct xfs_mount *mp = bp->b_target->bt_mount; - struct xfs_dsb *dsb = XFS_BUF_TO_SBP(bp); - int error; + struct xfs_sb sb; + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_dsb *dsb = XFS_BUF_TO_SBP(bp); + int error; /* * open code the version check to avoid needing to convert the entire @@ -657,7 +654,16 @@ xfs_sb_read_verify( } } } - error = xfs_sb_verify(bp, true); + + /* + * Check all the superblock fields. Don't byteswap the xquota flags + * because _verify_common checks the on-disk values. + */ + __xfs_sb_from_disk(&sb, XFS_BUF_TO_SBP(bp), false); + error = xfs_validate_sb_common(mp, bp, &sb); + if (error) + goto out_error; + error = xfs_validate_sb_read(mp, &sb); out_error: if (error == -EFSCORRUPTED || error == -EFSBADCRC) @@ -691,15 +697,22 @@ static void xfs_sb_write_verify( struct xfs_buf *bp) { + struct xfs_sb sb; struct xfs_mount *mp = bp->b_target->bt_mount; struct xfs_buf_log_item *bip = bp->b_log_item; int error; - error = xfs_sb_verify(bp, false); - if (error) { - xfs_verifier_error(bp, error, __this_address); - return; - } + /* + * Check all the superblock fields. Don't byteswap the xquota flags + * because _verify_common checks the on-disk values. + */ + __xfs_sb_from_disk(&sb, XFS_BUF_TO_SBP(bp), false); + error = xfs_validate_sb_common(mp, bp, &sb); + if (error) + goto out_error; + error = xfs_validate_sb_write(mp, &sb); + if (error) + goto out_error; if (!xfs_sb_version_hascrc(&mp->m_sb)) return; @@ -708,6 +721,10 @@ xfs_sb_write_verify( XFS_BUF_TO_SBP(bp)->sb_lsn = cpu_to_be64(bip->bli_item.li_lsn); xfs_buf_update_cksum(bp, XFS_SB_CRC_OFF); + return; + +out_error: + xfs_verifier_error(bp, error, __this_address); } const struct xfs_buf_ops xfs_sb_buf_ops = { -- cgit v1.2.3 From 8756a5af18191a471e670cc577aea60b652fea4c Mon Sep 17 00:00:00 2001 From: Bill O'Donnell Date: Thu, 26 Jul 2018 10:10:34 -0700 Subject: libxfs: add more bounds checking to sb sanity checks Current sb verifier doesn't check bounds on sb_fdblocks and sb_ifree. Add sanity checks for these parameters. Signed-off-by: Bill O'Donnell [darrick: port to refactored sb validation predicates] Signed-off-by: Darrick J. Wong Reviewed-by: Eric Sandeen --- fs/xfs/libxfs/xfs_sb.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index f3835e923893..3d29f4a5242f 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -150,6 +150,18 @@ xfs_validate_sb_write( struct xfs_mount *mp, struct xfs_sb *sbp) { + /* + * Carry out additional sb summary counter sanity checks when we write + * the superblock. We skip this in the read validator because there + * could be newer superblocks in the log and if the values are garbage + * we'll recalculate them at the end of log mount. + */ + if (sbp->sb_fdblocks > sbp->sb_dblocks || + sbp->sb_ifree > sbp->sb_icount) { + xfs_warn(mp, "SB summary counter sanity check failed"); + return -EFSCORRUPTED; + } + if (XFS_SB_VERSION_NUM(sbp) != XFS_SB_VERSION_5) return 0; -- cgit v1.2.3 From 69775fd15dc78e0547af45fb3e375d5423cb21b1 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 26 Jul 2018 10:10:42 -0700 Subject: xfs: verify icount in superblock write Add a helper predicate to check the inode count for sanity, then use it in the superblock write verifier to inspect sb_icount. Signed-off-by: Darrick J. Wong Reviewed-by: Bill O'Donnell Reviewed-by: Eric Sandeen --- fs/xfs/libxfs/xfs_sb.c | 3 ++- fs/xfs/libxfs/xfs_types.c | 34 ++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_types.h | 1 + 3 files changed, 37 insertions(+), 1 deletion(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index 3d29f4a5242f..05e7ed1b8022 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -154,9 +154,10 @@ xfs_validate_sb_write( * Carry out additional sb summary counter sanity checks when we write * the superblock. We skip this in the read validator because there * could be newer superblocks in the log and if the values are garbage - * we'll recalculate them at the end of log mount. + * even after replay we'll recalculate them at the end of log mount. */ if (sbp->sb_fdblocks > sbp->sb_dblocks || + !xfs_verify_icount(mp, sbp->sb_icount) || sbp->sb_ifree > sbp->sb_icount) { xfs_warn(mp, "SB summary counter sanity check failed"); return -EFSCORRUPTED; diff --git a/fs/xfs/libxfs/xfs_types.c b/fs/xfs/libxfs/xfs_types.c index 2e2a243cef2e..33a5ca346baf 100644 --- a/fs/xfs/libxfs/xfs_types.c +++ b/fs/xfs/libxfs/xfs_types.c @@ -171,3 +171,37 @@ xfs_verify_rtbno( { return rtbno < mp->m_sb.sb_rblocks; } + +/* Calculate the range of valid icount values. */ +static void +xfs_icount_range( + struct xfs_mount *mp, + unsigned long long *min, + unsigned long long *max) +{ + unsigned long long nr_inos = 0; + xfs_agnumber_t agno; + + /* root, rtbitmap, rtsum all live in the first chunk */ + *min = XFS_INODES_PER_CHUNK; + + for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { + xfs_agino_t first, last; + + xfs_agino_range(mp, agno, &first, &last); + nr_inos += last - first + 1; + } + *max = nr_inos; +} + +/* Sanity-checking of inode counts. */ +bool +xfs_verify_icount( + struct xfs_mount *mp, + unsigned long long icount) +{ + unsigned long long min, max; + + xfs_icount_range(mp, &min, &max); + return icount >= min && icount <= max; +} diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h index 4055d62f690c..b9e6c89284c3 100644 --- a/fs/xfs/libxfs/xfs_types.h +++ b/fs/xfs/libxfs/xfs_types.h @@ -165,5 +165,6 @@ bool xfs_verify_ino(struct xfs_mount *mp, xfs_ino_t ino); bool xfs_internal_inum(struct xfs_mount *mp, xfs_ino_t ino); bool xfs_verify_dir_ino(struct xfs_mount *mp, xfs_ino_t ino); bool xfs_verify_rtbno(struct xfs_mount *mp, xfs_rtblock_t rtbno); +bool xfs_verify_icount(struct xfs_mount *mp, unsigned long long icount); #endif /* __XFS_TYPES_H__ */ -- cgit v1.2.3 From 9e037cb7972fab5a9f55bca4ebe6e4dbf7e160bc Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 30 Jul 2018 16:45:35 -0700 Subject: xfs: check for unknown v5 feature bits in superblock write verifier Make sure we never try to write the superblock with unknown feature bits set. We checked those at mount time, so if they're set now then memory is corrupt. Signed-off-by: Darrick J. Wong Reviewed-by: Eric Sandeen --- fs/xfs/libxfs/xfs_sb.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index 05e7ed1b8022..ca1b3a7a9171 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -166,7 +166,40 @@ xfs_validate_sb_write( if (XFS_SB_VERSION_NUM(sbp) != XFS_SB_VERSION_5) return 0; - /* XXX: For write validation, we don't need to check feature masks?? */ + /* + * Version 5 superblock feature mask validation. Reject combinations + * the kernel cannot support since we checked for unsupported bits in + * the read verifier, which means that memory is corrupt. + */ + if (xfs_sb_has_compat_feature(sbp, XFS_SB_FEAT_COMPAT_UNKNOWN)) { + xfs_warn(mp, +"Corruption detected in superblock compatible features (0x%x)!", + (sbp->sb_features_compat & XFS_SB_FEAT_COMPAT_UNKNOWN)); + return -EFSCORRUPTED; + } + + if (xfs_sb_has_ro_compat_feature(sbp, XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) { + xfs_alert(mp, +"Corruption detected in superblock read-only compatible features (0x%x)!", + (sbp->sb_features_ro_compat & + XFS_SB_FEAT_RO_COMPAT_UNKNOWN)); + return -EFSCORRUPTED; + } + if (xfs_sb_has_incompat_feature(sbp, XFS_SB_FEAT_INCOMPAT_UNKNOWN)) { + xfs_warn(mp, +"Corruption detected in superblock incompatible features (0x%x)!", + (sbp->sb_features_incompat & + XFS_SB_FEAT_INCOMPAT_UNKNOWN)); + return -EFSCORRUPTED; + } + if (xfs_sb_has_incompat_log_feature(sbp, + XFS_SB_FEAT_INCOMPAT_LOG_UNKNOWN)) { + xfs_warn(mp, +"Corruption detected in superblock incompatible log features (0x%x)!", + (sbp->sb_features_log_incompat & + XFS_SB_FEAT_INCOMPAT_LOG_UNKNOWN)); + return -EFSCORRUPTED; + } /* * We can't read verify the sb LSN because the read verifier is called -- cgit v1.2.3 From 745b3f76d1c889d738a1c4537a3c491bc1ecac4d Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 17 Jul 2018 16:51:51 -0700 Subject: xfs: maintain a sequence count for inode fork manipulations Add a simple 32-bit unsigned integer as the sequence count for modifications to the extent list in the inode fork. This will be used to optimize away extent list lookups in the writeback code. Signed-off-by: Christoph Hellwig Reviewed-by: Carlos Maiolino Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_iext_tree.c | 6 ++++++ fs/xfs/libxfs/xfs_inode_fork.h | 1 + 2 files changed, 7 insertions(+) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_iext_tree.c b/fs/xfs/libxfs/xfs_iext_tree.c index b80c63faace2..8a7aea041ee1 100644 --- a/fs/xfs/libxfs/xfs_iext_tree.c +++ b/fs/xfs/libxfs/xfs_iext_tree.c @@ -624,6 +624,8 @@ xfs_iext_insert( struct xfs_iext_leaf *new = NULL; int nr_entries, i; + ifp->if_seq++; + if (ifp->if_height == 0) xfs_iext_alloc_root(ifp, cur); else if (ifp->if_height == 1) @@ -864,6 +866,8 @@ xfs_iext_remove( ASSERT(ifp->if_u1.if_root != NULL); ASSERT(xfs_iext_valid(ifp, cur)); + ifp->if_seq++; + nr_entries = xfs_iext_leaf_nr_entries(ifp, leaf, cur->pos) - 1; for (i = cur->pos; i < nr_entries; i++) leaf->recs[i] = leaf->recs[i + 1]; @@ -970,6 +974,8 @@ xfs_iext_update_extent( { struct xfs_ifork *ifp = xfs_iext_state_to_fork(ip, state); + ifp->if_seq++; + if (cur->pos == 0) { struct xfs_bmbt_irec old; diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h index 1492143371f3..60361d2d74a1 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.h +++ b/fs/xfs/libxfs/xfs_inode_fork.h @@ -14,6 +14,7 @@ struct xfs_dinode; */ struct xfs_ifork { int if_bytes; /* bytes in if_u1 */ + unsigned int if_seq; /* cow fork mod counter */ struct xfs_btree_block *if_broot; /* file's incore btree root */ short if_broot_bytes; /* bytes allocated for root */ unsigned char if_flags; /* per-fork flags */ -- cgit v1.2.3 From e666aa37f4330cb93a5004a89b7a938312e74e36 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 17 Jul 2018 16:51:52 -0700 Subject: xfs: avoid COW fork extent lookups in writeback if the fork didn't change Used the per-fork sequence counter to avoid lookups in the writeback code unless the COW fork actually changed. Signed-off-by: Christoph Hellwig Reviewed-by: Carlos Maiolino Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 38 +++++++++++++++++++++++++++++++++----- fs/xfs/xfs_iomap.c | 5 ++++- fs/xfs/xfs_iomap.h | 2 +- 3 files changed, 38 insertions(+), 7 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 814100d27343..235b4ddcd324 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -29,6 +29,7 @@ struct xfs_writepage_ctx { struct xfs_bmbt_irec imap; unsigned int io_type; + unsigned int cow_seq; struct xfs_ioend *ioend; }; @@ -310,6 +311,7 @@ xfs_map_blocks( struct xfs_mount *mp = ip->i_mount; ssize_t count = i_blocksize(inode); xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset), end_fsb; + xfs_fileoff_t cow_fsb = NULLFILEOFF; struct xfs_bmbt_irec imap; int whichfork = XFS_DATA_FORK; struct xfs_iext_cursor icur; @@ -333,12 +335,23 @@ xfs_map_blocks( * COW fork blocks can overlap data fork blocks even if the blocks * aren't shared. COW I/O always takes precedent, so we must always * check for overlap on reflink inodes unless the mapping is already a - * COW one. + * COW one, or the COW fork hasn't changed from the last time we looked + * at it. + * + * It's safe to check the COW fork if_seq here without the ILOCK because + * we've indirectly protected against concurrent updates: writeback has + * the page locked, which prevents concurrent invalidations by reflink + * and directio and prevents concurrent buffered writes to the same + * page. Changes to if_seq always happen under i_lock, which protects + * against concurrent updates and provides a memory barrier on the way + * out that ensures that we always see the current value. */ imap_valid = offset_fsb >= wpc->imap.br_startoff && offset_fsb < wpc->imap.br_startoff + wpc->imap.br_blockcount; if (imap_valid && - (!xfs_inode_has_cow_data(ip) || wpc->io_type == XFS_IO_COW)) + (!xfs_inode_has_cow_data(ip) || + wpc->io_type == XFS_IO_COW || + wpc->cow_seq == ip->i_cowfp->if_seq)) return 0; if (XFS_FORCED_SHUTDOWN(mp)) @@ -364,8 +377,10 @@ xfs_map_blocks( * it directly instead of looking up anything in the data fork. */ if (xfs_inode_has_cow_data(ip) && - xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, &imap) && - imap.br_startoff <= offset_fsb) { + xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, &imap)) + cow_fsb = imap.br_startoff; + if (cow_fsb != NULLFILEOFF && cow_fsb <= offset_fsb) { + wpc->cow_seq = ip->i_cowfp->if_seq; xfs_iunlock(ip, XFS_ILOCK_SHARED); /* * Truncate can race with writeback since writeback doesn't @@ -411,6 +426,16 @@ xfs_map_blocks( imap.br_startblock = HOLESTARTBLOCK; wpc->io_type = XFS_IO_HOLE; } else { + /* + * Truncate to the next COW extent if there is one. This is the + * only opportunity to do this because we can skip COW fork + * lookups for the subsequent blocks in the mapping; however, + * the requirement to treat the COW range separately remains. + */ + if (cow_fsb != NULLFILEOFF && + cow_fsb < imap.br_startoff + imap.br_blockcount) + imap.br_blockcount = cow_fsb - imap.br_startoff; + if (isnullstartblock(imap.br_startblock)) { /* got a delalloc extent */ wpc->io_type = XFS_IO_DELALLOC; @@ -427,9 +452,12 @@ xfs_map_blocks( trace_xfs_map_blocks_found(ip, offset, count, wpc->io_type, &imap); return 0; allocate_blocks: - error = xfs_iomap_write_allocate(ip, whichfork, offset, &imap); + error = xfs_iomap_write_allocate(ip, whichfork, offset, &imap, + &wpc->cow_seq); if (error) return error; + ASSERT(whichfork == XFS_COW_FORK || cow_fsb == NULLFILEOFF || + imap.br_startoff + imap.br_blockcount <= cow_fsb); wpc->imap = imap; trace_xfs_map_blocks_alloc(ip, offset, count, wpc->io_type, &imap); return 0; diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 8e8ca9f03f0e..3282575e2df4 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -651,7 +651,8 @@ xfs_iomap_write_allocate( xfs_inode_t *ip, int whichfork, xfs_off_t offset, - xfs_bmbt_irec_t *imap) + xfs_bmbt_irec_t *imap, + unsigned int *cow_seq) { xfs_mount_t *mp = ip->i_mount; xfs_fileoff_t offset_fsb, last_block; @@ -766,6 +767,8 @@ xfs_iomap_write_allocate( if (error) goto error0; + if (whichfork == XFS_COW_FORK) + *cow_seq = XFS_IFORK_PTR(ip, whichfork)->if_seq; xfs_iunlock(ip, XFS_ILOCK_EXCL); } diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h index 83474c9cede9..c6170548831b 100644 --- a/fs/xfs/xfs_iomap.h +++ b/fs/xfs/xfs_iomap.h @@ -14,7 +14,7 @@ struct xfs_bmbt_irec; int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t, struct xfs_bmbt_irec *, int); int xfs_iomap_write_allocate(struct xfs_inode *, int, xfs_off_t, - struct xfs_bmbt_irec *); + struct xfs_bmbt_irec *, unsigned int *); int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, xfs_off_t, bool); void xfs_bmbt_to_iomap(struct xfs_inode *, struct iomap *, -- cgit v1.2.3 From ff23f4af7efd86cbb1bda42fe2171e0790f9cb5a Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 31 Jul 2018 13:18:02 -0700 Subject: xfs: move extent busy tree initialization to xfs_initialize_perag Move the per-AG busy extent tree initialization to the per-ag structure initialization since we don't want online repair to leak the old tree. We only deconstruct the tree at unmount time, so this should be safe. This also enables us to eliminate the commented out initialization in the xfsprogs libxfs. Signed-off-by: Darrick J. Wong Reviewed-by: Brian Foster Reviewed-by: Carlos Maiolino Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_alloc.c | 3 --- fs/xfs/xfs_mount.c | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 3c3f2d5119ea..9847c1632712 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -2755,9 +2755,6 @@ xfs_alloc_read_agf( pag->pagf_levels[XFS_BTNUM_RMAPi] = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAPi]); pag->pagf_refcount_level = be32_to_cpu(agf->agf_refcount_level); - spin_lock_init(&pag->pagb_lock); - pag->pagb_count = 0; - pag->pagb_tree = RB_ROOT; pag->pagf_init = 1; pag->pagf_agflreset = xfs_agfl_needs_reset(mp, agf); } diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 8f739e4d0d1c..99db27d6ac8a 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -207,6 +207,9 @@ xfs_initialize_perag( if (xfs_buf_hash_init(pag)) goto out_free_pag; init_waitqueue_head(&pag->pagb_wait); + spin_lock_init(&pag->pagb_lock); + pag->pagb_count = 0; + pag->pagb_tree = RB_ROOT; if (radix_tree_preload(GFP_NOFS)) goto out_hash_destroy; -- cgit v1.2.3 From 0c60d3aa0e2d007e7f79c96c118da25f594afe02 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 1 Aug 2018 07:40:48 -0700 Subject: xfs: refactor log recovery check Add a predicate to decide if the log is actively in recovery and use that instead of open-coding a pagf_init check in the attr leaf verifier. Signed-off-by: Darrick J. Wong Reviewed-by: Brian Foster Reviewed-by: Carlos Maiolino --- fs/xfs/libxfs/xfs_attr_leaf.c | 3 +-- fs/xfs/xfs_log.c | 9 +++++++++ fs/xfs/xfs_log.h | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index 4e7ef79a83c7..6fc5425b1474 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -242,7 +242,6 @@ xfs_attr3_leaf_verify( struct xfs_attr3_icleaf_hdr ichdr; struct xfs_mount *mp = bp->b_target->bt_mount; struct xfs_attr_leafblock *leaf = bp->b_addr; - struct xfs_perag *pag = bp->b_pag; struct xfs_attr_leaf_entry *entries; uint16_t end; int i; @@ -270,7 +269,7 @@ xfs_attr3_leaf_verify( * because we may have transitioned an empty shortform attr to a leaf * if the attr didn't fit in shortform. */ - if (pag && pag->pagf_init && ichdr.count == 0) + if (!xfs_log_in_recovery(mp) && ichdr.count == 0) return __this_address; /* diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index fd10b1426382..00df4f39093a 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -4104,3 +4104,12 @@ xfs_log_check_lsn( return valid; } + +bool +xfs_log_in_recovery( + struct xfs_mount *mp) +{ + struct xlog *log = mp->m_log; + + return log->l_flags & XLOG_ACTIVE_RECOVERY; +} diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h index 3c1f6a8b4b70..73a64bf32f6f 100644 --- a/fs/xfs/xfs_log.h +++ b/fs/xfs/xfs_log.h @@ -153,5 +153,6 @@ bool xfs_log_item_in_current_chkpt(struct xfs_log_item *lip); void xfs_log_work_queue(struct xfs_mount *mp); void xfs_log_quiesce(struct xfs_mount *mp); bool xfs_log_check_lsn(struct xfs_mount *, xfs_lsn_t); +bool xfs_log_in_recovery(struct xfs_mount *); #endif /* __XFS_LOG_H__ */ -- cgit v1.2.3 From 611995db2ce210d20d51c5270639b750476534e5 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 1 Aug 2018 07:40:48 -0700 Subject: xfs: use a local variable for magic number in xfs_da3_node_lookup_int Use a local variable for the block magic number checks instead of abusing blk->magic. Signed-off-by: Darrick J. Wong Reviewed-by: Brian Foster Reviewed-by: Carlos Maiolino --- fs/xfs/libxfs/xfs_da_btree.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index 9efbd2038ffb..8ffe17b223da 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -1481,6 +1481,7 @@ xfs_da3_node_lookup_int( int error; int retval; unsigned int expected_level = 0; + uint16_t magic; struct xfs_inode *dp = state->args->dp; args = state->args; @@ -1505,17 +1506,17 @@ xfs_da3_node_lookup_int( return error; } curr = blk->bp->b_addr; - blk->magic = be16_to_cpu(curr->magic); + magic = be16_to_cpu(curr->magic); - if (blk->magic == XFS_ATTR_LEAF_MAGIC || - blk->magic == XFS_ATTR3_LEAF_MAGIC) { + if (magic == XFS_ATTR_LEAF_MAGIC || + magic == XFS_ATTR3_LEAF_MAGIC) { blk->magic = XFS_ATTR_LEAF_MAGIC; blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL); break; } - if (blk->magic == XFS_DIR2_LEAFN_MAGIC || - blk->magic == XFS_DIR3_LEAFN_MAGIC) { + if (magic == XFS_DIR2_LEAFN_MAGIC || + magic == XFS_DIR3_LEAFN_MAGIC) { blk->magic = XFS_DIR2_LEAFN_MAGIC; blk->hashval = xfs_dir2_leaf_lasthash(args->dp, blk->bp, NULL); -- cgit v1.2.3 From 56830d6cc114f76f656d5e65ab355b070d5a695e Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 1 Aug 2018 07:40:48 -0700 Subject: xfs: check da node magic in _node_lookup_int Before we start processing what we /think/ is a da3 node block, actually check the magic to make sure that we're looking at a node block. This way we won't blow the asserts in _node_hdr_from_disk on corrupted metadata. Signed-off-by: Darrick J. Wong Reviewed-by: Brian Foster Reviewed-by: Carlos Maiolino --- fs/xfs/libxfs/xfs_da_btree.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index 8ffe17b223da..376bee94b5dd 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -1523,8 +1523,10 @@ xfs_da3_node_lookup_int( break; } - blk->magic = XFS_DA_NODE_MAGIC; + if (magic != XFS_DA_NODE_MAGIC && magic != XFS_DA3_NODE_MAGIC) + return -EFSCORRUPTED; + blk->magic = XFS_DA_NODE_MAGIC; /* * Search an intermediate node for a match. -- cgit v1.2.3 From 98719051e75ccf9eca18bd2b569de4ea637b4479 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 1 Aug 2018 07:20:29 -0700 Subject: xfs: refactor internal dfops initialization The current transaction allocation code conditionally initializes the ->t_dfops indirection pointer. Transaction commit/cancel check the validity of the pointer to determine whether to finish/cancel the internal dfops. This disallows the ability to use the internal dfops list as a temporary container (via xfs_trans_alloc_empty()). Refactor transaction allocation to always initialize ->t_dfops and check permanent reservation state on transaction commit/cancel. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_trans.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 7bf5c1202719..12b6ad1558e6 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -281,13 +281,7 @@ xfs_trans_alloc( INIT_LIST_HEAD(&tp->t_items); INIT_LIST_HEAD(&tp->t_busy); tp->t_firstblock = NULLFSBLOCK; - /* - * We only roll transactions with permanent log reservation. Don't init - * ->t_dfops to skip attempts to finish or cancel an empty dfops with a - * non-permanent res. - */ - if (resp->tr_logflags & XFS_TRANS_PERM_LOG_RES) - xfs_defer_init(tp, &tp->t_dfops_internal); + xfs_defer_init(tp, &tp->t_dfops_internal); error = xfs_trans_reserve(tp, resp, blocks, rtextents); if (error) { @@ -931,8 +925,13 @@ __xfs_trans_commit( trace_xfs_trans_commit(tp, _RET_IP_); - /* finish deferred items on final commit */ - if (!regrant && tp->t_dfops) { + /* + * Finish deferred items on final commit. Only permanent transactions + * should ever have deferred ops. + */ + WARN_ON_ONCE(xfs_defer_has_unfinished_work(tp->t_dfops) && + !(tp->t_flags & XFS_TRANS_PERM_LOG_RES)); + if (!regrant && (tp->t_flags & XFS_TRANS_PERM_LOG_RES)) { error = xfs_defer_finish_noroll(&tp); if (error) { xfs_defer_cancel(tp); @@ -1029,7 +1028,7 @@ xfs_trans_cancel( trace_xfs_trans_cancel(tp, _RET_IP_); - if (tp->t_dfops) + if (tp->t_flags & XFS_TRANS_PERM_LOG_RES) xfs_defer_cancel(tp); /* -- cgit v1.2.3 From fbfa977d25dc8db92dbf5fcafb0e03fae0005be5 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 1 Aug 2018 07:20:29 -0700 Subject: xfs: use transaction for intent recovery instead of raw dfops Log intent recovery is the last user of an external (on-stack) dfops. The pattern exists because the dfops is used to collect additional deferred operations queued during the whole recovery sequence. The dfops is finished with a new transaction after intent recovery completes. We already have a mechanism to create an empty, container-like transaction to support the scrub infrastructure. We can reuse that mechanism here to drop the final user of external dfops. This facilitates folding dfops state (i.e., dop_low) into the transaction, the elimination of now unused external dfops support and also eliminates the only caller of __xfs_defer_cancel(). Replace the on-stack dfops with an empty transaction and pass it around to the various helpers that queue and finish deferred operations during intent recovery. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_bmap_item.c | 12 +++++------ fs/xfs/xfs_bmap_item.h | 3 +-- fs/xfs/xfs_log_recover.c | 51 ++++++++++++++++++++++++++-------------------- fs/xfs/xfs_refcount_item.c | 12 +++++------ fs/xfs/xfs_refcount_item.h | 3 +-- 5 files changed, 43 insertions(+), 38 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c index e1d6c127b07d..57429055e608 100644 --- a/fs/xfs/xfs_bmap_item.c +++ b/fs/xfs/xfs_bmap_item.c @@ -375,9 +375,8 @@ xfs_bud_init( */ int xfs_bui_recover( - struct xfs_mount *mp, - struct xfs_bui_log_item *buip, - struct xfs_defer_ops *dfops) + struct xfs_trans *parent_tp, + struct xfs_bui_log_item *buip) { int error = 0; unsigned int bui_type; @@ -393,6 +392,7 @@ xfs_bui_recover( struct xfs_trans *tp; struct xfs_inode *ip = NULL; struct xfs_bmbt_irec irec; + struct xfs_mount *mp = parent_tp->t_mountp; ASSERT(!test_bit(XFS_BUI_RECOVERED, &buip->bui_flags)); @@ -446,7 +446,7 @@ xfs_bui_recover( * finishes them on completion. Transfer current dfops state to this * transaction and transfer the result back before we return. */ - xfs_defer_move(tp->t_dfops, dfops); + xfs_defer_move(tp->t_dfops, parent_tp->t_dfops); budp = xfs_trans_get_bud(tp, buip); /* Grab the inode. */ @@ -494,7 +494,7 @@ xfs_bui_recover( } set_bit(XFS_BUI_RECOVERED, &buip->bui_flags); - xfs_defer_move(dfops, tp->t_dfops); + xfs_defer_move(parent_tp->t_dfops, tp->t_dfops); error = xfs_trans_commit(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); xfs_irele(ip); @@ -502,7 +502,7 @@ xfs_bui_recover( return error; err_inode: - xfs_defer_move(dfops, tp->t_dfops); + xfs_defer_move(parent_tp->t_dfops, tp->t_dfops); xfs_trans_cancel(tp); if (ip) { xfs_iunlock(ip, XFS_ILOCK_EXCL); diff --git a/fs/xfs/xfs_bmap_item.h b/fs/xfs/xfs_bmap_item.h index fd1a1b13df51..89e043a88bb8 100644 --- a/fs/xfs/xfs_bmap_item.h +++ b/fs/xfs/xfs_bmap_item.h @@ -79,7 +79,6 @@ struct xfs_bud_log_item *xfs_bud_init(struct xfs_mount *, struct xfs_bui_log_item *); void xfs_bui_item_free(struct xfs_bui_log_item *); void xfs_bui_release(struct xfs_bui_log_item *); -int xfs_bui_recover(struct xfs_mount *mp, struct xfs_bui_log_item *buip, - struct xfs_defer_ops *dfops); +int xfs_bui_recover(struct xfs_trans *parent_tp, struct xfs_bui_log_item *buip); #endif /* __XFS_BMAP_ITEM_H__ */ diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 7776fde9430c..fc1ce9a644e3 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4733,10 +4733,9 @@ xlog_recover_cancel_rui( /* Recover the CUI if necessary. */ STATIC int xlog_recover_process_cui( - struct xfs_mount *mp, + struct xfs_trans *parent_tp, struct xfs_ail *ailp, - struct xfs_log_item *lip, - struct xfs_defer_ops *dfops) + struct xfs_log_item *lip) { struct xfs_cui_log_item *cuip; int error; @@ -4749,7 +4748,7 @@ xlog_recover_process_cui( return 0; spin_unlock(&ailp->ail_lock); - error = xfs_cui_recover(mp, cuip, dfops); + error = xfs_cui_recover(parent_tp, cuip); spin_lock(&ailp->ail_lock); return error; @@ -4774,10 +4773,9 @@ xlog_recover_cancel_cui( /* Recover the BUI if necessary. */ STATIC int xlog_recover_process_bui( - struct xfs_mount *mp, + struct xfs_trans *parent_tp, struct xfs_ail *ailp, - struct xfs_log_item *lip, - struct xfs_defer_ops *dfops) + struct xfs_log_item *lip) { struct xfs_bui_log_item *buip; int error; @@ -4790,7 +4788,7 @@ xlog_recover_process_bui( return 0; spin_unlock(&ailp->ail_lock); - error = xfs_bui_recover(mp, buip, dfops); + error = xfs_bui_recover(parent_tp, buip); spin_lock(&ailp->ail_lock); return error; @@ -4829,9 +4827,9 @@ static inline bool xlog_item_is_intent(struct xfs_log_item *lip) /* Take all the collected deferred ops and finish them in order. */ static int xlog_finish_defer_ops( - struct xfs_mount *mp, - struct xfs_defer_ops *dfops) + struct xfs_trans *parent_tp) { + struct xfs_mount *mp = parent_tp->t_mountp; struct xfs_trans *tp; int64_t freeblks; uint resblks; @@ -4855,7 +4853,7 @@ xlog_finish_defer_ops( if (error) return error; /* transfer all collected dfops to this transaction */ - xfs_defer_move(tp->t_dfops, dfops); + xfs_defer_move(tp->t_dfops, parent_tp->t_dfops); return xfs_trans_commit(tp); } @@ -4880,22 +4878,34 @@ STATIC int xlog_recover_process_intents( struct xlog *log) { - struct xfs_defer_ops dfops; + struct xfs_trans *parent_tp; struct xfs_ail_cursor cur; struct xfs_log_item *lip; struct xfs_ail *ailp; - int error = 0; + int error; #if defined(DEBUG) || defined(XFS_WARN) xfs_lsn_t last_lsn; #endif + /* + * The intent recovery handlers commit transactions to complete recovery + * for individual intents, but any new deferred operations that are + * queued during that process are held off until the very end. The + * purpose of this transaction is to serve as a container for deferred + * operations. Each intent recovery handler must transfer dfops here + * before its local transaction commits, and we'll finish the entire + * list below. + */ + error = xfs_trans_alloc_empty(log->l_mp, &parent_tp); + if (error) + return error; + ailp = log->l_ailp; spin_lock(&ailp->ail_lock); lip = xfs_trans_ail_cursor_first(ailp, &cur, 0); #if defined(DEBUG) || defined(XFS_WARN) last_lsn = xlog_assign_lsn(log->l_curr_cycle, log->l_curr_block); #endif - xfs_defer_init(NULL, &dfops); while (lip != NULL) { /* * We're done when we see something other than an intent. @@ -4930,12 +4940,10 @@ xlog_recover_process_intents( error = xlog_recover_process_rui(log->l_mp, ailp, lip); break; case XFS_LI_CUI: - error = xlog_recover_process_cui(log->l_mp, ailp, lip, - &dfops); + error = xlog_recover_process_cui(parent_tp, ailp, lip); break; case XFS_LI_BUI: - error = xlog_recover_process_bui(log->l_mp, ailp, lip, - &dfops); + error = xlog_recover_process_bui(parent_tp, ailp, lip); break; } if (error) @@ -4945,10 +4953,9 @@ xlog_recover_process_intents( out: xfs_trans_ail_cursor_done(&cur); spin_unlock(&ailp->ail_lock); - if (error) - __xfs_defer_cancel(&dfops); - else - error = xlog_finish_defer_ops(log->l_mp, &dfops); + if (!error) + error = xlog_finish_defer_ops(parent_tp); + xfs_trans_cancel(parent_tp); return error; } diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c index d3582a06626f..011e1d0640fb 100644 --- a/fs/xfs/xfs_refcount_item.c +++ b/fs/xfs/xfs_refcount_item.c @@ -380,9 +380,8 @@ xfs_cud_init( */ int xfs_cui_recover( - struct xfs_mount *mp, - struct xfs_cui_log_item *cuip, - struct xfs_defer_ops *dfops) + struct xfs_trans *parent_tp, + struct xfs_cui_log_item *cuip) { int i; int error = 0; @@ -398,6 +397,7 @@ xfs_cui_recover( xfs_extlen_t new_len; struct xfs_bmbt_irec irec; bool requeue_only = false; + struct xfs_mount *mp = parent_tp->t_mountp; ASSERT(!test_bit(XFS_CUI_RECOVERED, &cuip->cui_flags)); @@ -457,7 +457,7 @@ xfs_cui_recover( * finishes them on completion. Transfer current dfops state to this * transaction and transfer the result back before we return. */ - xfs_defer_move(tp->t_dfops, dfops); + xfs_defer_move(tp->t_dfops, parent_tp->t_dfops); cudp = xfs_trans_get_cud(tp, cuip); for (i = 0; i < cuip->cui_format.cui_nextents; i++) { @@ -522,13 +522,13 @@ xfs_cui_recover( xfs_refcount_finish_one_cleanup(tp, rcur, error); set_bit(XFS_CUI_RECOVERED, &cuip->cui_flags); - xfs_defer_move(dfops, tp->t_dfops); + xfs_defer_move(parent_tp->t_dfops, tp->t_dfops); error = xfs_trans_commit(tp); return error; abort_error: xfs_refcount_finish_one_cleanup(tp, rcur, error); - xfs_defer_move(dfops, tp->t_dfops); + xfs_defer_move(parent_tp->t_dfops, tp->t_dfops); xfs_trans_cancel(tp); return error; } diff --git a/fs/xfs/xfs_refcount_item.h b/fs/xfs/xfs_refcount_item.h index dd830b69cd1e..3896dcc2368f 100644 --- a/fs/xfs/xfs_refcount_item.h +++ b/fs/xfs/xfs_refcount_item.h @@ -82,7 +82,6 @@ struct xfs_cud_log_item *xfs_cud_init(struct xfs_mount *, struct xfs_cui_log_item *); void xfs_cui_item_free(struct xfs_cui_log_item *); void xfs_cui_release(struct xfs_cui_log_item *); -int xfs_cui_recover(struct xfs_mount *mp, struct xfs_cui_log_item *cuip, - struct xfs_defer_ops *dfops); +int xfs_cui_recover(struct xfs_trans *parent_tp, struct xfs_cui_log_item *cuip); #endif /* __XFS_REFCOUNT_ITEM_H__ */ -- cgit v1.2.3 From 7279aa13b8fb954f50073a672f912898198efd14 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 1 Aug 2018 07:20:30 -0700 Subject: xfs: remove unused __xfs_defer_cancel() internal helper With no more external dfops users, there is no need for an xfs_defer_ops cancel wrapper. Signed-off-by: Brian Foster Reviewed-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_defer.c | 5 +++-- fs/xfs/libxfs/xfs_defer.h | 2 +- fs/xfs/xfs_trans.c | 7 ------- fs/xfs/xfs_trans.h | 3 --- 4 files changed, 4 insertions(+), 13 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index a5f7dc18a62f..ebead781613f 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -465,9 +465,10 @@ xfs_defer_finish( * Free up any items left in the list. */ void -__xfs_defer_cancel( - struct xfs_defer_ops *dop) +xfs_defer_cancel( + struct xfs_trans *tp) { + struct xfs_defer_ops *dop = tp->t_dfops; struct xfs_defer_pending *dfp; struct xfs_defer_pending *pli; struct list_head *pwi; diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index 85c41fe4dbae..da145fc04ae1 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h @@ -50,7 +50,7 @@ void xfs_defer_add(struct xfs_defer_ops *dop, enum xfs_defer_ops_type type, struct list_head *h); int xfs_defer_finish_noroll(struct xfs_trans **tp); int xfs_defer_finish(struct xfs_trans **tp); -void __xfs_defer_cancel(struct xfs_defer_ops *dop); +void xfs_defer_cancel(struct xfs_trans *); void xfs_defer_init(struct xfs_trans *tp, struct xfs_defer_ops *dop); bool xfs_defer_has_unfinished_work(struct xfs_defer_ops *dop); int xfs_defer_ijoin(struct xfs_defer_ops *dop, struct xfs_inode *ip); diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 12b6ad1558e6..0d07cdcc5c7d 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -1110,10 +1110,3 @@ xfs_trans_roll( tres.tr_logflags = XFS_TRANS_PERM_LOG_RES; return xfs_trans_reserve(*tpp, &tres, 0, 0); } - -void -xfs_defer_cancel( - struct xfs_trans *tp) -{ - __xfs_defer_cancel(tp->t_dfops); -} diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 5170e89bec02..dc79e3c1d3e8 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -214,9 +214,6 @@ xfs_trans_read_buf( flags, bpp, ops); } -/* cancel dfops associated with a transaction */ -void xfs_defer_cancel(struct xfs_trans *); - struct xfs_buf *xfs_trans_getsb(xfs_trans_t *, struct xfs_mount *, int); void xfs_trans_brelse(xfs_trans_t *, struct xfs_buf *); -- cgit v1.2.3 From ce356d64772f920f26cd6c1b02878a737a275638 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 1 Aug 2018 07:20:30 -0700 Subject: xfs: pass transaction to dfops reset/move helpers All callers pass ->t_dfops of the associated transactions. Refactor the helpers to receive the transactions and facilitate further cleanups between xfs_defer_ops and xfs_trans. Signed-off-by: Brian Foster Reviewed-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_defer.c | 15 ++++++++++----- fs/xfs/libxfs/xfs_defer.h | 2 +- fs/xfs/xfs_bmap_item.c | 6 +++--- fs/xfs/xfs_log_recover.c | 2 +- fs/xfs/xfs_refcount_item.c | 6 +++--- fs/xfs/xfs_trans.c | 2 +- 6 files changed, 19 insertions(+), 14 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index ebead781613f..e3517a53c525 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -324,9 +324,12 @@ xfs_defer_bjoin( */ static void xfs_defer_reset( - struct xfs_defer_ops *dop) + struct xfs_trans *tp) { + struct xfs_defer_ops *dop = tp->t_dfops; + ASSERT(!xfs_defer_has_unfinished_work(dop)); + dop->dop_low = false; memset(dop->dop_inodes, 0, sizeof(dop->dop_inodes)); memset(dop->dop_bufs, 0, sizeof(dop->dop_bufs)); @@ -457,7 +460,7 @@ xfs_defer_finish( if (error) return error; } - xfs_defer_reset((*tp)->t_dfops); + xfs_defer_reset(*tp); return 0; } @@ -575,9 +578,11 @@ xfs_defer_init( */ void xfs_defer_move( - struct xfs_defer_ops *dst, - struct xfs_defer_ops *src) + struct xfs_trans *dtp, + struct xfs_trans *stp) { + struct xfs_defer_ops *dst = dtp->t_dfops; + struct xfs_defer_ops *src = stp->t_dfops; ASSERT(dst != src); list_splice_init(&src->dop_intake, &dst->dop_intake); @@ -587,5 +592,5 @@ xfs_defer_move( memcpy(dst->dop_bufs, src->dop_bufs, sizeof(dst->dop_bufs)); dst->dop_low = src->dop_low; - xfs_defer_reset(src); + xfs_defer_reset(stp); } diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index da145fc04ae1..d60c50498fdf 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h @@ -55,7 +55,7 @@ void xfs_defer_init(struct xfs_trans *tp, struct xfs_defer_ops *dop); bool xfs_defer_has_unfinished_work(struct xfs_defer_ops *dop); int xfs_defer_ijoin(struct xfs_defer_ops *dop, struct xfs_inode *ip); int xfs_defer_bjoin(struct xfs_defer_ops *dop, struct xfs_buf *bp); -void xfs_defer_move(struct xfs_defer_ops *dst, struct xfs_defer_ops *src); +void xfs_defer_move(struct xfs_trans *dtp, struct xfs_trans *stp); /* Description of a deferred type. */ struct xfs_defer_op_type { diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c index 57429055e608..b8a6be036cd7 100644 --- a/fs/xfs/xfs_bmap_item.c +++ b/fs/xfs/xfs_bmap_item.c @@ -446,7 +446,7 @@ xfs_bui_recover( * finishes them on completion. Transfer current dfops state to this * transaction and transfer the result back before we return. */ - xfs_defer_move(tp->t_dfops, parent_tp->t_dfops); + xfs_defer_move(tp, parent_tp); budp = xfs_trans_get_bud(tp, buip); /* Grab the inode. */ @@ -494,7 +494,7 @@ xfs_bui_recover( } set_bit(XFS_BUI_RECOVERED, &buip->bui_flags); - xfs_defer_move(parent_tp->t_dfops, tp->t_dfops); + xfs_defer_move(parent_tp, tp); error = xfs_trans_commit(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); xfs_irele(ip); @@ -502,7 +502,7 @@ xfs_bui_recover( return error; err_inode: - xfs_defer_move(parent_tp->t_dfops, tp->t_dfops); + xfs_defer_move(parent_tp, tp); xfs_trans_cancel(tp); if (ip) { xfs_iunlock(ip, XFS_ILOCK_EXCL); diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index fc1ce9a644e3..a21dc61ec09e 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4853,7 +4853,7 @@ xlog_finish_defer_ops( if (error) return error; /* transfer all collected dfops to this transaction */ - xfs_defer_move(tp->t_dfops, parent_tp->t_dfops); + xfs_defer_move(tp, parent_tp); return xfs_trans_commit(tp); } diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c index 011e1d0640fb..4a417daae781 100644 --- a/fs/xfs/xfs_refcount_item.c +++ b/fs/xfs/xfs_refcount_item.c @@ -457,7 +457,7 @@ xfs_cui_recover( * finishes them on completion. Transfer current dfops state to this * transaction and transfer the result back before we return. */ - xfs_defer_move(tp->t_dfops, parent_tp->t_dfops); + xfs_defer_move(tp, parent_tp); cudp = xfs_trans_get_cud(tp, cuip); for (i = 0; i < cuip->cui_format.cui_nextents; i++) { @@ -522,13 +522,13 @@ xfs_cui_recover( xfs_refcount_finish_one_cleanup(tp, rcur, error); set_bit(XFS_CUI_RECOVERED, &cuip->cui_flags); - xfs_defer_move(parent_tp->t_dfops, tp->t_dfops); + xfs_defer_move(parent_tp, tp); error = xfs_trans_commit(tp); return error; abort_error: xfs_refcount_finish_one_cleanup(tp, rcur, error); - xfs_defer_move(parent_tp->t_dfops, tp->t_dfops); + xfs_defer_move(parent_tp, tp); xfs_trans_cancel(tp); return error; } diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 0d07cdcc5c7d..ae3c875a14e5 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -125,7 +125,7 @@ xfs_trans_dup( if (tp->t_dfops != &tp->t_dfops_internal) ntp->t_dfops = tp->t_dfops; else - xfs_defer_move(ntp->t_dfops, tp->t_dfops); + xfs_defer_move(ntp, tp); xfs_trans_dup_dqinfo(tp, ntp); -- cgit v1.2.3 From 1214f1cf663b0939fbb8f1bccdc74c1d1e452d53 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 1 Aug 2018 07:20:31 -0700 Subject: xfs: replace dop_low with transaction flag The dop_low field enables the low free space allocation mode when a previous allocation has detected difficulty allocating blocks. It has historically been part of the xfs_defer_ops structure, which means if enabled, it remains enabled across a set of transactions until the deferred operations have completed and the dfops is reset. Now that the dfops is embedded in the transaction, we can save a bit more space by using a transaction flag rather than a standalone boolean. Drop the ->dop_low field and replace it with a transaction flag that is set at the same points, carried across rolling transactions and cleared on completion of deferred operations. This essentially emulates the behavior of ->dop_low and so should not change behavior. Signed-off-by: Brian Foster Reviewed-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 8 ++++---- fs/xfs/libxfs/xfs_bmap_btree.c | 4 ++-- fs/xfs/libxfs/xfs_defer.c | 16 ++++++++++++++-- fs/xfs/libxfs/xfs_defer.h | 11 ----------- fs/xfs/libxfs/xfs_shared.h | 12 ++++++++++++ fs/xfs/xfs_filestream.c | 3 ++- fs/xfs/xfs_trace.h | 10 ++-------- fs/xfs/xfs_trans.h | 2 -- 8 files changed, 36 insertions(+), 30 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index a85c0445b38f..8edf7522aaff 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -700,7 +700,7 @@ xfs_bmap_extents_to_btree( if (tp->t_firstblock == NULLFSBLOCK) { args.type = XFS_ALLOCTYPE_START_BNO; args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); - } else if (tp->t_dfops->dop_low) { + } else if (tp->t_flags & XFS_TRANS_LOWMODE) { args.type = XFS_ALLOCTYPE_START_BNO; args.fsbno = tp->t_firstblock; } else { @@ -3449,7 +3449,7 @@ xfs_bmap_btalloc( error = xfs_bmap_btalloc_nullfb(ap, &args, &blen); if (error) return error; - } else if (ap->tp->t_dfops->dop_low) { + } else if (ap->tp->t_flags & XFS_TRANS_LOWMODE) { if (xfs_inode_is_filestream(ap->ip)) args.type = XFS_ALLOCTYPE_FIRST_AG; else @@ -3484,7 +3484,7 @@ xfs_bmap_btalloc( * is >= the stripe unit and the allocation offset is * at the end of file. */ - if (!ap->tp->t_dfops->dop_low && ap->aeof) { + if (!(ap->tp->t_flags & XFS_TRANS_LOWMODE) && ap->aeof) { if (!ap->offset) { args.alignment = stripe_align; atype = args.type; @@ -3576,7 +3576,7 @@ xfs_bmap_btalloc( args.total = ap->minlen; if ((error = xfs_alloc_vextent(&args))) return error; - ap->tp->t_dfops->dop_low = true; + ap->tp->t_flags |= XFS_TRANS_LOWMODE; } if (args.fsbno != NULLFSBLOCK) { /* diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 01489714a253..955e29de8cae 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -226,7 +226,7 @@ xfs_bmbt_alloc_block( * block allocation here and corrupt the filesystem. */ args.minleft = args.tp->t_blk_res; - } else if (cur->bc_tp->t_dfops->dop_low) { + } else if (cur->bc_tp->t_flags & XFS_TRANS_LOWMODE) { args.type = XFS_ALLOCTYPE_START_BNO; } else { args.type = XFS_ALLOCTYPE_NEAR_BNO; @@ -253,7 +253,7 @@ xfs_bmbt_alloc_block( error = xfs_alloc_vextent(&args); if (error) goto error0; - cur->bc_tp->t_dfops->dop_low = true; + cur->bc_tp->t_flags |= XFS_TRANS_LOWMODE; } if (WARN_ON_ONCE(args.fsbno == NULLFSBLOCK)) { *stat = 0; diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index e3517a53c525..64e1abc60edc 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -330,9 +330,14 @@ xfs_defer_reset( ASSERT(!xfs_defer_has_unfinished_work(dop)); - dop->dop_low = false; memset(dop->dop_inodes, 0, sizeof(dop->dop_inodes)); memset(dop->dop_bufs, 0, sizeof(dop->dop_bufs)); + + /* + * Low mode state transfers across transaction rolls to mirror dfops + * lifetime. Clear it now that dfops is reset. + */ + tp->t_flags &= ~XFS_TRANS_LOWMODE; } /* @@ -590,7 +595,14 @@ xfs_defer_move( memcpy(dst->dop_inodes, src->dop_inodes, sizeof(dst->dop_inodes)); memcpy(dst->dop_bufs, src->dop_bufs, sizeof(dst->dop_bufs)); - dst->dop_low = src->dop_low; + + /* + * Low free space mode was historically controlled by a dfops field. + * This meant that low mode state potentially carried across multiple + * transaction rolls. Transfer low mode on a dfops move to preserve + * that behavior. + */ + dtp->t_flags |= (stp->t_flags & XFS_TRANS_LOWMODE); xfs_defer_reset(stp); } diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index d60c50498fdf..8908a2716774 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h @@ -25,17 +25,6 @@ struct xfs_defer_pending { /* * Header for deferred operation list. - * - * dop_low is used by the allocator to activate the lowspace algorithm - - * when free space is running low the extent allocator may choose to - * allocate an extent from an AG without leaving sufficient space for - * a btree split when inserting the new extent. In this case the allocator - * will enable the lowspace algorithm which is supposed to allow further - * allocations (such as btree splits and newroots) to allocate from - * sequential AGs. In order to avoid locking AGs out of order the lowspace - * algorithm will start searching for free space from AG 0. If the correct - * transaction reservations have been made then this algorithm will eventually - * find all the space it needs. */ enum xfs_defer_ops_type { XFS_DEFER_OPS_TYPE_BMAP, diff --git a/fs/xfs/libxfs/xfs_shared.h b/fs/xfs/libxfs/xfs_shared.h index 22089f1c880a..1c5debe748f0 100644 --- a/fs/xfs/libxfs/xfs_shared.h +++ b/fs/xfs/libxfs/xfs_shared.h @@ -64,6 +64,18 @@ void xfs_log_get_max_trans_res(struct xfs_mount *mp, #define XFS_TRANS_RESERVE 0x20 /* OK to use reserved data blocks */ #define XFS_TRANS_NO_WRITECOUNT 0x40 /* do not elevate SB writecount */ #define XFS_TRANS_NOFS 0x80 /* pass KM_NOFS to kmem_alloc */ +/* + * LOWMODE is used by the allocator to activate the lowspace algorithm - when + * free space is running low the extent allocator may choose to allocate an + * extent from an AG without leaving sufficient space for a btree split when + * inserting the new extent. In this case the allocator will enable the + * lowspace algorithm which is supposed to allow further allocations (such as + * btree splits and newroots) to allocate from sequential AGs. In order to + * avoid locking AGs out of order the lowspace algorithm will start searching + * for free space from AG 0. If the correct transaction reservations have been + * made then this algorithm will eventually find all the space it needs. + */ +#define XFS_TRANS_LOWMODE 0x100 /* allocate in low space mode */ /* * Field values for xfs_trans_mod_sb. diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index 212173c62588..182501373af2 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -20,6 +20,7 @@ #include "xfs_trace.h" #include "xfs_ag_resv.h" #include "xfs_trans.h" +#include "xfs_shared.h" struct xfs_fstrm_item { struct xfs_mru_cache_elem mru; @@ -378,7 +379,7 @@ xfs_filestream_new_ag( if (xfs_alloc_is_userdata(ap->datatype)) flags |= XFS_PICK_USERDATA; - if (ap->tp->t_dfops->dop_low) + if (ap->tp->t_flags & XFS_TRANS_LOWMODE) flags |= XFS_PICK_LOWSPACE; err = xfs_filestream_pick_ag(pip, startag, agp, flags, minlen); diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index cc6995cfce66..8807f1bb814a 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -2223,19 +2223,16 @@ DECLARE_EVENT_CLASS(xfs_defer_class, __field(dev_t, dev) __field(void *, dop) __field(char, committed) - __field(char, low) __field(unsigned long, caller_ip) ), TP_fast_assign( __entry->dev = mp ? mp->m_super->s_dev : 0; __entry->dop = dop; - __entry->low = dop->dop_low; __entry->caller_ip = caller_ip; ), - TP_printk("dev %d:%d ops %p low %d, caller %pS", + TP_printk("dev %d:%d ops %p caller %pS", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->dop, - __entry->low, (char *)__entry->caller_ip) ) #define DEFINE_DEFER_EVENT(name) \ @@ -2251,19 +2248,16 @@ DECLARE_EVENT_CLASS(xfs_defer_error_class, __field(dev_t, dev) __field(void *, dop) __field(char, committed) - __field(char, low) __field(int, error) ), TP_fast_assign( __entry->dev = mp ? mp->m_super->s_dev : 0; __entry->dop = dop; - __entry->low = dop->dop_low; __entry->error = error; ), - TP_printk("dev %d:%d ops %p low %d err %d", + TP_printk("dev %d:%d ops %p err %d", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->dop, - __entry->low, __entry->error) ) #define DEFINE_DEFER_ERROR_EVENT(name) \ diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index dc79e3c1d3e8..7e493221160e 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -101,8 +101,6 @@ struct xfs_defer_ops { /* relog these with each roll */ struct xfs_inode *dop_inodes[XFS_DEFER_OPS_NR_INODES]; struct xfs_buf *dop_bufs[XFS_DEFER_OPS_NR_BUFS]; - - bool dop_low; /* alloc in low mode */ }; /* -- cgit v1.2.3 From 488c919a5bec3be4b8613898de6958043edbb8d9 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 1 Aug 2018 07:20:31 -0700 Subject: xfs: add missing defer ijoins for held inodes Log items that require relogging during deferred operations processing are explicitly joined to the associated dfops via the xfs_defer_*join() helpers. These calls imply that the associated object is "held" by the transaction such that when rolled, the item can be immediately joined to a follow up transaction. For buffers, this means the buffer remains locked and held after each roll. For inodes, this means that the inode remains locked. Failure to join a held item to the dfops structure means the associated object pins the tail of the log while dfops processing completes, because the item never relogs and is not unlocked or released until deferred processing completes. Currently, all buffers that are held in transactions (XFS_BLI_HOLD) with deferred operations are explicitly joined to the dfops. This is not the case for inodes, however, as various contexts defer operations to transactions with held inodes without explicit joins to the associated dfops (and thus not relogging). While this is not a catastrophic problem, it is not ideal. Given that we want to eventually relog such items automatically during dfops processing, start by explicitly adding these missing xfs_defer_ijoin() calls. A call is added everywhere an inode is joined to a transaction without transferring lock ownership and said transaction runs deferred operations. All xfs_defer_ijoin() calls will eventually be replaced by automatic dfops inode relogging. This patch essentially implements the behavior change that would otherwise occur due to automatic inode dfops relogging. Signed-off-by: Brian Foster Reviewed-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 1 + fs/xfs/xfs_bmap_util.c | 1 + fs/xfs/xfs_inode.c | 1 + fs/xfs/xfs_iomap.c | 3 +++ fs/xfs/xfs_reflink.c | 1 + 5 files changed, 7 insertions(+) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 8edf7522aaff..71687d805f79 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -1119,6 +1119,7 @@ xfs_bmap_add_attrfork( xfs_log_sb(tp); } + xfs_defer_ijoin(tp->t_dfops, ip); error = xfs_trans_commit(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); return error; diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 412dc58ae54d..0c58a66b39e5 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -979,6 +979,7 @@ xfs_alloc_file_space( /* * Complete the transaction */ + xfs_defer_ijoin(tp->t_dfops, ip); error = xfs_trans_commit(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); if (error) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 5fc1815c2b62..441c8593cfd7 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1810,6 +1810,7 @@ xfs_inactive_ifree( * Just ignore errors at this point. There is nothing we can do except * to try to keep going. Make sure it's not a silent error. */ + xfs_defer_ijoin(tp->t_dfops, ip); error = xfs_trans_commit(tp); if (error) xfs_notice(mp, "%s: xfs_trans_commit returned error %d", diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 3282575e2df4..8093a01fcf9e 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -261,6 +261,7 @@ xfs_iomap_write_direct( /* * Complete the transaction */ + xfs_defer_ijoin(tp->t_dfops, ip); error = xfs_trans_commit(tp); if (error) goto out_unlock; @@ -763,6 +764,7 @@ xfs_iomap_write_allocate( if (error) goto trans_cancel; + xfs_defer_ijoin(tp->t_dfops, ip); error = xfs_trans_commit(tp); if (error) goto error0; @@ -882,6 +884,7 @@ xfs_iomap_write_unwritten( xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); } + xfs_defer_ijoin(tp->t_dfops, ip); error = xfs_trans_commit(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); if (error) diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 9a0a56526266..e986fcf928e5 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -435,6 +435,7 @@ retry: xfs_inode_set_cowblocks_tag(ip); /* Finish up. */ + xfs_defer_ijoin(tp->t_dfops, ip); error = xfs_trans_commit(tp); if (error) return error; -- cgit v1.2.3 From 82ff27bc52a88cb5cc400bfa64e210d3ec8dfebd Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 1 Aug 2018 07:20:32 -0700 Subject: xfs: automatic dfops buffer relogging Buffers that are held across deferred operations are explicitly joined to the dfops structure to ensure appropriate relogging. While buffers are currently joined explicitly, we can detect the conditions that require relogging at dfops finish time by inspecting the transaction item list for held buffers. Replace the xfs_defer_bjoin() infrastructure with such detection and automatic relogging of held buffers. This eliminates the need for the per-dfops buffer list, replaced by an on-stack variant in xfs_defer_trans_roll(). Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr.c | 1 - fs/xfs/libxfs/xfs_defer.c | 58 +++++++++++++++++++++-------------------------- fs/xfs/libxfs/xfs_defer.h | 1 - fs/xfs/xfs_dquot.c | 1 - fs/xfs/xfs_trans.h | 1 - 5 files changed, 26 insertions(+), 36 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 3deb5cdadf08..227887bee00d 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -320,7 +320,6 @@ xfs_attr_set( * buffer and run into problems with the write verifier. */ xfs_trans_bhold(args.trans, leaf_bp); - xfs_defer_bjoin(args.trans->t_dfops, leaf_bp); xfs_defer_ijoin(args.trans->t_dfops, dp); error = xfs_defer_finish(&args.trans); if (error) diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index 64e1abc60edc..e9b7671d289a 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -14,6 +14,7 @@ #include "xfs_mount.h" #include "xfs_defer.h" #include "xfs_trans.h" +#include "xfs_buf_item.h" #include "xfs_trace.h" /* @@ -228,6 +229,10 @@ xfs_defer_trans_roll( struct xfs_trans **tp) { struct xfs_defer_ops *dop = (*tp)->t_dfops; + struct xfs_buf_log_item *bli; + struct xfs_log_item *lip; + struct xfs_buf *bplist[XFS_DEFER_OPS_NR_BUFS]; + int bpcount = 0; int i; int error; @@ -235,9 +240,24 @@ xfs_defer_trans_roll( for (i = 0; i < XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++) xfs_trans_log_inode(*tp, dop->dop_inodes[i], XFS_ILOG_CORE); - /* Hold the (previously bjoin'd) buffer locked across the roll. */ - for (i = 0; i < XFS_DEFER_OPS_NR_BUFS && dop->dop_bufs[i]; i++) - xfs_trans_dirty_buf(*tp, dop->dop_bufs[i]); + list_for_each_entry(lip, &(*tp)->t_items, li_trans) { + switch (lip->li_type) { + case XFS_LI_BUF: + bli = container_of(lip, struct xfs_buf_log_item, + bli_item); + if (bli->bli_flags & XFS_BLI_HOLD) { + if (bpcount >= XFS_DEFER_OPS_NR_BUFS) { + ASSERT(0); + return -EFSCORRUPTED; + } + xfs_trans_dirty_buf(*tp, bli->bli_buf); + bplist[bpcount++] = bli->bli_buf; + } + break; + default: + break; + } + } trace_xfs_defer_trans_roll((*tp)->t_mountp, dop, _RET_IP_); @@ -255,9 +275,9 @@ xfs_defer_trans_roll( xfs_trans_ijoin(*tp, dop->dop_inodes[i], 0); /* Rejoin the buffers and dirty them so the log moves forward. */ - for (i = 0; i < XFS_DEFER_OPS_NR_BUFS && dop->dop_bufs[i]; i++) { - xfs_trans_bjoin(*tp, dop->dop_bufs[i]); - xfs_trans_bhold(*tp, dop->dop_bufs[i]); + for (i = 0; i < bpcount; i++) { + xfs_trans_bjoin(*tp, bplist[i]); + xfs_trans_bhold(*tp, bplist[i]); } return error; @@ -295,30 +315,6 @@ xfs_defer_ijoin( return -EFSCORRUPTED; } -/* - * Add this buffer to the deferred op. Each joined buffer is relogged - * each time we roll the transaction. - */ -int -xfs_defer_bjoin( - struct xfs_defer_ops *dop, - struct xfs_buf *bp) -{ - int i; - - for (i = 0; i < XFS_DEFER_OPS_NR_BUFS; i++) { - if (dop->dop_bufs[i] == bp) - return 0; - else if (dop->dop_bufs[i] == NULL) { - dop->dop_bufs[i] = bp; - return 0; - } - } - - ASSERT(0); - return -EFSCORRUPTED; -} - /* * Reset an already used dfops after finish. */ @@ -331,7 +327,6 @@ xfs_defer_reset( ASSERT(!xfs_defer_has_unfinished_work(dop)); memset(dop->dop_inodes, 0, sizeof(dop->dop_inodes)); - memset(dop->dop_bufs, 0, sizeof(dop->dop_bufs)); /* * Low mode state transfers across transaction rolls to mirror dfops @@ -594,7 +589,6 @@ xfs_defer_move( list_splice_init(&src->dop_pending, &dst->dop_pending); memcpy(dst->dop_inodes, src->dop_inodes, sizeof(dst->dop_inodes)); - memcpy(dst->dop_bufs, src->dop_bufs, sizeof(dst->dop_bufs)); /* * Low free space mode was historically controlled by a dfops field. diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index 8908a2716774..4a8bb838adf2 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h @@ -43,7 +43,6 @@ void xfs_defer_cancel(struct xfs_trans *); void xfs_defer_init(struct xfs_trans *tp, struct xfs_defer_ops *dop); bool xfs_defer_has_unfinished_work(struct xfs_defer_ops *dop); int xfs_defer_ijoin(struct xfs_defer_ops *dop, struct xfs_inode *ip); -int xfs_defer_bjoin(struct xfs_defer_ops *dop, struct xfs_buf *bp); void xfs_defer_move(struct xfs_trans *dtp, struct xfs_trans *stp); /* Description of a deferred type. */ diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index da5c55cec966..e1196854dbcd 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -362,7 +362,6 @@ xfs_dquot_disk_alloc( * manually or by committing the transaction. */ xfs_trans_bhold(tp, bp); - error = xfs_defer_bjoin(tp->t_dfops, bp); if (error) { xfs_trans_bhold_release(tp, bp); xfs_trans_brelse(tp, bp); diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 7e493221160e..581456c79197 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -100,7 +100,6 @@ struct xfs_defer_ops { /* relog these with each roll */ struct xfs_inode *dop_inodes[XFS_DEFER_OPS_NR_INODES]; - struct xfs_buf *dop_bufs[XFS_DEFER_OPS_NR_BUFS]; }; /* -- cgit v1.2.3 From a8198666fb755e129c2fe92819774256ec26c79c Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 1 Aug 2018 07:20:32 -0700 Subject: xfs: automatic dfops inode relogging Inodes that are held across deferred operations are explicitly joined to the dfops structure to ensure appropriate relogging. While inodes are currently joined explicitly, we can detect the conditions that require relogging at dfops finish time by inspecting the transaction item list for inodes with ili_lock_flags == 0. Replace the xfs_defer_ijoin() infrastructure with such detection and automatic relogging of held inodes. This eliminates the need for the per-dfops inode list, replaced by an on-stack variant in xfs_defer_trans_roll(). Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr.c | 9 ------- fs/xfs/libxfs/xfs_attr_remote.c | 2 -- fs/xfs/libxfs/xfs_bmap.c | 8 ------ fs/xfs/libxfs/xfs_defer.c | 59 +++++++++++++++-------------------------- fs/xfs/libxfs/xfs_defer.h | 1 - fs/xfs/xfs_bmap_util.c | 4 --- fs/xfs/xfs_inode.c | 2 -- fs/xfs/xfs_iomap.c | 3 --- fs/xfs/xfs_reflink.c | 4 --- fs/xfs/xfs_symlink.c | 1 - fs/xfs/xfs_trans.h | 3 --- 11 files changed, 21 insertions(+), 75 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 227887bee00d..3190dfc21b60 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -320,7 +320,6 @@ xfs_attr_set( * buffer and run into problems with the write verifier. */ xfs_trans_bhold(args.trans, leaf_bp); - xfs_defer_ijoin(args.trans->t_dfops, dp); error = xfs_defer_finish(&args.trans); if (error) goto out; @@ -589,7 +588,6 @@ xfs_attr_leaf_addname( error = xfs_attr3_leaf_to_node(args); if (error) goto out_defer_cancel; - xfs_defer_ijoin(args->trans->t_dfops, dp); error = xfs_defer_finish(&args->trans); if (error) goto out_defer_cancel; @@ -678,7 +676,6 @@ xfs_attr_leaf_addname( /* bp is gone due to xfs_da_shrink_inode */ if (error) goto out_defer_cancel; - xfs_defer_ijoin(args->trans->t_dfops, dp); error = xfs_defer_finish(&args->trans); if (error) goto out_defer_cancel; @@ -742,7 +739,6 @@ xfs_attr_leaf_removename( /* bp is gone due to xfs_da_shrink_inode */ if (error) goto out_defer_cancel; - xfs_defer_ijoin(args->trans->t_dfops, dp); error = xfs_defer_finish(&args->trans); if (error) goto out_defer_cancel; @@ -869,7 +865,6 @@ restart: error = xfs_attr3_leaf_to_node(args); if (error) goto out_defer_cancel; - xfs_defer_ijoin(args->trans->t_dfops, dp); error = xfs_defer_finish(&args->trans); if (error) goto out_defer_cancel; @@ -894,7 +889,6 @@ restart: error = xfs_da3_split(state); if (error) goto out_defer_cancel; - xfs_defer_ijoin(args->trans->t_dfops, dp); error = xfs_defer_finish(&args->trans); if (error) goto out_defer_cancel; @@ -991,7 +985,6 @@ restart: error = xfs_da3_join(state); if (error) goto out_defer_cancel; - xfs_defer_ijoin(args->trans->t_dfops, dp); error = xfs_defer_finish(&args->trans); if (error) goto out_defer_cancel; @@ -1115,7 +1108,6 @@ xfs_attr_node_removename( error = xfs_da3_join(state); if (error) goto out_defer_cancel; - xfs_defer_ijoin(args->trans->t_dfops, dp); error = xfs_defer_finish(&args->trans); if (error) goto out_defer_cancel; @@ -1147,7 +1139,6 @@ xfs_attr_node_removename( /* bp is gone due to xfs_da_shrink_inode */ if (error) goto out_defer_cancel; - xfs_defer_ijoin(args->trans->t_dfops, dp); error = xfs_defer_finish(&args->trans); if (error) goto out_defer_cancel; diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index 77ca38586913..f52552313773 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -486,7 +486,6 @@ xfs_attr_rmtval_set( &nmap); if (error) goto out_defer_cancel; - xfs_defer_ijoin(args->trans->t_dfops, dp); error = xfs_defer_finish(&args->trans); if (error) goto out_defer_cancel; @@ -627,7 +626,6 @@ xfs_attr_rmtval_remove( XFS_BMAPI_ATTRFORK, 1, &done); if (error) goto out_defer_cancel; - xfs_defer_ijoin(args->trans->t_dfops, args->dp); error = xfs_defer_finish(&args->trans); if (error) goto out_defer_cancel; diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 71687d805f79..5cd490dc891a 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -1119,7 +1119,6 @@ xfs_bmap_add_attrfork( xfs_log_sb(tp); } - xfs_defer_ijoin(tp->t_dfops, ip); error = xfs_trans_commit(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); return error; @@ -5987,7 +5986,6 @@ __xfs_bmap_add( int whichfork, struct xfs_bmbt_irec *bmap) { - int error; struct xfs_bmap_intent *bi; trace_xfs_bmap_defer(mp, @@ -6006,12 +6004,6 @@ __xfs_bmap_add( bi->bi_whichfork = whichfork; bi->bi_bmap = *bmap; - error = xfs_defer_ijoin(dfops, bi->bi_owner); - if (error) { - kmem_free(bi); - return error; - } - xfs_defer_add(dfops, XFS_DEFER_OPS_TYPE_BMAP, &bi->bi_list); return 0; } diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index e9b7671d289a..1e7073252a5e 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -15,6 +15,8 @@ #include "xfs_defer.h" #include "xfs_trans.h" #include "xfs_buf_item.h" +#include "xfs_inode.h" +#include "xfs_inode_item.h" #include "xfs_trace.h" /* @@ -230,16 +232,14 @@ xfs_defer_trans_roll( { struct xfs_defer_ops *dop = (*tp)->t_dfops; struct xfs_buf_log_item *bli; + struct xfs_inode_log_item *ili; struct xfs_log_item *lip; struct xfs_buf *bplist[XFS_DEFER_OPS_NR_BUFS]; - int bpcount = 0; + struct xfs_inode *iplist[XFS_DEFER_OPS_NR_INODES]; + int bpcount = 0, ipcount = 0; int i; int error; - /* Log all the joined inodes. */ - for (i = 0; i < XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++) - xfs_trans_log_inode(*tp, dop->dop_inodes[i], XFS_ILOG_CORE); - list_for_each_entry(lip, &(*tp)->t_items, li_trans) { switch (lip->li_type) { case XFS_LI_BUF: @@ -254,6 +254,19 @@ xfs_defer_trans_roll( bplist[bpcount++] = bli->bli_buf; } break; + case XFS_LI_INODE: + ili = container_of(lip, struct xfs_inode_log_item, + ili_item); + if (ili->ili_lock_flags == 0) { + if (ipcount >= XFS_DEFER_OPS_NR_INODES) { + ASSERT(0); + return -EFSCORRUPTED; + } + xfs_trans_log_inode(*tp, ili->ili_inode, + XFS_ILOG_CORE); + iplist[ipcount++] = ili->ili_inode; + } + break; default: break; } @@ -271,8 +284,8 @@ xfs_defer_trans_roll( } /* Rejoin the joined inodes. */ - for (i = 0; i < XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++) - xfs_trans_ijoin(*tp, dop->dop_inodes[i], 0); + for (i = 0; i < ipcount; i++) + xfs_trans_ijoin(*tp, iplist[i], 0); /* Rejoin the buffers and dirty them so the log moves forward. */ for (i = 0; i < bpcount; i++) { @@ -291,30 +304,6 @@ xfs_defer_has_unfinished_work( return !list_empty(&dop->dop_pending) || !list_empty(&dop->dop_intake); } -/* - * Add this inode to the deferred op. Each joined inode is relogged - * each time we roll the transaction. - */ -int -xfs_defer_ijoin( - struct xfs_defer_ops *dop, - struct xfs_inode *ip) -{ - int i; - - for (i = 0; i < XFS_DEFER_OPS_NR_INODES; i++) { - if (dop->dop_inodes[i] == ip) - return 0; - else if (dop->dop_inodes[i] == NULL) { - dop->dop_inodes[i] = ip; - return 0; - } - } - - ASSERT(0); - return -EFSCORRUPTED; -} - /* * Reset an already used dfops after finish. */ @@ -322,11 +311,7 @@ static void xfs_defer_reset( struct xfs_trans *tp) { - struct xfs_defer_ops *dop = tp->t_dfops; - - ASSERT(!xfs_defer_has_unfinished_work(dop)); - - memset(dop->dop_inodes, 0, sizeof(dop->dop_inodes)); + ASSERT(!xfs_defer_has_unfinished_work(tp->t_dfops)); /* * Low mode state transfers across transaction rolls to mirror dfops @@ -588,8 +573,6 @@ xfs_defer_move( list_splice_init(&src->dop_intake, &dst->dop_intake); list_splice_init(&src->dop_pending, &dst->dop_pending); - memcpy(dst->dop_inodes, src->dop_inodes, sizeof(dst->dop_inodes)); - /* * Low free space mode was historically controlled by a dfops field. * This meant that low mode state potentially carried across multiple diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index 4a8bb838adf2..bf1e9f78561e 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h @@ -42,7 +42,6 @@ int xfs_defer_finish(struct xfs_trans **tp); void xfs_defer_cancel(struct xfs_trans *); void xfs_defer_init(struct xfs_trans *tp, struct xfs_defer_ops *dop); bool xfs_defer_has_unfinished_work(struct xfs_defer_ops *dop); -int xfs_defer_ijoin(struct xfs_defer_ops *dop, struct xfs_inode *ip); void xfs_defer_move(struct xfs_trans *dtp, struct xfs_trans *stp); /* Description of a deferred type. */ diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 0c58a66b39e5..30ac1300dc49 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -979,7 +979,6 @@ xfs_alloc_file_space( /* * Complete the transaction */ - xfs_defer_ijoin(tp->t_dfops, ip); error = xfs_trans_commit(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); if (error) @@ -1037,8 +1036,6 @@ xfs_unmap_extent( if (error) goto out_trans_cancel; - xfs_defer_ijoin(tp->t_dfops, ip); - error = xfs_trans_commit(tp); out_unlock: xfs_iunlock(ip, XFS_ILOCK_EXCL); @@ -1624,7 +1621,6 @@ xfs_swap_extent_rmap( if (error) goto out_defer; - xfs_defer_ijoin(tp->t_dfops, ip); error = xfs_defer_finish(tpp); tp = *tpp; if (error) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 441c8593cfd7..7bb46a0eecfc 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1569,7 +1569,6 @@ xfs_itruncate_extents_flags( * Duplicate the transaction that has the permanent * reservation and commit the old transaction. */ - xfs_defer_ijoin(tp->t_dfops, ip); error = xfs_defer_finish(&tp); if (error) goto out_bmap_cancel; @@ -1810,7 +1809,6 @@ xfs_inactive_ifree( * Just ignore errors at this point. There is nothing we can do except * to try to keep going. Make sure it's not a silent error. */ - xfs_defer_ijoin(tp->t_dfops, ip); error = xfs_trans_commit(tp); if (error) xfs_notice(mp, "%s: xfs_trans_commit returned error %d", diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 8093a01fcf9e..3282575e2df4 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -261,7 +261,6 @@ xfs_iomap_write_direct( /* * Complete the transaction */ - xfs_defer_ijoin(tp->t_dfops, ip); error = xfs_trans_commit(tp); if (error) goto out_unlock; @@ -764,7 +763,6 @@ xfs_iomap_write_allocate( if (error) goto trans_cancel; - xfs_defer_ijoin(tp->t_dfops, ip); error = xfs_trans_commit(tp); if (error) goto error0; @@ -884,7 +882,6 @@ xfs_iomap_write_unwritten( xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); } - xfs_defer_ijoin(tp->t_dfops, ip); error = xfs_trans_commit(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); if (error) diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index e986fcf928e5..dce8ba8ab681 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -435,7 +435,6 @@ retry: xfs_inode_set_cowblocks_tag(ip); /* Finish up. */ - xfs_defer_ijoin(tp->t_dfops, ip); error = xfs_trans_commit(tp); if (error) return error; @@ -518,7 +517,6 @@ xfs_reflink_cancel_cow_blocks( NULL); /* Roll the transaction */ - xfs_defer_ijoin((*tpp)->t_dfops, ip); error = xfs_defer_finish(tpp); if (error) { xfs_defer_cancel(*tpp); @@ -716,7 +714,6 @@ xfs_reflink_end_cow( /* Remove the mapping from the CoW fork. */ xfs_bmap_del_extent_cow(ip, &icur, &got, &del); - xfs_defer_ijoin(tp->t_dfops, ip); error = xfs_defer_finish(&tp); if (error) goto out_cancel; @@ -1077,7 +1074,6 @@ xfs_reflink_remap_extent( next_extent: /* Process all the deferred stuff. */ - xfs_defer_ijoin(tp->t_dfops, ip); error = xfs_defer_finish(&tp); if (error) goto out_cancel; diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 2bfe7fbbedb2..a3e98c64b6e3 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -454,7 +454,6 @@ xfs_inactive_symlink_rmt( * Commit the transaction. This first logs the EFI and the inode, then * rolls and commits the transaction that frees the extents. */ - xfs_defer_ijoin(tp->t_dfops, ip); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); error = xfs_trans_commit(tp); if (error) { diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 581456c79197..8665d45b82c6 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -97,9 +97,6 @@ void xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item, struct xfs_defer_ops { struct list_head dop_intake; /* unlogged pending work */ struct list_head dop_pending; /* logged pending work */ - - /* relog these with each roll */ - struct xfs_inode *dop_inodes[XFS_DEFER_OPS_NR_INODES]; }; /* -- cgit v1.2.3 From 7dbddbaccd189e63c39c9e22c728c4548b9893bb Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 1 Aug 2018 07:20:32 -0700 Subject: xfs: drop dop param from xfs_defer_op_type ->finish_item() callback The dfops infrastructure ->finish_item() callback passes the transaction and dfops as separate parameters. Since dfops is always part of a transaction, the latter parameter is no longer necessary. Remove it from the various callbacks. Signed-off-by: Brian Foster Reviewed-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 2 -- fs/xfs/libxfs/xfs_bmap.h | 6 +++--- fs/xfs/libxfs/xfs_defer.c | 2 +- fs/xfs/libxfs/xfs_defer.h | 4 ++-- fs/xfs/libxfs/xfs_refcount.c | 2 +- fs/xfs/libxfs/xfs_refcount.h | 7 +++---- fs/xfs/xfs_bmap_item.c | 5 ++--- fs/xfs/xfs_refcount_item.c | 4 ++-- fs/xfs/xfs_trans.h | 10 +++++----- fs/xfs/xfs_trans_bmap.c | 6 ++---- fs/xfs/xfs_trans_extfree.c | 2 -- fs/xfs/xfs_trans_refcount.c | 6 ++---- fs/xfs/xfs_trans_rmap.c | 1 - 13 files changed, 23 insertions(+), 34 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 5cd490dc891a..d20f541b7061 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -6045,7 +6045,6 @@ xfs_bmap_unmap_extent( int xfs_bmap_finish_one( struct xfs_trans *tp, - struct xfs_defer_ops *dfops, struct xfs_inode *ip, enum xfs_bmap_intent_type type, int whichfork, @@ -6072,7 +6071,6 @@ xfs_bmap_finish_one( switch (type) { case XFS_BMAP_MAP: - ASSERT(dfops == tp->t_dfops); error = xfs_bmapi_remap(tp, ip, startoff, *blockcount, startblock, 0); *blockcount = 0; diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 2e8555c1229a..9165a878edcd 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -252,9 +252,9 @@ struct xfs_bmap_intent { struct xfs_bmbt_irec bi_bmap; }; -int xfs_bmap_finish_one(struct xfs_trans *tp, struct xfs_defer_ops *dfops, - struct xfs_inode *ip, enum xfs_bmap_intent_type type, - int whichfork, xfs_fileoff_t startoff, xfs_fsblock_t startblock, +int xfs_bmap_finish_one(struct xfs_trans *tp, struct xfs_inode *ip, + enum xfs_bmap_intent_type type, int whichfork, + xfs_fileoff_t startoff, xfs_fsblock_t startblock, xfs_filblks_t *blockcount, xfs_exntst_t state); int xfs_bmap_map_extent(struct xfs_mount *mp, struct xfs_defer_ops *dfops, struct xfs_inode *ip, struct xfs_bmbt_irec *imap); diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index 1e7073252a5e..66ef9341813b 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -371,7 +371,7 @@ xfs_defer_finish_noroll( list_for_each_safe(li, n, &dfp->dfp_work) { list_del(li); dfp->dfp_count--; - error = dfp->dfp_type->finish_item(*tp, dop, li, + error = dfp->dfp_type->finish_item(*tp, li, dfp->dfp_done, &state); if (error == -EAGAIN) { /* diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index bf1e9f78561e..0de7504e5651 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h @@ -50,8 +50,8 @@ struct xfs_defer_op_type { unsigned int max_items; void (*abort_intent)(void *); void *(*create_done)(struct xfs_trans *, void *, unsigned int); - int (*finish_item)(struct xfs_trans *, struct xfs_defer_ops *, - struct list_head *, void *, void **); + int (*finish_item)(struct xfs_trans *, struct list_head *, void *, + void **); void (*finish_cleanup)(struct xfs_trans *, void *, int); void (*cancel_item)(struct list_head *); int (*diff_items)(void *, struct list_head *, struct list_head *); diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index 4cbc2efb099e..86f297ca90cd 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -1082,7 +1082,6 @@ xfs_refcount_finish_one_cleanup( int xfs_refcount_finish_one( struct xfs_trans *tp, - struct xfs_defer_ops *dfops, enum xfs_refcount_intent_type type, xfs_fsblock_t startblock, xfs_extlen_t blockcount, @@ -1091,6 +1090,7 @@ xfs_refcount_finish_one( struct xfs_btree_cur **pcur) { struct xfs_mount *mp = tp->t_mountp; + struct xfs_defer_ops *dfops = tp->t_dfops; struct xfs_btree_cur *rcur; struct xfs_buf *agbp = NULL; int error = 0; diff --git a/fs/xfs/libxfs/xfs_refcount.h b/fs/xfs/libxfs/xfs_refcount.h index 5fef74412727..3b72c6dbf6ad 100644 --- a/fs/xfs/libxfs/xfs_refcount.h +++ b/fs/xfs/libxfs/xfs_refcount.h @@ -37,10 +37,9 @@ extern int xfs_refcount_decrease_extent(struct xfs_mount *mp, extern void xfs_refcount_finish_one_cleanup(struct xfs_trans *tp, struct xfs_btree_cur *rcur, int error); extern int xfs_refcount_finish_one(struct xfs_trans *tp, - struct xfs_defer_ops *dfops, enum xfs_refcount_intent_type type, - xfs_fsblock_t startblock, xfs_extlen_t blockcount, - xfs_fsblock_t *new_fsb, xfs_extlen_t *new_len, - struct xfs_btree_cur **pcur); + enum xfs_refcount_intent_type type, xfs_fsblock_t startblock, + xfs_extlen_t blockcount, xfs_fsblock_t *new_fsb, + xfs_extlen_t *new_len, struct xfs_btree_cur **pcur); extern int xfs_refcount_find_shared(struct xfs_btree_cur *cur, xfs_agblock_t agbno, xfs_extlen_t aglen, xfs_agblock_t *fbno, diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c index b8a6be036cd7..e828e0b51814 100644 --- a/fs/xfs/xfs_bmap_item.c +++ b/fs/xfs/xfs_bmap_item.c @@ -475,9 +475,8 @@ xfs_bui_recover( xfs_trans_ijoin(tp, ip, 0); count = bmap->me_len; - error = xfs_trans_log_finish_bmap_update(tp, budp, tp->t_dfops, type, - ip, whichfork, bmap->me_startoff, - bmap->me_startblock, &count, state); + error = xfs_trans_log_finish_bmap_update(tp, budp, type, ip, whichfork, + bmap->me_startoff, bmap->me_startblock, &count, state); if (error) goto err_inode; diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c index 4a417daae781..43c4ac374cba 100644 --- a/fs/xfs/xfs_refcount_item.c +++ b/fs/xfs/xfs_refcount_item.c @@ -479,8 +479,8 @@ xfs_cui_recover( new_len = refc->pe_len; } else error = xfs_trans_log_finish_refcount_update(tp, cudp, - tp->t_dfops, type, refc->pe_startblock, - refc->pe_len, &new_fsb, &new_len, &rcur); + type, refc->pe_startblock, refc->pe_len, + &new_fsb, &new_len, &rcur); if (error) goto abort_error; diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 8665d45b82c6..299656dbf324 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -268,7 +268,7 @@ void xfs_refcount_update_init_defer_op(void); struct xfs_cud_log_item *xfs_trans_get_cud(struct xfs_trans *tp, struct xfs_cui_log_item *cuip); int xfs_trans_log_finish_refcount_update(struct xfs_trans *tp, - struct xfs_cud_log_item *cudp, struct xfs_defer_ops *dfops, + struct xfs_cud_log_item *cudp, enum xfs_refcount_intent_type type, xfs_fsblock_t startblock, xfs_extlen_t blockcount, xfs_fsblock_t *new_fsb, xfs_extlen_t *new_len, struct xfs_btree_cur **pcur); @@ -280,9 +280,9 @@ void xfs_bmap_update_init_defer_op(void); struct xfs_bud_log_item *xfs_trans_get_bud(struct xfs_trans *tp, struct xfs_bui_log_item *buip); int xfs_trans_log_finish_bmap_update(struct xfs_trans *tp, - struct xfs_bud_log_item *rudp, struct xfs_defer_ops *dfops, - enum xfs_bmap_intent_type type, struct xfs_inode *ip, - int whichfork, xfs_fileoff_t startoff, xfs_fsblock_t startblock, - xfs_filblks_t *blockcount, xfs_exntst_t state); + struct xfs_bud_log_item *rudp, enum xfs_bmap_intent_type type, + struct xfs_inode *ip, int whichfork, xfs_fileoff_t startoff, + xfs_fsblock_t startblock, xfs_filblks_t *blockcount, + xfs_exntst_t state); #endif /* __XFS_TRANS_H__ */ diff --git a/fs/xfs/xfs_trans_bmap.c b/fs/xfs/xfs_trans_bmap.c index a15a5cd867f9..741c558b2179 100644 --- a/fs/xfs/xfs_trans_bmap.c +++ b/fs/xfs/xfs_trans_bmap.c @@ -43,7 +43,6 @@ int xfs_trans_log_finish_bmap_update( struct xfs_trans *tp, struct xfs_bud_log_item *budp, - struct xfs_defer_ops *dop, enum xfs_bmap_intent_type type, struct xfs_inode *ip, int whichfork, @@ -54,7 +53,7 @@ xfs_trans_log_finish_bmap_update( { int error; - error = xfs_bmap_finish_one(tp, dop, ip, type, whichfork, startoff, + error = xfs_bmap_finish_one(tp, ip, type, whichfork, startoff, startblock, blockcount, state); /* @@ -176,7 +175,6 @@ xfs_bmap_update_create_done( STATIC int xfs_bmap_update_finish_item( struct xfs_trans *tp, - struct xfs_defer_ops *dop, struct list_head *item, void *done_item, void **state) @@ -187,7 +185,7 @@ xfs_bmap_update_finish_item( bmap = container_of(item, struct xfs_bmap_intent, bi_list); count = bmap->bi_bmap.br_blockcount; - error = xfs_trans_log_finish_bmap_update(tp, done_item, dop, + error = xfs_trans_log_finish_bmap_update(tp, done_item, bmap->bi_type, bmap->bi_owner, bmap->bi_whichfork, bmap->bi_bmap.br_startoff, diff --git a/fs/xfs/xfs_trans_extfree.c b/fs/xfs/xfs_trans_extfree.c index bd66c76f55e6..855c0b651fd4 100644 --- a/fs/xfs/xfs_trans_extfree.c +++ b/fs/xfs/xfs_trans_extfree.c @@ -171,7 +171,6 @@ xfs_extent_free_create_done( STATIC int xfs_extent_free_finish_item( struct xfs_trans *tp, - struct xfs_defer_ops *dop, struct list_head *item, void *done_item, void **state) @@ -226,7 +225,6 @@ static const struct xfs_defer_op_type xfs_extent_free_defer_type = { STATIC int xfs_agfl_free_finish_item( struct xfs_trans *tp, - struct xfs_defer_ops *dop, struct list_head *item, void *done_item, void **state) diff --git a/fs/xfs/xfs_trans_refcount.c b/fs/xfs/xfs_trans_refcount.c index 46dd4fca8aa7..523c55663954 100644 --- a/fs/xfs/xfs_trans_refcount.c +++ b/fs/xfs/xfs_trans_refcount.c @@ -42,7 +42,6 @@ int xfs_trans_log_finish_refcount_update( struct xfs_trans *tp, struct xfs_cud_log_item *cudp, - struct xfs_defer_ops *dop, enum xfs_refcount_intent_type type, xfs_fsblock_t startblock, xfs_extlen_t blockcount, @@ -52,7 +51,7 @@ xfs_trans_log_finish_refcount_update( { int error; - error = xfs_refcount_finish_one(tp, dop, type, startblock, + error = xfs_refcount_finish_one(tp, type, startblock, blockcount, new_fsb, new_len, pcur); /* @@ -169,7 +168,6 @@ xfs_refcount_update_create_done( STATIC int xfs_refcount_update_finish_item( struct xfs_trans *tp, - struct xfs_defer_ops *dop, struct list_head *item, void *done_item, void **state) @@ -180,7 +178,7 @@ xfs_refcount_update_finish_item( int error; refc = container_of(item, struct xfs_refcount_intent, ri_list); - error = xfs_trans_log_finish_refcount_update(tp, done_item, dop, + error = xfs_trans_log_finish_refcount_update(tp, done_item, refc->ri_type, refc->ri_startblock, refc->ri_blockcount, diff --git a/fs/xfs/xfs_trans_rmap.c b/fs/xfs/xfs_trans_rmap.c index 726d8e2c0558..05b00e40251f 100644 --- a/fs/xfs/xfs_trans_rmap.c +++ b/fs/xfs/xfs_trans_rmap.c @@ -193,7 +193,6 @@ xfs_rmap_update_create_done( STATIC int xfs_rmap_update_finish_item( struct xfs_trans *tp, - struct xfs_defer_ops *dop, struct list_head *item, void *done_item, void **state) -- cgit v1.2.3 From 60f31a609ed3d28791acb2bc24188cb7e2259176 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 1 Aug 2018 07:20:33 -0700 Subject: xfs: clean out superfluous dfops dop params/vars The dfops code still passes around the xfs_defer_ops pointer superfluously in a few places. Clean this up wherever the transaction will suffice. Signed-off-by: Brian Foster Reviewed-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_defer.c | 43 +++++++++++++++++++++---------------------- fs/xfs/libxfs/xfs_defer.h | 2 +- fs/xfs/xfs_trans.c | 2 +- 3 files changed, 23 insertions(+), 24 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index 66ef9341813b..7079f534c735 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -181,9 +181,9 @@ static const struct xfs_defer_op_type *defer_op_types[XFS_DEFER_OPS_TYPE_MAX]; */ STATIC void xfs_defer_intake_work( - struct xfs_trans *tp, - struct xfs_defer_ops *dop) + struct xfs_trans *tp) { + struct xfs_defer_ops *dop = tp->t_dfops; struct list_head *li; struct xfs_defer_pending *dfp; @@ -204,9 +204,9 @@ xfs_defer_intake_work( STATIC void xfs_defer_trans_abort( struct xfs_trans *tp, - struct xfs_defer_ops *dop, int error) { + struct xfs_defer_ops *dop = tp->t_dfops; struct xfs_defer_pending *dfp; trace_xfs_defer_trans_abort(tp->t_mountp, dop, _RET_IP_); @@ -230,7 +230,6 @@ STATIC int xfs_defer_trans_roll( struct xfs_trans **tp) { - struct xfs_defer_ops *dop = (*tp)->t_dfops; struct xfs_buf_log_item *bli; struct xfs_inode_log_item *ili; struct xfs_log_item *lip; @@ -272,14 +271,14 @@ xfs_defer_trans_roll( } } - trace_xfs_defer_trans_roll((*tp)->t_mountp, dop, _RET_IP_); + trace_xfs_defer_trans_roll((*tp)->t_mountp, (*tp)->t_dfops, _RET_IP_); /* Roll the transaction. */ error = xfs_trans_roll(tp); - dop = (*tp)->t_dfops; if (error) { - trace_xfs_defer_trans_roll_error((*tp)->t_mountp, dop, error); - xfs_defer_trans_abort(*tp, dop, error); + trace_xfs_defer_trans_roll_error((*tp)->t_mountp, + (*tp)->t_dfops, error); + xfs_defer_trans_abort(*tp, error); return error; } @@ -299,9 +298,10 @@ xfs_defer_trans_roll( /* Do we have any work items to finish? */ bool xfs_defer_has_unfinished_work( - struct xfs_defer_ops *dop) + struct xfs_trans *tp) { - return !list_empty(&dop->dop_pending) || !list_empty(&dop->dop_intake); + return !list_empty(&tp->t_dfops->dop_pending) || + !list_empty(&tp->t_dfops->dop_intake); } /* @@ -311,7 +311,7 @@ static void xfs_defer_reset( struct xfs_trans *tp) { - ASSERT(!xfs_defer_has_unfinished_work(tp->t_dfops)); + ASSERT(!xfs_defer_has_unfinished_work(tp)); /* * Low mode state transfers across transaction rolls to mirror dfops @@ -332,7 +332,6 @@ int xfs_defer_finish_noroll( struct xfs_trans **tp) { - struct xfs_defer_ops *dop = (*tp)->t_dfops; struct xfs_defer_pending *dfp; struct list_head *li; struct list_head *n; @@ -342,24 +341,22 @@ xfs_defer_finish_noroll( ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES); - trace_xfs_defer_finish((*tp)->t_mountp, dop, _RET_IP_); + trace_xfs_defer_finish((*tp)->t_mountp, (*tp)->t_dfops, _RET_IP_); /* Until we run out of pending work to finish... */ - while (xfs_defer_has_unfinished_work(dop)) { + while (xfs_defer_has_unfinished_work(*tp)) { /* Log intents for work items sitting in the intake. */ - xfs_defer_intake_work(*tp, dop); + xfs_defer_intake_work(*tp); /* - * Roll the transaction and update dop in case dfops was - * embedded in the transaction. + * Roll the transaction. */ error = xfs_defer_trans_roll(tp); if (error) goto out; - dop = (*tp)->t_dfops; /* Log an intent-done item for the first pending item. */ - dfp = list_first_entry(&dop->dop_pending, + dfp = list_first_entry(&(*tp)->t_dfops->dop_pending, struct xfs_defer_pending, dfp_list); trace_xfs_defer_pending_finish((*tp)->t_mountp, dfp); dfp->dfp_done = dfp->dfp_type->create_done(*tp, dfp->dfp_intent, @@ -390,7 +387,7 @@ xfs_defer_finish_noroll( */ if (cleanup_fn) cleanup_fn(*tp, state, error); - xfs_defer_trans_abort(*tp, dop, error); + xfs_defer_trans_abort(*tp, error); goto out; } } @@ -420,9 +417,11 @@ xfs_defer_finish_noroll( out: if (error) - trace_xfs_defer_finish_error((*tp)->t_mountp, dop, error); + trace_xfs_defer_finish_error((*tp)->t_mountp, (*tp)->t_dfops, + error); else - trace_xfs_defer_finish_done((*tp)->t_mountp, dop, _RET_IP_); + trace_xfs_defer_finish_done((*tp)->t_mountp, (*tp)->t_dfops, + _RET_IP_); return error; } diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index 0de7504e5651..f051c8056141 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h @@ -41,7 +41,7 @@ int xfs_defer_finish_noroll(struct xfs_trans **tp); int xfs_defer_finish(struct xfs_trans **tp); void xfs_defer_cancel(struct xfs_trans *); void xfs_defer_init(struct xfs_trans *tp, struct xfs_defer_ops *dop); -bool xfs_defer_has_unfinished_work(struct xfs_defer_ops *dop); +bool xfs_defer_has_unfinished_work(struct xfs_trans *tp); void xfs_defer_move(struct xfs_trans *dtp, struct xfs_trans *stp); /* Description of a deferred type. */ diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index ae3c875a14e5..b0130b21f4de 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -929,7 +929,7 @@ __xfs_trans_commit( * Finish deferred items on final commit. Only permanent transactions * should ever have deferred ops. */ - WARN_ON_ONCE(xfs_defer_has_unfinished_work(tp->t_dfops) && + WARN_ON_ONCE(xfs_defer_has_unfinished_work(tp) && !(tp->t_flags & XFS_TRANS_PERM_LOG_RES)); if (!regrant && (tp->t_flags & XFS_TRANS_PERM_LOG_RES)) { error = xfs_defer_finish_noroll(&tp); -- cgit v1.2.3 From 9b1f4e9831df29776031e86e112e68784f1fc079 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 1 Aug 2018 07:20:33 -0700 Subject: xfs: cancel dfops on xfs_defer_finish() error The current semantics of xfs_defer_finish() require the caller to call xfs_defer_cancel() on error. This is slightly inconsistent with transaction commit error handling where a failed commit cleans up the transaction before returning. More significantly, the only requirement for exposure of ->dop_pending outside of xfs_defer_finish() is so that xfs_defer_cancel() can drain it on error. Since the only recourse of xfs_defer_finish() errors is cancellation, mirror the transaction logic and cancel remaining dfops before returning from xfs_defer_finish() with an error. Beside simplifying xfs_defer_finish() semantics, this ensures that xfs_defer_finish() always returns with an empty ->dop_pending and thus facilitates removal of the list from xfs_defer_ops. Signed-off-by: Brian Foster Reviewed-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr.c | 16 ++++++++-------- fs/xfs/libxfs/xfs_attr_remote.c | 4 ++-- fs/xfs/libxfs/xfs_defer.c | 11 ++++++----- fs/xfs/xfs_bmap_util.c | 2 +- fs/xfs/xfs_dquot.c | 2 +- fs/xfs/xfs_inode.c | 2 +- fs/xfs/xfs_reflink.c | 4 +--- fs/xfs/xfs_trans.c | 4 +--- 8 files changed, 21 insertions(+), 24 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 3190dfc21b60..1e671d4eb6fa 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -590,7 +590,7 @@ xfs_attr_leaf_addname( goto out_defer_cancel; error = xfs_defer_finish(&args->trans); if (error) - goto out_defer_cancel; + return error; /* * Commit the current trans (including the inode) and start @@ -678,7 +678,7 @@ xfs_attr_leaf_addname( goto out_defer_cancel; error = xfs_defer_finish(&args->trans); if (error) - goto out_defer_cancel; + return error; } /* @@ -741,7 +741,7 @@ xfs_attr_leaf_removename( goto out_defer_cancel; error = xfs_defer_finish(&args->trans); if (error) - goto out_defer_cancel; + return error; } return 0; out_defer_cancel: @@ -867,7 +867,7 @@ restart: goto out_defer_cancel; error = xfs_defer_finish(&args->trans); if (error) - goto out_defer_cancel; + goto out; /* * Commit the node conversion and start the next @@ -891,7 +891,7 @@ restart: goto out_defer_cancel; error = xfs_defer_finish(&args->trans); if (error) - goto out_defer_cancel; + goto out; } else { /* * Addition succeeded, update Btree hashvals. @@ -987,7 +987,7 @@ restart: goto out_defer_cancel; error = xfs_defer_finish(&args->trans); if (error) - goto out_defer_cancel; + goto out; } /* @@ -1110,7 +1110,7 @@ xfs_attr_node_removename( goto out_defer_cancel; error = xfs_defer_finish(&args->trans); if (error) - goto out_defer_cancel; + goto out; /* * Commit the Btree join operation and start a new trans. */ @@ -1141,7 +1141,7 @@ xfs_attr_node_removename( goto out_defer_cancel; error = xfs_defer_finish(&args->trans); if (error) - goto out_defer_cancel; + goto out; } else xfs_trans_brelse(args->trans, bp); } diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index f52552313773..af094063e402 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -488,7 +488,7 @@ xfs_attr_rmtval_set( goto out_defer_cancel; error = xfs_defer_finish(&args->trans); if (error) - goto out_defer_cancel; + return error; ASSERT(nmap == 1); ASSERT((map.br_startblock != DELAYSTARTBLOCK) && @@ -628,7 +628,7 @@ xfs_attr_rmtval_remove( goto out_defer_cancel; error = xfs_defer_finish(&args->trans); if (error) - goto out_defer_cancel; + return error; /* * Close out trans and start the next one in the chain. diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index 7079f534c735..b656a399cd71 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -416,14 +416,15 @@ xfs_defer_finish_noroll( } out: - if (error) + if (error) { trace_xfs_defer_finish_error((*tp)->t_mountp, (*tp)->t_dfops, error); - else - trace_xfs_defer_finish_done((*tp)->t_mountp, (*tp)->t_dfops, - _RET_IP_); + xfs_defer_cancel(*tp); + return error; + } - return error; + trace_xfs_defer_finish_done((*tp)->t_mountp, (*tp)->t_dfops, _RET_IP_); + return 0; } int diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 30ac1300dc49..d9dad399440a 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1624,7 +1624,7 @@ xfs_swap_extent_rmap( error = xfs_defer_finish(tpp); tp = *tpp; if (error) - goto out_defer; + goto out; tirec.br_startoff += rlen; if (tirec.br_startblock != HOLESTARTBLOCK && diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index e1196854dbcd..70a76ac41f01 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -371,7 +371,7 @@ xfs_dquot_disk_alloc( tp = *tpp; if (error) { xfs_buf_relse(bp); - goto error1; + goto error0; } *bpp = bp; return 0; diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 7bb46a0eecfc..d957a46dc1cb 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1571,7 +1571,7 @@ xfs_itruncate_extents_flags( */ error = xfs_defer_finish(&tp); if (error) - goto out_bmap_cancel; + goto out; error = xfs_trans_roll_inode(&tp, ip); if (error) diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index dce8ba8ab681..2ec562d75494 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -518,10 +518,8 @@ xfs_reflink_cancel_cow_blocks( /* Roll the transaction */ error = xfs_defer_finish(tpp); - if (error) { - xfs_defer_cancel(*tpp); + if (error) break; - } /* Remove the mapping from the CoW fork. */ xfs_bmap_del_extent_cow(ip, &icur, &got, &del); diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index b0130b21f4de..b050663c2a70 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -933,10 +933,8 @@ __xfs_trans_commit( !(tp->t_flags & XFS_TRANS_PERM_LOG_RES)); if (!regrant && (tp->t_flags & XFS_TRANS_PERM_LOG_RES)) { error = xfs_defer_finish_noroll(&tp); - if (error) { - xfs_defer_cancel(tp); + if (error) goto out_unreserve; - } } /* -- cgit v1.2.3 From 1ae093cbea3d1ef04e1344b9e3996a9e1763a91b Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 1 Aug 2018 07:20:34 -0700 Subject: xfs: replace xfs_defer_ops ->dop_pending with on-stack list The xfs_defer_ops ->dop_pending list is used to track active deferred operations once intents are logged. These items must be aborted in the event of an error. The list is populated as intents are logged and items are removed as they complete (or are aborted). Now that xfs_defer_finish() cancels on error, there is no need to ever access ->dop_pending outside of xfs_defer_finish(). The list is only ever populated after xfs_defer_finish() begins and is either completed or cancelled before it returns. Remove ->dop_pending from xfs_defer_ops and replace it with a local list in the xfs_defer_finish() path. Pass the local list to the various helpers now that it is not accessible via dfops. Note that we have to check for NULL in the abort case as the final tx roll occurs outside of the scope of the new local list (once the dfops has completed and thus drained the list). Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_defer.c | 146 +++++++++++++++++++++------------------------- fs/xfs/libxfs/xfs_defer.h | 1 - fs/xfs/xfs_trace.h | 5 +- fs/xfs/xfs_trans.c | 2 +- fs/xfs/xfs_trans.h | 1 - 5 files changed, 71 insertions(+), 84 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index b656a399cd71..1cbddcf539da 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -180,7 +180,7 @@ static const struct xfs_defer_op_type *defer_op_types[XFS_DEFER_OPS_TYPE_MAX]; * the pending list. */ STATIC void -xfs_defer_intake_work( +xfs_defer_create_intents( struct xfs_trans *tp) { struct xfs_defer_ops *dop = tp->t_dfops; @@ -190,21 +190,19 @@ xfs_defer_intake_work( list_for_each_entry(dfp, &dop->dop_intake, dfp_list) { dfp->dfp_intent = dfp->dfp_type->create_intent(tp, dfp->dfp_count); - trace_xfs_defer_intake_work(tp->t_mountp, dfp); + trace_xfs_defer_create_intent(tp->t_mountp, dfp); list_sort(tp->t_mountp, &dfp->dfp_work, dfp->dfp_type->diff_items); list_for_each(li, &dfp->dfp_work) dfp->dfp_type->log_item(tp, dfp->dfp_intent, li); } - - list_splice_tail_init(&dop->dop_intake, &dop->dop_pending); } /* Abort all the intents that were committed. */ STATIC void xfs_defer_trans_abort( struct xfs_trans *tp, - int error) + struct list_head *dop_pending) { struct xfs_defer_ops *dop = tp->t_dfops; struct xfs_defer_pending *dfp; @@ -212,24 +210,21 @@ xfs_defer_trans_abort( trace_xfs_defer_trans_abort(tp->t_mountp, dop, _RET_IP_); /* Abort intent items that don't have a done item. */ - list_for_each_entry(dfp, &dop->dop_pending, dfp_list) { + list_for_each_entry(dfp, dop_pending, dfp_list) { trace_xfs_defer_pending_abort(tp->t_mountp, dfp); if (dfp->dfp_intent && !dfp->dfp_done) { dfp->dfp_type->abort_intent(dfp->dfp_intent); dfp->dfp_intent = NULL; } } - - /* Shut down FS. */ - xfs_force_shutdown(tp->t_mountp, (error == -EFSCORRUPTED) ? - SHUTDOWN_CORRUPT_INCORE : SHUTDOWN_META_IO_ERROR); } /* Roll a transaction so we can do some deferred op processing. */ STATIC int xfs_defer_trans_roll( - struct xfs_trans **tp) + struct xfs_trans **tpp) { + struct xfs_trans *tp = *tpp; struct xfs_buf_log_item *bli; struct xfs_inode_log_item *ili; struct xfs_log_item *lip; @@ -239,7 +234,7 @@ xfs_defer_trans_roll( int i; int error; - list_for_each_entry(lip, &(*tp)->t_items, li_trans) { + list_for_each_entry(lip, &tp->t_items, li_trans) { switch (lip->li_type) { case XFS_LI_BUF: bli = container_of(lip, struct xfs_buf_log_item, @@ -249,7 +244,7 @@ xfs_defer_trans_roll( ASSERT(0); return -EFSCORRUPTED; } - xfs_trans_dirty_buf(*tp, bli->bli_buf); + xfs_trans_dirty_buf(tp, bli->bli_buf); bplist[bpcount++] = bli->bli_buf; } break; @@ -261,7 +256,7 @@ xfs_defer_trans_roll( ASSERT(0); return -EFSCORRUPTED; } - xfs_trans_log_inode(*tp, ili->ili_inode, + xfs_trans_log_inode(tp, ili->ili_inode, XFS_ILOG_CORE); iplist[ipcount++] = ili->ili_inode; } @@ -271,39 +266,30 @@ xfs_defer_trans_roll( } } - trace_xfs_defer_trans_roll((*tp)->t_mountp, (*tp)->t_dfops, _RET_IP_); + trace_xfs_defer_trans_roll(tp->t_mountp, tp->t_dfops, _RET_IP_); /* Roll the transaction. */ - error = xfs_trans_roll(tp); + error = xfs_trans_roll(tpp); + tp = *tpp; if (error) { - trace_xfs_defer_trans_roll_error((*tp)->t_mountp, - (*tp)->t_dfops, error); - xfs_defer_trans_abort(*tp, error); + trace_xfs_defer_trans_roll_error(tp->t_mountp, + tp->t_dfops, error); return error; } /* Rejoin the joined inodes. */ for (i = 0; i < ipcount; i++) - xfs_trans_ijoin(*tp, iplist[i], 0); + xfs_trans_ijoin(tp, iplist[i], 0); /* Rejoin the buffers and dirty them so the log moves forward. */ for (i = 0; i < bpcount; i++) { - xfs_trans_bjoin(*tp, bplist[i]); - xfs_trans_bhold(*tp, bplist[i]); + xfs_trans_bjoin(tp, bplist[i]); + xfs_trans_bhold(tp, bplist[i]); } return error; } -/* Do we have any work items to finish? */ -bool -xfs_defer_has_unfinished_work( - struct xfs_trans *tp) -{ - return !list_empty(&tp->t_dfops->dop_pending) || - !list_empty(&tp->t_dfops->dop_intake); -} - /* * Reset an already used dfops after finish. */ @@ -311,7 +297,7 @@ static void xfs_defer_reset( struct xfs_trans *tp) { - ASSERT(!xfs_defer_has_unfinished_work(tp)); + ASSERT(list_empty(&tp->t_dfops->dop_intake)); /* * Low mode state transfers across transaction rolls to mirror dfops @@ -320,6 +306,36 @@ xfs_defer_reset( tp->t_flags &= ~XFS_TRANS_LOWMODE; } +/* + * Free up any items left in the list. + */ +static void +xfs_defer_cancel_list( + struct xfs_mount *mp, + struct list_head *dop_list) +{ + struct xfs_defer_pending *dfp; + struct xfs_defer_pending *pli; + struct list_head *pwi; + struct list_head *n; + + /* + * Free the pending items. Caller should already have arranged + * for the intent items to be released. + */ + list_for_each_entry_safe(dfp, pli, dop_list, dfp_list) { + trace_xfs_defer_cancel_list(mp, dfp); + list_del(&dfp->dfp_list); + list_for_each_safe(pwi, n, &dfp->dfp_work) { + list_del(pwi); + dfp->dfp_count--; + dfp->dfp_type->cancel_item(pwi); + } + ASSERT(dfp->dfp_count == 0); + kmem_free(dfp); + } +} + /* * Finish all the pending work. This involves logging intent items for * any work items that wandered in since the last transaction roll (if @@ -338,15 +354,19 @@ xfs_defer_finish_noroll( void *state; int error = 0; void (*cleanup_fn)(struct xfs_trans *, void *, int); + LIST_HEAD(dop_pending); ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES); trace_xfs_defer_finish((*tp)->t_mountp, (*tp)->t_dfops, _RET_IP_); /* Until we run out of pending work to finish... */ - while (xfs_defer_has_unfinished_work(*tp)) { - /* Log intents for work items sitting in the intake. */ - xfs_defer_intake_work(*tp); + while (!list_empty(&dop_pending) || + !list_empty(&(*tp)->t_dfops->dop_intake)) { + /* log intents and pull in intake items */ + xfs_defer_create_intents(*tp); + list_splice_tail_init(&(*tp)->t_dfops->dop_intake, + &dop_pending); /* * Roll the transaction. @@ -356,8 +376,8 @@ xfs_defer_finish_noroll( goto out; /* Log an intent-done item for the first pending item. */ - dfp = list_first_entry(&(*tp)->t_dfops->dop_pending, - struct xfs_defer_pending, dfp_list); + dfp = list_first_entry(&dop_pending, struct xfs_defer_pending, + dfp_list); trace_xfs_defer_pending_finish((*tp)->t_mountp, dfp); dfp->dfp_done = dfp->dfp_type->create_done(*tp, dfp->dfp_intent, dfp->dfp_count); @@ -387,7 +407,6 @@ xfs_defer_finish_noroll( */ if (cleanup_fn) cleanup_fn(*tp, state, error); - xfs_defer_trans_abort(*tp, error); goto out; } } @@ -417,8 +436,11 @@ xfs_defer_finish_noroll( out: if (error) { + xfs_defer_trans_abort(*tp, &dop_pending); + xfs_force_shutdown((*tp)->t_mountp, SHUTDOWN_CORRUPT_INCORE); trace_xfs_defer_finish_error((*tp)->t_mountp, (*tp)->t_dfops, error); + xfs_defer_cancel_list((*tp)->t_mountp, &dop_pending); xfs_defer_cancel(*tp); return error; } @@ -442,54 +464,24 @@ xfs_defer_finish( return error; if ((*tp)->t_flags & XFS_TRANS_DIRTY) { error = xfs_defer_trans_roll(tp); - if (error) + if (error) { + xfs_force_shutdown((*tp)->t_mountp, + SHUTDOWN_CORRUPT_INCORE); return error; + } } xfs_defer_reset(*tp); return 0; } -/* - * Free up any items left in the list. - */ void xfs_defer_cancel( - struct xfs_trans *tp) + struct xfs_trans *tp) { - struct xfs_defer_ops *dop = tp->t_dfops; - struct xfs_defer_pending *dfp; - struct xfs_defer_pending *pli; - struct list_head *pwi; - struct list_head *n; + struct xfs_mount *mp = tp->t_mountp; - trace_xfs_defer_cancel(NULL, dop, _RET_IP_); - - /* - * Free the pending items. Caller should already have arranged - * for the intent items to be released. - */ - list_for_each_entry_safe(dfp, pli, &dop->dop_intake, dfp_list) { - trace_xfs_defer_intake_cancel(NULL, dfp); - list_del(&dfp->dfp_list); - list_for_each_safe(pwi, n, &dfp->dfp_work) { - list_del(pwi); - dfp->dfp_count--; - dfp->dfp_type->cancel_item(pwi); - } - ASSERT(dfp->dfp_count == 0); - kmem_free(dfp); - } - list_for_each_entry_safe(dfp, pli, &dop->dop_pending, dfp_list) { - trace_xfs_defer_pending_cancel(NULL, dfp); - list_del(&dfp->dfp_list); - list_for_each_safe(pwi, n, &dfp->dfp_work) { - list_del(pwi); - dfp->dfp_count--; - dfp->dfp_type->cancel_item(pwi); - } - ASSERT(dfp->dfp_count == 0); - kmem_free(dfp); - } + trace_xfs_defer_cancel(mp, tp->t_dfops, _RET_IP_); + xfs_defer_cancel_list(mp, &tp->t_dfops->dop_intake); } /* Add an item for later deferred processing. */ @@ -547,7 +539,6 @@ xfs_defer_init( memset(dop, 0, sizeof(struct xfs_defer_ops)); INIT_LIST_HEAD(&dop->dop_intake); - INIT_LIST_HEAD(&dop->dop_pending); if (tp) { ASSERT(tp->t_firstblock == NULLFSBLOCK); tp->t_dfops = dop; @@ -571,7 +562,6 @@ xfs_defer_move( ASSERT(dst != src); list_splice_init(&src->dop_intake, &dst->dop_intake); - list_splice_init(&src->dop_pending, &dst->dop_pending); /* * Low free space mode was historically controlled by a dfops field. diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index f051c8056141..f091bf3abeaf 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h @@ -41,7 +41,6 @@ int xfs_defer_finish_noroll(struct xfs_trans **tp); int xfs_defer_finish(struct xfs_trans **tp); void xfs_defer_cancel(struct xfs_trans *); void xfs_defer_init(struct xfs_trans *tp, struct xfs_defer_ops *dop); -bool xfs_defer_has_unfinished_work(struct xfs_trans *tp); void xfs_defer_move(struct xfs_trans *dtp, struct xfs_trans *stp); /* Description of a deferred type. */ diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 8807f1bb814a..fec9cfe3dfb4 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -2392,9 +2392,8 @@ DEFINE_DEFER_EVENT(xfs_defer_finish_done); DEFINE_DEFER_ERROR_EVENT(xfs_defer_trans_roll_error); DEFINE_DEFER_ERROR_EVENT(xfs_defer_finish_error); -DEFINE_DEFER_PENDING_EVENT(xfs_defer_intake_work); -DEFINE_DEFER_PENDING_EVENT(xfs_defer_intake_cancel); -DEFINE_DEFER_PENDING_EVENT(xfs_defer_pending_cancel); +DEFINE_DEFER_PENDING_EVENT(xfs_defer_create_intent); +DEFINE_DEFER_PENDING_EVENT(xfs_defer_cancel_list); DEFINE_DEFER_PENDING_EVENT(xfs_defer_pending_finish); DEFINE_DEFER_PENDING_EVENT(xfs_defer_pending_abort); diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index b050663c2a70..413e4138357f 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -929,7 +929,7 @@ __xfs_trans_commit( * Finish deferred items on final commit. Only permanent transactions * should ever have deferred ops. */ - WARN_ON_ONCE(xfs_defer_has_unfinished_work(tp) && + WARN_ON_ONCE(!list_empty(&tp->t_dfops->dop_intake) && !(tp->t_flags & XFS_TRANS_PERM_LOG_RES)); if (!regrant && (tp->t_flags & XFS_TRANS_PERM_LOG_RES)) { error = xfs_defer_finish_noroll(&tp); diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 299656dbf324..1cdc7c0ebeac 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -96,7 +96,6 @@ void xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item, #define XFS_DEFER_OPS_NR_BUFS 2 /* join up to two buffers */ struct xfs_defer_ops { struct list_head dop_intake; /* unlogged pending work */ - struct list_head dop_pending; /* logged pending work */ }; /* -- cgit v1.2.3 From 0f37d1780c3d864599fb377dcb47ad1aa0686b4e Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 1 Aug 2018 07:20:34 -0700 Subject: xfs: pass transaction to xfs_defer_add() The majority of remaining references to struct xfs_defer_ops in XFS are associated with xfs_defer_add(). At this point, there are no more external xfs_defer_ops users left. All instances of xfs_defer_ops are embedded in the transaction, which means we can safely pass the transaction down to the dfops add interface. Update xfs_defer_add() to receive the transaction as a parameter. Various subsystems implement wrappers to allocate and construct the context specific data structures for the associated deferred operation type. Update these to also carry the transaction down as needed and clean up unused dfops parameters along the way. This removes most of the remaining references to struct xfs_defer_ops throughout the code and facilitates removal of the structure. Signed-off-by: Brian Foster Reviewed-by: Darrick J. Wong Reviewed-by: Christoph Hellwig [darrick: fix unused variable warnings with ftrace disabled] Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_alloc.c | 9 ++--- fs/xfs/libxfs/xfs_bmap.c | 89 +++++++++++++++++++----------------------- fs/xfs/libxfs/xfs_bmap.h | 19 +++++---- fs/xfs/libxfs/xfs_bmap_btree.c | 2 +- fs/xfs/libxfs/xfs_defer.c | 5 ++- fs/xfs/libxfs/xfs_defer.h | 2 +- fs/xfs/libxfs/xfs_ialloc.c | 25 ++++++------ fs/xfs/libxfs/xfs_refcount.c | 80 ++++++++++++++++--------------------- fs/xfs/libxfs/xfs_refcount.h | 18 ++++----- fs/xfs/libxfs/xfs_rmap.c | 57 +++++++++++++-------------- fs/xfs/libxfs/xfs_rmap.h | 22 +++++------ fs/xfs/xfs_bmap_item.c | 3 +- fs/xfs/xfs_bmap_util.c | 13 ++---- fs/xfs/xfs_refcount_item.c | 14 ++----- fs/xfs/xfs_reflink.c | 21 +++++----- 15 files changed, 169 insertions(+), 210 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 9847c1632712..5580b6e23bb3 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -2198,12 +2198,12 @@ xfs_agfl_reset( */ STATIC void xfs_defer_agfl_block( - struct xfs_mount *mp, - struct xfs_defer_ops *dfops, + struct xfs_trans *tp, xfs_agnumber_t agno, xfs_fsblock_t agbno, struct xfs_owner_info *oinfo) { + struct xfs_mount *mp = tp->t_mountp; struct xfs_extent_free_item *new; /* new element */ ASSERT(xfs_bmap_free_item_zone != NULL); @@ -2216,7 +2216,7 @@ xfs_defer_agfl_block( trace_xfs_agfl_free_defer(mp, agno, 0, agbno, 1); - xfs_defer_add(dfops, XFS_DEFER_OPS_TYPE_AGFL_FREE, &new->xefi_list); + xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_AGFL_FREE, &new->xefi_list); } /* @@ -2325,8 +2325,7 @@ xfs_alloc_fix_freelist( /* defer agfl frees if dfops is provided */ if (tp->t_dfops) { - xfs_defer_agfl_block(mp, tp->t_dfops, args->agno, - bno, &targs.oinfo); + xfs_defer_agfl_block(tp, args->agno, bno, &targs.oinfo); } else { error = xfs_free_agfl_block(tp, args->agno, bno, agbp, &targs.oinfo); diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index d20f541b7061..c9fec0443f38 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -533,8 +533,7 @@ xfs_bmap_validate_ret( */ void __xfs_bmap_add_free( - struct xfs_mount *mp, - struct xfs_defer_ops *dfops, + struct xfs_trans *tp, xfs_fsblock_t bno, xfs_filblks_t len, struct xfs_owner_info *oinfo, @@ -542,8 +541,9 @@ __xfs_bmap_add_free( { struct xfs_extent_free_item *new; /* new element */ #ifdef DEBUG - xfs_agnumber_t agno; - xfs_agblock_t agbno; + struct xfs_mount *mp = tp->t_mountp; + xfs_agnumber_t agno; + xfs_agblock_t agbno; ASSERT(bno != NULLFSBLOCK); ASSERT(len > 0); @@ -566,9 +566,10 @@ __xfs_bmap_add_free( else xfs_rmap_skip_owner_update(&new->xefi_oinfo); new->xefi_skip_discard = skip_discard; - trace_xfs_bmap_free_defer(mp, XFS_FSB_TO_AGNO(mp, bno), 0, - XFS_FSB_TO_AGBNO(mp, bno), len); - xfs_defer_add(dfops, XFS_DEFER_OPS_TYPE_FREE, &new->xefi_list); + trace_xfs_bmap_free_defer(tp->t_mountp, + XFS_FSB_TO_AGNO(tp->t_mountp, bno), 0, + XFS_FSB_TO_AGBNO(tp->t_mountp, bno), len); + xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_FREE, &new->xefi_list); } /* @@ -624,7 +625,7 @@ xfs_bmap_btree_to_extents( if ((error = xfs_btree_check_block(cur, cblock, 0, cbp))) return error; xfs_rmap_ino_bmbt_owner(&oinfo, ip->i_ino, whichfork); - xfs_bmap_add_free(mp, cur->bc_tp->t_dfops, cbno, 1, &oinfo); + xfs_bmap_add_free(cur->bc_tp, cbno, 1, &oinfo); ip->i_d.di_nblocks--; xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); xfs_trans_binval(tp, cbp); @@ -1961,8 +1962,7 @@ xfs_bmap_add_extent_delay_real( /* add reverse mapping unless caller opted out */ if (!(bma->flags & XFS_BMAPI_NORMAP)) { - error = xfs_rmap_map_extent(mp, bma->tp->t_dfops, bma->ip, - whichfork, new); + error = xfs_rmap_map_extent(bma->tp, bma->ip, whichfork, new); if (error) goto done; } @@ -2026,7 +2026,6 @@ xfs_bmap_add_extent_unwritten_real( int state = xfs_bmap_fork_to_state(whichfork); struct xfs_mount *mp = ip->i_mount; struct xfs_bmbt_irec old; - struct xfs_defer_ops *dfops = tp ? tp->t_dfops : NULL; *logflagsp = 0; @@ -2445,7 +2444,7 @@ xfs_bmap_add_extent_unwritten_real( } /* update reverse mappings */ - error = xfs_rmap_convert_extent(mp, dfops, ip, whichfork, new); + error = xfs_rmap_convert_extent(mp, tp, ip, whichfork, new); if (error) goto done; @@ -2806,8 +2805,7 @@ xfs_bmap_add_extent_hole_real( /* add reverse mapping unless caller opted out */ if (!(flags & XFS_BMAPI_NORMAP)) { - error = xfs_rmap_map_extent(mp, tp->t_dfops, ip, whichfork, - new); + error = xfs_rmap_map_extent(tp, ip, whichfork, new); if (error) goto done; } @@ -4364,9 +4362,8 @@ xfs_bmapi_write( * the refcount btree for orphan recovery. */ if (whichfork == XFS_COW_FORK) { - error = xfs_refcount_alloc_cow_extent(mp, - tp->t_dfops, bma.blkno, - bma.length); + error = xfs_refcount_alloc_cow_extent(tp, + bma.blkno, bma.length); if (error) goto error0; } @@ -4852,7 +4849,6 @@ xfs_bmap_del_extent_real( uint qfield; /* quota field to update */ int state = xfs_bmap_fork_to_state(whichfork); struct xfs_bmbt_irec old; - struct xfs_defer_ops *dfops = tp ? tp->t_dfops : NULL; mp = ip->i_mount; XFS_STATS_INC(mp, xs_del_exlist); @@ -5036,7 +5032,7 @@ xfs_bmap_del_extent_real( } /* remove reverse mapping */ - error = xfs_rmap_unmap_extent(mp, dfops, ip, whichfork, del); + error = xfs_rmap_unmap_extent(tp, ip, whichfork, del); if (error) goto done; @@ -5045,11 +5041,11 @@ xfs_bmap_del_extent_real( */ if (do_fx && !(bflags & XFS_BMAPI_REMAP)) { if (xfs_is_reflink_inode(ip) && whichfork == XFS_DATA_FORK) { - error = xfs_refcount_decrease_extent(mp, dfops, del); + error = xfs_refcount_decrease_extent(tp, del); if (error) goto done; } else { - __xfs_bmap_add_free(mp, dfops, del->br_startblock, + __xfs_bmap_add_free(tp, del->br_startblock, del->br_blockcount, NULL, (bflags & XFS_BMAPI_NODISCARD) || del->br_state == XFS_EXT_UNWRITTEN); @@ -5489,6 +5485,7 @@ xfs_bmse_can_merge( */ STATIC int xfs_bmse_merge( + struct xfs_trans *tp, struct xfs_inode *ip, int whichfork, xfs_fileoff_t shift, /* shift fsb */ @@ -5496,8 +5493,7 @@ xfs_bmse_merge( struct xfs_bmbt_irec *got, /* extent to shift */ struct xfs_bmbt_irec *left, /* preceding extent */ struct xfs_btree_cur *cur, - int *logflags, /* output */ - struct xfs_defer_ops *dfops) + int *logflags) /* output */ { struct xfs_bmbt_irec new; xfs_filblks_t blockcount; @@ -5553,23 +5549,23 @@ done: &new); /* update reverse mapping. rmap functions merge the rmaps for us */ - error = xfs_rmap_unmap_extent(mp, dfops, ip, whichfork, got); + error = xfs_rmap_unmap_extent(tp, ip, whichfork, got); if (error) return error; memcpy(&new, got, sizeof(new)); new.br_startoff = left->br_startoff + left->br_blockcount; - return xfs_rmap_map_extent(mp, dfops, ip, whichfork, &new); + return xfs_rmap_map_extent(tp, ip, whichfork, &new); } static int xfs_bmap_shift_update_extent( + struct xfs_trans *tp, struct xfs_inode *ip, int whichfork, struct xfs_iext_cursor *icur, struct xfs_bmbt_irec *got, struct xfs_btree_cur *cur, int *logflags, - struct xfs_defer_ops *dfops, xfs_fileoff_t startoff) { struct xfs_mount *mp = ip->i_mount; @@ -5597,10 +5593,10 @@ xfs_bmap_shift_update_extent( got); /* update reverse mapping */ - error = xfs_rmap_unmap_extent(mp, dfops, ip, whichfork, &prev); + error = xfs_rmap_unmap_extent(tp, ip, whichfork, &prev); if (error) return error; - return xfs_rmap_map_extent(mp, dfops, ip, whichfork, got); + return xfs_rmap_map_extent(tp, ip, whichfork, got); } int @@ -5660,9 +5656,9 @@ xfs_bmap_collapse_extents( } if (xfs_bmse_can_merge(&prev, &got, offset_shift_fsb)) { - error = xfs_bmse_merge(ip, whichfork, offset_shift_fsb, - &icur, &got, &prev, cur, &logflags, - tp->t_dfops); + error = xfs_bmse_merge(tp, ip, whichfork, + offset_shift_fsb, &icur, &got, &prev, + cur, &logflags); if (error) goto del_cursor; goto done; @@ -5674,8 +5670,8 @@ xfs_bmap_collapse_extents( } } - error = xfs_bmap_shift_update_extent(ip, whichfork, &icur, &got, cur, - &logflags, tp->t_dfops, new_startoff); + error = xfs_bmap_shift_update_extent(tp, ip, whichfork, &icur, &got, + cur, &logflags, new_startoff); if (error) goto del_cursor; @@ -5801,8 +5797,8 @@ xfs_bmap_insert_extents( WARN_ON_ONCE(1); } - error = xfs_bmap_shift_update_extent(ip, whichfork, &icur, &got, cur, - &logflags, tp->t_dfops, new_startoff); + error = xfs_bmap_shift_update_extent(tp, ip, whichfork, &icur, &got, + cur, &logflags, new_startoff); if (error) goto del_cursor; @@ -5979,8 +5975,7 @@ xfs_bmap_is_update_needed( /* Record a bmap intent. */ static int __xfs_bmap_add( - struct xfs_mount *mp, - struct xfs_defer_ops *dfops, + struct xfs_trans *tp, enum xfs_bmap_intent_type type, struct xfs_inode *ip, int whichfork, @@ -5988,10 +5983,10 @@ __xfs_bmap_add( { struct xfs_bmap_intent *bi; - trace_xfs_bmap_defer(mp, - XFS_FSB_TO_AGNO(mp, bmap->br_startblock), + trace_xfs_bmap_defer(tp->t_mountp, + XFS_FSB_TO_AGNO(tp->t_mountp, bmap->br_startblock), type, - XFS_FSB_TO_AGBNO(mp, bmap->br_startblock), + XFS_FSB_TO_AGBNO(tp->t_mountp, bmap->br_startblock), ip->i_ino, whichfork, bmap->br_startoff, bmap->br_blockcount, @@ -6004,38 +5999,34 @@ __xfs_bmap_add( bi->bi_whichfork = whichfork; bi->bi_bmap = *bmap; - xfs_defer_add(dfops, XFS_DEFER_OPS_TYPE_BMAP, &bi->bi_list); + xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_BMAP, &bi->bi_list); return 0; } /* Map an extent into a file. */ int xfs_bmap_map_extent( - struct xfs_mount *mp, - struct xfs_defer_ops *dfops, + struct xfs_trans *tp, struct xfs_inode *ip, struct xfs_bmbt_irec *PREV) { if (!xfs_bmap_is_update_needed(PREV)) return 0; - return __xfs_bmap_add(mp, dfops, XFS_BMAP_MAP, ip, - XFS_DATA_FORK, PREV); + return __xfs_bmap_add(tp, XFS_BMAP_MAP, ip, XFS_DATA_FORK, PREV); } /* Unmap an extent out of a file. */ int xfs_bmap_unmap_extent( - struct xfs_mount *mp, - struct xfs_defer_ops *dfops, + struct xfs_trans *tp, struct xfs_inode *ip, struct xfs_bmbt_irec *PREV) { if (!xfs_bmap_is_update_needed(PREV)) return 0; - return __xfs_bmap_add(mp, dfops, XFS_BMAP_UNMAP, ip, - XFS_DATA_FORK, PREV); + return __xfs_bmap_add(tp, XFS_BMAP_UNMAP, ip, XFS_DATA_FORK, PREV); } /* diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 9165a878edcd..b6e9b639e731 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -184,9 +184,9 @@ void xfs_trim_extent(struct xfs_bmbt_irec *irec, xfs_fileoff_t bno, void xfs_trim_extent_eof(struct xfs_bmbt_irec *, struct xfs_inode *); int xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd); void xfs_bmap_local_to_extents_empty(struct xfs_inode *ip, int whichfork); -void __xfs_bmap_add_free(struct xfs_mount *mp, struct xfs_defer_ops *dfops, - xfs_fsblock_t bno, xfs_filblks_t len, - struct xfs_owner_info *oinfo, bool skip_discard); +void __xfs_bmap_add_free(struct xfs_trans *tp, xfs_fsblock_t bno, + xfs_filblks_t len, struct xfs_owner_info *oinfo, + bool skip_discard); void xfs_bmap_compute_maxlevels(struct xfs_mount *mp, int whichfork); int xfs_bmap_first_unused(struct xfs_trans *tp, struct xfs_inode *ip, xfs_extlen_t len, xfs_fileoff_t *unused, int whichfork); @@ -230,13 +230,12 @@ int xfs_bmapi_reserve_delalloc(struct xfs_inode *ip, int whichfork, static inline void xfs_bmap_add_free( - struct xfs_mount *mp, - struct xfs_defer_ops *dfops, + struct xfs_trans *tp, xfs_fsblock_t bno, xfs_filblks_t len, struct xfs_owner_info *oinfo) { - __xfs_bmap_add_free(mp, dfops, bno, len, oinfo, false); + __xfs_bmap_add_free(tp, bno, len, oinfo, false); } enum xfs_bmap_intent_type { @@ -256,10 +255,10 @@ int xfs_bmap_finish_one(struct xfs_trans *tp, struct xfs_inode *ip, enum xfs_bmap_intent_type type, int whichfork, xfs_fileoff_t startoff, xfs_fsblock_t startblock, xfs_filblks_t *blockcount, xfs_exntst_t state); -int xfs_bmap_map_extent(struct xfs_mount *mp, struct xfs_defer_ops *dfops, - struct xfs_inode *ip, struct xfs_bmbt_irec *imap); -int xfs_bmap_unmap_extent(struct xfs_mount *mp, struct xfs_defer_ops *dfops, - struct xfs_inode *ip, struct xfs_bmbt_irec *imap); +int xfs_bmap_map_extent(struct xfs_trans *tp, struct xfs_inode *ip, + struct xfs_bmbt_irec *imap); +int xfs_bmap_unmap_extent(struct xfs_trans *tp, struct xfs_inode *ip, + struct xfs_bmbt_irec *imap); static inline int xfs_bmap_fork_to_state(int whichfork) { diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 955e29de8cae..cdb74d2e2a43 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -289,7 +289,7 @@ xfs_bmbt_free_block( struct xfs_owner_info oinfo; xfs_rmap_ino_bmbt_owner(&oinfo, ip->i_ino, cur->bc_private.b.whichfork); - xfs_bmap_add_free(mp, cur->bc_tp->t_dfops, fsbno, 1, &oinfo); + xfs_bmap_add_free(cur->bc_tp, fsbno, 1, &oinfo); ip->i_d.di_nblocks--; xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index 1cbddcf539da..ce2286763531 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -487,12 +487,15 @@ xfs_defer_cancel( /* Add an item for later deferred processing. */ void xfs_defer_add( - struct xfs_defer_ops *dop, + struct xfs_trans *tp, enum xfs_defer_ops_type type, struct list_head *li) { + struct xfs_defer_ops *dop = tp->t_dfops; struct xfs_defer_pending *dfp = NULL; + ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); + /* * Add the item to a pending item at the end of the intake list. * If the last pending item has the same type, reuse it. Else, diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index f091bf3abeaf..b2675f1ca909 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h @@ -35,7 +35,7 @@ enum xfs_defer_ops_type { XFS_DEFER_OPS_TYPE_MAX, }; -void xfs_defer_add(struct xfs_defer_ops *dop, enum xfs_defer_ops_type type, +void xfs_defer_add(struct xfs_trans *tp, enum xfs_defer_ops_type type, struct list_head *h); int xfs_defer_finish_noroll(struct xfs_trans **tp); int xfs_defer_finish(struct xfs_trans **tp); diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 295304ad1bc1..a8f6db735d5d 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -1838,23 +1838,24 @@ out_error: */ STATIC void xfs_difree_inode_chunk( - struct xfs_mount *mp, + struct xfs_trans *tp, xfs_agnumber_t agno, - struct xfs_inobt_rec_incore *rec, - struct xfs_defer_ops *dfops) + struct xfs_inobt_rec_incore *rec) { - xfs_agblock_t sagbno = XFS_AGINO_TO_AGBNO(mp, rec->ir_startino); - int startidx, endidx; - int nextbit; - xfs_agblock_t agbno; - int contigblk; - struct xfs_owner_info oinfo; + struct xfs_mount *mp = tp->t_mountp; + xfs_agblock_t sagbno = XFS_AGINO_TO_AGBNO(mp, + rec->ir_startino); + int startidx, endidx; + int nextbit; + xfs_agblock_t agbno; + int contigblk; + struct xfs_owner_info oinfo; DECLARE_BITMAP(holemask, XFS_INOBT_HOLEMASK_BITS); xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INODES); if (!xfs_inobt_issparse(rec->ir_holemask)) { /* not sparse, calculate extent info directly */ - xfs_bmap_add_free(mp, dfops, XFS_AGB_TO_FSB(mp, agno, sagbno), + xfs_bmap_add_free(tp, XFS_AGB_TO_FSB(mp, agno, sagbno), mp->m_ialloc_blks, &oinfo); return; } @@ -1898,7 +1899,7 @@ xfs_difree_inode_chunk( ASSERT(agbno % mp->m_sb.sb_spino_align == 0); ASSERT(contigblk % mp->m_sb.sb_spino_align == 0); - xfs_bmap_add_free(mp, dfops, XFS_AGB_TO_FSB(mp, agno, agbno), + xfs_bmap_add_free(tp, XFS_AGB_TO_FSB(mp, agno, agbno), contigblk, &oinfo); /* reset range to current bit and carry on... */ @@ -2002,7 +2003,7 @@ xfs_difree_inobt( goto error0; } - xfs_difree_inode_chunk(mp, agno, &rec, tp->t_dfops); + xfs_difree_inode_chunk(tp, agno, &rec); } else { xic->deleted = false; diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index 86f297ca90cd..542aa1475b5f 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -34,11 +34,9 @@ enum xfs_refc_adjust_op { }; STATIC int __xfs_refcount_cow_alloc(struct xfs_btree_cur *rcur, - xfs_agblock_t agbno, xfs_extlen_t aglen, - struct xfs_defer_ops *dfops); + xfs_agblock_t agbno, xfs_extlen_t aglen); STATIC int __xfs_refcount_cow_free(struct xfs_btree_cur *rcur, - xfs_agblock_t agbno, xfs_extlen_t aglen, - struct xfs_defer_ops *dfops); + xfs_agblock_t agbno, xfs_extlen_t aglen); /* * Look up the first record less than or equal to [bno, len] in the btree @@ -870,7 +868,6 @@ xfs_refcount_adjust_extents( xfs_agblock_t *agbno, xfs_extlen_t *aglen, enum xfs_refc_adjust_op adj, - struct xfs_defer_ops *dfops, struct xfs_owner_info *oinfo) { struct xfs_refcount_irec ext, tmp; @@ -925,8 +922,8 @@ xfs_refcount_adjust_extents( fsbno = XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_private.a.agno, tmp.rc_startblock); - xfs_bmap_add_free(cur->bc_mp, dfops, fsbno, - tmp.rc_blockcount, oinfo); + xfs_bmap_add_free(cur->bc_tp, fsbno, + tmp.rc_blockcount, oinfo); } (*agbno) += tmp.rc_blockcount; @@ -968,8 +965,8 @@ xfs_refcount_adjust_extents( fsbno = XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_private.a.agno, ext.rc_startblock); - xfs_bmap_add_free(cur->bc_mp, dfops, fsbno, - ext.rc_blockcount, oinfo); + xfs_bmap_add_free(cur->bc_tp, fsbno, ext.rc_blockcount, + oinfo); } skip: @@ -998,7 +995,6 @@ xfs_refcount_adjust( xfs_agblock_t *new_agbno, xfs_extlen_t *new_aglen, enum xfs_refc_adjust_op adj, - struct xfs_defer_ops *dfops, struct xfs_owner_info *oinfo) { bool shape_changed; @@ -1043,7 +1039,7 @@ xfs_refcount_adjust( /* Now that we've taken care of the ends, adjust the middle extents */ error = xfs_refcount_adjust_extents(cur, new_agbno, new_aglen, - adj, dfops, oinfo); + adj, oinfo); if (error) goto out_error; @@ -1090,7 +1086,6 @@ xfs_refcount_finish_one( struct xfs_btree_cur **pcur) { struct xfs_mount *mp = tp->t_mountp; - struct xfs_defer_ops *dfops = tp->t_dfops; struct xfs_btree_cur *rcur; struct xfs_buf *agbp = NULL; int error = 0; @@ -1145,23 +1140,23 @@ xfs_refcount_finish_one( switch (type) { case XFS_REFCOUNT_INCREASE: error = xfs_refcount_adjust(rcur, bno, blockcount, &new_agbno, - new_len, XFS_REFCOUNT_ADJUST_INCREASE, dfops, NULL); + new_len, XFS_REFCOUNT_ADJUST_INCREASE, NULL); *new_fsb = XFS_AGB_TO_FSB(mp, agno, new_agbno); break; case XFS_REFCOUNT_DECREASE: error = xfs_refcount_adjust(rcur, bno, blockcount, &new_agbno, - new_len, XFS_REFCOUNT_ADJUST_DECREASE, dfops, NULL); + new_len, XFS_REFCOUNT_ADJUST_DECREASE, NULL); *new_fsb = XFS_AGB_TO_FSB(mp, agno, new_agbno); break; case XFS_REFCOUNT_ALLOC_COW: *new_fsb = startblock + blockcount; *new_len = 0; - error = __xfs_refcount_cow_alloc(rcur, bno, blockcount, dfops); + error = __xfs_refcount_cow_alloc(rcur, bno, blockcount); break; case XFS_REFCOUNT_FREE_COW: *new_fsb = startblock + blockcount; *new_len = 0; - error = __xfs_refcount_cow_free(rcur, bno, blockcount, dfops); + error = __xfs_refcount_cow_free(rcur, bno, blockcount); break; default: ASSERT(0); @@ -1183,16 +1178,16 @@ out_cur: */ static int __xfs_refcount_add( - struct xfs_mount *mp, - struct xfs_defer_ops *dfops, + struct xfs_trans *tp, enum xfs_refcount_intent_type type, xfs_fsblock_t startblock, xfs_extlen_t blockcount) { struct xfs_refcount_intent *ri; - trace_xfs_refcount_defer(mp, XFS_FSB_TO_AGNO(mp, startblock), - type, XFS_FSB_TO_AGBNO(mp, startblock), + trace_xfs_refcount_defer(tp->t_mountp, + XFS_FSB_TO_AGNO(tp->t_mountp, startblock), + type, XFS_FSB_TO_AGBNO(tp->t_mountp, startblock), blockcount); ri = kmem_alloc(sizeof(struct xfs_refcount_intent), @@ -1202,7 +1197,7 @@ __xfs_refcount_add( ri->ri_startblock = startblock; ri->ri_blockcount = blockcount; - xfs_defer_add(dfops, XFS_DEFER_OPS_TYPE_REFCOUNT, &ri->ri_list); + xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_REFCOUNT, &ri->ri_list); return 0; } @@ -1211,14 +1206,13 @@ __xfs_refcount_add( */ int xfs_refcount_increase_extent( - struct xfs_mount *mp, - struct xfs_defer_ops *dfops, + struct xfs_trans *tp, struct xfs_bmbt_irec *PREV) { - if (!xfs_sb_version_hasreflink(&mp->m_sb)) + if (!xfs_sb_version_hasreflink(&tp->t_mountp->m_sb)) return 0; - return __xfs_refcount_add(mp, dfops, XFS_REFCOUNT_INCREASE, + return __xfs_refcount_add(tp, XFS_REFCOUNT_INCREASE, PREV->br_startblock, PREV->br_blockcount); } @@ -1227,14 +1221,13 @@ xfs_refcount_increase_extent( */ int xfs_refcount_decrease_extent( - struct xfs_mount *mp, - struct xfs_defer_ops *dfops, + struct xfs_trans *tp, struct xfs_bmbt_irec *PREV) { - if (!xfs_sb_version_hasreflink(&mp->m_sb)) + if (!xfs_sb_version_hasreflink(&tp->t_mountp->m_sb)) return 0; - return __xfs_refcount_add(mp, dfops, XFS_REFCOUNT_DECREASE, + return __xfs_refcount_add(tp, XFS_REFCOUNT_DECREASE, PREV->br_startblock, PREV->br_blockcount); } @@ -1522,8 +1515,7 @@ STATIC int __xfs_refcount_cow_alloc( struct xfs_btree_cur *rcur, xfs_agblock_t agbno, - xfs_extlen_t aglen, - struct xfs_defer_ops *dfops) + xfs_extlen_t aglen) { trace_xfs_refcount_cow_increase(rcur->bc_mp, rcur->bc_private.a.agno, agbno, aglen); @@ -1540,8 +1532,7 @@ STATIC int __xfs_refcount_cow_free( struct xfs_btree_cur *rcur, xfs_agblock_t agbno, - xfs_extlen_t aglen, - struct xfs_defer_ops *dfops) + xfs_extlen_t aglen) { trace_xfs_refcount_cow_decrease(rcur->bc_mp, rcur->bc_private.a.agno, agbno, aglen); @@ -1554,47 +1545,45 @@ __xfs_refcount_cow_free( /* Record a CoW staging extent in the refcount btree. */ int xfs_refcount_alloc_cow_extent( - struct xfs_mount *mp, - struct xfs_defer_ops *dfops, + struct xfs_trans *tp, xfs_fsblock_t fsb, xfs_extlen_t len) { + struct xfs_mount *mp = tp->t_mountp; int error; if (!xfs_sb_version_hasreflink(&mp->m_sb)) return 0; - error = __xfs_refcount_add(mp, dfops, XFS_REFCOUNT_ALLOC_COW, - fsb, len); + error = __xfs_refcount_add(tp, XFS_REFCOUNT_ALLOC_COW, fsb, len); if (error) return error; /* Add rmap entry */ - return xfs_rmap_alloc_extent(mp, dfops, XFS_FSB_TO_AGNO(mp, fsb), + return xfs_rmap_alloc_extent(tp, XFS_FSB_TO_AGNO(mp, fsb), XFS_FSB_TO_AGBNO(mp, fsb), len, XFS_RMAP_OWN_COW); } /* Forget a CoW staging event in the refcount btree. */ int xfs_refcount_free_cow_extent( - struct xfs_mount *mp, - struct xfs_defer_ops *dfops, + struct xfs_trans *tp, xfs_fsblock_t fsb, xfs_extlen_t len) { + struct xfs_mount *mp = tp->t_mountp; int error; if (!xfs_sb_version_hasreflink(&mp->m_sb)) return 0; /* Remove rmap entry */ - error = xfs_rmap_free_extent(mp, dfops, XFS_FSB_TO_AGNO(mp, fsb), + error = xfs_rmap_free_extent(tp, XFS_FSB_TO_AGNO(mp, fsb), XFS_FSB_TO_AGBNO(mp, fsb), len, XFS_RMAP_OWN_COW); if (error) return error; - return __xfs_refcount_add(mp, dfops, XFS_REFCOUNT_FREE_COW, - fsb, len); + return __xfs_refcount_add(tp, XFS_REFCOUNT_FREE_COW, fsb, len); } struct xfs_refcount_recovery { @@ -1692,14 +1681,13 @@ xfs_refcount_recover_cow_leftovers( /* Free the orphan record */ agbno = rr->rr_rrec.rc_startblock - XFS_REFC_COW_START; fsb = XFS_AGB_TO_FSB(mp, agno, agbno); - error = xfs_refcount_free_cow_extent(mp, tp->t_dfops, fsb, + error = xfs_refcount_free_cow_extent(tp, fsb, rr->rr_rrec.rc_blockcount); if (error) goto out_trans; /* Free the block. */ - xfs_bmap_add_free(mp, tp->t_dfops, fsb, - rr->rr_rrec.rc_blockcount, NULL); + xfs_bmap_add_free(tp, fsb, rr->rr_rrec.rc_blockcount, NULL); error = xfs_trans_commit(tp); if (error) diff --git a/fs/xfs/libxfs/xfs_refcount.h b/fs/xfs/libxfs/xfs_refcount.h index 3b72c6dbf6ad..1d9c518575e7 100644 --- a/fs/xfs/libxfs/xfs_refcount.h +++ b/fs/xfs/libxfs/xfs_refcount.h @@ -29,10 +29,10 @@ struct xfs_refcount_intent { xfs_extlen_t ri_blockcount; }; -extern int xfs_refcount_increase_extent(struct xfs_mount *mp, - struct xfs_defer_ops *dfops, struct xfs_bmbt_irec *irec); -extern int xfs_refcount_decrease_extent(struct xfs_mount *mp, - struct xfs_defer_ops *dfops, struct xfs_bmbt_irec *irec); +extern int xfs_refcount_increase_extent(struct xfs_trans *tp, + struct xfs_bmbt_irec *irec); +extern int xfs_refcount_decrease_extent(struct xfs_trans *tp, + struct xfs_bmbt_irec *irec); extern void xfs_refcount_finish_one_cleanup(struct xfs_trans *tp, struct xfs_btree_cur *rcur, int error); @@ -45,12 +45,10 @@ extern int xfs_refcount_find_shared(struct xfs_btree_cur *cur, xfs_agblock_t agbno, xfs_extlen_t aglen, xfs_agblock_t *fbno, xfs_extlen_t *flen, bool find_end_of_shared); -extern int xfs_refcount_alloc_cow_extent(struct xfs_mount *mp, - struct xfs_defer_ops *dfops, xfs_fsblock_t fsb, - xfs_extlen_t len); -extern int xfs_refcount_free_cow_extent(struct xfs_mount *mp, - struct xfs_defer_ops *dfops, xfs_fsblock_t fsb, - xfs_extlen_t len); +extern int xfs_refcount_alloc_cow_extent(struct xfs_trans *tp, + xfs_fsblock_t fsb, xfs_extlen_t len); +extern int xfs_refcount_free_cow_extent(struct xfs_trans *tp, + xfs_fsblock_t fsb, xfs_extlen_t len); extern int xfs_refcount_recover_cow_leftovers(struct xfs_mount *mp, xfs_agnumber_t agno); diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index fb266fa2cc45..245af452840e 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -2277,18 +2277,18 @@ xfs_rmap_update_is_needed( */ static int __xfs_rmap_add( - struct xfs_mount *mp, - struct xfs_defer_ops *dfops, + struct xfs_trans *tp, enum xfs_rmap_intent_type type, uint64_t owner, int whichfork, struct xfs_bmbt_irec *bmap) { - struct xfs_rmap_intent *ri; + struct xfs_rmap_intent *ri; - trace_xfs_rmap_defer(mp, XFS_FSB_TO_AGNO(mp, bmap->br_startblock), + trace_xfs_rmap_defer(tp->t_mountp, + XFS_FSB_TO_AGNO(tp->t_mountp, bmap->br_startblock), type, - XFS_FSB_TO_AGBNO(mp, bmap->br_startblock), + XFS_FSB_TO_AGBNO(tp->t_mountp, bmap->br_startblock), owner, whichfork, bmap->br_startoff, bmap->br_blockcount, @@ -2301,23 +2301,22 @@ __xfs_rmap_add( ri->ri_whichfork = whichfork; ri->ri_bmap = *bmap; - xfs_defer_add(dfops, XFS_DEFER_OPS_TYPE_RMAP, &ri->ri_list); + xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_RMAP, &ri->ri_list); return 0; } /* Map an extent into a file. */ int xfs_rmap_map_extent( - struct xfs_mount *mp, - struct xfs_defer_ops *dfops, + struct xfs_trans *tp, struct xfs_inode *ip, int whichfork, struct xfs_bmbt_irec *PREV) { - if (!xfs_rmap_update_is_needed(mp, whichfork)) + if (!xfs_rmap_update_is_needed(tp->t_mountp, whichfork)) return 0; - return __xfs_rmap_add(mp, dfops, xfs_is_reflink_inode(ip) ? + return __xfs_rmap_add(tp, xfs_is_reflink_inode(ip) ? XFS_RMAP_MAP_SHARED : XFS_RMAP_MAP, ip->i_ino, whichfork, PREV); } @@ -2325,25 +2324,29 @@ xfs_rmap_map_extent( /* Unmap an extent out of a file. */ int xfs_rmap_unmap_extent( - struct xfs_mount *mp, - struct xfs_defer_ops *dfops, + struct xfs_trans *tp, struct xfs_inode *ip, int whichfork, struct xfs_bmbt_irec *PREV) { - if (!xfs_rmap_update_is_needed(mp, whichfork)) + if (!xfs_rmap_update_is_needed(tp->t_mountp, whichfork)) return 0; - return __xfs_rmap_add(mp, dfops, xfs_is_reflink_inode(ip) ? + return __xfs_rmap_add(tp, xfs_is_reflink_inode(ip) ? XFS_RMAP_UNMAP_SHARED : XFS_RMAP_UNMAP, ip->i_ino, whichfork, PREV); } -/* Convert a data fork extent from unwritten to real or vice versa. */ +/* + * Convert a data fork extent from unwritten to real or vice versa. + * + * Note that tp can be NULL here as no transaction is used for COW fork + * unwritten conversion. + */ int xfs_rmap_convert_extent( struct xfs_mount *mp, - struct xfs_defer_ops *dfops, + struct xfs_trans *tp, struct xfs_inode *ip, int whichfork, struct xfs_bmbt_irec *PREV) @@ -2351,7 +2354,7 @@ xfs_rmap_convert_extent( if (!xfs_rmap_update_is_needed(mp, whichfork)) return 0; - return __xfs_rmap_add(mp, dfops, xfs_is_reflink_inode(ip) ? + return __xfs_rmap_add(tp, xfs_is_reflink_inode(ip) ? XFS_RMAP_CONVERT_SHARED : XFS_RMAP_CONVERT, ip->i_ino, whichfork, PREV); } @@ -2359,8 +2362,7 @@ xfs_rmap_convert_extent( /* Schedule the creation of an rmap for non-file data. */ int xfs_rmap_alloc_extent( - struct xfs_mount *mp, - struct xfs_defer_ops *dfops, + struct xfs_trans *tp, xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, @@ -2368,23 +2370,21 @@ xfs_rmap_alloc_extent( { struct xfs_bmbt_irec bmap; - if (!xfs_rmap_update_is_needed(mp, XFS_DATA_FORK)) + if (!xfs_rmap_update_is_needed(tp->t_mountp, XFS_DATA_FORK)) return 0; - bmap.br_startblock = XFS_AGB_TO_FSB(mp, agno, bno); + bmap.br_startblock = XFS_AGB_TO_FSB(tp->t_mountp, agno, bno); bmap.br_blockcount = len; bmap.br_startoff = 0; bmap.br_state = XFS_EXT_NORM; - return __xfs_rmap_add(mp, dfops, XFS_RMAP_ALLOC, owner, - XFS_DATA_FORK, &bmap); + return __xfs_rmap_add(tp, XFS_RMAP_ALLOC, owner, XFS_DATA_FORK, &bmap); } /* Schedule the deletion of an rmap for non-file data. */ int xfs_rmap_free_extent( - struct xfs_mount *mp, - struct xfs_defer_ops *dfops, + struct xfs_trans *tp, xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, @@ -2392,16 +2392,15 @@ xfs_rmap_free_extent( { struct xfs_bmbt_irec bmap; - if (!xfs_rmap_update_is_needed(mp, XFS_DATA_FORK)) + if (!xfs_rmap_update_is_needed(tp->t_mountp, XFS_DATA_FORK)) return 0; - bmap.br_startblock = XFS_AGB_TO_FSB(mp, agno, bno); + bmap.br_startblock = XFS_AGB_TO_FSB(tp->t_mountp, agno, bno); bmap.br_blockcount = len; bmap.br_startoff = 0; bmap.br_state = XFS_EXT_NORM; - return __xfs_rmap_add(mp, dfops, XFS_RMAP_FREE, owner, - XFS_DATA_FORK, &bmap); + return __xfs_rmap_add(tp, XFS_RMAP_FREE, owner, XFS_DATA_FORK, &bmap); } /* Compare rmap records. Returns -1 if a < b, 1 if a > b, and 0 if equal. */ diff --git a/fs/xfs/libxfs/xfs_rmap.h b/fs/xfs/libxfs/xfs_rmap.h index 9f19454768b2..157dc722ad35 100644 --- a/fs/xfs/libxfs/xfs_rmap.h +++ b/fs/xfs/libxfs/xfs_rmap.h @@ -185,21 +185,17 @@ struct xfs_rmap_intent { }; /* functions for updating the rmapbt based on bmbt map/unmap operations */ -int xfs_rmap_map_extent(struct xfs_mount *mp, struct xfs_defer_ops *dfops, +int xfs_rmap_map_extent(struct xfs_trans *tp, struct xfs_inode *ip, + int whichfork, struct xfs_bmbt_irec *imap); +int xfs_rmap_unmap_extent(struct xfs_trans *tp, struct xfs_inode *ip, + int whichfork, struct xfs_bmbt_irec *imap); +int xfs_rmap_convert_extent(struct xfs_mount *mp, struct xfs_trans *tp, struct xfs_inode *ip, int whichfork, struct xfs_bmbt_irec *imap); -int xfs_rmap_unmap_extent(struct xfs_mount *mp, struct xfs_defer_ops *dfops, - struct xfs_inode *ip, int whichfork, - struct xfs_bmbt_irec *imap); -int xfs_rmap_convert_extent(struct xfs_mount *mp, struct xfs_defer_ops *dfops, - struct xfs_inode *ip, int whichfork, - struct xfs_bmbt_irec *imap); -int xfs_rmap_alloc_extent(struct xfs_mount *mp, struct xfs_defer_ops *dfops, - xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, - uint64_t owner); -int xfs_rmap_free_extent(struct xfs_mount *mp, struct xfs_defer_ops *dfops, - xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, - uint64_t owner); +int xfs_rmap_alloc_extent(struct xfs_trans *tp, xfs_agnumber_t agno, + xfs_agblock_t bno, xfs_extlen_t len, uint64_t owner); +int xfs_rmap_free_extent(struct xfs_trans *tp, xfs_agnumber_t agno, + xfs_agblock_t bno, xfs_extlen_t len, uint64_t owner); void xfs_rmap_finish_one_cleanup(struct xfs_trans *tp, struct xfs_btree_cur *rcur, int error); diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c index e828e0b51814..ce45f066995e 100644 --- a/fs/xfs/xfs_bmap_item.c +++ b/fs/xfs/xfs_bmap_item.c @@ -486,8 +486,7 @@ xfs_bui_recover( irec.br_blockcount = count; irec.br_startoff = bmap->me_startoff; irec.br_state = state; - error = xfs_bmap_unmap_extent(tp->t_mountp, tp->t_dfops, ip, - &irec); + error = xfs_bmap_unmap_extent(tp, ip, &irec); if (error) goto err_inode; } diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index d9dad399440a..addbd74ecd8e 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1534,7 +1534,6 @@ xfs_swap_extent_rmap( struct xfs_inode *tip) { struct xfs_trans *tp = *tpp; - struct xfs_mount *mp = tp->t_mountp; struct xfs_bmbt_irec irec; struct xfs_bmbt_irec uirec; struct xfs_bmbt_irec tirec; @@ -1598,26 +1597,22 @@ xfs_swap_extent_rmap( trace_xfs_swap_extent_rmap_remap_piece(tip, &uirec); /* Remove the mapping from the donor file. */ - error = xfs_bmap_unmap_extent(mp, tp->t_dfops, tip, - &uirec); + error = xfs_bmap_unmap_extent(tp, tip, &uirec); if (error) goto out_defer; /* Remove the mapping from the source file. */ - error = xfs_bmap_unmap_extent(mp, tp->t_dfops, ip, - &irec); + error = xfs_bmap_unmap_extent(tp, ip, &irec); if (error) goto out_defer; /* Map the donor file's blocks into the source file. */ - error = xfs_bmap_map_extent(mp, tp->t_dfops, ip, - &uirec); + error = xfs_bmap_map_extent(tp, ip, &uirec); if (error) goto out_defer; /* Map the source file's blocks into the donor file. */ - error = xfs_bmap_map_extent(mp, tp->t_dfops, tip, - &irec); + error = xfs_bmap_map_extent(tp, tip, &irec); if (error) goto out_defer; diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c index 43c4ac374cba..fce38b56b962 100644 --- a/fs/xfs/xfs_refcount_item.c +++ b/fs/xfs/xfs_refcount_item.c @@ -490,24 +490,18 @@ xfs_cui_recover( irec.br_blockcount = new_len; switch (type) { case XFS_REFCOUNT_INCREASE: - error = xfs_refcount_increase_extent( - tp->t_mountp, tp->t_dfops, - &irec); + error = xfs_refcount_increase_extent(tp, &irec); break; case XFS_REFCOUNT_DECREASE: - error = xfs_refcount_decrease_extent( - tp->t_mountp, tp->t_dfops, - &irec); + error = xfs_refcount_decrease_extent(tp, &irec); break; case XFS_REFCOUNT_ALLOC_COW: - error = xfs_refcount_alloc_cow_extent( - tp->t_mountp, tp->t_dfops, + error = xfs_refcount_alloc_cow_extent(tp, irec.br_startblock, irec.br_blockcount); break; case XFS_REFCOUNT_FREE_COW: - error = xfs_refcount_free_cow_extent( - tp->t_mountp, tp->t_dfops, + error = xfs_refcount_free_cow_extent(tp, irec.br_startblock, irec.br_blockcount); break; diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 2ec562d75494..cbceb320a2e7 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -506,15 +506,13 @@ xfs_reflink_cancel_cow_blocks( ASSERT((*tpp)->t_firstblock == NULLFSBLOCK); /* Free the CoW orphan record. */ - error = xfs_refcount_free_cow_extent(ip->i_mount, - (*tpp)->t_dfops, del.br_startblock, - del.br_blockcount); + error = xfs_refcount_free_cow_extent(*tpp, + del.br_startblock, del.br_blockcount); if (error) break; - xfs_bmap_add_free(ip->i_mount, (*tpp)->t_dfops, - del.br_startblock, del.br_blockcount, - NULL); + xfs_bmap_add_free(*tpp, del.br_startblock, + del.br_blockcount, NULL); /* Roll the transaction */ error = xfs_defer_finish(tpp); @@ -694,14 +692,13 @@ xfs_reflink_end_cow( trace_xfs_reflink_cow_remap(ip, &del); /* Free the CoW orphan record. */ - error = xfs_refcount_free_cow_extent(tp->t_mountp, tp->t_dfops, - del.br_startblock, del.br_blockcount); + error = xfs_refcount_free_cow_extent(tp, del.br_startblock, + del.br_blockcount); if (error) goto out_cancel; /* Map the new blocks into the data fork. */ - error = xfs_bmap_map_extent(tp->t_mountp, tp->t_dfops, ip, - &del); + error = xfs_bmap_map_extent(tp, ip, &del); if (error) goto out_cancel; @@ -1046,12 +1043,12 @@ xfs_reflink_remap_extent( uirec.br_blockcount, uirec.br_startblock); /* Update the refcount tree */ - error = xfs_refcount_increase_extent(mp, tp->t_dfops, &uirec); + error = xfs_refcount_increase_extent(tp, &uirec); if (error) goto out_cancel; /* Map the new blocks into the data fork. */ - error = xfs_bmap_map_extent(mp, tp->t_dfops, ip, &uirec); + error = xfs_bmap_map_extent(tp, ip, &uirec); if (error) goto out_cancel; -- cgit v1.2.3 From c03edc9e49b6a3c1f4b27f505a04093ab333b245 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 1 Aug 2018 07:20:35 -0700 Subject: xfs: always defer agfl block frees The AGFL fixup code conditionally defers block frees from the free list based on whether the current transaction has an associated xfs_defer_ops structure. Now that dfops is embedded in the transaction and the internal dfops is used unconditionally, this invariant is always true. Remove the now dead logic to check for ->t_dfops in xfs_alloc_fix_freelist() and unconditionally defer AGFL block frees. Signed-off-by: Brian Foster Reviewed-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_alloc.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 5580b6e23bb3..e1c0c0d2f1b0 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -2323,15 +2323,8 @@ xfs_alloc_fix_freelist( if (error) goto out_agbp_relse; - /* defer agfl frees if dfops is provided */ - if (tp->t_dfops) { - xfs_defer_agfl_block(tp, args->agno, bno, &targs.oinfo); - } else { - error = xfs_free_agfl_block(tp, args->agno, bno, agbp, - &targs.oinfo); - if (error) - goto out_agbp_relse; - } + /* defer agfl frees */ + xfs_defer_agfl_block(tp, args->agno, bno, &targs.oinfo); } targs.tp = tp; -- cgit v1.2.3 From 9d9e6233859706875c392707efd6d516cfb764fb Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 1 Aug 2018 07:20:35 -0700 Subject: xfs: fold dfops into the transaction struct xfs_defer_ops has now been reduced to a single list_head. The external dfops mechanism is unused and thus everywhere a (permanent) transaction is accessible the associated dfops structure is as well. Remove the xfs_defer_ops structure and fold the list_head into the transaction. Also remove the last remnant of external dfops in xfs_trans_dup(). Signed-off-by: Brian Foster Reviewed-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 1 - fs/xfs/libxfs/xfs_btree.h | 1 - fs/xfs/libxfs/xfs_da_btree.h | 1 - fs/xfs/libxfs/xfs_defer.c | 67 +++++++++++++------------------------------- fs/xfs/libxfs/xfs_defer.h | 2 -- fs/xfs/libxfs/xfs_dir2.c | 2 -- fs/xfs/libxfs/xfs_dir2.h | 1 - fs/xfs/xfs_inode.h | 1 - fs/xfs/xfs_reflink.c | 5 ++-- fs/xfs/xfs_trace.h | 40 ++++++++++++-------------- fs/xfs/xfs_trans.c | 13 ++++----- fs/xfs/xfs_trans.h | 8 ++---- 12 files changed, 46 insertions(+), 96 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index c9fec0443f38..5648a177e0ac 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -4286,7 +4286,6 @@ xfs_bmapi_write( bma.ip = ip; bma.total = total; bma.datatype = 0; - ASSERT(!tp || tp->t_dfops); while (bno < end && n < *nmap) { bool need_alloc = false, wasdelay = false; diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 503615f4d729..e3b3e9dce5da 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -7,7 +7,6 @@ #define __XFS_BTREE_H__ struct xfs_buf; -struct xfs_defer_ops; struct xfs_inode; struct xfs_mount; struct xfs_trans; diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h index 59e290ef334f..84dd865b6c3d 100644 --- a/fs/xfs/libxfs/xfs_da_btree.h +++ b/fs/xfs/libxfs/xfs_da_btree.h @@ -7,7 +7,6 @@ #ifndef __XFS_DA_BTREE_H__ #define __XFS_DA_BTREE_H__ -struct xfs_defer_ops; struct xfs_inode; struct xfs_trans; struct zone; diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index ce2286763531..e792b167150a 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -183,11 +183,10 @@ STATIC void xfs_defer_create_intents( struct xfs_trans *tp) { - struct xfs_defer_ops *dop = tp->t_dfops; struct list_head *li; struct xfs_defer_pending *dfp; - list_for_each_entry(dfp, &dop->dop_intake, dfp_list) { + list_for_each_entry(dfp, &tp->t_dfops, dfp_list) { dfp->dfp_intent = dfp->dfp_type->create_intent(tp, dfp->dfp_count); trace_xfs_defer_create_intent(tp->t_mountp, dfp); @@ -204,10 +203,9 @@ xfs_defer_trans_abort( struct xfs_trans *tp, struct list_head *dop_pending) { - struct xfs_defer_ops *dop = tp->t_dfops; struct xfs_defer_pending *dfp; - trace_xfs_defer_trans_abort(tp->t_mountp, dop, _RET_IP_); + trace_xfs_defer_trans_abort(tp, _RET_IP_); /* Abort intent items that don't have a done item. */ list_for_each_entry(dfp, dop_pending, dfp_list) { @@ -266,14 +264,13 @@ xfs_defer_trans_roll( } } - trace_xfs_defer_trans_roll(tp->t_mountp, tp->t_dfops, _RET_IP_); + trace_xfs_defer_trans_roll(tp, _RET_IP_); /* Roll the transaction. */ error = xfs_trans_roll(tpp); tp = *tpp; if (error) { - trace_xfs_defer_trans_roll_error(tp->t_mountp, - tp->t_dfops, error); + trace_xfs_defer_trans_roll_error(tp, error); return error; } @@ -297,7 +294,7 @@ static void xfs_defer_reset( struct xfs_trans *tp) { - ASSERT(list_empty(&tp->t_dfops->dop_intake)); + ASSERT(list_empty(&tp->t_dfops)); /* * Low mode state transfers across transaction rolls to mirror dfops @@ -358,15 +355,13 @@ xfs_defer_finish_noroll( ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES); - trace_xfs_defer_finish((*tp)->t_mountp, (*tp)->t_dfops, _RET_IP_); + trace_xfs_defer_finish(*tp, _RET_IP_); /* Until we run out of pending work to finish... */ - while (!list_empty(&dop_pending) || - !list_empty(&(*tp)->t_dfops->dop_intake)) { + while (!list_empty(&dop_pending) || !list_empty(&(*tp)->t_dfops)) { /* log intents and pull in intake items */ xfs_defer_create_intents(*tp); - list_splice_tail_init(&(*tp)->t_dfops->dop_intake, - &dop_pending); + list_splice_tail_init(&(*tp)->t_dfops, &dop_pending); /* * Roll the transaction. @@ -438,14 +433,13 @@ out: if (error) { xfs_defer_trans_abort(*tp, &dop_pending); xfs_force_shutdown((*tp)->t_mountp, SHUTDOWN_CORRUPT_INCORE); - trace_xfs_defer_finish_error((*tp)->t_mountp, (*tp)->t_dfops, - error); + trace_xfs_defer_finish_error(*tp, error); xfs_defer_cancel_list((*tp)->t_mountp, &dop_pending); xfs_defer_cancel(*tp); return error; } - trace_xfs_defer_finish_done((*tp)->t_mountp, (*tp)->t_dfops, _RET_IP_); + trace_xfs_defer_finish_done(*tp, _RET_IP_); return 0; } @@ -480,8 +474,8 @@ xfs_defer_cancel( { struct xfs_mount *mp = tp->t_mountp; - trace_xfs_defer_cancel(mp, tp->t_dfops, _RET_IP_); - xfs_defer_cancel_list(mp, &tp->t_dfops->dop_intake); + trace_xfs_defer_cancel(tp, _RET_IP_); + xfs_defer_cancel_list(mp, &tp->t_dfops); } /* Add an item for later deferred processing. */ @@ -491,7 +485,6 @@ xfs_defer_add( enum xfs_defer_ops_type type, struct list_head *li) { - struct xfs_defer_ops *dop = tp->t_dfops; struct xfs_defer_pending *dfp = NULL; ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); @@ -501,8 +494,8 @@ xfs_defer_add( * If the last pending item has the same type, reuse it. Else, * create a new pending item at the end of the intake list. */ - if (!list_empty(&dop->dop_intake)) { - dfp = list_last_entry(&dop->dop_intake, + if (!list_empty(&tp->t_dfops)) { + dfp = list_last_entry(&tp->t_dfops, struct xfs_defer_pending, dfp_list); if (dfp->dfp_type->type != type || (dfp->dfp_type->max_items && @@ -517,7 +510,7 @@ xfs_defer_add( dfp->dfp_done = NULL; dfp->dfp_count = 0; INIT_LIST_HEAD(&dfp->dfp_work); - list_add_tail(&dfp->dfp_list, &dop->dop_intake); + list_add_tail(&dfp->dfp_list, &tp->t_dfops); } list_add_tail(li, &dfp->dfp_work); @@ -532,39 +525,17 @@ xfs_defer_init_op_type( defer_op_types[type->type] = type; } -/* Initialize a deferred operation. */ -void -xfs_defer_init( - struct xfs_trans *tp, - struct xfs_defer_ops *dop) -{ - struct xfs_mount *mp = NULL; - - memset(dop, 0, sizeof(struct xfs_defer_ops)); - INIT_LIST_HEAD(&dop->dop_intake); - if (tp) { - ASSERT(tp->t_firstblock == NULLFSBLOCK); - tp->t_dfops = dop; - mp = tp->t_mountp; - } - trace_xfs_defer_init(mp, dop, _RET_IP_); -} - /* - * Move state from one xfs_defer_ops to another and reset the source to initial - * state. This is primarily used to carry state forward across transaction rolls - * with internal dfops. + * Move deferred ops from one transaction to another and reset the source to + * initial state. This is primarily used to carry state forward across + * transaction rolls with pending dfops. */ void xfs_defer_move( struct xfs_trans *dtp, struct xfs_trans *stp) { - struct xfs_defer_ops *dst = dtp->t_dfops; - struct xfs_defer_ops *src = stp->t_dfops; - ASSERT(dst != src); - - list_splice_init(&src->dop_intake, &dst->dop_intake); + list_splice_init(&stp->t_dfops, &dtp->t_dfops); /* * Low free space mode was historically controlled by a dfops field. diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index b2675f1ca909..2584a5b95b0d 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h @@ -7,7 +7,6 @@ #define __XFS_DEFER_H__ struct xfs_defer_op_type; -struct xfs_defer_ops; /* * Save a log intent item and a list of extents, so that we can replay @@ -40,7 +39,6 @@ void xfs_defer_add(struct xfs_trans *tp, enum xfs_defer_ops_type type, int xfs_defer_finish_noroll(struct xfs_trans **tp); int xfs_defer_finish(struct xfs_trans **tp); void xfs_defer_cancel(struct xfs_trans *); -void xfs_defer_init(struct xfs_trans *tp, struct xfs_defer_ops *dop); void xfs_defer_move(struct xfs_trans *dtp, struct xfs_trans *stp); /* Description of a deferred type. */ diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 4ea1fddb126f..229152cd1a24 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -424,7 +424,6 @@ xfs_dir_removename( int v; /* type-checking value */ ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); - ASSERT(tp->t_dfops); XFS_STATS_INC(dp->i_mount, xs_dir_remove); args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS); @@ -483,7 +482,6 @@ xfs_dir_replace( int v; /* type-checking value */ ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); - ASSERT(tp->t_dfops); rval = xfs_dir_ino_validate(tp->t_mountp, inum); if (rval) diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index ba5acd03de94..c3e3f6b813d8 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -9,7 +9,6 @@ #include "xfs_da_format.h" #include "xfs_da_btree.h" -struct xfs_defer_ops; struct xfs_da_args; struct xfs_inode; struct xfs_mount; diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 79a3e61a6991..be2014520155 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -15,7 +15,6 @@ struct xfs_dinode; struct xfs_inode; struct xfs_buf; -struct xfs_defer_ops; struct xfs_bmbt_irec; struct xfs_inode_log_item; struct xfs_mount; diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index cbceb320a2e7..38f405415b88 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -502,7 +502,6 @@ xfs_reflink_cancel_cow_blocks( if (error) break; } else if (del.br_state == XFS_EXT_UNWRITTEN || cancel_real) { - ASSERT((*tpp)->t_dfops); ASSERT((*tpp)->t_firstblock == NULLFSBLOCK); /* Free the CoW orphan record. */ @@ -678,7 +677,7 @@ xfs_reflink_end_cow( goto prev_extent; /* Unmap the old blocks in the data fork. */ - ASSERT(tp->t_dfops && tp->t_firstblock == NULLFSBLOCK); + ASSERT(tp->t_firstblock == NULLFSBLOCK); rlen = del.br_blockcount; error = __xfs_bunmapi(tp, ip, del.br_startoff, &rlen, 0, 1); if (error) @@ -1021,7 +1020,7 @@ xfs_reflink_remap_extent( /* Unmap the old blocks in the data fork. */ rlen = unmap_len; while (rlen) { - ASSERT(tp->t_dfops && tp->t_firstblock == NULLFSBLOCK); + ASSERT(tp->t_firstblock == NULLFSBLOCK); error = __xfs_bunmapi(tp, ip, destoff, &rlen, 0, 1); if (error) goto out_cancel; diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index fec9cfe3dfb4..ad315e83bc02 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -2213,57 +2213,54 @@ DEFINE_BTREE_CUR_EVENT(xfs_btree_overlapped_query_range); /* deferred ops */ struct xfs_defer_pending; -struct xfs_defer_ops; DECLARE_EVENT_CLASS(xfs_defer_class, - TP_PROTO(struct xfs_mount *mp, struct xfs_defer_ops *dop, - unsigned long caller_ip), - TP_ARGS(mp, dop, caller_ip), + TP_PROTO(struct xfs_trans *tp, unsigned long caller_ip), + TP_ARGS(tp, caller_ip), TP_STRUCT__entry( __field(dev_t, dev) - __field(void *, dop) + __field(struct xfs_trans *, tp) __field(char, committed) __field(unsigned long, caller_ip) ), TP_fast_assign( - __entry->dev = mp ? mp->m_super->s_dev : 0; - __entry->dop = dop; + __entry->dev = tp->t_mountp->m_super->s_dev; + __entry->tp = tp; __entry->caller_ip = caller_ip; ), - TP_printk("dev %d:%d ops %p caller %pS", + TP_printk("dev %d:%d tp %p caller %pS", MAJOR(__entry->dev), MINOR(__entry->dev), - __entry->dop, + __entry->tp, (char *)__entry->caller_ip) ) #define DEFINE_DEFER_EVENT(name) \ DEFINE_EVENT(xfs_defer_class, name, \ - TP_PROTO(struct xfs_mount *mp, struct xfs_defer_ops *dop, \ - unsigned long caller_ip), \ - TP_ARGS(mp, dop, caller_ip)) + TP_PROTO(struct xfs_trans *tp, unsigned long caller_ip), \ + TP_ARGS(tp, caller_ip)) DECLARE_EVENT_CLASS(xfs_defer_error_class, - TP_PROTO(struct xfs_mount *mp, struct xfs_defer_ops *dop, int error), - TP_ARGS(mp, dop, error), + TP_PROTO(struct xfs_trans *tp, int error), + TP_ARGS(tp, error), TP_STRUCT__entry( __field(dev_t, dev) - __field(void *, dop) + __field(struct xfs_trans *, tp) __field(char, committed) __field(int, error) ), TP_fast_assign( - __entry->dev = mp ? mp->m_super->s_dev : 0; - __entry->dop = dop; + __entry->dev = tp->t_mountp->m_super->s_dev; + __entry->tp = tp; __entry->error = error; ), - TP_printk("dev %d:%d ops %p err %d", + TP_printk("dev %d:%d tp %p err %d", MAJOR(__entry->dev), MINOR(__entry->dev), - __entry->dop, + __entry->tp, __entry->error) ) #define DEFINE_DEFER_ERROR_EVENT(name) \ DEFINE_EVENT(xfs_defer_error_class, name, \ - TP_PROTO(struct xfs_mount *mp, struct xfs_defer_ops *dop, int error), \ - TP_ARGS(mp, dop, error)) + TP_PROTO(struct xfs_trans *tp, int error), \ + TP_ARGS(tp, error)) DECLARE_EVENT_CLASS(xfs_defer_pending_class, TP_PROTO(struct xfs_mount *mp, struct xfs_defer_pending *dfp), @@ -2382,7 +2379,6 @@ DEFINE_EVENT(xfs_map_extent_deferred_class, name, \ xfs_exntst_t state), \ TP_ARGS(mp, agno, op, agbno, ino, whichfork, offset, len, state)) -DEFINE_DEFER_EVENT(xfs_defer_init); DEFINE_DEFER_EVENT(xfs_defer_cancel); DEFINE_DEFER_EVENT(xfs_defer_trans_roll); DEFINE_DEFER_EVENT(xfs_defer_trans_abort); diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 413e4138357f..bedc5a5133a5 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -100,6 +100,7 @@ xfs_trans_dup( ntp->t_mountp = tp->t_mountp; INIT_LIST_HEAD(&ntp->t_items); INIT_LIST_HEAD(&ntp->t_busy); + INIT_LIST_HEAD(&ntp->t_dfops); ntp->t_firstblock = NULLFSBLOCK; ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); @@ -120,12 +121,8 @@ xfs_trans_dup( tp->t_rtx_res = tp->t_rtx_res_used; ntp->t_pflags = tp->t_pflags; - /* copy the dfops pointer if it's external, otherwise move it */ - xfs_defer_init(ntp, &ntp->t_dfops_internal); - if (tp->t_dfops != &tp->t_dfops_internal) - ntp->t_dfops = tp->t_dfops; - else - xfs_defer_move(ntp, tp); + /* move deferred ops over to the new tp */ + xfs_defer_move(ntp, tp); xfs_trans_dup_dqinfo(tp, ntp); @@ -280,8 +277,8 @@ xfs_trans_alloc( tp->t_mountp = mp; INIT_LIST_HEAD(&tp->t_items); INIT_LIST_HEAD(&tp->t_busy); + INIT_LIST_HEAD(&tp->t_dfops); tp->t_firstblock = NULLFSBLOCK; - xfs_defer_init(tp, &tp->t_dfops_internal); error = xfs_trans_reserve(tp, resp, blocks, rtextents); if (error) { @@ -929,7 +926,7 @@ __xfs_trans_commit( * Finish deferred items on final commit. Only permanent transactions * should ever have deferred ops. */ - WARN_ON_ONCE(!list_empty(&tp->t_dfops->dop_intake) && + WARN_ON_ONCE(!list_empty(&tp->t_dfops) && !(tp->t_flags & XFS_TRANS_PERM_LOG_RES)); if (!regrant && (tp->t_flags & XFS_TRANS_PERM_LOG_RES)) { error = xfs_defer_finish_noroll(&tp); diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 1cdc7c0ebeac..c3d278e96ad1 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -90,13 +90,10 @@ void xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item, #define XFS_ITEM_FLUSHING 3 /* - * Deferred operations tracking structure. + * Deferred operation item relogging limits. */ #define XFS_DEFER_OPS_NR_INODES 2 /* join up to two inodes */ #define XFS_DEFER_OPS_NR_BUFS 2 /* join up to two buffers */ -struct xfs_defer_ops { - struct list_head dop_intake; /* unlogged pending work */ -}; /* * This is the structure maintained for every active transaction. @@ -114,7 +111,6 @@ typedef struct xfs_trans { struct xlog_ticket *t_ticket; /* log mgr ticket */ struct xfs_mount *t_mountp; /* ptr to fs mount struct */ struct xfs_dquot_acct *t_dqinfo; /* acctg info for dquots */ - struct xfs_defer_ops *t_dfops; /* dfops reference */ int64_t t_icount_delta; /* superblock icount change */ int64_t t_ifree_delta; /* superblock ifree change */ int64_t t_fdblocks_delta; /* superblock fdblocks chg */ @@ -136,8 +132,8 @@ typedef struct xfs_trans { int64_t t_rextslog_delta;/* superblocks rextslog chg */ struct list_head t_items; /* log item descriptors */ struct list_head t_busy; /* list of busy extents */ + struct list_head t_dfops; /* deferred operations */ unsigned long t_pflags; /* saved process flags state */ - struct xfs_defer_ops t_dfops_internal; } xfs_trans_t; /* -- cgit v1.2.3 From c2b6e1591b6b15e1dcd9c1596b0371b6abc48fed Mon Sep 17 00:00:00 2001 From: Thomas Bianchi Date: Wed, 1 Aug 2018 12:58:34 -0700 Subject: xfs: substitute spaces with tabs Inside xfs_attr_shortform_list removes spaces at the beginnig of the line and replaces with tabs. Issue found by checkpatch. ERROR: code indent should use tabs where possible Signed-off-by: Thomas Bianchi Reviewed-by: Bill O'Donnell Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_attr_list.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c index f9ca80154c9c..a58034049995 100644 --- a/fs/xfs/xfs_attr_list.c +++ b/fs/xfs/xfs_attr_list.c @@ -87,7 +87,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) */ if (context->bufsize == 0 || (XFS_ISRESET_CURSOR(cursor) && - (dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) { + (dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) { for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) { context->put_listent(context, sfe->flags, -- cgit v1.2.3 From 1f31c98d650ca342e2f54cb17c4554ad110c5a11 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 1 Aug 2018 15:50:27 -0700 Subject: xfs: only validate summary counts on primary superblock Skip the summary counter checks for secondary superblocks and inprogress primary superblocks because mkfs has always written those out with zeroed summary counters. Signed-off-by: Darrick J. Wong Reviewed-by: Carlos Maiolino --- fs/xfs/libxfs/xfs_sb.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index ca1b3a7a9171..081f46e30556 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -148,6 +148,7 @@ xfs_validate_sb_read( STATIC int xfs_validate_sb_write( struct xfs_mount *mp, + struct xfs_buf *bp, struct xfs_sb *sbp) { /* @@ -155,10 +156,15 @@ xfs_validate_sb_write( * the superblock. We skip this in the read validator because there * could be newer superblocks in the log and if the values are garbage * even after replay we'll recalculate them at the end of log mount. + * + * mkfs has traditionally written zeroed counters to inprogress and + * secondary superblocks, so allow this usage to continue because + * we never read counters from such superblocks. */ - if (sbp->sb_fdblocks > sbp->sb_dblocks || - !xfs_verify_icount(mp, sbp->sb_icount) || - sbp->sb_ifree > sbp->sb_icount) { + if (XFS_BUF_ADDR(bp) == XFS_SB_DADDR && !sbp->sb_inprogress && + (sbp->sb_fdblocks > sbp->sb_dblocks || + !xfs_verify_icount(mp, sbp->sb_icount) || + sbp->sb_ifree > sbp->sb_icount)) { xfs_warn(mp, "SB summary counter sanity check failed"); return -EFSCORRUPTED; } @@ -756,7 +762,7 @@ xfs_sb_write_verify( error = xfs_validate_sb_common(mp, bp, &sb); if (error) goto out_error; - error = xfs_validate_sb_write(mp, &sb); + error = xfs_validate_sb_write(mp, bp, &sb); if (error) goto out_error; -- cgit v1.2.3 From a0e336ba3e3d1c7ec0f738a2e2e203434c00b08e Mon Sep 17 00:00:00 2001 From: Huang Chong Date: Fri, 3 Aug 2018 08:17:54 -0700 Subject: xfs: fix a comment in xfs_log_reserve Fix the comment in xfs_log_reserve to avoid confusing. Signed-of-by: Huang Chong Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 00df4f39093a..c3b610b687d1 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -410,7 +410,7 @@ out_error: } /* - * Reserve log space and return a ticket corresponding the reservation. + * Reserve log space and return a ticket corresponding to the reservation. * * Each reservation is going to reserve extra space for a log record header. * When writes happen to the on-disk log, we don't subtract the length of the -- cgit v1.2.3 From 2ba090d521c5e09f32316c179d25bb6f699d3568 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 7 Aug 2018 10:57:12 -0700 Subject: xfs: use WRITE_ONCE to update if_seq This adds ordering of the updates and makes sure we always see the if_seq update before the extent tree is modified. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_iext_tree.c | 20 +++++++++++++++++--- fs/xfs/xfs_aops.c | 4 ++-- fs/xfs/xfs_iomap.c | 3 ++- 3 files changed, 21 insertions(+), 6 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_iext_tree.c b/fs/xfs/libxfs/xfs_iext_tree.c index 8a7aea041ee1..771dd072015d 100644 --- a/fs/xfs/libxfs/xfs_iext_tree.c +++ b/fs/xfs/libxfs/xfs_iext_tree.c @@ -14,6 +14,7 @@ #include "xfs_inode_fork.h" #include "xfs_trans_resv.h" #include "xfs_mount.h" +#include "xfs_bmap.h" #include "xfs_trace.h" /* @@ -612,6 +613,19 @@ xfs_iext_realloc_root( cur->leaf = new; } +/* + * Increment the sequence counter if we are on a COW fork. This allows + * the writeback code to skip looking for a COW extent if the COW fork + * hasn't changed. We use WRITE_ONCE here to ensure the update to the + * sequence counter is seen before the modifications to the extent + * tree itself take effect. + */ +static inline void xfs_iext_inc_seq(struct xfs_ifork *ifp, int state) +{ + if (state & BMAP_COWFORK) + WRITE_ONCE(ifp->if_seq, READ_ONCE(ifp->if_seq) + 1); +} + void xfs_iext_insert( struct xfs_inode *ip, @@ -624,7 +638,7 @@ xfs_iext_insert( struct xfs_iext_leaf *new = NULL; int nr_entries, i; - ifp->if_seq++; + xfs_iext_inc_seq(ifp, state); if (ifp->if_height == 0) xfs_iext_alloc_root(ifp, cur); @@ -866,7 +880,7 @@ xfs_iext_remove( ASSERT(ifp->if_u1.if_root != NULL); ASSERT(xfs_iext_valid(ifp, cur)); - ifp->if_seq++; + xfs_iext_inc_seq(ifp, state); nr_entries = xfs_iext_leaf_nr_entries(ifp, leaf, cur->pos) - 1; for (i = cur->pos; i < nr_entries; i++) @@ -974,7 +988,7 @@ xfs_iext_update_extent( { struct xfs_ifork *ifp = xfs_iext_state_to_fork(ip, state); - ifp->if_seq++; + xfs_iext_inc_seq(ifp, state); if (cur->pos == 0) { struct xfs_bmbt_irec old; diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 235b4ddcd324..49f5f5896a43 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -351,7 +351,7 @@ xfs_map_blocks( if (imap_valid && (!xfs_inode_has_cow_data(ip) || wpc->io_type == XFS_IO_COW || - wpc->cow_seq == ip->i_cowfp->if_seq)) + wpc->cow_seq == READ_ONCE(ip->i_cowfp->if_seq))) return 0; if (XFS_FORCED_SHUTDOWN(mp)) @@ -380,7 +380,7 @@ xfs_map_blocks( xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, &imap)) cow_fsb = imap.br_startoff; if (cow_fsb != NULLFILEOFF && cow_fsb <= offset_fsb) { - wpc->cow_seq = ip->i_cowfp->if_seq; + wpc->cow_seq = READ_ONCE(ip->i_cowfp->if_seq); xfs_iunlock(ip, XFS_ILOCK_SHARED); /* * Truncate can race with writeback since writeback doesn't diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 3282575e2df4..6320aca39f39 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -655,6 +655,7 @@ xfs_iomap_write_allocate( unsigned int *cow_seq) { xfs_mount_t *mp = ip->i_mount; + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); xfs_fileoff_t offset_fsb, last_block; xfs_fileoff_t end_fsb, map_start_fsb; xfs_filblks_t count_fsb; @@ -768,7 +769,7 @@ xfs_iomap_write_allocate( goto error0; if (whichfork == XFS_COW_FORK) - *cow_seq = XFS_IFORK_PTR(ip, whichfork)->if_seq; + *cow_seq = READ_ONCE(ifp->if_seq); xfs_iunlock(ip, XFS_ILOCK_EXCL); } -- cgit v1.2.3 From 73971b172a435079340007bee12b4944cc599a8a Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Tue, 7 Aug 2018 10:57:13 -0700 Subject: xfs: remove dead error handling code in xfs_dquot_disk_alloc() Colin Ian King reports that commit 82ff27bc52 ("xfs: automatic dfops buffer relogging") leaves around some dead error handling code in xfs_dquot_disk_alloc(). This was discovered via Coverity scan. Since the associated commit eliminates the act of joining a buffer to a dfops, this intermediate error state is no longer possible and the error handling code can be removed. Since the caller cancels the transaction on error, which cancels the dfops, eliminate the unnecessary xfs_defer_cancel() call and error handling labels. Fixes: 82ff27bc52 ("xfs: automatic dfops buffer relogging") Reported-by: Colin Ian King Signed-off-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_dquot.c | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 70a76ac41f01..87e6dd5326d5 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -311,7 +311,7 @@ xfs_dquot_disk_alloc( XFS_DQUOT_CLUSTER_SIZE_FSB, XFS_BMAPI_METADATA, XFS_QM_DQALLOC_SPACE_RES(mp), &map, &nmaps); if (error) - goto error0; + return error; ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB); ASSERT(nmaps == 1); ASSERT((map.br_startblock != DELAYSTARTBLOCK) && @@ -325,10 +325,8 @@ xfs_dquot_disk_alloc( /* now we can just get the buffer (there's nothing to read yet) */ bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, dqp->q_blkno, mp->m_quotainfo->qi_dqchunklen, 0); - if (!bp) { - error = -ENOMEM; - goto error1; - } + if (!bp) + return -ENOMEM; bp->b_ops = &xfs_dquot_buf_ops; /* @@ -349,10 +347,8 @@ xfs_dquot_disk_alloc( * the buffer locked across the _defer_finish call. We can now do * this correctly with xfs_defer_bjoin. * - * Above, we allocated a disk block for the dquot information and - * used get_buf to initialize the dquot. If the _defer_bjoin fails, - * the buffer is still locked to *tpp, so we must _bhold_release and - * then _trans_brelse the buffer. If the _defer_finish fails, the old + * Above, we allocated a disk block for the dquot information and used + * get_buf to initialize the dquot. If the _defer_finish fails, the old * transaction is gone but the new buffer is not joined or held to any * transaction, so we must _buf_relse it. * @@ -362,24 +358,14 @@ xfs_dquot_disk_alloc( * manually or by committing the transaction. */ xfs_trans_bhold(tp, bp); - if (error) { - xfs_trans_bhold_release(tp, bp); - xfs_trans_brelse(tp, bp); - goto error1; - } error = xfs_defer_finish(tpp); tp = *tpp; if (error) { xfs_buf_relse(bp); - goto error0; + return error; } *bpp = bp; return 0; - -error1: - xfs_defer_cancel(tp); -error0: - return error; } /* -- cgit v1.2.3 From f9ed6debca45dd9bcc02d77c98822d50aba342f4 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 9 Aug 2018 22:42:53 -0700 Subject: xfs: repair the AGF Regenerate the AGF from the rmap data. Signed-off-by: Darrick J. Wong Reviewed-by: Brian Foster --- fs/xfs/scrub/agheader_repair.c | 379 +++++++++++++++++++++++++++++++++++++++++ fs/xfs/scrub/repair.c | 27 ++- fs/xfs/scrub/repair.h | 2 + fs/xfs/scrub/scrub.c | 2 +- 4 files changed, 400 insertions(+), 10 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/scrub/agheader_repair.c b/fs/xfs/scrub/agheader_repair.c index 1e96621ece3a..aa180492a4a5 100644 --- a/fs/xfs/scrub/agheader_repair.c +++ b/fs/xfs/scrub/agheader_repair.c @@ -17,12 +17,19 @@ #include "xfs_sb.h" #include "xfs_inode.h" #include "xfs_alloc.h" +#include "xfs_alloc_btree.h" #include "xfs_ialloc.h" +#include "xfs_ialloc_btree.h" #include "xfs_rmap.h" +#include "xfs_rmap_btree.h" +#include "xfs_refcount.h" +#include "xfs_refcount_btree.h" #include "scrub/xfs_scrub.h" #include "scrub/scrub.h" #include "scrub/common.h" #include "scrub/trace.h" +#include "scrub/repair.h" +#include "scrub/bitmap.h" /* Superblock */ @@ -54,3 +61,375 @@ xrep_superblock( xfs_trans_log_buf(sc->tp, bp, 0, BBTOB(bp->b_length) - 1); return error; } + +/* AGF */ + +struct xrep_agf_allocbt { + struct xfs_scrub *sc; + xfs_agblock_t freeblks; + xfs_agblock_t longest; +}; + +/* Record free space shape information. */ +STATIC int +xrep_agf_walk_allocbt( + struct xfs_btree_cur *cur, + struct xfs_alloc_rec_incore *rec, + void *priv) +{ + struct xrep_agf_allocbt *raa = priv; + int error = 0; + + if (xchk_should_terminate(raa->sc, &error)) + return error; + + raa->freeblks += rec->ar_blockcount; + if (rec->ar_blockcount > raa->longest) + raa->longest = rec->ar_blockcount; + return error; +} + +/* Does this AGFL block look sane? */ +STATIC int +xrep_agf_check_agfl_block( + struct xfs_mount *mp, + xfs_agblock_t agbno, + void *priv) +{ + struct xfs_scrub *sc = priv; + + if (!xfs_verify_agbno(mp, sc->sa.agno, agbno)) + return -EFSCORRUPTED; + return 0; +} + +/* + * Offset within the xrep_find_ag_btree array for each btree type. Avoid the + * XFS_BTNUM_ names here to avoid creating a sparse array. + */ +enum { + XREP_AGF_BNOBT = 0, + XREP_AGF_CNTBT, + XREP_AGF_RMAPBT, + XREP_AGF_REFCOUNTBT, + XREP_AGF_END, + XREP_AGF_MAX +}; + +/* Check a btree root candidate. */ +static inline bool +xrep_check_btree_root( + struct xfs_scrub *sc, + struct xrep_find_ag_btree *fab) +{ + struct xfs_mount *mp = sc->mp; + xfs_agnumber_t agno = sc->sm->sm_agno; + + return xfs_verify_agbno(mp, agno, fab->root) && + fab->height <= XFS_BTREE_MAXLEVELS; +} + +/* + * Given the btree roots described by *fab, find the roots, check them for + * sanity, and pass the root data back out via *fab. + * + * This is /also/ a chicken and egg problem because we have to use the rmapbt + * (rooted in the AGF) to find the btrees rooted in the AGF. We also have no + * idea if the btrees make any sense. If we hit obvious corruptions in those + * btrees we'll bail out. + */ +STATIC int +xrep_agf_find_btrees( + struct xfs_scrub *sc, + struct xfs_buf *agf_bp, + struct xrep_find_ag_btree *fab, + struct xfs_buf *agfl_bp) +{ + struct xfs_agf *old_agf = XFS_BUF_TO_AGF(agf_bp); + int error; + + /* Go find the root data. */ + error = xrep_find_ag_btree_roots(sc, agf_bp, fab, agfl_bp); + if (error) + return error; + + /* We must find the bnobt, cntbt, and rmapbt roots. */ + if (!xrep_check_btree_root(sc, &fab[XREP_AGF_BNOBT]) || + !xrep_check_btree_root(sc, &fab[XREP_AGF_CNTBT]) || + !xrep_check_btree_root(sc, &fab[XREP_AGF_RMAPBT])) + return -EFSCORRUPTED; + + /* + * We relied on the rmapbt to reconstruct the AGF. If we get a + * different root then something's seriously wrong. + */ + if (fab[XREP_AGF_RMAPBT].root != + be32_to_cpu(old_agf->agf_roots[XFS_BTNUM_RMAPi])) + return -EFSCORRUPTED; + + /* We must find the refcountbt root if that feature is enabled. */ + if (xfs_sb_version_hasreflink(&sc->mp->m_sb) && + !xrep_check_btree_root(sc, &fab[XREP_AGF_REFCOUNTBT])) + return -EFSCORRUPTED; + + return 0; +} + +/* + * Reinitialize the AGF header, making an in-core copy of the old contents so + * that we know which in-core state needs to be reinitialized. + */ +STATIC void +xrep_agf_init_header( + struct xfs_scrub *sc, + struct xfs_buf *agf_bp, + struct xfs_agf *old_agf) +{ + struct xfs_mount *mp = sc->mp; + struct xfs_agf *agf = XFS_BUF_TO_AGF(agf_bp); + + memcpy(old_agf, agf, sizeof(*old_agf)); + memset(agf, 0, BBTOB(agf_bp->b_length)); + agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC); + agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION); + agf->agf_seqno = cpu_to_be32(sc->sa.agno); + agf->agf_length = cpu_to_be32(xfs_ag_block_count(mp, sc->sa.agno)); + agf->agf_flfirst = old_agf->agf_flfirst; + agf->agf_fllast = old_agf->agf_fllast; + agf->agf_flcount = old_agf->agf_flcount; + if (xfs_sb_version_hascrc(&mp->m_sb)) + uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid); + + /* Mark the incore AGF data stale until we're done fixing things. */ + ASSERT(sc->sa.pag->pagf_init); + sc->sa.pag->pagf_init = 0; +} + +/* Set btree root information in an AGF. */ +STATIC void +xrep_agf_set_roots( + struct xfs_scrub *sc, + struct xfs_agf *agf, + struct xrep_find_ag_btree *fab) +{ + agf->agf_roots[XFS_BTNUM_BNOi] = + cpu_to_be32(fab[XREP_AGF_BNOBT].root); + agf->agf_levels[XFS_BTNUM_BNOi] = + cpu_to_be32(fab[XREP_AGF_BNOBT].height); + + agf->agf_roots[XFS_BTNUM_CNTi] = + cpu_to_be32(fab[XREP_AGF_CNTBT].root); + agf->agf_levels[XFS_BTNUM_CNTi] = + cpu_to_be32(fab[XREP_AGF_CNTBT].height); + + agf->agf_roots[XFS_BTNUM_RMAPi] = + cpu_to_be32(fab[XREP_AGF_RMAPBT].root); + agf->agf_levels[XFS_BTNUM_RMAPi] = + cpu_to_be32(fab[XREP_AGF_RMAPBT].height); + + if (xfs_sb_version_hasreflink(&sc->mp->m_sb)) { + agf->agf_refcount_root = + cpu_to_be32(fab[XREP_AGF_REFCOUNTBT].root); + agf->agf_refcount_level = + cpu_to_be32(fab[XREP_AGF_REFCOUNTBT].height); + } +} + +/* Update all AGF fields which derive from btree contents. */ +STATIC int +xrep_agf_calc_from_btrees( + struct xfs_scrub *sc, + struct xfs_buf *agf_bp) +{ + struct xrep_agf_allocbt raa = { .sc = sc }; + struct xfs_btree_cur *cur = NULL; + struct xfs_agf *agf = XFS_BUF_TO_AGF(agf_bp); + struct xfs_mount *mp = sc->mp; + xfs_agblock_t btreeblks; + xfs_agblock_t blocks; + int error; + + /* Update the AGF counters from the bnobt. */ + cur = xfs_allocbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.agno, + XFS_BTNUM_BNO); + error = xfs_alloc_query_all(cur, xrep_agf_walk_allocbt, &raa); + if (error) + goto err; + error = xfs_btree_count_blocks(cur, &blocks); + if (error) + goto err; + xfs_btree_del_cursor(cur, error); + btreeblks = blocks - 1; + agf->agf_freeblks = cpu_to_be32(raa.freeblks); + agf->agf_longest = cpu_to_be32(raa.longest); + + /* Update the AGF counters from the cntbt. */ + cur = xfs_allocbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.agno, + XFS_BTNUM_CNT); + error = xfs_btree_count_blocks(cur, &blocks); + if (error) + goto err; + xfs_btree_del_cursor(cur, error); + btreeblks += blocks - 1; + + /* Update the AGF counters from the rmapbt. */ + cur = xfs_rmapbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.agno); + error = xfs_btree_count_blocks(cur, &blocks); + if (error) + goto err; + xfs_btree_del_cursor(cur, error); + agf->agf_rmap_blocks = cpu_to_be32(blocks); + btreeblks += blocks - 1; + + agf->agf_btreeblks = cpu_to_be32(btreeblks); + + /* Update the AGF counters from the refcountbt. */ + if (xfs_sb_version_hasreflink(&mp->m_sb)) { + cur = xfs_refcountbt_init_cursor(mp, sc->tp, agf_bp, + sc->sa.agno); + error = xfs_btree_count_blocks(cur, &blocks); + if (error) + goto err; + xfs_btree_del_cursor(cur, error); + agf->agf_refcount_blocks = cpu_to_be32(blocks); + } + + return 0; +err: + xfs_btree_del_cursor(cur, error); + return error; +} + +/* Commit the new AGF and reinitialize the incore state. */ +STATIC int +xrep_agf_commit_new( + struct xfs_scrub *sc, + struct xfs_buf *agf_bp) +{ + struct xfs_perag *pag; + struct xfs_agf *agf = XFS_BUF_TO_AGF(agf_bp); + + /* Trigger fdblocks recalculation */ + xfs_force_summary_recalc(sc->mp); + + /* Write this to disk. */ + xfs_trans_buf_set_type(sc->tp, agf_bp, XFS_BLFT_AGF_BUF); + xfs_trans_log_buf(sc->tp, agf_bp, 0, BBTOB(agf_bp->b_length) - 1); + + /* Now reinitialize the in-core counters we changed. */ + pag = sc->sa.pag; + pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks); + pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks); + pag->pagf_longest = be32_to_cpu(agf->agf_longest); + pag->pagf_levels[XFS_BTNUM_BNOi] = + be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]); + pag->pagf_levels[XFS_BTNUM_CNTi] = + be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]); + pag->pagf_levels[XFS_BTNUM_RMAPi] = + be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAPi]); + pag->pagf_refcount_level = be32_to_cpu(agf->agf_refcount_level); + pag->pagf_init = 1; + + return 0; +} + +/* Repair the AGF. v5 filesystems only. */ +int +xrep_agf( + struct xfs_scrub *sc) +{ + struct xrep_find_ag_btree fab[XREP_AGF_MAX] = { + [XREP_AGF_BNOBT] = { + .rmap_owner = XFS_RMAP_OWN_AG, + .buf_ops = &xfs_allocbt_buf_ops, + .magic = XFS_ABTB_CRC_MAGIC, + }, + [XREP_AGF_CNTBT] = { + .rmap_owner = XFS_RMAP_OWN_AG, + .buf_ops = &xfs_allocbt_buf_ops, + .magic = XFS_ABTC_CRC_MAGIC, + }, + [XREP_AGF_RMAPBT] = { + .rmap_owner = XFS_RMAP_OWN_AG, + .buf_ops = &xfs_rmapbt_buf_ops, + .magic = XFS_RMAP_CRC_MAGIC, + }, + [XREP_AGF_REFCOUNTBT] = { + .rmap_owner = XFS_RMAP_OWN_REFC, + .buf_ops = &xfs_refcountbt_buf_ops, + .magic = XFS_REFC_CRC_MAGIC, + }, + [XREP_AGF_END] = { + .buf_ops = NULL, + }, + }; + struct xfs_agf old_agf; + struct xfs_mount *mp = sc->mp; + struct xfs_buf *agf_bp; + struct xfs_buf *agfl_bp; + struct xfs_agf *agf; + int error; + + /* We require the rmapbt to rebuild anything. */ + if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) + return -EOPNOTSUPP; + + xchk_perag_get(sc->mp, &sc->sa); + /* + * Make sure we have the AGF buffer, as scrub might have decided it + * was corrupt after xfs_alloc_read_agf failed with -EFSCORRUPTED. + */ + error = xfs_trans_read_buf(mp, sc->tp, mp->m_ddev_targp, + XFS_AG_DADDR(mp, sc->sa.agno, XFS_AGF_DADDR(mp)), + XFS_FSS_TO_BB(mp, 1), 0, &agf_bp, NULL); + if (error) + return error; + agf_bp->b_ops = &xfs_agf_buf_ops; + agf = XFS_BUF_TO_AGF(agf_bp); + + /* + * Load the AGFL so that we can screen out OWN_AG blocks that are on + * the AGFL now; these blocks might have once been part of the + * bno/cnt/rmap btrees but are not now. This is a chicken and egg + * problem: the AGF is corrupt, so we have to trust the AGFL contents + * because we can't do any serious cross-referencing with any of the + * btrees rooted in the AGF. If the AGFL contents are obviously bad + * then we'll bail out. + */ + error = xfs_alloc_read_agfl(mp, sc->tp, sc->sa.agno, &agfl_bp); + if (error) + return error; + + /* + * Spot-check the AGFL blocks; if they're obviously corrupt then + * there's nothing we can do but bail out. + */ + error = xfs_agfl_walk(sc->mp, XFS_BUF_TO_AGF(agf_bp), agfl_bp, + xrep_agf_check_agfl_block, sc); + if (error) + return error; + + /* + * Find the AGF btree roots. This is also a chicken-and-egg situation; + * see the function for more details. + */ + error = xrep_agf_find_btrees(sc, agf_bp, fab, agfl_bp); + if (error) + return error; + + /* Start rewriting the header and implant the btrees we found. */ + xrep_agf_init_header(sc, agf_bp, &old_agf); + xrep_agf_set_roots(sc, agf, fab); + error = xrep_agf_calc_from_btrees(sc, agf_bp); + if (error) + goto out_revert; + + /* Commit the changes and reinitialize incore state. */ + return xrep_agf_commit_new(sc, agf_bp); + +out_revert: + /* Mark the incore AGF state stale and revert the AGF. */ + sc->sa.pag->pagf_init = 0; + memcpy(agf, &old_agf, sizeof(old_agf)); + return error; +} diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 85b048b341a0..17cf48564390 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -128,9 +128,12 @@ xrep_roll_ag_trans( int error; /* Keep the AG header buffers locked so we can keep going. */ - xfs_trans_bhold(sc->tp, sc->sa.agi_bp); - xfs_trans_bhold(sc->tp, sc->sa.agf_bp); - xfs_trans_bhold(sc->tp, sc->sa.agfl_bp); + if (sc->sa.agi_bp) + xfs_trans_bhold(sc->tp, sc->sa.agi_bp); + if (sc->sa.agf_bp) + xfs_trans_bhold(sc->tp, sc->sa.agf_bp); + if (sc->sa.agfl_bp) + xfs_trans_bhold(sc->tp, sc->sa.agfl_bp); /* Roll the transaction. */ error = xfs_trans_roll(&sc->tp); @@ -138,9 +141,12 @@ xrep_roll_ag_trans( goto out_release; /* Join AG headers to the new transaction. */ - xfs_trans_bjoin(sc->tp, sc->sa.agi_bp); - xfs_trans_bjoin(sc->tp, sc->sa.agf_bp); - xfs_trans_bjoin(sc->tp, sc->sa.agfl_bp); + if (sc->sa.agi_bp) + xfs_trans_bjoin(sc->tp, sc->sa.agi_bp); + if (sc->sa.agf_bp) + xfs_trans_bjoin(sc->tp, sc->sa.agf_bp); + if (sc->sa.agfl_bp) + xfs_trans_bjoin(sc->tp, sc->sa.agfl_bp); return 0; @@ -150,9 +156,12 @@ out_release: * buffers will be released during teardown on our way out * of the kernel. */ - xfs_trans_bhold_release(sc->tp, sc->sa.agi_bp); - xfs_trans_bhold_release(sc->tp, sc->sa.agf_bp); - xfs_trans_bhold_release(sc->tp, sc->sa.agfl_bp); + if (sc->sa.agi_bp) + xfs_trans_bhold_release(sc->tp, sc->sa.agi_bp); + if (sc->sa.agf_bp) + xfs_trans_bhold_release(sc->tp, sc->sa.agf_bp); + if (sc->sa.agfl_bp) + xfs_trans_bhold_release(sc->tp, sc->sa.agfl_bp); return error; } diff --git a/fs/xfs/scrub/repair.h b/fs/xfs/scrub/repair.h index 5a4e92221916..6f0903c51a47 100644 --- a/fs/xfs/scrub/repair.h +++ b/fs/xfs/scrub/repair.h @@ -58,6 +58,7 @@ int xrep_ino_dqattach(struct xfs_scrub *sc); int xrep_probe(struct xfs_scrub *sc); int xrep_superblock(struct xfs_scrub *sc); +int xrep_agf(struct xfs_scrub *sc); #else @@ -81,6 +82,7 @@ xrep_calc_ag_resblks( #define xrep_probe xrep_notsupported #define xrep_superblock xrep_notsupported +#define xrep_agf xrep_notsupported #endif /* CONFIG_XFS_ONLINE_REPAIR */ diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c index 6efb926f3cf8..1e8a17c8e2b9 100644 --- a/fs/xfs/scrub/scrub.c +++ b/fs/xfs/scrub/scrub.c @@ -214,7 +214,7 @@ static const struct xchk_meta_ops meta_scrub_ops[] = { .type = ST_PERAG, .setup = xchk_setup_fs, .scrub = xchk_agf, - .repair = xrep_notsupported, + .repair = xrep_agf, }, [XFS_SCRUB_TYPE_AGFL]= { /* agfl */ .type = ST_PERAG, -- cgit v1.2.3 From 0e93d3f43ec7d3308bff25ce1be81d46330168c9 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 9 Aug 2018 22:43:02 -0700 Subject: xfs: repair the AGFL Repair the AGFL from the rmap data. Signed-off-by: Darrick J. Wong Reviewed-by: Brian Foster --- fs/xfs/scrub/agheader_repair.c | 281 +++++++++++++++++++++++++++++++++++++++++ fs/xfs/scrub/bitmap.c | 92 ++++++++++++++ fs/xfs/scrub/bitmap.h | 4 + fs/xfs/scrub/repair.h | 2 + fs/xfs/scrub/scrub.c | 2 +- 5 files changed, 380 insertions(+), 1 deletion(-) (limited to 'fs/xfs') diff --git a/fs/xfs/scrub/agheader_repair.c b/fs/xfs/scrub/agheader_repair.c index aa180492a4a5..9ce302360bbb 100644 --- a/fs/xfs/scrub/agheader_repair.c +++ b/fs/xfs/scrub/agheader_repair.c @@ -433,3 +433,284 @@ out_revert: memcpy(agf, &old_agf, sizeof(old_agf)); return error; } + +/* AGFL */ + +struct xrep_agfl { + /* Bitmap of other OWN_AG metadata blocks. */ + struct xfs_bitmap agmetablocks; + + /* Bitmap of free space. */ + struct xfs_bitmap *freesp; + + struct xfs_scrub *sc; +}; + +/* Record all OWN_AG (free space btree) information from the rmap data. */ +STATIC int +xrep_agfl_walk_rmap( + struct xfs_btree_cur *cur, + struct xfs_rmap_irec *rec, + void *priv) +{ + struct xrep_agfl *ra = priv; + xfs_fsblock_t fsb; + int error = 0; + + if (xchk_should_terminate(ra->sc, &error)) + return error; + + /* Record all the OWN_AG blocks. */ + if (rec->rm_owner == XFS_RMAP_OWN_AG) { + fsb = XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_private.a.agno, + rec->rm_startblock); + error = xfs_bitmap_set(ra->freesp, fsb, rec->rm_blockcount); + if (error) + return error; + } + + return xfs_bitmap_set_btcur_path(&ra->agmetablocks, cur); +} + +/* + * Map out all the non-AGFL OWN_AG space in this AG so that we can deduce + * which blocks belong to the AGFL. + * + * Compute the set of old AGFL blocks by subtracting from the list of OWN_AG + * blocks the list of blocks owned by all other OWN_AG metadata (bnobt, cntbt, + * rmapbt). These are the old AGFL blocks, so return that list and the number + * of blocks we're actually going to put back on the AGFL. + */ +STATIC int +xrep_agfl_collect_blocks( + struct xfs_scrub *sc, + struct xfs_buf *agf_bp, + struct xfs_bitmap *agfl_extents, + xfs_agblock_t *flcount) +{ + struct xrep_agfl ra; + struct xfs_mount *mp = sc->mp; + struct xfs_btree_cur *cur; + struct xfs_bitmap_range *br; + struct xfs_bitmap_range *n; + int error; + + ra.sc = sc; + ra.freesp = agfl_extents; + xfs_bitmap_init(&ra.agmetablocks); + + /* Find all space used by the free space btrees & rmapbt. */ + cur = xfs_rmapbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.agno); + error = xfs_rmap_query_all(cur, xrep_agfl_walk_rmap, &ra); + if (error) + goto err; + xfs_btree_del_cursor(cur, error); + + /* Find all blocks currently being used by the bnobt. */ + cur = xfs_allocbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.agno, + XFS_BTNUM_BNO); + error = xfs_bitmap_set_btblocks(&ra.agmetablocks, cur); + if (error) + goto err; + xfs_btree_del_cursor(cur, error); + + /* Find all blocks currently being used by the cntbt. */ + cur = xfs_allocbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.agno, + XFS_BTNUM_CNT); + error = xfs_bitmap_set_btblocks(&ra.agmetablocks, cur); + if (error) + goto err; + + xfs_btree_del_cursor(cur, error); + + /* + * Drop the freesp meta blocks that are in use by btrees. + * The remaining blocks /should/ be AGFL blocks. + */ + error = xfs_bitmap_disunion(agfl_extents, &ra.agmetablocks); + xfs_bitmap_destroy(&ra.agmetablocks); + if (error) + return error; + + /* + * Calculate the new AGFL size. If we found more blocks than fit in + * the AGFL we'll free them later. + */ + *flcount = 0; + for_each_xfs_bitmap_extent(br, n, agfl_extents) { + *flcount += br->len; + if (*flcount > xfs_agfl_size(mp)) + break; + } + if (*flcount > xfs_agfl_size(mp)) + *flcount = xfs_agfl_size(mp); + return 0; + +err: + xfs_bitmap_destroy(&ra.agmetablocks); + xfs_btree_del_cursor(cur, error); + return error; +} + +/* Update the AGF and reset the in-core state. */ +STATIC void +xrep_agfl_update_agf( + struct xfs_scrub *sc, + struct xfs_buf *agf_bp, + xfs_agblock_t flcount) +{ + struct xfs_agf *agf = XFS_BUF_TO_AGF(agf_bp); + + ASSERT(flcount <= xfs_agfl_size(sc->mp)); + + /* Trigger fdblocks recalculation */ + xfs_force_summary_recalc(sc->mp); + + /* Update the AGF counters. */ + if (sc->sa.pag->pagf_init) + sc->sa.pag->pagf_flcount = flcount; + agf->agf_flfirst = cpu_to_be32(0); + agf->agf_flcount = cpu_to_be32(flcount); + agf->agf_fllast = cpu_to_be32(flcount - 1); + + xfs_alloc_log_agf(sc->tp, agf_bp, + XFS_AGF_FLFIRST | XFS_AGF_FLLAST | XFS_AGF_FLCOUNT); +} + +/* Write out a totally new AGFL. */ +STATIC void +xrep_agfl_init_header( + struct xfs_scrub *sc, + struct xfs_buf *agfl_bp, + struct xfs_bitmap *agfl_extents, + xfs_agblock_t flcount) +{ + struct xfs_mount *mp = sc->mp; + __be32 *agfl_bno; + struct xfs_bitmap_range *br; + struct xfs_bitmap_range *n; + struct xfs_agfl *agfl; + xfs_agblock_t agbno; + unsigned int fl_off; + + ASSERT(flcount <= xfs_agfl_size(mp)); + + /* + * Start rewriting the header by setting the bno[] array to + * NULLAGBLOCK, then setting AGFL header fields. + */ + agfl = XFS_BUF_TO_AGFL(agfl_bp); + memset(agfl, 0xFF, BBTOB(agfl_bp->b_length)); + agfl->agfl_magicnum = cpu_to_be32(XFS_AGFL_MAGIC); + agfl->agfl_seqno = cpu_to_be32(sc->sa.agno); + uuid_copy(&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid); + + /* + * Fill the AGFL with the remaining blocks. If agfl_extents has more + * blocks than fit in the AGFL, they will be freed in a subsequent + * step. + */ + fl_off = 0; + agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agfl_bp); + for_each_xfs_bitmap_extent(br, n, agfl_extents) { + agbno = XFS_FSB_TO_AGBNO(mp, br->start); + + trace_xrep_agfl_insert(mp, sc->sa.agno, agbno, br->len); + + while (br->len > 0 && fl_off < flcount) { + agfl_bno[fl_off] = cpu_to_be32(agbno); + fl_off++; + agbno++; + + /* + * We've now used br->start by putting it in the AGFL, + * so bump br so that we don't reap the block later. + */ + br->start++; + br->len--; + } + + if (br->len) + break; + list_del(&br->list); + kmem_free(br); + } + + /* Write new AGFL to disk. */ + xfs_trans_buf_set_type(sc->tp, agfl_bp, XFS_BLFT_AGFL_BUF); + xfs_trans_log_buf(sc->tp, agfl_bp, 0, BBTOB(agfl_bp->b_length) - 1); +} + +/* Repair the AGFL. */ +int +xrep_agfl( + struct xfs_scrub *sc) +{ + struct xfs_owner_info oinfo; + struct xfs_bitmap agfl_extents; + struct xfs_mount *mp = sc->mp; + struct xfs_buf *agf_bp; + struct xfs_buf *agfl_bp; + xfs_agblock_t flcount; + int error; + + /* We require the rmapbt to rebuild anything. */ + if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) + return -EOPNOTSUPP; + + xchk_perag_get(sc->mp, &sc->sa); + xfs_bitmap_init(&agfl_extents); + + /* + * Read the AGF so that we can query the rmapbt. We hope that there's + * nothing wrong with the AGF, but all the AG header repair functions + * have this chicken-and-egg problem. + */ + error = xfs_alloc_read_agf(mp, sc->tp, sc->sa.agno, 0, &agf_bp); + if (error) + return error; + if (!agf_bp) + return -ENOMEM; + + /* + * Make sure we have the AGFL buffer, as scrub might have decided it + * was corrupt after xfs_alloc_read_agfl failed with -EFSCORRUPTED. + */ + error = xfs_trans_read_buf(mp, sc->tp, mp->m_ddev_targp, + XFS_AG_DADDR(mp, sc->sa.agno, XFS_AGFL_DADDR(mp)), + XFS_FSS_TO_BB(mp, 1), 0, &agfl_bp, NULL); + if (error) + return error; + agfl_bp->b_ops = &xfs_agfl_buf_ops; + + /* Gather all the extents we're going to put on the new AGFL. */ + error = xrep_agfl_collect_blocks(sc, agf_bp, &agfl_extents, &flcount); + if (error) + goto err; + + /* + * Update AGF and AGFL. We reset the global free block counter when + * we adjust the AGF flcount (which can fail) so avoid updating any + * buffers until we know that part works. + */ + xrep_agfl_update_agf(sc, agf_bp, flcount); + xrep_agfl_init_header(sc, agfl_bp, &agfl_extents, flcount); + + /* + * Ok, the AGFL should be ready to go now. Roll the transaction to + * make the new AGFL permanent before we start using it to return + * freespace overflow to the freespace btrees. + */ + sc->sa.agf_bp = agf_bp; + sc->sa.agfl_bp = agfl_bp; + error = xrep_roll_ag_trans(sc); + if (error) + goto err; + + /* Dump any AGFL overflow. */ + xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_AG); + return xrep_reap_extents(sc, &agfl_extents, &oinfo, XFS_AG_RESV_AGFL); +err: + xfs_bitmap_destroy(&agfl_extents); + return error; +} diff --git a/fs/xfs/scrub/bitmap.c b/fs/xfs/scrub/bitmap.c index c770e2d0b6aa..fdadc9e1dc49 100644 --- a/fs/xfs/scrub/bitmap.c +++ b/fs/xfs/scrub/bitmap.c @@ -9,6 +9,7 @@ #include "xfs_format.h" #include "xfs_trans_resv.h" #include "xfs_mount.h" +#include "xfs_btree.h" #include "scrub/xfs_scrub.h" #include "scrub/scrub.h" #include "scrub/common.h" @@ -209,3 +210,94 @@ out: } #undef LEFT_ALIGNED #undef RIGHT_ALIGNED + +/* + * Record all btree blocks seen while iterating all records of a btree. + * + * We know that the btree query_all function starts at the left edge and walks + * towards the right edge of the tree. Therefore, we know that we can walk up + * the btree cursor towards the root; if the pointer for a given level points + * to the first record/key in that block, we haven't seen this block before; + * and therefore we need to remember that we saw this block in the btree. + * + * So if our btree is: + * + * 4 + * / | \ + * 1 2 3 + * + * Pretend for this example that each leaf block has 100 btree records. For + * the first btree record, we'll observe that bc_ptrs[0] == 1, so we record + * that we saw block 1. Then we observe that bc_ptrs[1] == 1, so we record + * block 4. The list is [1, 4]. + * + * For the second btree record, we see that bc_ptrs[0] == 2, so we exit the + * loop. The list remains [1, 4]. + * + * For the 101st btree record, we've moved onto leaf block 2. Now + * bc_ptrs[0] == 1 again, so we record that we saw block 2. We see that + * bc_ptrs[1] == 2, so we exit the loop. The list is now [1, 4, 2]. + * + * For the 102nd record, bc_ptrs[0] == 2, so we continue. + * + * For the 201st record, we've moved on to leaf block 3. bc_ptrs[0] == 1, so + * we add 3 to the list. Now it is [1, 4, 2, 3]. + * + * For the 300th record we just exit, with the list being [1, 4, 2, 3]. + */ + +/* + * Record all the buffers pointed to by the btree cursor. Callers already + * engaged in a btree walk should call this function to capture the list of + * blocks going from the leaf towards the root. + */ +int +xfs_bitmap_set_btcur_path( + struct xfs_bitmap *bitmap, + struct xfs_btree_cur *cur) +{ + struct xfs_buf *bp; + xfs_fsblock_t fsb; + int i; + int error; + + for (i = 0; i < cur->bc_nlevels && cur->bc_ptrs[i] == 1; i++) { + xfs_btree_get_block(cur, i, &bp); + if (!bp) + continue; + fsb = XFS_DADDR_TO_FSB(cur->bc_mp, bp->b_bn); + error = xfs_bitmap_set(bitmap, fsb, 1); + if (error) + return error; + } + + return 0; +} + +/* Collect a btree's block in the bitmap. */ +STATIC int +xfs_bitmap_collect_btblock( + struct xfs_btree_cur *cur, + int level, + void *priv) +{ + struct xfs_bitmap *bitmap = priv; + struct xfs_buf *bp; + xfs_fsblock_t fsbno; + + xfs_btree_get_block(cur, level, &bp); + if (!bp) + return 0; + + fsbno = XFS_DADDR_TO_FSB(cur->bc_mp, bp->b_bn); + return xfs_bitmap_set(bitmap, fsbno, 1); +} + +/* Walk the btree and mark the bitmap wherever a btree block is found. */ +int +xfs_bitmap_set_btblocks( + struct xfs_bitmap *bitmap, + struct xfs_btree_cur *cur) +{ + return xfs_btree_visit_blocks(cur, xfs_bitmap_collect_btblock, bitmap); +} diff --git a/fs/xfs/scrub/bitmap.h b/fs/xfs/scrub/bitmap.h index dad652ee9177..ae8ecbce6fa6 100644 --- a/fs/xfs/scrub/bitmap.h +++ b/fs/xfs/scrub/bitmap.h @@ -28,5 +28,9 @@ void xfs_bitmap_destroy(struct xfs_bitmap *bitmap); int xfs_bitmap_set(struct xfs_bitmap *bitmap, uint64_t start, uint64_t len); int xfs_bitmap_disunion(struct xfs_bitmap *bitmap, struct xfs_bitmap *sub); +int xfs_bitmap_set_btcur_path(struct xfs_bitmap *bitmap, + struct xfs_btree_cur *cur); +int xfs_bitmap_set_btblocks(struct xfs_bitmap *bitmap, + struct xfs_btree_cur *cur); #endif /* __XFS_SCRUB_BITMAP_H__ */ diff --git a/fs/xfs/scrub/repair.h b/fs/xfs/scrub/repair.h index 6f0903c51a47..1d283360b5ab 100644 --- a/fs/xfs/scrub/repair.h +++ b/fs/xfs/scrub/repair.h @@ -59,6 +59,7 @@ int xrep_ino_dqattach(struct xfs_scrub *sc); int xrep_probe(struct xfs_scrub *sc); int xrep_superblock(struct xfs_scrub *sc); int xrep_agf(struct xfs_scrub *sc); +int xrep_agfl(struct xfs_scrub *sc); #else @@ -83,6 +84,7 @@ xrep_calc_ag_resblks( #define xrep_probe xrep_notsupported #define xrep_superblock xrep_notsupported #define xrep_agf xrep_notsupported +#define xrep_agfl xrep_notsupported #endif /* CONFIG_XFS_ONLINE_REPAIR */ diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c index 1e8a17c8e2b9..2670f4cf62f4 100644 --- a/fs/xfs/scrub/scrub.c +++ b/fs/xfs/scrub/scrub.c @@ -220,7 +220,7 @@ static const struct xchk_meta_ops meta_scrub_ops[] = { .type = ST_PERAG, .setup = xchk_setup_fs, .scrub = xchk_agfl, - .repair = xrep_notsupported, + .repair = xrep_agfl, }, [XFS_SCRUB_TYPE_AGI] = { /* agi */ .type = ST_PERAG, -- cgit v1.2.3 From 13942aa94a8b5df662d93c42c307b2f50cbe88b0 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 9 Aug 2018 22:43:04 -0700 Subject: xfs: repair the AGI Rebuild the AGI header items with some help from the rmapbt. Signed-off-by: Darrick J. Wong Reviewed-by: Brian Foster --- fs/xfs/scrub/agheader_repair.c | 217 +++++++++++++++++++++++++++++++++++++++++ fs/xfs/scrub/repair.h | 2 + fs/xfs/scrub/scrub.c | 2 +- 3 files changed, 220 insertions(+), 1 deletion(-) (limited to 'fs/xfs') diff --git a/fs/xfs/scrub/agheader_repair.c b/fs/xfs/scrub/agheader_repair.c index 9ce302360bbb..f7568a4b5fe5 100644 --- a/fs/xfs/scrub/agheader_repair.c +++ b/fs/xfs/scrub/agheader_repair.c @@ -714,3 +714,220 @@ err: xfs_bitmap_destroy(&agfl_extents); return error; } + +/* AGI */ + +/* + * Offset within the xrep_find_ag_btree array for each btree type. Avoid the + * XFS_BTNUM_ names here to avoid creating a sparse array. + */ +enum { + XREP_AGI_INOBT = 0, + XREP_AGI_FINOBT, + XREP_AGI_END, + XREP_AGI_MAX +}; + +/* + * Given the inode btree roots described by *fab, find the roots, check them + * for sanity, and pass the root data back out via *fab. + */ +STATIC int +xrep_agi_find_btrees( + struct xfs_scrub *sc, + struct xrep_find_ag_btree *fab) +{ + struct xfs_buf *agf_bp; + struct xfs_mount *mp = sc->mp; + int error; + + /* Read the AGF. */ + error = xfs_alloc_read_agf(mp, sc->tp, sc->sa.agno, 0, &agf_bp); + if (error) + return error; + if (!agf_bp) + return -ENOMEM; + + /* Find the btree roots. */ + error = xrep_find_ag_btree_roots(sc, agf_bp, fab, NULL); + if (error) + return error; + + /* We must find the inobt root. */ + if (!xrep_check_btree_root(sc, &fab[XREP_AGI_INOBT])) + return -EFSCORRUPTED; + + /* We must find the finobt root if that feature is enabled. */ + if (xfs_sb_version_hasfinobt(&mp->m_sb) && + !xrep_check_btree_root(sc, &fab[XREP_AGI_FINOBT])) + return -EFSCORRUPTED; + + return 0; +} + +/* + * Reinitialize the AGI header, making an in-core copy of the old contents so + * that we know which in-core state needs to be reinitialized. + */ +STATIC void +xrep_agi_init_header( + struct xfs_scrub *sc, + struct xfs_buf *agi_bp, + struct xfs_agi *old_agi) +{ + struct xfs_agi *agi = XFS_BUF_TO_AGI(agi_bp); + struct xfs_mount *mp = sc->mp; + + memcpy(old_agi, agi, sizeof(*old_agi)); + memset(agi, 0, BBTOB(agi_bp->b_length)); + agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC); + agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION); + agi->agi_seqno = cpu_to_be32(sc->sa.agno); + agi->agi_length = cpu_to_be32(xfs_ag_block_count(mp, sc->sa.agno)); + agi->agi_newino = cpu_to_be32(NULLAGINO); + agi->agi_dirino = cpu_to_be32(NULLAGINO); + if (xfs_sb_version_hascrc(&mp->m_sb)) + uuid_copy(&agi->agi_uuid, &mp->m_sb.sb_meta_uuid); + + /* We don't know how to fix the unlinked list yet. */ + memcpy(&agi->agi_unlinked, &old_agi->agi_unlinked, + sizeof(agi->agi_unlinked)); + + /* Mark the incore AGF data stale until we're done fixing things. */ + ASSERT(sc->sa.pag->pagi_init); + sc->sa.pag->pagi_init = 0; +} + +/* Set btree root information in an AGI. */ +STATIC void +xrep_agi_set_roots( + struct xfs_scrub *sc, + struct xfs_agi *agi, + struct xrep_find_ag_btree *fab) +{ + agi->agi_root = cpu_to_be32(fab[XREP_AGI_INOBT].root); + agi->agi_level = cpu_to_be32(fab[XREP_AGI_INOBT].height); + + if (xfs_sb_version_hasfinobt(&sc->mp->m_sb)) { + agi->agi_free_root = cpu_to_be32(fab[XREP_AGI_FINOBT].root); + agi->agi_free_level = cpu_to_be32(fab[XREP_AGI_FINOBT].height); + } +} + +/* Update the AGI counters. */ +STATIC int +xrep_agi_calc_from_btrees( + struct xfs_scrub *sc, + struct xfs_buf *agi_bp) +{ + struct xfs_btree_cur *cur; + struct xfs_agi *agi = XFS_BUF_TO_AGI(agi_bp); + struct xfs_mount *mp = sc->mp; + xfs_agino_t count; + xfs_agino_t freecount; + int error; + + cur = xfs_inobt_init_cursor(mp, sc->tp, agi_bp, sc->sa.agno, + XFS_BTNUM_INO); + error = xfs_ialloc_count_inodes(cur, &count, &freecount); + if (error) + goto err; + xfs_btree_del_cursor(cur, error); + + agi->agi_count = cpu_to_be32(count); + agi->agi_freecount = cpu_to_be32(freecount); + return 0; +err: + xfs_btree_del_cursor(cur, error); + return error; +} + +/* Trigger reinitialization of the in-core data. */ +STATIC int +xrep_agi_commit_new( + struct xfs_scrub *sc, + struct xfs_buf *agi_bp) +{ + struct xfs_perag *pag; + struct xfs_agi *agi = XFS_BUF_TO_AGI(agi_bp); + + /* Trigger inode count recalculation */ + xfs_force_summary_recalc(sc->mp); + + /* Write this to disk. */ + xfs_trans_buf_set_type(sc->tp, agi_bp, XFS_BLFT_AGI_BUF); + xfs_trans_log_buf(sc->tp, agi_bp, 0, BBTOB(agi_bp->b_length) - 1); + + /* Now reinitialize the in-core counters if necessary. */ + pag = sc->sa.pag; + pag->pagi_count = be32_to_cpu(agi->agi_count); + pag->pagi_freecount = be32_to_cpu(agi->agi_freecount); + pag->pagi_init = 1; + + return 0; +} + +/* Repair the AGI. */ +int +xrep_agi( + struct xfs_scrub *sc) +{ + struct xrep_find_ag_btree fab[XREP_AGI_MAX] = { + [XREP_AGI_INOBT] = { + .rmap_owner = XFS_RMAP_OWN_INOBT, + .buf_ops = &xfs_inobt_buf_ops, + .magic = XFS_IBT_CRC_MAGIC, + }, + [XREP_AGI_FINOBT] = { + .rmap_owner = XFS_RMAP_OWN_INOBT, + .buf_ops = &xfs_inobt_buf_ops, + .magic = XFS_FIBT_CRC_MAGIC, + }, + [XREP_AGI_END] = { + .buf_ops = NULL + }, + }; + struct xfs_agi old_agi; + struct xfs_mount *mp = sc->mp; + struct xfs_buf *agi_bp; + struct xfs_agi *agi; + int error; + + /* We require the rmapbt to rebuild anything. */ + if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) + return -EOPNOTSUPP; + + xchk_perag_get(sc->mp, &sc->sa); + /* + * Make sure we have the AGI buffer, as scrub might have decided it + * was corrupt after xfs_ialloc_read_agi failed with -EFSCORRUPTED. + */ + error = xfs_trans_read_buf(mp, sc->tp, mp->m_ddev_targp, + XFS_AG_DADDR(mp, sc->sa.agno, XFS_AGI_DADDR(mp)), + XFS_FSS_TO_BB(mp, 1), 0, &agi_bp, NULL); + if (error) + return error; + agi_bp->b_ops = &xfs_agi_buf_ops; + agi = XFS_BUF_TO_AGI(agi_bp); + + /* Find the AGI btree roots. */ + error = xrep_agi_find_btrees(sc, fab); + if (error) + return error; + + /* Start rewriting the header and implant the btrees we found. */ + xrep_agi_init_header(sc, agi_bp, &old_agi); + xrep_agi_set_roots(sc, agi, fab); + error = xrep_agi_calc_from_btrees(sc, agi_bp); + if (error) + goto out_revert; + + /* Reinitialize in-core state. */ + return xrep_agi_commit_new(sc, agi_bp); + +out_revert: + /* Mark the incore AGI state stale and revert the AGI. */ + sc->sa.pag->pagi_init = 0; + memcpy(agi, &old_agi, sizeof(old_agi)); + return error; +} diff --git a/fs/xfs/scrub/repair.h b/fs/xfs/scrub/repair.h index 1d283360b5ab..9de321eee4ab 100644 --- a/fs/xfs/scrub/repair.h +++ b/fs/xfs/scrub/repair.h @@ -60,6 +60,7 @@ int xrep_probe(struct xfs_scrub *sc); int xrep_superblock(struct xfs_scrub *sc); int xrep_agf(struct xfs_scrub *sc); int xrep_agfl(struct xfs_scrub *sc); +int xrep_agi(struct xfs_scrub *sc); #else @@ -85,6 +86,7 @@ xrep_calc_ag_resblks( #define xrep_superblock xrep_notsupported #define xrep_agf xrep_notsupported #define xrep_agfl xrep_notsupported +#define xrep_agi xrep_notsupported #endif /* CONFIG_XFS_ONLINE_REPAIR */ diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c index 2670f4cf62f4..4bfae1e61d30 100644 --- a/fs/xfs/scrub/scrub.c +++ b/fs/xfs/scrub/scrub.c @@ -226,7 +226,7 @@ static const struct xchk_meta_ops meta_scrub_ops[] = { .type = ST_PERAG, .setup = xchk_setup_fs, .scrub = xchk_agi, - .repair = xrep_notsupported, + .repair = xrep_agi, }, [XFS_SCRUB_TYPE_BNOBT] = { /* bnobt */ .type = ST_PERAG, -- cgit v1.2.3 From e25ff835af89a80aa6a4de58f413e494b2b96bd1 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Fri, 10 Aug 2018 08:48:18 -0700 Subject: xfs: Close race between direct IO and xfs_break_layouts() This patch is the duplicate of ross's fix for ext4 for xfs. If the refcount of a page is lowered between the time that it is returned by dax_busy_page() and when the refcount is again checked in xfs_break_layouts() => ___wait_var_event(), the waiting function xfs_wait_dax_page() will never be called. This means that xfs_break_layouts() will still have 'retry' set to false, so we'll stop looping and never check the refcount of other pages in this inode. Instead, always continue looping as long as dax_layout_busy_page() gives us a page which it found with an elevated refcount. Signed-off-by: Dave Jiang Reviewed-by: Jan Kara Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_file.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 6b31f41eafa2..181e9084519b 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -721,12 +721,10 @@ xfs_file_write_iter( static void xfs_wait_dax_page( - struct inode *inode, - bool *did_unlock) + struct inode *inode) { struct xfs_inode *ip = XFS_I(inode); - *did_unlock = true; xfs_iunlock(ip, XFS_MMAPLOCK_EXCL); schedule(); xfs_ilock(ip, XFS_MMAPLOCK_EXCL); @@ -735,7 +733,7 @@ xfs_wait_dax_page( static int xfs_break_dax_layouts( struct inode *inode, - bool *did_unlock) + bool *retry) { struct page *page; @@ -745,9 +743,10 @@ xfs_break_dax_layouts( if (!page) return 0; + *retry = true; return ___wait_var_event(&page->_refcount, atomic_read(&page->_refcount) == 1, TASK_INTERRUPTIBLE, - 0, 0, xfs_wait_dax_page(inode, did_unlock)); + 0, 0, xfs_wait_dax_page(inode)); } int -- cgit v1.2.3 From fa6c668d807b1e9ac041101dfcb59bd8e279cfe5 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Fri, 10 Aug 2018 13:56:25 -0700 Subject: xfs: remove b_last_holder & associated macros The old lock tracking infrastructure in xfs using the b_last_holder field seems to only be useful if you can get into the system with a debugger; it seems that the existing tracepoints would be the way to go these days, and this old infrastructure can be removed. Signed-off-by: Eric Sandeen Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs.h | 1 - fs/xfs/xfs_buf.c | 20 ++------------------ fs/xfs/xfs_buf.h | 4 ---- 3 files changed, 2 insertions(+), 23 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/xfs.h b/fs/xfs/xfs.h index 583a9f539bf1..f6ffb4f248f7 100644 --- a/fs/xfs/xfs.h +++ b/fs/xfs/xfs.h @@ -8,7 +8,6 @@ #ifdef CONFIG_XFS_DEBUG #define DEBUG 1 -#define XFS_BUF_LOCK_TRACKING 1 #endif #ifdef CONFIG_XFS_ASSERT_FATAL diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index c641c7fa1a03..e839907e8492 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -34,16 +34,6 @@ static kmem_zone_t *xfs_buf_zone; -#ifdef XFS_BUF_LOCK_TRACKING -# define XB_SET_OWNER(bp) ((bp)->b_last_holder = current->pid) -# define XB_CLEAR_OWNER(bp) ((bp)->b_last_holder = -1) -# define XB_GET_OWNER(bp) ((bp)->b_last_holder) -#else -# define XB_SET_OWNER(bp) do { } while (0) -# define XB_CLEAR_OWNER(bp) do { } while (0) -# define XB_GET_OWNER(bp) do { } while (0) -#endif - #define xb_to_gfp(flags) \ ((((flags) & XBF_READ_AHEAD) ? __GFP_NORETRY : GFP_NOFS) | __GFP_NOWARN) @@ -226,7 +216,6 @@ _xfs_buf_alloc( INIT_LIST_HEAD(&bp->b_li_list); sema_init(&bp->b_sema, 0); /* held, no waiters */ spin_lock_init(&bp->b_lock); - XB_SET_OWNER(bp); bp->b_target = target; bp->b_flags = flags; @@ -1091,12 +1080,10 @@ xfs_buf_trylock( int locked; locked = down_trylock(&bp->b_sema) == 0; - if (locked) { - XB_SET_OWNER(bp); + if (locked) trace_xfs_buf_trylock(bp, _RET_IP_); - } else { + else trace_xfs_buf_trylock_fail(bp, _RET_IP_); - } return locked; } @@ -1118,7 +1105,6 @@ xfs_buf_lock( if (atomic_read(&bp->b_pin_count) && (bp->b_flags & XBF_STALE)) xfs_log_force(bp->b_target->bt_mount, 0); down(&bp->b_sema); - XB_SET_OWNER(bp); trace_xfs_buf_lock_done(bp, _RET_IP_); } @@ -1129,9 +1115,7 @@ xfs_buf_unlock( { ASSERT(xfs_buf_islocked(bp)); - XB_CLEAR_OWNER(bp); up(&bp->b_sema); - trace_xfs_buf_unlock(bp, _RET_IP_); } diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index f04613181ca1..4e3171acd0f8 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -198,10 +198,6 @@ typedef struct xfs_buf { int b_last_error; const struct xfs_buf_ops *b_ops; - -#ifdef XFS_BUF_LOCK_TRACKING - int b_last_holder; -#endif } xfs_buf_t; /* Finding and Reading Buffers */ -- cgit v1.2.3 From 01239d77b9dd978863d1a75f0d095ab942a1fe66 Mon Sep 17 00:00:00 2001 From: Shan Hai Date: Fri, 10 Aug 2018 17:55:55 -0700 Subject: xfs: fix a null pointer dereference in xfs_bmap_extents_to_btree Fuzzing tool reports a write to null pointer error in the xfs_bmap_extents_to_btree, fix it by bailing out on encountering a null pointer. Signed-off-by: Shan Hai Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'fs/xfs') diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 5648a177e0ac..2760314fdf7f 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -712,19 +712,14 @@ xfs_bmap_extents_to_btree( args.wasdel = wasdel; *logflagsp = 0; if ((error = xfs_alloc_vextent(&args))) { - xfs_iroot_realloc(ip, -1, whichfork); ASSERT(ifp->if_broot == NULL); - XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); - xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); - return error; + goto err1; } if (WARN_ON_ONCE(args.fsbno == NULLFSBLOCK)) { - xfs_iroot_realloc(ip, -1, whichfork); ASSERT(ifp->if_broot == NULL); - XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); - xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); - return -ENOSPC; + error = -ENOSPC; + goto err1; } /* * Allocation can't fail, the space was reserved. @@ -736,6 +731,10 @@ xfs_bmap_extents_to_btree( ip->i_d.di_nblocks++; xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L); abp = xfs_btree_get_bufl(mp, tp, args.fsbno, 0); + if (!abp) { + error = -ENOSPC; + goto err2; + } /* * Fill in the child block. */ @@ -775,6 +774,15 @@ xfs_bmap_extents_to_btree( *curp = cur; *logflagsp = XFS_ILOG_CORE | xfs_ilog_fbroot(whichfork); return 0; + +err2: + xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); +err1: + xfs_iroot_realloc(ip, -1, whichfork); + XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); + xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); + + return error; } /* -- cgit v1.2.3