diff options
Diffstat (limited to 'fs/xfs/xfs_extfree_item.c')
-rw-r--r-- | fs/xfs/xfs_extfree_item.c | 56 |
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 | */ | ||
303 | int | ||
304 | xfs_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 |