Skip to content

Commit b477ff9

Browse files
committed
Merge tag 'xfs-merge-6.14' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull XFS updates from Carlos Maiolino: "This is mostly focused on the implementation of reflink and reverse-mapping support for XFS's real-time devices. It also includes several bugfixes. - Implement reflink support for the realtime device - Implement reverse-mapping support for the realtime device - Several bug fixes and cleanups" * tag 'xfs-merge-6.14' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (121 commits) xfs: fix buffer lookup vs release race xfs: check for dead buffers in xfs_buf_find_insert xfs: add a b_iodone callback to struct xfs_buf xfs: move b_li_list based retry handling to common code xfs: simplify xfsaild_resubmit_item xfs: always complete the buffer inline in xfs_buf_submit xfs: remove the extra buffer reference in xfs_buf_submit xfs: move invalidate_kernel_vmap_range to xfs_buf_ioend xfs: simplify buffer I/O submission xfs: move in-memory buftarg handling out of _xfs_buf_ioapply xfs: move write verification out of _xfs_buf_ioapply xfs: remove xfs_buf_delwri_submit_buffers xfs: simplify xfs_buf_delwri_pushbuf xfs: move xfs_buf_iowait out of (__)xfs_buf_submit xfs: remove the incorrect comment about the b_pag field xfs: remove the incorrect comment above xfs_buf_free_maps xfs: fix a double completion for buffers on in-memory targets xfs/libxfs: replace kmalloc() and memcpy() with kmemdup() xfs: constify feature checks xfs: refactor xfs_fs_statfs ...
2 parents d0d106a + ee10f6f commit b477ff9

File tree

131 files changed

+10861
-1440
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

131 files changed

+10861
-1440
lines changed

