From c2f07654a5190cb96895c556e7240385cce8149c Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sat, 7 Mar 2020 04:56:40 +0000 Subject: [PATCH 1/2] CTASSERT lfs on-disk structure sizes. --- sys/ufs/lfs/lfs.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/sys/ufs/lfs/lfs.h b/sys/ufs/lfs/lfs.h index 069a43fe9127..932ded1e1040 100644 --- a/sys/ufs/lfs/lfs.h +++ b/sys/ufs/lfs/lfs.h @@ -355,6 +355,7 @@ struct lfs_dirheader32 { uint8_t dh_type; /* file type, see below */ uint8_t dh_namlen; /* length of string in d_name */ }; +__CTASSERT(sizeof(struct lfs_dirheader32) == 8); struct lfs_dirheader64 { uint32_t dh_inoA; /* inode number of entry */ @@ -363,6 +364,7 @@ struct lfs_dirheader64 { uint8_t dh_type; /* file type, see below */ uint8_t dh_namlen; /* length of string in d_name */ }; +__CTASSERT(sizeof(struct lfs_dirheader64) == 12); union lfs_dirheader { struct lfs_dirheader64 u_64; @@ -381,6 +383,7 @@ struct lfs_dirtemplate32 { struct lfs_dirheader32 dotdot_header; char dotdot_name[4]; /* ditto */ }; +__CTASSERT(sizeof(struct lfs_dirtemplate32) == 2*(8 + 4)); struct lfs_dirtemplate64 { struct lfs_dirheader64 dot_header; @@ -388,6 +391,7 @@ struct lfs_dirtemplate64 { struct lfs_dirheader64 dotdot_header; char dotdot_name[4]; /* ditto */ }; +__CTASSERT(sizeof(struct lfs_dirtemplate64) == 2*(12 + 4)); union lfs_dirtemplate { struct lfs_dirtemplate64 u_64; @@ -408,6 +412,7 @@ struct lfs_odirtemplate { uint16_t dotdot_namlen; char dotdot_name[4]; /* ditto */ }; +__CTASSERT(sizeof(struct lfs_odirtemplate) == 2*(8 + 4)); #endif /* @@ -441,6 +446,7 @@ struct lfs32_dinode { uint32_t di_gid; /* 116: File group. */ uint64_t di_modrev; /* 120: i_modrev for NFSv4 */ }; +__CTASSERT(sizeof(struct lfs32_dinode) == 128); struct lfs64_dinode { uint16_t di_mode; /* 0: IFMT, permissions; see below. */ @@ -469,6 +475,7 @@ struct lfs64_dinode { uint64_t di_inumber; /* 240: Inode number */ uint64_t di_spare[1]; /* 248: Reserved; currently unused */ }; +__CTASSERT(sizeof(struct lfs64_dinode) == 256); union lfs_dinode { struct lfs64_dinode u_64; @@ -529,6 +536,7 @@ struct segusage { uint32_t su_flags; /* 12: segment flags */ uint64_t su_lastmod; /* 16: last modified timestamp */ }; +__CTASSERT(sizeof(struct segusage) == 24); typedef struct segusage_v1 SEGUSE_V1; struct segusage_v1 { @@ -538,6 +546,7 @@ struct segusage_v1 { uint16_t su_ninos; /* 10: number of inode blocks in seg */ uint32_t su_flags; /* 12: segment flags */ }; +__CTASSERT(sizeof(struct segusage_v1) == 16); /* * On-disk file information. One per file with data blocks in the segment. @@ -555,6 +564,7 @@ struct finfo64 { uint32_t fi_lastlength; /* length of last block in array */ uint32_t fi_pad; /* unused */ }; +__CTASSERT(sizeof(struct finfo64) == 24); typedef struct finfo32 FINFO32; struct finfo32 { @@ -563,6 +573,7 @@ struct finfo32 { uint32_t fi_ino; /* inode number */ uint32_t fi_lastlength; /* length of last block in array */ }; +__CTASSERT(sizeof(struct finfo32) == 16); typedef union finfo { struct finfo64 u_64; @@ -580,10 +591,12 @@ typedef union finfo { typedef struct iinfo64 { uint64_t ii_block; /* block number */ } IINFO64; +__CTASSERT(sizeof(struct iinfo64) == 8); typedef struct iinfo32 { uint32_t ii_block; /* block number */ } IINFO32; +__CTASSERT(sizeof(struct iinfo32) == 4); typedef union iinfo { struct iinfo64 u_64; @@ -608,6 +621,7 @@ struct ifile64 { int64_t if_daddr; /* inode disk address */ uint64_t if_nextfree; /* next-unallocated inode */ }; +__CTASSERT(sizeof(struct ifile64) == 32); typedef struct ifile32 IFILE32; struct ifile32 { @@ -617,6 +631,7 @@ struct ifile32 { uint32_t if_atime_sec; /* Last access time, seconds */ uint32_t if_atime_nsec; /* and nanoseconds */ }; +__CTASSERT(sizeof(struct ifile32) == 20); typedef struct ifile_v1 IFILE_V1; struct ifile_v1 { @@ -628,6 +643,7 @@ struct ifile_v1 { struct timespec if_atime; /* Last access time */ #endif }; +__CTASSERT(sizeof(struct ifile_v1) == 12); /* * Note: struct ifile_v1 is often handled by accessing the first three @@ -657,6 +673,7 @@ typedef struct _cleanerinfo32 { uint32_t free_tail; /* 20: tail of the inode free list */ uint32_t flags; /* 24: status word from the kernel */ } CLEANERINFO32; +__CTASSERT(sizeof(struct _cleanerinfo32) == 28); typedef struct _cleanerinfo64 { uint32_t clean; /* 0: number of clean segments */ @@ -668,6 +685,7 @@ typedef struct _cleanerinfo64 { uint32_t flags; /* 40: status word from the kernel */ uint32_t pad; /* 44: must be 64-bit aligned */ } CLEANERINFO64; +__CTASSERT(sizeof(struct _cleanerinfo64) == 48); /* this must not go to disk directly of course */ typedef union _cleanerinfo { @@ -705,6 +723,7 @@ struct segsum_v1 { uint16_t ss_pad; /* 26: extra space */ /* FINFO's and inode daddr's... */ }; +__CTASSERT(sizeof(struct segsum_v1) == 28); typedef struct segsum32 SEGSUM32; struct segsum32 { @@ -722,6 +741,7 @@ struct segsum32 { uint64_t ss_create; /* 40: time stamp */ /* FINFO's and inode daddr's... */ }; +__CTASSERT(sizeof(struct segsum32) == 48); typedef struct segsum64 SEGSUM64; struct segsum64 { @@ -739,6 +759,7 @@ struct segsum64 { uint64_t ss_create; /* 48: time stamp */ /* FINFO's and inode daddr's... */ }; +__CTASSERT(sizeof(struct segsum64) == 56); typedef union segsum SEGSUM; union segsum { From 89eec3adade33ae66882a023aacfd5a9796d6feb Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sat, 7 Mar 2020 21:53:08 +0000 Subject: [PATCH 2/2] Avoid misaligned access to lfs64 on-disk records in memory. lfs64 directory entries are only 32-bit-aligned in order to conserve space in directory blocks, and we already had a hack to stuff a 64-bit inode in them; this change extends the hack to other data structures on disk: - Some of them are not obviously naturally 64-bit aligned for lfs64 on disk anyway. - We access even the lfs32 data structures via a union that has lfs64 members, and it turns out that the compilers will assume access through a union with 64-bit-aligned members implies that the whole union has 64-bit alignment, even if we're only accessing a 32-bit-aligned member. --- sys/ufs/lfs/lfs.h | 60 +++++++++++++--- sys/ufs/lfs/lfs_accessors.h | 134 ++++++++++++++++++++++++------------ sys/ufs/lfs/lfs_alloc.c | 6 +- 3 files changed, 143 insertions(+), 57 deletions(-) diff --git a/sys/ufs/lfs/lfs.h b/sys/ufs/lfs/lfs.h index 932ded1e1040..f041e7c440cd 100644 --- a/sys/ufs/lfs/lfs.h +++ b/sys/ufs/lfs/lfs.h @@ -212,6 +212,27 @@ #endif #define LFS_MARKV_MAXBLKCNT 65536 /* Max block count for lfs_markv() */ +/* + * lfs64 64-bit fields -- we do this because not all the structures on + * disk for lfs64 were designed to be 64-bit aligned, so we can't use + * uint64_t + */ +struct lfs64_int { + uint32_t v[2]; +}; +typedef struct lfs64_int lfs64_int64_t; +typedef lfs64_int64_t lfs64_daddr_t; +typedef lfs64_int64_t lfs64_blkcnt_t; + +struct lfs64_uint { + uint32_t v[2]; +}; +typedef struct lfs64_uint lfs64_uint64_t; +typedef lfs64_uint64_t lfs64_ino_t; +typedef lfs64_uint64_t lfs64_blkno_t; +typedef lfs64_uint64_t lfs64_sec_t; +typedef lfs64_uint64_t lfs64_serial_t; + /* * Directories */ @@ -358,8 +379,7 @@ struct lfs_dirheader32 { __CTASSERT(sizeof(struct lfs_dirheader32) == 8); struct lfs_dirheader64 { - uint32_t dh_inoA; /* inode number of entry */ - uint32_t dh_inoB; /* inode number of entry */ + lfs64_ino_t dh_ino; /* inode number of entry */ uint16_t dh_reclen; /* length of this record */ uint8_t dh_type; /* file type, see below */ uint8_t dh_namlen; /* length of string in d_name */ @@ -481,6 +501,8 @@ union lfs_dinode { struct lfs64_dinode u_64; struct lfs32_dinode u_32; }; +__CTASSERT(__alignof(union lfs_dinode) == __alignof(struct lfs64_dinode)); +__CTASSERT(__alignof(union lfs_dinode) == __alignof(struct lfs32_dinode)); /* * The di_db fields may be overlaid with other information for @@ -560,7 +582,7 @@ typedef struct finfo64 FINFO64; struct finfo64 { uint32_t fi_nblocks; /* number of blocks */ uint32_t fi_version; /* version number */ - uint64_t fi_ino; /* inode number */ + lfs64_ino_t fi_ino; /* inode number */ uint32_t fi_lastlength; /* length of last block in array */ uint32_t fi_pad; /* unused */ }; @@ -579,6 +601,8 @@ typedef union finfo { struct finfo64 u_64; struct finfo32 u_32; } FINFO; +__CTASSERT(__alignof(FINFO) == __alignof(struct finfo64)); +__CTASSERT(__alignof(FINFO) == __alignof(struct finfo32)); /* * inode info (part of the segment summary) @@ -589,7 +613,7 @@ typedef union finfo { */ typedef struct iinfo64 { - uint64_t ii_block; /* block number */ + lfs64_blkno_t ii_block; /* block number */ } IINFO64; __CTASSERT(sizeof(struct iinfo64) == 8); @@ -602,6 +626,8 @@ typedef union iinfo { struct iinfo64 u_64; struct iinfo32 u_32; } IINFO; +__CTASSERT(__alignof(IINFO) == __alignof(struct iinfo64)); +__CTASSERT(__alignof(IINFO) == __alignof(struct iinfo32)); /* * Index file inode entries. @@ -617,9 +643,9 @@ typedef struct ifile64 IFILE64; struct ifile64 { uint32_t if_version; /* inode version number */ uint32_t if_atime_nsec; /* and nanoseconds */ - uint64_t if_atime_sec; /* Last access time, seconds */ - int64_t if_daddr; /* inode disk address */ - uint64_t if_nextfree; /* next-unallocated inode */ + lfs64_sec_t if_atime_sec; /* Last access time, seconds */ + lfs64_daddr_t if_daddr; /* inode disk address */ + lfs64_ino_t if_nextfree; /* next-unallocated inode */ }; __CTASSERT(sizeof(struct ifile64) == 32); @@ -655,6 +681,9 @@ typedef union ifile { struct ifile32 u_32; struct ifile_v1 u_v1; } IFILE; +__CTASSERT(__alignof(IFILE) == __alignof(struct ifile64)); +__CTASSERT(__alignof(IFILE) == __alignof(struct ifile32)); +__CTASSERT(__alignof(IFILE) == __alignof(struct ifile_v1)); /* * Cleaner information structure. This resides in the ifile and is used @@ -678,10 +707,10 @@ __CTASSERT(sizeof(struct _cleanerinfo32) == 28); typedef struct _cleanerinfo64 { uint32_t clean; /* 0: number of clean segments */ uint32_t dirty; /* 4: number of dirty segments */ - int64_t bfree; /* 8: disk blocks free */ - int64_t avail; /* 16: disk blocks available */ - uint64_t free_head; /* 24: head of the inode free list */ - uint64_t free_tail; /* 32: tail of the inode free list */ + lfs64_blkcnt_t bfree; /* 8: disk blocks free */ + lfs64_blkcnt_t avail; /* 16: disk blocks available */ + lfs64_ino_t free_head; /* 24: head of the inode free list */ + lfs64_ino_t free_tail; /* 32: tail of the inode free list */ uint32_t flags; /* 40: status word from the kernel */ uint32_t pad; /* 44: must be 64-bit aligned */ } CLEANERINFO64; @@ -692,6 +721,8 @@ typedef union _cleanerinfo { CLEANERINFO32 u_32; CLEANERINFO64 u_64; } CLEANERINFO; +__CTASSERT(__alignof(CLEANERINFO) == __alignof(CLEANERINFO32)); +__CTASSERT(__alignof(CLEANERINFO) == __alignof(CLEANERINFO64)); /* * On-disk segment summary information @@ -768,6 +799,11 @@ union segsum { struct segsum_v1 u_v1; }; +/* + * Segment summaries always appear at the start of a disk sector, so + * they will always be aligned as long as the buffer cache's buffer + * allocator is reasonable. + */ /* * On-disk super block. @@ -956,6 +992,8 @@ struct dlfs64 { uint32_t dlfs_cksum; /* 508: checksum for superblock checking */ }; +__CTASSERT(__alignof(struct dlfs) == __alignof(struct dlfs64)); + /* Type used for the inode bitmap */ typedef uint32_t lfs_bm_t; diff --git a/sys/ufs/lfs/lfs_accessors.h b/sys/ufs/lfs/lfs_accessors.h index b4accd6c358a..60867ac640ee 100644 --- a/sys/ufs/lfs/lfs_accessors.h +++ b/sys/ufs/lfs/lfs_accessors.h @@ -216,6 +216,52 @@ #define LFS_LITTLE_ENDIAN_ONDISK(fs) ((fs)->lfs_dobyteswap) #endif +/* + * Loading possibly-misaligned 64-bit quantities from pairs of 32-bit + * quantities. + */ + +static __inline uint64_t +lfs64_uint64dec(lfs64_uint64_t x) +{ + uint64_t y; + + memcpy(&y, x.v, sizeof y); + + return y; +} + +static __inline lfs64_uint64_t +lfs64_uint64enc(uint64_t y) +{ + lfs64_uint64_t x; + + memcpy(x.v, &y, sizeof y); + + return x; +} + +static __inline int64_t +lfs64_int64dec(lfs64_int64_t x) +{ + int64_t y; + + memcpy(&y, x.v, sizeof y); + + return y; +} + +static __inline lfs64_int64_t +lfs64_int64enc(int64_t y) +{ + lfs64_int64_t x; + + memcpy(x.v, &y, sizeof y); + + return x; +} + +#define LFS64_IDENTITY(x) (x) /* * directories @@ -274,17 +320,7 @@ static __inline uint64_t lfs_dir_getino(const STRUCT_LFS *fs, const LFS_DIRHEADER *dh) { if (fs->lfs_is64) { - uint64_t ino; - - /* - * XXX we can probably write this in a way that's both - * still legal and generates better code. - */ - memcpy(&ino, &dh->u_64.dh_inoA, sizeof(dh->u_64.dh_inoA)); - memcpy((char *)&ino + sizeof(dh->u_64.dh_inoA), - &dh->u_64.dh_inoB, - sizeof(dh->u_64.dh_inoB)); - return LFS_SWAP_uint64_t(fs, ino); + return LFS_SWAP_uint64_t(fs, lfs64_uint64dec(dh->u_64.dh_ino)); } else { return LFS_SWAP_uint32_t(fs, dh->u_32.dh_ino); } @@ -331,16 +367,7 @@ static __inline void lfs_dir_setino(STRUCT_LFS *fs, LFS_DIRHEADER *dh, uint64_t ino) { if (fs->lfs_is64) { - - ino = LFS_SWAP_uint64_t(fs, ino); - /* - * XXX we can probably write this in a way that's both - * still legal and generates better code. - */ - memcpy(&dh->u_64.dh_inoA, &ino, sizeof(dh->u_64.dh_inoA)); - memcpy(&dh->u_64.dh_inoB, - (char *)&ino + sizeof(dh->u_64.dh_inoA), - sizeof(dh->u_64.dh_inoB)); + dh->u_64.dh_ino = lfs64_uint64enc(LFS_SWAP_uint64_t(fs, ino)); } else { dh->u_32.dh_ino = LFS_SWAP_uint32_t(fs, ino); } @@ -717,12 +744,12 @@ lfs_iblock_set(STRUCT_LFS *fs, void *block, unsigned ix, daddr_t val) #define NEXT_FINFO(fs, fip) \ ((FINFO *)((char *)(fip) + FINFO_FULLSIZE(fs, fip))) -#define LFS_DEF_FI_ACCESSOR(type, type32, field) \ +#define LFS_DEF_FI_ACCESSOR_(type, type32, type64, field, enc64, dec64) \ static __inline type \ lfs_fi_get##field(STRUCT_LFS *fs, FINFO *fip) \ { \ if (fs->lfs_is64) { \ - return fip->u_64.fi_##field; \ + return dec64(fip->u_64.fi_##field); \ } else { \ return fip->u_32.fi_##field; \ } \ @@ -731,9 +758,9 @@ lfs_iblock_set(STRUCT_LFS *fs, void *block, unsigned ix, daddr_t val) lfs_fi_set##field(STRUCT_LFS *fs, FINFO *fip, type val) \ { \ if (fs->lfs_is64) { \ - type *p = &fip->u_64.fi_##field; \ + type64 *p = &fip->u_64.fi_##field; \ (void)p; \ - fip->u_64.fi_##field = val; \ + fip->u_64.fi_##field = enc64(val); \ } else { \ type32 *p = &fip->u_32.fi_##field; \ (void)p; \ @@ -741,9 +768,14 @@ lfs_iblock_set(STRUCT_LFS *fs, void *block, unsigned ix, daddr_t val) } \ } \ +#define LFS_DEF_FI_ACCESSOR(type, type32, field) \ + LFS_DEF_FI_ACCESSOR_(type, type32, type, field, \ + LFS64_IDENTITY, LFS64_IDENTITY) + LFS_DEF_FI_ACCESSOR(uint32_t, uint32_t, nblocks); LFS_DEF_FI_ACCESSOR(uint32_t, uint32_t, version); -LFS_DEF_FI_ACCESSOR(uint64_t, uint32_t, ino); +LFS_DEF_FI_ACCESSOR_(uint64_t, uint32_t, lfs64_uint64_t, ino, + lfs64_uint64enc, lfs64_uint64dec); LFS_DEF_FI_ACCESSOR(uint32_t, uint32_t, lastlength); static __inline daddr_t @@ -790,11 +822,12 @@ lfs_fi_setblock(STRUCT_LFS *fs, FINFO *fip, unsigned idx, daddr_t blk) #define NTH_IINFO(fs, buf, n) \ ((IINFO *)((char *)SEGSUM_IINFOSTART(fs, buf) - (n)*IINFOSIZE(fs))) +/* XXX Shouldn't this have byte-swapping? */ static __inline uint64_t lfs_ii_getblock(STRUCT_LFS *fs, IINFO *iip) { if (fs->lfs_is64) { - return iip->u_64.ii_block; + return lfs64_uint64dec(iip->u_64.ii_block); } else { return iip->u_32.ii_block; } @@ -804,7 +837,7 @@ static __inline void lfs_ii_setblock(STRUCT_LFS *fs, IINFO *iip, uint64_t block) { if (fs->lfs_is64) { - iip->u_64.ii_block = block; + iip->u_64.ii_block = lfs64_uint64enc(block); } else { iip->u_32.ii_block = block; } @@ -852,12 +885,12 @@ lfs_ii_setblock(STRUCT_LFS *fs, IINFO *iip, uint64_t block) } \ } while (0) -#define LFS_DEF_IF_ACCESSOR(type, type32, field) \ +#define LFS_DEF_IF_ACCESSOR_(type, type32, type64, field, enc64, dec64) \ static __inline type \ lfs_if_get##field(STRUCT_LFS *fs, IFILE *ifp) \ { \ if (fs->lfs_is64) { \ - return ifp->u_64.if_##field; \ + return dec64(ifp->u_64.if_##field); \ } else { \ return ifp->u_32.if_##field; \ } \ @@ -866,9 +899,9 @@ lfs_ii_setblock(STRUCT_LFS *fs, IINFO *iip, uint64_t block) lfs_if_set##field(STRUCT_LFS *fs, IFILE *ifp, type val) \ { \ if (fs->lfs_is64) { \ - type *p = &ifp->u_64.if_##field; \ + type64 *p = &ifp->u_64.if_##field; \ (void)p; \ - ifp->u_64.if_##field = val; \ + ifp->u_64.if_##field = enc64(val); \ } else { \ type32 *p = &ifp->u_32.if_##field; \ (void)p; \ @@ -876,10 +909,17 @@ lfs_ii_setblock(STRUCT_LFS *fs, IINFO *iip, uint64_t block) } \ } \ +#define LFS_DEF_IF_ACCESSOR(type, type32, field) \ + LFS_DEF_IF_ACCESSOR_(type, type32, type, field, \ + LFS64_IDENTITY, LFS64_IDENTITY) + LFS_DEF_IF_ACCESSOR(uint32_t, uint32_t, version); -LFS_DEF_IF_ACCESSOR(int64_t, int32_t, daddr); -LFS_DEF_IF_ACCESSOR(uint64_t, uint32_t, nextfree); -LFS_DEF_IF_ACCESSOR(uint64_t, uint32_t, atime_sec); +LFS_DEF_IF_ACCESSOR_(int64_t, int32_t, lfs64_daddr_t, daddr, + lfs64_int64enc, lfs64_int64dec); +LFS_DEF_IF_ACCESSOR_(uint64_t, uint32_t, lfs64_ino_t, nextfree, + lfs64_uint64enc, lfs64_uint64dec); +LFS_DEF_IF_ACCESSOR_(uint64_t, uint32_t, lfs64_sec_t, atime_sec, + lfs64_uint64enc, lfs64_uint64dec); LFS_DEF_IF_ACCESSOR(uint32_t, uint32_t, atime_nsec); /* @@ -891,12 +931,12 @@ LFS_DEF_IF_ACCESSOR(uint32_t, uint32_t, atime_nsec); ((((fs)->lfs_is64 ? sizeof(CLEANERINFO64) : sizeof(CLEANERINFO32)) + \ lfs_sb_getbsize(fs) - 1) >> lfs_sb_getbshift(fs)) -#define LFS_DEF_CI_ACCESSOR(type, type32, field) \ +#define LFS_DEF_CI_ACCESSOR_(type, type32, type64, field, enc64, dec64) \ static __inline type \ lfs_ci_get##field(STRUCT_LFS *fs, CLEANERINFO *cip) \ { \ if (fs->lfs_is64) { \ - return cip->u_64.field; \ + return dec64(cip->u_64.field); \ } else { \ return cip->u_32.field; \ } \ @@ -905,9 +945,9 @@ LFS_DEF_IF_ACCESSOR(uint32_t, uint32_t, atime_nsec); lfs_ci_set##field(STRUCT_LFS *fs, CLEANERINFO *cip, type val) \ { \ if (fs->lfs_is64) { \ - type *p = &cip->u_64.field; \ + type64 *p = &cip->u_64.field; \ (void)p; \ - cip->u_64.field = val; \ + cip->u_64.field = enc64(val); \ } else { \ type32 *p = &cip->u_32.field; \ (void)p; \ @@ -915,12 +955,20 @@ LFS_DEF_IF_ACCESSOR(uint32_t, uint32_t, atime_nsec); } \ } \ +#define LFS_DEF_CI_ACCESSOR(type, type32, field) \ + LFS_DEF_CI_ACCESSOR_(type, type32, type, field, \ + LFS64_IDENTITY, LFS64_IDENTITY) + LFS_DEF_CI_ACCESSOR(uint32_t, uint32_t, clean); LFS_DEF_CI_ACCESSOR(uint32_t, uint32_t, dirty); -LFS_DEF_CI_ACCESSOR(int64_t, int32_t, bfree); -LFS_DEF_CI_ACCESSOR(int64_t, int32_t, avail); -LFS_DEF_CI_ACCESSOR(uint64_t, uint32_t, free_head); -LFS_DEF_CI_ACCESSOR(uint64_t, uint32_t, free_tail); +LFS_DEF_CI_ACCESSOR_(int64_t, int32_t, lfs64_blkcnt_t, bfree, + lfs64_int64enc, lfs64_int64dec); +LFS_DEF_CI_ACCESSOR_(int64_t, int32_t, lfs64_blkcnt_t, avail, + lfs64_int64enc, lfs64_int64dec); +LFS_DEF_CI_ACCESSOR_(uint64_t, uint32_t, lfs64_ino_t, free_head, + lfs64_uint64enc, lfs64_uint64dec); +LFS_DEF_CI_ACCESSOR_(uint64_t, uint32_t, lfs64_ino_t, free_tail, + lfs64_uint64enc, lfs64_uint64dec); LFS_DEF_CI_ACCESSOR(uint32_t, uint32_t, flags); static __inline void diff --git a/sys/ufs/lfs/lfs_alloc.c b/sys/ufs/lfs/lfs_alloc.c index 1f6d9dd2e3f7..41f528ba55c8 100644 --- a/sys/ufs/lfs/lfs_alloc.c +++ b/sys/ufs/lfs/lfs_alloc.c @@ -185,11 +185,11 @@ lfs_extend_ifile(struct lfs *fs, kauth_cred_t cred) for (ifp64 = (IFILE64 *)bp->b_data; i < xmax; ++ifp64) { SET_BITMAP_FREE(fs, i); ifp64->if_version = 1; - ifp64->if_daddr = LFS_UNUSED_DADDR; - ifp64->if_nextfree = ++i; + ifp64->if_daddr = lfs64_int64enc(LFS_UNUSED_DADDR); + ifp64->if_nextfree = lfs64_uint64enc(++i); } ifp64--; - ifp64->if_nextfree = oldlast; + ifp64->if_nextfree = lfs64_uint64enc(oldlast); } else if (lfs_sb_getversion(fs) > 1) { for (ifp32 = (IFILE32 *)bp->b_data; i < xmax; ++ifp32) { SET_BITMAP_FREE(fs, i);