From f9e56f43b974b8aa1681c3ba6f2b4652de49e9a9 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Fri, 3 Jan 2003 04:44:31 +0000 Subject: [PATCH] Sync up user/kernel sources and headers (native extents). Use libxfs_bmbt_disk_get_all which replaces libxfs_bmbt_get_all. --- db/bmap.c | 2 +- include/libxfs.h | 7 +- include/xfs_bmap_btree.h | 55 +++++++++ include/xfs_inode.h | 10 +- include/xfs_inode_item.h | 7 +- include/xfs_log_priv.h | 4 +- include/xfs_mount.h | 97 ++++++++++----- libxfs/xfs.h | 37 +++--- libxfs/xfs_alloc.c | 13 -- libxfs/xfs_alloc_btree.c | 32 +++++ libxfs/xfs_bmap.c | 26 ++-- libxfs/xfs_bmap_btree.c | 254 ++++++++++++++++++++++++++++++++------- libxfs/xfs_btree.c | 6 +- libxfs/xfs_inode.c | 57 ++++----- repair/dinode.c | 2 +- 15 files changed, 451 insertions(+), 158 deletions(-) diff --git a/db/bmap.c b/db/bmap.c index fe6fe380b..7a3362f4f 100644 --- a/db/bmap.c +++ b/db/bmap.c @@ -298,7 +298,7 @@ convert_extent( xfs_bmbt_rec_t rpcopy, *p = &rpcopy; memmove(&rpcopy, rp, sizeof(rpcopy)); - libxfs_bmbt_get_all(p, s); + libxfs_bmbt_disk_get_all(p, s); if (s->br_state == XFS_EXT_UNWRITTEN) { *fp = 1; diff --git a/include/libxfs.h b/include/libxfs.h index 61b7aa4d8..b15a8c02d 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -437,9 +437,12 @@ extern int libxfs_alloc_file_space (xfs_inode_t *, xfs_off_t, extern xfs_dahash_t libxfs_da_hashname (uchar_t *, int); extern int libxfs_attr_leaf_newentsize (xfs_da_args_t *, int, int *); -extern xfs_filblks_t libxfs_bmbt_get_blockcount (xfs_bmbt_rec_t *); -extern xfs_fileoff_t libxfs_bmbt_get_startoff (xfs_bmbt_rec_t *); extern void libxfs_bmbt_get_all (xfs_bmbt_rec_t *, xfs_bmbt_irec_t *); +#if ARCH_CONVERT != ARCH_NOCONVERT +extern void libxfs_bmbt_disk_get_all (xfs_bmbt_rec_t *, xfs_bmbt_irec_t *); +#else +# define libxfs_bmbt_disk_get_all(r,s) libxfs_bmbt_get_all(r,s) +#endif extern int libxfs_free_extent (xfs_trans_t *, xfs_fsblock_t, xfs_extlen_t); extern int libxfs_rtfree_extent (xfs_trans_t *, xfs_rtblock_t, diff --git a/include/xfs_bmap_btree.h b/include/xfs_bmap_btree.h index b29f6d978..ffa9eb0ec 100644 --- a/include/xfs_bmap_btree.h +++ b/include/xfs_bmap_btree.h @@ -509,6 +509,41 @@ xfs_exntst_t xfs_bmbt_get_state( xfs_bmbt_rec_t *r); +#if ARCH_CONVERT != ARCH_NOCONVERT +void +xfs_bmbt_disk_get_all( + xfs_bmbt_rec_t *r, + xfs_bmbt_irec_t *s); + +xfs_exntst_t +xfs_bmbt_disk_get_state( + xfs_bmbt_rec_t *r); + +xfs_filblks_t +xfs_bmbt_disk_get_blockcount( + xfs_bmbt_rec_t *r); + +xfs_fsblock_t +xfs_bmbt_disk_get_startblock( + xfs_bmbt_rec_t *r); + +xfs_fileoff_t +xfs_bmbt_disk_get_startoff( + xfs_bmbt_rec_t *r); + +#else +#define xfs_bmbt_disk_get_all(r, s) \ + xfs_bmbt_get_all(r, s) +#define xfs_bmbt_disk_get_state(r) \ + xfs_bmbt_get_state(r) +#define xfs_bmbt_disk_get_blockcount(r) \ + xfs_bmbt_get_blockcount(r) +#define xfs_bmbt_disk_get_startblock(r) \ + xfs_bmbt_get_blockcount(r) +#define xfs_bmbt_disk_get_startoff(r) \ + xfs_bmbt_get_startoff(r) +#endif + int xfs_bmbt_increment( struct xfs_btree_cur *, @@ -607,6 +642,26 @@ xfs_bmbt_set_state( xfs_bmbt_rec_t *r, xfs_exntst_t v); +#if ARCH_CONVERT != ARCH_NOCONVERT +void +xfs_bmbt_disk_set_all( + xfs_bmbt_rec_t *r, + xfs_bmbt_irec_t *s); + +void +xfs_bmbt_disk_set_allf( + xfs_bmbt_rec_t *r, + xfs_fileoff_t o, + xfs_fsblock_t b, + xfs_filblks_t c, + xfs_exntst_t v); +#else +#define xfs_bmbt_disk_set_all(r, s) \ + xfs_bmbt_set_all(r, s) +#define xfs_bmbt_disk_set_allf(r, o, b, c, v) \ + xfs_bmbt_set_allf(r, o, b, c, v) +#endif + void xfs_bmbt_to_bmdr( xfs_bmbt_block_t *, diff --git a/include/xfs_inode.h b/include/xfs_inode.h index ea739492d..8e55d407b 100644 --- a/include/xfs_inode.h +++ b/include/xfs_inode.h @@ -416,11 +416,9 @@ void xfs_ifork_next_set(xfs_inode_t *ip, int w, int n); * max file offset is 2^(31+PAGE_SHIFT) - 1 (due to linux page cache) * * NOTE: XFS itself can handle 2^63 - 1 (largest positive value of xfs_fsize_t) - * but Linux can't go above 2^(31+PAGE_SHIFT)-1: the Linux VM uses a 32 bit - * signed variable to index cache data, so 2^31 * PAGE_SIZE is as big as - * you can go. + * but this is the Linux limit. */ -#define XFS_MAX_FILE_OFFSET ((long long)((1ULL<<(31+PAGE_SHIFT))-1ULL)) +#define XFS_MAX_FILE_OFFSET MAX_LFS_FILESIZE #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ITOV) struct vnode *xfs_itov(xfs_inode_t *ip); @@ -520,7 +518,7 @@ void xfs_iext_realloc(xfs_inode_t *, int, int); void xfs_iroot_realloc(xfs_inode_t *, int, int); void xfs_ipin(xfs_inode_t *); void xfs_iunpin(xfs_inode_t *); -int xfs_iextents_copy(xfs_inode_t *, xfs_bmbt_rec_32_t *, int); +int xfs_iextents_copy(xfs_inode_t *, xfs_bmbt_rec_t *, int); int xfs_iflush(xfs_inode_t *, uint); int xfs_iflush_all(struct xfs_mount *, int); int xfs_ibusy_check(xfs_inode_t *, int); @@ -532,8 +530,6 @@ void xfs_lock_inodes(xfs_inode_t **, int, int, uint); #define xfs_ipincount(ip) ((unsigned int) atomic_read(&ip->i_pincount)) -void xfs_revalidate_inode(struct xfs_mount *, vnode_t *vp, xfs_inode_t *); - #ifdef DEBUG void xfs_isize_check(struct xfs_mount *, xfs_inode_t *, xfs_fsize_t); #else /* DEBUG */ diff --git a/include/xfs_inode_item.h b/include/xfs_inode_item.h index d90407088..c893dbfc9 100644 --- a/include/xfs_inode_item.h +++ b/include/xfs_inode_item.h @@ -126,7 +126,7 @@ typedef struct xfs_inode_log_format_v1 { #ifdef __KERNEL__ struct xfs_buf; -struct xfs_bmbt_rec_32; +struct xfs_bmbt_rec_64; struct xfs_inode; struct xfs_mount; @@ -141,7 +141,10 @@ typedef struct xfs_inode_log_item { unsigned short ili_flags; /* misc flags */ unsigned short ili_logged; /* flushed logged data */ unsigned int ili_last_fields; /* fields when flushed */ - struct xfs_bmbt_rec_32 *ili_extents_buf; /* array of logged exts */ + struct xfs_bmbt_rec_64 *ili_extents_buf; /* array of logged + data exts */ + struct xfs_bmbt_rec_64 *ili_aextents_buf; /* array of logged + attr exts */ unsigned int ili_pushbuf_flag; /* one bit used in push_ail */ #ifdef DEBUG diff --git a/include/xfs_log_priv.h b/include/xfs_log_priv.h index 9bdce316d..77c02ef65 100644 --- a/include/xfs_log_priv.h +++ b/include/xfs_log_priv.h @@ -422,6 +422,7 @@ typedef struct xlog_rec_ext_header { */ typedef struct xlog_iclog_fields { sv_t ic_forcesema; + sv_t ic_writesema; struct xlog_in_core *ic_next; struct xlog_in_core *ic_prev; struct xfs_buf *ic_bp; @@ -438,7 +439,6 @@ typedef struct xlog_iclog_fields { int ic_bwritecnt; ushort_t ic_state; char *ic_datap; /* pointer to iclog data */ - struct tq_struct ic_write_sched; } xlog_iclog_fields_t; typedef struct xlog_in_core2 { @@ -458,7 +458,7 @@ typedef struct xlog_in_core { * Defines to save our code from this glop. */ #define ic_forcesema hic_fields.ic_forcesema -#define ic_write_sched hic_fields.ic_write_sched +#define ic_writesema hic_fields.ic_writesema #define ic_next hic_fields.ic_next #define ic_prev hic_fields.ic_prev #define ic_bp hic_fields.ic_bp diff --git a/include/xfs_mount.h b/include/xfs_mount.h index 51e672e1e..27c53f7a0 100644 --- a/include/xfs_mount.h +++ b/include/xfs_mount.h @@ -87,41 +87,60 @@ struct xfs_bmap_free; #define AIL_LOCK(mp,s) s=mutex_spinlock(&(mp)->m_ail_lock) #define AIL_UNLOCK(mp,s) mutex_spinunlock(&(mp)->m_ail_lock, s) - -/* Prototypes and functions for I/O core modularization, a vector - * of functions is used to indirect from xfs/cxfs independent code - * to the xfs/cxfs dependent code. - * The vector is placed in the mount structure so that we can - * minimize the number of memory indirections involved. +/* + * Prototypes and functions for I/O core modularization. */ + +struct flid; +struct buf; +typedef int (*xfs_ioinit_t)(struct vfs *, + struct xfs_mount_args *, int *); typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *, xfs_fileoff_t, xfs_filblks_t, int, xfs_fsblock_t *, xfs_extlen_t, struct xfs_bmbt_irec *, int *, struct xfs_bmap_free *); typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *); +typedef int (*xfs_iomap_write_direct_t)( + void *, loff_t, size_t, int, + struct xfs_bmbt_irec *, int *, int); +typedef int (*xfs_iomap_write_delay_t)( + void *, loff_t, size_t, int, + struct xfs_bmbt_irec *, int *); +typedef int (*xfs_iomap_write_allocate_t)( + void *, struct xfs_bmbt_irec *, int *); +typedef int (*xfs_iomap_write_unwritten_t)( + void *, loff_t, size_t); +typedef uint (*xfs_lck_map_shared_t)(void *); typedef void (*xfs_lock_t)(void *, uint); typedef void (*xfs_lock_demote_t)(void *, uint); typedef int (*xfs_lock_nowait_t)(void *, uint); typedef void (*xfs_unlk_t)(void *, unsigned int); -typedef void (*xfs_chgtime_t)(void *, int); typedef xfs_fsize_t (*xfs_size_t)(void *); -typedef xfs_fsize_t (*xfs_lastbyte_t)(void *); +typedef xfs_fsize_t (*xfs_iodone_t)(struct vfs *); typedef struct xfs_ioops { - xfs_bmapi_t xfs_bmapi_func; - xfs_bmap_eof_t xfs_bmap_eof_func; - xfs_lock_t xfs_ilock; - xfs_lock_demote_t xfs_ilock_demote; - xfs_lock_nowait_t xfs_ilock_nowait; - xfs_unlk_t xfs_unlock; - xfs_chgtime_t xfs_chgtime; - xfs_size_t xfs_size_func; - xfs_lastbyte_t xfs_lastbyte; + xfs_ioinit_t xfs_ioinit; + xfs_bmapi_t xfs_bmapi_func; + xfs_bmap_eof_t xfs_bmap_eof_func; + xfs_iomap_write_direct_t xfs_iomap_write_direct; + xfs_iomap_write_delay_t xfs_iomap_write_delay; + xfs_iomap_write_allocate_t xfs_iomap_write_allocate; + xfs_iomap_write_unwritten_t xfs_iomap_write_unwritten; + xfs_lock_t xfs_ilock; + xfs_lck_map_shared_t xfs_lck_map_shared; + xfs_lock_demote_t xfs_ilock_demote; + xfs_lock_nowait_t xfs_ilock_nowait; + xfs_unlk_t xfs_unlock; + xfs_size_t xfs_size_func; + xfs_iodone_t xfs_iodone; } xfs_ioops_t; +#define XFS_IOINIT(vfsp, args, flags) \ + (*(mp)->m_io_ops.xfs_ioinit)(vfsp, args, flags) + #define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist) \ (*(mp)->m_io_ops.xfs_bmapi_func) \ (trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist) @@ -130,9 +149,31 @@ typedef struct xfs_ioops { (*(mp)->m_io_ops.xfs_bmap_eof_func) \ ((io)->io_obj, endoff, whichfork, eof) +#define XFS_IOMAP_WRITE_DIRECT(mp, io, offset, count, flags, mval, nmap, found)\ + (*(mp)->m_io_ops.xfs_iomap_write_direct) \ + ((io)->io_obj, offset, count, flags, mval, nmap, found) + +#define XFS_IOMAP_WRITE_DELAY(mp, io, offset, count, flags, mval, nmap) \ + (*(mp)->m_io_ops.xfs_iomap_write_delay) \ + ((io)->io_obj, offset, count, flags, mval, nmap) + +#define XFS_IOMAP_WRITE_ALLOCATE(mp, io, mval, nmap) \ + (*(mp)->m_io_ops.xfs_iomap_write_allocate) \ + ((io)->io_obj, mval, nmap) + +#define XFS_IOMAP_WRITE_UNWRITTEN(mp, io, offset, count) \ + (*(mp)->m_io_ops.xfs_iomap_write_unwritten) \ + ((io)->io_obj, offset, count) + +#define XFS_LCK_MAP_SHARED(mp, io) \ + (*(mp)->m_io_ops.xfs_lck_map_shared)((io)->io_obj) + #define XFS_ILOCK(mp, io, mode) \ (*(mp)->m_io_ops.xfs_ilock)((io)->io_obj, mode) +#define XFS_ILOCK_NOWAIT(mp, io, mode) \ + (*(mp)->m_io_ops.xfs_ilock_nowait)((io)->io_obj, mode) + #define XFS_IUNLOCK(mp, io, mode) \ (*(mp)->m_io_ops.xfs_unlock)((io)->io_obj, mode) @@ -142,8 +183,13 @@ typedef struct xfs_ioops { #define XFS_SIZE(mp, io) \ (*(mp)->m_io_ops.xfs_size_func)((io)->io_obj) -#define XFS_LASTBYTE(mp, io) \ - (*(mp)->m_io_ops.xfs_lastbyte)((io)->io_obj) +#define XFS_IODONE(vfsp) \ + (*(mp)->m_io_ops.xfs_iodone)(vfsp) + + +/* + * Prototypes and functions for the XFS realtime subsystem. + */ typedef struct xfs_mount { @@ -268,7 +314,7 @@ typedef struct xfs_mount { #if XFS_BIG_FILESYSTEMS #define XFS_MOUNT_INO64 0x00000002 #endif -#define XFS_MOUNT_ROOTQCHECK 0x00000004 + /* 0x00000004 -- currently unused */ /* 0x00000008 -- currently unused */ #define XFS_MOUNT_FS_SHUTDOWN 0x00000010 /* atomic stop of all filesystem operations, typically for @@ -305,8 +351,8 @@ typedef struct xfs_mount { /* * Default minimum read and write sizes. */ -#define XFS_READIO_LOG_LARGE 12 -#define XFS_WRITEIO_LOG_LARGE 12 +#define XFS_READIO_LOG_LARGE 16 +#define XFS_WRITEIO_LOG_LARGE 16 /* * Default allocation size */ @@ -422,7 +468,7 @@ int xfs_unmountfs_writesb(xfs_mount_t *); int xfs_unmount_flush(xfs_mount_t *, int); int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int, int); int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *, uint, int); -int xfs_readsb(xfs_mount_t *mp, unsigned int, int, int); +int xfs_readsb(xfs_mount_t *mp); struct xfs_buf *xfs_getsb(xfs_mount_t *, int); void xfs_freesb(xfs_mount_t *); void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int); @@ -430,11 +476,6 @@ int xfs_syncsub(xfs_mount_t *, int, int, int *); void xfs_initialize_perag(xfs_mount_t *, int); void xfs_xlatesb(void *, struct xfs_sb *, int, xfs_arch_t, __int64_t); -int xfs_blkdev_get(const char *, struct block_device **); -void xfs_blkdev_put(struct block_device *); -struct xfs_buftarg *xfs_alloc_buftarg(struct block_device *); -void xfs_free_buftarg(struct xfs_buftarg *); - /* * Flags for freeze operations. */ diff --git a/libxfs/xfs.h b/libxfs/xfs.h index 74418ddfd..39fa846c8 100644 --- a/libxfs/xfs.h +++ b/libxfs/xfs.h @@ -67,22 +67,21 @@ #define xfs_xlatesb libxfs_xlate_sb #define xfs_xlate_dinode_core libxfs_xlate_dinode_core -#define xfs_bmbt_get_all libxfs_bmbt_get_all -#define xfs_bmbt_get_blockcount libxfs_bmbt_get_blockcount -#define xfs_bmbt_get_startoff libxfs_bmbt_get_startoff -#define xfs_da_hashname libxfs_da_hashname -#define xfs_da_log2_roundup libxfs_da_log2_roundup -#define xfs_highbit32 libxfs_highbit32 -#define xfs_highbit64 libxfs_highbit64 -#define xfs_attr_leaf_newentsize libxfs_attr_leaf_newentsize -#define xfs_alloc_compute_maxlevels libxfs_alloc_compute_maxlevels -#define xfs_bmap_compute_maxlevels libxfs_bmap_compute_maxlevels -#define xfs_ialloc_compute_maxlevels libxfs_ialloc_compute_maxlevels +#define xfs_bmbt_get_all libxfs_bmbt_get_all +#define xfs_bmbt_disk_get_all libxfs_bmbt_disk_get_all +#define xfs_da_hashname libxfs_da_hashname +#define xfs_da_log2_roundup libxfs_da_log2_roundup +#define xfs_highbit32 libxfs_highbit32 +#define xfs_highbit64 libxfs_highbit64 +#define xfs_attr_leaf_newentsize libxfs_attr_leaf_newentsize +#define xfs_alloc_compute_maxlevels libxfs_alloc_compute_maxlevels +#define xfs_bmap_compute_maxlevels libxfs_bmap_compute_maxlevels +#define xfs_ialloc_compute_maxlevels libxfs_ialloc_compute_maxlevels #define xfs_dir_init libxfs_dir_init #define xfs_dir2_init libxfs_dir2_init -#define xfs_dir_mount libxfs_dir_mount -#define xfs_dir2_mount libxfs_dir2_mount +#define xfs_dir_mount libxfs_dir_mount +#define xfs_dir2_mount libxfs_dir2_mount #define xfs_dir_createname libxfs_dir_createname #define xfs_dir2_createname libxfs_dir2_createname #define xfs_dir_lookup libxfs_dir_lookup @@ -94,9 +93,9 @@ #define xfs_dir_bogus_removename libxfs_dir_bogus_removename #define xfs_dir2_bogus_removename libxfs_dir2_bogus_removename -#define xfs_mount_common libxfs_mount_common -#define xfs_initialize_perag libxfs_initialize_perag -#define xfs_rtmount_init libxfs_rtmount_init +#define xfs_mount_common libxfs_mount_common +#define xfs_initialize_perag libxfs_initialize_perag +#define xfs_rtmount_init libxfs_rtmount_init #define xfs_alloc_fix_freelist libxfs_alloc_fix_freelist #define xfs_iread libxfs_iread #define xfs_ialloc libxfs_ialloc @@ -112,7 +111,7 @@ #define xfs_mod_sb libxfs_mod_sb #define xfs_mod_incore_sb libxfs_mod_incore_sb -#define xfs_trans_init libxfs_trans_init +#define xfs_trans_init libxfs_trans_init #define xfs_trans_dup libxfs_trans_dup #define xfs_trans_iget libxfs_trans_iget #define xfs_trans_ijoin libxfs_trans_ijoin @@ -168,7 +167,7 @@ #define xfs_baread(a,b,c) ((void) 0) /* no readahead */ #define xfs_buftrace(x,y) ((void) 0) /* debug only */ #define xfs_buf_item_log_debug(bip,a,b) ((void) 0) /* debug only */ -#define xfs_validate_extents(e,n,f) ((void) 0) /* debug only */ +#define xfs_validate_extents(e,n,d,f) ((void) 0) /* debug only */ #define xfs_buf_relse(bp) libxfs_putbuf(bp) #define xfs_read_buf(mp,devp,blkno,len,f,bpp) \ ( *(bpp) = libxfs_readbuf( *(dev_t*)devp, (blkno), (len), 1), 0 ) @@ -373,7 +372,7 @@ int xfs_ialloc (xfs_trans_t *, xfs_inode_t *, mode_t, nlink_t, dev_t, cred_t *, xfs_prid_t, int, xfs_buf_t **, boolean_t *, xfs_inode_t **); int xfs_iread_extents (xfs_trans_t *, xfs_inode_t *, int); int xfs_imap (xfs_mount_t *, xfs_trans_t *, xfs_ino_t, xfs_imap_t *, uint); -int xfs_iextents_copy (xfs_inode_t *, xfs_bmbt_rec_32_t *, int); +int xfs_iextents_copy (xfs_inode_t *, xfs_bmbt_rec_t *, int); int xfs_iflush_int (xfs_inode_t *, xfs_buf_t *); int xfs_iflush_fork (xfs_inode_t *, xfs_dinode_t *, xfs_inode_log_item_t *, int, xfs_buf_t *); diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c index 3ccb367c3..c2ff3a7ef 100644 --- a/libxfs/xfs_alloc.c +++ b/libxfs/xfs_alloc.c @@ -2056,19 +2056,6 @@ xfs_alloc_put_freelist( (int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl), (int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl + sizeof(xfs_agblock_t) - 1)); - /* - * Since blocks move to the free list without the coordination - * used in xfs_bmap_finish, we can't allow block to be available - * for reallocation and non-transaction writing (user data) - * until we know that the transaction that moved it to the free - * list is permanently on disk. We track the blocks by declaring - * these blocks as "busy"; the busy list is maintained on a per-ag - * basis and each transaction records which entries should be removed - * when the iclog commits to disk. If a busy block is allocated, - * the iclog is pushed up to the LSN that freed the block. - */ - xfs_alloc_mark_busy(tp, INT_GET(agf->agf_seqno, ARCH_CONVERT), bno, 1); - return 0; } diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c index 88dcdb5f4..53751ca04 100644 --- a/libxfs/xfs_alloc_btree.c +++ b/libxfs/xfs_alloc_btree.c @@ -204,6 +204,23 @@ xfs_alloc_delrec( if ((error = xfs_alloc_put_freelist(cur->bc_tp, cur->bc_private.a.agbp, NULL, bno))) return error; + /* + * Since blocks move to the free list without the + * coordination used in xfs_bmap_finish, we can't allow + * block to be available for reallocation and + * non-transaction writing (user data) until we know + * that the transaction that moved it to the free list + * is permanently on disk. We track the blocks by + * declaring these blocks as "busy"; the busy list is + * maintained on a per-ag basis and each transaction + * records which entries should be removed when the + * iclog commits to disk. If a busy block is + * allocated, the iclog is pushed up to the LSN + * that freed the block. + */ + xfs_alloc_mark_busy(cur->bc_tp, + INT_GET(agf->agf_seqno, ARCH_CONVERT), bno, 1); + xfs_trans_agbtree_delta(cur->bc_tp, -1); xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS); @@ -509,6 +526,21 @@ xfs_alloc_delrec( if ((error = xfs_alloc_put_freelist(cur->bc_tp, cur->bc_private.a.agbp, NULL, rbno))) return error; + /* + * Since blocks move to the free list without the coordination + * used in xfs_bmap_finish, we can't allow block to be available + * for reallocation and non-transaction writing (user data) + * until we know that the transaction that moved it to the free + * list is permanently on disk. We track the blocks by declaring + * these blocks as "busy"; the busy list is maintained on a + * per-ag basis and each transaction records which entries + * should be removed when the iclog commits to disk. If a + * busy block is allocated, the iclog is pushed up to the + * LSN that freed the block. + */ + xfs_alloc_mark_busy(cur->bc_tp, + INT_GET(agf->agf_seqno, ARCH_CONVERT), bno, 1); + xfs_trans_agbtree_delta(cur->bc_tp, -1); /* * Adjust the current level's cursor so that we're left referring diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c index e7384d258..1f0af7274 100644 --- a/libxfs/xfs_bmap.c +++ b/libxfs/xfs_bmap.c @@ -2705,7 +2705,7 @@ xfs_bmap_extents_to_btree( xfs_btree_cur_t *cur; /* bmap btree cursor */ xfs_bmbt_rec_t *ep; /* extent list pointer */ int error; /* error return value */ - xfs_extnum_t i; /* extent list index */ + xfs_extnum_t i, cnt; /* extent list index */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_bmbt_key_t *kp; /* root block key pointer */ xfs_mount_t *mp; /* mount structure */ @@ -2787,24 +2787,25 @@ xfs_bmap_extents_to_btree( ablock = XFS_BUF_TO_BMBT_BLOCK(abp); INT_SET(ablock->bb_magic, ARCH_CONVERT, XFS_BMAP_MAGIC); INT_ZERO(ablock->bb_level, ARCH_CONVERT); - INT_ZERO(ablock->bb_numrecs, ARCH_CONVERT); INT_SET(ablock->bb_leftsib, ARCH_CONVERT, NULLDFSBNO); INT_SET(ablock->bb_rightsib, ARCH_CONVERT, NULLDFSBNO); arp = XFS_BMAP_REC_IADDR(ablock, 1, cur); nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); - for (ep = ifp->if_u1.if_extents, i = 0; i < nextents; i++, ep++) { + for (ep = ifp->if_u1.if_extents, cnt = i = 0; i < nextents; i++, ep++) { if (!ISNULLSTARTBLOCK(xfs_bmbt_get_startblock(ep))) { - *arp++ = *ep; - INT_MOD(ablock->bb_numrecs, ARCH_CONVERT, +1); + arp->l0 = INT_GET(ep->l0, ARCH_CONVERT); + arp->l1 = INT_GET(ep->l1, ARCH_CONVERT); + arp++; cnt++; } } + INT_SET(ablock->bb_numrecs, ARCH_CONVERT, cnt); ASSERT(INT_GET(ablock->bb_numrecs, ARCH_CONVERT) == XFS_IFORK_NEXTENTS(ip, whichfork)); /* * Fill in the root key and pointer. */ kp = XFS_BMAP_KEY_IADDR(block, 1, cur); arp = XFS_BMAP_REC_IADDR(ablock, 1, cur); - INT_SET(kp->br_startoff, ARCH_CONVERT, xfs_bmbt_get_startoff(arp)); + INT_SET(kp->br_startoff, ARCH_CONVERT, xfs_bmbt_disk_get_startoff(arp)); pp = XFS_BMAP_PTR_IADDR(block, 1, cur); INT_SET(*pp, ARCH_CONVERT, args.fsbno); /* @@ -3383,7 +3384,7 @@ xfs_bmap_read_extents( #ifdef XFS_BMAP_TRACE static char fname[] = "xfs_bmap_read_extents"; #endif - xfs_extnum_t i; /* index into the extents list */ + xfs_extnum_t i, j; /* index into the extents list */ xfs_ifork_t *ifp; /* fork structure */ int level; /* btree level, for checking */ xfs_mount_t *mp; /* file system mount structure */ @@ -3440,7 +3441,7 @@ xfs_bmap_read_extents( * Loop over all leaf nodes. Copy information to the extent list. */ for (;;) { - xfs_bmbt_rec_t *frp; + xfs_bmbt_rec_t *frp, *temp; xfs_fsblock_t nextbno; xfs_extnum_t num_recs; @@ -3468,18 +3469,21 @@ xfs_bmap_read_extents( */ frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, 1, mp->m_bmap_dmxr[0]); - memcpy(trp, frp, num_recs * sizeof(*frp)); + temp = trp; + for (j = 0; j < num_recs; j++, frp++, trp++) { + trp->l0 = INT_GET(frp->l0, ARCH_CONVERT); + trp->l1 = INT_GET(frp->l1, ARCH_CONVERT); + } if (exntf == XFS_EXTFMT_NOSTATE) { /* * Check all attribute bmap btree records and * any "older" data bmap btree records for a * set bit in the "extent flag" position. */ - if (xfs_check_nostate_extents(trp, num_recs)) { + if (xfs_check_nostate_extents(temp, num_recs)) { goto error0; } } - trp += num_recs; i += num_recs; xfs_trans_brelse(tp, bp); bno = nextbno; diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c index fd9b46270..dee3e5579 100644 --- a/libxfs/xfs_bmap_btree.c +++ b/libxfs/xfs_bmap_btree.c @@ -127,7 +127,7 @@ xfs_bmbt_delrec( xfs_bmbt_log_recs(cur, bp, ptr, numrecs - 1); } if (ptr == 1) { - INT_SET(key.br_startoff, ARCH_CONVERT, xfs_bmbt_get_startoff(rp)); + INT_SET(key.br_startoff, ARCH_CONVERT, xfs_bmbt_disk_get_startoff(rp)); kp = &key; } } @@ -447,7 +447,8 @@ xfs_bmbt_insrec( XFS_BMBT_TRACE_CURSOR(cur, ENTRY); XFS_BMBT_TRACE_ARGIFR(cur, level, *bnop, recp); ncur = (xfs_btree_cur_t *)0; - INT_SET(key.br_startoff, ARCH_CONVERT, xfs_bmbt_get_startoff(recp)); + INT_SET(key.br_startoff, ARCH_CONVERT, + xfs_bmbt_disk_get_startoff(recp)); optr = ptr = cur->bc_ptrs[level]; if (ptr == 0) { XFS_BMBT_TRACE_CURSOR(cur, EXIT); @@ -525,7 +526,7 @@ xfs_bmbt_insrec( } #endif ptr = cur->bc_ptrs[level]; - xfs_bmbt_set_allf(&nrec, + xfs_bmbt_disk_set_allf(&nrec, nkey.br_startoff, 0, 0, XFS_EXT_NORM); } else { @@ -865,7 +866,7 @@ xfs_bmbt_lookup( startoff = INT_GET(kkp->br_startoff, ARCH_CONVERT); } else { krp = krbase + keyno - 1; - startoff = xfs_bmbt_get_startoff(krp); + startoff = xfs_bmbt_disk_get_startoff(krp); } diff = (xfs_sfiloff_t) (startoff - rp->br_startoff); @@ -1046,7 +1047,8 @@ xfs_bmbt_lshift( } else { memmove(rrp, rrp + 1, rrecs * sizeof(*rrp)); xfs_bmbt_log_recs(cur, rbp, 1, rrecs); - INT_SET(key.br_startoff, ARCH_CONVERT, xfs_bmbt_get_startoff(rrp)); + INT_SET(key.br_startoff, ARCH_CONVERT, + xfs_bmbt_disk_get_startoff(rrp)); rkp = &key; } if ((error = xfs_bmbt_updkey(cur, rkp, level + 1))) { @@ -1160,7 +1162,8 @@ xfs_bmbt_rshift( memmove(rrp + 1, rrp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rrp)); *rrp = *lrp; xfs_bmbt_log_recs(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT) + 1); - INT_SET(key.br_startoff, ARCH_CONVERT, xfs_bmbt_get_startoff(rrp)); + INT_SET(key.br_startoff, ARCH_CONVERT, + xfs_bmbt_disk_get_startoff(rrp)); rkp = &key; } INT_MOD(left->bb_numrecs, ARCH_CONVERT, -1); @@ -1329,7 +1332,7 @@ xfs_bmbt_split( rrp = XFS_BMAP_REC_IADDR(right, 1, cur); memcpy(rrp, lrp, INT_GET(right->bb_numrecs, ARCH_CONVERT) * sizeof(*rrp)); xfs_bmbt_log_recs(cur, rbp, 1, INT_GET(right->bb_numrecs, ARCH_CONVERT)); - keyp->br_startoff = xfs_bmbt_get_startoff(rrp); + keyp->br_startoff = xfs_bmbt_disk_get_startoff(rrp); } INT_MOD(left->bb_numrecs, ARCH_CONVERT, -(INT_GET(right->bb_numrecs, ARCH_CONVERT))); right->bb_rightsib = left->bb_rightsib; /* INT_: direct copy */ @@ -1563,17 +1566,15 @@ xfs_bmbt_delete( * This code must be in sync with the routines xfs_bmbt_get_startoff, * xfs_bmbt_get_startblock, xfs_bmbt_get_blockcount and xfs_bmbt_get_state. */ -void -xfs_bmbt_get_all( - xfs_bmbt_rec_t *r, - xfs_bmbt_irec_t *s) +STATIC __inline__ void +__xfs_bmbt_get_all( + __uint64_t l0, + __uint64_t l1, + xfs_bmbt_irec_t *s) { int ext_flag; xfs_exntst_t st; - __uint64_t l0, l1; - l0 = INT_GET(r->l0, ARCH_CONVERT); - l1 = INT_GET(r->l1, ARCH_CONVERT); ext_flag = (int)(l0 >> (64 - BMBT_EXNTFLAG_BITLEN)); s->br_startoff = ((xfs_fileoff_t)l0 & XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; @@ -1604,6 +1605,14 @@ xfs_bmbt_get_all( s->br_state = st; } +void +xfs_bmbt_get_all( + xfs_bmbt_rec_t *r, + xfs_bmbt_irec_t *s) +{ + __xfs_bmbt_get_all(r->l0, r->l1, s); +} + /* * Get the block pointer for the given level of the cursor. * Fill in the buffer pointer, if applicable. @@ -1636,7 +1645,7 @@ xfs_filblks_t xfs_bmbt_get_blockcount( xfs_bmbt_rec_t *r) { - return (xfs_filblks_t)(INT_GET(r->l1, ARCH_CONVERT) & XFS_MASK64LO(21)); + return (xfs_filblks_t)(r->l1 & XFS_MASK64LO(21)); } /* @@ -1646,6 +1655,77 @@ xfs_fsblock_t xfs_bmbt_get_startblock( xfs_bmbt_rec_t *r) { +#if XFS_BIG_FILESYSTEMS + return (((xfs_fsblock_t)r->l0 & XFS_MASK64LO(9)) << 43) | + (((xfs_fsblock_t)r->l1) >> 21); +#else +#ifdef DEBUG + xfs_dfsbno_t b; + + b = (((xfs_dfsbno_t)r->l0 & XFS_MASK64LO(9)) << 43) | + (((xfs_dfsbno_t)r->l1) >> 21); + ASSERT((b >> 32) == 0 || ISNULLDSTARTBLOCK(b)); + return (xfs_fsblock_t)b; +#else /* !DEBUG */ + return (xfs_fsblock_t)(((xfs_dfsbno_t)r->l1) >> 21); +#endif /* DEBUG */ +#endif /* XFS_BIG_FILESYSTEMS */ +} + +/* + * Extract the startoff field from a bmap extent record. + */ +xfs_fileoff_t +xfs_bmbt_get_startoff( + xfs_bmbt_rec_t *r) +{ + return ((xfs_fileoff_t)r->l0 & + XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; +} + +xfs_exntst_t +xfs_bmbt_get_state( + xfs_bmbt_rec_t *r) +{ + int ext_flag; + + ext_flag = (int)((r->l0) >> (64 - BMBT_EXNTFLAG_BITLEN)); + return xfs_extent_state(xfs_bmbt_get_blockcount(r), + ext_flag); +} + +#if ARCH_CONVERT != ARCH_NOCONVERT +/* Endian flipping versions of the bmbt extraction functions */ +void +xfs_bmbt_disk_get_all( + xfs_bmbt_rec_t *r, + xfs_bmbt_irec_t *s) +{ + __uint64_t l0, l1; + + l0 = INT_GET(r->l0, ARCH_CONVERT); + l1 = INT_GET(r->l1, ARCH_CONVERT); + + __xfs_bmbt_get_all(l0, l1, s); +} + +/* + * Extract the blockcount field from an on disk bmap extent record. + */ +xfs_filblks_t +xfs_bmbt_disk_get_blockcount( + xfs_bmbt_rec_t *r) +{ + return (xfs_filblks_t)(INT_GET(r->l1, ARCH_CONVERT) & XFS_MASK64LO(21)); +} + +/* + * Extract the startblock field from an on disk bmap extent record. + */ +xfs_fsblock_t +xfs_bmbt_disk_get_startblock( + xfs_bmbt_rec_t *r) +{ #if XFS_BIG_FILESYSTEMS return (((xfs_fsblock_t)INT_GET(r->l0, ARCH_CONVERT) & XFS_MASK64LO(9)) << 43) | (((xfs_fsblock_t)INT_GET(r->l1, ARCH_CONVERT)) >> 21); @@ -1664,10 +1744,10 @@ xfs_bmbt_get_startblock( } /* - * Extract the startoff field from a bmap extent record. + * Extract the startoff field from a disk format bmap extent record. */ xfs_fileoff_t -xfs_bmbt_get_startoff( +xfs_bmbt_disk_get_startoff( xfs_bmbt_rec_t *r) { return ((xfs_fileoff_t)INT_GET(r->l0, ARCH_CONVERT) & @@ -1675,16 +1755,16 @@ xfs_bmbt_get_startoff( } xfs_exntst_t -xfs_bmbt_get_state( +xfs_bmbt_disk_get_state( xfs_bmbt_rec_t *r) { int ext_flag; ext_flag = (int)((INT_GET(r->l0, ARCH_CONVERT)) >> (64 - BMBT_EXNTFLAG_BITLEN)); - return xfs_extent_state(xfs_bmbt_get_blockcount(r), + return xfs_extent_state(xfs_bmbt_disk_get_blockcount(r), ext_flag); } - +#endif /* * Increment cursor by one record at the level. @@ -1792,7 +1872,7 @@ xfs_bmbt_insert( XFS_BMBT_TRACE_CURSOR(cur, ENTRY); level = 0; nbno = NULLFSBLOCK; - xfs_bmbt_set_all(&nrec, &cur->bc_rec.b); + xfs_bmbt_disk_set_all(&nrec, &cur->bc_rec.b); ncur = (xfs_btree_cur_t *)0; pcur = cur; do { @@ -2076,6 +2156,97 @@ xfs_bmbt_set_all( #if XFS_BIG_FILESYSTEMS ASSERT((s->br_startblock & XFS_MASK64HI(12)) == 0); #endif /* XFS_BIG_FILESYSTEMS */ +#if XFS_BIG_FILESYSTEMS + r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | + ((xfs_bmbt_rec_base_t)s->br_startoff << 9) | + ((xfs_bmbt_rec_base_t)s->br_startblock >> 43); + r->l1 = ((xfs_bmbt_rec_base_t)s->br_startblock << 21) | + ((xfs_bmbt_rec_base_t)s->br_blockcount & + (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); +#else /* !XFS_BIG_FILESYSTEMS */ + if (ISNULLSTARTBLOCK(s->br_startblock)) { + r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | + ((xfs_bmbt_rec_base_t)s->br_startoff << 9) | + (xfs_bmbt_rec_base_t)XFS_MASK64LO(9); + r->l1 = XFS_MASK64HI(11) | + ((xfs_bmbt_rec_base_t)s->br_startblock << 21) | + ((xfs_bmbt_rec_base_t)s->br_blockcount & + (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); + } else { + r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | + ((xfs_bmbt_rec_base_t)s->br_startoff << 9); + r->l1 = ((xfs_bmbt_rec_base_t)s->br_startblock << 21) | + ((xfs_bmbt_rec_base_t)s->br_blockcount & + (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); + } +#endif /* XFS_BIG_FILESYSTEMS */ +} + +/* + * Set all the fields in a bmap extent record from the arguments. + */ +void +xfs_bmbt_set_allf( + xfs_bmbt_rec_t *r, + xfs_fileoff_t o, + xfs_fsblock_t b, + xfs_filblks_t c, + xfs_exntst_t v) +{ + int extent_flag; + + ASSERT((v == XFS_EXT_NORM) || (v == XFS_EXT_UNWRITTEN)); + extent_flag = (v == XFS_EXT_NORM) ? 0 : 1; + ASSERT((o & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0); + ASSERT((c & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); +#if XFS_BIG_FILESYSTEMS + ASSERT((b & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0); +#endif /* XFS_BIG_FILESYSTEMS */ +#if XFS_BIG_FILESYSTEMS + r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | + ((xfs_bmbt_rec_base_t)o << 9) | + ((xfs_bmbt_rec_base_t)b >> 43); + r->l1 = ((xfs_bmbt_rec_base_t)b << 21) | + ((xfs_bmbt_rec_base_t)c & + (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); +#else /* !XFS_BIG_FILESYSTEMS */ + if (ISNULLSTARTBLOCK(b)) { + r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | + ((xfs_bmbt_rec_base_t)o << 9) | + (xfs_bmbt_rec_base_t)XFS_MASK64LO(9); + r->l1 = XFS_MASK64HI(11) | + ((xfs_bmbt_rec_base_t)b << 21) | + ((xfs_bmbt_rec_base_t)c & + (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); + } else { + r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | + ((xfs_bmbt_rec_base_t)o << 9); + r->l1 = ((xfs_bmbt_rec_base_t)b << 21) | + ((xfs_bmbt_rec_base_t)c & + (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); + } +#endif /* XFS_BIG_FILESYSTEMS */ +} + +#if ARCH_CONVERT != ARCH_NOCONVERT +/* + * Set all the fields in a bmap extent record from the uncompressed form. + */ +void +xfs_bmbt_disk_set_all( + xfs_bmbt_rec_t *r, + xfs_bmbt_irec_t *s) +{ + int extent_flag; + + ASSERT((s->br_state == XFS_EXT_NORM) || + (s->br_state == XFS_EXT_UNWRITTEN)); + extent_flag = (s->br_state == XFS_EXT_NORM) ? 0 : 1; + ASSERT((s->br_startoff & XFS_MASK64HI(9)) == 0); + ASSERT((s->br_blockcount & XFS_MASK64HI(43)) == 0); +#if XFS_BIG_FILESYSTEMS + ASSERT((s->br_startblock & XFS_MASK64HI(12)) == 0); +#endif /* XFS_BIG_FILESYSTEMS */ #if XFS_BIG_FILESYSTEMS INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) | ((xfs_bmbt_rec_base_t)s->br_startoff << 9) | @@ -2103,10 +2274,10 @@ xfs_bmbt_set_all( } /* - * Set all the fields in a bmap extent record from the arguments. + * Set all the fields in a disk format bmap extent record from the arguments. */ void -xfs_bmbt_set_allf( +xfs_bmbt_disk_set_allf( xfs_bmbt_rec_t *r, xfs_fileoff_t o, xfs_fsblock_t b, @@ -2147,6 +2318,7 @@ xfs_bmbt_set_allf( } #endif /* XFS_BIG_FILESYSTEMS */ } +#endif /* * Set the blockcount field in a bmap extent record. @@ -2157,8 +2329,8 @@ xfs_bmbt_set_blockcount( xfs_filblks_t v) { ASSERT((v & XFS_MASK64HI(43)) == 0); - INT_SET(r->l1, ARCH_CONVERT, (INT_GET(r->l1, ARCH_CONVERT) & (xfs_bmbt_rec_base_t)XFS_MASK64HI(43)) | - (xfs_bmbt_rec_base_t)(v & XFS_MASK64LO(21))); + r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64HI(43)) | + (xfs_bmbt_rec_base_t)(v & XFS_MASK64LO(21)); } /* @@ -2173,20 +2345,20 @@ xfs_bmbt_set_startblock( ASSERT((v & XFS_MASK64HI(12)) == 0); #endif /* XFS_BIG_FILESYSTEMS */ #if XFS_BIG_FILESYSTEMS - INT_SET(r->l0, ARCH_CONVERT, (INT_GET(r->l0, ARCH_CONVERT) & (xfs_bmbt_rec_base_t)XFS_MASK64HI(55)) | - (xfs_bmbt_rec_base_t)(v >> 43)); - INT_SET(r->l1, ARCH_CONVERT, (INT_GET(r->l1, ARCH_CONVERT) & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)) | - (xfs_bmbt_rec_base_t)(v << 21)); + r->l0 = (r->l0 & (xfs_bmbt_rec_base_t)XFS_MASK64HI(55)) | + (xfs_bmbt_rec_base_t)(v >> 43); + r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)) | + (xfs_bmbt_rec_base_t)(v << 21); #else /* !XFS_BIG_FILESYSTEMS */ if (ISNULLSTARTBLOCK(v)) { - INT_SET(r->l0, ARCH_CONVERT, (INT_GET(r->l0, ARCH_CONVERT) | (xfs_bmbt_rec_base_t)XFS_MASK64LO(9))); - INT_SET(r->l1, ARCH_CONVERT, (xfs_bmbt_rec_base_t)XFS_MASK64HI(11) | + r->l0 |= (xfs_bmbt_rec_base_t)XFS_MASK64LO(9); + r->l1 = (xfs_bmbt_rec_base_t)XFS_MASK64HI(11) | ((xfs_bmbt_rec_base_t)v << 21) | - (INT_GET(r->l1, ARCH_CONVERT) & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); + (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); } else { - INT_SET(r->l0, ARCH_CONVERT, (INT_GET(r->l0, ARCH_CONVERT) & ~(xfs_bmbt_rec_base_t)XFS_MASK64LO(9))); - INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)v << 21) | - (INT_GET(r->l1, ARCH_CONVERT) & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); + r->l0 &= ~(xfs_bmbt_rec_base_t)XFS_MASK64LO(9); + r->l1 = ((xfs_bmbt_rec_base_t)v << 21) | + (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); } #endif /* XFS_BIG_FILESYSTEMS */ } @@ -2200,9 +2372,9 @@ xfs_bmbt_set_startoff( xfs_fileoff_t v) { ASSERT((v & XFS_MASK64HI(9)) == 0); - INT_SET(r->l0, ARCH_CONVERT, (INT_GET(r->l0, ARCH_CONVERT) & (xfs_bmbt_rec_base_t) XFS_MASK64HI(1)) | + r->l0 = (r->l0 & (xfs_bmbt_rec_base_t) XFS_MASK64HI(1)) | ((xfs_bmbt_rec_base_t)v << 9) | - (INT_GET(r->l0, ARCH_CONVERT) & (xfs_bmbt_rec_base_t)XFS_MASK64LO(9))); + (r->l0 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(9)); } /* @@ -2215,9 +2387,9 @@ xfs_bmbt_set_state( { ASSERT(v == XFS_EXT_NORM || v == XFS_EXT_UNWRITTEN); if (v == XFS_EXT_NORM) - INT_SET(r->l0, ARCH_CONVERT, INT_GET(r->l0, ARCH_CONVERT) & XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)); + r->l0 &= XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN); else - INT_SET(r->l0, ARCH_CONVERT, INT_GET(r->l0, ARCH_CONVERT) | XFS_MASK64HI(BMBT_EXNTFLAG_BITLEN)); + r->l0 |= XFS_MASK64HI(BMBT_EXNTFLAG_BITLEN); } /* @@ -2285,7 +2457,7 @@ xfs_bmbt_update( #endif ptr = cur->bc_ptrs[0]; rp = XFS_BMAP_REC_IADDR(block, ptr, cur); - xfs_bmbt_set_allf(rp, off, bno, len, state); + xfs_bmbt_disk_set_allf(rp, off, bno, len, state); xfs_bmbt_log_recs(cur, bp, ptr, ptr); if (ptr > 1) { XFS_BMBT_TRACE_CURSOR(cur, EXIT); @@ -2313,7 +2485,7 @@ xfs_check_nostate_extents( xfs_extnum_t num) { for (; num > 0; num--, ep++) { - if (((INT_GET(ep->l0, ARCH_CONVERT)) >> + if ((ep->l0 >> (64 - BMBT_EXNTFLAG_BITLEN)) != 0) { ASSERT(0); return 1; diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c index 9402b7284..50f67bfd2 100644 --- a/libxfs/xfs_btree.c +++ b/libxfs/xfs_btree.c @@ -261,9 +261,9 @@ xfs_btree_check_rec( r1 = ar1; r2 = ar2; - ASSERT(xfs_bmbt_get_startoff(r1) + - xfs_bmbt_get_blockcount(r1) <= - xfs_bmbt_get_startoff(r2)); + ASSERT(xfs_bmbt_disk_get_startoff(r1) + + xfs_bmbt_disk_get_blockcount(r1) <= + xfs_bmbt_disk_get_startoff(r2)); break; } case XFS_BTNUM_INO: { diff --git a/libxfs/xfs_inode.c b/libxfs/xfs_inode.c index fcf7ca8ac..602849cfb 100644 --- a/libxfs/xfs_inode.c +++ b/libxfs/xfs_inode.c @@ -419,6 +419,10 @@ xfs_iformat_extents( int nex; int real_size; int size; +#if ARCH_CONVERT != ARCH_NOCONVERT + int i; +#endif + xfs_bmbt_rec_t *ep, *dp; ifp = XFS_IFORK_PTR(ip, whichfork); nex = XFS_DFORK_NEXTENTS_ARCH(dip, whichfork, ARCH_CONVERT); @@ -451,10 +455,18 @@ xfs_iformat_extents( ifp->if_real_bytes = real_size; if (size) { xfs_validate_extents( - (xfs_bmbt_rec_32_t *)XFS_DFORK_PTR_ARCH(dip, whichfork, ARCH_CONVERT), - nex, XFS_EXTFMT_INODE(ip)); - memcpy(ifp->if_u1.if_extents, - XFS_DFORK_PTR_ARCH(dip, whichfork, ARCH_CONVERT), size); + (xfs_bmbt_rec_t *)XFS_DFORK_PTR_ARCH(dip, whichfork, ARCH_CONVERT), + nex, 1, XFS_EXTFMT_INODE(ip)); + dp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR_ARCH(dip, whichfork, ARCH_CONVERT); + ep = ifp->if_u1.if_extents; +#if ARCH_CONVERT != ARCH_NOCONVERT + for (i = 0; i < nex; i++, ep++, dp++) { + ep->l0 = INT_GET(dp->l0, ARCH_CONVERT); + ep->l1 = INT_GET(dp->l1, ARCH_CONVERT); + } +#else + memcpy(ep, dp, size); +#endif xfs_bmap_trace_exlist("xfs_iformat_extents", ip, nex, whichfork); if (whichfork != XFS_DATA_FORK || @@ -797,8 +809,8 @@ xfs_iread_extents( ifp->if_flags &= ~XFS_IFEXTENTS; return error; } - xfs_validate_extents((xfs_bmbt_rec_32_t *)ifp->if_u1.if_extents, - XFS_IFORK_NEXTENTS(ip, whichfork), XFS_EXTFMT_INODE(ip)); + xfs_validate_extents((xfs_bmbt_rec_t *)ifp->if_u1.if_extents, + XFS_IFORK_NEXTENTS(ip, whichfork), 0, XFS_EXTFMT_INODE(ip)); return 0; } @@ -1233,11 +1245,11 @@ xfs_iroundup( int xfs_iextents_copy( xfs_inode_t *ip, - xfs_bmbt_rec_32_t *buffer, + xfs_bmbt_rec_t *buffer, int whichfork) { int copied; - xfs_bmbt_rec_32_t *dest_ep; + xfs_bmbt_rec_t *dest_ep; xfs_bmbt_rec_t *ep; #ifdef XFS_BMAP_TRACE static char fname[] = "xfs_iextents_copy"; @@ -1254,28 +1266,13 @@ xfs_iextents_copy( nrecs = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); xfs_bmap_trace_exlist(fname, ip, nrecs, whichfork); ASSERT(nrecs > 0); - if (nrecs == XFS_IFORK_NEXTENTS(ip, whichfork)) { - /* - * There are no delayed allocation extents, - * so just copy everything. - */ - ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); - ASSERT(ifp->if_bytes == - (XFS_IFORK_NEXTENTS(ip, whichfork) * - (uint)sizeof(xfs_bmbt_rec_t))); - memcpy(buffer, ifp->if_u1.if_extents, ifp->if_bytes); - xfs_validate_extents(buffer, nrecs, XFS_EXTFMT_INODE(ip)); - return ifp->if_bytes; - } - ASSERT(whichfork == XFS_DATA_FORK); /* * There are some delayed allocation extents in the * inode, so copy the extents one at a time and skip * the delayed ones. There must be at least one * non-delayed extent. */ - ASSERT(nrecs > ip->i_d.di_nextents); ep = ifp->if_u1.if_extents; dest_ep = buffer; copied = 0; @@ -1289,15 +1286,19 @@ xfs_iextents_copy( continue; } - *dest_ep = *(xfs_bmbt_rec_32_t *)ep; +#if ARCH_CONVERT != ARCH_NOCONVERT + /* Translate to on disk format */ + dest_ep->l0 = INT_GET(ep->l0, ARCH_CONVERT); + dest_ep->l1 = INT_GET(ep->l1, ARCH_CONVERT); +#else + *dest_ep = *ep; +#endif dest_ep++; ep++; copied++; } ASSERT(copied != 0); - ASSERT(copied == ip->i_d.di_nextents); - ASSERT((copied * (uint)sizeof(xfs_bmbt_rec_t)) <= XFS_IFORK_DSIZE(ip)); - xfs_validate_extents(buffer, copied, XFS_EXTFMT_INODE(ip)); + xfs_validate_extents(buffer, copied, 1, XFS_EXTFMT_INODE(ip)); return (copied * (uint)sizeof(xfs_bmbt_rec_t)); } @@ -1369,7 +1370,7 @@ xfs_iflush_fork( if ((iip->ili_format.ilf_fields & extflag[whichfork]) && (ifp->if_bytes > 0)) { ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0); - (void)xfs_iextents_copy(ip, (xfs_bmbt_rec_32_t *)cp, + (void)xfs_iextents_copy(ip, (xfs_bmbt_rec_t *)cp, whichfork); } break; diff --git a/repair/dinode.c b/repair/dinode.c index 91fd917a9..e3a483c01 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -447,7 +447,7 @@ convert_extent( memcpy(&rpcopy, rp, sizeof(rpcopy)); /* Just use the extent parsing routine from the kernel */ - libxfs_bmbt_get_all(p, s); + libxfs_bmbt_disk_get_all(p, s); if (fs_has_extflgbit) { if (s->br_state == XFS_EXT_UNWRITTEN) { -- 2.47.2