[BACK]Return to xfs_rpc_item.c CVS log [TXT][DIR] Up to [Development] / xfs-linux-nodel

File: [Development] / xfs-linux-nodel / Attic / xfs_rpc_item.c (download)

Revision 1.7, Fri Jun 9 06:40:03 2000 UTC (17 years, 4 months ago) by ananth
Branch: MAIN
Changes since 1.6: +2 -2 lines

Merge of 2.3.99pre2-xfs:slinx:63026a originally by cattelan on 05/30/00
  Masive type update 
  all daddr_t -> xfs_daddr_t
  caddr_t -> xfs_caddr_t
  off_t   -> xfs_off_t
  ino_t   -> xfs_ino_t
  off64_t -> xfs_off_t 
  Removed need for file xfs_to_linux.h and lunux_to_xfs.h

/*
 * Copyright (c) 2000 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
 * published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it would be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * 
 * Further, this software is distributed without any warranty that it is
 * free of the rightful claim of any third person regarding infringement
 * or the like.  Any license provided herein, whether implied or
 * otherwise, applies only to this software file.  Patent licenses, if
 * any, provided herein do not apply to combinations of this program with
 * other software, or any other product whatsoever.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write the Free Software Foundation, Inc., 59
 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
 * 
 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
 * Mountain View, CA  94043, or:
 * 
 * http://www.sgi.com 
 * 
 * For further information regarding this notice, see: 
 * 
 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
 */
#ident "$Revision: 1.7 $"
#include <xfs_os_defs.h>

/*
 * Implementation of CXFS RPC log items -- needed to implement
 * atomic rpc's for CXFS
 */

#ifdef SIM
#define _KERNEL 1
#endif

#include <sys/param.h>
#include <sys/kmem.h>
#include "xfs_buf.h"
#include <sys/vnode.h>
#include <sys/uuid.h>
#include <sys/debug.h>

#ifdef SIM
#undef _KERNEL
#endif

#include "xfs_macros.h"
#include "xfs_types.h"
#include "xfs_inum.h"
#include "xfs_log.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_mount.h"
#include "xfs_rpc_item.h"

zone_t *xfs_rpcli_zone;		/* rpc log item zone */

/*
 * returns the number of iovecs needed to log the rpc.
 *
 * the number is always 2 -- one for the log format structure
 * and the second to log the return results
 */
/* ARGSUSED */
uint
xfs_rpc_item_size(xfs_rpc_log_item_t *rpcip)
{
	return 2;
}

/*
 * Called to fill in the the vector of log iovecs with
 * the data to be logged.  The first vector will be filled
 * with the log format structure, the second with the return
 * results.
 */
void
xfs_rpc_item_format(xfs_rpc_log_item_t *rpcip, xfs_log_iovec_t *logvec)
{
	xfs_log_iovec_t *vec = logvec;

	rpcip->rpcli_format.rlf_type = XFS_LI_RPC;

	/*
	 * first logvec contains everything but the data union
	 */
	vec->i_addr = (xfs_caddr_t) &rpcip->rpcli_format;
	vec->i_len = sizeof(cxfs_rpc_log_format_t);
	vec++;

	/*
	 * second logvec contains the contents of the data union
	 */
	vec->i_addr = (xfs_caddr_t) &rpcip->rpcli_data.rpcli_base;
	vec->i_len = rpcip->rpcli_format.rlf_size;
}

/*
 * Pin the rpc item to memory.  The rpc return results cannot 
 * be flushed back to the client until the rpc has been first
 * logged to disk or until the rpc is safely replicated in the
 * shadow logs.  The log pin/unpin calls and the shadow log
 * pin/unpin calls use the same fundamental field (a 64-bit
 * bitmask) with the disk being the low bit (bit 0).
 *
 * pin clears all bits.  The bits get set when the data has
 * the corresponding shadow or disk.
 */
void
xfs_rpc_item_pin(xfs_rpc_log_item_t *rpcip)
{
	int s;

	s = mutex_spinlock(&rpcip->rpcli_lock);
	rpcip->rpcli_pinmask = 0;
	mutex_spinunlock(&rpcip->rpcli_lock, s);

	return;
}

/*
 * Unpin the rpc item.  Drop the disk-based pin because the
 * item has hit the disk (sets the low-order bit high).
 */
void
xfs_rpc_item_unpin(xfs_rpc_log_item_t *rpcip)
{
	int s;

	s = mutex_spinlock(&rpcip->rpcli_lock);
	rpcip->rpcli_pinmask |= 0x1;
	mutex_spinunlock(&rpcip->rpcli_lock, s);

	return;
}

/*
 * Same as above for aborting dirty transactions (typically just
 * before shutting down the filesystem).
 */
void
xfs_rpc_item_unpin_remove(xfs_rpc_log_item_t *rpcip)
{
	int s;

	s = mutex_spinlock(&rpcip->rpcli_lock);
	rpcip->rpcli_pinmask |= 0x1;
	mutex_spinunlock(&rpcip->rpcli_lock, s);

	return;
}

