aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2016-02-09 00:54:58 -0500
committerDave Chinner <david@fromorbit.com>2016-02-09 00:54:58 -0500
commitf8d55aa0523ad0f78979c222ed18b78ea7be793a (patch)
tree61550e48a25099ead7d25eb08175cfb7962a9db5
parent36f90b0a2ddd60823fe193a85e60ff1906c2a9b3 (diff)
xfs: introduce inode log format object
We currently carry around and log an entire inode core in the struct xfs_inode. A lot of the information in the inode core is duplicated in the VFS inode, but we cannot remove this duplication of infomration because the inode core is logged directly in xfs_inode_item_format(). Add a new function xfs_inode_item_format_core() that copies the inode core data into a struct xfs_icdinode that is pulled directly from the log vector buffer. This means we no longer directly copy the inode core, but copy the structures one member at a time. This will be slightly less efficient than copying, but will allow us to remove duplicate and unnecessary items from the struct xfs_inode. To enable us to do this, call the new structure a xfs_log_dinode, so that we know it's different to the physical xfs_dinode and the in-core xfs_icdinode. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Dave Chinner <david@fromorbit.com>
-rw-r--r--fs/xfs/libxfs/xfs_inode_buf.c8
-rw-r--r--fs/xfs/libxfs/xfs_inode_buf.h53
-rw-r--r--fs/xfs/libxfs/xfs_log_format.h15
-rw-r--r--fs/xfs/xfs_icache.c2
-rw-r--r--fs/xfs/xfs_inode.h2
-rw-r--r--fs/xfs/xfs_inode_item.c128
-rw-r--r--fs/xfs/xfs_inode_item.h2
-rw-r--r--fs/xfs/xfs_log_recover.c52
8 files changed, 218 insertions, 44 deletions
diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
index 1aabfda669b0..63d46bf65540 100644
--- a/fs/xfs/libxfs/xfs_inode_buf.c
+++ b/fs/xfs/libxfs/xfs_inode_buf.c
@@ -196,8 +196,8 @@ xfs_imap_to_bp(
196 196
197void 197void
198xfs_dinode_from_disk( 198xfs_dinode_from_disk(
199 xfs_icdinode_t *to, 199 struct xfs_icdinode *to,
200 xfs_dinode_t *from) 200 struct xfs_dinode *from)
201{ 201{
202 to->di_magic = be16_to_cpu(from->di_magic); 202 to->di_magic = be16_to_cpu(from->di_magic);
203 to->di_mode = be16_to_cpu(from->di_mode); 203 to->di_mode = be16_to_cpu(from->di_mode);
@@ -243,8 +243,8 @@ xfs_dinode_from_disk(
243 243
244void 244void
245xfs_dinode_to_disk( 245xfs_dinode_to_disk(
246 xfs_dinode_t *to, 246 struct xfs_dinode *to,
247 xfs_icdinode_t *from) 247 struct xfs_icdinode *from)
248{ 248{
249 to->di_magic = cpu_to_be16(from->di_magic); 249 to->di_magic = cpu_to_be16(from->di_magic);
250 to->di_mode = cpu_to_be16(from->di_mode); 250 to->di_mode = cpu_to_be16(from->di_mode);
diff --git a/fs/xfs/libxfs/xfs_inode_buf.h b/fs/xfs/libxfs/xfs_inode_buf.h
index 9308c47f2a52..642f2a297c26 100644
--- a/fs/xfs/libxfs/xfs_inode_buf.h
+++ b/fs/xfs/libxfs/xfs_inode_buf.h
@@ -20,7 +20,58 @@
20 20
21struct xfs_inode; 21struct xfs_inode;
22struct xfs_dinode; 22struct xfs_dinode;
23struct xfs_icdinode; 23
24/*
25 * In memory representation of the XFS inode. This is held in the in-core
26 * struct xfs_inode to represent the on disk values, but no longer needs to be
27 * identical to the on-disk structure as it is always translated to on-disk
28 * format specific structures at the appropriate time.
29 */
30struct xfs_icdinode {
31 __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */
32 __uint16_t di_mode; /* mode and type of file */
33 __int8_t di_version; /* inode version */
34 __int8_t di_format; /* format of di_c data */
35 __uint16_t di_onlink; /* old number of links to file */
36 __uint32_t di_uid; /* owner's user id */
37 __uint32_t di_gid; /* owner's group id */
38 __uint32_t di_nlink; /* number of links to file */
39 __uint16_t di_projid_lo; /* lower part of owner's project id */
40 __uint16_t di_projid_hi; /* higher part of owner's project id */
41 __uint8_t di_pad[6]; /* unused, zeroed space */
42 __uint16_t di_flushiter; /* incremented on flush */
43 xfs_ictimestamp_t di_atime; /* time last accessed */
44 xfs_ictimestamp_t di_mtime; /* time last modified */
45 xfs_ictimestamp_t di_ctime; /* time created/inode modified */
46 xfs_fsize_t di_size; /* number of bytes in file */
47 xfs_rfsblock_t di_nblocks; /* # of direct & btree blocks used */
48 xfs_extlen_t di_extsize; /* basic/minimum extent size for file */
49 xfs_extnum_t di_nextents; /* number of extents in data fork */
50 xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/
51 __uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */
52 __int8_t di_aformat; /* format of attr fork's data */
53 __uint32_t di_dmevmask; /* DMIG event mask */
54 __uint16_t di_dmstate; /* DMIG state info */
55 __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */
56 __uint32_t di_gen; /* generation number */
57
58 /* di_next_unlinked is the only non-core field in the old dinode */
59 xfs_agino_t di_next_unlinked;/* agi unlinked list ptr */
60
61 /* start of the extended dinode, writable fields */
62 __uint32_t di_crc; /* CRC of the inode */
63 __uint64_t di_changecount; /* number of attribute changes */
64 xfs_lsn_t di_lsn; /* flush sequence */
65 __uint64_t di_flags2; /* more random flags */
66 __uint8_t di_pad2[16]; /* more padding for future expansion */
67
68 /* fields only written to during inode creation */
69 xfs_ictimestamp_t di_crtime; /* time created */
70 xfs_ino_t di_ino; /* inode number */
71 uuid_t di_uuid; /* UUID of the filesystem */
72
73 /* structure must be padded to 64 bit alignment */
74};
24 75
25/* 76/*
26 * Inode location information. Stored in the inode and passed to 77 * Inode location information. Stored in the inode and passed to
diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h
index 265314690415..d00ed639e0bc 100644
--- a/fs/xfs/libxfs/xfs_log_format.h
+++ b/fs/xfs/libxfs/xfs_log_format.h
@@ -290,6 +290,7 @@ typedef struct xfs_inode_log_format_64 {
290 __int32_t ilf_boffset; /* off of inode in buffer */ 290 __int32_t ilf_boffset; /* off of inode in buffer */
291} xfs_inode_log_format_64_t; 291} xfs_inode_log_format_64_t;
292 292
293
293/* 294/*
294 * Flags for xfs_trans_log_inode flags field. 295 * Flags for xfs_trans_log_inode flags field.
295 */ 296 */
@@ -360,10 +361,10 @@ typedef struct xfs_ictimestamp {
360} xfs_ictimestamp_t; 361} xfs_ictimestamp_t;
361 362
362/* 363/*
363 * NOTE: This structure must be kept identical to struct xfs_dinode 364 * Define the format of the inode core that is logged. This structure must be
364 * except for the endianness annotations. 365 * kept identical to struct xfs_dinode except for the endianness annotations.
365 */ 366 */
366typedef struct xfs_icdinode { 367struct xfs_log_dinode {
367 __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */ 368 __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */
368 __uint16_t di_mode; /* mode and type of file */ 369 __uint16_t di_mode; /* mode and type of file */
369 __int8_t di_version; /* inode version */ 370 __int8_t di_version; /* inode version */
@@ -407,13 +408,13 @@ typedef struct xfs_icdinode {
407 uuid_t di_uuid; /* UUID of the filesystem */ 408 uuid_t di_uuid; /* UUID of the filesystem */
408 409
409 /* structure must be padded to 64 bit alignment */ 410 /* structure must be padded to 64 bit alignment */
410} xfs_icdinode_t; 411};
411 412
412static inline uint xfs_icdinode_size(int version) 413static inline uint xfs_log_dinode_size(int version)
413{ 414{
414 if (version == 3) 415 if (version == 3)
415 return sizeof(struct xfs_icdinode); 416 return sizeof(struct xfs_log_dinode);
416 return offsetof(struct xfs_icdinode, di_next_unlinked); 417 return offsetof(struct xfs_log_dinode, di_next_unlinked);
417} 418}
418 419
419/* 420/*
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index d7a490f24ead..7c26f8611891 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -79,7 +79,7 @@ xfs_inode_alloc(
79 memset(&ip->i_df, 0, sizeof(xfs_ifork_t)); 79 memset(&ip->i_df, 0, sizeof(xfs_ifork_t));
80 ip->i_flags = 0; 80 ip->i_flags = 0;
81 ip->i_delayed_blks = 0; 81 ip->i_delayed_blks = 0;
82 memset(&ip->i_d, 0, sizeof(xfs_icdinode_t)); 82 memset(&ip->i_d, 0, sizeof(ip->i_d));
83 83
84 return ip; 84 return ip;
85} 85}
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index ca9e11989cbd..aef5452b1a90 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -63,7 +63,7 @@ typedef struct xfs_inode {
63 unsigned long i_flags; /* see defined flags below */ 63 unsigned long i_flags; /* see defined flags below */
64 unsigned int i_delayed_blks; /* count of delay alloc blks */ 64 unsigned int i_delayed_blks; /* count of delay alloc blks */
65 65
66 xfs_icdinode_t i_d; /* most of ondisk inode */ 66 struct xfs_icdinode i_d; /* most of ondisk inode */
67 67
68 /* VFS inode */ 68 /* VFS inode */
69 struct inode i_vnode; /* embedded VFS inode */ 69 struct inode i_vnode; /* embedded VFS inode */
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index d14b12b8cfef..3ad997278869 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -135,7 +135,7 @@ xfs_inode_item_size(
135 135
136 *nvecs += 2; 136 *nvecs += 2;
137 *nbytes += sizeof(struct xfs_inode_log_format) + 137 *nbytes += sizeof(struct xfs_inode_log_format) +
138 xfs_icdinode_size(ip->i_d.di_version); 138 xfs_log_dinode_size(ip->i_d.di_version);
139 139
140 xfs_inode_item_data_fork_size(iip, nvecs, nbytes); 140 xfs_inode_item_data_fork_size(iip, nvecs, nbytes);
141 if (XFS_IFORK_Q(ip)) 141 if (XFS_IFORK_Q(ip))
@@ -322,6 +322,127 @@ xfs_inode_item_format_attr_fork(
322 } 322 }
323} 323}
324 324
325static void
326xfs_icdinode_to_log_dinode(
327 struct xfs_icdinode *from,
328 struct xfs_log_dinode *to)
329{
330 to->di_magic = from->di_magic;
331 to->di_mode = from->di_mode;
332 to->di_version = from->di_version;
333 to->di_format = from->di_format;
334 to->di_onlink = from->di_onlink;
335 to->di_uid = from->di_uid;
336 to->di_gid = from->di_gid;
337 to->di_nlink = from->di_nlink;
338 to->di_projid_lo = from->di_projid_lo;
339 to->di_projid_hi = from->di_projid_hi;
340 memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
341 to->di_atime.t_sec = from->di_atime.t_sec;
342 to->di_atime.t_nsec = from->di_atime.t_nsec;
343 to->di_mtime.t_sec = from->di_mtime.t_sec;
344 to->di_mtime.t_nsec = from->di_mtime.t_nsec;
345 to->di_ctime.t_sec = from->di_ctime.t_sec;
346 to->di_ctime.t_nsec = from->di_ctime.t_nsec;
347 to->di_size = from->di_size;
348 to->di_nblocks = from->di_nblocks;
349 to->di_extsize = from->di_extsize;
350 to->di_nextents = from->di_nextents;
351 to->di_anextents = from->di_anextents;
352 to->di_forkoff = from->di_forkoff;
353 to->di_aformat = from->di_aformat;
354 to->di_dmevmask = from->di_dmevmask;
355 to->di_dmstate = from->di_dmstate;
356 to->di_flags = from->di_flags;
357 to->di_gen = from->di_gen;
358
359 if (from->di_version == 3) {
360 to->di_changecount = from->di_changecount;
361 to->di_crtime.t_sec = from->di_crtime.t_sec;
362 to->di_crtime.t_nsec = from->di_crtime.t_nsec;
363 to->di_flags2 = from->di_flags2;
364 to->di_ino = from->di_ino;
365 to->di_lsn = from->di_lsn;
366 memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2));
367 uuid_copy(&to->di_uuid, &from->di_uuid);
368 to->di_flushiter = 0;
369 } else {
370 to->di_flushiter = from->di_flushiter;
371 }
372}
373
374/*
375 * Recovery needs to be able to convert a log dinode back to a real dinode
376 * for writeback we do that by converting a log dinode to a icdinode, and
377 * then passing that to the formatting function.
378 */
379void
380xfs_log_dinode_to_icdinode(
381 struct xfs_log_dinode *from,
382 struct xfs_icdinode *to)
383{
384 to->di_magic = from->di_magic;
385 to->di_mode = from->di_mode;
386 to->di_version = from->di_version;
387 to->di_format = from->di_format;
388 to->di_onlink = from->di_onlink;
389 to->di_uid = from->di_uid;
390 to->di_gid = from->di_gid;
391 to->di_nlink = from->di_nlink;
392 to->di_projid_lo = from->di_projid_lo;
393 to->di_projid_hi = from->di_projid_hi;
394 memset(to->di_pad, 0, sizeof(to->di_pad));
395 to->di_atime.t_sec = from->di_atime.t_sec;
396 to->di_atime.t_nsec = from->di_atime.t_nsec;
397 to->di_mtime.t_sec = from->di_mtime.t_sec;
398 to->di_mtime.t_nsec = from->di_mtime.t_nsec;
399 to->di_ctime.t_sec = from->di_ctime.t_sec;
400 to->di_ctime.t_nsec = from->di_ctime.t_nsec;
401 to->di_size = from->di_size;
402 to->di_nblocks = from->di_nblocks;
403 to->di_extsize = from->di_extsize;
404 to->di_nextents = from->di_nextents;
405 to->di_anextents = from->di_anextents;
406 to->di_forkoff = from->di_forkoff;
407 to->di_aformat = from->di_aformat;
408 to->di_dmevmask = from->di_dmevmask;
409 to->di_dmstate = from->di_dmstate;
410 to->di_flags = from->di_flags;
411 to->di_gen = from->di_gen;
412
413 if (from->di_version == 3) {
414 to->di_changecount = from->di_changecount;
415 to->di_crtime.t_sec = from->di_crtime.t_sec;
416 to->di_crtime.t_nsec = from->di_crtime.t_nsec;
417 to->di_flags2 = from->di_flags2;
418 to->di_ino = from->di_ino;
419 to->di_lsn = from->di_lsn;
420 memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2));
421 uuid_copy(&to->di_uuid, &from->di_uuid);
422 to->di_flushiter = 0;
423 } else {
424 to->di_flushiter = from->di_flushiter;
425 }
426}
427
428/*
429 * Format the inode core. Current timestamp data is only in the VFS inode
430 * fields, so we need to grab them from there. Hence rather than just copying
431 * the XFS inode core structure, format the fields directly into the iovec.
432 */
433static void
434xfs_inode_item_format_core(
435 struct xfs_inode *ip,
436 struct xfs_log_vec *lv,
437 struct xfs_log_iovec **vecp)
438{
439 struct xfs_log_dinode *dic;
440
441 dic = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_ICORE);
442 xfs_icdinode_to_log_dinode(&ip->i_d, dic);
443 xlog_finish_iovec(lv, *vecp, xfs_log_dinode_size(ip->i_d.di_version));
444}
445
325/* 446/*
326 * This is called to fill in the vector of log iovecs for the given inode 447 * This is called to fill in the vector of log iovecs for the given inode
327 * log item. It fills the first item with an inode log format structure, 448 * log item. It fills the first item with an inode log format structure,
@@ -351,10 +472,7 @@ xfs_inode_item_format(
351 ilf->ilf_size = 2; /* format + core */ 472 ilf->ilf_size = 2; /* format + core */
352 xlog_finish_iovec(lv, vecp, sizeof(struct xfs_inode_log_format)); 473 xlog_finish_iovec(lv, vecp, sizeof(struct xfs_inode_log_format));
353 474
354 xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ICORE, 475 xfs_inode_item_format_core(ip, lv, &vecp);
355 &ip->i_d,
356 xfs_icdinode_size(ip->i_d.di_version));
357
358 xfs_inode_item_format_data_fork(iip, ilf, lv, &vecp); 476 xfs_inode_item_format_data_fork(iip, ilf, lv, &vecp);
359 if (XFS_IFORK_Q(ip)) { 477 if (XFS_IFORK_Q(ip)) {
360 xfs_inode_item_format_attr_fork(iip, ilf, lv, &vecp); 478 xfs_inode_item_format_attr_fork(iip, ilf, lv, &vecp);
diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h
index 4c7722e325b3..24261180ba66 100644
--- a/fs/xfs/xfs_inode_item.h
+++ b/fs/xfs/xfs_inode_item.h
@@ -49,6 +49,8 @@ extern void xfs_istale_done(struct xfs_buf *, struct xfs_log_item *);
49extern void xfs_iflush_abort(struct xfs_inode *, bool); 49extern void xfs_iflush_abort(struct xfs_inode *, bool);
50extern int xfs_inode_item_format_convert(xfs_log_iovec_t *, 50extern int xfs_inode_item_format_convert(xfs_log_iovec_t *,
51 xfs_inode_log_format_t *); 51 xfs_inode_log_format_t *);
52extern void xfs_log_dinode_to_icdinode(struct xfs_log_dinode *from,
53 struct xfs_icdinode *to);
52 54
53extern struct kmem_zone *xfs_ili_zone; 55extern struct kmem_zone *xfs_ili_zone;
54 56
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index da37beb76f6e..3120f7bbb180 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -2839,7 +2839,8 @@ xlog_recover_inode_pass2(
2839 int error; 2839 int error;
2840 int attr_index; 2840 int attr_index;
2841 uint fields; 2841 uint fields;
2842 xfs_icdinode_t *dicp; 2842 struct xfs_log_dinode *ldip;
2843 struct xfs_icdinode icic;
2843 uint isize; 2844 uint isize;
2844 int need_free = 0; 2845 int need_free = 0;
2845 2846
@@ -2892,8 +2893,8 @@ xlog_recover_inode_pass2(
2892 error = -EFSCORRUPTED; 2893 error = -EFSCORRUPTED;
2893 goto out_release; 2894 goto out_release;
2894 } 2895 }
2895 dicp = item->ri_buf[1].i_addr; 2896 ldip = item->ri_buf[1].i_addr;
2896 if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) { 2897 if (unlikely(ldip->di_magic != XFS_DINODE_MAGIC)) {
2897 xfs_alert(mp, 2898 xfs_alert(mp,
2898 "%s: Bad inode log record, rec ptr 0x%p, ino %Ld", 2899 "%s: Bad inode log record, rec ptr 0x%p, ino %Ld",
2899 __func__, item, in_f->ilf_ino); 2900 __func__, item, in_f->ilf_ino);
@@ -2929,13 +2930,13 @@ xlog_recover_inode_pass2(
2929 * to skip replay when the on disk inode is newer than the log one 2930 * to skip replay when the on disk inode is newer than the log one
2930 */ 2931 */
2931 if (!xfs_sb_version_hascrc(&mp->m_sb) && 2932 if (!xfs_sb_version_hascrc(&mp->m_sb) &&
2932 dicp->di_flushiter < be16_to_cpu(dip->di_flushiter)) { 2933 ldip->di_flushiter < be16_to_cpu(dip->di_flushiter)) {
2933 /* 2934 /*
2934 * Deal with the wrap case, DI_MAX_FLUSH is less 2935 * Deal with the wrap case, DI_MAX_FLUSH is less
2935 * than smaller numbers 2936 * than smaller numbers
2936 */ 2937 */
2937 if (be16_to_cpu(dip->di_flushiter) == DI_MAX_FLUSH && 2938 if (be16_to_cpu(dip->di_flushiter) == DI_MAX_FLUSH &&
2938 dicp->di_flushiter < (DI_MAX_FLUSH >> 1)) { 2939 ldip->di_flushiter < (DI_MAX_FLUSH >> 1)) {
2939 /* do nothing */ 2940 /* do nothing */
2940 } else { 2941 } else {
2941 trace_xfs_log_recover_inode_skip(log, in_f); 2942 trace_xfs_log_recover_inode_skip(log, in_f);
@@ -2945,13 +2946,13 @@ xlog_recover_inode_pass2(
2945 } 2946 }
2946 2947
2947 /* Take the opportunity to reset the flush iteration count */ 2948 /* Take the opportunity to reset the flush iteration count */
2948 dicp->di_flushiter = 0; 2949 ldip->di_flushiter = 0;
2949 2950
2950 if (unlikely(S_ISREG(dicp->di_mode))) { 2951 if (unlikely(S_ISREG(ldip->di_mode))) {
2951 if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) && 2952 if ((ldip->di_format != XFS_DINODE_FMT_EXTENTS) &&
2952 (dicp->di_format != XFS_DINODE_FMT_BTREE)) { 2953 (ldip->di_format != XFS_DINODE_FMT_BTREE)) {
2953 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(3)", 2954 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(3)",
2954 XFS_ERRLEVEL_LOW, mp, dicp); 2955 XFS_ERRLEVEL_LOW, mp, ldip);
2955 xfs_alert(mp, 2956 xfs_alert(mp,
2956 "%s: Bad regular inode log record, rec ptr 0x%p, " 2957 "%s: Bad regular inode log record, rec ptr 0x%p, "
2957 "ino ptr = 0x%p, ino bp = 0x%p, ino %Ld", 2958 "ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
@@ -2959,12 +2960,12 @@ xlog_recover_inode_pass2(
2959 error = -EFSCORRUPTED; 2960 error = -EFSCORRUPTED;
2960 goto out_release; 2961 goto out_release;
2961 } 2962 }
2962 } else if (unlikely(S_ISDIR(dicp->di_mode))) { 2963 } else if (unlikely(S_ISDIR(ldip->di_mode))) {
2963 if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) && 2964 if ((ldip->di_format != XFS_DINODE_FMT_EXTENTS) &&
2964 (dicp->di_format != XFS_DINODE_FMT_BTREE) && 2965 (ldip->di_format != XFS_DINODE_FMT_BTREE) &&
2965 (dicp->di_format != XFS_DINODE_FMT_LOCAL)) { 2966 (ldip->di_format != XFS_DINODE_FMT_LOCAL)) {
2966 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(4)", 2967 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(4)",
2967 XFS_ERRLEVEL_LOW, mp, dicp); 2968 XFS_ERRLEVEL_LOW, mp, ldip);
2968 xfs_alert(mp, 2969 xfs_alert(mp,
2969 "%s: Bad dir inode log record, rec ptr 0x%p, " 2970 "%s: Bad dir inode log record, rec ptr 0x%p, "
2970 "ino ptr = 0x%p, ino bp = 0x%p, ino %Ld", 2971 "ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
@@ -2973,32 +2974,32 @@ xlog_recover_inode_pass2(
2973 goto out_release; 2974 goto out_release;
2974 } 2975 }
2975 } 2976 }
2976 if (unlikely(dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks)){ 2977 if (unlikely(ldip->di_nextents + ldip->di_anextents > ldip->di_nblocks)){
2977 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(5)", 2978 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(5)",
2978 XFS_ERRLEVEL_LOW, mp, dicp); 2979 XFS_ERRLEVEL_LOW, mp, ldip);
2979 xfs_alert(mp, 2980 xfs_alert(mp,
2980 "%s: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, " 2981 "%s: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, "
2981 "dino bp 0x%p, ino %Ld, total extents = %d, nblocks = %Ld", 2982 "dino bp 0x%p, ino %Ld, total extents = %d, nblocks = %Ld",
2982 __func__, item, dip, bp, in_f->ilf_ino, 2983 __func__, item, dip, bp, in_f->ilf_ino,
2983 dicp->di_nextents + dicp->di_anextents, 2984 ldip->di_nextents + ldip->di_anextents,
2984 dicp->di_nblocks); 2985 ldip->di_nblocks);
2985 error = -EFSCORRUPTED; 2986 error = -EFSCORRUPTED;
2986 goto out_release; 2987 goto out_release;
2987 } 2988 }
2988 if (unlikely(dicp->di_forkoff > mp->m_sb.sb_inodesize)) { 2989 if (unlikely(ldip->di_forkoff > mp->m_sb.sb_inodesize)) {
2989 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(6)", 2990 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(6)",
2990 XFS_ERRLEVEL_LOW, mp, dicp); 2991 XFS_ERRLEVEL_LOW, mp, ldip);
2991 xfs_alert(mp, 2992 xfs_alert(mp,
2992 "%s: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, " 2993 "%s: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, "
2993 "dino bp 0x%p, ino %Ld, forkoff 0x%x", __func__, 2994 "dino bp 0x%p, ino %Ld, forkoff 0x%x", __func__,
2994 item, dip, bp, in_f->ilf_ino, dicp->di_forkoff); 2995 item, dip, bp, in_f->ilf_ino, ldip->di_forkoff);
2995 error = -EFSCORRUPTED; 2996 error = -EFSCORRUPTED;
2996 goto out_release; 2997 goto out_release;
2997 } 2998 }
2998 isize = xfs_icdinode_size(dicp->di_version); 2999 isize = xfs_log_dinode_size(ldip->di_version);
2999 if (unlikely(item->ri_buf[1].i_len > isize)) { 3000 if (unlikely(item->ri_buf[1].i_len > isize)) {
3000 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)", 3001 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)",
3001 XFS_ERRLEVEL_LOW, mp, dicp); 3002 XFS_ERRLEVEL_LOW, mp, ldip);
3002 xfs_alert(mp, 3003 xfs_alert(mp,
3003 "%s: Bad inode log record length %d, rec ptr 0x%p", 3004 "%s: Bad inode log record length %d, rec ptr 0x%p",
3004 __func__, item->ri_buf[1].i_len, item); 3005 __func__, item->ri_buf[1].i_len, item);
@@ -3007,7 +3008,8 @@ xlog_recover_inode_pass2(
3007 } 3008 }
3008 3009
3009 /* The core is in in-core format */ 3010 /* The core is in in-core format */
3010 xfs_dinode_to_disk(dip, dicp); 3011 xfs_log_dinode_to_icdinode(ldip, &icic);
3012 xfs_dinode_to_disk(dip, &icic);
3011 3013
3012 /* the rest is in on-disk format */ 3014 /* the rest is in on-disk format */
3013 if (item->ri_buf[1].i_len > isize) { 3015 if (item->ri_buf[1].i_len > isize) {