mirror of
https://git.openafs.org/openafs.git
synced 2025-01-18 06:50:12 +00:00
Add support for extended hash tables in the PTS database.
This commit is contained in:
parent
0c8728f337
commit
5013288de5
@ -29,6 +29,8 @@ AC_ARG_ENABLE( namei-fileserver,
|
||||
[ --enable-namei-fileserver force compilation of namei fileserver in preference to inode fileserver],, enable_namei_fileserver="no")
|
||||
AC_ARG_ENABLE( supergroups,
|
||||
[ --enable-supergroups enable support for nested pts groups],, enable_supergroups="no")
|
||||
AC_ARG_ENABLE( prdb-extensions,
|
||||
[ --enable-prdb-extensions enable support for pts database extensions],, enable_prdb_extensions="no")
|
||||
AC_ARG_ENABLE( fast-restart,
|
||||
[ --enable-fast-restart enable fast startup of file server without salvaging],, enable_fast_restart="no")
|
||||
AC_ARG_ENABLE( bitmap-later,
|
||||
@ -949,6 +951,10 @@ if test "$enable_supergroups" = "yes"; then
|
||||
AC_DEFINE(SUPERGROUPS, 1, [define if you want to have support for nested pts groups])
|
||||
fi
|
||||
|
||||
if test "$enable_prdb_extensions" = "yes"; then
|
||||
AC_DEFINE(PRDB_EXTENSIONS, 1, [define if you want to have pts database extensions])
|
||||
fi
|
||||
|
||||
if test "$enable_fast_restart" = "yes"; then
|
||||
AC_DEFINE(FAST_RESTART, 1, [define if you want to have fast restart])
|
||||
fi
|
||||
|
@ -87,8 +87,8 @@ ${TOP_INCDIR}/afs/ptserver.h: ptserver.h
|
||||
#
|
||||
# Build targets
|
||||
#
|
||||
ptserver: ptserver.o ptutils.o ptprocs.o ptint.ss.o ptint.xdr.o utils.o $(LIBS) ${TOP_LIBDIR}/libaudit.a map.o
|
||||
$(CC) ${CFLAGS} -o ptserver ptserver.o ptutils.o ptprocs.o ptint.ss.o ptint.xdr.o utils.o map.o $(LIBS) ${XLIBS} ${TOP_LIBDIR}/libaudit.a
|
||||
ptserver: ptserver.o ptutils.o ptprocs.o ptint.ss.o ptint.xdr.o utils.o $(LIBS) ${TOP_LIBDIR}/libaudit.a map.o xht.o
|
||||
$(CC) ${CFLAGS} -o ptserver ptserver.o ptutils.o ptprocs.o ptint.ss.o ptint.xdr.o utils.o map.o xht.o $(LIBS) ${XLIBS} ${TOP_LIBDIR}/libaudit.a
|
||||
|
||||
ptserver.o: ptserver.c ${INCLS} AFS_component_version_number.c
|
||||
|
||||
@ -100,6 +100,8 @@ utils.o: utils.c ${INCLS}
|
||||
|
||||
map.o: map.c ${INCLS}
|
||||
|
||||
xht.o: xht.c ${INCLS}
|
||||
|
||||
ptint.ss.o: ptint.ss.c ptint.xdr.c ptint.xg
|
||||
ptint.cs.o: ptint.cs.c ptint.xdr.c ptint.xg
|
||||
ptint.xdr.o: ptint.xdr.c ptint.h ptint.xg
|
||||
@ -177,8 +179,8 @@ testpt: testpt.o libprot.a ${TOP_LIBDIR}/libcmd.a $(LIBS)
|
||||
|
||||
testpt.o: testpt.c ${INCLS} ${TOP_INCDIR}/afs/cmd.h AFS_component_version_number.c
|
||||
|
||||
pt_util: pt_util.o ptutils.o ubik.o utils.o map.o libprot.a $(LIBS)
|
||||
$(CC) ${CFLAGS} -o pt_util pt_util.o ptutils.o ubik.o utils.o map.o libprot.a ${TOP_LIBDIR}/libcmd.a $(LIBS) ${XLIBS}
|
||||
pt_util: pt_util.o ptutils.o ubik.o utils.o map.o xht.o libprot.a $(LIBS)
|
||||
$(CC) ${CFLAGS} -o pt_util pt_util.o ptutils.o ubik.o utils.o map.o xht.o libprot.a ${TOP_LIBDIR}/libcmd.a $(LIBS) ${XLIBS}
|
||||
|
||||
ubik.o: ubik.c ${INCLS}
|
||||
|
||||
|
@ -99,10 +99,12 @@ pr_PrintEntry(FILE *f, int hostOrder, afs_int32 ea, struct prentry *e, int inden
|
||||
|
||||
if (e->cellid)
|
||||
fprintf(f, "cellid == %d\n", host(e->cellid));
|
||||
#if !(defined(PR_REMEMBER_TIMES) && defined(PRDB_EXTENSIONS))
|
||||
for (i = 0; i < sizeof(e->reserved) / sizeof(e->reserved[0]); i++)
|
||||
if (e->reserved[i])
|
||||
fprintf(f, "reserved field [%d] not zero: %d\n", i,
|
||||
host(e->reserved[i]));
|
||||
#endif
|
||||
|
||||
fprintf(f, "%*s", indent, "");
|
||||
fprintf(f, "Entry at %d: flags 0x%x, id %di, next %d.\n", ea,
|
||||
|
@ -42,5 +42,14 @@ extern afs_int32 RemoveFromOrphan(struct ubik_trans *at, afs_int32 gid);
|
||||
extern afs_int32 IsOwnerOf(struct ubik_trans *at, afs_int32 aid, afs_int32 gid);
|
||||
extern afs_int32 OwnerOf(struct ubik_trans *at, afs_int32 gid);
|
||||
extern afs_int32 IsAMemberOf(struct ubik_trans *at, afs_int32 aid, afs_int32 gid);
|
||||
|
||||
#if defined(PRDB_EXTENSIONS)
|
||||
extern int pr_XHTInit(void);
|
||||
extern int pr_WriteXHTEntry(struct ubik_trans *tt, afs_int32 afd, afs_int32 pos, struct hashentry *tentry);
|
||||
extern int pr_ReadXHTEntry(struct ubik_trans *tt, afs_int32 afd, afs_int32 pos, struct hashentry *tentry);
|
||||
extern int pr_LoadXHTs(struct ubik_trans *tt);
|
||||
extern int pr_CreateXHT(struct ubik_trans *tt, struct pr_xht *table);
|
||||
extern afs_int32 RemoveFromExtendedHash(struct ubik_trans *tt, struct pr_xht *table, void *aname, int anamelen, afs_int32 *loc);
|
||||
extern afs_int32 AddToExtendedHash(struct ubik_trans *tt, struct pr_xht *table, void *aname, int anamelen, afs_int32 loc);
|
||||
#endif
|
||||
#endif
|
||||
/* vi:set cin noet sw=4 tw=70: */
|
||||
|
@ -429,6 +429,14 @@ main(int argc, char **argv)
|
||||
OpenLog(AFSDIR_SERVER_PTLOG_FILEPATH); /* set up logging */
|
||||
SetupLogSignals();
|
||||
|
||||
#if defined(PRDB_EXTENSIONS)
|
||||
code = pr_XHTInit();
|
||||
if (code) {
|
||||
com_err(whoami, code, "XHT init failed");
|
||||
PT_EXIT(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
prdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
|
||||
if (!prdir) {
|
||||
fprintf(stderr, "ptserver: can't open configuration directory.\n");
|
||||
@ -575,3 +583,4 @@ main(int argc, char **argv)
|
||||
osi_audit(PTS_FinishEvent, -1, AUD_END);
|
||||
exit(0);
|
||||
}
|
||||
/* vi:set cin noet sw=4 tw=70: */
|
||||
|
@ -43,7 +43,12 @@ struct prheader {
|
||||
afs_int32 groupcount; /* num groups in system */
|
||||
afs_int32 foreigncount; /* num registered foreign users NYI */
|
||||
afs_int32 instcount; /* number of sub and super users NYI */
|
||||
#if defined(PRDB_EXTENSIONS)
|
||||
afs_int32 reserved[4]; /* just in case */
|
||||
afs_int32 ext_hashtables; /* chain of extended hash tables */
|
||||
#else
|
||||
afs_int32 reserved[5]; /* just in case */
|
||||
#endif
|
||||
afs_int32 nameHash[HASHSIZE]; /* hash table for names */
|
||||
afs_int32 idHash[HASHSIZE]; /* hash table for ids */
|
||||
};
|
||||
@ -67,13 +72,22 @@ extern struct prheader cheader;
|
||||
#define PRCELL 8 /* 1 if cell entry */
|
||||
#define PRFOREIGN 16 /* 1 if foreign user */
|
||||
#define PRINST 32 /* 1 if sub/super instance */
|
||||
#define PRHASHTBL 0x100 /* 1 if extended hash table */
|
||||
#define PRAUTHNAME 0x200 /* 1 if auth name entry */
|
||||
|
||||
#if defined(PRDB_EXTENSIONS)
|
||||
#define PRTYPE 0x33f /* type bits: only one should be set */
|
||||
#else
|
||||
#define PRTYPE 0x3f /* type bits: only one should be set */
|
||||
#endif
|
||||
#define PRUSER 0 /* all type bits 0 => user entry */
|
||||
|
||||
#define PRACCESS (1<<6) /* access checking enabled */
|
||||
#define PRQUOTA (1<<7) /* group creation quota checking on */
|
||||
|
||||
/* extended hash table types */
|
||||
#define PRTABLE_AUTHNAME 0
|
||||
|
||||
/* define the access bits for entries, they are stored in the left half of the
|
||||
* entry's flags. The SetFields interface takes them in the right half. There
|
||||
* are eight bits altogether defining access rights for status, owned, member,
|
||||
@ -102,9 +116,18 @@ struct prentry {
|
||||
afs_int32 next; /* next block same entry (or freelist) */
|
||||
#ifdef PR_REMEMBER_TIMES
|
||||
afs_uint32 createTime, addTime, removeTime, changeTime;
|
||||
#ifdef PRDB_EXTENSIONS
|
||||
afs_int32 authnames; /* chain of authentication names for this entry */
|
||||
#else
|
||||
afs_int32 reserved[1];
|
||||
#endif
|
||||
#else
|
||||
#ifdef PRDB_EXTENSIONS
|
||||
afs_int32 reserved[4];
|
||||
afs_int32 authnames; /* chain of authentication names for this entry */
|
||||
#else
|
||||
afs_int32 reserved[5];
|
||||
#endif
|
||||
#endif
|
||||
afs_int32 entries[PRSIZE]; /* groups a user is a member of (or list of members */
|
||||
afs_int32 nextID; /* id hash table next pointer */
|
||||
@ -166,6 +189,71 @@ struct contentry { /* continuation of entry */
|
||||
afs_int32 entries[COSIZE];
|
||||
};
|
||||
|
||||
|
||||
/* prdb entry containing a portion of an extended hash table */
|
||||
/* note that 40 buckets would fit, but only 32 are used. */
|
||||
struct hashentry {
|
||||
afs_int32 flags; /* random flags */
|
||||
afs_int32 id; /* unused */
|
||||
afs_int32 cellid; /* unused */
|
||||
afs_int32 next; /* next entry this table */
|
||||
afs_int32 nextTable; /* next table */
|
||||
afs_int32 tableid; /* table type */
|
||||
afs_int32 offset; /* first bucket # in this entry */
|
||||
afs_int32 reserved;
|
||||
afs_int32 buckets[32];
|
||||
};
|
||||
|
||||
|
||||
#define ANSIZE 160
|
||||
|
||||
struct authentry {
|
||||
afs_int32 flags; /* random flags */
|
||||
afs_int32 id; /* id of owning entry */
|
||||
afs_int32 cellid; /* unused */
|
||||
afs_int32 next; /* next block for this authname */
|
||||
afs_int32 nextHash; /* next authname in this bucket */
|
||||
afs_int32 nextAuthName; /* next authname for this entry */
|
||||
afs_int32 kind; /* PRAUTHTYPE_* */
|
||||
afs_int32 length; /* total length of auth data */
|
||||
unsigned char data[ANSIZE];
|
||||
};
|
||||
|
||||
/* The following are flags for PR_ListEntries() */
|
||||
#define PRUSERS 0x1
|
||||
#define PRGROUPS 0x2
|
||||
|
||||
#if defined(PRDB_EXTENSIONS)
|
||||
struct pr_xht {
|
||||
char *name; /* descriptive name of this table */
|
||||
afs_int32 tableid; /* table ID in database file */
|
||||
int nbuckets; /* number of buckets in table */
|
||||
|
||||
/* compute the hash bucket number for a key on this table */
|
||||
afs_int32 (*hash)(void *name, int namelen);
|
||||
|
||||
/*
|
||||
* check whether the entry at a specified location has the
|
||||
* desired name. Returns 0 on success, error code on failure.
|
||||
* On success, *next is set to the location of the next entry,
|
||||
* and *found is set nonzero iff the name matches.
|
||||
*/
|
||||
afs_int32 (*ckname)(struct ubik_trans *tt, afs_int32 loc,
|
||||
void *name, int namelen, afs_int32 *next, int *found);
|
||||
|
||||
/*
|
||||
* Set the next-entry pointer in the entry at the specified location.
|
||||
* Returns 0 on success, error code on failure.
|
||||
*/
|
||||
afs_int32 (*setnxt)(struct ubik_trans *tt, afs_int32 loc, afs_int32 next);
|
||||
|
||||
int flags; /* random flags */
|
||||
int nparts; /* number of entries containing table */
|
||||
afs_int32 *partids; /* array of entry locations */
|
||||
struct hashentry *parts; /* array of parts */
|
||||
|
||||
};
|
||||
|
||||
#define XHT_INITED 1 /* hashtable has been inited */
|
||||
#endif
|
||||
/* vi:set cin noet sw=4 tw=70: */
|
||||
|
@ -1705,6 +1705,24 @@ read_DbHeader(struct ubik_trans *tt)
|
||||
int pr_noAuth;
|
||||
afs_int32 initd = 0;
|
||||
|
||||
#if defined(PRDB_EXTENSIONS)
|
||||
afs_int32
|
||||
InitDBExtensions(struct ubik_trans *tt)
|
||||
{
|
||||
afs_int32 code, entry;
|
||||
struct hashentry hent;
|
||||
|
||||
code = pr_LoadXHTs(tt);
|
||||
if (code)
|
||||
return code;
|
||||
|
||||
code = ubik_EndTrans(tt);
|
||||
if (code)
|
||||
return code;
|
||||
return PRSUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
afs_int32
|
||||
Initdb()
|
||||
{
|
||||
@ -1744,10 +1762,14 @@ Initdb()
|
||||
&& ntohl(cheader.eofPtr) != (afs_uint32) NULL
|
||||
&& FindByID(tt, ANONYMOUSID) != 0) {
|
||||
/* database exists, so we don't have to build it */
|
||||
#if defined(PRDB_EXTENSIONS)
|
||||
return InitDBExtensions(tt);
|
||||
#else
|
||||
code = ubik_EndTrans(tt);
|
||||
if (code)
|
||||
return code;
|
||||
return PRSUCCESS;
|
||||
#endif
|
||||
}
|
||||
/* else we need to build a database */
|
||||
code = ubik_EndTrans(tt);
|
||||
@ -1794,10 +1816,14 @@ Initdb()
|
||||
&& ntohl(cheader.eofPtr) != (afs_uint32) NULL
|
||||
&& FindByID(tt, ANONYMOUSID) != 0) {
|
||||
/* database exists, so we don't have to build it */
|
||||
#if defined(PRDB_EXTENSIONS)
|
||||
return InitDBExtensions(tt);
|
||||
#else
|
||||
code = ubik_EndTrans(tt);
|
||||
if (code)
|
||||
return code;
|
||||
return PRSUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Initialize the database header */
|
||||
@ -1837,10 +1863,14 @@ Initdb()
|
||||
return code;
|
||||
}
|
||||
|
||||
#if defined(PRDB_EXTENSIONS)
|
||||
return InitDBExtensions(tt);
|
||||
#else
|
||||
code = ubik_EndTrans(tt);
|
||||
if (code)
|
||||
return code;
|
||||
return PRSUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
afs_int32
|
||||
@ -2187,3 +2217,4 @@ AddAuthGroup(struct prentry *tentry, prlist *alist, afs_int32 *size)
|
||||
else
|
||||
return PRSUCCESS;
|
||||
}
|
||||
/* vi:set cin noet sw=4 tw=70: */
|
||||
|
259
src/ptserver/xht.c
Normal file
259
src/ptserver/xht.c
Normal file
@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Copyright 2000, International Business Machines Corporation and others.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This software has been released under the terms of the IBM Public
|
||||
* License. For details, see the LICENSE file in the top-level source
|
||||
* directory or online at http://www.openafs.org/dl/license10.html
|
||||
*/
|
||||
|
||||
#include <afsconfig.h>
|
||||
#include <afs/param.h>
|
||||
|
||||
RCSID
|
||||
("$Header$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <lock.h>
|
||||
#include <ubik.h>
|
||||
#include <stdio.h>
|
||||
#ifdef AFS_NT40_ENV
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#else
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#endif
|
||||
#include "ptserver.h"
|
||||
#include "pterror.h"
|
||||
|
||||
#if defined(PRDB_EXTENSIONS)
|
||||
struct pr_xht xtables[] = {
|
||||
{ "authname", HASHSIZE, 0/*hash*/, 0/*ckname*/, 0/*setnxt*/ }
|
||||
};
|
||||
#define NTABLES (sizeof(xtables) / sizeof(xtables[0]))
|
||||
|
||||
int
|
||||
pr_XHTInit(void) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NTABLES; i++) {
|
||||
xtables[i].nparts = (xtables[i].nbuckets + 1) / 32;
|
||||
xtables[i].partids = malloc(xtables[i].nparts * sizeof(afs_int32));
|
||||
xtables[i].parts = malloc(xtables[i].nparts * sizeof(struct hashentry));
|
||||
if (!xtables[i].partids || !xtables[i].parts)
|
||||
return PRNOMEM;
|
||||
memset(xtables[i].partids, 0, xtables[i].nparts * sizeof(afs_int32));
|
||||
memset(xtables[i].parts, 0, xtables[i].nparts * sizeof(struct hashentry));
|
||||
}
|
||||
return PRSUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
pr_WriteXHTEntry(struct ubik_trans *tt, afs_int32 afd, afs_int32 pos, struct hashentry *tentry)
|
||||
{
|
||||
afs_int32 code;
|
||||
register afs_int32 i;
|
||||
struct hashentry nentry;
|
||||
|
||||
if (ntohl(1) != 1) { /* No need to swap */
|
||||
memset(&nentry, 0, sizeof(nentry)); /* make reseved fields zero */
|
||||
nentry.flags = htonl(tentry->flags);
|
||||
nentry.id = htonl(tentry->id);
|
||||
nentry.cellid = htonl(tentry->cellid);
|
||||
nentry.next = htonl(tentry->next);
|
||||
nentry.nextTable = htonl(tentry->nextTable);
|
||||
nentry.tableid = htonl(tentry->tableid);
|
||||
nentry.offset = htonl(tentry->offset);
|
||||
for (i = 0; i < 32; i++)
|
||||
nentry.buckets[i] = htonl(tentry->buckets[i]);
|
||||
tentry = &nentry;
|
||||
}
|
||||
code = pr_Write(tt, afd, pos, (char *)tentry, sizeof(struct hashentry));
|
||||
return (code);
|
||||
}
|
||||
|
||||
int
|
||||
pr_ReadXHTEntry(struct ubik_trans *tt, afs_int32 afd, afs_int32 pos, struct hashentry *tentry)
|
||||
{
|
||||
afs_int32 code;
|
||||
register afs_int32 i;
|
||||
struct hashentry nentry;
|
||||
code = ubik_Seek(tt, afd, pos);
|
||||
if (code)
|
||||
return (code);
|
||||
if (ntohl(1) == 1) { /* No swapping needed. */
|
||||
code = ubik_Read(tt, (char *)tentry, sizeof(struct hashentry));
|
||||
return (code);
|
||||
}
|
||||
code = ubik_Read(tt, (char *)&nentry, sizeof(struct hashentry));
|
||||
if (code)
|
||||
return (code);
|
||||
|
||||
memset(tentry, 0, sizeof(*tentry)); /* make reseved fields zero */
|
||||
tentry->flags = ntohl(nentry.flags);
|
||||
tentry->id = ntohl(nentry.id);
|
||||
tentry->cellid = ntohl(nentry.cellid);
|
||||
tentry->next = ntohl(nentry.next);
|
||||
tentry->nextTable = ntohl(nentry.nextTable);
|
||||
tentry->tableid = ntohl(nentry.tableid);
|
||||
tentry->offset = ntohl(nentry.offset);
|
||||
for (i = 0; i < 32; i++)
|
||||
tentry->buckets[i] = ntohl(nentry.buckets[i]);
|
||||
return (code);
|
||||
}
|
||||
|
||||
int
|
||||
pr_LoadXHTs(struct ubik_trans *tt)
|
||||
{
|
||||
int tbl, i;
|
||||
afs_int32 code, loc, next_table;
|
||||
struct hashentry tentry;
|
||||
|
||||
for (loc = ntohl(cheader.ext_hashtables); loc; loc = next_table) {
|
||||
code = pr_ReadXHTEntry(tt, 0, loc, &tentry);
|
||||
if (code)
|
||||
return PRDBFAIL;
|
||||
if ((tentry.flags & PRTYPE) != PRHASHTBL)
|
||||
return PRINCONSISTENT;
|
||||
next_table = tentry.nextTable;
|
||||
tbl = tentry.tableid;
|
||||
if (tbl < 0 || tbl >= NTABLES)
|
||||
continue;
|
||||
for (i = 0; i < xtables[tbl].nparts; i++) {
|
||||
xtables[tbl].partids[i] = loc;
|
||||
if (i) {
|
||||
code = pr_ReadXHTEntry(tt, 0, loc, &xtables[tbl].parts[i]);
|
||||
if (code)
|
||||
return PRDBFAIL;
|
||||
} else {
|
||||
memcpy(&xtables[tbl].parts[i], &tentry, sizeof(tentry));
|
||||
}
|
||||
if (((xtables[tbl].parts[i].flags & PRTYPE) != PRHASHTBL) ||
|
||||
(xtables[tbl].parts[i].tableid != tbl) ||
|
||||
xtables[tbl].parts[i].offset != i >> 5) {
|
||||
return PRINCONSISTENT;
|
||||
}
|
||||
loc = xtables[tbl].parts[i].next;
|
||||
}
|
||||
}
|
||||
return PRSUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
pr_CreateXHT(struct ubik_trans *tt, struct pr_xht *table)
|
||||
{
|
||||
afs_int32 code, next;
|
||||
int i;
|
||||
|
||||
if ((table->flags & XHT_INITED))
|
||||
return PRSUCCESS;
|
||||
|
||||
next = 0;
|
||||
for (i = table->nparts; i--;) {
|
||||
memset(&table->parts[i], 0, sizeof(struct hashentry));
|
||||
table->parts[i].flags = PRHASHTBL;
|
||||
table->parts[i].next = next;
|
||||
table->parts[i].nextTable = i ? 0 : ntohl(cheader.ext_hashtables);
|
||||
table->parts[i].tableid = table - xtables;
|
||||
table->parts[i].offset = i >> 5;
|
||||
table->partids[i] = next = AllocBlock(tt);
|
||||
if (!next)
|
||||
return PRDBFAIL;
|
||||
code = pr_WriteXHTEntry(tt, 0, next, &table->parts[i]);
|
||||
if (code)
|
||||
return PRDBFAIL;
|
||||
}
|
||||
cheader.ext_hashtables = htonl(next);
|
||||
code = pr_Write(tt, 0, 68, (char *)&cheader.ext_hashtables,
|
||||
sizeof(cheader.ext_hashtables));
|
||||
if (code)
|
||||
return PRDBFAIL;
|
||||
|
||||
table->flags |= XHT_INITED;
|
||||
return PRSUCCESS;
|
||||
}
|
||||
|
||||
/* Remove an entry from an extended hash table. */
|
||||
afs_int32
|
||||
RemoveFromExtendedHash(struct ubik_trans *tt, struct pr_xht *table,
|
||||
void *aname, int anamelen, afs_int32 *loc)
|
||||
{
|
||||
afs_int32 code, current, next, trail, i, part, bucket;
|
||||
int found;
|
||||
|
||||
if (!(table->flags & XHT_INITED))
|
||||
return PRSUCCESS;
|
||||
|
||||
i = (table->hash)(aname, anamelen);
|
||||
if (i < 0 || i >= table->nbuckets)
|
||||
return PRINCONSISTENT;
|
||||
part = i >> 5;
|
||||
bucket = i & 0x1f;
|
||||
|
||||
current = table->parts[part].buckets[bucket];
|
||||
trail = 0;
|
||||
for (;;) {
|
||||
if (current == 0)
|
||||
return PRSUCCESS; /* already gone */
|
||||
code = (table->ckname)(tt, current, aname, anamelen, &next, &found);
|
||||
if (code)
|
||||
return PRDBFAIL;
|
||||
if (found) break;
|
||||
trail = current;
|
||||
current = next;
|
||||
}
|
||||
if (trail == 0) {
|
||||
next = htonl(next);
|
||||
code = pr_Write(tt, 0, table->partids[part] + 32 + 4*bucket,
|
||||
(char *)&next, sizeof(next));
|
||||
if (code)
|
||||
return PRDBFAIL;
|
||||
} else {
|
||||
code = (table->setnxt)(tt, trail, next);
|
||||
if (code)
|
||||
return PRDBFAIL;
|
||||
}
|
||||
*loc = current;
|
||||
return PRSUCCESS;
|
||||
}
|
||||
|
||||
afs_int32
|
||||
AddToExtendedHash(struct ubik_trans *tt, struct pr_xht *table,
|
||||
void *aname, int anamelen, afs_int32 loc)
|
||||
{
|
||||
afs_int32 code, i, part, bucket, next;
|
||||
|
||||
if (!(table->flags & XHT_INITED)) {
|
||||
code = pr_CreateXHT(tt, table);
|
||||
if (code)
|
||||
return PRDBFAIL;
|
||||
}
|
||||
|
||||
i = (table->hash)(aname, anamelen);
|
||||
if (i < 0 || i >= table->nbuckets)
|
||||
return PRINCONSISTENT;
|
||||
part = i >> 5;
|
||||
bucket = i & 0x1f;
|
||||
|
||||
code = (table->setnxt)(tt, loc, table->parts[part].buckets[bucket]);
|
||||
if (code)
|
||||
return PRDBFAIL;
|
||||
|
||||
table->parts[part].buckets[bucket] = loc;
|
||||
next = htonl(loc);
|
||||
code = pr_Write(tt, 0, table->partids[part] + 32 + 4*bucket,
|
||||
(char *)&next, sizeof(next));
|
||||
if (code)
|
||||
return PRDBFAIL;
|
||||
return PRSUCCESS;
|
||||
}
|
||||
#endif
|
||||
/* vi:set cin noet sw=4 tw=70: */
|
Loading…
Reference in New Issue
Block a user