/*
 * nasd_edrfs_client_dux.h
 *
 * DUX-specific EDRFS stuff
 *
 * Author: Erik Riedel
 */
/*
 * Copyright (c) of Carnegie Mellon University, 1996,1997,1998,1999.
 *
 * Permission to reproduce, use, and prepare derivative works of
 * this software for internal use is granted provided the copyright
 * and "No Warranty" statements are included with all reproductions
 * and derivative works. This software may also be redistributed
 * without charge provided that the copyright and "No Warranty"
 * statements are included in all redistributions.
 *
 * NO WARRANTY. THIS SOFTWARE IS FURNISHED ON AN "AS IS" BASIS.
 * CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER
 * EXPRESSED OR IMPLIED AS TO THE MATTER INCLUDING, BUT NOT LIMITED
 * TO: WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY
 * OF RESULTS OR RESULTS OBTAINED FROM USE OF THIS SOFTWARE. CARNEGIE
 * MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT
 * TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
 */


#ifndef _NASD__NASD_EDRFS_CLIENT_DUX_H_
#define _NASD__NASD_EDRFS_CLIENT_DUX_H_

#include <nasd/nasd_options.h>
#include <nasd/nasd_types.h>
#include <nasd/nasd_edrfs_types.h>
#include <nasd/nasd_pdrive_client.h> /* for nasd_drive_handle_t */

/* to keep track of binding handles on the client */

/* NOTE: the size of this structure must be less than what is set in 
	nfs/nfs_clnt.h for struct mntinfo mi_nasd_handles */

typedef struct nasd_kernel_handles_s {
  nasd_edrfs_handle_t         server_handle;
  nasd_drive_handle_t       drive_handle;
  nasd_int32                flags;
  nasd_int32                partnum;
} nasd_kernel_handles_t;

#define NASD_HANDLE_NEWDRIVE(_h_) ((_h_)->flags&NASD_BINDING_DRIVE_NEW)

#define NASD_BINDING_SERVER_VALID      0x00000001
#define NASD_BINDING_DRIVE_VALID       0x00000002
#define NASD_BINDING_DRIVE_NEW         0x00000004

/* what we are going to put into the NFS3 filehandle */

/* The size of this structure _must_ be <= NFS3_FHSIZE (64) */

/* The first 32 bytes must be filesystem-wide unique and must
   be identical for identical objects (i.e. one-to-one correspondence) */
/* What we are going to do is stuff this into an nfs3 filehandle, then
   we are going to change the filehandle comparison code to only look
   at the first NFS_FHSIZE (32) bytes when doing compares.  This allows
   us to put our cookie bits into the other 32 bytes. */

typedef struct nasd_identpair_s {
  nasd_edrfs_identifier_t  identifier; /* 16 bytes */
  nasd_int32               pad1[4];    /* 16 bytes */
  nasd_edrfs_credential_t  cred;       /* 8  bytes */
  nasd_int32               pad2[6];    /* 24 bytes */
} nasd_identpair_t;                  /* 64 bytes */

/*
 * !!! Match with aprintfidentpair()
 */
#define INIT_NASD_EDRFS_IDENTIFIER(_id_) { \
  (_id_).pad1 = 0xfad0eaea; \
}


/*
 * !!! Match with aprintfidentpair()
 */
#define INIT_NASD_IDENTPAIR_PAD(_idp_) { \
  (_idp_).pad1[0] = 0x4e415344; \
  (_idp_).pad1[1] = 0x444e4153; \
  (_idp_).pad1[2] = 0x53444e41; \
  (_idp_).pad1[3] = 0x4153444e; \
  (_idp_).pad2[0] = 0x12345678; \
  (_idp_).pad2[1] = 0x9abcdef0; \
  (_idp_).pad2[2] = 0xffffffff; \
  (_idp_).pad2[3] = 0xfeedfeed; \
  (_idp_).pad2[4] = 0xabababab; \
  (_idp_).pad2[5] = 0xcdcdcdcd; \
  INIT_NASD_EDRFS_IDENTIFIER((_idp_).identifier); \
}

/* backwards compat */
#define INIT_PAD(_id_) INIT_NASD_IDENTPAIR_PAD(_id_)

#define NASD_EDRFS_MAX_ACTIVE_CAPS     1024
#define NASD_EDRFS_CAP_TABLE_SZ        128

typedef struct nasd_edrfs_captable_entry_s nasd_edrfs_captable_entry_t;

struct nasd_edrfs_captable_entry_s {
  nasd_edrfs_identifier_t       identifier; /*  16 bytes */ 
  nasd_edrfs_credential_t       cred;       /*   8 bytes */
  nasd_cookie_t                 cookie;     /*  56 bytes */
  nasd_edrfs_captable_entry_t  *next;       /*   8 bytes */
  nasd_edrfs_captable_entry_t  *prev;       /*   8 bytes */
  nasd_edrfs_captable_entry_t  *l_next;     /*   8 bytes */
  nasd_edrfs_captable_entry_t  *l_prev;     /*   8 bytes */
};                                        /* 112 bytes total */

#define NASD_EDRFS_IDPAIR_HASH_CALC(idp) ((  (idp)->identifier.nasd_identifier + (idp)->identifier.disk_identifier+(idp)->identifier.partnum << 4) % NASD_EDRFS_CAP_TABLE_SZ )

/* This looks ugly but any decent compiler will to the right thing */
#define NASD_EDRFS_IDPAIR_HASH(idp) ( (idp)->identifier.nasd_identifier > 0 ? ((idp)->identifier.nasd_identifier % NASD_EDRFS_CAP_TABLE_SZ) : ((-1 * (idp)->identifier.nasd_identifier) % NASD_EDRFS_CAP_TABLE_SZ) ) 

#define SETUP_SECURITY_PARAM(_sp_, _cap_) { \
    (_sp_).type=(_cap_).type; \
    (_sp_).partnum=(_cap_).partnum; \
    (_sp_).actual_protection=(_cap_).min_protection; \
}


nasd_status_t nasd_edrfs_caps_lookup(nasd_identpair_t *idpair, nasd_cookie_t *cookie);
nasd_status_t nasd_edrfs_caps_init();
nasd_status_t nasd_edrfs_caps_insert(nasd_identpair_t *idpair, nasd_cookie_t *cookie);

#define nasd_edrfs_type_to_sys_nfs_type(_nasdtype_) \
  (((_nasdtype_) == NASD_EDRFS_TYPE_REG) ? NF3REG : (((_nasdtype_) == NASD_EDRFS_TYPE_DIR) ? NF3DIR : (((_nasdtype_) == NASD_EDRFS_TYPE_LNK) ? NF3LNK : 0)))

#endif /* !_NASD__NASD_EDRFS_CLIENT_DUX_H_ */
