diff options
author | Christoph Hellwig <hch@infradead.org> | 2013-12-12 19:34:04 -0500 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2013-12-12 19:34:04 -0500 |
commit | da7765031de15273d370d18a5354e1d8001ce2a9 (patch) | |
tree | 6093d45f13fd5228e076a6406ebaed83ff88c193 /fs/xfs/xfs_inode_item.c | |
parent | bde7cff67c39227c6ad503394e19e58debdbc5e3 (diff) |
xfs: format logged extents directly into the CIL
With the new iop_format scheme there is no need to have a temporary buffer
to format logged extents into, we can do so directly into the CIL. This
also allows to remove the shortcut for big endian systems that probably
hasn't gotten a lot of test coverage for a long time.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs/xfs_inode_item.c')
-rw-r--r-- | fs/xfs/xfs_inode_item.c | 113 |
1 files changed, 18 insertions, 95 deletions
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 6ab318f80c96..45224d28049e 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c | |||
@@ -146,43 +146,6 @@ xfs_inode_item_size( | |||
146 | } | 146 | } |
147 | 147 | ||
148 | /* | 148 | /* |
149 | * xfs_inode_item_format_extents - convert in-core extents to on-disk form | ||
150 | * | ||
151 | * For either the data or attr fork in extent format, we need to endian convert | ||
152 | * the in-core extent as we place them into the on-disk inode. In this case, we | ||
153 | * need to do this conversion before we write the extents into the log. Because | ||
154 | * we don't have the disk inode to write into here, we allocate a buffer and | ||
155 | * format the extents into it via xfs_iextents_copy(). We free the buffer in | ||
156 | * the unlock routine after the copy for the log has been made. | ||
157 | * | ||
158 | * In the case of the data fork, the in-core and on-disk fork sizes can be | ||
159 | * different due to delayed allocation extents. We only log on-disk extents | ||
160 | * here, so always use the physical fork size to determine the size of the | ||
161 | * buffer we need to allocate. | ||
162 | */ | ||
163 | STATIC int | ||
164 | xfs_inode_item_format_extents( | ||
165 | struct xfs_inode *ip, | ||
166 | struct xfs_log_vec *lv, | ||
167 | struct xfs_log_iovec **vecp, | ||
168 | int whichfork, | ||
169 | int type) | ||
170 | { | ||
171 | xfs_bmbt_rec_t *ext_buffer; | ||
172 | int len; | ||
173 | |||
174 | ext_buffer = kmem_alloc(XFS_IFORK_SIZE(ip, whichfork), KM_SLEEP); | ||
175 | if (whichfork == XFS_DATA_FORK) | ||
176 | ip->i_itemp->ili_extents_buf = ext_buffer; | ||
177 | else | ||
178 | ip->i_itemp->ili_aextents_buf = ext_buffer; | ||
179 | |||
180 | len = xfs_iextents_copy(ip, ext_buffer, whichfork); | ||
181 | xlog_copy_iovec(lv, vecp, type, ext_buffer, len); | ||
182 | return len; | ||
183 | } | ||
184 | |||
185 | /* | ||
186 | * If this is a v1 format inode, then we need to log it as such. This means | 149 | * If this is a v1 format inode, then we need to log it as such. This means |
187 | * that we have to copy the link count from the new field to the old. We | 150 | * that we have to copy the link count from the new field to the old. We |
188 | * don't have to worry about the new fields, because nothing trusts them as | 151 | * don't have to worry about the new fields, because nothing trusts them as |
@@ -229,30 +192,18 @@ xfs_inode_item_format_data_fork( | |||
229 | if ((iip->ili_fields & XFS_ILOG_DEXT) && | 192 | if ((iip->ili_fields & XFS_ILOG_DEXT) && |
230 | ip->i_d.di_nextents > 0 && | 193 | ip->i_d.di_nextents > 0 && |
231 | ip->i_df.if_bytes > 0) { | 194 | ip->i_df.if_bytes > 0) { |
195 | struct xfs_bmbt_rec *p; | ||
196 | |||
232 | ASSERT(ip->i_df.if_u1.if_extents != NULL); | 197 | ASSERT(ip->i_df.if_u1.if_extents != NULL); |
233 | ASSERT(ip->i_df.if_bytes / sizeof(xfs_bmbt_rec_t) > 0); | 198 | ASSERT(ip->i_df.if_bytes / sizeof(xfs_bmbt_rec_t) > 0); |
234 | ASSERT(iip->ili_extents_buf == NULL); | 199 | |
235 | 200 | p = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_IEXT); | |
236 | #ifdef XFS_NATIVE_HOST | 201 | data_bytes = xfs_iextents_copy(ip, p, XFS_DATA_FORK); |
237 | if (ip->i_d.di_nextents == ip->i_df.if_bytes / | 202 | xlog_finish_iovec(lv, *vecp, data_bytes); |
238 | (uint)sizeof(xfs_bmbt_rec_t)) { | 203 | |
239 | /* | 204 | ASSERT(data_bytes <= ip->i_df.if_bytes); |
240 | * There are no delayed allocation | 205 | |
241 | * extents, so just point to the | 206 | ilf->ilf_dsize = data_bytes; |
242 | * real extents array. | ||
243 | */ | ||
244 | xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IEXT, | ||
245 | ip->i_df.if_u1.if_extents, | ||
246 | ip->i_df.if_bytes); | ||
247 | ilf->ilf_dsize = ip->i_df.if_bytes; | ||
248 | } else | ||
249 | #endif | ||
250 | { | ||
251 | ilf->ilf_dsize = | ||
252 | xfs_inode_item_format_extents(ip, lv, vecp, | ||
253 | XFS_DATA_FORK, XLOG_REG_TYPE_IEXT); | ||
254 | ASSERT(iip->ili_format.ilf_dsize <= ip->i_df.if_bytes); | ||
255 | } | ||
256 | ilf->ilf_size++; | 207 | ilf->ilf_size++; |
257 | } else { | 208 | } else { |
258 | iip->ili_fields &= ~XFS_ILOG_DEXT; | 209 | iip->ili_fields &= ~XFS_ILOG_DEXT; |
@@ -339,24 +290,17 @@ xfs_inode_item_format_attr_fork( | |||
339 | if ((iip->ili_fields & XFS_ILOG_AEXT) && | 290 | if ((iip->ili_fields & XFS_ILOG_AEXT) && |
340 | ip->i_d.di_anextents > 0 && | 291 | ip->i_d.di_anextents > 0 && |
341 | ip->i_afp->if_bytes > 0) { | 292 | ip->i_afp->if_bytes > 0) { |
293 | struct xfs_bmbt_rec *p; | ||
294 | |||
342 | ASSERT(ip->i_afp->if_bytes / sizeof(xfs_bmbt_rec_t) == | 295 | ASSERT(ip->i_afp->if_bytes / sizeof(xfs_bmbt_rec_t) == |
343 | ip->i_d.di_anextents); | 296 | ip->i_d.di_anextents); |
344 | ASSERT(ip->i_afp->if_u1.if_extents != NULL); | 297 | ASSERT(ip->i_afp->if_u1.if_extents != NULL); |
345 | #ifdef XFS_NATIVE_HOST | 298 | |
346 | /* | 299 | p = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_EXT); |
347 | * There are not delayed allocation extents | 300 | data_bytes = xfs_iextents_copy(ip, p, XFS_ATTR_FORK); |
348 | * for attributes, so just point at the array. | 301 | xlog_finish_iovec(lv, *vecp, data_bytes); |
349 | */ | 302 | |
350 | xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_EXT, | 303 | ilf->ilf_asize = data_bytes; |
351 | ip->i_afp->if_u1.if_extents, | ||
352 | ip->i_afp->if_bytes); | ||
353 | ilf->ilf_asize = ip->i_afp->if_bytes; | ||
354 | #else | ||
355 | ASSERT(iip->ili_aextents_buf == NULL); | ||
356 | ilf->ilf_asize = | ||
357 | xfs_inode_item_format_extents(ip, lv, vecp, | ||
358 | XFS_ATTR_FORK, XLOG_REG_TYPE_IATTR_EXT); | ||
359 | #endif | ||
360 | ilf->ilf_size++; | 304 | ilf->ilf_size++; |
361 | } else { | 305 | } else { |
362 | iip->ili_fields &= ~XFS_ILOG_AEXT; | 306 | iip->ili_fields &= ~XFS_ILOG_AEXT; |
@@ -571,27 +515,6 @@ xfs_inode_item_unlock( | |||
571 | ASSERT(ip->i_itemp != NULL); | 515 | ASSERT(ip->i_itemp != NULL); |
572 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); | 516 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
573 | 517 | ||
574 | /* | ||
575 | * If the inode needed a separate buffer with which to log | ||
576 | * its extents, then free it now. | ||
577 | */ | ||
578 | if (iip->ili_extents_buf != NULL) { | ||
579 | ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS); | ||
580 | ASSERT(ip->i_d.di_nextents > 0); | ||
581 | ASSERT(iip->ili_fields & XFS_ILOG_DEXT); | ||
582 | ASSERT(ip->i_df.if_bytes > 0); | ||
583 | kmem_free(iip->ili_extents_buf); | ||
584 | iip->ili_extents_buf = NULL; | ||
585 | } | ||
586 | if (iip->ili_aextents_buf != NULL) { | ||
587 | ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS); | ||
588 | ASSERT(ip->i_d.di_anextents > 0); | ||
589 | ASSERT(iip->ili_fields & XFS_ILOG_AEXT); | ||
590 | ASSERT(ip->i_afp->if_bytes > 0); | ||
591 | kmem_free(iip->ili_aextents_buf); | ||
592 | iip->ili_aextents_buf = NULL; | ||
593 | } | ||
594 | |||
595 | lock_flags = iip->ili_lock_flags; | 518 | lock_flags = iip->ili_lock_flags; |
596 | iip->ili_lock_flags = 0; | 519 | iip->ili_lock_flags = 0; |
597 | if (lock_flags) | 520 | if (lock_flags) |