summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_log_priv.h
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-05-25 19:34:40 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2022-05-25 19:34:40 -0700
commitbabf0bb978e3c9fce6c4eba6b744c8754fd43d8e (patch)
tree5ba842c2855515047416e5b5950a0b56ff25d9e1 /fs/xfs/xfs_log_priv.h
parente375780b631a5fc2a61a3b4fa12429255361a31e (diff)
parentefd409a4329f6927795be5ae080cd3ec8c014f49 (diff)
Merge tag 'xfs-5.19-for-linus' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull xfs updates from Dave Chinner: "This is a big update with lots of new code. The summary below them all, so I'll just touch on teh higlights. The two main new features are Large Extent Counts and Logged Attribute Replay - these are two new foundational features that we are building more complex future features on top of. For upcoming functionality, we need to be able to store hundreds of millions of xattrs per inode. The Large Extent Count feature removes the limits that prevent this scale of xattr storage, and while we were modifying the on disk extent count format we also increased the number of data extents we support per inode from 2^32 to 2^47. We also need to be able to modify xattrs as part of larger atomic transactions rather than as standalone transactions. The Logged Attribute Replay feature introduces the infrastructure that allows us to use intents to record the attribute modifications in the journal before we start them, hence allowing other atomic transactions to log attribute modification intents and then defer the actual modification to later. If we then crash, log recovery then guarantees that the attribute is replayed in the context of the atomic transaction that logged the intent. A significant chunk of the commits in this merge are for the base attribute replay functionality along with fixes, improvements and cleanups related to this new functioanlity. Allison deserves a big round of thanks for her ongoing work to get this functionality into XFS. There are also many other smaller changes and improvements, so overall this is one of the bigger XFS merge requests in some time. I will be following up next week with another smaller pull request - we already have another round of fixes and improvements to the logged attribute replay functionality just about ready to go. They'll soak and test over the next week, and I'll send a pull request for them near the end of the merge window. Summary: - support for printk message indexing. - large extent counts to provide support for up to 2^47 data extents and 2^32 attribute extents, allowing us to scale beyond 4 billion data extents to billions of xattrs per inode. - conversion of various flags fields to be consistently declared as unsigned bit fields. - improvements to realtime extent accounting and converts them to per-cpu counters to match all the other block and inode accounting. - reworks core log formatting code to reduce iterations, have a shorter, cleaner fast path and generally be easier to understand and maintain. - improvements to rmap btree searches that reduce overhead by up to 30% resulting in xfs_scrub runtime reductions of 15%. - improvements to reflink that remove the size limitations in remapping operations and greatly reduce the size of transaction reservations. - reworks the minimum log size calculations to allow us to change transaction reservations without changing the minimum supported log size. - removal of quota warning support as it has never been used on Linux. - intent whiteouts to allow us to cancel intents that are completed entirely in memory rather than having use CPU and disk bandwidth formatting and writing them into the journal when it is not necessary. This makes rmap, reflink and extent freeing slightly more efficient, but provides massive improvements for.... - Logged Attribute Replay feature support. This is a fundamental change to the way we modify attributes, laying the foundation for future integration of attribute modifications as part of other atomic transactional operations the filesystem performs. - Lots of cleanups and fixes for the logged attribute replay functionality" * tag 'xfs-5.19-for-linus' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (124 commits) xfs: can't use kmem_zalloc() for attribute buffers xfs: detect empty attr leaf blocks in xfs_attr3_leaf_verify xfs: ATTR_REPLACE algorithm with LARP enabled needs rework xfs: use XFS_DA_OP flags in deferred attr ops xfs: remove xfs_attri_remove_iter xfs: switch attr remove to xfs_attri_set_iter xfs: introduce attr remove initial states into xfs_attr_set_iter xfs: xfs_attr_set_iter() does not need to return EAGAIN xfs: clean up final attr removal in xfs_attr_set_iter xfs: remote xattr removal in xfs_attr_set_iter() is conditional xfs: XFS_DAS_LEAF_REPLACE state only needed if !LARP xfs: split remote attr setting out from replace path xfs: consolidate leaf/node states in xfs_attr_set_iter xfs: kill XFS_DAC_LEAF_ADDNAME_INIT xfs: separate out initial attr_set states xfs: don't set quota warning values xfs: remove warning counters from struct xfs_dquot_res xfs: remove quota warning limit from struct xfs_quota_limits xfs: rework deferred attribute operation setup xfs: make xattri_leaf_bp more useful ...
Diffstat (limited to 'fs/xfs/xfs_log_priv.h')
-rw-r--r--fs/xfs/xfs_log_priv.h89
1 files changed, 42 insertions, 47 deletions
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
index 401cdc400980..67fd9789e69a 100644
--- a/fs/xfs/xfs_log_priv.h
+++ b/fs/xfs/xfs_log_priv.h
@@ -51,8 +51,8 @@ enum xlog_iclog_state {
/*
* In core log flags
*/
-#define XLOG_ICL_NEED_FLUSH (1 << 0) /* iclog needs REQ_PREFLUSH */
-#define XLOG_ICL_NEED_FUA (1 << 1) /* iclog needs REQ_FUA */
+#define XLOG_ICL_NEED_FLUSH (1u << 0) /* iclog needs REQ_PREFLUSH */
+#define XLOG_ICL_NEED_FUA (1u << 1) /* iclog needs REQ_FUA */
#define XLOG_ICL_STRINGS \
{ XLOG_ICL_NEED_FLUSH, "XLOG_ICL_NEED_FLUSH" }, \
@@ -62,7 +62,7 @@ enum xlog_iclog_state {
/*
* Log ticket flags
*/
-#define XLOG_TIC_PERM_RESERV 0x1 /* permanent reservation */
+#define XLOG_TIC_PERM_RESERV (1u << 0) /* permanent reservation */
#define XLOG_TIC_FLAGS \
{ XLOG_TIC_PERM_RESERV, "XLOG_TIC_PERM_RESERV" }
@@ -142,19 +142,6 @@ enum xlog_iclog_state {
#define XLOG_COVER_OPS 5
-/* Ticket reservation region accounting */
-#define XLOG_TIC_LEN_MAX 15
-
-/*
- * Reservation region
- * As would be stored in xfs_log_iovec but without the i_addr which
- * we don't care about.
- */
-typedef struct xlog_res {
- uint r_len; /* region length :4 */
- uint r_type; /* region's transaction type :4 */
-} xlog_res_t;
-
typedef struct xlog_ticket {
struct list_head t_queue; /* reserve/write queue */
struct task_struct *t_task; /* task that owns this ticket */
@@ -164,15 +151,7 @@ typedef struct xlog_ticket {
int t_unit_res; /* unit reservation in bytes : 4 */
char t_ocnt; /* original count : 1 */
char t_cnt; /* current count : 1 */
- char t_clientid; /* who does this belong to; : 1 */
- char t_flags; /* properties of reservation : 1 */
-
- /* reservation array fields */
- uint t_res_num; /* num in array : 4 */
- uint t_res_num_ophdrs; /* num op hdrs : 4 */
- uint t_res_arr_sum; /* array sum : 4 */
- uint t_res_o_flow; /* sum overflow : 4 */
- xlog_res_t t_res_arr[XLOG_TIC_LEN_MAX]; /* array of res : 8 * 15 */
+ uint8_t t_flags; /* properties of reservation : 1 */
} xlog_ticket_t;
/*
@@ -211,7 +190,7 @@ typedef struct xlog_in_core {
u32 ic_offset;
enum xlog_iclog_state ic_state;
unsigned int ic_flags;
- char *ic_datap; /* pointer to iclog data */
+ void *ic_datap; /* pointer to iclog data */
struct list_head ic_callbacks;
/* reference counts need their own cacheline */
@@ -242,7 +221,6 @@ struct xfs_cil_ctx {
xfs_lsn_t commit_lsn; /* chkpt commit record lsn */
struct xlog_in_core *commit_iclog;
struct xlog_ticket *ticket; /* chkpt ticket */
- int nvecs; /* number of regions */
int space_used; /* aggregate size of regions */
struct list_head busy_extents; /* busy extents in chkpt */
struct xfs_log_vec *lv_chain; /* logvecs being pushed */
@@ -441,10 +419,6 @@ struct xlog {
struct xfs_kobj l_kobj;
- /* The following field are used for debugging; need to hold icloglock */
-#ifdef DEBUG
- void *l_iclog_bak[XLOG_MAX_ICLOGS];
-#endif
/* log recovery lsn tracking (for buffer submission */
xfs_lsn_t l_recovery_lsn;
@@ -509,27 +483,14 @@ extern __le32 xlog_cksum(struct xlog *log, struct xlog_rec_header *rhead,
char *dp, int size);
extern struct kmem_cache *xfs_log_ticket_cache;
-struct xlog_ticket *
-xlog_ticket_alloc(
- struct xlog *log,
- int unit_bytes,
- int count,
- char client,
- bool permanent);
-
-static inline void
-xlog_write_adv_cnt(void **ptr, int *len, int *off, size_t bytes)
-{
- *ptr += bytes;
- *len -= bytes;
- *off += bytes;
-}
+struct xlog_ticket *xlog_ticket_alloc(struct xlog *log, int unit_bytes,
+ int count, bool permanent);
void xlog_print_tic_res(struct xfs_mount *mp, struct xlog_ticket *ticket);
void xlog_print_trans(struct xfs_trans *);
int xlog_write(struct xlog *log, struct xfs_cil_ctx *ctx,
struct xfs_log_vec *log_vector, struct xlog_ticket *tic,
- uint optype);
+ uint32_t len);
void xfs_log_ticket_ungrant(struct xlog *log, struct xlog_ticket *ticket);
void xfs_log_ticket_regrant(struct xlog *log, struct xlog_ticket *ticket);
@@ -690,4 +651,38 @@ xlog_valid_lsn(
return valid;
}
+/*
+ * Log vector and shadow buffers can be large, so we need to use kvmalloc() here
+ * to ensure success. Unfortunately, kvmalloc() only allows GFP_KERNEL contexts
+ * to fall back to vmalloc, so we can't actually do anything useful with gfp
+ * flags to control the kmalloc() behaviour within kvmalloc(). Hence kmalloc()
+ * will do direct reclaim and compaction in the slow path, both of which are
+ * horrendously expensive. We just want kmalloc to fail fast and fall back to
+ * vmalloc if it can't get somethign straight away from the free lists or
+ * buddy allocator. Hence we have to open code kvmalloc outselves here.
+ *
+ * This assumes that the caller uses memalloc_nofs_save task context here, so
+ * despite the use of GFP_KERNEL here, we are going to be doing GFP_NOFS
+ * allocations. This is actually the only way to make vmalloc() do GFP_NOFS
+ * allocations, so lets just all pretend this is a GFP_KERNEL context
+ * operation....
+ */
+static inline void *
+xlog_kvmalloc(
+ size_t buf_size)
+{
+ gfp_t flags = GFP_KERNEL;
+ void *p;
+
+ flags &= ~__GFP_DIRECT_RECLAIM;
+ flags |= __GFP_NOWARN | __GFP_NORETRY;
+ do {
+ p = kmalloc(buf_size, flags);
+ if (!p)
+ p = vmalloc(buf_size);
+ } while (!p);
+
+ return p;
+}
+
#endif /* __XFS_LOG_PRIV_H__ */