#ifdef __KERNEL__
+#if defined(XFS_ALLOC_TRACE)
+/*
+ * Allocation tracing buffer size.
+ */
+#define XFS_ALLOC_TRACE_SIZE 4096
+extern ktrace_t *xfs_alloc_trace_buf;
+
/*
* Types for alloc tracing.
*/
#define XFS_ALLOC_KTRACE_BUSY 4
#define XFS_ALLOC_KTRACE_UNBUSY 5
#define XFS_ALLOC_KTRACE_BUSYSEARCH 6
-
-
-/*
- * Allocation tracing buffer size.
- */
-#define XFS_ALLOC_TRACE_SIZE 4096
-
-#ifdef XFS_ALL_TRACE
-#define XFS_ALLOC_TRACE
-#endif
-
-#if !defined(DEBUG)
-#undef XFS_ALLOC_TRACE
#endif
-/*
- * Prototypes for visible xfs_alloc.c routines
- */
-
/*
* Compute and fill in value of m_ag_maxlevels.
*/
#define ARCH_NOCONVERT 1
#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define ARCH_CONVERT 0
+# define ARCH_CONVERT 0
#else
-#define ARCH_CONVERT ARCH_NOCONVERT
+# define ARCH_CONVERT ARCH_NOCONVERT
#endif
/* generic swapping macros */
+#ifndef HAVE_SWABMACROS
#define INT_SWAP16(type,var) ((typeof(type))(__swab16((__u16)(var))))
#define INT_SWAP32(type,var) ((typeof(type))(__swab32((__u32)(var))))
#define INT_SWAP64(type,var) ((typeof(type))(__swab64((__u64)(var))))
+#endif
#define INT_SWAP(type, var) \
((sizeof(type) == 8) ? INT_SWAP64(type,var) : \
(INT_GET(((xfs_attr_shortform_t *)((dp)->i_afp->if_u1.if_data))->hdr.totsize, ARCH_CONVERT))
#endif
-#ifdef XFS_ALL_TRACE
-#define XFS_ATTR_TRACE
-#endif
-
-#if !defined(DEBUG)
-#undef XFS_ATTR_TRACE
-#endif
-
+#if defined(XFS_ATTR_TRACE)
/*
* Kernel tracing support for attribute lists
*/
struct xfs_attr_leafblock;
#define XFS_ATTR_TRACE_SIZE 4096 /* size of global trace buffer */
+extern ktrace_t *xfs_attr_trace_buf;
/*
* Trace record types.
#define XFS_ATTR_KTRACE_L_CB 3 /* context, btree */
#define XFS_ATTR_KTRACE_L_CL 4 /* context, leaf */
-#if defined(XFS_ATTR_TRACE)
-
void xfs_attr_trace_l_c(char *where, struct xfs_attr_list_context *context);
void xfs_attr_trace_l_cn(char *where, struct xfs_attr_list_context *context,
struct xfs_da_intnode *node);
#define DELAYSTARTBLOCK ((xfs_fsblock_t)-1LL)
#define HOLESTARTBLOCK ((xfs_fsblock_t)-2LL)
-/*
- * Trace operations for bmap extent tracing
- */
-#define XFS_BMAP_KTRACE_DELETE 1
-#define XFS_BMAP_KTRACE_INSERT 2
-#define XFS_BMAP_KTRACE_PRE_UP 3
-#define XFS_BMAP_KTRACE_POST_UP 4
-
-#define XFS_BMAP_TRACE_SIZE 4096 /* size of global trace buffer */
-#define XFS_BMAP_KTRACE_SIZE 32 /* size of per-inode trace buffer */
-
-#if defined(XFS_ALL_TRACE)
-#define XFS_BMAP_TRACE
-#endif
-
-#if !defined(DEBUG)
-#undef XFS_BMAP_TRACE
-#endif
-
-
#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BMAP_INIT)
void xfs_bmap_init(xfs_bmap_free_t *flp, xfs_fsblock_t *fbp);
#define XFS_BMAP_INIT(flp,fbp) xfs_bmap_init(flp,fbp)
} xfs_bmalloca_t;
#ifdef __KERNEL__
+
+#if defined(XFS_BMAP_TRACE)
+/*
+ * Trace operations for bmap extent tracing
+ */
+#define XFS_BMAP_KTRACE_DELETE 1
+#define XFS_BMAP_KTRACE_INSERT 2
+#define XFS_BMAP_KTRACE_PRE_UP 3
+#define XFS_BMAP_KTRACE_POST_UP 4
+
+#define XFS_BMAP_TRACE_SIZE 4096 /* size of global trace buffer */
+#define XFS_BMAP_KTRACE_SIZE 32 /* size of per-inode trace buffer */
+extern ktrace_t *xfs_bmap_trace_buf;
+
+/*
+ * Add bmap trace insert entries for all the contents of the extent list.
+ */
+void
+xfs_bmap_trace_exlist(
+ char *fname, /* function name */
+ struct xfs_inode *ip, /* incore inode pointer */
+ xfs_extnum_t cnt, /* count of entries in list */
+ int whichfork); /* data or attr fork */
+#else
+#define xfs_bmap_trace_exlist(f,ip,c,w)
+#endif
+
/*
* Convert inode from non-attributed to attributed.
* Must not be in a transaction, ip must not be locked.
struct xfs_inode *ip, /* incore inode */
int whichfork); /* data or attr fork */
-#if defined(XFS_BMAP_TRACE)
-/*
- * Add bmap trace insert entries for all the contents of the extent list.
- */
-void
-xfs_bmap_trace_exlist(
- char *fname, /* function name */
- struct xfs_inode *ip, /* incore inode pointer */
- xfs_extnum_t cnt, /* count of entries in list */
- int whichfork); /* data or attr fork */
-#else
-#define xfs_bmap_trace_exlist(f,ip,c,w)
-#endif
-
/*
* Map file blocks to filesystem blocks.
* File range is given by the bno/len pair.
int
xfs_bmap_count_blocks(
xfs_trans_t *tp,
- xfs_inode_t *ip,
+ struct xfs_inode *ip,
int whichfork,
int *count);
INT_GET((bb)->bb_numrecs, ARCH_CONVERT) <= (mp)->m_bmap_dmxr[(level) != 0])
#endif
+
+#ifdef __KERNEL__
+
+#if defined(XFS_BMBT_TRACE)
/*
* Trace buffer entry types.
*/
#define XFS_BMBT_TRACE_SIZE 4096 /* size of global trace buffer */
#define XFS_BMBT_KTRACE_SIZE 32 /* size of per-inode trace buffer */
-
-#if defined(XFS_ALL_TRACE)
-#define XFS_BMBT_TRACE
+extern ktrace_t *xfs_bmbt_trace_buf;
#endif
-#if !defined(DEBUG)
-#undef XFS_BMBT_TRACE
-#endif
-
-
-#ifdef __KERNEL__
-
/*
* Prototypes for xfs_bmap.c to call.
*/
#define XFS_BLI_STALE 0x04
#define XFS_BLI_LOGGED 0x08
#define XFS_BLI_INODE_ALLOC_BUF 0x10
+#define XFS_BLI_STALE_INODE 0x20
#ifdef __KERNEL__
struct xfs_buf;
struct ktrace;
struct xfs_mount;
+struct xfs_buf_log_item;
+
+#if defined(XFS_BLI_TRACE)
+#define XFS_BLI_TRACE_SIZE 32
+
+void xfs_buf_item_trace(char *, struct xfs_buf_log_item *);
+#else
+#define xfs_buf_item_trace(id, bip)
+#endif
/*
* This is the in core log item structure used to track information
unsigned int bli_flags; /* misc flags */
unsigned int bli_recur; /* lock recursion count */
atomic_t bli_refcount; /* cnt of tp refs */
-#ifdef DEBUG
+#ifdef XFS_BLI_TRACE
struct ktrace *bli_trace; /* event trace buf */
#endif
#ifdef XFS_TRANS_DEBUG
* items which have been canceled and should not be replayed.
*/
typedef struct xfs_buf_cancel {
- xfs_daddr_t bc_blkno;
+ xfs_daddr_t bc_blkno;
uint bc_len;
int bc_refcount;
struct xfs_buf_cancel *bc_next;
} xfs_buf_cancel_t;
-#define XFS_BLI_TRACE_SIZE 32
-
-
-#if defined(XFS_ALL_TRACE)
-#define XFS_BLI_TRACE
-#endif
-
-#if !defined(DEBUG)
-#undef XFS_BLI_TRACE
-#endif
-
-#if defined(XFS_BLI_TRACE)
-void xfs_buf_item_trace(char *, xfs_buf_log_item_t *);
-#else
-#define xfs_buf_item_trace(id, bip)
-#endif
-
void xfs_buf_item_init(struct xfs_buf *, struct xfs_mount *);
void xfs_buf_item_relse(struct xfs_buf *);
void xfs_buf_item_log(xfs_buf_log_item_t *, uint, uint);
inst_t *ra; /* return address of caller to make */
struct xfs_dabuf *next; /* next in global chain */
struct xfs_dabuf *prev; /* previous in global chain */
- dev_t dev; /* device for buffer */
+ struct xfs_buftarg *target; /* device for buffer */
xfs_daddr_t blkno; /* daddr first in bps[0] */
#endif
struct xfs_buf *bps[1]; /* actually nbuf of these */
* as possible so as to fit into the literal area of the inode.
*/
-#ifdef XFS_ALL_TRACE
-#define XFS_DIR_TRACE
-#endif
-
-#if !defined(DEBUG)
-#undef XFS_DIR_TRACE
-#endif
-
/*========================================================================
* Function prototypes for the kernel.
*========================================================================*/
((uint)sizeof(xfs_dir_sf_entry_t)-1)*(count) + (totallen))
#endif
-#ifdef XFS_ALL_TRACE
-#define XFS_DIR_TRACE
-#endif
-
-#if !defined(DEBUG)
-#undef XFS_DIR_TRACE
-#endif
+#if defined(XFS_DIR_TRACE)
/*
* Kernel tracing support for directories.
struct xfs_dir_leaf_entry;
#define XFS_DIR_TRACE_SIZE 4096 /* size of global trace buffer */
+extern ktrace_t *xfs_dir_trace_buf;
/*
* Trace record types.
#define XFS_DIR_KTRACE_G_DUE 5 /* dp, uio, leaf entry */
#define XFS_DIR_KTRACE_G_DUC 6 /* dp, uio, cookie */
-#if defined(XFS_DIR_TRACE)
-
void xfs_dir_trace_g_du(char *where, struct xfs_inode *dp, struct uio *uio);
void xfs_dir_trace_g_dub(char *where, struct xfs_inode *dp, struct uio *uio,
xfs_dablk_t bno);
void xfs_dir_trace_g_duc(char *where, struct xfs_inode *dp, struct uio *uio,
xfs_off_t cookie);
void xfs_dir_trace_enter(int type, char *where,
- __psunsigned_t a0, __psunsigned_t a1,
- __psunsigned_t a2, __psunsigned_t a3,
- __psunsigned_t a4, __psunsigned_t a5,
- __psunsigned_t a6, __psunsigned_t a7,
- __psunsigned_t a8, __psunsigned_t a9,
- __psunsigned_t a10, __psunsigned_t a11);
+ void *a0, void *a1, void *a2, void *a3,
+ void *a4, void *a5, void *a6, void *a7,
+ void *a8, void *a9, void *a10, void *a11);
#else
#define xfs_dir_trace_g_du(w,d,u)
#define xfs_dir_trace_g_dub(w,d,u,b)
} xfs_fsop_attrmulti_handlereq_t;
/*
- * File system identifier. Should be unique (at least per machine).
+ * per machine unique filesystem identifier types.
*/
-typedef struct {
- __u32 val[2]; /* file system id type */
-} xfs_fsid_t;
+typedef struct { __u32 val[2]; } xfs_fsid_t; /* file system id type */
+
-/*
- * File identifier. Should be unique per filesystem on a single machine.
- * This is typically called by a stateless file server in order to generate
- * "file handles".
- */
#ifndef HAVE_FID
#define MAXFIDSZ 46
+
typedef struct fid {
__u16 fid_len; /* length of data in bytes */
- unsigned char fid_data[MAXFIDSZ]; /* data (variable length) */
+ unsigned char fid_data[MAXFIDSZ]; /* data (fid_len worth) */
} fid_t;
#endif
int /* error */
xfs_difree(
struct xfs_trans *tp, /* transaction pointer */
- xfs_ino_t inode); /* inode to be freed */
+ xfs_ino_t inode, /* inode to be freed */
+ struct xfs_bmap_free *flist, /* extents to free */
+ int *delete, /* set if inode cluster was deleted */
+ xfs_ino_t *first_ino); /* first inode in deleted cluster */
/*
* Return the location of the inode in bno/len/off,
int level, /* level in btree, 0 is leaf */
int *stat); /* success/failure */
-#ifdef _NOTYET_
/*
* Delete the record pointed to by cur.
* The cursor refers to the place where the record was (could be inserted)
xfs_inobt_delete(
struct xfs_btree_cur *cur, /* btree cursor */
int *stat); /* success/failure */
-#endif /* _NOTYET_ */
/*
* Get the data from the pointed-to record.
struct xfs_trans;
struct xfs_dquot;
+#if defined(XFS_ILOCK_TRACE)
+#define XFS_ILOCK_KTRACE_SIZE 32
+extern ktrace_t *xfs_ilock_trace_buf;
+extern void xfs_ilock_trace(struct xfs_inode *, int, unsigned int, inst_t *);
+#else
+#define xfs_ilock_trace(i,n,f,ra)
+#endif
/*
* This structure is used to communicate which extents of a file
sema_t i_flock; /* inode flush lock */
atomic_t i_pincount; /* inode pin count */
wait_queue_head_t i_ipin_wait; /* inode pinning wait queue */
+#ifdef HAVE_REFCACHE
struct xfs_inode **i_refcache; /* ptr to entry in ref cache */
struct xfs_inode *i_release; /* inode to unref */
-
+#endif
/* I/O state */
xfs_iocore_t i_iocore; /* I/O core */
struct xfs_inode *i_cnext; /* cluster hash link forward */
struct xfs_inode *i_cprev; /* cluster hash link backward */
-#ifdef DEBUG
/* Trace buffers per inode. */
+#ifdef XFS_BMAP_TRACE
struct ktrace *i_xtrace; /* inode extent list trace */
+#endif
+#ifdef XFS_BMBT_TRACE
struct ktrace *i_btrace; /* inode bmap btree trace */
+#endif
+#ifdef XFS_RW_TRACE
struct ktrace *i_rwtrace; /* inode read/write trace */
- struct ktrace *i_strat_trace; /* inode strat_write trace */
+#endif
+#ifdef XFS_ILOCK_TRACE
struct ktrace *i_lock_trace; /* inode lock/unlock trace */
+#endif
+#ifdef XFS_DIR2_TRACE
struct ktrace *i_dir_trace; /* inode directory trace */
-#endif /* DEBUG */
+#endif
} xfs_inode_t;
#endif /* __KERNEL__ */
extern struct kmem_zone *xfs_ili_zone;
extern struct vnodeops xfs_vnodeops;
-#ifdef XFS_ILOCK_TRACE
-#define XFS_ILOCK_KTRACE_SIZE 32
-void xfs_ilock_trace(xfs_inode_t *ip, int lock, unsigned int lockflags,
- inst_t *ra);
-#endif
-
#endif /* __KERNEL__ */
#endif /* __XFS_INODE_H__ */
void xfs_inode_item_init(struct xfs_inode *, struct xfs_mount *);
void xfs_inode_item_destroy(struct xfs_inode *);
void xfs_iflush_done(struct xfs_buf *, xfs_inode_log_item_t *);
+void xfs_istale_done(struct xfs_buf *, xfs_inode_log_item_t *);
void xfs_iflush_abort(struct xfs_inode *);
#endif /* __KERNEL__ */
* endian issues in treating two 32 bit numbers as one 64 bit number
*/
static
-#if defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ == 95)
-__attribute__((unused)) /* gcc 2.95 miscompiles this when inlined */
+#if defined(__GNUC__) && (__GNUC__ == 2) && ( (__GNUC_MINOR__ == 95) || (__GNUC_MINOR__ == 96))
+__attribute__((unused)) /* gcc 2.95, 2.96 miscompile this when inlined */
#else
__inline__
#endif
int xfs_log_force(struct xfs_mount *mp,
xfs_lsn_t lsn,
uint flags);
-int xfs_log_mount(struct xfs_mount *mp,
- dev_t log_dev,
- xfs_daddr_t start_block,
- int num_bblocks);
+int xfs_log_mount(struct xfs_mount *mp,
+ struct xfs_buftarg *log_target,
+ xfs_daddr_t start_block,
+ int num_bblocks);
int xfs_log_mount_finish(struct xfs_mount *mp, int);
void xfs_log_move_tail(struct xfs_mount *mp,
xfs_lsn_t tail_lsn);
#ifndef __XFS_LOG_PRIV_H__
#define __XFS_LOG_PRIV_H__
-#if defined(XFS_ALL_TRACE)
-#define XFS_LOG_TRACE
-#endif
-
-#if !defined(DEBUG)
-#undef XFS_LOG_TRACE
-#endif
-
struct xfs_buf;
struct ktrace;
struct log;
#ifdef __KERNEL__
+
/*
* get client id from packed copy.
*
struct log *ic_log;
xfs_log_callback_t *ic_callback;
xfs_log_callback_t **ic_callback_tail;
-#ifdef DEBUG
+#ifdef XFS_LOG_TRACE
struct ktrace *ic_trace;
#endif
int ic_size;
struct xfs_mount *l_mp; /* mount point */
struct xfs_buf *l_xbuf; /* extra buffer for log
* wrapping */
- dev_t l_dev; /* dev_t of log */
+ struct xfs_buftarg *l_targ; /* buftarg of log */
xfs_daddr_t l_logBBstart; /* start block of log */
int l_logsize; /* size of log in bytes */
int l_logBBsize; /* size of log in BB chunks */
int l_grant_write_bytes;
/* The following fields don't need locking */
-#ifdef DEBUG
+#ifdef XFS_LOG_TRACE
struct ktrace *l_trace;
struct ktrace *l_grant_trace;
#endif
* Prototypes and functions for the Data Migration subsystem.
*/
-typedef int (*xfs_send_data_t)(int, struct bhv_desc *,
+typedef int (*xfs_send_data_t)(int, struct vnode *,
xfs_off_t, size_t, int, vrwlock_t *);
typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint);
-typedef int (*xfs_send_destroy_t)(struct bhv_desc *, dm_right_t);
+typedef int (*xfs_send_destroy_t)(struct vnode *, dm_right_t);
typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct vnode *,
dm_right_t, struct vnode *, dm_right_t,
char *, char *, mode_t, int, int);
xfs_send_unmount_t xfs_send_unmount;
} xfs_dmops_t;
-#define XFS_SEND_DATA(mp, ev,bdp,off,len,fl,lock) \
- (*(mp)->m_dm_ops.xfs_send_data)(ev,bdp,off,len,fl,lock)
+#define XFS_SEND_DATA(mp, ev,vp,off,len,fl,lock) \
+ (*(mp)->m_dm_ops.xfs_send_data)(ev,vp,off,len,fl,lock)
#define XFS_SEND_MMAP(mp, vma,fl) \
(*(mp)->m_dm_ops.xfs_send_mmap)(vma,fl)
-#define XFS_SEND_DESTROY(mp, bdp,right) \
- (*(mp)->m_dm_ops.xfs_send_destroy)(bdp,right)
+#define XFS_SEND_DESTROY(mp, vp,right) \
+ (*(mp)->m_dm_ops.xfs_send_destroy)(vp,right)
#define XFS_SEND_NAMESP(mp, ev,b1,r1,b2,r2,n1,n2,mode,rval,fl) \
(*(mp)->m_dm_ops.xfs_send_namesp)(ev,b1,r1,b2,r2,n1,n2,mode,rval,fl)
#define XFS_SEND_UNMOUNT(mp, vfsp,vp,right,mode,rval,fl) \
#define XFS_MOUNT_32BITINOOPT 0x00008000 /* saved mount option state */
#define XFS_MOUNT_NOUUID 0x00010000 /* ignore uuid during mount */
#define XFS_MOUNT_NOLOGFLUSH 0x00020000
+#define XFS_MOUNT_IDELETE 0x00040000 /* delete empty inode clusters*/
/*
* Default minimum read and write sizes.
* the agi hash list and counters: sector size
* the inode btree entry: block size
* the on disk inode before ours in the agi hash list: inode cluster size
+ * the inode btree: max depth * blocksize
+ * the allocation btrees: 2 trees * (max depth - 1) * block size
*/
#define XFS_CALC_IFREE_LOG_RES(mp) \
((mp)->m_sb.sb_inodesize + \
(mp)->m_sb.sb_sectsize + \
XFS_FSB_TO_B((mp), 1) + \
MAX((__uint16_t)XFS_FSB_TO_B((mp), 1), XFS_INODE_CLUSTER_SIZE(mp)) + \
- (128 * 5))
+ (128 * 5) + \
+ (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \
+ XFS_ALLOCFREE_LOG_COUNT(mp, 1))))
+
#define XFS_IFREE_LOG_RES(mp) ((mp)->m_reservations.tr_ifree)
#define XFS_DEFAULT_LOG_COUNT 1
#define XFS_DEFAULT_PERM_LOG_COUNT 2
#define XFS_ITRUNCATE_LOG_COUNT 2
+#define XFS_INACTIVE_LOG_COUNT 2
#define XFS_CREATE_LOG_COUNT 2
#define XFS_MKDIR_LOG_COUNT 3
#define XFS_SYMLINK_LOG_COUNT 3
void xfs_trans_bhold_until_committed(xfs_trans_t *, struct xfs_buf *);
void xfs_trans_binval(xfs_trans_t *, struct xfs_buf *);
void xfs_trans_inode_buf(xfs_trans_t *, struct xfs_buf *);
+void xfs_trans_inode_buf(xfs_trans_t *, struct xfs_buf *);
+void xfs_trans_stale_inode_buf(xfs_trans_t *, struct xfs_buf *);
void xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint);
void xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *);
int xfs_trans_iget(struct xfs_mount *, xfs_trans_t *,
xfs_ino_t , uint, struct xfs_inode **);
-void xfs_trans_iput(xfs_trans_t *, struct xfs_inode *, uint);
void xfs_trans_ijoin(xfs_trans_t *, struct xfs_inode *, uint);
void xfs_trans_ihold(xfs_trans_t *, struct xfs_inode *);
void xfs_trans_ihold_release(xfs_trans_t *, struct xfs_inode *);
dabuf->dirty = 0;
#ifdef XFS_DABUF_DEBUG
dabuf->ra = ra;
- dabuf->dev = XFS_BUF_TARGET_DEV(bps[0]);
+ dabuf->target = XFS_BUF_TARGET(bps[0]);
dabuf->blkno = XFS_BUF_ADDR(bps[0]);
#endif
if (nbuf == 1) {
s = mutex_spinlock(&xfs_dabuf_global_lock);
for (p = xfs_dabuf_global_list; p; p = p->next) {
ASSERT(p->blkno != dabuf->blkno ||
- p->dev != dabuf->dev);
+ p->target != dabuf->target);
}
dabuf->prev = NULL;
if (xfs_dabuf_global_list)
xfs_dir2_db_t fbno; /* freespace block number */
xfs_dabuf_t *fbp; /* freespace buffer */
int findex; /* freespace entry index */
- xfs_dir2_db_t foundbno=0; /* found freespace block no */
- int foundindex=0; /* found freespace entry idx */
- int foundhole; /* found hole in freespace */
xfs_dir2_free_t *free=NULL; /* freespace block structure */
xfs_dir2_db_t ifbno; /* initial freespace block no */
xfs_dir2_db_t lastfbno=0; /* highest freespace block no */
xfs_mount_t *mp; /* filesystem mount point */
int needlog; /* need to log data header */
int needscan; /* need to rescan data frees */
- int needfreesp; /* need to allocate freesp blk */
xfs_dir2_data_off_t *tagp; /* data entry tag pointer */
xfs_trans_t *tp; /* transaction pointer */
mp = dp->i_mount;
tp = args->trans;
length = XFS_DIR2_DATA_ENTSIZE(args->namelen);
- foundhole = 0;
/*
* If we came in with a freespace block that means that lookup
* found an entry with our hash value. This is the freespace
return error;
lastfbno = XFS_DIR2_DA_TO_DB(mp, (xfs_dablk_t)fo);
fbno = ifbno;
- foundindex = -1;
}
/*
* While we haven't identified a data block, search the freeblock
return error;
}
if (unlikely(fbp == NULL)) {
- foundhole = 1;
continue;
}
free = fbp->data;
INT_GET(free->bests[findex], ARCH_CONVERT) >= length)
dbno = INT_GET(free->hdr.firstdb, ARCH_CONVERT) + findex;
else {
- /*
- * If we haven't found an empty entry yet, and this
- * one is empty, remember this slot.
- */
- if (foundindex == -1 &&
- INT_GET(free->bests[findex], ARCH_CONVERT) == NULLDATAOFF && !foundhole) {
- foundindex = findex;
- foundbno = fbno;
- }
/*
* Are we done with the freeblock?
*/
if (++findex == INT_GET(free->hdr.nvalid, ARCH_CONVERT)) {
- /*
- * If there is space left in this freeblock,
- * and we don't have an empty entry yet,
- * remember this slot.
- */
- if (foundindex == -1 &&
- findex < XFS_DIR2_MAX_FREE_BESTS(mp) &&
- !foundhole) {
- foundindex = findex;
- foundbno = fbno;
- }
/*
* Drop the block.
*/
/*
* Allocate and initialize the new data block.
*/
- if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE,
- &dbno)) ||
- (error = xfs_dir2_data_init(args, dbno, &dbp))) {
+ if (unlikely((error = xfs_dir2_grow_inode(args,
+ XFS_DIR2_DATA_SPACE,
+ &dbno)) ||
+ (error = xfs_dir2_data_init(args, dbno, &dbp)))) {
/*
* Drop the freespace buffer unless it came from our
* caller.
return error;
}
/*
- * If the freespace entry for this data block is not in the
- * freespace block we have in hand, drop the one we have
- * and get the right one.
+ * If (somehow) we have a freespace block, get rid of it.
*/
- needfreesp = 0;
- if (XFS_DIR2_DB_TO_FDB(mp, dbno) != fbno || fbp == NULL) {
- if (fbp)
- xfs_da_brelse(tp, fbp);
- if (fblk && fblk->bp)
- fblk->bp = NULL;
- fbno = XFS_DIR2_DB_TO_FDB(mp, dbno);
- if ((error = xfs_da_read_buf(tp, dp,
- XFS_DIR2_DB_TO_DA(mp, fbno), -2, &fbp,
- XFS_DATA_FORK))) {
- xfs_da_buf_done(dbp);
- return error;
- }
-
- /*
- * If there wasn't a freespace block, the read will
- * return a NULL fbp. Allocate one later.
- */
-
- if(unlikely( fbp == NULL )) {
- needfreesp = 1;
- } else {
- free = fbp->data;
- ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
- }
- }
+ if (fbp)
+ xfs_da_brelse(tp, fbp);
+ if (fblk && fblk->bp)
+ fblk->bp = NULL;
/*
- * If we don't have a data block, and there's no free slot in a
- * freeblock, we need to add a new freeblock.
+ * Get the freespace block corresponding to the data block
+ * that was just allocated.
*/
- if (unlikely(needfreesp || foundindex == -1)) {
- /*
- * Add the new freeblock.
- */
+ fbno = XFS_DIR2_DB_TO_FDB(mp, dbno);
+ if (unlikely(error = xfs_da_read_buf(tp, dp,
+ XFS_DIR2_DB_TO_DA(mp, fbno), -2, &fbp,
+ XFS_DATA_FORK))) {
+ xfs_da_buf_done(dbp);
+ return error;
+ }
+ /*
+ * If there wasn't a freespace block, the read will
+ * return a NULL fbp. Allocate and initialize a new one.
+ */
+ if( fbp == NULL ) {
if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE,
&fbno))) {
return error;
}
- if (XFS_DIR2_DB_TO_FDB(mp, dbno) != fbno) {
+ if (unlikely(XFS_DIR2_DB_TO_FDB(mp, dbno) != fbno)) {
cmn_err(CE_ALERT,
- "xfs_dir2_node_addname_int: needed block %lld, got %lld\n",
- (long long)XFS_DIR2_DB_TO_FDB(mp, dbno),
- (long long)fbno);
+ "xfs_dir2_node_addname_int: dir ino "
+ "%llu needed freesp block %lld for\n"
+ " data block %lld, got %lld\n"
+ " ifbno %llu lastfbno %d\n",
+ dp->i_ino,
+ XFS_DIR2_DB_TO_FDB(mp, dbno),
+ dbno, fbno,
+ ifbno, lastfbno);
+ if (fblk) {
+ cmn_err(CE_ALERT,
+ " fblk 0x%llu blkno %llu "
+ "index %d magic 0x%x\n",
+ fblk, fblk->blkno,
+ fblk->index,
+ fblk->magic);
+ } else {
+ cmn_err(CE_ALERT,
+ " ... fblk is NULL\n");
+ }
XFS_ERROR_REPORT("xfs_dir2_node_addname_int",
XFS_ERRLEVEL_LOW, mp);
return XFS_ERROR(EFSCORRUPTED);
XFS_DIR2_MAX_FREE_BESTS(mp));
INT_ZERO(free->hdr.nvalid, ARCH_CONVERT);
INT_ZERO(free->hdr.nused, ARCH_CONVERT);
- foundindex = 0;
- foundbno = fbno;
+ } else {
+ free = fbp->data;
+ ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
}
/*
xfs_btree_cur_t *ncur; /* new cursor to be used at next lvl */
xfs_inobt_key_t nkey; /* new key value, from split */
xfs_inobt_rec_t nrec; /* new record value, for caller */
+ int numrecs;
int optr; /* old ptr value */
xfs_inobt_ptr_t *pp; /* pointer to btree addresses */
int ptr; /* index in btree block for this rec */
*/
bp = cur->bc_bufs[level];
block = XFS_BUF_TO_INOBT_BLOCK(bp);
+ numrecs = INT_GET(block->bb_numrecs, ARCH_CONVERT);
#ifdef DEBUG
if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
return error;
/*
* Check that the new entry is being inserted in the right place.
*/
- if (ptr <= INT_GET(block->bb_numrecs, ARCH_CONVERT)) {
+ if (ptr <= numrecs) {
if (level == 0) {
rp = XFS_INOBT_REC_ADDR(block, ptr, cur);
xfs_btree_check_rec(cur->bc_btnum, recp, rp);
* If the block is full, we can't insert the new entry until we
* make the block un-full.
*/
- if (INT_GET(block->bb_numrecs, ARCH_CONVERT) == XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
+ if (numrecs == XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
/*
* First, try shifting an entry to the right neighbor.
*/
* At this point we know there's room for our new entry in the block
* we're pointing at.
*/
+ numrecs = INT_GET(block->bb_numrecs, ARCH_CONVERT);
if (level > 0) {
/*
* It's a non-leaf entry. Make a hole for the new data
kp = XFS_INOBT_KEY_ADDR(block, 1, cur);
pp = XFS_INOBT_PTR_ADDR(block, 1, cur);
#ifdef DEBUG
- for (i = INT_GET(block->bb_numrecs, ARCH_CONVERT); i >= ptr; i--) {
+ for (i = numrecs; i >= ptr; i--) {
if ((error = xfs_btree_check_sptr(cur, INT_GET(pp[i - 1], ARCH_CONVERT), level)))
return error;
}
#endif
memmove(&kp[ptr], &kp[ptr - 1],
- (INT_GET(block->bb_numrecs, ARCH_CONVERT) - ptr + 1) * sizeof(*kp));
+ (numrecs - ptr + 1) * sizeof(*kp));
memmove(&pp[ptr], &pp[ptr - 1],
- (INT_GET(block->bb_numrecs, ARCH_CONVERT) - ptr + 1) * sizeof(*pp));
+ (numrecs - ptr + 1) * sizeof(*pp));
/*
* Now stuff the new data in, bump numrecs and log the new data.
*/
#endif
kp[ptr - 1] = key; /* INT_: struct copy */
INT_SET(pp[ptr - 1], ARCH_CONVERT, *bnop);
- INT_MOD(block->bb_numrecs, ARCH_CONVERT, +1);
- xfs_inobt_log_keys(cur, bp, ptr, INT_GET(block->bb_numrecs, ARCH_CONVERT));
- xfs_inobt_log_ptrs(cur, bp, ptr, INT_GET(block->bb_numrecs, ARCH_CONVERT));
+ numrecs++;
+ INT_SET(block->bb_numrecs, ARCH_CONVERT, numrecs);
+ xfs_inobt_log_keys(cur, bp, ptr, numrecs);
+ xfs_inobt_log_ptrs(cur, bp, ptr, numrecs);
} else {
/*
* It's a leaf entry. Make a hole for the new record.
*/
rp = XFS_INOBT_REC_ADDR(block, 1, cur);
memmove(&rp[ptr], &rp[ptr - 1],
- (INT_GET(block->bb_numrecs, ARCH_CONVERT) - ptr + 1) * sizeof(*rp));
+ (numrecs - ptr + 1) * sizeof(*rp));
/*
* Now stuff the new record in, bump numrecs
* and log the new data.
*/
rp[ptr - 1] = *recp; /* INT_: struct copy */
- INT_MOD(block->bb_numrecs, ARCH_CONVERT, +1);
- xfs_inobt_log_recs(cur, bp, ptr, INT_GET(block->bb_numrecs, ARCH_CONVERT));
+ numrecs++;
+ INT_SET(block->bb_numrecs, ARCH_CONVERT, numrecs);
+ xfs_inobt_log_recs(cur, bp, ptr, numrecs);
}
/*
* Log the new number of records in the btree header.
/*
* Check that the key/record is in the right place, now.
*/
- if (ptr < INT_GET(block->bb_numrecs, ARCH_CONVERT)) {
+ if (ptr < numrecs) {
if (level == 0)
xfs_btree_check_rec(cur->bc_btnum, rp + ptr - 1,
rp + ptr);
xfs_agblock_t agbno; /* a.g. relative btree block number */
xfs_agnumber_t agno; /* allocation group number */
xfs_inobt_block_t *block=NULL; /* current btree block */
- int diff; /* difference for the current key */
+ __int64_t diff; /* difference for the current key */
int error; /* error return value */
int keyno=0; /* current key number */
int level; /* level in the btree */
*/
for (level = cur->bc_nlevels - 1, diff = 1; level >= 0; level--) {
xfs_buf_t *bp; /* buffer pointer for btree block */
- xfs_daddr_t d; /* disk address of btree block */
+ xfs_daddr_t d; /* disk address of btree block */
/*
* Get the disk address we're looking for.
/*
* Compute difference to get next direction.
*/
- diff = (int)startino - cur->bc_rec.i.ir_startino;
+ diff = (__int64_t)
+ startino - cur->bc_rec.i.ir_startino;
/*
* Less than, move right.
*/
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP,
XFS_RANDOM_ITOBP_INOTOBP))) {
#ifdef DEBUG
- prdev("bad inode magic/vsn daddr 0x%llx #%d (magic=%x)",
- mp->m_dev, (unsigned long long)imap.im_blkno, i,
+ prdev("bad inode magic/vsn daddr %lld #%d (magic=%x)",
+ mp->m_ddev_targp,
+ (unsigned long long)imap.im_blkno, i,
INT_GET(dip->di_core.di_magic, ARCH_CONVERT));
#endif
XFS_CORRUPTION_ERROR("xfs_itobp", XFS_ERRLEVEL_HIGH,
#ifdef XFS_RW_TRACE
ip->i_rwtrace = ktrace_alloc(XFS_RW_KTRACE_SIZE, KM_SLEEP);
#endif
-#ifdef XFS_STRAT_TRACE
- ip->i_strat_trace = ktrace_alloc(XFS_STRAT_KTRACE_SIZE, KM_SLEEP);
-#endif
#ifdef XFS_ILOCK_TRACE
ip->i_lock_trace = ktrace_alloc(XFS_ILOCK_KTRACE_SIZE, KM_SLEEP);
#endif