aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_extfree_item.c
diff options
context:
space:
mode:
authorTim Shimmin <tes@sgi.com>2006-06-09 00:55:38 -0400
committerNathan Scott <nathans@sgi.com>2006-06-09 00:55:38 -0400
commit6d192a9b82212abf1e0e89da6e3a952afba7e4d6 (patch)
tree608a463ba4fd04f518558ead3567952e757cd2ae /fs/xfs/xfs_extfree_item.c
parentd210a28cd851082cec9b282443f8cc0e6fc09830 (diff)
[XFS] inode items and EFI/EFDs have different ondisk format for 32bit and
64bit kernels allow recovery to handle both versions and do the necessary decoding SGI-PV: 952214 SGI-Modid: xfs-linux-melb:xfs-kern:26011a Signed-off-by: Tim Shimmin <tes@sgi.com> Signed-off-by: Nathan Scott <nathans@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_extfree_item.c')
-rw-r--r--fs/xfs/xfs_extfree_item.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
index f19282ec8549..8b028f128547 100644
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -294,6 +294,62 @@ xfs_efi_init(xfs_mount_t *mp,
294} 294}
295 295
296/* 296/*
297 * Copy an EFI format buffer from the given buf, and into the destination
298 * EFI format structure.
299 * The given buffer can be in 32 bit or 64 bit form (which has different padding),
300 * one of which will be the native format for this kernel.
301 * It will handle the conversion of formats if necessary.
302 */
303int
304xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt)
305{
306 xfs_efi_log_format_t *src_efi_fmt = (xfs_efi_log_format_t *)buf->i_addr;
307 uint i;
308 uint len = sizeof(xfs_efi_log_format_t) +
309 (src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_t);
310 uint len32 = sizeof(xfs_efi_log_format_32_t) +
311 (src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_32_t);
312 uint len64 = sizeof(xfs_efi_log_format_64_t) +
313 (src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_64_t);
314
315 if (buf->i_len == len) {
316 memcpy((char *)dst_efi_fmt, (char*)src_efi_fmt, len);
317 return 0;
318 } else if (buf->i_len == len32) {
319 xfs_efi_log_format_32_t *src_efi_fmt_32 =
320 (xfs_efi_log_format_32_t *)buf->i_addr;
321
322 dst_efi_fmt->efi_type = src_efi_fmt_32->efi_type;
323 dst_efi_fmt->efi_size = src_efi_fmt_32->efi_size;
324 dst_efi_fmt->efi_nextents = src_efi_fmt_32->efi_nextents;
325 dst_efi_fmt->efi_id = src_efi_fmt_32->efi_id;
326 for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
327 dst_efi_fmt->efi_extents[i].ext_start =
328 src_efi_fmt_32->efi_extents[i].ext_start;
329 dst_efi_fmt->efi_extents[i].ext_len =
330 src_efi_fmt_32->efi_extents[i].ext_len;
331 }
332 return 0;
333 } else if (buf->i_len == len64) {
334 xfs_efi_log_format_64_t *src_efi_fmt_64 =
335 (xfs_efi_log_format_64_t *)buf->i_addr;
336
337 dst_efi_fmt->efi_type = src_efi_fmt_64->efi_type;
338 dst_efi_fmt->efi_size = src_efi_fmt_64->efi_size;
339 dst_efi_fmt->efi_nextents = src_efi_fmt_64->efi_nextents;
340 dst_efi_fmt->efi_id = src_efi_fmt_64->efi_id;
341 for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
342 dst_efi_fmt->efi_extents[i].ext_start =
343 src_efi_fmt_64->efi_extents[i].ext_start;
344 dst_efi_fmt->efi_extents[i].ext_len =
345 src_efi_fmt_64->efi_extents[i].ext_len;
346 }
347 return 0;
348 }
349 return EFSCORRUPTED;
350}
351
352/*
297 * This is called by the efd item code below to release references to 353 * This is called by the efd item code below to release references to
298 * the given efi item. Each efd calls this with the number of 354 * the given efi item. Each efd calls this with the number of
299 * extents that it has logged, and when the sum of these reaches 355 * extents that it has logged, and when the sum of these reaches