Skip to content

Commit 5e116e9

Browse files
committed
Merge branch 'guilt/xlog-intent-whiteouts' into xfs-5.19-for-next
2 parents 9cf4f61 + 0d22746 commit 5e116e9

14 files changed

+323
-143
lines changed

fs/xfs/libxfs/xfs_defer.c

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ static const struct xfs_defer_op_type *defer_op_types[] = {
186186
[XFS_DEFER_OPS_TYPE_AGFL_FREE] = &xfs_agfl_free_defer_type,
187187
};
188188

189-
static void
189+
static bool
190190
xfs_defer_create_intent(
191191
struct xfs_trans *tp,
192192
struct xfs_defer_pending *dfp,
@@ -197,23 +197,26 @@ xfs_defer_create_intent(
197197
if (!dfp->dfp_intent)
198198
dfp->dfp_intent = ops->create_intent(tp, &dfp->dfp_work,
199199
dfp->dfp_count, sort);
200+
return dfp->dfp_intent != NULL;
200201
}
201202

202203
/*
203204
* For each pending item in the intake list, log its intent item and the
204205
* associated extents, then add the entire intake list to the end of
205206
* the pending list.
206207
*/
207-
STATIC void
208+
static bool
208209
xfs_defer_create_intents(
209210
struct xfs_trans *tp)
210211
{
211212
struct xfs_defer_pending *dfp;
213+
bool ret = false;
212214

213215
list_for_each_entry(dfp, &tp->t_dfops, dfp_list) {
214216
trace_xfs_defer_create_intent(tp->t_mountp, dfp);
215-
xfs_defer_create_intent(tp, dfp, true);
217+
ret |= xfs_defer_create_intent(tp, dfp, true);
216218
}
219+
return ret;
217220
}
218221

219222
/* Abort all the intents that were committed. */
@@ -487,7 +490,7 @@ int
487490
xfs_defer_finish_noroll(
488491
struct xfs_trans **tp)
489492
{
490-
struct xfs_defer_pending *dfp;
493+
struct xfs_defer_pending *dfp = NULL;
491494
int error = 0;
492495
LIST_HEAD(dop_pending);
493496

@@ -506,17 +509,20 @@ xfs_defer_finish_noroll(
506509
* of time that any one intent item can stick around in memory,
507510
* pinning the log tail.
508511
*/
509-
xfs_defer_create_intents(*tp);
512+
bool has_intents = xfs_defer_create_intents(*tp);
513+
510514
list_splice_init(&(*tp)->t_dfops, &dop_pending);
511515

512-
error = xfs_defer_trans_roll(tp);
513-
if (error)
514-
goto out_shutdown;
516+
if (has_intents || dfp) {
517+
error = xfs_defer_trans_roll(tp);
518+
if (error)
519+
goto out_shutdown;
515520

516-
/* Possibly relog intent items to keep the log moving. */
517-
error = xfs_defer_relog(tp, &dop_pending);
518-
if (error)
519-
goto out_shutdown;
521+
/* Relog intent items to keep the log moving. */
522+
error = xfs_defer_relog(tp, &dop_pending);
523+
if (error)
524+
goto out_shutdown;
525+
}
520526

521527
dfp = list_first_entry(&dop_pending, struct xfs_defer_pending,
522528
dfp_list);

fs/xfs/libxfs/xfs_inode_fork.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ xfs_init_local_fork(
3636
int64_t size)
3737
{
3838
struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
39-
int mem_size = size, real_size = 0;
39+
int mem_size = size;
4040
bool zero_terminate;
4141

4242
/*
@@ -50,8 +50,7 @@ xfs_init_local_fork(
5050
mem_size++;
5151

5252
if (size) {
53-
real_size = roundup(mem_size, 4);
54-
ifp->if_u1.if_data = kmem_alloc(real_size, KM_NOFS);
53+
ifp->if_u1.if_data = kmem_alloc(mem_size, KM_NOFS);
5554
memcpy(ifp->if_u1.if_data, data, size);
5655
if (zero_terminate)
5756
ifp->if_u1.if_data[size] = '\0';
@@ -497,12 +496,7 @@ xfs_idata_realloc(
497496
return;
498497
}
499498

500-
/*
501-
* For inline data, the underlying buffer must be a multiple of 4 bytes
502-
* in size so that it can be logged and stay on word boundaries.
503-
* We enforce that here.
504-
*/
505-
ifp->if_u1.if_data = krealloc(ifp->if_u1.if_data, roundup(new_size, 4),
499+
ifp->if_u1.if_data = krealloc(ifp->if_u1.if_data, new_size,
506500
GFP_NOFS | __GFP_NOFAIL);
507501
ifp->if_bytes = new_size;
508502
}

fs/xfs/libxfs/xfs_shared.h

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,23 @@ void xfs_log_get_max_trans_res(struct xfs_mount *mp,
5454
/*
5555
* Values for t_flags.
5656
*/
57-
#define XFS_TRANS_DIRTY 0x01 /* something needs to be logged */
58-
#define XFS_TRANS_SB_DIRTY 0x02 /* superblock is modified */
59-
#define XFS_TRANS_PERM_LOG_RES 0x04 /* xact took a permanent log res */
60-
#define XFS_TRANS_SYNC 0x08 /* make commit synchronous */
61-
#define XFS_TRANS_RESERVE 0x20 /* OK to use reserved data blocks */
62-
#define XFS_TRANS_NO_WRITECOUNT 0x40 /* do not elevate SB writecount */
63-
#define XFS_TRANS_RES_FDBLKS 0x80 /* reserve newly freed blocks */
57+
/* Transaction needs to be logged */
58+
#define XFS_TRANS_DIRTY (1u << 0)
59+
/* Superblock is dirty and needs to be logged */
60+
#define XFS_TRANS_SB_DIRTY (1u << 1)
61+
/* Transaction took a permanent log reservation */
62+
#define XFS_TRANS_PERM_LOG_RES (1u << 2)
63+
/* Synchronous transaction commit needed */
64+
#define XFS_TRANS_SYNC (1u << 3)
65+
/* Transaction can use reserve block pool */
66+
#define XFS_TRANS_RESERVE (1u << 4)
67+
/* Transaction should avoid VFS level superblock write accounting */
68+
#define XFS_TRANS_NO_WRITECOUNT (1u << 5)
69+
/* Transaction has freed blocks returned to it's reservation */
70+
#define XFS_TRANS_RES_FDBLKS (1u << 6)
71+
/* Transaction contains an intent done log item */
72+
#define XFS_TRANS_HAS_INTENT_DONE (1u << 7)
73+
6474
/*
6575
* LOWMODE is used by the allocator to activate the lowspace algorithm - when
6676
* free space is running low the extent allocator may choose to allocate an

fs/xfs/xfs_bmap_item.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ STATIC void
3939
xfs_bui_item_free(
4040
struct xfs_bui_log_item *buip)
4141
{
42+
kmem_free(buip->bui_item.li_lv_shadow);
4243
kmem_cache_free(xfs_bui_cache, buip);
4344
}
4445

@@ -54,10 +55,11 @@ xfs_bui_release(
5455
struct xfs_bui_log_item *buip)
5556
{
5657
ASSERT(atomic_read(&buip->bui_refcount) > 0);
57-
if (atomic_dec_and_test(&buip->bui_refcount)) {
58-
xfs_trans_ail_delete(&buip->bui_item, SHUTDOWN_LOG_IO_ERROR);
59-
xfs_bui_item_free(buip);
60-
}
58+
if (!atomic_dec_and_test(&buip->bui_refcount))
59+
return;
60+
61+
xfs_trans_ail_delete(&buip->bui_item, 0);
62+
xfs_bui_item_free(buip);
6163
}
6264

6365

@@ -198,14 +200,24 @@ xfs_bud_item_release(
198200
struct xfs_bud_log_item *budp = BUD_ITEM(lip);
199201

200202
xfs_bui_release(budp->bud_buip);
203+
kmem_free(budp->bud_item.li_lv_shadow);
201204
kmem_cache_free(xfs_bud_cache, budp);
202205
}
203206

207+
static struct xfs_log_item *
208+
xfs_bud_item_intent(
209+
struct xfs_log_item *lip)
210+
{
211+
return &BUD_ITEM(lip)->bud_buip->bui_item;
212+
}
213+
204214
static const struct xfs_item_ops xfs_bud_item_ops = {
205-
.flags = XFS_ITEM_RELEASE_WHEN_COMMITTED,
215+
.flags = XFS_ITEM_RELEASE_WHEN_COMMITTED |
216+
XFS_ITEM_INTENT_DONE,
206217
.iop_size = xfs_bud_item_size,
207218
.iop_format = xfs_bud_item_format,
208219
.iop_release = xfs_bud_item_release,
220+
.iop_intent = xfs_bud_item_intent,
209221
};
210222

211223
static struct xfs_bud_log_item *
@@ -254,7 +266,7 @@ xfs_trans_log_finish_bmap_update(
254266
* 1.) releases the BUI and frees the BUD
255267
* 2.) shuts down the filesystem
256268
*/
257-
tp->t_flags |= XFS_TRANS_DIRTY;
269+
tp->t_flags |= XFS_TRANS_DIRTY | XFS_TRANS_HAS_INTENT_DONE;
258270
set_bit(XFS_LI_DIRTY, &budp->bud_item.li_flags);
259271

260272
return error;
@@ -586,6 +598,7 @@ xfs_bui_item_relog(
586598
}
587599

588600
static const struct xfs_item_ops xfs_bui_item_ops = {
601+
.flags = XFS_ITEM_INTENT,
589602
.iop_size = xfs_bui_item_size,
590603
.iop_format = xfs_bui_item_format,
591604
.iop_unpin = xfs_bui_item_unpin,

fs/xfs/xfs_extfree_item.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,11 @@ xfs_efi_release(
5858
struct xfs_efi_log_item *efip)
5959
{
6060
ASSERT(atomic_read(&efip->efi_refcount) > 0);
61-
if (atomic_dec_and_test(&efip->efi_refcount)) {
62-
xfs_trans_ail_delete(&efip->efi_item, SHUTDOWN_LOG_IO_ERROR);
63-
xfs_efi_item_free(efip);
64-
}
61+
if (!atomic_dec_and_test(&efip->efi_refcount))
62+
return;
63+
64+
xfs_trans_ail_delete(&efip->efi_item, 0);
65+
xfs_efi_item_free(efip);
6566
}
6667

6768
/*
@@ -306,11 +307,20 @@ xfs_efd_item_release(
306307
xfs_efd_item_free(efdp);
307308
}
308309

310+
static struct xfs_log_item *
311+
xfs_efd_item_intent(
312+
struct xfs_log_item *lip)
313+
{
314+
return &EFD_ITEM(lip)->efd_efip->efi_item;
315+
}
316+
309317
static const struct xfs_item_ops xfs_efd_item_ops = {
310-
.flags = XFS_ITEM_RELEASE_WHEN_COMMITTED,
318+
.flags = XFS_ITEM_RELEASE_WHEN_COMMITTED |
319+
XFS_ITEM_INTENT_DONE,
311320
.iop_size = xfs_efd_item_size,
312321
.iop_format = xfs_efd_item_format,
313322
.iop_release = xfs_efd_item_release,
323+
.iop_intent = xfs_efd_item_intent,
314324
};
315325

316326
/*
@@ -380,7 +390,7 @@ xfs_trans_free_extent(
380390
* 1.) releases the EFI and frees the EFD
381391
* 2.) shuts down the filesystem
382392
*/
383-
tp->t_flags |= XFS_TRANS_DIRTY;
393+
tp->t_flags |= XFS_TRANS_DIRTY | XFS_TRANS_HAS_INTENT_DONE;
384394
set_bit(XFS_LI_DIRTY, &efdp->efd_item.li_flags);
385395

386396
next_extent = efdp->efd_next_extent;
@@ -688,6 +698,7 @@ xfs_efi_item_relog(
688698
}
689699

690700
static const struct xfs_item_ops xfs_efi_item_ops = {
701+
.flags = XFS_ITEM_INTENT,
691702
.iop_size = xfs_efi_item_size,
692703
.iop_format = xfs_efi_item_format,
693704
.iop_unpin = xfs_efi_item_unpin,

fs/xfs/xfs_icreate_item.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ STATIC void
6363
xfs_icreate_item_release(
6464
struct xfs_log_item *lip)
6565
{
66+
kmem_free(ICR_ITEM(lip)->ic_item.li_lv_shadow);
6667
kmem_cache_free(xfs_icreate_cache, ICR_ITEM(lip));
6768
}
6869

fs/xfs/xfs_inode_item.c

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ xfs_inode_item_data_fork_size(
7171
case XFS_DINODE_FMT_LOCAL:
7272
if ((iip->ili_fields & XFS_ILOG_DDATA) &&
7373
ip->i_df.if_bytes > 0) {
74-
*nbytes += roundup(ip->i_df.if_bytes, 4);
74+
*nbytes += xlog_calc_iovec_len(ip->i_df.if_bytes);
7575
*nvecs += 1;
7676
}
7777
break;
@@ -112,7 +112,7 @@ xfs_inode_item_attr_fork_size(
112112
case XFS_DINODE_FMT_LOCAL:
113113
if ((iip->ili_fields & XFS_ILOG_ADATA) &&
114114
ip->i_afp->if_bytes > 0) {
115-
*nbytes += roundup(ip->i_afp->if_bytes, 4);
115+
*nbytes += xlog_calc_iovec_len(ip->i_afp->if_bytes);
116116
*nvecs += 1;
117117
}
118118
break;
@@ -204,17 +204,12 @@ xfs_inode_item_format_data_fork(
204204
~(XFS_ILOG_DEXT | XFS_ILOG_DBROOT | XFS_ILOG_DEV);
205205
if ((iip->ili_fields & XFS_ILOG_DDATA) &&
206206
ip->i_df.if_bytes > 0) {
207-
/*
208-
* Round i_bytes up to a word boundary.
209-
* The underlying memory is guaranteed
210-
* to be there by xfs_idata_realloc().
211-
*/
212-
data_bytes = roundup(ip->i_df.if_bytes, 4);
213207
ASSERT(ip->i_df.if_u1.if_data != NULL);
214208
ASSERT(ip->i_disk_size > 0);
215209
xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_ILOCAL,
216-
ip->i_df.if_u1.if_data, data_bytes);
217-
ilf->ilf_dsize = (unsigned)data_bytes;
210+
ip->i_df.if_u1.if_data,
211+
ip->i_df.if_bytes);
212+
ilf->ilf_dsize = (unsigned)ip->i_df.if_bytes;
218213
ilf->ilf_size++;
219214
} else {
220215
iip->ili_fields &= ~XFS_ILOG_DDATA;
@@ -288,17 +283,11 @@ xfs_inode_item_format_attr_fork(
288283

289284
if ((iip->ili_fields & XFS_ILOG_ADATA) &&
290285
ip->i_afp->if_bytes > 0) {
291-
/*
292-
* Round i_bytes up to a word boundary.
293-
* The underlying memory is guaranteed
294-
* to be there by xfs_idata_realloc().
295-
*/
296-
data_bytes = roundup(ip->i_afp->if_bytes, 4);
297286
ASSERT(ip->i_afp->if_u1.if_data != NULL);
298287
xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_LOCAL,
299288
ip->i_afp->if_u1.if_data,
300-
data_bytes);
301-
ilf->ilf_asize = (unsigned)data_bytes;
289+
ip->i_afp->if_bytes);
290+
ilf->ilf_asize = (unsigned)ip->i_afp->if_bytes;
302291
ilf->ilf_size++;
303292
} else {
304293
iip->ili_fields &= ~XFS_ILOG_ADATA;

fs/xfs/xfs_inode_item_recover.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ xlog_recover_inode_commit_pass2(
462462
ASSERT(in_f->ilf_size <= 4);
463463
ASSERT((in_f->ilf_size == 3) || (fields & XFS_ILOG_AFORK));
464464
ASSERT(!(fields & XFS_ILOG_DFORK) ||
465-
(len == in_f->ilf_dsize));
465+
(len == xlog_calc_iovec_len(in_f->ilf_dsize)));
466466

467467
switch (fields & XFS_ILOG_DFORK) {
468468
case XFS_ILOG_DDATA:
@@ -497,7 +497,7 @@ xlog_recover_inode_commit_pass2(
497497
}
498498
len = item->ri_buf[attr_index].i_len;
499499
src = item->ri_buf[attr_index].i_addr;
500-
ASSERT(len == in_f->ilf_asize);
500+
ASSERT(len == xlog_calc_iovec_len(in_f->ilf_asize));
501501

502502
switch (in_f->ilf_fields & XFS_ILOG_AFORK) {
503503
case XFS_ILOG_ADATA:

0 commit comments

Comments
 (0)