diff options
| -rw-r--r-- | fs/xfs/xfs_log.h | 19 | ||||
| -rw-r--r-- | fs/xfs/xfs_log_cil.c | 7 |
2 files changed, 17 insertions, 9 deletions
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h index 2c4004475e71..84e0deb95abd 100644 --- a/fs/xfs/xfs_log.h +++ b/fs/xfs/xfs_log.h | |||
| @@ -24,7 +24,8 @@ struct xfs_log_vec { | |||
| 24 | struct xfs_log_iovec *lv_iovecp; /* iovec array */ | 24 | struct xfs_log_iovec *lv_iovecp; /* iovec array */ |
| 25 | struct xfs_log_item *lv_item; /* owner */ | 25 | struct xfs_log_item *lv_item; /* owner */ |
| 26 | char *lv_buf; /* formatted buffer */ | 26 | char *lv_buf; /* formatted buffer */ |
| 27 | int lv_buf_len; /* size of formatted buffer */ | 27 | int lv_bytes; /* accounted space in buffer */ |
| 28 | int lv_buf_len; /* aligned size of buffer */ | ||
| 28 | int lv_size; /* size of allocated lv */ | 29 | int lv_size; /* size of allocated lv */ |
| 29 | }; | 30 | }; |
| 30 | 31 | ||
| @@ -52,15 +53,21 @@ xlog_prepare_iovec(struct xfs_log_vec *lv, struct xfs_log_iovec **vecp, | |||
| 52 | return vec->i_addr; | 53 | return vec->i_addr; |
| 53 | } | 54 | } |
| 54 | 55 | ||
| 56 | /* | ||
| 57 | * We need to make sure the next buffer is naturally aligned for the biggest | ||
| 58 | * basic data type we put into it. We already accounted for this padding when | ||
| 59 | * sizing the buffer. | ||
| 60 | * | ||
| 61 | * However, this padding does not get written into the log, and hence we have to | ||
| 62 | * track the space used by the log vectors separately to prevent log space hangs | ||
| 63 | * due to inaccurate accounting (i.e. a leak) of the used log space through the | ||
| 64 | * CIL context ticket. | ||
| 65 | */ | ||
| 55 | static inline void | 66 | static inline void |
| 56 | xlog_finish_iovec(struct xfs_log_vec *lv, struct xfs_log_iovec *vec, int len) | 67 | xlog_finish_iovec(struct xfs_log_vec *lv, struct xfs_log_iovec *vec, int len) |
| 57 | { | 68 | { |
| 58 | /* | ||
| 59 | * We need to make sure the next buffer is naturally aligned for the | ||
| 60 | * biggest basic data type we put into it. We already accounted for | ||
| 61 | * this when sizing the buffer. | ||
| 62 | */ | ||
| 63 | lv->lv_buf_len += round_up(len, sizeof(uint64_t)); | 69 | lv->lv_buf_len += round_up(len, sizeof(uint64_t)); |
| 70 | lv->lv_bytes += len; | ||
| 64 | vec->i_len = len; | 71 | vec->i_len = len; |
| 65 | } | 72 | } |
| 66 | 73 | ||
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index 7e5455391176..de835da6764d 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c | |||
| @@ -97,7 +97,7 @@ xfs_cil_prepare_item( | |||
| 97 | { | 97 | { |
| 98 | /* Account for the new LV being passed in */ | 98 | /* Account for the new LV being passed in */ |
| 99 | if (lv->lv_buf_len != XFS_LOG_VEC_ORDERED) { | 99 | if (lv->lv_buf_len != XFS_LOG_VEC_ORDERED) { |
| 100 | *diff_len += lv->lv_buf_len; | 100 | *diff_len += lv->lv_bytes; |
| 101 | *diff_iovecs += lv->lv_niovecs; | 101 | *diff_iovecs += lv->lv_niovecs; |
| 102 | } | 102 | } |
| 103 | 103 | ||
| @@ -111,7 +111,7 @@ xfs_cil_prepare_item( | |||
| 111 | else if (old_lv != lv) { | 111 | else if (old_lv != lv) { |
| 112 | ASSERT(lv->lv_buf_len != XFS_LOG_VEC_ORDERED); | 112 | ASSERT(lv->lv_buf_len != XFS_LOG_VEC_ORDERED); |
| 113 | 113 | ||
| 114 | *diff_len -= old_lv->lv_buf_len; | 114 | *diff_len -= old_lv->lv_bytes; |
| 115 | *diff_iovecs -= old_lv->lv_niovecs; | 115 | *diff_iovecs -= old_lv->lv_niovecs; |
| 116 | kmem_free(old_lv); | 116 | kmem_free(old_lv); |
| 117 | } | 117 | } |
| @@ -239,7 +239,7 @@ xlog_cil_insert_format_items( | |||
| 239 | * that the space reservation accounting is correct. | 239 | * that the space reservation accounting is correct. |
| 240 | */ | 240 | */ |
| 241 | *diff_iovecs -= lv->lv_niovecs; | 241 | *diff_iovecs -= lv->lv_niovecs; |
| 242 | *diff_len -= lv->lv_buf_len; | 242 | *diff_len -= lv->lv_bytes; |
| 243 | } else { | 243 | } else { |
| 244 | /* allocate new data chunk */ | 244 | /* allocate new data chunk */ |
| 245 | lv = kmem_zalloc(buf_size, KM_SLEEP|KM_NOFS); | 245 | lv = kmem_zalloc(buf_size, KM_SLEEP|KM_NOFS); |
| @@ -259,6 +259,7 @@ xlog_cil_insert_format_items( | |||
| 259 | 259 | ||
| 260 | /* The allocated data region lies beyond the iovec region */ | 260 | /* The allocated data region lies beyond the iovec region */ |
| 261 | lv->lv_buf_len = 0; | 261 | lv->lv_buf_len = 0; |
| 262 | lv->lv_bytes = 0; | ||
| 262 | lv->lv_buf = (char *)lv + buf_size - nbytes; | 263 | lv->lv_buf = (char *)lv + buf_size - nbytes; |
| 263 | ASSERT(IS_ALIGNED((unsigned long)lv->lv_buf, sizeof(uint64_t))); | 264 | ASSERT(IS_ALIGNED((unsigned long)lv->lv_buf, sizeof(uint64_t))); |
| 264 | 265 | ||
