/* * Format the inode core. Current timestamp data is only in the VFS inode * fields, so we need to grab them from there. Hence rather than just copying * the XFS inode core structure, format the fields directly into the iovec. */ static void xfs_inode_item_format_core( struct xfs_inode *ip, struct xfs_log_vec *lv, struct xfs_log_iovec **vecp) { struct xfs_log_dinode *dic; dic = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_ICORE); xfs_inode_to_log_dinode(ip, dic, ip->i_itemp->ili_item.li_lsn); xlog_finish_iovec(lv, *vecp, xfs_log_dinode_size(ip->i_d.di_version)); }
/* * This returns the number of iovecs needed to log the given inode item. * * We need one iovec for the inode log format structure, one for the * inode core, and possibly one for the inode data/extents/b-tree root * and one for the inode attribute data/extents/b-tree root. */ STATIC void xfs_inode_item_size( struct xfs_log_item *lip, int *nvecs, int *nbytes) { struct xfs_inode_log_item *iip = INODE_ITEM(lip); struct xfs_inode *ip = iip->ili_inode; *nvecs += 2; *nbytes += sizeof(struct xfs_inode_log_format) + xfs_log_dinode_size(ip->i_d.di_version); xfs_inode_item_data_fork_size(iip, nvecs, nbytes); if (XFS_IFORK_Q(ip)) xfs_inode_item_attr_fork_size(iip, nvecs, nbytes); }
int xlog_print_trans_inode( struct xlog *log, char **ptr, int len, int *i, int num_ops, int continued) { struct xfs_log_dinode dino; xlog_op_header_t *op_head; xfs_inode_log_format_t dst_lbuf; xfs_inode_log_format_64_t src_lbuf; /* buffer of biggest one */ xfs_inode_log_format_t *f; int mode; int size; /* * print inode type header region * * memmove to ensure 8-byte alignment for the long longs in * xfs_inode_log_format_t structure * * len can be smaller than xfs_inode_log_format_32|64_t * if format data is split over operations */ memmove(&src_lbuf, *ptr, MIN(sizeof(xfs_inode_log_format_64_t), len)); (*i)++; /* bump index */ *ptr += len; if (!continued && (len == sizeof(xfs_inode_log_format_32_t) || len == sizeof(xfs_inode_log_format_64_t))) { f = xfs_inode_item_format_convert((char*)&src_lbuf, len, &dst_lbuf); printf(_("INODE: ")); printf(_("#regs: %d ino: 0x%llx flags: 0x%x dsize: %d\n"), f->ilf_size, (unsigned long long)f->ilf_ino, f->ilf_fields, f->ilf_dsize); printf(_(" blkno: %lld len: %d boff: %d\n"), (long long)f->ilf_blkno, f->ilf_len, f->ilf_boffset); } else { ASSERT(len >= 4); /* must have at least 4 bytes if != 0 */ f = (xfs_inode_log_format_t *)&src_lbuf; printf(_("INODE: #regs: %d Not printing rest of data\n"), f->ilf_size); return f->ilf_size; } if (*i >= num_ops) /* end of LR */ return f->ilf_size-1; /* core inode comes 2nd */ op_head = (xlog_op_header_t *)*ptr; xlog_print_op_header(op_head, *i, ptr); if (op_head->oh_flags & XLOG_CONTINUE_TRANS) { return f->ilf_size-1; } memmove(&dino, *ptr, sizeof(dino)); mode = dino.di_mode & S_IFMT; size = (int)dino.di_size; xlog_print_trans_inode_core(&dino); *ptr += xfs_log_dinode_size(dino.di_version); if (*i == num_ops-1 && f->ilf_size == 3) { return 1; } /* does anything come next */ op_head = (xlog_op_header_t *)*ptr; switch (f->ilf_fields & (XFS_ILOG_DEV | XFS_ILOG_UUID)) { case XFS_ILOG_DEV: printf(_("DEV inode: no extra region\n")); break; case XFS_ILOG_UUID: printf(_("UUID inode: no extra region\n")); break; } /* Only the inode core is logged */ if (f->ilf_size == 2) return 0; ASSERT(f->ilf_size <= 4); ASSERT((f->ilf_size == 3) || (f->ilf_fields & XFS_ILOG_AFORK)); if (f->ilf_fields & XFS_ILOG_DFORK) { (*i)++; xlog_print_op_header(op_head, *i, ptr); switch (f->ilf_fields & XFS_ILOG_DFORK) { case XFS_ILOG_DEXT: printf(_("EXTENTS inode data\n")); break; case XFS_ILOG_DBROOT: printf(_("BTREE inode data\n")); break; case XFS_ILOG_DDATA: printf(_("LOCAL inode data\n")); if (mode == S_IFDIR) xlog_print_dir2_sf(log, (xfs_dir2_sf_hdr_t *)*ptr, size); break; default: ASSERT((f->ilf_fields & XFS_ILOG_DFORK) == 0); break; } *ptr += be32_to_cpu(op_head->oh_len); if (op_head->oh_flags & XLOG_CONTINUE_TRANS) return 1; op_head = (xlog_op_header_t *)*ptr; } if (f->ilf_fields & XFS_ILOG_AFORK) { (*i)++; xlog_print_op_header(op_head, *i, ptr); switch (f->ilf_fields & XFS_ILOG_AFORK) { case XFS_ILOG_AEXT: printf(_("EXTENTS attr data\n")); break; case XFS_ILOG_ABROOT: printf(_("BTREE attr data\n")); break; case XFS_ILOG_ADATA: printf(_("LOCAL attr data\n")); if (mode == S_IFDIR) xlog_print_dir2_sf(log, (xfs_dir2_sf_hdr_t *)*ptr, size); break; default: ASSERT((f->ilf_fields & XFS_ILOG_AFORK) == 0); break; } *ptr += be32_to_cpu(op_head->oh_len); if (op_head->oh_flags & XLOG_CONTINUE_TRANS) return 1; } return 0; } /* xlog_print_trans_inode */