/*
 * Non-blocking lock routine for tail-pushing.  I *think* we
 * can make this a spinlock that actually waits a split-second
 * since no one should be holding the rpc item lock for very long.
 * So this routine actually does nothing but return success since
 * we know we're going to be able to lock the item in the push routine.
 */
/* ARGSUSED */
uint
xfs_rpc_item_trylock(xfs_rpc_log_item_t *rpcip)
{
	return XFS_ITEM_SUCCESS;
}

/*
 * Unlock the item after the transaction has committed to
 * the incore log buffer.  This routine does nothing since
 * there is no long-term locking on the rpc/rpc-item.  There
 * is one rpc-item per rpc and all rpc's are single-threaded.
 */
/* ARGSUSED */
void
xfs_rpc_item_unlock(xfs_rpc_log_item_t *rpcip)
{
	return;
}

/*
 * return the lsn that the transaction system should
 * think was last committed for the rpc.  For rpc's,
 * it's the given lsn (see buffer items for a case
 * where we don't use the given lsn).
 */
/* ARGSUSED */
xfs_lsn_t
xfs_rpc_item_committed( xfs_rpc_log_item_t *rpcip, xfs_lsn_t lsn)
{
	return lsn;
}

/*
 * abort - not used right now since it's not called.
 */
/* ARGSUSED */
void
xfs_rpc_item_abort(xfs_rpc_log_item_t *rpcip)
{
	return;
}

/*
 * push - rpc the logged info back to the client
 * so we can pull the item from the AIL.  We don't want
 * make it a synchronous RPC since we don't want to wait
 * too long here.  However, for simplicity's sake, I'm
 * willing to do that for now since we expect this to be
 * a rarely (if ever) executed code path.
 */
/* ARGSUSED */
void
xfs_rpc_item_push(xfs_rpc_log_item_t *rpcip)
{
	/*
	 * XXX - do nothing right now.  Later this will
	 * have to lock the rpc log item, snapshot the
	 * results into a buffer, drop the lock, and send
	 * the buffer.  After the rpc is received by the
	 * client, then pull the item from AIL.  Either that,
	 * or let the async data transmission completion callout
	 * pull the item from the AIL.
	 */
	return;
}

/* the pushbuf op is NULL */

/*
 * committing - does nothing since the rpc is in and of itself not
 * a metadata object that another rpc will see depend on.
 */
/* ARGSUSED */
void
xfs_rpc_item_committing( xfs_rpc_log_item_t *rpcip, xfs_lsn_t lsn)
{
	return;
}

struct xfs_item_ops xfs_rpc_item_ops = {
	(uint(*)(xfs_log_item_t*))xfs_rpc_item_size,
	(void(*)(xfs_log_item_t*, xfs_log_iovec_t*))xfs_rpc_item_format,
	(void(*)(xfs_log_item_t*))xfs_rpc_item_pin,
	(void(*)(xfs_log_item_t*))xfs_rpc_item_unpin,
	(void(*)(xfs_log_item_t*, xfs_trans_t*))xfs_rpc_item_unpin_remove,
	(uint(*)(xfs_log_item_t*))xfs_rpc_item_trylock,
	(void(*)(xfs_log_item_t*))xfs_rpc_item_unlock,
	(xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))xfs_rpc_item_committed,
	(void(*)(xfs_log_item_t*))xfs_rpc_item_push,
	(void(*)(xfs_log_item_t*))xfs_rpc_item_abort,
	NULL,
	(void(*)(xfs_log_item_t*, xfs_lsn_t))xfs_rpc_item_committing
};

xfs_rpc_log_item_t *
xfs_rpc_item_init(
	xfs_mount_t	*mp,
	uint		rpctype,
	cell_t		caller,
	struct chandle	*handle,
	uuid_t		caller_uuid)
{
	xfs_rpc_log_item_t *rpcip;

	rpcip = kmem_zone_alloc(xfs_rpcli_zone, KM_SLEEP);

	/*
	 * initialize base fields in embedded XFS log item
	 */
	rpcip->rpcli_item.li_type = XFS_LI_RPC;
	rpcip->rpcli_item.li_ops = &xfs_rpc_item_ops;
	rpcip->rpcli_item.li_mountp = mp;

	spinlock_init(&rpcip->rpcli_lock, "XFS rpc log item");
	rpcip->rpcli_handle = handle;	/* XXX might need to dup them instead */
	rpcip->rpcli_cell = caller;

	rpcip->rpcli_format.rlf_op = rpctype;
	rpcip->rpcli_format.rlf_cellid = caller_uuid;

	/*
	 * XXX rcc - probably more here ...
	 */

	return rpcip;
}

/*
 * XXX rcc - tear an rpc log item down
 */
/* ARGSUSED */
void
xfs_rpc_item_destroy(xfs_rpc_log_item_t *rpcip)
{
	return;
}