static char rcsid[] = "$Header: dfs_subr.c,v 820.1 86/12/04 19:44:59 root Exp $";
static char sccsid[]="%W% %Y% %Q% %G%";

/************************************************************************
*									*
*				Copyright 1984				*
*			VALID LOGIC SYSTEMS INCORPORATED		*
*									*
*	This listing contains confidential proprietary information	*
*	which is not to be disclosed to unauthorized persons without	*
*	written consent of an officer of Valid Logic Systems 		*
*	Incorporated.							*
*									*
*	The copyright notice appearing above is included to provide	*
*	statutory protection in the event of unauthorized or 		*
*	unintentional public disclosure.				*
*									*
************************************************************************/

/*
 * DFS subroutines
 *
 *	Bakul Shah
 *
 * bvs 840423 --original version
 * jht 841115,16,26-29 -- complete conversion to use prpc.
 * jht 850213 -- add dfsPktHdr_t containing version/functionality info to pkts.
 * jht 850401 -- fill out the gathering of statistics.
 * jht 850414 -- differentiate between no remote struct and one not locked.
 */

#include "../h/param.h"
#include "../h/ioctl.h"
#include "../h/dir.h"
#include "../h/user.h"

#include "../vnet/vnet.h"
#include "../conn/conn.h"
#include "../rpc/rpc.h"
#include "../dfs/dfs.h"

#include "../h/inode.h"
#include "../h/socket.h"
#include "../h/kernel.h"
#include "../net/if.h"
#include "../h/mbuf.h"


typedef struct dfsc_syncip {	/* Pkt from client --> server	*/
#ifdef	DFS_PACKETHDR
	dfsPktHdr_t	dfsPktHdr;	/* Info about DFS versions, etc	*/
#endif	DFS_PACKETHDR
	caddr_t 	ip;	/* Ptr to inode			*/
} dfsc_syncip_t;

typedef struct dfsr_syncip {	/* Pkt from client <-- server	*/
#ifdef	DFS_PACKETHDR
	dfsPktHdr_t	dfsPktHdr;	/* Info about DFS versions, etc	*/
#endif	DFS_PACKETHDR
	int		error;	/* Error number or 0 on success	*/
} dfsr_syncip_t;

/*
 * Make a remote syncip call.
 * Nothing is expected to be returned.
 */
dfsClient_syncip(ip)
	register struct	inode	* ip;
{
	register dfsc_syncip_t	* call;
	register dfsr_syncip_t	* result;

	dfs_incClient(syncip);
	if (!dfsClient_validContext(ip, "syncip"))
		return;
	call = DFSC_PACKET(syncip);
	if (!call)
		return;
	call->ip = ip->i_rmt_ip;
	result = DFS_CALL(ip->i_host,syncip,call);
	if (!result)
		return;
	u.u_error = result->error;
	DFS_FREE_RESULTS(result);
}

/*
 * Server-side of syncip()
 *
 *	Inputs:			Standard prpc invocation.
 *	Outputs:		C.f., result pkt above.
 *	Errors:
 *		NULL		No result pkt obtainable;
 *		DFS_EINVAL	Bad inode pointer;
 *		DFS_EBADRMTDESC	No rmt_;
 */
dfsr_syncip_t *
dfsServer_syncip(clientConn, clientId, operation, call)
	connection_t	       * clientConn;	/* Host we are serving	*/
	u_long			 clientId;	/* Specific client@host	*/
	u_short			 operation;	/* Redundant: what to do*/
	register dfsc_syncip_t * call;		/* Call pkt -- params	*/
{
	register dfsr_syncip_t * result;
	register struct inode  * ip;
	register dfs_remote_t  * rp;

	dfs_incServer(syncip);
	result = DFSR_PACKET(syncip);
	if (!result) {
		DFS_FREE_PARAMS(call);
		return NULL;		/* Say "no result pkt" */
	}
	rp = dfs_rmt_find(DFS_NODE(clientConn), call->ip);
	if (!rp || !(rp->flags & DFS_RMT_LOCKED)) {
		result->error = !rp ? DFS_EBADRMTDESC : DFS_ERMTNOTLOCKED;
		goto bad;
	}
	rp->locktime = UPTIME();
	if (!(ip = rp->ip)) {
		u.u_error = DFS_EINVAL;
		goto bad;
	}
	syncip(ip);
bad:
	result->error = u.u_error;
	DFS_FREE_PARAMS(call);
	DFS_RETURN(result);
}
