Commit 6413a014 authored by Darrick J. Wong's avatar Darrick J. Wong

xfs: create bmbt update intent log items

Create bmbt update intent/done log items to record redo information in
the log.  Because we roll transactions multiple times for reflink
operations, we also have to track the status of the metadata updates
that will be recorded in the post-roll transactions in case we crash
before committing the final transaction.  This mechanism enables log
recovery to finish what was already started.
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent 350a27a6
......@@ -102,6 +102,7 @@ xfs-y += xfs_aops.o \
# low-level transaction/log code
xfs-y += xfs_log.o \
xfs_log_cil.o \
xfs_bmap_item.o \
xfs_buf_item.o \
xfs_extfree_item.o \
xfs_icreate_item.o \
......
......@@ -114,7 +114,9 @@ static inline uint xlog_get_cycle(char *ptr)
#define XLOG_REG_TYPE_RUD_FORMAT 22
#define XLOG_REG_TYPE_CUI_FORMAT 23
#define XLOG_REG_TYPE_CUD_FORMAT 24
#define XLOG_REG_TYPE_MAX 24
#define XLOG_REG_TYPE_BUI_FORMAT 25
#define XLOG_REG_TYPE_BUD_FORMAT 26
#define XLOG_REG_TYPE_MAX 26
/*
* Flags to log operation header
......@@ -235,6 +237,8 @@ typedef struct xfs_trans_header {
#define XFS_LI_RUD 0x1241
#define XFS_LI_CUI 0x1242 /* refcount update intent */
#define XFS_LI_CUD 0x1243
#define XFS_LI_BUI 0x1244 /* bmbt update intent */
#define XFS_LI_BUD 0x1245
#define XFS_LI_TYPE_DESC \
{ XFS_LI_EFI, "XFS_LI_EFI" }, \
......@@ -248,7 +252,9 @@ typedef struct xfs_trans_header {
{ XFS_LI_RUI, "XFS_LI_RUI" }, \
{ XFS_LI_RUD, "XFS_LI_RUD" }, \
{ XFS_LI_CUI, "XFS_LI_CUI" }, \
{ XFS_LI_CUD, "XFS_LI_CUD" }
{ XFS_LI_CUD, "XFS_LI_CUD" }, \
{ XFS_LI_BUI, "XFS_LI_BUI" }, \
{ XFS_LI_BUD, "XFS_LI_BUD" }
/*
* Inode Log Item Format definitions.
......@@ -724,6 +730,54 @@ struct xfs_cud_log_format {
__uint64_t cud_cui_id; /* id of corresponding cui */
};
/*
* BUI/BUD (inode block mapping) log format definitions
*/
/* bmbt me_flags: upper bits are flags, lower byte is type code */
/* Type codes are taken directly from enum xfs_bmap_intent_type. */
#define XFS_BMAP_EXTENT_TYPE_MASK 0xFF
#define XFS_BMAP_EXTENT_ATTR_FORK (1U << 31)
#define XFS_BMAP_EXTENT_UNWRITTEN (1U << 30)
#define XFS_BMAP_EXTENT_FLAGS (XFS_BMAP_EXTENT_TYPE_MASK | \
XFS_BMAP_EXTENT_ATTR_FORK | \
XFS_BMAP_EXTENT_UNWRITTEN)
/*
* This is the structure used to lay out an bui log item in the
* log. The bui_extents field is a variable size array whose
* size is given by bui_nextents.
*/
struct xfs_bui_log_format {
__uint16_t bui_type; /* bui log item type */
__uint16_t bui_size; /* size of this item */
__uint32_t bui_nextents; /* # extents to free */
__uint64_t bui_id; /* bui identifier */
struct xfs_map_extent bui_extents[]; /* array of extents to bmap */
};
static inline size_t
xfs_bui_log_format_sizeof(
unsigned int nr)
{
return sizeof(struct xfs_bui_log_format) +
nr * sizeof(struct xfs_map_extent);
}
/*
* This is the structure used to lay out an bud log item in the
* log. The bud_extents array is a variable size array whose
* size is given by bud_nextents;
*/
struct xfs_bud_log_format {
__uint16_t bud_type; /* bud log item type */
__uint16_t bud_size; /* size of this item */
__uint32_t __pad;
__uint64_t bud_bui_id; /* id of corresponding bui */
};
/*
* Dquot Log format definitions.
*
......
This diff is collapsed.
/*
* Copyright (C) 2016 Oracle. All Rights Reserved.
*
* Author: Darrick J. Wong <darrick.wong@oracle.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it would be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __XFS_BMAP_ITEM_H__
#define __XFS_BMAP_ITEM_H__
/*
* There are (currently) two pairs of bmap btree redo item types: map & unmap.
* The common abbreviations for these are BUI (bmap update intent) and BUD
* (bmap update done). The redo item type is encoded in the flags field of
* each xfs_map_extent.
*
* *I items should be recorded in the *first* of a series of rolled
* transactions, and the *D items should be recorded in the same transaction
* that records the associated bmbt updates.
*
* Should the system crash after the commit of the first transaction but
* before the commit of the final transaction in a series, log recovery will
* use the redo information recorded by the intent items to replay the
* bmbt metadata updates in the non-first transaction.
*/
/* kernel only BUI/BUD definitions */
struct xfs_mount;
struct kmem_zone;
/*
* Max number of extents in fast allocation path.
*/
#define XFS_BUI_MAX_FAST_EXTENTS 1
/*
* Define BUI flag bits. Manipulated by set/clear/test_bit operators.
*/
#define XFS_BUI_RECOVERED 1
/*
* This is the "bmap update intent" log item. It is used to log the fact that
* some reverse mappings need to change. It is used in conjunction with the
* "bmap update done" log item described below.
*
* These log items follow the same rules as struct xfs_efi_log_item; see the
* comments about that structure (in xfs_extfree_item.h) for more details.
*/
struct xfs_bui_log_item {
struct xfs_log_item bui_item;
atomic_t bui_refcount;
atomic_t bui_next_extent;
unsigned long bui_flags; /* misc flags */
struct xfs_bui_log_format bui_format;
};
static inline size_t
xfs_bui_log_item_sizeof(
unsigned int nr)
{
return offsetof(struct xfs_bui_log_item, bui_format) +
xfs_bui_log_format_sizeof(nr);
}
/*
* This is the "bmap update done" log item. It is used to log the fact that
* some bmbt updates mentioned in an earlier bui item have been performed.
*/
struct xfs_bud_log_item {
struct xfs_log_item bud_item;
struct xfs_bui_log_item *bud_buip;
struct xfs_bud_log_format bud_format;
};
extern struct kmem_zone *xfs_bui_zone;
extern struct kmem_zone *xfs_bud_zone;
struct xfs_bui_log_item *xfs_bui_init(struct xfs_mount *);
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 *);
#endif /* __XFS_BMAP_ITEM_H__ */
......@@ -48,6 +48,7 @@
#include "xfs_ondisk.h"
#include "xfs_rmap_item.h"
#include "xfs_refcount_item.h"
#include "xfs_bmap_item.h"
#include <linux/namei.h>
#include <linux/init.h>
......@@ -1800,8 +1801,23 @@ xfs_init_zones(void)
if (!xfs_cui_zone)
goto out_destroy_cud_zone;
xfs_bud_zone = kmem_zone_init(sizeof(struct xfs_bud_log_item),
"xfs_bud_item");
if (!xfs_bud_zone)
goto out_destroy_cui_zone;
xfs_bui_zone = kmem_zone_init(
xfs_bui_log_item_sizeof(XFS_BUI_MAX_FAST_EXTENTS),
"xfs_bui_item");
if (!xfs_bui_zone)
goto out_destroy_bud_zone;
return 0;
out_destroy_bud_zone:
kmem_zone_destroy(xfs_bud_zone);
out_destroy_cui_zone:
kmem_zone_destroy(xfs_cui_zone);
out_destroy_cud_zone:
kmem_zone_destroy(xfs_cud_zone);
out_destroy_rui_zone:
......@@ -1848,6 +1864,8 @@ xfs_destroy_zones(void)
* destroy caches.
*/
rcu_barrier();
kmem_zone_destroy(xfs_bui_zone);
kmem_zone_destroy(xfs_bud_zone);
kmem_zone_destroy(xfs_cui_zone);
kmem_zone_destroy(xfs_cud_zone);
kmem_zone_destroy(xfs_rui_zone);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment