Skip to content

Commit 0efdc09

Browse files
committed
Merge tag 'xfs-6.11-fixes-4' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull xfs fixes from Chandan Babu: - Do not call out v1 inodes with non-zero di_nlink field as being corrupt - Change xfs_finobt_count_blocks() to count "free inode btree" blocks rather than "inode btree" blocks - Don't report the number of trimmed bytes via FITRIM because the underlying storage isn't required to do anything and failed discard IOs aren't reported to the caller anyway - Fix incorrect setting of rm_owner field in an rmap query - Report missing disk offset range in an fsmap query - Obtain m_growlock when extending realtime section of the filesystem - Reset rootdir extent size hint after extending realtime section of the filesystem * tag 'xfs-6.11-fixes-4' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: xfs: reset rootdir extent size hint after growfsrt xfs: take m_growlock when running growfsrt xfs: Fix missing interval for missing_owner in xfs fsmap xfs: use XFS_BUF_DADDR_NULL for daddrs in getfsmap code xfs: Fix the owner setting issue for rmap query in xfs fsmap xfs: don't bother reporting blocks trimmed via FITRIM xfs: xfs_finobt_count_blocks() walks the wrong btree xfs: fix folio dirtying for XFILE_ALLOC callers xfs: fix di_onlink checking for V1/V2 inodes
2 parents 35667a2 + a24cae8 commit 0efdc09

File tree

6 files changed

+114
-48
lines changed

6 files changed

+114
-48
lines changed

