Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
0004  * All Rights Reserved.
0005  */
0006 #ifndef __XFS_LOG_FORMAT_H__
0007 #define __XFS_LOG_FORMAT_H__
0008 
0009 struct xfs_mount;
0010 struct xfs_trans_res;
0011 
0012 /*
0013  * On-disk Log Format definitions.
0014  *
0015  * This file contains all the on-disk format definitions used within the log. It
0016  * includes the physical log structure itself, as well as all the log item
0017  * format structures that are written into the log and intepreted by log
0018  * recovery. We start with the physical log format definitions, and then work
0019  * through all the log items definitions and everything they encode into the
0020  * log.
0021  */
0022 typedef uint32_t xlog_tid_t;
0023 
0024 #define XLOG_MIN_ICLOGS     2
0025 #define XLOG_MAX_ICLOGS     8
0026 #define XLOG_HEADER_MAGIC_NUM   0xFEEDbabe  /* Invalid cycle number */
0027 #define XLOG_VERSION_1      1
0028 #define XLOG_VERSION_2      2       /* Large IClogs, Log sunit */
0029 #define XLOG_VERSION_OKBITS (XLOG_VERSION_1 | XLOG_VERSION_2)
0030 #define XLOG_MIN_RECORD_BSIZE   (16*1024)   /* eventually 32k */
0031 #define XLOG_BIG_RECORD_BSIZE   (32*1024)   /* 32k buffers */
0032 #define XLOG_MAX_RECORD_BSIZE   (256*1024)
0033 #define XLOG_HEADER_CYCLE_SIZE  (32*1024)   /* cycle data in header */
0034 #define XLOG_MIN_RECORD_BSHIFT  14      /* 16384 == 1 << 14 */
0035 #define XLOG_BIG_RECORD_BSHIFT  15      /* 32k == 1 << 15 */
0036 #define XLOG_MAX_RECORD_BSHIFT  18      /* 256k == 1 << 18 */
0037 
0038 #define XLOG_HEADER_SIZE    512
0039 
0040 /* Minimum number of transactions that must fit in the log (defined by mkfs) */
0041 #define XFS_MIN_LOG_FACTOR  3
0042 
0043 #define XLOG_REC_SHIFT(log) \
0044     BTOBB(1 << (xfs_has_logv2(log->l_mp) ? \
0045      XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT))
0046 #define XLOG_TOTAL_REC_SHIFT(log) \
0047     BTOBB(XLOG_MAX_ICLOGS << (xfs_has_logv2(log->l_mp) ? \
0048      XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT))
0049 
0050 /* get lsn fields */
0051 #define CYCLE_LSN(lsn) ((uint)((lsn)>>32))
0052 #define BLOCK_LSN(lsn) ((uint)(lsn))
0053 
0054 /* this is used in a spot where we might otherwise double-endian-flip */
0055 #define CYCLE_LSN_DISK(lsn) (((__be32 *)&(lsn))[0])
0056 
0057 static inline xfs_lsn_t xlog_assign_lsn(uint cycle, uint block)
0058 {
0059     return ((xfs_lsn_t)cycle << 32) | block;
0060 }
0061 
0062 static inline uint xlog_get_cycle(char *ptr)
0063 {
0064     if (be32_to_cpu(*(__be32 *)ptr) == XLOG_HEADER_MAGIC_NUM)
0065         return be32_to_cpu(*((__be32 *)ptr + 1));
0066     else
0067         return be32_to_cpu(*(__be32 *)ptr);
0068 }
0069 
0070 /* Log Clients */
0071 #define XFS_TRANSACTION     0x69
0072 #define XFS_LOG         0xaa
0073 
0074 #define XLOG_UNMOUNT_TYPE   0x556e  /* Un for Unmount */
0075 
0076 /*
0077  * Log item for unmount records.
0078  *
0079  * The unmount record used to have a string "Unmount filesystem--" in the
0080  * data section where the "Un" was really a magic number (XLOG_UNMOUNT_TYPE).
0081  * We just write the magic number now; see xfs_log_unmount_write.
0082  */
0083 struct xfs_unmount_log_format {
0084     uint16_t    magic;  /* XLOG_UNMOUNT_TYPE */
0085     uint16_t    pad1;
0086     uint32_t    pad2;   /* may as well make it 64 bits */
0087 };
0088 
0089 /* Region types for iovec's i_type */
0090 #define XLOG_REG_TYPE_BFORMAT       1
0091 #define XLOG_REG_TYPE_BCHUNK        2
0092 #define XLOG_REG_TYPE_EFI_FORMAT    3
0093 #define XLOG_REG_TYPE_EFD_FORMAT    4
0094 #define XLOG_REG_TYPE_IFORMAT       5
0095 #define XLOG_REG_TYPE_ICORE     6
0096 #define XLOG_REG_TYPE_IEXT      7
0097 #define XLOG_REG_TYPE_IBROOT        8
0098 #define XLOG_REG_TYPE_ILOCAL        9
0099 #define XLOG_REG_TYPE_IATTR_EXT     10
0100 #define XLOG_REG_TYPE_IATTR_BROOT   11
0101 #define XLOG_REG_TYPE_IATTR_LOCAL   12
0102 #define XLOG_REG_TYPE_QFORMAT       13
0103 #define XLOG_REG_TYPE_DQUOT     14
0104 #define XLOG_REG_TYPE_QUOTAOFF      15
0105 #define XLOG_REG_TYPE_LRHEADER      16
0106 #define XLOG_REG_TYPE_UNMOUNT       17
0107 #define XLOG_REG_TYPE_COMMIT        18
0108 #define XLOG_REG_TYPE_TRANSHDR      19
0109 #define XLOG_REG_TYPE_ICREATE       20
0110 #define XLOG_REG_TYPE_RUI_FORMAT    21
0111 #define XLOG_REG_TYPE_RUD_FORMAT    22
0112 #define XLOG_REG_TYPE_CUI_FORMAT    23
0113 #define XLOG_REG_TYPE_CUD_FORMAT    24
0114 #define XLOG_REG_TYPE_BUI_FORMAT    25
0115 #define XLOG_REG_TYPE_BUD_FORMAT    26
0116 #define XLOG_REG_TYPE_ATTRI_FORMAT  27
0117 #define XLOG_REG_TYPE_ATTRD_FORMAT  28
0118 #define XLOG_REG_TYPE_ATTR_NAME 29
0119 #define XLOG_REG_TYPE_ATTR_VALUE    30
0120 #define XLOG_REG_TYPE_MAX       30
0121 
0122 
0123 /*
0124  * Flags to log operation header
0125  *
0126  * The first write of a new transaction will be preceded with a start
0127  * record, XLOG_START_TRANS.  Once a transaction is committed, a commit
0128  * record is written, XLOG_COMMIT_TRANS.  If a single region can not fit into
0129  * the remainder of the current active in-core log, it is split up into
0130  * multiple regions.  Each partial region will be marked with a
0131  * XLOG_CONTINUE_TRANS until the last one, which gets marked with XLOG_END_TRANS.
0132  *
0133  */
0134 #define XLOG_START_TRANS    0x01    /* Start a new transaction */
0135 #define XLOG_COMMIT_TRANS   0x02    /* Commit this transaction */
0136 #define XLOG_CONTINUE_TRANS 0x04    /* Cont this trans into new region */
0137 #define XLOG_WAS_CONT_TRANS 0x08    /* Cont this trans into new region */
0138 #define XLOG_END_TRANS      0x10    /* End a continued transaction */
0139 #define XLOG_UNMOUNT_TRANS  0x20    /* Unmount a filesystem transaction */
0140 
0141 
0142 typedef struct xlog_op_header {
0143     __be32     oh_tid;  /* transaction id of operation  :  4 b */
0144     __be32     oh_len;  /* bytes in data region     :  4 b */
0145     __u8       oh_clientid; /* who sent me this     :  1 b */
0146     __u8       oh_flags;    /*              :  1 b */
0147     __u16      oh_res2; /* 32 bit align         :  2 b */
0148 } xlog_op_header_t;
0149 
0150 /* valid values for h_fmt */
0151 #define XLOG_FMT_UNKNOWN  0
0152 #define XLOG_FMT_LINUX_LE 1
0153 #define XLOG_FMT_LINUX_BE 2
0154 #define XLOG_FMT_IRIX_BE  3
0155 
0156 /* our fmt */
0157 #ifdef XFS_NATIVE_HOST
0158 #define XLOG_FMT XLOG_FMT_LINUX_BE
0159 #else
0160 #define XLOG_FMT XLOG_FMT_LINUX_LE
0161 #endif
0162 
0163 typedef struct xlog_rec_header {
0164     __be32    h_magicno;    /* log record (LR) identifier       :  4 */
0165     __be32    h_cycle;  /* write cycle of log           :  4 */
0166     __be32    h_version;    /* LR version               :  4 */
0167     __be32    h_len;    /* len in bytes; should be 64-bit aligned: 4 */
0168     __be64    h_lsn;    /* lsn of this LR           :  8 */
0169     __be64    h_tail_lsn;   /* lsn of 1st LR w/ buffers not committed: 8 */
0170     __le32    h_crc;    /* crc of log record                    :  4 */
0171     __be32    h_prev_block; /* block number to previous LR      :  4 */
0172     __be32    h_num_logops; /* number of log operations in this LR  :  4 */
0173     __be32    h_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE];
0174     /* new fields */
0175     __be32    h_fmt;        /* format of log record                 :  4 */
0176     uuid_t    h_fs_uuid;    /* uuid of FS                           : 16 */
0177     __be32    h_size;   /* iclog size               :  4 */
0178 } xlog_rec_header_t;
0179 
0180 typedef struct xlog_rec_ext_header {
0181     __be32    xh_cycle; /* write cycle of log           : 4 */
0182     __be32    xh_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; /*    : 256 */
0183 } xlog_rec_ext_header_t;
0184 
0185 /*
0186  * Quite misnamed, because this union lays out the actual on-disk log buffer.
0187  */
0188 typedef union xlog_in_core2 {
0189     xlog_rec_header_t   hic_header;
0190     xlog_rec_ext_header_t   hic_xheader;
0191     char            hic_sector[XLOG_HEADER_SIZE];
0192 } xlog_in_core_2_t;
0193 
0194 /* not an on-disk structure, but needed by log recovery in userspace */
0195 typedef struct xfs_log_iovec {
0196     void        *i_addr;    /* beginning address of region */
0197     int     i_len;      /* length in bytes of region */
0198     uint        i_type;     /* type of region */
0199 } xfs_log_iovec_t;
0200 
0201 
0202 /*
0203  * Transaction Header definitions.
0204  *
0205  * This is the structure written in the log at the head of every transaction. It
0206  * identifies the type and id of the transaction, and contains the number of
0207  * items logged by the transaction so we know how many to expect during
0208  * recovery.
0209  *
0210  * Do not change the below structure without redoing the code in
0211  * xlog_recover_add_to_trans() and xlog_recover_add_to_cont_trans().
0212  */
0213 typedef struct xfs_trans_header {
0214     uint        th_magic;       /* magic number */
0215     uint        th_type;        /* transaction type */
0216     int32_t     th_tid;         /* transaction id (unused) */
0217     uint        th_num_items;       /* num items logged by trans */
0218 } xfs_trans_header_t;
0219 
0220 #define XFS_TRANS_HEADER_MAGIC  0x5452414e  /* TRAN */
0221 
0222 /*
0223  * The only type valid for th_type in CIL-enabled file system logs:
0224  */
0225 #define XFS_TRANS_CHECKPOINT    40
0226 
0227 /*
0228  * Log item types.
0229  */
0230 #define XFS_LI_EFI      0x1236
0231 #define XFS_LI_EFD      0x1237
0232 #define XFS_LI_IUNLINK      0x1238
0233 #define XFS_LI_INODE        0x123b  /* aligned ino chunks, var-size ibufs */
0234 #define XFS_LI_BUF      0x123c  /* v2 bufs, variable sized inode bufs */
0235 #define XFS_LI_DQUOT        0x123d
0236 #define XFS_LI_QUOTAOFF     0x123e
0237 #define XFS_LI_ICREATE      0x123f
0238 #define XFS_LI_RUI      0x1240  /* rmap update intent */
0239 #define XFS_LI_RUD      0x1241
0240 #define XFS_LI_CUI      0x1242  /* refcount update intent */
0241 #define XFS_LI_CUD      0x1243
0242 #define XFS_LI_BUI      0x1244  /* bmbt update intent */
0243 #define XFS_LI_BUD      0x1245
0244 #define XFS_LI_ATTRI        0x1246  /* attr set/remove intent*/
0245 #define XFS_LI_ATTRD        0x1247  /* attr set/remove done */
0246 
0247 #define XFS_LI_TYPE_DESC \
0248     { XFS_LI_EFI,       "XFS_LI_EFI" }, \
0249     { XFS_LI_EFD,       "XFS_LI_EFD" }, \
0250     { XFS_LI_IUNLINK,   "XFS_LI_IUNLINK" }, \
0251     { XFS_LI_INODE,     "XFS_LI_INODE" }, \
0252     { XFS_LI_BUF,       "XFS_LI_BUF" }, \
0253     { XFS_LI_DQUOT,     "XFS_LI_DQUOT" }, \
0254     { XFS_LI_QUOTAOFF,  "XFS_LI_QUOTAOFF" }, \
0255     { XFS_LI_ICREATE,   "XFS_LI_ICREATE" }, \
0256     { XFS_LI_RUI,       "XFS_LI_RUI" }, \
0257     { XFS_LI_RUD,       "XFS_LI_RUD" }, \
0258     { XFS_LI_CUI,       "XFS_LI_CUI" }, \
0259     { XFS_LI_CUD,       "XFS_LI_CUD" }, \
0260     { XFS_LI_BUI,       "XFS_LI_BUI" }, \
0261     { XFS_LI_BUD,       "XFS_LI_BUD" }, \
0262     { XFS_LI_ATTRI,     "XFS_LI_ATTRI" }, \
0263     { XFS_LI_ATTRD,     "XFS_LI_ATTRD" }
0264 
0265 /*
0266  * Inode Log Item Format definitions.
0267  *
0268  * This is the structure used to lay out an inode log item in the
0269  * log.  The size of the inline data/extents/b-tree root to be logged
0270  * (if any) is indicated in the ilf_dsize field.  Changes to this structure
0271  * must be added on to the end.
0272  */
0273 struct xfs_inode_log_format {
0274     uint16_t        ilf_type;   /* inode log item type */
0275     uint16_t        ilf_size;   /* size of this item */
0276     uint32_t        ilf_fields; /* flags for fields logged */
0277     uint16_t        ilf_asize;  /* size of attr d/ext/root */
0278     uint16_t        ilf_dsize;  /* size of data/ext/root */
0279     uint32_t        ilf_pad;    /* pad for 64 bit boundary */
0280     uint64_t        ilf_ino;    /* inode number */
0281     union {
0282         uint32_t    ilfu_rdev;  /* rdev value for dev inode*/
0283         uint8_t     __pad[16];  /* unused */
0284     } ilf_u;
0285     int64_t         ilf_blkno;  /* blkno of inode buffer */
0286     int32_t         ilf_len;    /* len of inode buffer */
0287     int32_t         ilf_boffset;    /* off of inode in buffer */
0288 };
0289 
0290 /*
0291  * Old 32 bit systems will log in this format without the 64 bit
0292  * alignment padding. Recovery will detect this and convert it to the
0293  * correct format.
0294  */
0295 struct xfs_inode_log_format_32 {
0296     uint16_t        ilf_type;   /* inode log item type */
0297     uint16_t        ilf_size;   /* size of this item */
0298     uint32_t        ilf_fields; /* flags for fields logged */
0299     uint16_t        ilf_asize;  /* size of attr d/ext/root */
0300     uint16_t        ilf_dsize;  /* size of data/ext/root */
0301     uint64_t        ilf_ino;    /* inode number */
0302     union {
0303         uint32_t    ilfu_rdev;  /* rdev value for dev inode*/
0304         uint8_t     __pad[16];  /* unused */
0305     } ilf_u;
0306     int64_t         ilf_blkno;  /* blkno of inode buffer */
0307     int32_t         ilf_len;    /* len of inode buffer */
0308     int32_t         ilf_boffset;    /* off of inode in buffer */
0309 } __attribute__((packed));
0310 
0311 
0312 /*
0313  * Flags for xfs_trans_log_inode flags field.
0314  */
0315 #define XFS_ILOG_CORE   0x001   /* log standard inode fields */
0316 #define XFS_ILOG_DDATA  0x002   /* log i_df.if_data */
0317 #define XFS_ILOG_DEXT   0x004   /* log i_df.if_extents */
0318 #define XFS_ILOG_DBROOT 0x008   /* log i_df.i_broot */
0319 #define XFS_ILOG_DEV    0x010   /* log the dev field */
0320 #define XFS_ILOG_UUID   0x020   /* added long ago, but never used */
0321 #define XFS_ILOG_ADATA  0x040   /* log i_af.if_data */
0322 #define XFS_ILOG_AEXT   0x080   /* log i_af.if_extents */
0323 #define XFS_ILOG_ABROOT 0x100   /* log i_af.i_broot */
0324 #define XFS_ILOG_DOWNER 0x200   /* change the data fork owner on replay */
0325 #define XFS_ILOG_AOWNER 0x400   /* change the attr fork owner on replay */
0326 
0327 
0328 /*
0329  * The timestamps are dirty, but not necessarily anything else in the inode
0330  * core.  Unlike the other fields above this one must never make it to disk
0331  * in the ilf_fields of the inode_log_format, but is purely store in-memory in
0332  * ili_fields in the inode_log_item.
0333  */
0334 #define XFS_ILOG_TIMESTAMP  0x4000
0335 
0336 #define XFS_ILOG_NONCORE    (XFS_ILOG_DDATA | XFS_ILOG_DEXT | \
0337                  XFS_ILOG_DBROOT | XFS_ILOG_DEV | \
0338                  XFS_ILOG_ADATA | XFS_ILOG_AEXT | \
0339                  XFS_ILOG_ABROOT | XFS_ILOG_DOWNER | \
0340                  XFS_ILOG_AOWNER)
0341 
0342 #define XFS_ILOG_DFORK      (XFS_ILOG_DDATA | XFS_ILOG_DEXT | \
0343                  XFS_ILOG_DBROOT)
0344 
0345 #define XFS_ILOG_AFORK      (XFS_ILOG_ADATA | XFS_ILOG_AEXT | \
0346                  XFS_ILOG_ABROOT)
0347 
0348 #define XFS_ILOG_ALL        (XFS_ILOG_CORE | XFS_ILOG_DDATA | \
0349                  XFS_ILOG_DEXT | XFS_ILOG_DBROOT | \
0350                  XFS_ILOG_DEV | XFS_ILOG_ADATA | \
0351                  XFS_ILOG_AEXT | XFS_ILOG_ABROOT | \
0352                  XFS_ILOG_TIMESTAMP | XFS_ILOG_DOWNER | \
0353                  XFS_ILOG_AOWNER)
0354 
0355 static inline int xfs_ilog_fbroot(int w)
0356 {
0357     return (w == XFS_DATA_FORK ? XFS_ILOG_DBROOT : XFS_ILOG_ABROOT);
0358 }
0359 
0360 static inline int xfs_ilog_fext(int w)
0361 {
0362     return (w == XFS_DATA_FORK ? XFS_ILOG_DEXT : XFS_ILOG_AEXT);
0363 }
0364 
0365 static inline int xfs_ilog_fdata(int w)
0366 {
0367     return (w == XFS_DATA_FORK ? XFS_ILOG_DDATA : XFS_ILOG_ADATA);
0368 }
0369 
0370 /*
0371  * Incore version of the on-disk inode core structures. We log this directly
0372  * into the journal in host CPU format (for better or worse) and as such
0373  * directly mirrors the xfs_dinode structure as it must contain all the same
0374  * information.
0375  */
0376 typedef uint64_t xfs_log_timestamp_t;
0377 
0378 /* Legacy timestamp encoding format. */
0379 struct xfs_log_legacy_timestamp {
0380     int32_t     t_sec;      /* timestamp seconds */
0381     int32_t     t_nsec;     /* timestamp nanoseconds */
0382 };
0383 
0384 /*
0385  * Define the format of the inode core that is logged. This structure must be
0386  * kept identical to struct xfs_dinode except for the endianness annotations.
0387  */
0388 struct xfs_log_dinode {
0389     uint16_t    di_magic;   /* inode magic # = XFS_DINODE_MAGIC */
0390     uint16_t    di_mode;    /* mode and type of file */
0391     int8_t      di_version; /* inode version */
0392     int8_t      di_format;  /* format of di_c data */
0393     uint8_t     di_pad3[2]; /* unused in v2/3 inodes */
0394     uint32_t    di_uid;     /* owner's user id */
0395     uint32_t    di_gid;     /* owner's group id */
0396     uint32_t    di_nlink;   /* number of links to file */
0397     uint16_t    di_projid_lo;   /* lower part of owner's project id */
0398     uint16_t    di_projid_hi;   /* higher part of owner's project id */
0399     union {
0400         /* Number of data fork extents if NREXT64 is set */
0401         uint64_t    di_big_nextents;
0402 
0403         /* Padding for V3 inodes without NREXT64 set. */
0404         uint64_t    di_v3_pad;
0405 
0406         /* Padding and inode flush counter for V2 inodes. */
0407         struct {
0408             uint8_t di_v2_pad[6];   /* V2 inode zeroed space */
0409             uint16_t di_flushiter;  /* V2 inode incremented on flush */
0410         };
0411     };
0412     xfs_log_timestamp_t di_atime;   /* time last accessed */
0413     xfs_log_timestamp_t di_mtime;   /* time last modified */
0414     xfs_log_timestamp_t di_ctime;   /* time created/inode modified */
0415     xfs_fsize_t di_size;    /* number of bytes in file */
0416     xfs_rfsblock_t  di_nblocks; /* # of direct & btree blocks used */
0417     xfs_extlen_t    di_extsize; /* basic/minimum extent size for file */
0418     union {
0419         /*
0420          * For V2 inodes and V3 inodes without NREXT64 set, this
0421          * is the number of data and attr fork extents.
0422          */
0423         struct {
0424             uint32_t  di_nextents;
0425             uint16_t  di_anextents;
0426         } __packed;
0427 
0428         /* Number of attr fork extents if NREXT64 is set. */
0429         struct {
0430             uint32_t  di_big_anextents;
0431             uint16_t  di_nrext64_pad;
0432         } __packed;
0433     } __packed;
0434     uint8_t     di_forkoff; /* attr fork offs, <<3 for 64b align */
0435     int8_t      di_aformat; /* format of attr fork's data */
0436     uint32_t    di_dmevmask;    /* DMIG event mask */
0437     uint16_t    di_dmstate; /* DMIG state info */
0438     uint16_t    di_flags;   /* random flags, XFS_DIFLAG_... */
0439     uint32_t    di_gen;     /* generation number */
0440 
0441     /* di_next_unlinked is the only non-core field in the old dinode */
0442     xfs_agino_t di_next_unlinked;/* agi unlinked list ptr */
0443 
0444     /* start of the extended dinode, writable fields */
0445     uint32_t    di_crc;     /* CRC of the inode */
0446     uint64_t    di_changecount; /* number of attribute changes */
0447 
0448     /*
0449      * The LSN we write to this field during formatting is not a reflection
0450      * of the current on-disk LSN. It should never be used for recovery
0451      * sequencing, nor should it be recovered into the on-disk inode at all.
0452      * See xlog_recover_inode_commit_pass2() and xfs_log_dinode_to_disk()
0453      * for details.
0454      */
0455     xfs_lsn_t   di_lsn;
0456 
0457     uint64_t    di_flags2;  /* more random flags */
0458     uint32_t    di_cowextsize;  /* basic cow extent size for file */
0459     uint8_t     di_pad2[12];    /* more padding for future expansion */
0460 
0461     /* fields only written to during inode creation */
0462     xfs_log_timestamp_t di_crtime;  /* time created */
0463     xfs_ino_t   di_ino;     /* inode number */
0464     uuid_t      di_uuid;    /* UUID of the filesystem */
0465 
0466     /* structure must be padded to 64 bit alignment */
0467 };
0468 
0469 #define xfs_log_dinode_size(mp)                     \
0470     (xfs_has_v3inodes((mp)) ?                   \
0471         sizeof(struct xfs_log_dinode) :             \
0472         offsetof(struct xfs_log_dinode, di_next_unlinked))
0473 
0474 /*
0475  * Buffer Log Format definitions
0476  *
0477  * These are the physical dirty bitmap definitions for the log format structure.
0478  */
0479 #define XFS_BLF_CHUNK       128
0480 #define XFS_BLF_SHIFT       7
0481 #define BIT_TO_WORD_SHIFT   5
0482 #define NBWORD          (NBBY * sizeof(unsigned int))
0483 
0484 /*
0485  * This flag indicates that the buffer contains on disk inodes
0486  * and requires special recovery handling.
0487  */
0488 #define XFS_BLF_INODE_BUF   (1<<0)
0489 
0490 /*
0491  * This flag indicates that the buffer should not be replayed
0492  * during recovery because its blocks are being freed.
0493  */
0494 #define XFS_BLF_CANCEL      (1<<1)
0495 
0496 /*
0497  * This flag indicates that the buffer contains on disk
0498  * user or group dquots and may require special recovery handling.
0499  */
0500 #define XFS_BLF_UDQUOT_BUF  (1<<2)
0501 #define XFS_BLF_PDQUOT_BUF  (1<<3)
0502 #define XFS_BLF_GDQUOT_BUF  (1<<4)
0503 
0504 /*
0505  * This is the structure used to lay out a buf log item in the log.  The data
0506  * map describes which 128 byte chunks of the buffer have been logged.
0507  *
0508  * The placement of blf_map_size causes blf_data_map to start at an odd
0509  * multiple of sizeof(unsigned int) offset within the struct.  Because the data
0510  * bitmap size will always be an even number, the end of the data_map (and
0511  * therefore the structure) will also be at an odd multiple of sizeof(unsigned
0512  * int).  Some 64-bit compilers will insert padding at the end of the struct to
0513  * ensure 64-bit alignment of blf_blkno, but 32-bit ones will not.  Therefore,
0514  * XFS_BLF_DATAMAP_SIZE must be an odd number to make the padding explicit and
0515  * keep the structure size consistent between 32-bit and 64-bit platforms.
0516  */
0517 #define __XFS_BLF_DATAMAP_SIZE  ((XFS_MAX_BLOCKSIZE / XFS_BLF_CHUNK) / NBWORD)
0518 #define XFS_BLF_DATAMAP_SIZE    (__XFS_BLF_DATAMAP_SIZE + 1)
0519 
0520 typedef struct xfs_buf_log_format {
0521     unsigned short  blf_type;   /* buf log item type indicator */
0522     unsigned short  blf_size;   /* size of this item */
0523     unsigned short  blf_flags;  /* misc state */
0524     unsigned short  blf_len;    /* number of blocks in this buf */
0525     int64_t     blf_blkno;  /* starting blkno of this buf */
0526     unsigned int    blf_map_size;   /* used size of data bitmap in words */
0527     unsigned int    blf_data_map[XFS_BLF_DATAMAP_SIZE]; /* dirty bitmap */
0528 } xfs_buf_log_format_t;
0529 
0530 /*
0531  * All buffers now need to tell recovery where the magic number
0532  * is so that it can verify and calculate the CRCs on the buffer correctly
0533  * once the changes have been replayed into the buffer.
0534  *
0535  * The type value is held in the upper 5 bits of the blf_flags field, which is
0536  * an unsigned 16 bit field. Hence we need to shift it 11 bits up and down.
0537  */
0538 #define XFS_BLFT_BITS   5
0539 #define XFS_BLFT_SHIFT  11
0540 #define XFS_BLFT_MASK   (((1 << XFS_BLFT_BITS) - 1) << XFS_BLFT_SHIFT)
0541 
0542 enum xfs_blft {
0543     XFS_BLFT_UNKNOWN_BUF = 0,
0544     XFS_BLFT_UDQUOT_BUF,
0545     XFS_BLFT_PDQUOT_BUF,
0546     XFS_BLFT_GDQUOT_BUF,
0547     XFS_BLFT_BTREE_BUF,
0548     XFS_BLFT_AGF_BUF,
0549     XFS_BLFT_AGFL_BUF,
0550     XFS_BLFT_AGI_BUF,
0551     XFS_BLFT_DINO_BUF,
0552     XFS_BLFT_SYMLINK_BUF,
0553     XFS_BLFT_DIR_BLOCK_BUF,
0554     XFS_BLFT_DIR_DATA_BUF,
0555     XFS_BLFT_DIR_FREE_BUF,
0556     XFS_BLFT_DIR_LEAF1_BUF,
0557     XFS_BLFT_DIR_LEAFN_BUF,
0558     XFS_BLFT_DA_NODE_BUF,
0559     XFS_BLFT_ATTR_LEAF_BUF,
0560     XFS_BLFT_ATTR_RMT_BUF,
0561     XFS_BLFT_SB_BUF,
0562     XFS_BLFT_RTBITMAP_BUF,
0563     XFS_BLFT_RTSUMMARY_BUF,
0564     XFS_BLFT_MAX_BUF = (1 << XFS_BLFT_BITS),
0565 };
0566 
0567 static inline void
0568 xfs_blft_to_flags(struct xfs_buf_log_format *blf, enum xfs_blft type)
0569 {
0570     ASSERT(type > XFS_BLFT_UNKNOWN_BUF && type < XFS_BLFT_MAX_BUF);
0571     blf->blf_flags &= ~XFS_BLFT_MASK;
0572     blf->blf_flags |= ((type << XFS_BLFT_SHIFT) & XFS_BLFT_MASK);
0573 }
0574 
0575 static inline uint16_t
0576 xfs_blft_from_flags(struct xfs_buf_log_format *blf)
0577 {
0578     return (blf->blf_flags & XFS_BLFT_MASK) >> XFS_BLFT_SHIFT;
0579 }
0580 
0581 /*
0582  * EFI/EFD log format definitions
0583  */
0584 typedef struct xfs_extent {
0585     xfs_fsblock_t   ext_start;
0586     xfs_extlen_t    ext_len;
0587 } xfs_extent_t;
0588 
0589 /*
0590  * Since an xfs_extent_t has types (start:64, len: 32)
0591  * there are different alignments on 32 bit and 64 bit kernels.
0592  * So we provide the different variants for use by a
0593  * conversion routine.
0594  */
0595 typedef struct xfs_extent_32 {
0596     uint64_t    ext_start;
0597     uint32_t    ext_len;
0598 } __attribute__((packed)) xfs_extent_32_t;
0599 
0600 typedef struct xfs_extent_64 {
0601     uint64_t    ext_start;
0602     uint32_t    ext_len;
0603     uint32_t    ext_pad;
0604 } xfs_extent_64_t;
0605 
0606 /*
0607  * This is the structure used to lay out an efi log item in the
0608  * log.  The efi_extents field is a variable size array whose
0609  * size is given by efi_nextents.
0610  */
0611 typedef struct xfs_efi_log_format {
0612     uint16_t        efi_type;   /* efi log item type */
0613     uint16_t        efi_size;   /* size of this item */
0614     uint32_t        efi_nextents;   /* # extents to free */
0615     uint64_t        efi_id;     /* efi identifier */
0616     xfs_extent_t        efi_extents[1]; /* array of extents to free */
0617 } xfs_efi_log_format_t;
0618 
0619 typedef struct xfs_efi_log_format_32 {
0620     uint16_t        efi_type;   /* efi log item type */
0621     uint16_t        efi_size;   /* size of this item */
0622     uint32_t        efi_nextents;   /* # extents to free */
0623     uint64_t        efi_id;     /* efi identifier */
0624     xfs_extent_32_t     efi_extents[1]; /* array of extents to free */
0625 } __attribute__((packed)) xfs_efi_log_format_32_t;
0626 
0627 typedef struct xfs_efi_log_format_64 {
0628     uint16_t        efi_type;   /* efi log item type */
0629     uint16_t        efi_size;   /* size of this item */
0630     uint32_t        efi_nextents;   /* # extents to free */
0631     uint64_t        efi_id;     /* efi identifier */
0632     xfs_extent_64_t     efi_extents[1]; /* array of extents to free */
0633 } xfs_efi_log_format_64_t;
0634 
0635 /*
0636  * This is the structure used to lay out an efd log item in the
0637  * log.  The efd_extents array is a variable size array whose
0638  * size is given by efd_nextents;
0639  */
0640 typedef struct xfs_efd_log_format {
0641     uint16_t        efd_type;   /* efd log item type */
0642     uint16_t        efd_size;   /* size of this item */
0643     uint32_t        efd_nextents;   /* # of extents freed */
0644     uint64_t        efd_efi_id; /* id of corresponding efi */
0645     xfs_extent_t        efd_extents[1]; /* array of extents freed */
0646 } xfs_efd_log_format_t;
0647 
0648 typedef struct xfs_efd_log_format_32 {
0649     uint16_t        efd_type;   /* efd log item type */
0650     uint16_t        efd_size;   /* size of this item */
0651     uint32_t        efd_nextents;   /* # of extents freed */
0652     uint64_t        efd_efi_id; /* id of corresponding efi */
0653     xfs_extent_32_t     efd_extents[1]; /* array of extents freed */
0654 } __attribute__((packed)) xfs_efd_log_format_32_t;
0655 
0656 typedef struct xfs_efd_log_format_64 {
0657     uint16_t        efd_type;   /* efd log item type */
0658     uint16_t        efd_size;   /* size of this item */
0659     uint32_t        efd_nextents;   /* # of extents freed */
0660     uint64_t        efd_efi_id; /* id of corresponding efi */
0661     xfs_extent_64_t     efd_extents[1]; /* array of extents freed */
0662 } xfs_efd_log_format_64_t;
0663 
0664 /*
0665  * RUI/RUD (reverse mapping) log format definitions
0666  */
0667 struct xfs_map_extent {
0668     uint64_t        me_owner;
0669     uint64_t        me_startblock;
0670     uint64_t        me_startoff;
0671     uint32_t        me_len;
0672     uint32_t        me_flags;
0673 };
0674 
0675 /* rmap me_flags: upper bits are flags, lower byte is type code */
0676 #define XFS_RMAP_EXTENT_MAP     1
0677 #define XFS_RMAP_EXTENT_MAP_SHARED  2
0678 #define XFS_RMAP_EXTENT_UNMAP       3
0679 #define XFS_RMAP_EXTENT_UNMAP_SHARED    4
0680 #define XFS_RMAP_EXTENT_CONVERT     5
0681 #define XFS_RMAP_EXTENT_CONVERT_SHARED  6
0682 #define XFS_RMAP_EXTENT_ALLOC       7
0683 #define XFS_RMAP_EXTENT_FREE        8
0684 #define XFS_RMAP_EXTENT_TYPE_MASK   0xFF
0685 
0686 #define XFS_RMAP_EXTENT_ATTR_FORK   (1U << 31)
0687 #define XFS_RMAP_EXTENT_BMBT_BLOCK  (1U << 30)
0688 #define XFS_RMAP_EXTENT_UNWRITTEN   (1U << 29)
0689 
0690 #define XFS_RMAP_EXTENT_FLAGS       (XFS_RMAP_EXTENT_TYPE_MASK | \
0691                      XFS_RMAP_EXTENT_ATTR_FORK | \
0692                      XFS_RMAP_EXTENT_BMBT_BLOCK | \
0693                      XFS_RMAP_EXTENT_UNWRITTEN)
0694 
0695 /*
0696  * This is the structure used to lay out an rui log item in the
0697  * log.  The rui_extents field is a variable size array whose
0698  * size is given by rui_nextents.
0699  */
0700 struct xfs_rui_log_format {
0701     uint16_t        rui_type;   /* rui log item type */
0702     uint16_t        rui_size;   /* size of this item */
0703     uint32_t        rui_nextents;   /* # extents to free */
0704     uint64_t        rui_id;     /* rui identifier */
0705     struct xfs_map_extent   rui_extents[];  /* array of extents to rmap */
0706 };
0707 
0708 static inline size_t
0709 xfs_rui_log_format_sizeof(
0710     unsigned int        nr)
0711 {
0712     return sizeof(struct xfs_rui_log_format) +
0713             nr * sizeof(struct xfs_map_extent);
0714 }
0715 
0716 /*
0717  * This is the structure used to lay out an rud log item in the
0718  * log.  The rud_extents array is a variable size array whose
0719  * size is given by rud_nextents;
0720  */
0721 struct xfs_rud_log_format {
0722     uint16_t        rud_type;   /* rud log item type */
0723     uint16_t        rud_size;   /* size of this item */
0724     uint32_t        __pad;
0725     uint64_t        rud_rui_id; /* id of corresponding rui */
0726 };
0727 
0728 /*
0729  * CUI/CUD (refcount update) log format definitions
0730  */
0731 struct xfs_phys_extent {
0732     uint64_t        pe_startblock;
0733     uint32_t        pe_len;
0734     uint32_t        pe_flags;
0735 };
0736 
0737 /* refcount pe_flags: upper bits are flags, lower byte is type code */
0738 /* Type codes are taken directly from enum xfs_refcount_intent_type. */
0739 #define XFS_REFCOUNT_EXTENT_TYPE_MASK   0xFF
0740 
0741 #define XFS_REFCOUNT_EXTENT_FLAGS   (XFS_REFCOUNT_EXTENT_TYPE_MASK)
0742 
0743 /*
0744  * This is the structure used to lay out a cui log item in the
0745  * log.  The cui_extents field is a variable size array whose
0746  * size is given by cui_nextents.
0747  */
0748 struct xfs_cui_log_format {
0749     uint16_t        cui_type;   /* cui log item type */
0750     uint16_t        cui_size;   /* size of this item */
0751     uint32_t        cui_nextents;   /* # extents to free */
0752     uint64_t        cui_id;     /* cui identifier */
0753     struct xfs_phys_extent  cui_extents[];  /* array of extents */
0754 };
0755 
0756 static inline size_t
0757 xfs_cui_log_format_sizeof(
0758     unsigned int        nr)
0759 {
0760     return sizeof(struct xfs_cui_log_format) +
0761             nr * sizeof(struct xfs_phys_extent);
0762 }
0763 
0764 /*
0765  * This is the structure used to lay out a cud log item in the
0766  * log.  The cud_extents array is a variable size array whose
0767  * size is given by cud_nextents;
0768  */
0769 struct xfs_cud_log_format {
0770     uint16_t        cud_type;   /* cud log item type */
0771     uint16_t        cud_size;   /* size of this item */
0772     uint32_t        __pad;
0773     uint64_t        cud_cui_id; /* id of corresponding cui */
0774 };
0775 
0776 /*
0777  * BUI/BUD (inode block mapping) log format definitions
0778  */
0779 
0780 /* bmbt me_flags: upper bits are flags, lower byte is type code */
0781 /* Type codes are taken directly from enum xfs_bmap_intent_type. */
0782 #define XFS_BMAP_EXTENT_TYPE_MASK   0xFF
0783 
0784 #define XFS_BMAP_EXTENT_ATTR_FORK   (1U << 31)
0785 #define XFS_BMAP_EXTENT_UNWRITTEN   (1U << 30)
0786 
0787 #define XFS_BMAP_EXTENT_FLAGS       (XFS_BMAP_EXTENT_TYPE_MASK | \
0788                      XFS_BMAP_EXTENT_ATTR_FORK | \
0789                      XFS_BMAP_EXTENT_UNWRITTEN)
0790 
0791 /*
0792  * This is the structure used to lay out an bui log item in the
0793  * log.  The bui_extents field is a variable size array whose
0794  * size is given by bui_nextents.
0795  */
0796 struct xfs_bui_log_format {
0797     uint16_t        bui_type;   /* bui log item type */
0798     uint16_t        bui_size;   /* size of this item */
0799     uint32_t        bui_nextents;   /* # extents to free */
0800     uint64_t        bui_id;     /* bui identifier */
0801     struct xfs_map_extent   bui_extents[];  /* array of extents to bmap */
0802 };
0803 
0804 static inline size_t
0805 xfs_bui_log_format_sizeof(
0806     unsigned int        nr)
0807 {
0808     return sizeof(struct xfs_bui_log_format) +
0809             nr * sizeof(struct xfs_map_extent);
0810 }
0811 
0812 /*
0813  * This is the structure used to lay out an bud log item in the
0814  * log.  The bud_extents array is a variable size array whose
0815  * size is given by bud_nextents;
0816  */
0817 struct xfs_bud_log_format {
0818     uint16_t        bud_type;   /* bud log item type */
0819     uint16_t        bud_size;   /* size of this item */
0820     uint32_t        __pad;
0821     uint64_t        bud_bui_id; /* id of corresponding bui */
0822 };
0823 
0824 /*
0825  * Dquot Log format definitions.
0826  *
0827  * The first two fields must be the type and size fitting into
0828  * 32 bits : log_recovery code assumes that.
0829  */
0830 typedef struct xfs_dq_logformat {
0831     uint16_t        qlf_type;      /* dquot log item type */
0832     uint16_t        qlf_size;      /* size of this item */
0833     xfs_dqid_t      qlf_id;        /* usr/grp/proj id : 32 bits */
0834     int64_t         qlf_blkno;     /* blkno of dquot buffer */
0835     int32_t         qlf_len;       /* len of dquot buffer */
0836     uint32_t        qlf_boffset;   /* off of dquot in buffer */
0837 } xfs_dq_logformat_t;
0838 
0839 /*
0840  * log format struct for QUOTAOFF records.
0841  * The first two fields must be the type and size fitting into
0842  * 32 bits : log_recovery code assumes that.
0843  * We write two LI_QUOTAOFF logitems per quotaoff, the last one keeps a pointer
0844  * to the first and ensures that the first logitem is taken out of the AIL
0845  * only when the last one is securely committed.
0846  */
0847 typedef struct xfs_qoff_logformat {
0848     unsigned short      qf_type;    /* quotaoff log item type */
0849     unsigned short      qf_size;    /* size of this item */
0850     unsigned int        qf_flags;   /* USR and/or GRP */
0851     char            qf_pad[12]; /* padding for future */
0852 } xfs_qoff_logformat_t;
0853 
0854 /*
0855  * Disk quotas status in m_qflags, and also sb_qflags. 16 bits.
0856  */
0857 #define XFS_UQUOTA_ACCT 0x0001  /* user quota accounting ON */
0858 #define XFS_UQUOTA_ENFD 0x0002  /* user quota limits enforced */
0859 #define XFS_UQUOTA_CHKD 0x0004  /* quotacheck run on usr quotas */
0860 #define XFS_PQUOTA_ACCT 0x0008  /* project quota accounting ON */
0861 #define XFS_OQUOTA_ENFD 0x0010  /* other (grp/prj) quota limits enforced */
0862 #define XFS_OQUOTA_CHKD 0x0020  /* quotacheck run on other (grp/prj) quotas */
0863 #define XFS_GQUOTA_ACCT 0x0040  /* group quota accounting ON */
0864 
0865 /*
0866  * Conversion to and from the combined OQUOTA flag (if necessary)
0867  * is done only in xfs_sb_qflags_to_disk() and xfs_sb_qflags_from_disk()
0868  */
0869 #define XFS_GQUOTA_ENFD 0x0080  /* group quota limits enforced */
0870 #define XFS_GQUOTA_CHKD 0x0100  /* quotacheck run on group quotas */
0871 #define XFS_PQUOTA_ENFD 0x0200  /* project quota limits enforced */
0872 #define XFS_PQUOTA_CHKD 0x0400  /* quotacheck run on project quotas */
0873 
0874 #define XFS_ALL_QUOTA_ACCT  \
0875         (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT | XFS_PQUOTA_ACCT)
0876 #define XFS_ALL_QUOTA_ENFD  \
0877         (XFS_UQUOTA_ENFD | XFS_GQUOTA_ENFD | XFS_PQUOTA_ENFD)
0878 #define XFS_ALL_QUOTA_CHKD  \
0879         (XFS_UQUOTA_CHKD | XFS_GQUOTA_CHKD | XFS_PQUOTA_CHKD)
0880 
0881 #define XFS_MOUNT_QUOTA_ALL (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
0882                  XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\
0883                  XFS_GQUOTA_ENFD|XFS_GQUOTA_CHKD|\
0884                  XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD|\
0885                  XFS_PQUOTA_CHKD)
0886 
0887 /*
0888  * Inode create log item structure
0889  *
0890  * Log recovery assumes the first two entries are the type and size and they fit
0891  * in 32 bits. Also in host order (ugh) so they have to be 32 bit aligned so
0892  * decoding can be done correctly.
0893  */
0894 struct xfs_icreate_log {
0895     uint16_t    icl_type;   /* type of log format structure */
0896     uint16_t    icl_size;   /* size of log format structure */
0897     __be32      icl_ag;     /* ag being allocated in */
0898     __be32      icl_agbno;  /* start block of inode range */
0899     __be32      icl_count;  /* number of inodes to initialise */
0900     __be32      icl_isize;  /* size of inodes */
0901     __be32      icl_length; /* length of extent to initialise */
0902     __be32      icl_gen;    /* inode generation number to use */
0903 };
0904 
0905 /*
0906  * Flags for deferred attribute operations.
0907  * Upper bits are flags, lower byte is type code
0908  */
0909 #define XFS_ATTRI_OP_FLAGS_SET      1   /* Set the attribute */
0910 #define XFS_ATTRI_OP_FLAGS_REMOVE   2   /* Remove the attribute */
0911 #define XFS_ATTRI_OP_FLAGS_REPLACE  3   /* Replace the attribute */
0912 #define XFS_ATTRI_OP_FLAGS_TYPE_MASK    0xFF    /* Flags type mask */
0913 
0914 /*
0915  * alfi_attr_filter captures the state of xfs_da_args.attr_filter, so it should
0916  * never have any other bits set.
0917  */
0918 #define XFS_ATTRI_FILTER_MASK       (XFS_ATTR_ROOT | \
0919                      XFS_ATTR_SECURE | \
0920                      XFS_ATTR_INCOMPLETE)
0921 
0922 /*
0923  * This is the structure used to lay out an attr log item in the
0924  * log.
0925  */
0926 struct xfs_attri_log_format {
0927     uint16_t    alfi_type;  /* attri log item type */
0928     uint16_t    alfi_size;  /* size of this item */
0929     uint32_t    __pad;      /* pad to 64 bit aligned */
0930     uint64_t    alfi_id;    /* attri identifier */
0931     uint64_t    alfi_ino;   /* the inode for this attr operation */
0932     uint32_t    alfi_op_flags;  /* marks the op as a set or remove */
0933     uint32_t    alfi_name_len;  /* attr name length */
0934     uint32_t    alfi_value_len; /* attr value length */
0935     uint32_t    alfi_attr_filter;/* attr filter flags */
0936 };
0937 
0938 struct xfs_attrd_log_format {
0939     uint16_t    alfd_type;  /* attrd log item type */
0940     uint16_t    alfd_size;  /* size of this item */
0941     uint32_t    __pad;      /* pad to 64 bit aligned */
0942     uint64_t    alfd_alf_id;    /* id of corresponding attri */
0943 };
0944 
0945 #endif /* __XFS_LOG_FORMAT_H__ */