Loading fs/xfs/libxfs/xfs_defer.c +18 −12 Original line number Diff line number Diff line Loading @@ -186,7 +186,7 @@ static const struct xfs_defer_op_type *defer_op_types[] = { [XFS_DEFER_OPS_TYPE_AGFL_FREE] = &xfs_agfl_free_defer_type, }; static void static bool xfs_defer_create_intent( struct xfs_trans *tp, struct xfs_defer_pending *dfp, Loading @@ -197,6 +197,7 @@ xfs_defer_create_intent( if (!dfp->dfp_intent) dfp->dfp_intent = ops->create_intent(tp, &dfp->dfp_work, dfp->dfp_count, sort); return dfp->dfp_intent != NULL; } /* Loading @@ -204,16 +205,18 @@ xfs_defer_create_intent( * associated extents, then add the entire intake list to the end of * the pending list. */ STATIC void static bool xfs_defer_create_intents( struct xfs_trans *tp) { struct xfs_defer_pending *dfp; bool ret = false; list_for_each_entry(dfp, &tp->t_dfops, dfp_list) { trace_xfs_defer_create_intent(tp->t_mountp, dfp); xfs_defer_create_intent(tp, dfp, true); ret |= xfs_defer_create_intent(tp, dfp, true); } return ret; } /* Abort all the intents that were committed. */ Loading Loading @@ -487,7 +490,7 @@ int xfs_defer_finish_noroll( struct xfs_trans **tp) { struct xfs_defer_pending *dfp; struct xfs_defer_pending *dfp = NULL; int error = 0; LIST_HEAD(dop_pending); Loading @@ -506,17 +509,20 @@ xfs_defer_finish_noroll( * of time that any one intent item can stick around in memory, * pinning the log tail. */ xfs_defer_create_intents(*tp); bool has_intents = xfs_defer_create_intents(*tp); list_splice_init(&(*tp)->t_dfops, &dop_pending); if (has_intents || dfp) { error = xfs_defer_trans_roll(tp); if (error) goto out_shutdown; /* Possibly relog intent items to keep the log moving. */ /* Relog intent items to keep the log moving. */ error = xfs_defer_relog(tp, &dop_pending); if (error) goto out_shutdown; } dfp = list_first_entry(&dop_pending, struct xfs_defer_pending, dfp_list); Loading fs/xfs/libxfs/xfs_inode_fork.c +3 −9 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ xfs_init_local_fork( int64_t size) { struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); int mem_size = size, real_size = 0; int mem_size = size; bool zero_terminate; /* Loading @@ -50,8 +50,7 @@ xfs_init_local_fork( mem_size++; if (size) { real_size = roundup(mem_size, 4); ifp->if_u1.if_data = kmem_alloc(real_size, KM_NOFS); ifp->if_u1.if_data = kmem_alloc(mem_size, KM_NOFS); memcpy(ifp->if_u1.if_data, data, size); if (zero_terminate) ifp->if_u1.if_data[size] = '\0'; Loading Loading @@ -497,12 +496,7 @@ xfs_idata_realloc( 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 = krealloc(ifp->if_u1.if_data, roundup(new_size, 4), ifp->if_u1.if_data = krealloc(ifp->if_u1.if_data, new_size, GFP_NOFS | __GFP_NOFAIL); ifp->if_bytes = new_size; } Loading fs/xfs/libxfs/xfs_shared.h +17 −7 Original line number Diff line number Diff line Loading @@ -54,13 +54,23 @@ void xfs_log_get_max_trans_res(struct xfs_mount *mp, /* * Values for t_flags. */ #define XFS_TRANS_DIRTY 0x01 /* something needs to be logged */ #define XFS_TRANS_SB_DIRTY 0x02 /* superblock is modified */ #define XFS_TRANS_PERM_LOG_RES 0x04 /* xact took a permanent log res */ #define XFS_TRANS_SYNC 0x08 /* make commit synchronous */ #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_RES_FDBLKS 0x80 /* reserve newly freed blocks */ /* Transaction needs to be logged */ #define XFS_TRANS_DIRTY (1u << 0) /* Superblock is dirty and needs to be logged */ #define XFS_TRANS_SB_DIRTY (1u << 1) /* Transaction took a permanent log reservation */ #define XFS_TRANS_PERM_LOG_RES (1u << 2) /* Synchronous transaction commit needed */ #define XFS_TRANS_SYNC (1u << 3) /* Transaction can use reserve block pool */ #define XFS_TRANS_RESERVE (1u << 4) /* Transaction should avoid VFS level superblock write accounting */ #define XFS_TRANS_NO_WRITECOUNT (1u << 5) /* Transaction has freed blocks returned to it's reservation */ #define XFS_TRANS_RES_FDBLKS (1u << 6) /* Transaction contains an intent done log item */ #define XFS_TRANS_HAS_INTENT_DONE (1u << 7) /* * 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 Loading fs/xfs/xfs_bmap_item.c +19 −6 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ STATIC void xfs_bui_item_free( struct xfs_bui_log_item *buip) { kmem_free(buip->bui_item.li_lv_shadow); kmem_cache_free(xfs_bui_cache, buip); } Loading @@ -54,11 +55,12 @@ xfs_bui_release( struct xfs_bui_log_item *buip) { ASSERT(atomic_read(&buip->bui_refcount) > 0); if (atomic_dec_and_test(&buip->bui_refcount)) { xfs_trans_ail_delete(&buip->bui_item, SHUTDOWN_LOG_IO_ERROR); if (!atomic_dec_and_test(&buip->bui_refcount)) return; xfs_trans_ail_delete(&buip->bui_item, 0); xfs_bui_item_free(buip); } } STATIC void Loading Loading @@ -198,14 +200,24 @@ xfs_bud_item_release( struct xfs_bud_log_item *budp = BUD_ITEM(lip); xfs_bui_release(budp->bud_buip); kmem_free(budp->bud_item.li_lv_shadow); kmem_cache_free(xfs_bud_cache, budp); } static struct xfs_log_item * xfs_bud_item_intent( struct xfs_log_item *lip) { return &BUD_ITEM(lip)->bud_buip->bui_item; } static const struct xfs_item_ops xfs_bud_item_ops = { .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED, .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED | XFS_ITEM_INTENT_DONE, .iop_size = xfs_bud_item_size, .iop_format = xfs_bud_item_format, .iop_release = xfs_bud_item_release, .iop_intent = xfs_bud_item_intent, }; static struct xfs_bud_log_item * Loading Loading @@ -254,7 +266,7 @@ xfs_trans_log_finish_bmap_update( * 1.) releases the BUI and frees the BUD * 2.) shuts down the filesystem */ tp->t_flags |= XFS_TRANS_DIRTY; tp->t_flags |= XFS_TRANS_DIRTY | XFS_TRANS_HAS_INTENT_DONE; set_bit(XFS_LI_DIRTY, &budp->bud_item.li_flags); return error; Loading Loading @@ -586,6 +598,7 @@ xfs_bui_item_relog( } static const struct xfs_item_ops xfs_bui_item_ops = { .flags = XFS_ITEM_INTENT, .iop_size = xfs_bui_item_size, .iop_format = xfs_bui_item_format, .iop_unpin = xfs_bui_item_unpin, Loading fs/xfs/xfs_extfree_item.c +17 −6 Original line number Diff line number Diff line Loading @@ -58,11 +58,12 @@ xfs_efi_release( struct xfs_efi_log_item *efip) { ASSERT(atomic_read(&efip->efi_refcount) > 0); if (atomic_dec_and_test(&efip->efi_refcount)) { xfs_trans_ail_delete(&efip->efi_item, SHUTDOWN_LOG_IO_ERROR); if (!atomic_dec_and_test(&efip->efi_refcount)) return; xfs_trans_ail_delete(&efip->efi_item, 0); xfs_efi_item_free(efip); } } /* * This returns the number of iovecs needed to log the given efi item. Loading Loading @@ -306,11 +307,20 @@ xfs_efd_item_release( xfs_efd_item_free(efdp); } static struct xfs_log_item * xfs_efd_item_intent( struct xfs_log_item *lip) { return &EFD_ITEM(lip)->efd_efip->efi_item; } static const struct xfs_item_ops xfs_efd_item_ops = { .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED, .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED | XFS_ITEM_INTENT_DONE, .iop_size = xfs_efd_item_size, .iop_format = xfs_efd_item_format, .iop_release = xfs_efd_item_release, .iop_intent = xfs_efd_item_intent, }; /* Loading Loading @@ -380,7 +390,7 @@ xfs_trans_free_extent( * 1.) releases the EFI and frees the EFD * 2.) shuts down the filesystem */ tp->t_flags |= XFS_TRANS_DIRTY; tp->t_flags |= XFS_TRANS_DIRTY | XFS_TRANS_HAS_INTENT_DONE; set_bit(XFS_LI_DIRTY, &efdp->efd_item.li_flags); next_extent = efdp->efd_next_extent; Loading Loading @@ -688,6 +698,7 @@ xfs_efi_item_relog( } static const struct xfs_item_ops xfs_efi_item_ops = { .flags = XFS_ITEM_INTENT, .iop_size = xfs_efi_item_size, .iop_format = xfs_efi_item_format, .iop_unpin = xfs_efi_item_unpin, Loading Loading
fs/xfs/libxfs/xfs_defer.c +18 −12 Original line number Diff line number Diff line Loading @@ -186,7 +186,7 @@ static const struct xfs_defer_op_type *defer_op_types[] = { [XFS_DEFER_OPS_TYPE_AGFL_FREE] = &xfs_agfl_free_defer_type, }; static void static bool xfs_defer_create_intent( struct xfs_trans *tp, struct xfs_defer_pending *dfp, Loading @@ -197,6 +197,7 @@ xfs_defer_create_intent( if (!dfp->dfp_intent) dfp->dfp_intent = ops->create_intent(tp, &dfp->dfp_work, dfp->dfp_count, sort); return dfp->dfp_intent != NULL; } /* Loading @@ -204,16 +205,18 @@ xfs_defer_create_intent( * associated extents, then add the entire intake list to the end of * the pending list. */ STATIC void static bool xfs_defer_create_intents( struct xfs_trans *tp) { struct xfs_defer_pending *dfp; bool ret = false; list_for_each_entry(dfp, &tp->t_dfops, dfp_list) { trace_xfs_defer_create_intent(tp->t_mountp, dfp); xfs_defer_create_intent(tp, dfp, true); ret |= xfs_defer_create_intent(tp, dfp, true); } return ret; } /* Abort all the intents that were committed. */ Loading Loading @@ -487,7 +490,7 @@ int xfs_defer_finish_noroll( struct xfs_trans **tp) { struct xfs_defer_pending *dfp; struct xfs_defer_pending *dfp = NULL; int error = 0; LIST_HEAD(dop_pending); Loading @@ -506,17 +509,20 @@ xfs_defer_finish_noroll( * of time that any one intent item can stick around in memory, * pinning the log tail. */ xfs_defer_create_intents(*tp); bool has_intents = xfs_defer_create_intents(*tp); list_splice_init(&(*tp)->t_dfops, &dop_pending); if (has_intents || dfp) { error = xfs_defer_trans_roll(tp); if (error) goto out_shutdown; /* Possibly relog intent items to keep the log moving. */ /* Relog intent items to keep the log moving. */ error = xfs_defer_relog(tp, &dop_pending); if (error) goto out_shutdown; } dfp = list_first_entry(&dop_pending, struct xfs_defer_pending, dfp_list); Loading
fs/xfs/libxfs/xfs_inode_fork.c +3 −9 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ xfs_init_local_fork( int64_t size) { struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); int mem_size = size, real_size = 0; int mem_size = size; bool zero_terminate; /* Loading @@ -50,8 +50,7 @@ xfs_init_local_fork( mem_size++; if (size) { real_size = roundup(mem_size, 4); ifp->if_u1.if_data = kmem_alloc(real_size, KM_NOFS); ifp->if_u1.if_data = kmem_alloc(mem_size, KM_NOFS); memcpy(ifp->if_u1.if_data, data, size); if (zero_terminate) ifp->if_u1.if_data[size] = '\0'; Loading Loading @@ -497,12 +496,7 @@ xfs_idata_realloc( 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 = krealloc(ifp->if_u1.if_data, roundup(new_size, 4), ifp->if_u1.if_data = krealloc(ifp->if_u1.if_data, new_size, GFP_NOFS | __GFP_NOFAIL); ifp->if_bytes = new_size; } Loading
fs/xfs/libxfs/xfs_shared.h +17 −7 Original line number Diff line number Diff line Loading @@ -54,13 +54,23 @@ void xfs_log_get_max_trans_res(struct xfs_mount *mp, /* * Values for t_flags. */ #define XFS_TRANS_DIRTY 0x01 /* something needs to be logged */ #define XFS_TRANS_SB_DIRTY 0x02 /* superblock is modified */ #define XFS_TRANS_PERM_LOG_RES 0x04 /* xact took a permanent log res */ #define XFS_TRANS_SYNC 0x08 /* make commit synchronous */ #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_RES_FDBLKS 0x80 /* reserve newly freed blocks */ /* Transaction needs to be logged */ #define XFS_TRANS_DIRTY (1u << 0) /* Superblock is dirty and needs to be logged */ #define XFS_TRANS_SB_DIRTY (1u << 1) /* Transaction took a permanent log reservation */ #define XFS_TRANS_PERM_LOG_RES (1u << 2) /* Synchronous transaction commit needed */ #define XFS_TRANS_SYNC (1u << 3) /* Transaction can use reserve block pool */ #define XFS_TRANS_RESERVE (1u << 4) /* Transaction should avoid VFS level superblock write accounting */ #define XFS_TRANS_NO_WRITECOUNT (1u << 5) /* Transaction has freed blocks returned to it's reservation */ #define XFS_TRANS_RES_FDBLKS (1u << 6) /* Transaction contains an intent done log item */ #define XFS_TRANS_HAS_INTENT_DONE (1u << 7) /* * 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 Loading
fs/xfs/xfs_bmap_item.c +19 −6 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ STATIC void xfs_bui_item_free( struct xfs_bui_log_item *buip) { kmem_free(buip->bui_item.li_lv_shadow); kmem_cache_free(xfs_bui_cache, buip); } Loading @@ -54,11 +55,12 @@ xfs_bui_release( struct xfs_bui_log_item *buip) { ASSERT(atomic_read(&buip->bui_refcount) > 0); if (atomic_dec_and_test(&buip->bui_refcount)) { xfs_trans_ail_delete(&buip->bui_item, SHUTDOWN_LOG_IO_ERROR); if (!atomic_dec_and_test(&buip->bui_refcount)) return; xfs_trans_ail_delete(&buip->bui_item, 0); xfs_bui_item_free(buip); } } STATIC void Loading Loading @@ -198,14 +200,24 @@ xfs_bud_item_release( struct xfs_bud_log_item *budp = BUD_ITEM(lip); xfs_bui_release(budp->bud_buip); kmem_free(budp->bud_item.li_lv_shadow); kmem_cache_free(xfs_bud_cache, budp); } static struct xfs_log_item * xfs_bud_item_intent( struct xfs_log_item *lip) { return &BUD_ITEM(lip)->bud_buip->bui_item; } static const struct xfs_item_ops xfs_bud_item_ops = { .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED, .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED | XFS_ITEM_INTENT_DONE, .iop_size = xfs_bud_item_size, .iop_format = xfs_bud_item_format, .iop_release = xfs_bud_item_release, .iop_intent = xfs_bud_item_intent, }; static struct xfs_bud_log_item * Loading Loading @@ -254,7 +266,7 @@ xfs_trans_log_finish_bmap_update( * 1.) releases the BUI and frees the BUD * 2.) shuts down the filesystem */ tp->t_flags |= XFS_TRANS_DIRTY; tp->t_flags |= XFS_TRANS_DIRTY | XFS_TRANS_HAS_INTENT_DONE; set_bit(XFS_LI_DIRTY, &budp->bud_item.li_flags); return error; Loading Loading @@ -586,6 +598,7 @@ xfs_bui_item_relog( } static const struct xfs_item_ops xfs_bui_item_ops = { .flags = XFS_ITEM_INTENT, .iop_size = xfs_bui_item_size, .iop_format = xfs_bui_item_format, .iop_unpin = xfs_bui_item_unpin, Loading
fs/xfs/xfs_extfree_item.c +17 −6 Original line number Diff line number Diff line Loading @@ -58,11 +58,12 @@ xfs_efi_release( struct xfs_efi_log_item *efip) { ASSERT(atomic_read(&efip->efi_refcount) > 0); if (atomic_dec_and_test(&efip->efi_refcount)) { xfs_trans_ail_delete(&efip->efi_item, SHUTDOWN_LOG_IO_ERROR); if (!atomic_dec_and_test(&efip->efi_refcount)) return; xfs_trans_ail_delete(&efip->efi_item, 0); xfs_efi_item_free(efip); } } /* * This returns the number of iovecs needed to log the given efi item. Loading Loading @@ -306,11 +307,20 @@ xfs_efd_item_release( xfs_efd_item_free(efdp); } static struct xfs_log_item * xfs_efd_item_intent( struct xfs_log_item *lip) { return &EFD_ITEM(lip)->efd_efip->efi_item; } static const struct xfs_item_ops xfs_efd_item_ops = { .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED, .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED | XFS_ITEM_INTENT_DONE, .iop_size = xfs_efd_item_size, .iop_format = xfs_efd_item_format, .iop_release = xfs_efd_item_release, .iop_intent = xfs_efd_item_intent, }; /* Loading Loading @@ -380,7 +390,7 @@ xfs_trans_free_extent( * 1.) releases the EFI and frees the EFD * 2.) shuts down the filesystem */ tp->t_flags |= XFS_TRANS_DIRTY; tp->t_flags |= XFS_TRANS_DIRTY | XFS_TRANS_HAS_INTENT_DONE; set_bit(XFS_LI_DIRTY, &efdp->efd_item.li_flags); next_extent = efdp->efd_next_extent; Loading Loading @@ -688,6 +698,7 @@ xfs_efi_item_relog( } static const struct xfs_item_ops xfs_efi_item_ops = { .flags = XFS_ITEM_INTENT, .iop_size = xfs_efi_item_size, .iop_format = xfs_efi_item_format, .iop_unpin = xfs_efi_item_unpin, Loading