XLOG_TIC_ADD_OPHDR(ticket); 
xlog_write(xfs_mount_t *	mp,	   xfs_log_iovec_t	reg[],	   int			nentries,	   xfs_log_ticket_t	tic,	   xfs_lsn_t		*start_lsn,	   xlog_in_core_t	**commit_iclog,	   uint			flags){    xlog_t	     *log    = mp->m_log;    xlog_ticket_t    *ticket = (xlog_ticket_t *)tic;    xlog_op_header_t *logop_head;    /* ptr to log operation header */    xlog_in_core_t   *iclog;	     /* ptr to current in-core log */    __psint_t	     ptr;	     /* copy address into data region */    int		     len;	     /* # xlog_write() bytes 2 still copy */    int		     index;	     /* region index currently copying */    int		     log_offset;     /* offset (from 0) into data region */    int		     start_rec_copy; /* # bytes to copy for start record */    int		     partial_copy;   /* did we split a region? */    int		     partial_copy_len;/* # bytes copied if split region */    int		     need_copy;	     /* # bytes need to memcpy this region */    int		     copy_len;	     /* # bytes actually memcpy'ing */    int		     copy_off;	     /* # bytes from entry start */    int		     contwr;	     /* continued write of in-core log? */    int		     error;    int		     record_cnt = 0, data_cnt = 0;    partial_copy_len = partial_copy = 0;    /* Calculate potential maximum space.  Each region gets its own     * xlog_op_header_t and may need to be double word aligned.     */    len = 0;    if (ticket->t_flags & XLOG_TIC_INITED)     /* acct for start rec of xact */	len += sizeof(xlog_op_header_t);    for (index = 0; index < nentries; index++) {	len += sizeof(xlog_op_header_t);	    /* each region gets >= 1 */	len += reg[index].i_len;    }    contwr = *start_lsn = 0;    if (ticket->t_curr_res < len) {#ifdef DEBUG	xlog_panic(		"xfs_log_write: reservation ran out. Need to up reservation");#else	/* Customer configurable panic */	xfs_cmn_err(XFS_PTAG_LOGRES, CE_ALERT, mp,		"xfs_log_write: reservation ran out. Need to up reservation");	/* If we did not panic, shutdown the filesystem */	xfs_force_shutdown(mp, XFS_CORRUPT_INCORE);#endif    } else	ticket->t_curr_res -= len;    for (index = 0; index < nentries; ) {	if ((error = xlog_state_get_iclog_space(log, len, &iclog, ticket,					       &contwr, &log_offset)))		return (error);	ASSERT(log_offset <= iclog->ic_size - 1);	ptr = (__psint_t) ((char *)iclog->ic_datap+log_offset);	/* start_lsn is the first lsn written to. That's all we need. */	if (! *start_lsn)	    *start_lsn = INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT);	/* This loop writes out as many regions as can fit in the amount	 * of space which was allocated by xlog_state_get_iclog_space().	 */	while (index < nentries) {	    ASSERT(reg[index].i_len % sizeof(__int32_t) == 0);	    ASSERT((__psint_t)ptr % sizeof(__int32_t) == 0);	    start_rec_copy = 0;	    /* If first write for transaction, insert start record.	     * We can't be trying to commit if we are inited.  We can't	     * have any "partial_copy" if we are inited.	     */	    if (ticket->t_flags & XLOG_TIC_INITED) {		logop_head		= (xlog_op_header_t *)ptr;		INT_SET(logop_head->oh_tid, ARCH_CONVERT, ticket->t_tid);		logop_head->oh_clientid = ticket->t_clientid;		logop_head->oh_len	= 0;		logop_head->oh_flags    = XLOG_START_TRANS;		logop_head->oh_res2	= 0;		ticket->t_flags		&= ~XLOG_TIC_INITED;	/* clear bit */		record_cnt++;		start_rec_copy = sizeof(xlog_op_header_t);		xlog_write_adv_cnt(ptr, len, log_offset, start_rec_copy);	    }	    /* Copy log operation header directly into data section */	    logop_head			= (xlog_op_header_t *)ptr;	    INT_SET(logop_head->oh_tid, ARCH_CONVERT, ticket->t_tid);	    logop_head->oh_clientid	= ticket->t_clientid;	    logop_head->oh_res2		= 0;	    /* header copied directly */	    xlog_write_adv_cnt(ptr, len, log_offset, sizeof(xlog_op_header_t));	    /* are we copying a commit or unmount record? */	    logop_head->oh_flags = flags;	    /*	     * We've seen logs corrupted with bad transaction client	     * ids.  This makes sure that XFS doesn't generate them on.	     * Turn this into an EIO and shut down the filesystem.	     */	    switch (logop_head->oh_clientid)  {	    case XFS_TRANSACTION:	    case XFS_VOLUME:	    case XFS_LOG:		break;	    default:		xfs_fs_cmn_err(CE_WARN, mp,		    "Bad XFS transaction clientid 0x%x in ticket 0x%p",		    logop_head->oh_clientid, tic);		return XFS_ERROR(EIO);	    }	    /* Partial write last time? => (partial_copy != 0)	     * need_copy is the amount we'd like to copy if everything could	     * fit in the current memcpy.	     */	    need_copy =	reg[index].i_len - partial_copy_len;	    copy_off = partial_copy_len;	    if (need_copy <= iclog->ic_size - log_offset) { /*complete write */		INT_SET(logop_head->oh_len, ARCH_CONVERT, copy_len = need_copy);		if (partial_copy)		    logop_head->oh_flags|= (XLOG_END_TRANS|XLOG_WAS_CONT_TRANS);		partial_copy_len = partial_copy = 0;	    } else {					    /* partial write */		copy_len = iclog->ic_size - log_offset;		INT_SET(logop_head->oh_len, ARCH_CONVERT, copy_len);		logop_head->oh_flags |= XLOG_CONTINUE_TRANS;		if (partial_copy)			logop_head->oh_flags |= XLOG_WAS_CONT_TRANS;		partial_copy_len += copy_len;		partial_copy++;		len += sizeof(xlog_op_header_t); /* from splitting of region */		/* account for new log op header */		ticket->t_curr_res -= sizeof(xlog_op_header_t);	    }	    xlog_verify_dest_ptr(log, ptr);	    /* copy region */	    ASSERT(copy_len >= 0);	    memcpy((xfs_caddr_t)ptr, reg[index].i_addr + copy_off, copy_len);	    xlog_write_adv_cnt(ptr, len, log_offset, copy_len);	    /* make copy_len total bytes copied, including headers */	    copy_len += start_rec_copy + sizeof(xlog_op_header_t);	    record_cnt++;	    data_cnt += contwr ? copy_len : 0;	    if (partial_copy) {			/* copied partial region */		    /* already marked WANT_SYNC by xlog_state_get_iclog_space */		    xlog_state_finish_copy(log, iclog, record_cnt, data_cnt);		    record_cnt = data_cnt = 0;		    if ((error = xlog_state_release_iclog(log, iclog)))			    return (error);		    break;			/* don't increment index */	    } else {				/* copied entire region */		index++;		partial_copy_len = partial_copy = 0;		if (iclog->ic_size - log_offset <= sizeof(xlog_op_header_t)) {		    xlog_state_finish_copy(log, iclog, record_cnt, data_cnt);		    record_cnt = data_cnt = 0;		    xlog_state_want_sync(log, iclog);		    if (commit_iclog) {			ASSERT(flags & XLOG_COMMIT_TRANS);			*commit_iclog = iclog;		    } else if ((error = xlog_state_release_iclog(log, iclog)))			   return (error);		    if (index == nentries)			    return 0;		/* we are done */		    else			    break;		}	    } /* if (partial_copy) */	} /* while (index < nentries) */    } /* for (index = 0; index < nentries; ) */    ASSERT(len == 0);    xlog_state_finish_copy(log, iclog, record_cnt, data_cnt);    if (commit_iclog) {	ASSERT(flags & XLOG_COMMIT_TRANS);	*commit_iclog = iclog;	return 0;    }    return (xlog_state_release_iclog(log, iclog));}	/* xlog_write */
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/7e9c63961558092d584936a874cf3fee80002eb6/xfs_log.c/buggy/fs/xfs/xfs_log.c