aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_log_cil.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-23 12:16:20 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-23 12:16:20 -0500
commit1d32bdafaaa8bcc4c39b41ab9f674887d147f188 (patch)
treec1aae09d8b98b033fd4dd85ba3dbf97a25776e90 /fs/xfs/xfs_log_cil.c
parent0dc3fd0249a295863900984e02dd4bb89204205b (diff)
parentbf3964c188d686424ff7b69a45941851b9f437f0 (diff)
Merge tag 'xfs-for-linus-v3.14-rc1' of git://oss.sgi.com/xfs/xfs
Pull xfs update from Ben Myers: "This is primarily bug fixes, many of which you already have. New stuff includes a series to decouple the in-memory and on-disk log format, helpers in the area of inode clusters, and i_version handling. We decided to try to use more topic branches this release, so there are some merge commits in there on account of that. I'm afraid I didn't do a good job of putting meaningful comments in the first couple of merges. Sorry about that. I think I have the hang of it now. For 3.14-rc1 there are fixes in the areas of remote attributes, discard, growfs, memory leaks in recovery, directory v2, quotas, the MAINTAINERS file, allocation alignment, extent list locking, and in xfs_bmapi_allocate. There are cleanups in xfs_setsize_buftarg, removing unused macros, quotas, setattr, and freeing of inode clusters. The in-memory and on-disk log format have been decoupled, a common helper to calculate the number of blocks in an inode cluster has been added, and handling of i_version has been pulled into the filesystems that use it. - cleanup in xfs_setsize_buftarg - removal of remaining unused flags for vop toss/flush/flushinval - fix for memory corruption in xfs_attrlist_by_handle - fix for out-of-date comment in xfs_trans_dqlockedjoin - fix for discard if range length is less than one block - fix for overrun of agfl buffer using growfs on v4 superblock filesystems - pull i_version handling out into the filesystems that use it - don't leak recovery items on error - fix for memory leak in xfs_dir2_node_removename - several cleanups for quotas - fix bad assertion in xfs_qm_vop_create_dqattach - cleanup for xfs_setattr_mode, and add xfs_setattr_time - fix quota assert in xfs_setattr_nonsize - fix an infinite loop when turning off group/project quota before user quota - fix for temporary buffer allocation failure in xfs_dir2_block_to_sf with large directory block sizes - fix Dave's email address in MAINTAINERS - cleanup calculation of freed inode cluster blocks - fix alignment of initial file allocations to match filesystem geometry - decouple in-memory and on-disk log format - introduce a common helper to calculate the number of filesystem blocks in an inode cluster - fixes for extent list locking - fix for off-by-one in xfs_attr3_rmt_verify - fix for missing destroy_work_on_stack in xfs_bmapi_allocate" * tag 'xfs-for-linus-v3.14-rc1' of git://oss.sgi.com/xfs/xfs: (51 commits) xfs: Calling destroy_work_on_stack() to pair with INIT_WORK_ONSTACK() xfs: fix off-by-one error in xfs_attr3_rmt_verify xfs: assert that we hold the ilock for extent map access xfs: use xfs_ilock_attr_map_shared in xfs_attr_list_int xfs: use xfs_ilock_attr_map_shared in xfs_attr_get xfs: use xfs_ilock_data_map_shared in xfs_qm_dqiterate xfs: use xfs_ilock_data_map_shared in xfs_qm_dqtobp xfs: take the ilock around xfs_bmapi_read in xfs_zero_remaining_bytes xfs: reinstate the ilock in xfs_readdir xfs: add xfs_ilock_attr_map_shared xfs: rename xfs_ilock_map_shared xfs: remove xfs_iunlock_map_shared xfs: no need to lock the inode in xfs_find_handle xfs: use xfs_icluster_size_fsb in xfs_imap xfs: use xfs_icluster_size_fsb in xfs_ifree_cluster xfs: use xfs_icluster_size_fsb in xfs_ialloc_inode_init xfs: use xfs_icluster_size_fsb in xfs_bulkstat xfs: introduce a common helper xfs_icluster_size_fsb xfs: get rid of XFS_IALLOC_BLOCKS macros xfs: get rid of XFS_INODE_CLUSTER_SIZE macros ...
Diffstat (limited to 'fs/xfs/xfs_log_cil.c')
-rw-r--r--fs/xfs/xfs_log_cil.c74
1 files changed, 22 insertions, 52 deletions
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c
index 5eb51fc5eb84..cdebd832c3db 100644
--- a/fs/xfs/xfs_log_cil.c
+++ b/fs/xfs/xfs_log_cil.c
@@ -82,36 +82,6 @@ xlog_cil_init_post_recovery(
82 log->l_curr_block); 82 log->l_curr_block);
83} 83}
84 84
85STATIC int
86xlog_cil_lv_item_format(
87 struct xfs_log_item *lip,
88 struct xfs_log_vec *lv)
89{
90 int index;
91 char *ptr;
92
93 /* format new vectors into array */
94 lip->li_ops->iop_format(lip, lv->lv_iovecp);
95
96 /* copy data into existing array */
97 ptr = lv->lv_buf;
98 for (index = 0; index < lv->lv_niovecs; index++) {
99 struct xfs_log_iovec *vec = &lv->lv_iovecp[index];
100
101 memcpy(ptr, vec->i_addr, vec->i_len);
102 vec->i_addr = ptr;
103 ptr += vec->i_len;
104 }
105
106 /*
107 * some size calculations for log vectors over-estimate, so the caller
108 * doesn't know the amount of space actually used by the item. Return
109 * the byte count to the caller so they can check and store it
110 * appropriately.
111 */
112 return ptr - lv->lv_buf;
113}
114
115/* 85/*
116 * Prepare the log item for insertion into the CIL. Calculate the difference in 86 * Prepare the log item for insertion into the CIL. Calculate the difference in
117 * log space and vectors it will consume, and if it is a new item pin it as 87 * log space and vectors it will consume, and if it is a new item pin it as
@@ -232,6 +202,13 @@ xlog_cil_insert_format_items(
232 nbytes = 0; 202 nbytes = 0;
233 } 203 }
234 204
205 /*
206 * We 64-bit align the length of each iovec so that the start
207 * of the next one is naturally aligned. We'll need to
208 * account for that slack space here.
209 */
210 nbytes += niovecs * sizeof(uint64_t);
211
235 /* grab the old item if it exists for reservation accounting */ 212 /* grab the old item if it exists for reservation accounting */
236 old_lv = lip->li_lv; 213 old_lv = lip->li_lv;
237 214
@@ -254,34 +231,27 @@ xlog_cil_insert_format_items(
254 */ 231 */
255 *diff_iovecs -= lv->lv_niovecs; 232 *diff_iovecs -= lv->lv_niovecs;
256 *diff_len -= lv->lv_buf_len; 233 *diff_len -= lv->lv_buf_len;
257 234 } else {
258 /* Ensure the lv is set up according to ->iop_size */ 235 /* allocate new data chunk */
259 lv->lv_niovecs = niovecs; 236 lv = kmem_zalloc(buf_size, KM_SLEEP|KM_NOFS);
260 lv->lv_buf = (char *)lv + buf_size - nbytes; 237 lv->lv_item = lip;
261 238 lv->lv_size = buf_size;
262 lv->lv_buf_len = xlog_cil_lv_item_format(lip, lv); 239 if (ordered) {
263 goto insert; 240 /* track as an ordered logvec */
241 ASSERT(lip->li_lv == NULL);
242 lv->lv_buf_len = XFS_LOG_VEC_ORDERED;
243 goto insert;
244 }
245 lv->lv_iovecp = (struct xfs_log_iovec *)&lv[1];
264 } 246 }
265 247
266 /* allocate new data chunk */ 248 /* Ensure the lv is set up according to ->iop_size */
267 lv = kmem_zalloc(buf_size, KM_SLEEP|KM_NOFS);
268 lv->lv_item = lip;
269 lv->lv_size = buf_size;
270 lv->lv_niovecs = niovecs; 249 lv->lv_niovecs = niovecs;
271 if (ordered) {
272 /* track as an ordered logvec */
273 ASSERT(lip->li_lv == NULL);
274 lv->lv_buf_len = XFS_LOG_VEC_ORDERED;
275 goto insert;
276 }
277
278 /* The allocated iovec region lies beyond the log vector. */
279 lv->lv_iovecp = (struct xfs_log_iovec *)&lv[1];
280 250
281 /* The allocated data region lies beyond the iovec region */ 251 /* The allocated data region lies beyond the iovec region */
252 lv->lv_buf_len = 0;
282 lv->lv_buf = (char *)lv + buf_size - nbytes; 253 lv->lv_buf = (char *)lv + buf_size - nbytes;
283 254 lip->li_ops->iop_format(lip, lv);
284 lv->lv_buf_len = xlog_cil_lv_item_format(lip, lv);
285insert: 255insert:
286 ASSERT(lv->lv_buf_len <= nbytes); 256 ASSERT(lv->lv_buf_len <= nbytes);
287 xfs_cil_prepare_item(log, lv, old_lv, diff_len, diff_iovecs); 257 xfs_cil_prepare_item(log, lv, old_lv, diff_len, diff_iovecs);