+
+/* Read in the block with the cleaner info from the ifile. */
+#define LFS_CLEANERINFO(CP, F, BP) { \
+ VTOI((F)->lfs_ivnode)->i_flag |= IACC; \
+ if (bread((F)->lfs_ivnode, (daddr_t)0, (F)->lfs_bsize, NOCRED, &(BP))) \
+ panic("lfs: ifile read"); \
+ (CP) = (CLEANERINFO *)(BP)->b_un.b_addr; \
+}
+
+/* Read in the block with a specific inode from the ifile. */
+#define LFS_IENTRY(IP, F, IN, BP) { \
+ VTOI((F)->lfs_ivnode)->i_flag |= IACC; \
+ if (bread((F)->lfs_ivnode, \
+ (IN) / (F)->lfs_ifpb + (F)->lfs_cleansz + (F)->lfs_segtabsz, \
+ (F)->lfs_bsize, NOCRED, &(BP))) \
+ panic("lfs: ifile read"); \
+ (IP) = (IFILE *)(BP)->b_un.b_addr + (IN) % (F)->lfs_ifpb; \
+}
+
+/* Read in the block with a specific segment usage entry from the ifile. */
+#define LFS_SEGENTRY(SP, F, IN, BP) { \
+ VTOI((F)->lfs_ivnode)->i_flag |= IACC; \
+ if (bread((F)->lfs_ivnode, (IN) / (F)->lfs_sepb + (F)->lfs_cleansz, \
+ (F)->lfs_bsize, NOCRED, &(BP))) \
+ panic("lfs: ifile read"); \
+ (SP) = (SEGUSE *)(BP)->b_un.b_addr + (IN) % (F)->lfs_sepb; \
+}
+
+/* Write a block and update the inode change times. */
+#define LFS_UBWRITE(BP) { \
+ VTOI((BP)->b_vp)->i_flag |= ICHG | IUPD; \
+ lfs_bwrite(BP); \
+}
+
+/*
+ * Structures used by lfs_bmapv and lfs_markv to communicate information
+ * about inodes and data blocks.
+ */
+typedef struct block_info {
+ ino_t bi_inode; /* inode # */
+ off_t bi_lbn; /* logical block w/in file */
+ daddr_t bi_daddr; /* disk address of block */
+ time_t bi_segcreate; /* origin segment create time */
+ void *bi_bp; /* data buffer */
+} BLOCK_INFO;
+
+typedef struct inode_info {
+ ino_t ii_inode; /* inode # */
+ daddr_t ii_daddr; /* disk address of block */
+ time_t ii_segcreate; /* origin segment create time */
+ struct dinode *ii_dinode; /* data buffer */
+} INODE_INFO;