fs/xfs/libxfs/xfs_ialloc_btree.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ xfs_finobt_count_blocks(
749749
if (error)
750750
return error;
751751

752-
cur = xfs_inobt_init_cursor(pag, tp, agbp);
752+
cur = xfs_finobt_init_cursor(pag, tp, agbp);
753753
error = xfs_btree_count_blocks(cur, tree_blocks);
754754
xfs_btree_del_cursor(cur, error);
755755
xfs_trans_brelse(tp, agbp);

fs/xfs/libxfs/xfs_inode_buf.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -514,12 +514,18 @@ xfs_dinode_verify(
514514
return __this_address;
515515
}
516516

517-
if (dip->di_version > 1) {
517+
/*
518+
* Historical note: xfsprogs in the 3.2 era set up its incore inodes to
519+
* have di_nlink track the link count, even if the actual filesystem
520+
* only supported V1 inodes (i.e. di_onlink). When writing out the
521+
* ondisk inode, it would set both the ondisk di_nlink and di_onlink to
522+
* the the incore di_nlink value, which is why we cannot check for
523+
* di_nlink==0 on a V1 inode. V2/3 inodes would get written out with
524+
* di_onlink==0, so we can check that.
525+
*/
526+
if (dip->di_version >= 2) {
518527
if (dip->di_onlink)
519528
return __this_address;
520-
} else {
521-
if (dip->di_nlink)
522-
return __this_address;
523529
}
524530

525531
/* don't allow invalid i_size */

fs/xfs/scrub/xfile.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ xfile_get_folio(
293293
* (potentially last) reference in xfile_put_folio.
294294
*/
295295
if (flags & XFILE_ALLOC)
296-
folio_set_dirty(folio);
296+
folio_mark_dirty(folio);
297297
return folio;
298298
}
299299

fs/xfs/xfs_discard.c

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,7 @@ static int
158158
xfs_trim_gather_extents(
159159
struct xfs_perag *pag,
160160
struct xfs_trim_cur *tcur,
161-
struct xfs_busy_extents *extents,
162-
uint64_t *blocks_trimmed)
161+
struct xfs_busy_extents *extents)
163162
{
164163
struct xfs_mount *mp = pag->pag_mount;
165164
struct xfs_trans *tp;
@@ -280,7 +279,6 @@ xfs_trim_gather_extents(
280279

281280
xfs_extent_busy_insert_discard(pag, fbno, flen,
282281
&extents->extent_list);
283-
*blocks_trimmed += flen;
284282
next_extent:
285283
if (tcur->by_bno)
286284
error = xfs_btree_increment(cur, 0, &i);
@@ -327,8 +325,7 @@ xfs_trim_perag_extents(
327325
struct xfs_perag *pag,
328326
xfs_agblock_t start,
329327
xfs_agblock_t end,
330-
xfs_extlen_t minlen,
331-
uint64_t *blocks_trimmed)
328+
xfs_extlen_t minlen)
332329
{
333330
struct xfs_trim_cur tcur = {
334331
.start = start,
@@ -354,8 +351,7 @@ xfs_trim_perag_extents(
354351
extents->owner = extents;
355352
INIT_LIST_HEAD(&extents->extent_list);
356353

357-
error = xfs_trim_gather_extents(pag, &tcur, extents,
358-
blocks_trimmed);
354+
error = xfs_trim_gather_extents(pag, &tcur, extents);
359355
if (error) {
360356
kfree(extents);
361357
break;
@@ -389,8 +385,7 @@ xfs_trim_datadev_extents(
389385
struct xfs_mount *mp,
390386
xfs_daddr_t start,
391387
xfs_daddr_t end,
392-
xfs_extlen_t minlen,
393-
uint64_t *blocks_trimmed)
388+
xfs_extlen_t minlen)
394389
{
395390
xfs_agnumber_t start_agno, end_agno;
396391
xfs_agblock_t start_agbno, end_agbno;
@@ -411,8 +406,7 @@ xfs_trim_datadev_extents(
411406

412407
if (start_agno == end_agno)
413408
agend = end_agbno;
414-
error = xfs_trim_perag_extents(pag, start_agbno, agend, minlen,
415-
blocks_trimmed);
409+
error = xfs_trim_perag_extents(pag, start_agbno, agend, minlen);
416410
if (error)
417411
last_error = error;
418412

@@ -431,9 +425,6 @@ struct xfs_trim_rtdev {
431425
/* list of rt extents to free */
432426
struct list_head extent_list;
433427

434-
/* pointer to count of blocks trimmed */
435-
uint64_t *blocks_trimmed;
436-
437428
/* minimum length that caller allows us to trim */
438429
xfs_rtblock_t minlen_fsb;
439430

@@ -551,7 +542,6 @@ xfs_trim_gather_rtextent(
551542
busyp->length = rlen;
552543
INIT_LIST_HEAD(&busyp->list);
553544
list_add_tail(&busyp->list, &tr->extent_list);
554-
*tr->blocks_trimmed += rlen;
555545

556546
tr->restart_rtx = rec->ar_startext + rec->ar_extcount;
557547
return 0;
@@ -562,13 +552,11 @@ xfs_trim_rtdev_extents(
562552
struct xfs_mount *mp,
563553
xfs_daddr_t start,
564554
xfs_daddr_t end,
565-
xfs_daddr_t minlen,
566-
uint64_t *blocks_trimmed)
555+
xfs_daddr_t minlen)
567556
{
568557
struct xfs_rtalloc_rec low = { };
569558
struct xfs_rtalloc_rec high = { };
570559
struct xfs_trim_rtdev tr = {
571-
.blocks_trimmed = blocks_trimmed,
572560
.minlen_fsb = XFS_BB_TO_FSB(mp, minlen),
573561
};
574562
struct xfs_trans *tp;
@@ -634,7 +622,7 @@ xfs_trim_rtdev_extents(
634622
return error;
635623
}
636624
#else
637-
# define xfs_trim_rtdev_extents(m,s,e,n,b) (-EOPNOTSUPP)
625+
# define xfs_trim_rtdev_extents(...) (-EOPNOTSUPP)
638626
#endif /* CONFIG_XFS_RT */
639627

640628
/*
@@ -661,7 +649,6 @@ xfs_ioc_trim(
661649
xfs_daddr_t start, end;
662650
xfs_extlen_t minlen;
663651
xfs_rfsblock_t max_blocks;
664-
uint64_t blocks_trimmed = 0;
665652
int error, last_error = 0;
666653

667654
if (!capable(CAP_SYS_ADMIN))
@@ -706,23 +693,22 @@ xfs_ioc_trim(
706693
end = start + BTOBBT(range.len) - 1;
707694

708695
if (bdev_max_discard_sectors(mp->m_ddev_targp->bt_bdev)) {
709-
error = xfs_trim_datadev_extents(mp, start, end, minlen,
710-
&blocks_trimmed);
696+
error = xfs_trim_datadev_extents(mp, start, end, minlen);
711697
if (error)
712698
last_error = error;
713699
}
714700

715701
if (rt_bdev && !xfs_trim_should_stop()) {
716-
error = xfs_trim_rtdev_extents(mp, start, end, minlen,
717-
&blocks_trimmed);
702+
error = xfs_trim_rtdev_extents(mp, start, end, minlen);
718703
if (error)
719704
last_error = error;
720705
}
721706

722707
if (last_error)
723708
return last_error;
724709

725-
range.len = XFS_FSB_TO_B(mp, blocks_trimmed);
710+
range.len = min_t(unsigned long long, range.len,
711+
XFS_FSB_TO_B(mp, max_blocks));
726712
if (copy_to_user(urange, &range, sizeof(range)))
727713
return -EFAULT;
728714
return 0;

fs/xfs/xfs_fsmap.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ xfs_fsmap_owner_to_rmap(
7171
switch (src->fmr_owner) {
7272
case 0: /* "lowest owner id possible" */
7373
case -1ULL: /* "highest owner id possible" */
74-
dest->rm_owner = 0;
74+
dest->rm_owner = src->fmr_owner;
7575
break;
7676
case XFS_FMR_OWN_FREE:
7777
dest->rm_owner = XFS_RMAP_OWN_NULL;
@@ -162,6 +162,7 @@ struct xfs_getfsmap_info {
162162
xfs_daddr_t next_daddr; /* next daddr we expect */
163163
/* daddr of low fsmap key when we're using the rtbitmap */
164164
xfs_daddr_t low_daddr;
165+
xfs_daddr_t end_daddr; /* daddr of high fsmap key */
165166
u64 missing_owner; /* owner of holes */
166167
u32 dev; /* device id */
167168
/*
@@ -182,6 +183,7 @@ struct xfs_getfsmap_dev {
182183
int (*fn)(struct xfs_trans *tp,
183184
const struct xfs_fsmap *keys,
184185
struct xfs_getfsmap_info *info);
186+
sector_t nr_sectors;
185187
};
186188

187189
/* Compare two getfsmap device handlers. */
@@ -252,7 +254,7 @@ xfs_getfsmap_rec_before_start(
252254
const struct xfs_rmap_irec *rec,
253255
xfs_daddr_t rec_daddr)
254256
{
255-
if (info->low_daddr != -1ULL)
257+
if (info->low_daddr != XFS_BUF_DADDR_NULL)
256258
return rec_daddr < info->low_daddr;
257259
if (info->low.rm_blockcount)
258260
return xfs_rmap_compare(rec, &info->low) < 0;
@@ -294,6 +296,18 @@ xfs_getfsmap_helper(
294296
return 0;
295297
}
296298

299+
/*
300+
* For an info->last query, we're looking for a gap between the last
301+
* mapping emitted and the high key specified by userspace. If the
302+
* user's query spans less than 1 fsblock, then info->high and
303+
* info->low will have the same rm_startblock, which causes rec_daddr
304+
* and next_daddr to be the same. Therefore, use the end_daddr that
305+
* we calculated from userspace's high key to synthesize the record.
306+
* Note that if the btree query found a mapping, there won't be a gap.
307+
*/
308+
if (info->last && info->end_daddr != XFS_BUF_DADDR_NULL)
309+
rec_daddr = info->end_daddr;
310+
297311
/* Are we just counting mappings? */
298312
if (info->head->fmh_count == 0) {
299313
if (info->head->fmh_entries == UINT_MAX)
@@ -904,17 +918,21 @@ xfs_getfsmap(
904918

905919
/* Set up our device handlers. */
906920
memset(handlers, 0, sizeof(handlers));
921+
handlers[0].nr_sectors = XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);
907922
handlers[0].dev = new_encode_dev(mp->m_ddev_targp->bt_dev);
908923
if (use_rmap)
909924
handlers[0].fn = xfs_getfsmap_datadev_rmapbt;
910925
else
911926
handlers[0].fn = xfs_getfsmap_datadev_bnobt;
912927
if (mp->m_logdev_targp != mp->m_ddev_targp) {
928+
handlers[1].nr_sectors = XFS_FSB_TO_BB(mp,
929+
mp->m_sb.sb_logblocks);
913930
handlers[1].dev = new_encode_dev(mp->m_logdev_targp->bt_dev);
914931
handlers[1].fn = xfs_getfsmap_logdev;
915932
}
916933
#ifdef CONFIG_XFS_RT
917934
if (mp->m_rtdev_targp) {
935+
handlers[2].nr_sectors = XFS_FSB_TO_BB(mp, mp->m_sb.sb_rblocks);
918936
handlers[2].dev = new_encode_dev(mp->m_rtdev_targp->bt_dev);
919937
handlers[2].fn = xfs_getfsmap_rtdev_rtbitmap;
920938
}
@@ -946,6 +964,7 @@ xfs_getfsmap(
946964

947965
info.next_daddr = head->fmh_keys[0].fmr_physical +
948966
head->fmh_keys[0].fmr_length;
967+
info.end_daddr = XFS_BUF_DADDR_NULL;
949968
info.fsmap_recs = fsmap_recs;
950969
info.head = head;
951970

@@ -966,8 +985,11 @@ xfs_getfsmap(
966985
* low key, zero out the low key so that we get
967986
* everything from the beginning.
968987
*/
969-
if (handlers[i].dev == head->fmh_keys[1].fmr_device)
988+
if (handlers[i].dev == head->fmh_keys[1].fmr_device) {
970989
dkeys[1] = head->fmh_keys[1];
990+
info.end_daddr = min(handlers[i].nr_sectors - 1,
991+
dkeys[1].fmr_physical);
992+
}
971993
if (handlers[i].dev > head->fmh_keys[0].fmr_device)
972994
memset(&dkeys[0], 0, sizeof(struct xfs_fsmap));
973995

@@ -983,7 +1005,7 @@ xfs_getfsmap(
9831005
info.dev = handlers[i].dev;
9841006
info.last = false;
9851007
info.pag = NULL;
986-
info.low_daddr = -1ULL;
1008+
info.low_daddr = XFS_BUF_DADDR_NULL;
9871009
info.low.rm_blockcount = 0;
9881010
error = handlers[i].fn(tp, dkeys, &info);
9891011
if (error)

0 commit comments

Comments
 (0)