Skip to content

Commit db35707

Browse files
dgchinnerdchinner
authored andcommitted
xfs: introduce xlog_write_full()
Introduce an optimised version of xlog_write() that is used when the entire write will fit in a single iclog. This greatly simplifies the implementation of writing a log vector chain into an iclog, and sets the ground work for a much more understandable xlog_write() implementation. This incorporates some factoring and simplifications proposed by Christoph Hellwig. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Chandan Babu R <chandan.babu@oracle.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
1 parent decb545 commit db35707

1 file changed

Lines changed: 66 additions & 3 deletions

File tree

fs/xfs/xfs_log.c

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2210,6 +2210,58 @@ xlog_print_trans(
22102210
}
22112211
}
22122212

2213+
static inline void
2214+
xlog_write_iovec(
2215+
struct xlog_in_core *iclog,
2216+
uint32_t *log_offset,
2217+
void *data,
2218+
uint32_t write_len,
2219+
int *bytes_left,
2220+
uint32_t *record_cnt,
2221+
uint32_t *data_cnt)
2222+
{
2223+
ASSERT(*log_offset % sizeof(int32_t) == 0);
2224+
ASSERT(write_len % sizeof(int32_t) == 0);
2225+
2226+
memcpy(iclog->ic_datap + *log_offset, data, write_len);
2227+
*log_offset += write_len;
2228+
*bytes_left -= write_len;
2229+
(*record_cnt)++;
2230+
*data_cnt += write_len;
2231+
}
2232+
2233+
/*
2234+
* Write log vectors into a single iclog which is guaranteed by the caller
2235+
* to have enough space to write the entire log vector into.
2236+
*/
2237+
static void
2238+
xlog_write_full(
2239+
struct xfs_log_vec *lv,
2240+
struct xlog_ticket *ticket,
2241+
struct xlog_in_core *iclog,
2242+
uint32_t *log_offset,
2243+
uint32_t *len,
2244+
uint32_t *record_cnt,
2245+
uint32_t *data_cnt)
2246+
{
2247+
int index;
2248+
2249+
ASSERT(*log_offset + *len <= iclog->ic_size);
2250+
2251+
/*
2252+
* Ordered log vectors have no regions to write so this
2253+
* loop will naturally skip them.
2254+
*/
2255+
for (index = 0; index < lv->lv_niovecs; index++) {
2256+
struct xfs_log_iovec *reg = &lv->lv_iovecp[index];
2257+
struct xlog_op_header *ophdr = reg->i_addr;
2258+
2259+
ophdr->oh_tid = cpu_to_be32(ticket->t_tid);
2260+
xlog_write_iovec(iclog, log_offset, reg->i_addr,
2261+
reg->i_len, len, record_cnt, data_cnt);
2262+
}
2263+
}
2264+
22132265
static xlog_op_header_t *
22142266
xlog_write_setup_ophdr(
22152267
struct xlog_op_header *ophdr,
@@ -2374,8 +2426,8 @@ xlog_write(
23742426
int partial_copy = 0;
23752427
int partial_copy_len = 0;
23762428
int contwr = 0;
2377-
int record_cnt = 0;
2378-
int data_cnt = 0;
2429+
uint32_t record_cnt = 0;
2430+
uint32_t data_cnt = 0;
23792431
int error = 0;
23802432

23812433
if (ticket->t_curr_res < 0) {
@@ -2395,7 +2447,6 @@ xlog_write(
23952447
return error;
23962448

23972449
ASSERT(log_offset <= iclog->ic_size - 1);
2398-
ptr = iclog->ic_datap + log_offset;
23992450

24002451
/*
24012452
* If we have a context pointer, pass it the first iclog we are
@@ -2407,10 +2458,22 @@ xlog_write(
24072458
ctx = NULL;
24082459
}
24092460

2461+
/* If this is a single iclog write, go fast... */
2462+
if (!contwr && lv == log_vector) {
2463+
while (lv) {
2464+
xlog_write_full(lv, ticket, iclog, &log_offset,
2465+
&len, &record_cnt, &data_cnt);
2466+
lv = lv->lv_next;
2467+
}
2468+
data_cnt = 0;
2469+
break;
2470+
}
2471+
24102472
/*
24112473
* This loop writes out as many regions as can fit in the amount
24122474
* of space which was allocated by xlog_state_get_iclog_space().
24132475
*/
2476+
ptr = iclog->ic_datap + log_offset;
24142477
while (lv && (!lv->lv_niovecs || index < lv->lv_niovecs)) {
24152478
struct xfs_log_iovec *reg;
24162479
struct xlog_op_header *ophdr;

0 commit comments

Comments
 (0)