fs/xfs/Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ xfs-y += $(addprefix libxfs/, \
5151
xfs_rmap_btree.o \
5252
xfs_refcount.o \
5353
xfs_refcount_btree.o \
54+
xfs_rtrefcount_btree.o \
55+
xfs_rtrmap_btree.o \
5456
xfs_sb.o \
5557
xfs_symlink_remote.o \
5658
xfs_trans_inode.o \
@@ -193,6 +195,8 @@ xfs-$(CONFIG_XFS_ONLINE_SCRUB_STATS) += scrub/stats.o
193195
xfs-$(CONFIG_XFS_RT) += $(addprefix scrub/, \
194196
rgsuper.o \
195197
rtbitmap.o \
198+
rtrefcount.o \
199+
rtrmap.o \
196200
rtsummary.o \
197201
)
198202

@@ -232,6 +236,8 @@ xfs-y += $(addprefix scrub/, \
232236

233237
xfs-$(CONFIG_XFS_RT) += $(addprefix scrub/, \
234238
rtbitmap_repair.o \
239+
rtrefcount_repair.o \
240+
rtrmap_repair.o \
235241
rtsummary_repair.o \
236242
)
237243

fs/xfs/libxfs/xfs_ag_resv.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ xfs_ag_resv_needed(
114114
case XFS_AG_RESV_RMAPBT:
115115
len -= xfs_perag_resv(pag, type)->ar_reserved;
116116
break;
117+
case XFS_AG_RESV_METAFILE:
117118
case XFS_AG_RESV_NONE:
118119
/* empty */
119120
break;
@@ -347,6 +348,7 @@ xfs_ag_resv_alloc_extent(
347348

348349
switch (type) {
349350
case XFS_AG_RESV_AGFL:
351+
case XFS_AG_RESV_METAFILE:
350352
return;
351353
case XFS_AG_RESV_METADATA:
352354
case XFS_AG_RESV_RMAPBT:
@@ -389,6 +391,7 @@ xfs_ag_resv_free_extent(
389391

390392
switch (type) {
391393
case XFS_AG_RESV_AGFL:
394+
case XFS_AG_RESV_METAFILE:
392395
return;
393396
case XFS_AG_RESV_METADATA:
394397
case XFS_AG_RESV_RMAPBT:

fs/xfs/libxfs/xfs_attr.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,9 +1004,7 @@ xfs_attr_add_fork(
10041004
unsigned int blks; /* space reservation */
10051005
int error; /* error return value */
10061006

1007-
if (xfs_is_metadir_inode(ip))
1008-
ASSERT(XFS_IS_DQDETACHED(ip));
1009-
else
1007+
if (!xfs_is_metadir_inode(ip))
10101008
ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
10111009

10121010
blks = XFS_ADDAFORK_SPACE_RES(mp);

fs/xfs/libxfs/xfs_bmap.c

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ xfs_bmap_btree_to_extents(
615615
xfs_trans_binval(tp, cbp);
616616
if (cur->bc_levels[0].bp == cbp)
617617
cur->bc_levels[0].bp = NULL;
618-
xfs_iroot_realloc(ip, -1, whichfork);
618+
xfs_bmap_broot_realloc(ip, whichfork, 0);
619619
ASSERT(ifp->if_broot == NULL);
620620
ifp->if_format = XFS_DINODE_FMT_EXTENTS;
621621
*logflagsp |= XFS_ILOG_CORE | xfs_ilog_fext(whichfork);
@@ -659,12 +659,11 @@ xfs_bmap_extents_to_btree(
659659
* Make space in the inode incore. This needs to be undone if we fail
660660
* to expand the root.
661661
*/
662-
xfs_iroot_realloc(ip, 1, whichfork);
662+
block = xfs_bmap_broot_realloc(ip, whichfork, 1);
663663

664664
/*
665665
* Fill in the root.
666666
*/
667-
block = ifp->if_broot;
668667
xfs_bmbt_init_block(ip, block, NULL, 1, 1);
669668
/*
670669
* Need a cursor. Can't allocate until bb_level is filled in.
@@ -746,7 +745,7 @@ xfs_bmap_extents_to_btree(
746745
out_unreserve_dquot:
747746
xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
748747
out_root_realloc:
749-
xfs_iroot_realloc(ip, -1, whichfork);
748+
xfs_bmap_broot_realloc(ip, whichfork, 0);
750749
ifp->if_format = XFS_DINODE_FMT_EXTENTS;
751750
ASSERT(ifp->if_broot == NULL);
752751
xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
@@ -1043,9 +1042,7 @@ xfs_bmap_add_attrfork(
10431042
int error; /* error return value */
10441043

10451044
xfs_assert_ilocked(ip, XFS_ILOCK_EXCL);
1046-
if (xfs_is_metadir_inode(ip))
1047-
ASSERT(XFS_IS_DQDETACHED(ip));
1048-
else
1045+
if (!xfs_is_metadir_inode(ip))
10491046
ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
10501047
ASSERT(!xfs_inode_has_attr_fork(ip));
10511048

@@ -4567,8 +4564,9 @@ xfs_bmapi_write(
45674564
* the refcount btree for orphan recovery.
45684565
*/
45694566
if (whichfork == XFS_COW_FORK)
4570-
xfs_refcount_alloc_cow_extent(tp, bma.blkno,
4571-
bma.length);
4567+
xfs_refcount_alloc_cow_extent(tp,
4568+
XFS_IS_REALTIME_INODE(ip),
4569+
bma.blkno, bma.length);
45724570
}
45734571

45744572
/* Deal with the allocated space we found. */
@@ -4743,7 +4741,8 @@ xfs_bmapi_convert_one_delalloc(
47434741
*seq = READ_ONCE(ifp->if_seq);
47444742

47454743
if (whichfork == XFS_COW_FORK)
4746-
xfs_refcount_alloc_cow_extent(tp, bma.blkno, bma.length);
4744+
xfs_refcount_alloc_cow_extent(tp, XFS_IS_REALTIME_INODE(ip),
4745+
bma.blkno, bma.length);
47474746

47484747
error = xfs_bmap_btree_to_extents(tp, ip, bma.cur, &bma.logflags,
47494748
whichfork);
@@ -5391,7 +5390,7 @@ xfs_bmap_del_extent_real(
53915390
bool isrt = xfs_ifork_is_realtime(ip, whichfork);
53925391

53935392
if (xfs_is_reflink_inode(ip) && whichfork == XFS_DATA_FORK) {
5394-
xfs_refcount_decrease_extent(tp, del);
5393+
xfs_refcount_decrease_extent(tp, isrt, del);
53955394
} else if (isrt && !xfs_has_rtgroups(mp)) {
53965395
error = xfs_bmap_free_rtblocks(tp, del);
53975396
} else {
@@ -6501,9 +6500,8 @@ xfs_get_extsz_hint(
65016500
* No point in aligning allocations if we need to COW to actually
65026501
* write to them.
65036502
*/
6504-
if (xfs_is_always_cow_inode(ip))
6505-
return 0;
6506-
if ((ip->i_diflags & XFS_DIFLAG_EXTSIZE) && ip->i_extsize)
6503+
if (!xfs_is_always_cow_inode(ip) &&
6504+
(ip->i_diflags & XFS_DIFLAG_EXTSIZE) && ip->i_extsize)
65076505
return ip->i_extsize;
65086506
if (XFS_IS_REALTIME_INODE(ip) &&
65096507
ip->i_mount->m_sb.sb_rextsize > 1)
@@ -6526,7 +6524,13 @@ xfs_get_cowextsz_hint(
65266524
a = 0;
65276525
if (ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE)
65286526
a = ip->i_cowextsize;
6529-
b = xfs_get_extsz_hint(ip);
6527+
if (XFS_IS_REALTIME_INODE(ip)) {
6528+
b = 0;
6529+
if (ip->i_diflags & XFS_DIFLAG_EXTSIZE)
6530+
b = ip->i_extsize;
6531+
} else {
6532+
b = xfs_get_extsz_hint(ip);
6533+
}
65306534

65316535
a = max(a, b);
65326536
if (a == 0)

fs/xfs/libxfs/xfs_bmap_btree.c

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,116 @@ xfs_bmbt_keys_contiguous(
516516
be64_to_cpu(key2->bmbt.br_startoff));
517517
}
518518

519+
static inline void
520+
xfs_bmbt_move_ptrs(
521+
struct xfs_mount *mp,
522+
struct xfs_btree_block *broot,
523+
short old_size,
524+
size_t new_size,
525+
unsigned int numrecs)
526+
{
527+
void *dptr;
528+
void *sptr;
529+
530+
sptr = xfs_bmap_broot_ptr_addr(mp, broot, 1, old_size);
531+
dptr = xfs_bmap_broot_ptr_addr(mp, broot, 1, new_size);
532+
memmove(dptr, sptr, numrecs * sizeof(xfs_bmbt_ptr_t));
533+
}
534+
535+
/*
536+
* Reallocate the space for if_broot based on the number of records. Move the
537+
* records and pointers in if_broot to fit the new size. When shrinking this
538+
* will eliminate holes between the records and pointers created by the caller.
539+
* When growing this will create holes to be filled in by the caller.
540+
*
541+
* The caller must not request to add more records than would fit in the
542+
* on-disk inode root. If the if_broot is currently NULL, then if we are
543+
* adding records, one will be allocated. The caller must also not request
544+
* that the number of records go below zero, although it can go to zero.
545+
*
546+
* ip -- the inode whose if_broot area is changing
547+
* whichfork -- which inode fork to change
548+
* new_numrecs -- the new number of records requested for the if_broot array
549+
*
550+
* Returns the incore btree root block.
551+
*/
552+
struct xfs_btree_block *
553+
xfs_bmap_broot_realloc(
554+
struct xfs_inode *ip,
555+
int whichfork,
556+
unsigned int new_numrecs)
557+
{
558+
struct xfs_mount *mp = ip->i_mount;
559+
struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork);
560+
struct xfs_btree_block *broot;
561+
unsigned int new_size;
562+
unsigned int old_size = ifp->if_broot_bytes;
563+
564+
/*
565+
* Block mapping btrees do not support storing zero records; if this
566+
* happens, the fork is being changed to FMT_EXTENTS. Free the broot
567+
* and get out.
568+
*/
569+
if (new_numrecs == 0)
570+
return xfs_broot_realloc(ifp, 0);
571+
572+
new_size = xfs_bmap_broot_space_calc(mp, new_numrecs);
573+
574+
/* Handle the nop case quietly. */
575+
if (new_size == old_size)
576+
return ifp->if_broot;
577+
578+
if (new_size > old_size) {
579+
unsigned int old_numrecs;
580+
581+
/*
582+
* If there wasn't any memory allocated before, just
583+
* allocate it now and get out.
584+
*/
585+
if (old_size == 0)
586+
return xfs_broot_realloc(ifp, new_size);
587+
588+
/*
589+
* If there is already an existing if_broot, then we need
590+
* to realloc() it and shift the pointers to their new
591+
* location. The records don't change location because
592+
* they are kept butted up against the btree block header.
593+
*/
594+
old_numrecs = xfs_bmbt_maxrecs(mp, old_size, false);
595+
broot = xfs_broot_realloc(ifp, new_size);
596+
ASSERT(xfs_bmap_bmdr_space(broot) <=
597+
xfs_inode_fork_size(ip, whichfork));
598+
xfs_bmbt_move_ptrs(mp, broot, old_size, new_size, old_numrecs);
599+
return broot;
600+
}
601+
602+
/*
603+
* We're reducing, but not totally eliminating, numrecs. In this case,
604+
* we are shrinking the if_broot buffer, so it must already exist.
605+
*/
606+
ASSERT(ifp->if_broot != NULL && old_size > 0 && new_size > 0);
607+
608+
/*
609+
* Shrink the btree root by moving the bmbt pointers, since they are
610+
* not butted up against the btree block header, then reallocating
611+
* broot.
612+
*/
613+
xfs_bmbt_move_ptrs(mp, ifp->if_broot, old_size, new_size, new_numrecs);
614+
broot = xfs_broot_realloc(ifp, new_size);
615+
ASSERT(xfs_bmap_bmdr_space(broot) <=
616+
xfs_inode_fork_size(ip, whichfork));
617+
return broot;
618+
}
619+
620+
static struct xfs_btree_block *
621+
xfs_bmbt_broot_realloc(
622+
struct xfs_btree_cur *cur,
623+
unsigned int new_numrecs)
624+
{
625+
return xfs_bmap_broot_realloc(cur->bc_ino.ip, cur->bc_ino.whichfork,
626+
new_numrecs);
627+
}
628+
519629
const struct xfs_btree_ops xfs_bmbt_ops = {
520630
.name = "bmap",
521631
.type = XFS_BTREE_TYPE_INODE,
@@ -543,6 +653,7 @@ const struct xfs_btree_ops xfs_bmbt_ops = {
543653
.keys_inorder = xfs_bmbt_keys_inorder,
544654
.recs_inorder = xfs_bmbt_recs_inorder,
545655
.keys_contiguous = xfs_bmbt_keys_contiguous,
656+
.broot_realloc = xfs_bmbt_broot_realloc,
546657
};
547658

548659
/*

fs/xfs/libxfs/xfs_bmap_btree.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,4 +198,7 @@ xfs_bmap_bmdr_space(struct xfs_btree_block *bb)
198198
return xfs_bmdr_space_calc(be16_to_cpu(bb->bb_numrecs));
199199
}
200200

201+
struct xfs_btree_block *xfs_bmap_broot_realloc(struct xfs_inode *ip,
202+
int whichfork, unsigned int new_numrecs);
203+
201204
#endif /* __XFS_BMAP_BTREE_H__ */

0 commit comments

Comments
 (0)