diff options
author | Hans Insulander <hin@cvs.openbsd.org> | 2003-08-05 08:42:42 +0000 |
---|---|---|
committer | Hans Insulander <hin@cvs.openbsd.org> | 2003-08-05 08:42:42 +0000 |
commit | 3f898bc9738b2b9e412ef593b11fc317e854a360 (patch) | |
tree | da31381bb6c6034e585ff8f63588f61e1b0f3632 /usr.sbin | |
parent | 52e046c7bcba608dab0f26de9a9c5fe6eea6af5b (diff) |
Merge
Diffstat (limited to 'usr.sbin')
54 files changed, 10403 insertions, 8294 deletions
diff --git a/usr.sbin/afs/src/arlad/.gdbinit b/usr.sbin/afs/src/arlad/.gdbinit index 644d8d62a7b..4e2581123bd 100644 --- a/usr.sbin/afs/src/arlad/.gdbinit +++ b/usr.sbin/afs/src/arlad/.gdbinit @@ -1,7 +1,15 @@ # -# $KTH: .gdbinit,v 1.5 2000/11/02 12:41:46 lha Exp $ +# $arla: .gdbinit,v 1.10 2002/04/10 08:56:33 lha Exp $ # +define memoryusage +y +printf "rx bytes: bytes: %d allocations: %d\n", rxi_Allocsize, rxi_Alloccnt +printf "fcache: highvnode: %d usedvnode: %d\n", highvnodes, usedvnodes +printf "conn: nconnections %d\n", nconnections +printf "cred: ncredentials %d\n", ncredentials +end + define listfcachenodes set $foo = lrulist->head @@ -62,52 +70,73 @@ end define lwp_ps_internal set $lwp_ps_queue = $arg0 +set $bf = $arg1 set $lwp_ps_counter = $lwp_ps_queue.count set $lwp_ps_foo = $lwp_ps_queue->head while $lwp_ps_counter != 0 - printf " name: %s", (char *) $lwp_ps_foo->name + printf " name: %s index: %d", (char *) $lwp_ps_foo->name, $lwp_ps_foo->index if $lwp_ps_foo == lwp_cpptr printf " RUNNING THREAD" end printf "\n" - printf " eventlist:" - set $lwp_ps_envcnt = 0 - while $lwp_ps_envcnt < $lwp_ps_foo->eventcnt - printf " %x", $lwp_ps_foo->eventlist[$lwp_ps_envcnt] - set $lwp_ps_envcnt = $lwp_ps_envcnt + 1 - end - printf "\n" - if $lwp_ps_foo == lwp_cpptr - printf " fp: 0x%x\n", $fp - printf " pc: 0x%x\n", $pc - printf " pointers on topstack added for completeness\n" + if $bf == 0 + printf " eventlist:" + set $lwp_ps_envcnt = 0 + while $lwp_ps_envcnt < $lwp_ps_foo->eventcnt + printf " %x", $lwp_ps_foo->eventlist[$lwp_ps_envcnt] + set $lwp_ps_envcnt = $lwp_ps_envcnt + 1 + end + printf "\n" + if $lwp_ps_foo == lwp_cpptr + printf " fp: 0x%x\n", $fp + printf " pc: 0x%x\n", $pc + printf " pointers on topstack added for completeness\n" + end + printf " fp: 0x%x\n", ((int *)$lwp_ps_foo->context->topstack)[2] + printf " pc: 0x%x\n", ((int *)$lwp_ps_foo->context->topstack)[3] + else + set $foo = ((int *)$lwp_ps_foo->context->topstack)[2] + backfrom $foo $foo end - printf " fp: 0x%x\n", ((int *)$lwp_ps_foo->context->topstack)[2] - printf " pc: 0x%x\n", ((int *)$lwp_ps_foo->context->topstack)[3] set $lwp_ps_foo = $lwp_ps_foo->next set $lwp_ps_counter = $lwp_ps_counter - 1 end end -define lwp_ps +define lwp_ps_int +set $bf = $arg0 echo Runnable[0]\n -lwp_ps_internal runnable[0] +lwp_ps_internal runnable[0] $bf echo Runnable[1]\n -lwp_ps_internal runnable[1] +lwp_ps_internal runnable[1] $bf echo Runnable[2]\n -lwp_ps_internal runnable[2] +lwp_ps_internal runnable[2] $bf echo Runnable[3]\n -lwp_ps_internal runnable[3] +lwp_ps_internal runnable[3] $bf echo Runnable[4]\n -lwp_ps_internal runnable[4] +lwp_ps_internal runnable[4] $bf echo Blocked\n -lwp_ps_internal blocked +lwp_ps_internal blocked $bf +end + +define lwp_ps +lwp_ps_int 0 end document lwp_ps Print all processes, running or blocked end +define lwp_backfrom_all +lwp_ps_int 1 +end + +document lwp_backfrom_all +Traces from all processes, running or blocked +end + + + define list_count set $count = 0 set $current = ((List *)$arg0)->head @@ -191,3 +220,22 @@ end document volume_check Check volcache consistency WRT fcache usage, too slow to use ! end + + +define conn_print +set $num = 0 +while $num < connhtab->sz + set $current = connhtab->tab[$num] + while $current != 0 + set $data = (ConnCacheEntry *)$current->ptr + print *$data + printf " Cuid: %lx/%lx\n", $data->connection.epoch, $data->connection.cid + set $current = $current->next + end + set $num = $num + 1 +end +end + +document conn_print +Print all entries on volcache cache +end diff --git a/usr.sbin/afs/src/arlad/CellServDB.5 b/usr.sbin/afs/src/arlad/CellServDB.5 index 1a63f017fd3..b036ca981cf 100644 --- a/usr.sbin/afs/src/arlad/CellServDB.5 +++ b/usr.sbin/afs/src/arlad/CellServDB.5 @@ -1,8 +1,40 @@ -.\" $OpenBSD: CellServDB.5,v 1.5 2002/06/10 20:09:46 hin Exp $ -.\" $KTH: CellServDB.5,v 1.3 2000/09/25 07:24:18 lha Exp $ +.\" Copyright (c) 2000 - 2002 Kungliga Tekniska Högskolan +.\" (Royal Institute of Technology, Stockholm, Sweden). +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" 3. Neither the name of the Institute nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $arla: CellServDB.5,v 1.10 2003/06/06 12:53:52 hin Exp $ +.\" $OpenBSD: CellServDB.5,v 1.6 2003/08/05 08:42:41 hin Exp $ +.\" .Dd April 19, 2000 .Dt CellServDB 5 -.Os Arla +.Os "The Arla Project" .Sh NAME .Nm CellServDB .Nd AFS cells and database servers @@ -40,9 +72,23 @@ with the AFSDB DNS resource records. This avoids having out of date information in .Nm Ns . .Pp +Entires in the file are searched and expanded by many programs. +.Pp +In most cases it is better to distribute the information in +.Nm +with the AFSDB DNS resource records. This avoids having out of date +information in +.Nm Ns . +.Pp When using AFSDB DNS resource records, entries entries should still be listed, but without any hosts. This is needed for dynroot to work. .Sh FILES .Pa /etc/afs/CellServDB .Sh SEE ALSO +.Xr fs 1 , +.Xr AliasDB 5 , +.Xr DynRootDB 5 , +.Xr ThisCell 5 , +.Xr afsd.conf 5 , .Xr afsd 8 + diff --git a/usr.sbin/afs/src/arlad/DynRootDB.5 b/usr.sbin/afs/src/arlad/DynRootDB.5 index 9ad67404aa2..1aa60ecd635 100644 --- a/usr.sbin/afs/src/arlad/DynRootDB.5 +++ b/usr.sbin/afs/src/arlad/DynRootDB.5 @@ -1,15 +1,46 @@ -.\" Copyright (c) 2001 Kungliga Tekniska Högskolan -.\" $KTH: DynRootDB.5,v 1.1.2.2 2001/06/10 21:13:14 lha Exp $ -.Dd April 30, 2001 +.\" Copyright (c) 2003 Kungliga Tekniska Högskolan +.\" (Royal Institute of Technology, Stockholm, Sweden). +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" 3. Neither the name of the Institute nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $arla: DynRootDB.5,v 1.9 2003/06/06 12:53:53 hin Exp $ +.\" +.Dd March 31, 2003 .Dt DynRootDB 5 -.Os Arla +.Os "The Arla Project" .Sh NAME .Nm DynRootDB .Nd AFS cells and database servers .Sh DESCRIPTION The file .Nm -lists AFS cells that should appear in the afs root +specifies what AFS cells that should appear in the AFS root .Pa ( /afs ) when starting .Nm afsd . @@ -29,11 +60,17 @@ is started, normally when the system boots. .Pp If .Nm -doesn't exist, then all cells listed in CellServDB and dynamically -found nodes appear in the afs root. +doesn't exist, then all cells listed in the CellServDB and the +dynamically found nodes appear in the +.Pa /afs +directory. .Sh FILES .Pa /etc/afs/DynRootDB .Pa /etc/afs/CellServDB .Sh SEE ALSO +.Xr AliasDB 5 , .Xr CellServDB 5 , +.Xr SuidCells 5 , +.Xr ThisCell 5 , +.Xr afsd.conf 5 , .Xr afsd 8 diff --git a/usr.sbin/afs/src/arlad/SuidCells.5 b/usr.sbin/afs/src/arlad/SuidCells.5 index 7db09b646ce..da7f5841dd0 100644 --- a/usr.sbin/afs/src/arlad/SuidCells.5 +++ b/usr.sbin/afs/src/arlad/SuidCells.5 @@ -1,11 +1,45 @@ -.\" $OpenBSD: SuidCells.5,v 1.4 2003/01/17 17:36:04 deraadt Exp $ -.\" $KTH: SuidCells.5,v 1.3 2000/09/25 07:25:59 lha Exp $ +.\" Copyright (c) 2000 - 2003 Kungliga Tekniska Högskolan +.\" (Royal Institute of Technology, Stockholm, Sweden). +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" 3. Neither the name of the Institute nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $arla: SuidCells.5,v 1.9 2003/06/06 12:53:53 hin Exp $ +.\" $OpenBSD: SuidCells.5,v 1.5 2003/08/05 08:42:41 hin Exp $ +.\" .Dd April 19, 2000 .Dt SuidCells 5 -.Os Arla +.Os "The Arla Project" .Sh NAME .Nm SuidCells -.Nd lists AFS cells which honor the setuid bit +.Nd lists AFS cells for which +.Nm afsd +will honor the setuid bit .Sh DESCRIPTION The setuid bit on binaries executed from AFS are ignored for the cells that are not listed in @@ -13,8 +47,12 @@ for the cells that are not listed in .Pp The .Nm -file contain a list of cells separated by newlines. The cells need to -exist in CellServDB or in DNS (with AFSDB resource records). +file contain a list of cells separated by newlines. The cells +need to exist in CellServDB or in DNS (with AFSDB resource records). .Sh SEE ALSO +.Xr AliasDB 5 , +.Xr DynRootDB 5 , .Xr CellServDB 5 , -.Xr arlad 8 +.Xr ThisCell 5 , +.Xr afsd.conf 5 , +.Xr afsd 8 diff --git a/usr.sbin/afs/src/arlad/ThisCell.5 b/usr.sbin/afs/src/arlad/ThisCell.5 index ab2ef47fe64..59e4cdd6746 100644 --- a/usr.sbin/afs/src/arlad/ThisCell.5 +++ b/usr.sbin/afs/src/arlad/ThisCell.5 @@ -1,8 +1,40 @@ -.\" $OpenBSD: ThisCell.5,v 1.3 2002/06/07 08:03:04 hin Exp $ -.\" $KTH: ThisCell.5,v 1.4 2000/09/26 22:36:29 lha Exp $ -.Dd April 19, 2000 +.\" Copyright (c) 2000 - 2003 Kungliga Tekniska Högskolan +.\" (Royal Institute of Technology, Stockholm, Sweden). +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" 3. Neither the name of the Institute nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $OpenBSD: ThisCell.5,v 1.4 2003/08/05 08:42:41 hin Exp $ +.\" $arla: ThisCell.5,v 1.10 2003/06/06 12:53:54 hin Exp $ +.\" +.Dd March 31, 2003 .Dt ThisCell 5 -.Os Arla +.Os "The Arla Project" .Sh NAME .Nm ThisCell .Nd specify a hosts home AFS cell @@ -25,5 +57,6 @@ having good connectivity to the default cell is very important. .Pp .Sh SEE ALSO .Xr CellServDB 5 , +.Xr DynRootDB 5 , .Xr SuidCells 5 , -.Xr arlad 8 +.Xr afsd 8 diff --git a/usr.sbin/afs/src/arlad/adir.c b/usr.sbin/afs/src/arlad/adir.c index b5744fcab4e..27f7c61aea3 100644 --- a/usr.sbin/afs/src/arlad/adir.c +++ b/usr.sbin/afs/src/arlad/adir.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,27 +37,26 @@ #include "arla_local.h" -RCSID("$KTH: adir.c,v 1.66.2.1 2001/06/04 22:16:34 ahltorp Exp $") ; +RCSID("$arla: adir.c,v 1.73 2002/07/24 05:56:27 lha Exp $") ; /* * */ static int -get_fbuf_from_fid (VenusFid *fid, CredCacheEntry **ce, - int *fd, fbuf *fbuf, - FCacheEntry **centry, - int open_flags, int fbuf_flags) +get_fbuf_from_centry (CredCacheEntry **ce, + int *fd, fbuf *fbuf, + FCacheEntry **centry, + int open_flags, int fbuf_flags) { int ret; - ret = fcache_get_data (centry, fid, ce); + ret = fcache_get_data (centry, ce, 0); if (ret) return ret; ret = fcache_get_fbuf (*centry, fd, fbuf, open_flags, fbuf_flags); if (ret) { - fcache_release(*centry); return ret; } return 0; @@ -99,25 +98,23 @@ adir_lookup (FCacheEntry *centry, const char *name, VenusFid *file) */ int -adir_changefid (VenusFid *dir, +adir_changefid (FCacheEntry **centry, const char *name, VenusFid *file, CredCacheEntry **ce) { - FCacheEntry *centry; int ret; int fd; fbuf the_fbuf; - ret = get_fbuf_from_fid (dir, ce, &fd, &the_fbuf, ¢ry, O_RDWR, - FBUF_READ|FBUF_WRITE|FBUF_SHARED); + ret = get_fbuf_from_centry (ce, &fd, &the_fbuf, centry, O_RDWR, + FBUF_READ|FBUF_WRITE|FBUF_SHARED); if (ret) return ret; ret = fdir_changefid (&the_fbuf, name, file); fbuf_end (&the_fbuf); close (fd); - fcache_release (centry); return ret; } @@ -126,23 +123,21 @@ adir_changefid (VenusFid *dir, */ int -adir_emptyp (VenusFid *dir, +adir_emptyp (FCacheEntry **centry, CredCacheEntry **ce) { - FCacheEntry *centry; int ret; int fd; fbuf the_fbuf; - ret = get_fbuf_from_fid (dir, ce, &fd, &the_fbuf, ¢ry, - O_RDONLY, FBUF_READ|FBUF_PRIVATE); + ret = get_fbuf_from_centry (ce, &fd, &the_fbuf, centry, + O_RDONLY, FBUF_READ|FBUF_PRIVATE); if (ret) return ret; ret = fdir_emptyp (&the_fbuf); fbuf_end (&the_fbuf); close (fd); - fcache_release (centry); return ret; } @@ -152,25 +147,23 @@ adir_emptyp (VenusFid *dir, */ int -adir_readdir (VenusFid *dir, - void (*func)(VenusFid *, const char *, void *), +adir_readdir (FCacheEntry **centry, + fdir_readdir_func func, void *arg, CredCacheEntry **ce) { int fd; fbuf the_fbuf; - FCacheEntry *centry; int ret; - ret = get_fbuf_from_fid (dir, ce, &fd, &the_fbuf, ¢ry, - O_RDONLY, FBUF_READ|FBUF_PRIVATE); + ret = get_fbuf_from_centry (ce, &fd, &the_fbuf, centry, + O_RDONLY, FBUF_READ|FBUF_PRIVATE); if (ret) return ret; - ret = fdir_readdir (&the_fbuf, func, arg, dir); + ret = fdir_readdir (&the_fbuf, func, arg, (*centry)->fid, NULL); fbuf_end (&the_fbuf); close (fd); - fcache_release (centry); return ret; } @@ -195,7 +188,7 @@ adir_mkdir (FCacheEntry *dir, return ret; ret = fdir_mkdir (&the_fbuf, dot, dot_dot); - fcache_update_length (dir, fbuf_len(&the_fbuf)); + fcache_update_length (dir, fbuf_len(&the_fbuf), fbuf_len(&the_fbuf)); fbuf_end (&the_fbuf); close (fd); return ret; @@ -220,7 +213,7 @@ adir_creat (FCacheEntry *dir, return ret; ret = fdir_creat (&the_fbuf, name, fid); - fcache_update_length (dir, fbuf_len(&the_fbuf)); + fcache_update_length (dir, fbuf_len(&the_fbuf), fbuf_len(&the_fbuf)); fbuf_end (&the_fbuf); close (fd); return ret; @@ -244,7 +237,7 @@ adir_remove (FCacheEntry *dir, return ret; ret = fdir_remove(&the_fbuf, name, NULL); - fcache_update_length (dir, fbuf_len(&the_fbuf)); + fcache_update_length (dir, fbuf_len(&the_fbuf), fbuf_len(&the_fbuf)); fbuf_end (&the_fbuf); close (fd); return ret; diff --git a/usr.sbin/afs/src/arlad/adir.h b/usr.sbin/afs/src/arlad/adir.h index 2b9dd3338c6..49432384688 100644 --- a/usr.sbin/afs/src/arlad/adir.h +++ b/usr.sbin/afs/src/arlad/adir.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -35,12 +35,11 @@ * Interface to directory handling routines */ -/* $KTH: adir.h,v 1.14.2.1 2001/06/04 22:16:35 ahltorp Exp $ */ +/* $arla: adir.h,v 1.18 2002/07/24 05:57:01 lha Exp $ */ #ifndef _ADIR_H_ #define _ADIR_H_ -#include "fs.h" #include "cred.h" #include "fcache.h" #include "fdir.h" @@ -49,17 +48,17 @@ int adir_lookup (FCacheEntry *centry, const char *name, VenusFid *file); int -adir_changefid (VenusFid *dir, +adir_changefid (FCacheEntry **centry, const char *name, VenusFid *file, CredCacheEntry **ce); int -adir_emptyp (VenusFid *dir, +adir_emptyp (FCacheEntry **centry, CredCacheEntry **ce); -int adir_readdir (VenusFid *dir, - void (*)(VenusFid *, const char *name, void *), +int adir_readdir (FCacheEntry **centry, + fdir_readdir_func func, void *arg, CredCacheEntry **ce); diff --git a/usr.sbin/afs/src/arlad/afsdir_check.c b/usr.sbin/afs/src/arlad/afsdir_check.c index 6fdb3c499f0..29904056da7 100644 --- a/usr.sbin/afs/src/arlad/afsdir_check.c +++ b/usr.sbin/afs/src/arlad/afsdir_check.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -38,7 +38,7 @@ #include "arla_local.h" #include <getarg.h> -RCSID("$KTH: afsdir_check.c,v 1.21.2.1 2001/10/03 23:36:00 assar Exp $"); +RCSID("$arla: afsdir_check.c,v 1.25 2002/07/24 05:57:41 lha Exp $"); static int help_flag; static int verbose = 0; @@ -75,7 +75,11 @@ getentry (DirPage0 *page0, page = (DirPage1 *)((char *)page0 + AFSDIR_PAGESIZE * (num / ENTRIESPERPAGE)); - assert (page->header.pg_tag == htons(AFSDIRMAGIC)); + if (page->header.pg_tag != htons(AFSDIRMAGIC)) { + printf ("Bad magic (%d) != %d in directory\n", + ntohs(page->header.pg_tag), AFSDIRMAGIC); + exit (1); + } return &page->entry[num % ENTRIESPERPAGE]; } @@ -94,7 +98,7 @@ check_dir (const char *filename) unsigned page_entry_count; unsigned hash_entry_count; unsigned noverfill; - u_int8_t **my_bitmaps = NULL; + uint8_t **my_bitmaps = NULL; fd = open (filename, O_RDONLY | O_BINARY, 0); if (fd < 0) diff --git a/usr.sbin/afs/src/arlad/aix-subr.c b/usr.sbin/afs/src/arlad/aix-subr.c index a60d351f218..dc2c056bf92 100644 --- a/usr.sbin/afs/src/arlad/aix-subr.c +++ b/usr.sbin/afs/src/arlad/aix-subr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -34,7 +34,7 @@ #define _KERNEL #include "arla_local.h" -RCSID("$KTH: aix-subr.c,v 1.14 2000/10/14 19:58:04 map Exp $"); +RCSID("$arla: aix-subr.c,v 1.17 2002/07/24 05:58:07 lha Exp $"); static long blocksize = 1024; @@ -58,7 +58,7 @@ flushbuf (void *vargs) (((sizeof(struct dirent)+ (strlen(name)+1)) + \ 3) & ~3) -static void +static int write_dirent(VenusFid *fid, const char *name, void *arg) { struct dirent *real; @@ -78,9 +78,10 @@ write_dirent(VenusFid *fid, const char *name, void *arg) args->off += real->d_reclen; real->d_offset = args->off; args->last = real; + return 0; } -Result +int conv_dir (FCacheEntry *e, CredCacheEntry *ce, u_int tokens, fcache_cache_handle *cache_handle, char *cache_name, size_t cache_name_sz) diff --git a/usr.sbin/afs/src/arlad/arla-cli.c b/usr.sbin/afs/src/arlad/arla-cli.c index cca16cbf828..2602146a0d9 100644 --- a/usr.sbin/afs/src/arlad/arla-cli.c +++ b/usr.sbin/afs/src/arlad/arla-cli.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -34,9 +34,9 @@ #include <arla_local.h> #include <sl.h> #include <getarg.h> -#include <arla-version.h> +#include <vers.h> -RCSID("$KTH: arla-cli.c,v 1.7 2000/12/04 22:45:19 lha Exp $"); +RCSID("$arla: arla-cli.c,v 1.35 2003/06/10 04:23:16 lha Exp $"); char *default_log_file = "/dev/stderr"; char *default_arla_cachedir = ".arlacache"; @@ -54,6 +54,7 @@ static int arla_chdir(int, char **); static int arla_ls(int, char **); static int arla_cat(int, char **); static int arla_cp(int, char **); +static int arla_sleep(int, char **); static int arla_wc(int, char **); static int help(int, char **); static int arla_quit(int, char **); @@ -64,18 +65,33 @@ static int arla_cred_status(int, char **); static int arla_fcache_status(int, char **); static int arla_cell_status (int, char **); static int arla_sysname(int, char**); +static int arla_mkdir (int, char**); +static int arla_rmdir (int, char**); +static int arla_rm (int, char**); +static int arla_put (int, char**); +static int arla_get (int, char**); #ifdef RXDEBUG static int arla_rx_status(int argc, char **argv); #endif static int arla_flushfid(int argc, char **argv); +static char *copy_dirname(const char *s); +static char *copy_basename(const char *s); + + static SL_cmd cmds[] = { {"chdir", arla_chdir, "chdir directory"}, {"cd"}, {"ls", arla_ls, "ls"}, {"cat", arla_cat, "cat file"}, {"cp", arla_cp, "copy file"}, + {"sleep", arla_sleep, "sleep seconds"}, {"wc", arla_wc, "wc file"}, + {"mkdir", arla_mkdir, "mkdir dir"}, + {"rmdir", arla_rmdir, "rmdir dir"}, + {"rm", arla_rm, "rm file"}, + {"put", arla_put, "put localfile [afsfile]"}, + {"get", arla_get, "get afsfile [localfile]"}, {"help", help, "help"}, {"?"}, {"checkservers", arla_checkserver, "poll servers are down"}, @@ -94,108 +110,56 @@ static SL_cmd cmds[] = { { NULL } }; -/* An emulation of kernel lookup, convert (startdir, fname) into - * (startdir). Strips away leading /afs, removes duobles slashes, - * and resolves symlinks. - * Return 0 for success, otherwise -1. +/* + * Return a malloced copy of the dirname of `s' */ -static int -walk (VenusFid *startdir, char *fname) -{ - VenusFid cwd = *startdir; - char *base; - VenusFid file; - Result ret; - FCacheEntry *entry; - int error; - char symlink[MAXPATHLEN]; - char store_name[MAXPATHLEN]; - - strlcpy(store_name, fname, sizeof(store_name)); - fname = store_name; - - do { - /* set things up so that fname points to the remainder of the path, - * whereas base points to the whatever preceeds the first / - */ - base = fname; - fname = strchr(fname, '/'); - if (fname) { - /* deal with repeated adjacent / chars by eliminating the - * duplicates. - */ - while (*fname == '/') { - *fname = '\0'; - fname++; - } - } - - /* deal with absolute pathnames first. */ - if (*base == '\0') { - cwd = rootcwd; - if (fname) { - if (strncmp("afs",fname,3) == 0) { - fname += 3; - } - continue; - } else { - break; - } - } - ret = cm_lookup (&cwd, base, &file, &ce, TRUE); - if (ret.res) { - arla_warn (ADEBWARN, ret.error, "lookup(%s)", base); - return -1; - } - error = fcache_get_data (&entry, &file, &ce); - if (error) { - arla_warn (ADEBWARN, error, "fcache_get"); - return -1; - } - - /* handle symlinks here */ - if (entry->status.FileType == TYPE_LINK) { - int len; - int fd; - - fd = fcache_open_file (entry, O_RDONLY); - /* read the symlink and null-terminate it */ - if (fd < 0) { - fcache_release(entry); - arla_warn (ADEBWARN, errno, "fcache_open_file"); - return -1; - } - len = read (fd, symlink, sizeof(symlink)); - close (fd); - if (len <= 0) { - fcache_release(entry); - arla_warnx (ADEBWARN, "cannot read symlink"); - return -1; - } - symlink[len] = '\0'; - /* if we're not at the end (i.e. fname is not null), take - * the expansion of the symlink and append fname to it. - */ - if (fname != NULL) { - strlcat(symlink, "/", sizeof(symlink)); - strlcat(symlink, fname, sizeof(symlink)); - } - strlcpy(store_name, symlink, sizeof(store_name)); - fname = store_name; - } else { - /* if not a symlink, just update cwd */ - cwd = file; - } - fcache_release(entry); - - /* the *fname condition below deals with a trailing / in a - * path-name */ - } while (fname != NULL && *fname); - *startdir = cwd; - return 0; +static char * +copy_dirname (const char *s) +{ + const char *p; + char *res; + + p = strrchr (s, '/'); + if (p == NULL) + return strdup("."); + res = malloc (p - s + 1); + if (res == NULL) + return NULL; + memmove (res, s, p - s); + res[p - s] = '\0'; + return res; +} + +/* + * Return the basename of `s'. + * The result is malloc'ed. + */ + +static char * +copy_basename (const char *s) +{ + const char *p, *q; + char *res; + + p = strrchr (s, '/'); + if (p == NULL) + p = s; + else + ++p; + q = s + strlen (s); + res = malloc (q - p + 1); + if (res == NULL) + return NULL; + memmove (res, p, q - p); + res[q - p] = '\0'; + return res; } +/* + * + */ + static int arla_quit (int argc, char **argv) { @@ -239,18 +203,19 @@ arla_chdir (int argc, char **argv) return 0; } - if(walk (&cwd, argv[1])) + if(cm_walk (cwd, argv[1], &cwd)) printf ("walk %s failed\n", argv[1]); return 0; } -static void +static int print_dir (VenusFid *fid, const char *name, void *v) { printf("(%d, %d, %d, %d): %s\n", fid->Cell, fid->fid.Volume, fid->fid.Vnode, fid->fid.Unique, name); + return 0; } struct ls_context { @@ -258,42 +223,47 @@ struct ls_context { CredCacheEntry *ce; }; -static void +static int print_dir_long (VenusFid *fid, const char *name, void *v) { - Result res; int ret; - AFSFetchStatus status; - VenusFid realfid; AccessEntry *ae; struct ls_context *context = (struct ls_context *)v; char type; CredCacheEntry *ce = context->ce; + FCacheEntry *entry; VenusFid *dir_fid = context->dir_fid; char timestr[20]; struct tm *t; time_t ti; if (VenusFid_cmp(fid, dir_fid) == 0) - return; + return 0; ret = followmountpoint (fid, dir_fid, NULL, &ce); if (ret) { printf ("follow %s: %d\n", name, ret); - return; + return 0; } /* Have we follow a mountpoint to ourself ? */ if (VenusFid_cmp(fid, dir_fid) == 0) - return; + return 0; - res = cm_getattr (*fid, &status, &realfid, context->ce, &ae); - if (res.res) { - printf ("%s: %d\n", name, res.res); - return; + ret = fcache_get(&entry, *fid, context->ce); + if (ret) { + printf("%s: %d\n", name, ret); + return 0; } - switch (status.FileType) { + ret = cm_getattr (entry, context->ce, &ae); + if (ret) { + fcache_release(entry); + printf ("%s: %d\n", name, ret); + return 0; + } + + switch (entry->status.FileType) { case TYPE_FILE : type = '-'; break; @@ -313,29 +283,31 @@ print_dir_long (VenusFid *fid, const char *name, void *v) fid->fid.Vnode, fid->fid.Unique); - ti = status.ClientModTime; + ti = entry->status.ClientModTime; t = localtime (&ti); strftime (timestr, sizeof(timestr), "%Y-%m-%d", t); printf ("%c%c%c%c%c%c%c%c%c%c %2d %6d %6d %8d %s ", type, - status.UnixModeBits & 0x100 ? 'w' : '-', - status.UnixModeBits & 0x080 ? 'r' : '-', - status.UnixModeBits & 0x040 ? 'x' : '-', - status.UnixModeBits & 0x020 ? 'w' : '-', - status.UnixModeBits & 0x010 ? 'r' : '-', - status.UnixModeBits & 0x008 ? 'x' : '-', - status.UnixModeBits & 0x004 ? 'w' : '-', - status.UnixModeBits & 0x002 ? 'r' : '-', - status.UnixModeBits & 0x001 ? 'x' : '-', - status.LinkCount, - status.Owner, - status.Group, - status.Length, + entry->status.UnixModeBits & 0x100 ? 'r' : '-', + entry->status.UnixModeBits & 0x080 ? 'w' : '-', + entry->status.UnixModeBits & 0x040 ? 'x' : '-', + entry->status.UnixModeBits & 0x020 ? 'r' : '-', + entry->status.UnixModeBits & 0x010 ? 'w' : '-', + entry->status.UnixModeBits & 0x008 ? 'x' : '-', + entry->status.UnixModeBits & 0x004 ? 'r' : '-', + entry->status.UnixModeBits & 0x002 ? 'w' : '-', + entry->status.UnixModeBits & 0x001 ? 'x' : '-', + entry->status.LinkCount, + entry->status.Owner, + entry->status.Group, + entry->status.Length, timestr); - printf ("v %d ", status.DataVersion); + printf ("v %d ", entry->status.DataVersion); printf ("%s\n", name); + fcache_release(entry); + return 0; } static int @@ -348,6 +320,7 @@ arla_ls (int argc, char **argv) int error; int optind = 0; struct ls_context context; + FCacheEntry *entry; args[0].value = &l_flag; @@ -357,10 +330,20 @@ arla_ls (int argc, char **argv) } context.dir_fid = &cwd; context.ce = ce; - error = adir_readdir (&cwd, l_flag ? print_dir_long : print_dir, + error = fcache_get(&entry, cwd, ce); + if (error) { + printf ("fcache_get failed: %s\n", koerr_gettext(error)); + return 0; + } + + error = adir_readdir (&entry, l_flag ? print_dir_long : print_dir, &context, &ce); - if (error) + fcache_release(entry); + if (error) { printf ("adir_readdir failed: %s\n", koerr_gettext(error)); + return 0; + } + cwd = entry->fid; return 0; } @@ -369,11 +352,11 @@ arla_sysname (int argc, char **argv) { switch (argc) { case 1: - printf("sysname: %s\n", arlasysname); + printf("sysname: %s\n", fcache_getdefsysname()); break; case 2: - strlcpy(arlasysname, argv[1], SYSNAMEMAXLEN); - printf("setting sysname to: %s\n", arlasysname); + fcache_setdefsysname(argv[1]); + printf("setting sysname to: %s\n", fcache_getdefsysname()); break; default: printf("syntax: sysname <sysname>\n"); @@ -382,6 +365,329 @@ arla_sysname (int argc, char **argv) return 0; } +static int +arla_mkdir (int argc, char **argv) +{ + VenusFid fid; + int ret; + FCacheEntry *e; + char *dirname; + char *basename; + AFSStoreStatus store_attr; + VenusFid res; + AFSFetchStatus fetch_attr; + + if (argc != 2) { + printf ("usage: %s file\n", argv[0]); + return 0; + } + dirname = strdup(argv[1]); + if (dirname == NULL) + err(1, "strdup"); + basename = strrchr(dirname, '/'); + if (basename == NULL) { + printf ("%s: filename contains no /\n", argv[0]); + free(dirname); + return 0; + } + basename[0] = '\0'; + basename++; + + if(cm_walk (cwd, dirname, &fid) == 0) { + + ret = fcache_get(&e, fid, ce); + if (ret) { + printf ("fcache_get failed: %d\n", ret); + free(dirname); + return 0; + } + + store_attr.Mask = 0; + store_attr.ClientModTime = 0; + store_attr.Owner = 0; + store_attr.Group = 0; + store_attr.UnixModeBits = 0; + store_attr.SegSize = 0; + ret = cm_mkdir(&e, basename, &store_attr, &res, &fetch_attr, &ce); + if (ret) { + arla_warn (ADEBWARN, ret, + "%s: cannot create directory `%s'", + argv[0], argv[1]); + fcache_release(e); + free(dirname); + return 1; + } + + fcache_release(e); + } + free(dirname); + return 0; +} + +static int +arla_rmdir (int argc, char **argv) +{ + VenusFid fid; + int ret; + FCacheEntry *e; + char *dirname; + char *basename; + + if (argc != 2) { + printf ("usage: %s file\n", argv[0]); + return 0; + } + dirname = strdup(argv[1]); + if (dirname == NULL) + err(1, "strdup"); + basename = strrchr(dirname, '/'); + if (basename == NULL) { + printf ("%s: filename contains no /\n", argv[0]); + free(dirname); + return 0; + } + basename[0] = '\0'; + basename++; + + if(cm_walk (cwd, dirname, &fid) == 0) { + + ret = fcache_get(&e, fid, ce); + if (ret) { + printf ("fcache_get failed: %d\n", ret); + free(dirname); + return 0; + } + + ret = cm_rmdir(&e, basename, &ce); + if (ret) { + arla_warn (ADEBWARN, ret, + "%s: cannot remove directory `%s'", + argv[0], argv[1]); + fcache_release(e); + free(dirname); + return 1; + } + + fcache_release(e); + } + free(dirname); + return 0; +} + +static int +arla_rm (int argc, char **argv) +{ + VenusFid fid; + int ret; + FCacheEntry *e; + char *dirname; + char *basename; + + if (argc != 2) { + printf ("usage: %s file\n", argv[0]); + return 0; + } + dirname = copy_dirname(argv[1]); + if (dirname == NULL) + err(1, "copy_dirname"); + basename = copy_basename(argv[1]); + if (basename == NULL) + err(1, "copy_basename"); + + if(cm_walk (cwd, dirname, &fid) == 0) { + + ret = fcache_get(&e, fid, ce); + if (ret) { + printf ("fcache_get failed: %d\n", ret); + free(dirname); + free(basename); + return 0; + } + + ret = cm_remove(&e, basename, &ce); + if (ret) { + arla_warn (ADEBWARN, ret, + "%s: cannot remove file `%s'", + argv[0], argv[1]); + fcache_release(e); + free(dirname); + free(basename); + return 1; + } + + fcache_release(e); + } + free(dirname); + free(basename); + return 0; +} + +static int +arla_put (int argc, char **argv) +{ + VenusFid dirfid; + VenusFid fid; + int ret; + FCacheEntry *e; + char *localname; + char *localbasename; + char *afsname; + char *afsbasename; + char *afsdirname; + AFSStoreStatus store_attr; + AFSFetchStatus fetch_attr; + int afs_fd; + int local_fd; + char buf[8192]; + int write_ret; + CredCacheEntry *ce; + + if (argc != 2 && argc != 3) { + printf ("usage: %s localfile [afsfile]\n", argv[0]); + return 0; + } + + localname = argv[1]; + + localbasename = copy_basename(localname); + if (localbasename == NULL) + err(1, "copy_basename"); + + if (argc == 3) { + afsname = argv[2]; + } else { + afsname = localbasename; + } + + afsdirname = copy_dirname(afsname); + if (afsdirname == NULL) + err(1, "copy_dirname"); + afsbasename = copy_basename(afsname); + if (afsbasename == NULL) + err(1, "copy_basename"); + + + printf("localbasename: *%s* afsname: *%s* afsdirname: *%s* afsbasename: *%s*\n", + localbasename, afsname, afsdirname, afsbasename); + + local_fd = open (localname, O_RDONLY, 0); + + if (local_fd < 0) { + printf ("open %s: %s\n", localname, strerror(errno)); + ret = 0; + goto out; + } + + if(cm_walk (cwd, afsdirname, &dirfid)) + goto out; + + ce = cred_get (dirfid.Cell, getuid(), CRED_ANY); + + ret = fcache_get(&e, dirfid, ce); + if (ret) { + printf ("fcache_get failed: %d\n", ret); + ret = 1; + goto out; + } + + memset(&store_attr, 0, sizeof(store_attr)); + + ret = cm_create(&e, afsbasename, &store_attr, &fid, &fetch_attr, &ce); + if (ret) { + if (ret != EEXIST) { + arla_warn (ADEBWARN, ret, + "%s: cannot create file `%s'", + argv[0], afsname); + fcache_release(e); + ret = 1; + goto out; + } else { + ret = cm_lookup (&e, afsbasename, &fid, &ce, 1); + if (ret) { + arla_warn (ADEBWARN, ret, + "%s: cannot open file `%s'", + argv[0], afsname); + fcache_release(e); + ret = 1; + goto out; + } + } + } + + fcache_release(e); + + ret = fcache_get(&e, fid, ce); + if (ret) { + printf ("fcache_get failed: %d\n", ret); + ret = 1; + goto out; + } + + ret = fcache_get_data (&e, &ce, 0); + if (ret) { + fcache_release(e); + printf ("fcache_get_data failed: %d\n", ret); + ret = 1; + goto out; + } + + afs_fd = fcache_open_file (e, O_WRONLY); + + if (afs_fd < 0) { + fcache_release(e); + printf ("fcache_open_file failed: %d\n", errno); + ret = 0; + goto out; + } + + ret = ftruncate(afs_fd, 0); + if (ret) { + fcache_release(e); + printf ("ftruncate failed: %d\n", errno); + } + + while ((ret = read (local_fd, buf, sizeof(buf))) > 0) { + write_ret = write (afs_fd, buf, ret); + if (write_ret < 0) { + printf("write failed: %d\n", errno); + ret = 1; + goto out; + } else if (write_ret != ret) { + printf("short write: %d should be %d\n", write_ret, ret); + ret = 1; + goto out; + } + } + + close(afs_fd); + close(local_fd); + + memset(&store_attr, 0, sizeof(store_attr)); + + ret = cm_close (e, NNPFS_WRITE, &store_attr, ce); + if (ret) { + arla_warn (ADEBWARN, ret, + "%s: cannot close file `%s'", + argv[0], afsname); + fcache_release(e); + ret = 1; + goto out; + } + + fcache_release(e); + + out: + free(localbasename); + free(afsdirname); + free(afsbasename); + return 0; +} + +static int +arla_get (int argc, char **argv) +{ + return 0; +} static int arla_cat_et_wc (int argc, char **argv, int do_cat, int out_fd) @@ -397,11 +703,17 @@ arla_cat_et_wc (int argc, char **argv, int do_cat, int out_fd) printf ("usage: %s file\n", argv[0]); return 0; } - fid = cwd; - if(walk (&fid, argv[1]) == 0) { + if(cm_walk (cwd, argv[1], &fid) == 0) { - ret = fcache_get_data (&e, &fid, &ce); + ret = fcache_get(&e, fid, ce); if (ret) { + printf ("fcache_get failed: %d\n", ret); + return 0; + } + + ret = fcache_get_data (&e, &ce, 0); + if (ret) { + fcache_release(e); printf ("fcache_get_data failed: %d\n", ret); return 0; } @@ -461,6 +773,23 @@ arla_cp (int argc, char **argv) } static int +arla_sleep(int argc, char **argv) +{ + struct timeval tv; + + if (argc != 2) { + printf ("usage: %s <time>\n", argv[0]); + return 0; + } + + tv.tv_sec = atoi(argv[1]); + tv.tv_usec = 0; + IOMGR_Select(0, NULL, NULL, NULL, &tv); + + return 0; +} + +static int arla_wc (int argc, char **argv) { return arla_cat_et_wc(argc, argv, 0, -1); @@ -477,7 +806,7 @@ help (int argc, char **argv) static int arla_checkserver (int argc, char **argv) { - u_int32_t hosts[12]; + uint32_t hosts[12]; int num = sizeof(hosts)/sizeof(hosts[0]); conn_downhosts(cwd.Cell, hosts, &num, 0); @@ -554,7 +883,7 @@ arla_rx_status(int argc, char **argv) #endif -#ifdef KERBEROS +#ifdef HAVE_KRB4 static int get_cred(const char *princ, const char *inst, const char *krealm, @@ -573,16 +902,19 @@ get_cred(const char *princ, const char *inst, const char *krealm, return k_errno; } -#endif /* KERBEROS */ +#endif /* HAVE_KRB4 */ -void -arla_start (char *device_file, const char *cache_dir) +static void +arla_start (char *device_file, const char *cache_dir, int argc, char **argv) { + CredCacheEntry *ce; int error; -#ifdef KERBEROS + +#ifdef HAVE_KRB4 { - krbstruct krbdata; + struct cred_rxkad cred; + CREDENTIALS c; int ret; char *realm; const char *this_cell = cell_getthiscell (); @@ -593,24 +925,42 @@ arla_start (char *device_file, const char *cache_dir) "no db server for cell %s", this_cell); realm = krb_realmofhost (db_server); - ret = get_cred("afs", this_cell, realm, &krbdata.c); + ret = get_cred("afs", this_cell, realm, &c); if (ret) - ret = get_cred("afs", "", realm, &krbdata.c); + ret = get_cred("afs", "", realm, &c); if (ret) { arla_warnx (ADEBWARN, "getting ticket for %s: %s", this_cell, krb_get_err_text (ret)); - } else if (cred_add_krb4(getuid(), getuid(), &krbdata.c) == NULL) { - arla_warnx (ADEBWARN, "Could not insert tokens to arla"); - } + return; + } + + memset(&cred, 0, sizeof(cred)); + + memcpy(&cred.ct.HandShakeKey, c.session, sizeof(cred.ct.AuthHandle)); + cred.ct.AuthHandle = c.kvno; + cred.ct.ViceId = getuid(); + cred.ct.BeginTimestamp = c.issue_date + 1; + cred.ct.EndTimestamp = krb_life_to_time(c.issue_date, c.lifetime); + + cred.ticket_len = c.ticket_st.length; + if (cred.ticket_len > sizeof(cred.ticket)) + arla_errx (1, ADEBERROR, "ticket too large"); + memcpy(cred.ticket, c.ticket_st.dat, cred.ticket_len); + + cred_add (getuid(), CRED_KRB4, 2, cell_name2num(cell_getthiscell()), + 2, &cred, sizeof(cred), getuid()); + } -#endif +#endif /* HAVE_KRB4 */ ce = cred_get (cell_name2num(cell_getthiscell()), getuid(), CRED_ANY); + + assert (ce != NULL); - xfs_message_init (); + nnpfs_message_init (); kernel_opendevice ("null"); arla_warnx (ADEBINIT, "Getting root..."); @@ -619,8 +969,18 @@ arla_start (char *device_file, const char *cache_dir) arla_err (1, ADEBERROR, error, "getroot"); cwd = rootcwd; arla_warnx(ADEBINIT, "arla loop started"); - sl_loop(cmds, "arla> "); + error = 0; + if (argc > 0) { + error = sl_command(cmds, argc, argv); + if (error == -1) + errx (1, "%s: Unknown command\n", argv[0]); + } else { + sl_loop(cmds, "arla> "); + } store_state(); + fcache_giveup_all_callbacks(); + if (error) + exit(1); } char * @@ -655,7 +1015,7 @@ static struct getargs args[] = { {"rxkad-level", 'r', arg_string, &rxkad_level_string, "the rxkad level to use (clear, auth or crypt)", NULL}, #endif - {"sysname", 's', arg_string, &temp_sysname, + {"sysname", 's', arg_string, &argv_sysname, "set the sysname of this system", NULL}, {"root-volume",0, arg_string, &root_volume}, {"port", 0, arg_integer, &client_port, @@ -677,7 +1037,7 @@ static struct getargs args[] = { static void usage (int ret) { - arg_printusage (args, sizeof(args)/sizeof(*args), NULL, "[device]"); + arg_printusage (args, sizeof(args)/sizeof(*args), NULL, "[command]"); exit (ret); } @@ -688,6 +1048,8 @@ main (int argc, char **argv) int ret; set_progname (argv[0]); + tzset(); + srand(time(NULL)); if (getarg (args, sizeof(args)/sizeof(*args), argc, argv, &optind)) usage (1); @@ -698,19 +1060,23 @@ main (int argc, char **argv) if (help_flag) usage (0); - if (version_flag) - errx (1, "%s", arla_version); + if (version_flag) { + print_version (NULL); + exit (0); + } - if (argc != 0) - usage (1); - default_log_file = "/dev/stderr"; - ret = arla_init(argc, argv); + ret = arla_init(); if (ret) return ret; - arla_start (NULL, cache_dir); + { + struct timeval tv = { 0, 10000} ; + IOMGR_Select(0, NULL, NULL, NULL, &tv); + } + + arla_start (NULL, cache_dir, argc, argv); return 0; } diff --git a/usr.sbin/afs/src/arlad/arla.c b/usr.sbin/afs/src/arlad/arla.c index 39294d7c903..b6e09542b02 100644 --- a/usr.sbin/afs/src/arlad/arla.c +++ b/usr.sbin/afs/src/arlad/arla.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2003 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -39,18 +39,21 @@ #include <parse_units.h> #include <getarg.h> -RCSID("$KTH: arla.c,v 1.135.2.2 2001/09/14 13:26:31 lha Exp $") ; +RCSID("$arla: arla.c,v 1.163 2003/06/10 16:25:07 lha Exp $") ; enum connected_mode connected_mode = CONNECTED; static void initrx (int port) { - int error; + int error; - error = rx_Init (htons(port)); - if (error) - arla_err (1, ADEBERROR, error, "rx_init"); + if (port == 0) + port = afscallbackport; + + error = rx_Init (htons(port)); + if (error) + arla_err (1, ADEBERROR, error, "rx_init"); } @@ -63,10 +66,16 @@ store_state (void) cm_store_state (); } +typedef enum { CONF_PARAM_INT, + CONF_PARAM_STR, + CONF_PARAM_BOOL, + CONF_PARAM_INT64 +} conf_type; + struct conf_param { const char *name; - unsigned *val; - unsigned default_val; + conf_type type; + void *val; }; /* @@ -74,13 +83,14 @@ struct conf_param { */ static struct units size_units[] = { + { "G", 1024 * 1024 * 1024 }, { "M", 1024 * 1024 }, { "k", 1024 }, { NULL, 0 } }; static void -read_conffile(char *fname, +read_conffile(const char *fname, struct conf_param *params) { FILE *fp; @@ -88,9 +98,6 @@ read_conffile(char *fname, int lineno; struct conf_param *p; - for (p = params; p->name; ++p) - *(p->val) = p->default_val; - arla_warnx (ADEBINIT, "read_conffile: %s", fname); fp = fopen(fname, "r"); @@ -107,13 +114,12 @@ read_conffile(char *fname, char *save = NULL; char *n; char *v; - unsigned val; + int64_t val; char *endptr; ++lineno; - if (buf[strlen(buf) - 1] == '\n') - buf[strlen(buf) - 1] = '\0'; - if (buf[0] == '#') + buf[strcspn(buf, "\n")] = '\0'; + if (buf[0] == '\0' || buf[0] == '#') continue; n = strtok_r (buf, " \t", &save); @@ -128,14 +134,7 @@ read_conffile(char *fname, continue; } - val = parse_units(v, size_units, NULL); - if(val == (unsigned)-1) { - val = strtol(v, &endptr, 0); - if (endptr == v) - fprintf (stderr, "%s:%d: bad value `%s'\n", - fname, lineno, v); - } - + for (p = params; p->name; ++p) { if (strcmp(n, p->name) == 0) { partial_match = 1; @@ -146,19 +145,70 @@ read_conffile(char *fname, partial_param = p; } } - if (partial_match == 1) - *(partial_param->val) = val; - else if (partial_match == 0) + if (partial_match == 0) { fprintf (stderr, "%s:%d: unknown parameter `%s'\n", fname, lineno, n); - else + continue; + } else if (partial_match != 1) { fprintf (stderr, "%s:%d: ambiguous parameter `%s'\n", fname, lineno, n); + continue; + } + + p = partial_param; + + switch (p->type) { + case CONF_PARAM_INT: + case CONF_PARAM_INT64: + + val = parse_units(v, size_units, NULL); + if(val == -1 || val < 0) { +#ifdef HAVE_STRTOLL + val = strtoll(v, &endptr, 0); +#else + val = strtol(v, &endptr, 0); +#endif + if (*endptr != '\0') + fprintf (stderr, "%s:%d: bad value `%s'\n", + fname, lineno, v); + } + + if (p->type == CONF_PARAM_INT) + *((unsigned *)partial_param->val) = val; + else if (p->type == CONF_PARAM_INT64) + *((int64_t *)partial_param->val) = val; + else + abort(); + break; + + case CONF_PARAM_STR: + + *((char **)partial_param->val) = strdup(v); + + break; + + case CONF_PARAM_BOOL: + + if (strcasecmp(v, "yes") == 0 || strcasecmp(v, "true") == 0) + *((unsigned *)partial_param->val) = 1; + else if (strcasecmp(v, "no") == 0 || strcasecmp(v, "false") == 0) + *((unsigned *)partial_param->val) = 0; + else + fprintf (stderr, "%s:%d: bad boolean value `%s'\n", + fname, lineno, v); + break; + default: + abort(); + } + + + } fclose(fp); } -#if KERBEROS && !defined(HAVE_KRB_GET_ERR_TEXT) +#ifdef HAVE_KRB4 +#ifndef HAVE_KRB_GET_ERR_TEXT #ifndef MAX_KRB_ERRORS #define MAX_KRB_ERRORS 256 @@ -173,31 +223,46 @@ krb_get_err_text(int code) return err_failure; return krb_err_txt[code]; } + +#endif #endif -static unsigned low_vnodes, high_vnodes, low_bytes, high_bytes; -static unsigned numcreds, numconns, numvols, dynrootlevel; +static unsigned low_vnodes = ARLA_LOW_VNODES; +static unsigned high_vnodes = ARLA_HIGH_VNODES; +static int64_t low_bytes = ARLA_LOW_BYTES; +static int64_t high_bytes = ARLA_HIGH_BYTES; +static unsigned numcreds = ARLA_NUMCREDS; +static unsigned numconns = ARLA_NUMCONNS; +static unsigned numvols = ARLA_NUMVOLS; +static unsigned dynrootlevel = DYNROOT_DEFAULT; +static char *conf_sysname = NULL; /* sysname from conf file */ +const char *argv_sysname = NULL; /* sysname from argv */ +#ifdef KERBEROS +const char *rxkad_level_string = "crypt"; +#endif static struct conf_param conf_params[] = { - {"low_vnodes", &low_vnodes, ARLA_LOW_VNODES}, - {"high_vnodes", &high_vnodes, ARLA_HIGH_VNODES}, - {"low_bytes", &low_bytes, ARLA_LOW_BYTES}, - {"high_bytes", &high_bytes, ARLA_HIGH_BYTES}, - {"numcreds", &numcreds, ARLA_NUMCREDS}, - {"numconns", &numconns, ARLA_NUMCREDS}, - {"numvols", &numvols, ARLA_NUMVOLS}, - {"fpriority", &fprioritylevel, FPRIO_DEFAULT}, - {"dynroot", &dynrootlevel, DYNROOT_DEFAULT}, - {NULL, NULL, 0}}; - -char *conf_file = ARLACONFFILE; + {"dynroot", CONF_PARAM_BOOL, &dynrootlevel}, + {"fake_stat", CONF_PARAM_BOOL, &fake_stat}, + {"fetch_block", CONF_PARAM_INT, &fetch_block_size}, + {"low_vnodes", CONF_PARAM_INT, &low_vnodes}, + {"high_vnodes", CONF_PARAM_INT, &high_vnodes}, + {"low_bytes", CONF_PARAM_INT64, &low_bytes}, + {"high_bytes", CONF_PARAM_INT64, &high_bytes}, + {"numcreds", CONF_PARAM_INT, &numcreds}, + {"numconns", CONF_PARAM_INT, &numconns}, + {"numvols", CONF_PARAM_INT, &numvols}, + {"sysname", CONF_PARAM_STR, &conf_sysname}, +#ifdef KERBEROS + {"rxkad-level", CONF_PARAM_STR, &rxkad_level_string}, +#endif + { NULL } +}; + +const char *conf_file = ARLACONFFILE; char *log_file = NULL; char *debug_levels = NULL; char *connected_mode_string = NULL; -#ifdef KERBEROS -char *rxkad_level_string = "auth"; -#endif -const char *temp_sysname = NULL; char *root_volume; int cpu_usage; int version_flag; @@ -205,6 +270,7 @@ int help_flag; int recover = 0; int dynroot_enable = 0; int cm_consistency = 0; +int fake_stat = 0; /* * These are exported to other modules @@ -279,26 +345,18 @@ set_connected_mode (const char *s) */ int -arla_init (int argc, char **argv) +arla_init (void) { log_flags log_flags; char fpriofile[MAXPATHLEN]; - - if (temp_sysname == NULL) - temp_sysname = arla_getsysname (); - - if (temp_sysname != NULL) - strlcpy(arlasysname, temp_sysname, SYSNAMEMAXLEN); - -#ifdef KERBEROS - conn_rxkad_level = parse_rxkad_level (rxkad_level_string); - if (conn_rxkad_level < 0) - errx (1, "bad rxkad level `%s'", rxkad_level_string); -#endif + const char *temp_sysname; if (log_file == NULL) log_file = default_log_file; + if (strcmp(log_file, "syslog") == 0) + log_file = "syslog:no-delay"; + log_flags = 0; if (cpu_usage) log_flags |= LOG_CPU_USAGE; @@ -322,6 +380,12 @@ arla_init (int argc, char **argv) read_conffile(conf_file, conf_params); +#ifdef KERBEROS + conn_rxkad_level = parse_rxkad_level (rxkad_level_string); + if (conn_rxkad_level < 0) + errx (1, "bad rxkad level `%s'", rxkad_level_string); +#endif + if (cache_dir == NULL) cache_dir = get_default_cache_dir(); @@ -331,6 +395,16 @@ arla_init (int argc, char **argv) arla_err (1, ADEBERROR, errno, "chdir %s", cache_dir); + if (argv_sysname) + temp_sysname = argv_sysname; + else if (conf_sysname) + temp_sysname = conf_sysname; + else + temp_sysname = arla_getsysname (); + + if (temp_sysname != NULL) + fcache_setdefsysname(temp_sysname); + if (dynrootlevel || dynroot_enable) dynroot_setenable (TRUE); @@ -345,12 +419,16 @@ arla_init (int argc, char **argv) connected_levels[connected_mode]); arla_warnx (ADEBINIT, "ports_init"); ports_init (); + arla_warnx (ADEBINIT, "uae_init"); + uae_init (); arla_warnx (ADEBINIT, "rx"); initrx (client_port); arla_warnx (ADEBINIT, "conn_init numconns = %u", numconns); conn_init (numconns); arla_warnx (ADEBINIT, "cellcache"); cell_init (0, arla_log_method); + arla_warnx (ADEBINIT, "poller"); + poller_init(); arla_warnx (ADEBINIT, "fprio"); fprio_init(fpriofile); arla_warnx (ADEBINIT, "volcache numvols = %u", numvols); @@ -370,9 +448,9 @@ arla_init (int argc, char **argv) arla_warnx (ADEBINIT, "fcache low_vnodes = %u, high_vnodes = %u" - "low_bytes = %u, high_bytes = %u", + "low_bytes = %ld, high_bytes = %ld", low_vnodes, high_vnodes, - low_bytes, high_bytes); + (long)low_bytes, (long)high_bytes); fcache_init (low_vnodes, high_vnodes, low_bytes, high_bytes, recover); diff --git a/usr.sbin/afs/src/arlad/arla.conf.5 b/usr.sbin/afs/src/arlad/arla.conf.5 index 732c7f8fb84..75ddf401fc2 100644 --- a/usr.sbin/afs/src/arlad/arla.conf.5 +++ b/usr.sbin/afs/src/arlad/arla.conf.5 @@ -1,47 +1,105 @@ -.\" Copyright (c) 2000 Kungliga Tekniska Högskolan -.\" $KTH: arla.conf.5,v 1.1 2000/09/09 14:24:38 lha Exp $ +.\" Copyright (c) 2000 - 2003 Kungliga Tekniska Högskolan +.\" $arla: arla.conf.5,v 1.16 2003/06/06 12:53:55 hin Exp $ .Dd Sep 09, 2000 .Dt afsd.conf 5 -.Os Arla +.Os "The Arla Project" .Sh NAME .Nm afsd.conf .Nd -configuration file for the arla afs implementation. +configuration file for the arla AFS implementation. .Sh SYNOPSIS The default configuration file works very well in most cases. .Sh DESCRIPTION Most flags can be overridden by command line arguments to .Nm afsd . .Pp -Supported flags: +Each option can be of the type integer, string or boolean. +.Pp +Integer values can be written with suffix +.Sq K +(kilo, 1000), +.Sq M +(mega, 10000000) +and +.Sq G +(giga, 10000000000) . +.Pp +Strings are written without quotes or spaces in the strings. +.Pp +Boolean values can be either of +.Ar yes , +.Ar true , +.Ar no , +or +.Ar false . +.Pp +Supported options: .Bl -tag -width Ds -.It high_vnodes -The upper limit of afsd's vnodes (think files and directories). +.It dynroot +Boolean value. Dynamic root, generates your +.Pa /afs +directory from +.Pa CellServDB or +.Pa DynRootDB . +Useful when you don't want to use your cell's root.afs. +.It fake_stat +Boolean value. +If set, do not fetch real stat information where it can be expensive +(i e across mountpoints), but make up some reasonable values. +.It fetch_block +Integer value. +Determines the fetch/pre-fetch block size. +This option will later be replaced by code to automagically tune this +setting. .It low_vnodes +Integer value. The number of used vnodes we try to keep in the cache. Any higher number of used nodes will trigger the cleaner thread. .It high_bytes -The high watermark for files used by afsd. +Integer value. +The high watermark for files used by arlad. .It low_bytes -The number of bytes we try to keep in the cache. Any higher number of -bytes will trigger the cleaner thread. +Integer value. +The number of bytes we try to keep in the cache. +Any higher number of bytes will trigger the cleaner thread. .It numcreds -The number of credentials in afsd, both unauthenticated, and authenticated -(like Kerberos V4 creds). +Integer value. +The maximum number of credentials kept in arla, both authenticated +(like Kerberos V4 creds), and not. .It numconns -The maximum connections afsd will have to all servers (fileserver and -vldb-server). +Integer value. +The maximum total number of connections arla will keep to servers +(fileserver and vldb-server). .It numvols +Integer value. The number of volumes stored in cache. -.It fpriority -File priority, the describes how the cleaner process will clean out -files when set to a non-zero value. You might lose files that you fell -is important (and isn't marked with priority flag) when you are in -disconnected mode. You might not want to set this since then you'll -loose valuble diskspace for to `sticky' files. +.It sysname +String value. +The sysname is possible to specify in the configuration file. It's +overridden by the command line argument +.Ar --sysname=sysname +to arlad. +.It rxkad-level +It can be one of: +.Ar clear , +.Ar auth , +or +.Ar crypt . +It's the same as the command line argument. +.It high_vnodes +Integer value. +The upper limit of arlad's vnodes (think files and directories). .El +.Sh BUGS +The parser that reads numbers doesn't support numbers larger than 2G +for most platforms when used on the abbreviated form (3G, 3000M, +etc). +Write out the whole number (3000000000) and make sure you have a +working +.Fn strtoll . .Sh SEE ALSO +.Xr AliasDB 5 , .Xr CellServDB 5 , -.Xr TheseCells 5 , +.Xr DynRootDB 5 , .Xr ThisCell 5 , .Xr afsd 8 diff --git a/usr.sbin/afs/src/arlad/arla_local.h b/usr.sbin/afs/src/arlad/arla_local.h index 5932d1a4d15..96e82c52d68 100644 --- a/usr.sbin/afs/src/arlad/arla_local.h +++ b/usr.sbin/afs/src/arlad/arla_local.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2003 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ /* * Include file for whole arlad - * $KTH: arla_local.h,v 1.61.2.3 2001/09/14 13:25:45 lha Exp $ + * $arla: arla_local.h,v 1.88 2003/06/10 16:26:19 lha Exp $ */ #ifdef HAVE_CONFIG_H @@ -68,7 +68,6 @@ #ifdef HAVE_SYS_MMAN_H #include <sys/mman.h> #endif -#include <sys/stat.h> #ifdef HAVE_SYS_IOCCOM_H #include <sys/ioccom.h> #endif @@ -95,20 +94,23 @@ #include <rx/rx.h> #include <rx/rx_null.h> -#include <rx/rxgencon.h> -#ifdef KERBEROS +#ifdef HAVE_KRB4 +#ifdef HAVE_OPENSSL +#include <openssl/des.h> +#else #include <des.h> +#endif #include <krb.h> -#include <rxkad.h> #endif +#include <rxkad.h> -#ifdef USE_MMAPTIME -#include <mmaptime.h> -#endif +#include <ifaddrs.h> #include <kafs.h> +#include <uae.h> + #include "log.h" #include "fs.h" @@ -119,25 +121,30 @@ #include "vldb.cs.h" #include "volcache.h" #include "fbuf.h" +#include "bool.h" #include "hash.h" +#include "heap.h" #include "afs_dir.h" -#include "service.h" #include "ports.h" #include "conn.h" +#include "poller.h" #include "fcache.h" +#include "state.h" #include "inter.h" #include "cred.h" #include "adir.h" #include "service.h" #include "subr.h" #include "fprio.h" -#include "bool.h" +#include "disco.h" +#include "stats.h" #include "kernel.h" #include "messages.h" #include "fs_errors.h" #include "arladeb.h" #include "ko.h" -#include "xfs.h" +#include "nnpfs.h" +#include "afs_uuid.h" enum connected_mode { CONNECTED = 0, FETCH_ONLY = 1, @@ -146,15 +153,19 @@ enum connected_mode { CONNECTED = 0, extern enum connected_mode connected_mode; -#include "darla.h" -#include "discon_log.h" -#include "discon.h" -#include "reconnect.h" - #include "dynroot.h" +#if 0 +#define assert_flag(e,f) assert((e)->flags.f) +#define assert_not_flag(e,f) assert(!(e)->flags.f) +#else +#define assert_flag(e,f) do { } while(0) +#define assert_not_flag(e,f) do { } while(0) +#endif + #define SYSNAMEMAXLEN 2048 -extern char arlasysname[SYSNAMEMAXLEN]; +extern char **sysnamelist; +extern int sysnamenum; #define ARLA_NUMCONNS 200 @@ -167,7 +178,7 @@ extern char arlasysname[SYSNAMEMAXLEN]; /* * This should be a not used uid in the system, - * XFS_ANONYMOUSID may be good + * NNPFS_ANONYMOUSID may be good */ #define ARLA_NO_AUTH_CRED 4 @@ -184,11 +195,8 @@ extern int afs_BusyWaitPeriod; /* number of sec to wait on fs when VBUSY */ void store_state (void); -void -arla_start (char *device_file, const char *cache_dir); - int -arla_init (int argc, char **argv); +arla_init (void); char * get_default_cache_dir (void); @@ -197,14 +205,14 @@ get_default_cache_dir (void); #define O_BINARY 0 #endif -extern char *conf_file; +extern const char *conf_file; extern char *log_file; extern char *debug_levels; extern char *connected_mode_string; #ifdef KERBEROS -extern char *rxkad_level_string; +extern const char *rxkad_level_string; #endif -extern const char *temp_sysname; +extern const char *argv_sysname; extern char *root_volume; extern int cpu_usage; extern int version_flag; @@ -212,5 +220,7 @@ extern int help_flag; extern int recover; extern int dynroot_enable; extern int cm_consistency; +extern int fake_stat; +extern int fetch_block_size; extern char *cache_dir; diff --git a/usr.sbin/afs/src/arlad/arlad.8 b/usr.sbin/afs/src/arlad/arlad.8 index 09118cfd5cc..cc23ebfcded 100644 --- a/usr.sbin/afs/src/arlad/arlad.8 +++ b/usr.sbin/afs/src/arlad/arlad.8 @@ -1,13 +1,45 @@ -.\" $OpenBSD: arlad.8,v 1.5 2003/01/29 16:53:36 jmc Exp $ -.\" $KTH: arlad.8,v 1.7.2.2 2001/05/06 22:49:03 ahltorp Exp $ +.\" Copyright (c) 2000 - 2003 Kungliga Tekniska Högskolan +.\" (Royal Institute of Technology, Stockholm, Sweden). +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" 3. Neither the name of the Institute nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $OpenBSD: arlad.8,v 1.6 2003/08/05 08:42:41 hin Exp $ +.\" $arla: arlad.8,v 1.18 2003/06/06 12:53:56 hin Exp $ +.\" .Dd September 5, 1998 .Dt AFSD 8 -.Os +.Os "The Arla Project" .Sh NAME .Nm afsd .Nd AFS cache manager .Sh SYNOPSIS -.Nm afsd +.Nm .Bk -words .Op Fl t | Fl -test .Oo Fl c Ar string \*(Ba Xo @@ -33,6 +65,7 @@ .Op Fl z | Fl -recover .Op Fl -cache-dir= Ns Ar string .Op Fl D | -dynroot +.Op Fl -cpu-usage .Op Fl -version .Op Fl -help .Op Ar device @@ -73,8 +106,8 @@ What to write in the log (default: none). .Fl d Ar string Ns , .Fl -device= Ns Ar string .Xc -The XFS device to use -.Po default: Pa /dev/xfs0 +The NNPFS device to use +.Po default: Pa /dev/nnpfs0 .Pc . .It Xo .Fl -connected-mode= Ns Ar string @@ -89,7 +122,7 @@ Don't fork and daemonize. .Fl r Ar string Ns , .Fl -rxkad-level= Ns Ar string .Xc -The rxkad level to use [clear|auth|crypt] (default: auth). +The rxkad level to use [clear|auth|crypt] (default: crypt). .It Xo .Fl s Ar string Ns , .Fl -sysname= Ns Ar string @@ -120,6 +153,11 @@ Cache directory .Xc Use dynamic root. .It Xo +.Fl -cpu-usage +.Xc +System and userland cpu-usage times is appended at the end line that +is logged. +.It Xo .Fl -version .Xc Print version information. @@ -146,6 +184,7 @@ drastically improve performance. .Xr fs 1 , .Xr pts 1 , .Xr afsd.conf 5 , +.Xr AliasDB 5 , .Xr CellServDB 5 , .Xr DynRootDB 5 , .Xr SuidCells 5 , diff --git a/usr.sbin/afs/src/arlad/arlad.c b/usr.sbin/afs/src/arlad/arlad.c index ee4acb64152..686acca6ace 100644 --- a/usr.sbin/afs/src/arlad/arlad.c +++ b/usr.sbin/afs/src/arlad/arlad.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,16 +33,19 @@ #include <arla_local.h> #include <getarg.h> -#include <arla-version.h> -RCSID("$KTH: arlad.c,v 1.5.2.2 2001/07/26 02:05:26 assar Exp $"); +#include <vers.h> +RCSID("$arla: arlad.c,v 1.21 2003/01/17 03:00:11 lha Exp $"); #define KERNEL_STACKSIZE (16*1024) char *default_log_file = "syslog"; -int client_port = 4711; +int client_port = 0; static char *pid_filename; +#define _PATH_VAR_RUN "/var/run" +#define _PATH_DEV_NNPFS0 "/dev/nnpfs0" +#define _PATH_DEV_STDERR "/dev/stderr" /* * @@ -54,7 +57,7 @@ write_pid_file (const char *progname) { FILE *fp; - asprintf (&pid_filename, "/var/run/%s.pid", progname); + asprintf (&pid_filename, _PATH_VAR_RUN "/%s.pid", progname); if (pid_filename == NULL) return; fp = fopen (pid_filename, "w"); @@ -134,7 +137,7 @@ daemonify (void) } -void +static void arla_start (char *device_file, const char *cache_dir) { struct kernel_args kernel_args; @@ -149,13 +152,13 @@ arla_start (char *device_file, const char *cache_dir) prctl(PR_SET_DUMPABLE, 1); #endif - xfs_message_init (); + nnpfs_message_init (); kernel_opendevice (device_file); kernel_args.num_workers = num_workers; if (LWP_CreateProcess (kernel_interface, KERNEL_STACKSIZE, 1, - (char *)&kernel_args, + (char *)&kernel_args, "Kernel-interface", &kernelpid)) arla_errx (1, ADEBERROR, "Cannot create kernel-interface process"); @@ -165,8 +168,8 @@ arla_start (char *device_file, const char *cache_dir) if (chroot (cache_dir) < 0) arla_err (1, ADEBERROR, errno, "chroot %s", cache_dir); - if (chdir ("/") < 0) - arla_err (1, ADEBERROR, errno, "chdir /"); + if (chdir("/") < 0) + arla_err (1, ADEBERROR, errno, "chdir /"); if (fork_flag) kill(getppid(), SIGUSR1); @@ -181,44 +184,46 @@ get_default_cache_dir (void) return ARLACACHEDIR; } -char *device_file = "/dev/xfs0"; +char *device_file = _PATH_DEV_NNPFS0; static struct getargs args[] = { - {"conffile", 'c', arg_string, &conf_file, - "path to configuration file", "file"}, + {"cache-dir", 0, arg_string, &cache_dir, + "cache directory", "directory"}, {"check-consistency", 'C', arg_flag, &cm_consistency, "if we want extra paranoid consistency checks", NULL }, - {"log", 'l', arg_string, &log_file, - "where to write log (stderr (default), syslog, or path to file)", NULL}, + {"cpu-usage", 0, arg_flag, &cpu_usage, + NULL, NULL}, + {"conffile", 'c', arg_string, &conf_file, + "path to configuration file", "file"}, + {"connected-mode", 0, arg_string, &connected_mode_string, + "initial connected mode [conncted|fetch-only|disconnected]", NULL}, {"debug", 0, arg_string, &debug_levels, "what to write in the log", NULL}, {"device", 'd', arg_string, &device_file, - "the XFS device to use [/dev/xfs0]", "path"}, - {"connected-mode", 0, arg_string, &connected_mode_string, - "initial connected mode [conncted|fetch-only|disconnected]", NULL}, + "the NNPFS device to use [/dev/nnpfs0]", "path"}, {"dynroot", 'D', arg_flag, &dynroot_enable, "if dynroot is enabled", NULL}, + {"log", 'l', arg_string, &log_file, + "where to write log (stderr (default), syslog, or path to file)", NULL}, + {"fake-mp", 0, arg_flag, &fake_mp, + "enable fake mountpoints", NULL}, + {"fake-stat", 0, arg_flag, &fake_stat, + "build stat info from afs rights", NULL}, {"fork", 'n', arg_negative_flag, &fork_flag, "don't fork and demonize", NULL}, + {"port", 0, arg_integer, &client_port, + "port number to use", "number"}, + {"recover", 'z', arg_negative_flag, &recover, + "don't recover state", NULL}, + {"root-volume",0, arg_string, &root_volume}, #ifdef KERBEROS {"rxkad-level", 'r', arg_string, &rxkad_level_string, "the rxkad level to use (clear, auth or crypt)", NULL}, #endif - {"sysname", 's', arg_string, &temp_sysname, + {"sysname", 's', arg_string, &argv_sysname, "set the sysname of this system", NULL}, - {"root-volume",0, arg_string, &root_volume}, - {"port", 0, arg_integer, &client_port, - "port number to use", "number"}, - {"recover", 'z', arg_negative_flag, &recover, - "don't recover state", NULL}, - {"cache-dir", 0, arg_string, &cache_dir, - "cache directory", "directory"}, {"workers", 0, arg_integer, &num_workers, "number of worker threads", NULL}, - {"fake-mp", 0, arg_flag, &fake_mp, - "enable fake mountpoints", NULL}, - {"cpu-usage", 0, arg_flag, &cpu_usage, - NULL, NULL}, {"version", 0, arg_flag, &version_flag, NULL, NULL}, {"help", 0, arg_flag, &help_flag, @@ -238,6 +243,9 @@ main (int argc, char **argv) int optind = 0; int ret; + tzset(); + srand(time(NULL)); + if (getarg (args, sizeof(args)/sizeof(*args), argc, argv, &optind)) usage (1); @@ -247,8 +255,10 @@ main (int argc, char **argv) if (help_flag) usage (0); - if (version_flag) - errx (1, "%s", arla_version); + if (version_flag) { + print_version (NULL); + exit (0); + } if (argc > 0) { device_file = *argv; @@ -260,12 +270,12 @@ main (int argc, char **argv) usage (1); if (!fork_flag) - default_log_file = "/dev/stderr"; + default_log_file = _PATH_DEV_STDERR; if (fork_flag) daemonify (); - ret = arla_init(argc, argv); + ret = arla_init(); if (ret) return ret; diff --git a/usr.sbin/afs/src/arlad/arladeb.c b/usr.sbin/afs/src/arlad/arladeb.c index f023f4a9416..c792053aa9e 100644 --- a/usr.sbin/afs/src/arlad/arladeb.c +++ b/usr.sbin/afs/src/arlad/arladeb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -32,13 +32,13 @@ */ #include <arla_local.h> -RCSID("$KTH: arladeb.c,v 1.24.2.2 2001/04/30 00:01:59 lha Exp $"); +RCSID("$arla: arladeb.c,v 1.29 2002/12/06 04:57:31 lha Exp $"); Log_method* arla_log_method = NULL; Log_unit* arla_log_unit = NULL; void -arla_log(unsigned level, char *fmt, ...) +arla_log(unsigned level, const char *fmt, ...) { va_list args; @@ -51,13 +51,13 @@ arla_log(unsigned level, char *fmt, ...) void -arla_loginit(char *log, log_flags flags) +arla_loginit(char *logname, log_flags flags) { - assert (log); + assert (logname); - arla_log_method = log_open("arla", log); + arla_log_method = log_open("arla", logname); if (arla_log_method == NULL) - errx (1, "arla_loginit: log_opened failed with log `%s'", log); + errx (1, "arla_loginit: log_opened failed with log `%s'", logname); arla_log_unit = log_unit_init (arla_log_method, "arla", arla_deb_units, ARLA_DEFAULT_LOG); if (arla_log_unit == NULL) diff --git a/usr.sbin/afs/src/arlad/arladeb.h b/usr.sbin/afs/src/arlad/arladeb.h index 8bb710c5f6e..502471a2c44 100644 --- a/usr.sbin/afs/src/arlad/arladeb.h +++ b/usr.sbin/afs/src/arlad/arladeb.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -32,7 +32,7 @@ */ /* - * $KTH: arladeb.h,v 1.24.2.1 2001/04/30 00:02:15 lha Exp $ + * $arla: arladeb.h,v 1.31 2002/12/06 04:58:00 lha Exp $ */ #ifndef _arladeb_h @@ -65,13 +65,14 @@ extern struct units arla_deb_units[]; #define ADEBWARN 0x08000000 /* don't ignore warning */ #define ADEBERROR 0x10000000 /* don't ignore error */ #define ADEBVLOG 0x20000000 /* venuslog output */ +#define ADEBINVALIDATOR 0x40000000 /* invalidator output */ #define ARLA_DEFAULT_LOG (ADEBWARN | ADEBERROR) extern struct units arla_deb_units[]; -void arla_log(unsigned level, char *fmt, ...); -void arla_loginit(char *log, log_flags flags); +void arla_log(unsigned level, const char *fmt, ...); +void arla_loginit(char *logname, log_flags flags); int arla_log_set_level (const char *s); void arla_log_set_level_num (unsigned level); void arla_log_get_level (char *s, size_t len); diff --git a/usr.sbin/afs/src/arlad/bsd-subr.c b/usr.sbin/afs/src/arlad/bsd-subr.c index 7b0b6946005..c764dcef657 100644 --- a/usr.sbin/afs/src/arlad/bsd-subr.c +++ b/usr.sbin/afs/src/arlad/bsd-subr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -39,16 +39,16 @@ #endif #include "arla_local.h" -RCSID("$KTH: bsd-subr.c,v 1.55.2.1 2001/01/29 02:02:17 lha Exp $"); +RCSID("$arla: bsd-subr.c,v 1.61 2003/02/15 02:24:08 lha Exp $"); #ifdef __linux__ -#include <xfs/xfs_dirent.h> +#include <nnpfs/nnpfs_dirent.h> #else -#define XFS_DIRENT_BLOCKSIZE 512 -#define xfs_dirent dirent +#define NNPFS_DIRENT_BLOCKSIZE 512 +#define nnpfs_dirent dirent #endif -static long blocksize = XFS_DIRENT_BLOCKSIZE; /* XXX */ +static long blocksize = NNPFS_DIRENT_BLOCKSIZE; /* XXX */ /* * Write out all remaining data in `args' @@ -59,7 +59,7 @@ flushbuf (void *vargs) { struct write_dirent_args *args = (struct write_dirent_args *)vargs; unsigned inc = blocksize - (args->ptr - args->buf); - struct xfs_dirent *last = (struct xfs_dirent *)args->last; + struct nnpfs_dirent *last = (struct nnpfs_dirent *)args->last; last->d_reclen += inc; if (write (args->fd, args->buf, blocksize) != blocksize) @@ -72,10 +72,10 @@ flushbuf (void *vargs) * Write a dirent to the args buf in `arg' containg `fid' and `name'. */ -static void +static int write_dirent(VenusFid *fid, const char *name, void *arg) { - struct xfs_dirent dirent, *real; + struct nnpfs_dirent dirent, *real; struct write_dirent_args *args = (struct write_dirent_args *)arg; dirent.d_namlen = strlen (name); @@ -89,7 +89,7 @@ write_dirent(VenusFid *fid, const char *name, void *arg) if (args->ptr + dirent.d_reclen > args->buf + blocksize) flushbuf (args); - real = (struct xfs_dirent *)args->ptr; + real = (struct nnpfs_dirent *)args->ptr; real->d_namlen = dirent.d_namlen; real->d_reclen = dirent.d_reclen; @@ -102,9 +102,10 @@ write_dirent(VenusFid *fid, const char *name, void *arg) args->ptr += real->d_reclen; args->off += real->d_reclen; args->last = real; + return 0; } -Result +int conv_dir (FCacheEntry *e, CredCacheEntry *ce, u_int tokens, fcache_cache_handle *cache_handle, char *cache_name, size_t cache_name_sz) @@ -133,8 +134,8 @@ dir_remove_name (FCacheEntry *e, const char *filename, char *buf; char *p; size_t len; - struct xfs_dirent *dp; - struct xfs_dirent *last_dp; + struct nnpfs_dirent *dp; + struct nnpfs_dirent *last_dp; fcache_extra_file_name (e, cache_name, cache_name_sz); fd = open (cache_name, O_RDWR, 0); @@ -157,21 +158,28 @@ dir_remove_name (FCacheEntry *e, const char *filename, ret = ENOENT; for (p = buf = fbuf_buf (&fb); p < buf + len; p += dp->d_reclen) { - dp = (struct xfs_dirent *)p; + dp = (struct nnpfs_dirent *)p; assert (dp->d_reclen > 0); if (strcmp (filename, dp->d_name) == 0) { if (last_dp != NULL) { + size_t off1, off2; unsigned len; /* - * It's not totally clear how large we can make - * d_reclen without loosing. Not making it larger - * than DIRBLKSIZ seems safe. + * d_reclen can be as largest (in worst case) + * DIRBLKSIZ, and may not cause the entry to cross a + * DIRBLKSIZ boundery. */ len = last_dp->d_reclen + dp->d_reclen; - if (len < DIRBLKSIZ) + + off1 = (char *)last_dp - buf; + off2 = off1 + len; + off1 /= DIRBLKSIZ; + off2 /= DIRBLKSIZ; + + if (len < DIRBLKSIZ && off1 == off2) last_dp->d_reclen = len; } dp->d_fileno = 0; diff --git a/usr.sbin/afs/src/arlad/cmcb.c b/usr.sbin/afs/src/arlad/cmcb.c index 2c5a3373d91..19bcc06039c 100644 --- a/usr.sbin/afs/src/arlad/cmcb.c +++ b/usr.sbin/afs/src/arlad/cmcb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2000, 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -36,7 +36,7 @@ */ #include "arla_local.h" -RCSID("$KTH: cmcb.c,v 1.29 2000/11/28 01:50:44 lha Exp $") ; +RCSID("$arla: cmcb.c,v 1.41 2003/03/06 00:38:47 lha Exp $") ; #include "cb.ss.h" @@ -44,12 +44,23 @@ RCSID("$KTH: cmcb.c,v 1.29 2000/11/28 01:50:44 lha Exp $") ; * Create an instance of the callback service and start a server. */ +static afsUUID arla_client_uuid; + +void +cmcb_reinit (void) +{ + if (afsUUID_create(&arla_client_uuid)) + arla_errx(1, ADEBWARN, "Failed to create uuid for client"); +} + void cmcb_init (void) { static struct rx_securityClass *nullSecObjP; static struct rx_securityClass *(securityObjects[1]); + cmcb_reinit (); + nullSecObjP = rxnull_NewClientSecurityObject (); if (nullSecObjP == NULL) arla_errx (1, ADEBWARN, "Cannot create null security object."); @@ -68,7 +79,7 @@ cmcb_init (void) */ int -RXAFSCB_Probe (struct rx_call *a_rxCallP) +SRXAFSCB_Probe (struct rx_call *a_rxCallP) { u_long host = rx_HostOf (rx_PeerOf (rx_ConnectionOf (a_rxCallP))); struct in_addr in_addr; @@ -79,27 +90,6 @@ RXAFSCB_Probe (struct rx_call *a_rxCallP) } /* - * Throw away all callbacks from the host in `a_rxCallP'. - */ - -int -RXAFSCB_InitCallBackState (struct rx_call *a_rxCallP) -{ - u_long host = rx_HostOf (rx_PeerOf (rx_ConnectionOf (a_rxCallP))); - struct in_addr in_addr; - - cm_check_consistency(); - - in_addr.s_addr = host; - arla_warnx (ADEBCALLBACK, "InitCallBackState (%s)", inet_ntoa(in_addr)); - fcache_purge_host (host); - - cm_check_consistency(); - - return 0; -} - -/* * Handle the callbacks in `a_fidArrayP' and `a_callBackArrayP' (this * array can be shorter). * There are two types of callbacks: @@ -108,18 +98,18 @@ RXAFSCB_InitCallBackState (struct rx_call *a_rxCallP) */ int -RXAFSCB_CallBack (struct rx_call *a_rxCallP, - const AFSCBFids *a_fidArrayP, - const AFSCBs *a_callBackArrayP) +SRXAFSCB_CallBack (struct rx_call *a_rxCallP, + const AFSCBFids *a_fidArrayP, + const AFSCBs *a_callBackArrayP) { int i; long cell; - u_long host = rx_HostOf (rx_PeerOf (rx_ConnectionOf (a_rxCallP))); + uint32_t host = rx_HostOf (rx_PeerOf (rx_ConnectionOf (a_rxCallP))); struct in_addr in_addr; in_addr.s_addr = host; arla_warnx (ADEBCALLBACK, "callback (%s)", inet_ntoa(in_addr)); - cell = conn_host2cell(host, afsport, FS_SERVICE_ID); + cell = poller_host2cell(host); if (cell == -1) arla_warnx (ADEBCALLBACK, "callback from unknown host: %s", @@ -152,62 +142,235 @@ RXAFSCB_CallBack (struct rx_call *a_rxCallP, int -RXAFSCB_GetLock(struct rx_call *a_rxCallP, - int32_t index, - AFSDBLock *lock) +SRXAFSCB_GetLock(struct rx_call *a_rxCallP, + int32_t index, + AFSDBLock *lock) { return 1; } int -RXAFSCB_GetCE(struct rx_call *a_rxCallP, - int32_t index, - AFSDBCacheEntry *dbentry) +SRXAFSCB_GetCE(struct rx_call *a_rxCallP, + int32_t index, + AFSDBCacheEntry *dbentry) { return 1; } int -RXAFSCB_XStatsVersion(struct rx_call *a_rxCallP, - int32_t *version) +SRXAFSCB_XStatsVersion(struct rx_call *a_rxCallP, + int32_t *version) { return RXGEN_OPCODE; } int -RXAFSCB_GetXStats(struct rx_call *a_rxCallP, - int32_t client_version_num, - int32_t collection_number, - int32_t *server_version_number, - int32_t *time, - AFSCB_CollData *stats) +SRXAFSCB_GetXStats(struct rx_call *a_rxCallP, + int32_t client_version_num, + int32_t collection_number, + int32_t *server_version_number, + int32_t *time, + AFSCB_CollData *stats) { return RXGEN_OPCODE; } + +/* + * Throw away all callbacks from the `host' + */ + +static void +init_callback_state(uint32_t host) +{ + struct in_addr in_addr; + + cm_check_consistency(); + + in_addr.s_addr = host; + arla_warnx (ADEBCALLBACK, "InitCallBackState (%s)", inet_ntoa(in_addr)); + fcache_purge_host (host); + + cm_check_consistency(); +} + +/* + * Init the CallBack address in `addr'. Returns 0 or RXGEN_OPCODE. + */ + +static int +init_address(interfaceAddr *addr) +{ + struct ifaddrs *ifa, *ifa0; + int num_addr; + + memset(addr, 0, sizeof(*addr)); + + addr->uuid = arla_client_uuid; + + if (getifaddrs(&ifa0) != 0) + return RXGEN_OPCODE; + + num_addr = 0; + + for (ifa = ifa0; ifa != NULL; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == NULL) + continue; + +#if IFF_LOOPBACK + if (ifa->ifa_flags & IFF_LOOPBACK) + continue; +#endif + + switch (ifa->ifa_addr->sa_family) { + case AF_INET: { + struct sockaddr_in *sin = (struct sockaddr_in *)ifa->ifa_addr; + struct sockaddr_in *netmask = (struct sockaddr_in *)ifa->ifa_netmask; + + if (sin->sin_addr.s_addr == htonl(0x7f000001)) + continue; + + addr->addr_in[num_addr] = sin->sin_addr.s_addr; + if (netmask) { + addr->subnetmask[num_addr] = netmask->sin_addr.s_addr; + } else { + /* dream up something */ + addr->subnetmask[num_addr] = htonl(0xffffff00); + } + + addr->mtu[num_addr] = 1500; /* XXX */ + + num_addr++; + break; + } + } + + if (num_addr >= AFS_MAX_INTERFACE_ADDR) + break; + } + + freeifaddrs(ifa0); + +#if 0 + /* fail if there was no good ipv4 addresses */ + if (num_addr == 0) + return RXGEN_OPCODE; +#endif + + addr->numberOfInterfaces = num_addr; + + return 0; +} + int -RXAFSCB_InitCallBackState2(struct rx_call *a_rxCallP, interfaceAddr *addr) +SRXAFSCB_InitCallBackState (struct rx_call *a_rxCallP) { - return RXGEN_OPCODE; + u_long host = rx_HostOf (rx_PeerOf (rx_ConnectionOf (a_rxCallP))); + + init_callback_state(host); + + return 0; } int -RXAFSCB_WhoAreYou(struct rx_call *a_rxCallP, - interfaceAddr *addr) +SRXAFSCB_InitCallBackState2 (struct rx_call *a_rxCallP, interfaceAddr *addr) +{ + u_long host = rx_HostOf (rx_PeerOf (rx_ConnectionOf (a_rxCallP))); + + init_callback_state(host); + + return init_address(addr); +} + +int +SRXAFSCB_InitCallBackState3 (struct rx_call *a_rxCallP, + const struct afsUUID *serverUuid) +{ + u_long host = rx_HostOf (rx_PeerOf (rx_ConnectionOf (a_rxCallP))); + + init_callback_state(host); + + return 0; +} + +int +SRXAFSCB_WhoAreYou(struct rx_call *a_rxCallP, + interfaceAddr *addr) +{ + return init_address(addr); +} + +int +SRXAFSCB_ProbeUUID(struct rx_call *a_rxCallP, + const struct afsUUID *uuid) +{ + /* the the uuids are equal, we are the host belive we is */ + + if (afsUUID_equal(uuid, &arla_client_uuid)) + return 0; + return 1; +} + +int +SRXAFSCB_GetCellServDB(struct rx_call *a_rxCallP, + const int32_t cellIndex, + char *cellName, + serverList *cellHosts) { return RXGEN_OPCODE; } int -RXAFSCB_InitCallBackState3(struct rx_call *a_rxCallP, - const struct afsUUID *serverUuid) +SRXAFSCB_GetLocalCell(struct rx_call *a_rxCallP, + char *cellName) +{ + strlcpy(cellName, cell_getthiscell(), AFSNAMEMAX); + return 0; +} + +int +SRXAFSCB_GetCacheConfig(struct rx_call *a_rxCallP, + const uint32_t callerVersion, + uint32_t *serverVersion, + uint32_t *configCount, + cacheConfig *config) { + *serverVersion = 0; + *configCount = 0; + config->len = 0; + config->val = NULL; + return RXGEN_OPCODE; } int -RXAFSCB_ProbeUUID(struct rx_call *a_rxCallP, - const struct afsUUID *uuid) +SRXAFSCB_GetCellByNum(struct rx_call *call, + const int32_t cellNumber, + char *cellName, + serverList *cellHosts) { return RXGEN_OPCODE; } + +int +SRXAFSCB_TellMeAboutYourself(struct rx_call *call, + struct interfaceAddr *addr, + Capabilities *capabilities) +{ + int ret; + + memset(addr, 0, sizeof(*addr)); + + capabilities->len = 1; + capabilities->val = malloc(sizeof(capabilities->val[0])); + if (capabilities->val == NULL) + return ENOMEM; + + capabilities->val[0] = 0x1; /* UAE */ + + ret = init_address(addr); + if (ret) + return ret; + + return 0; +} diff --git a/usr.sbin/afs/src/arlad/cmcb.h b/usr.sbin/afs/src/arlad/cmcb.h index 367ebaf0564..5ff92bde5dd 100644 --- a/usr.sbin/afs/src/arlad/cmcb.h +++ b/usr.sbin/afs/src/arlad/cmcb.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,11 +31,12 @@ * SUCH DAMAGE. */ -/* $KTH: cmcb.h,v 1.3 2000/10/02 22:30:54 lha Exp $ */ +/* $arla: cmcb.h,v 1.5 2002/07/24 06:02:02 lha Exp $ */ #ifndef _CMCB_H_ #define _CMCB_H_ void cmcb_init (void); +void cmcb_reinit (void); #endif /* _CMCB_H_ */ diff --git a/usr.sbin/afs/src/arlad/conn.c b/usr.sbin/afs/src/arlad/conn.c index 0b8a8ecae10..ac0552eff45 100644 --- a/usr.sbin/afs/src/arlad/conn.c +++ b/usr.sbin/afs/src/arlad/conn.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -38,7 +38,7 @@ #include "arla_local.h" #ifdef RCSID -RCSID("$KTH: conn.c,v 1.61.2.3 2001/09/03 22:12:07 ahltorp Exp $") ; +RCSID("$arla: conn.c,v 1.75 2003/06/10 04:23:20 lha Exp $") ; #endif #define CONNCACHESIZE 101 @@ -89,6 +89,9 @@ connhash (void *a) return c->cred + c->host + c->service + c->port + c->securityindex; } +/* 2^MAX_RETRIES is the maximum number of seconds between probes */ + +#define MAX_RETRIES 8 /* * Add this entry again to the probe list but without restarting ntries. @@ -102,15 +105,15 @@ re_probe (ConnCacheEntry *e) assert (e->probe != NULL); - if (e->probe_le != NULL) - listdel (connprobelist, e->probe_le); - gettimeofday (&tv, NULL); - if (e->probe_le) + if (e->probe_le) { + listdel (connprobelist, e->probe_le); e->probe_next = min(tv.tv_sec + (1 << e->ntries), e->probe_next); - else + } else e->probe_next = tv.tv_sec + (1 << e->ntries); - ++e->ntries; + + if (e->ntries <= MAX_RETRIES) + ++e->ntries; for (item = listhead (connprobelist); item; @@ -143,9 +146,7 @@ add_to_probe_list (ConnCacheEntry *e, int ntries) */ #define PINGER_STACKSIZE (16*1024) -#define PINGER_SLEEP 10 -#define MAX_RETRIES 5 static PROCESS pinger_pid; @@ -204,11 +205,14 @@ pinger (char *arg) "host: %s cell: %d port: %d", inet_ntoa(addr), e->cell, e->port); - if (e->probe && ((*(e->probe))(e->connection) == 0)) { + if (connected_mode == DISCONNECTED) { + arla_warnx(ADEBCONN, "pinger: ignoring host in disconnected mode"); + } else if (e->probe && ((*(e->probe))(e->connection) == 0)) { conn_alive (e); - } else if (e->ntries <= MAX_RETRIES) { + } else { re_probe (e); } + conn_free (e); } } @@ -344,10 +348,10 @@ get_free_connection (void) static ConnCacheEntry * new_connection (int32_t cell, - u_int32_t host, - u_int16_t port, - u_int16_t service, - xfs_pag_t cred, + uint32_t host, + uint16_t port, + uint16_t service, + nnpfs_pag_t cred, int securityindex, int (*probe)(struct rx_connection *), struct rx_securityClass *securityobject) @@ -385,16 +389,16 @@ new_connection (int32_t cell, static ConnCacheEntry * add_connection(int32_t cell, - u_int32_t host, - u_int16_t port, - u_int16_t service, + uint32_t host, + uint16_t port, + uint16_t service, int (*probe)(struct rx_connection *), CredCacheEntry *ce) { ConnCacheEntry *e; struct rx_securityClass *securityobj; int securityindex; - xfs_pag_t cred; + nnpfs_pag_t cred; if (ce) { securityindex = ce->securityindex; @@ -402,16 +406,14 @@ add_connection(int32_t cell, switch (ce->type) { #ifdef KERBEROS - case CRED_KRB4 : - case CRED_KRB5 : { - krbstruct *krbdata = (krbstruct *)ce->cred_data; + case CRED_KRB4 : { + struct cred_rxkad *cred = (struct cred_rxkad *)ce->cred_data; - securityobj = rxkad_NewClientSecurityObject( - conn_rxkad_level, - &krbdata->c.session, - krbdata->c.kvno, - krbdata->c.ticket_st.length, - krbdata->c.ticket_st.dat); + securityobj = rxkad_NewClientSecurityObject(conn_rxkad_level, + cred->ct.HandShakeKey, + cred->ct.AuthHandle, + cred->ticket_len, + cred->ticket); break; } #endif @@ -445,9 +447,9 @@ add_connection(int32_t cell, static ConnCacheEntry * internal_get (int32_t cell, - u_int32_t host, - u_int16_t port, - u_int16_t service, + uint32_t host, + uint16_t port, + uint16_t service, int (*probe)(struct rx_connection *), CredCacheEntry *ce) { @@ -485,6 +487,12 @@ internal_get (int32_t cell, if (parent != NULL) e->parent = parent; } + + /* + * Since we only probe the parent entry (ie noauth), we make sure + * the status from the parent entry is pushed down to the + * children. + */ if(e->parent != NULL) { e->flags.alivep = e->parent->flags.alivep; } @@ -493,35 +501,35 @@ internal_get (int32_t cell, } /* - * Dead servers don't exist. + * Return a connection to (cell, host, port, service, ce) */ ConnCacheEntry * conn_get (int32_t cell, - u_int32_t host, - u_int16_t port, - u_int16_t service, + uint32_t host, + uint16_t port, + uint16_t service, int (*probe)(struct rx_connection *), CredCacheEntry *ce) { ConnCacheEntry *e = internal_get (cell, host, port, service, probe, ce); - ConnCacheEntry *parent = e; - if (e != NULL) { - if (e->parent != NULL) - parent = e->parent; - if (e->flags.alivep) { - ++e->refcount; - } else { - e = NULL; - add_to_probe_list (parent, - min(parent->ntries, MAX_RETRIES)); - } - } + ++e->refcount; return e; } /* + * Add a new reference to a connection + */ + +void +conn_ref(ConnCacheEntry *e) +{ + assert(e->refcount > 0); + e->refcount++; +} + +/* * Free a reference to a ConnCacheEntry. * If refcount drops to zero, it makes it eligible for re-use. */ @@ -544,7 +552,7 @@ conn_free (ConnCacheEntry *e) */ int32_t -conn_host2cell (u_int32_t host, u_int16_t port, u_int16_t service) +conn_host2cell (uint32_t host, uint16_t port, uint16_t service) { ConnCacheEntry *e; ConnCacheEntry key; @@ -570,7 +578,8 @@ void conn_dead (ConnCacheEntry *e) { struct in_addr a; - const char *s; + char buf[10]; + const char *port; assert (e->probe != NULL); @@ -581,13 +590,14 @@ conn_dead (ConnCacheEntry *e) } add_to_probe_list (e, 0); a.s_addr = e->host; - s = ports_num2name (e->port); - if (s != NULL) - arla_warnx (ADEBWARN, "Lost connection to %s/%s", - inet_ntoa(a), s); - else - arla_warnx (ADEBWARN, "Lost connection to %s/%d", - inet_ntoa(a), e->port); + port = ports_num2name (e->port); + if (port == NULL) { + snprintf(buf, sizeof(buf), "%d", e->port); + port = buf; + } + + arla_warnx (ADEBWARN, "Lost connection to %s/%s in cell %s", + inet_ntoa(a), port, cell_num2name (e->cell)); } /* @@ -612,6 +622,19 @@ conn_alive (ConnCacheEntry *e) } /* + * Is this server known to be up? + */ + +Bool +conn_isalivep (ConnCacheEntry *e) +{ + if (e->parent != NULL) + e->flags.alivep = e->parent->flags.alivep; + + return e->flags.alivep; +} + +/* * Probe the service in `e' */ @@ -643,7 +666,7 @@ conn_probe (ConnCacheEntry *e) */ Bool -conn_serverupp (u_int32_t host, u_int16_t port, u_int16_t service) +conn_serverupp (uint32_t host, uint16_t port, uint16_t service) { ConnCacheEntry *e; ConnCacheEntry key; @@ -701,7 +724,7 @@ conn_status (void) struct clear_state { clear_state_mask mask; int32_t cell; - xfs_pag_t cred; + nnpfs_pag_t cred; int securityindex; }; @@ -733,7 +756,7 @@ clear_cred (void *ptr, void *arg) void conn_clearcred(clear_state_mask mask, - int32_t cell, xfs_pag_t cred, int securityindex) + int32_t cell, nnpfs_pag_t cred, int securityindex) { struct clear_state s; @@ -751,7 +774,7 @@ conn_clearcred(clear_state_mask mask, struct down_state { int32_t cell; - u_int32_t *hosts; + uint32_t *hosts; int len; int i; int flags; @@ -796,7 +819,7 @@ host_down (void *ptr, void *arg) */ void -conn_downhosts(int32_t cell, u_int32_t *hosts, int *num, int flags) +conn_downhosts(int32_t cell, uint32_t *hosts, int *num, int flags) { struct down_state s; diff --git a/usr.sbin/afs/src/arlad/conn.h b/usr.sbin/afs/src/arlad/conn.h index dbe13504ccb..92087df92b2 100644 --- a/usr.sbin/afs/src/arlad/conn.h +++ b/usr.sbin/afs/src/arlad/conn.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -35,23 +35,23 @@ * Header for connection cache */ -/* $KTH: conn.h,v 1.24.2.2 2001/09/28 00:59:11 mattiasa Exp $ */ +/* $arla: conn.h,v 1.31 2002/09/07 10:42:57 lha Exp $ */ #ifndef _CONN_H_ #define _CONN_H_ #include <stdio.h> -#include <xfs/xfs_message.h> +#include <nnpfs/nnpfs_message.h> #include <cred.h> struct conncacheentry { - u_int32_t host; /* IP address of host */ - u_int16_t port; /* port number at host */ - u_int16_t service; /* RX service # */ + uint32_t host; /* IP address of host */ + uint16_t port; /* port number at host */ + uint16_t service; /* RX service # */ int32_t cell; /* cell of host */ int securityindex; int (*probe)(struct rx_connection *); - xfs_pag_t cred; + nnpfs_pag_t cred; struct rx_connection *connection; struct { unsigned alivep : 1; @@ -82,7 +82,7 @@ void conn_init (unsigned nentries); ConnCacheEntry * -conn_get (int32_t cell, u_int32_t host, u_int16_t port, u_int16_t service, +conn_get (int32_t cell, uint32_t host, uint16_t port, uint16_t service, int (*probe)(struct rx_connection *), CredCacheEntry *ce); @@ -96,23 +96,26 @@ void conn_probe (ConnCacheEntry *); void +conn_ref (ConnCacheEntry *e); + +void conn_free (ConnCacheEntry *e); int32_t -conn_host2cell (u_int32_t host, u_int16_t port, u_int16_t service); +conn_host2cell (uint32_t host, uint16_t port, uint16_t service); Bool -conn_serverupp (u_int32_t host, u_int16_t port, u_int16_t service); +conn_serverupp (uint32_t host, uint16_t port, uint16_t service); void conn_status (void); void conn_clearcred (clear_state_mask mask, - int32_t cell, xfs_pag_t cred, int securityindex); + int32_t cell, nnpfs_pag_t cred, int securityindex); void -conn_downhosts(int32_t cell, u_int32_t *hosts, int *num, int flags); +conn_downhosts(int32_t cell, uint32_t *hosts, int *num, int flags); int conn_rtt_cmp (const void *v1, const void *v2); @@ -120,6 +123,9 @@ conn_rtt_cmp (const void *v1, const void *v2); Bool host_downp (int error); +Bool +conn_isalivep (ConnCacheEntry *e); + /* * Random factor to add to rtts when comparing them. * This is in microseconds/8 diff --git a/usr.sbin/afs/src/arlad/cred.c b/usr.sbin/afs/src/arlad/cred.c index 85030964a25..3b19bd5de7c 100644 --- a/usr.sbin/afs/src/arlad/cred.c +++ b/usr.sbin/afs/src/arlad/cred.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,10 +33,16 @@ /* * Cache of credentials + * + * Each 'cred,type' pair is collected on a list where the head is in + * the cell CRED_ROOT_CELL. This is to enable fast iterations over + * all creds for a user (indexed on cred,type). */ #include "arla_local.h" -RCSID("$KTH: cred.c,v 1.33.2.2 2001/04/21 14:55:34 lha Exp $"); +RCSID("$arla: cred.c,v 1.42 2003/06/10 04:23:23 lha Exp $"); + +#define CRED_ROOT_CELL (-1) #define CREDCACHESIZE 101 @@ -54,6 +60,8 @@ static unsigned ncredentials; /* # of active credentials */ static unsigned nactive_credentials; +static void root_free(CredCacheEntry *); + /* * Functions for handling entries into the credentials cache. */ @@ -116,11 +124,14 @@ cred_init (unsigned nentries) } static CredCacheEntry * -internal_get (long cell, xfs_pag_t cred, int type) +internal_get (long cell, nnpfs_pag_t cred, int type) { CredCacheEntry *e; CredCacheEntry key; + if (cell == CRED_ROOT_CELL) + return NULL; + key.cell = cell; key.type = type; key.cred = cred; @@ -131,14 +142,54 @@ internal_get (long cell, xfs_pag_t cred, int type) e = cred_add (cred, type, 0, cell, 0, NULL, 0, 0); } - if (e != NULL) + if (e != NULL) { ++e->refcount; + assert(e->cell != CRED_ROOT_CELL); + } return e; } +struct list_pag { + int (*func)(CredCacheEntry *, void *); + void *arg; +}; + +static Bool +list_pag_func(List *l, Listitem *li, void *arg) +{ + CredCacheEntry *e = listdata(li); + struct list_pag *d = arg; + + return (d->func)(e, d->arg); +} + +int +cred_list_pag(nnpfs_pag_t cred, int type, + int (*func)(CredCacheEntry *, void *), + void *ptr) +{ + CredCacheEntry key, *root_e; + struct list_pag d; + + key.cell = CRED_ROOT_CELL; + key.type = type; + key.cred = cred; + + root_e = (CredCacheEntry *)hashtabsearch (credhtab, (void *)&key); + if (root_e == NULL) + return 0; + + d.func = func; + d.arg = ptr; + + listiter(root_e->pag.list, list_pag_func, &d); + + return 0; +} + CredCacheEntry * -cred_get (long cell, xfs_pag_t cred, int type) +cred_get (long cell, nnpfs_pag_t cred, int type) { if (type == CRED_ANY) { CredCacheEntry *e; @@ -158,6 +209,10 @@ cred_get (long cell, xfs_pag_t cred, int type) static void recycle_entry (CredCacheEntry *ce) { + assert(ce->refcount == 0); + + if (ce->cell != CRED_ROOT_CELL) + root_free(ce); if (!ce->flags.killme) hashtabdel (credhtab, ce); if (ce->cred_data != NULL) @@ -170,6 +225,8 @@ recycle_entry (CredCacheEntry *ce) void cred_free (CredCacheEntry *ce) { + assert (ce->cell != CRED_ROOT_CELL); + --ce->refcount; if (ce->flags.killme && ce->refcount == 0) recycle_entry (ce); @@ -194,8 +251,68 @@ get_free_cred (void) "credcache: there was no way of getting a cred"); } +static void +root_free(CredCacheEntry *e) +{ + CredCacheEntry key, *root_e; + + assert(e->cell != CRED_ROOT_CELL); + + if (e->pag.li == NULL) + return; + + key.cell = CRED_ROOT_CELL; + key.type = e->type; + key.cred = e->cred; + + root_e = (CredCacheEntry *)hashtabsearch (credhtab, (void *)&key); + assert(root_e); + + listdel(root_e->pag.list, e->pag.li); + e->pag.li = NULL; + + if (listemptyp(root_e->pag.list)) { + listfree(root_e->pag.list); + root_e->pag.list = NULL; + recycle_entry(root_e); + } +} + +static void +add_to_root_entry(CredCacheEntry *e) +{ + CredCacheEntry key, *root_e; + + assert(e->cell != CRED_ROOT_CELL); + + key.cell = CRED_ROOT_CELL; + key.type = e->type; + key.cred = e->cred; + + root_e = (CredCacheEntry *)hashtabsearch (credhtab, (void *)&key); + if (root_e == NULL) { + root_e = get_free_cred (); + + root_e->cell = CRED_ROOT_CELL; + root_e->type = e->type; + root_e->cred = e->cred; + root_e->securityindex = -1; + root_e->expire = 0; + root_e->cred_data = NULL; + root_e->uid = e->uid; + root_e->pag.list = listnew(); + if (root_e->pag.list == NULL) + arla_errx (1, ADEBERROR, "add_to_root_entry: out of memory"); + + hashtabadd(credhtab, root_e); + + ++nactive_credentials; + } + e->pag.li = listaddhead (root_e->pag.list, e); +} + CredCacheEntry * -cred_add (xfs_pag_t cred, int type, int securityindex, long cell, +cred_add (nnpfs_pag_t cred, int type, int securityindex, long cell, time_t expire, void *cred_data, size_t cred_data_sz, uid_t uid) { @@ -220,40 +337,20 @@ cred_add (xfs_pag_t cred, int type, int securityindex, long cell, e->expire = expire; e->cred_data = data; e->uid = uid; + e->pag.li = NULL; + + add_to_root_entry(e); - old = hashtabsearch (credhtab, e); + old = (CredCacheEntry *)hashtabsearch (credhtab, (void *)e); if (old != NULL) - recycle_entry (old); + cred_delete (old); hashtabadd (credhtab, e); - ++nactive_credentials; - return e; -} - -#if KERBEROS -CredCacheEntry * -cred_add_krb4 (xfs_pag_t cred, uid_t uid, CREDENTIALS *c) -{ - CredCacheEntry *ce; - char *cellname; - int cellnum; - if (*c->instance == '\0') - cellname = strdup (c->realm); - else - cellname = strdup (c->instance); - if (cellname == NULL) - return NULL; - strlwr (cellname); - cellnum = cell_name2num(cellname); - free (cellname); - if (cellnum == -1) - return NULL; + ++nactive_credentials; - ce = cred_add (cred, CRED_KRB4, 2, cellnum, -1, c, sizeof(*c), uid); - return ce; + return e; } -#endif /* * @@ -262,9 +359,12 @@ cred_add_krb4 (xfs_pag_t cred, uid_t uid, CREDENTIALS *c) void cred_delete (CredCacheEntry *ce) { + assert(ce->cell != CRED_ROOT_CELL); + if (ce->refcount > 0) { ce->flags.killme = 1; hashtabdel (credhtab, ce); + root_free(ce); } else recycle_entry (ce); } @@ -280,11 +380,11 @@ cred_expire (CredCacheEntry *ce) if (cell_name != NULL) arla_warnx (ADEBWARN, - "Credentials for UID %u in cell %s has expired", + "Credentials for UID %u in cell %s have expired", (unsigned)ce->uid, cell_name); else arla_warnx (ADEBWARN, - "Credentials for UID %u in cell unknown %ld has expired", + "Credentials for UID %u in cell unknown %ld have expired", (unsigned)ce->uid, ce->cell); cred_delete (ce); @@ -294,7 +394,10 @@ static Bool remove_entry (void *ptr, void *arg) { CredCacheEntry *ce = (CredCacheEntry *)ptr; - xfs_pag_t *cred = (xfs_pag_t *)arg; + nnpfs_pag_t *cred = (nnpfs_pag_t *)arg; + + if (ce->cell == CRED_ROOT_CELL) + return FALSE; if (ce->cred == *cred) cred_delete (ce); @@ -302,7 +405,7 @@ remove_entry (void *ptr, void *arg) } void -cred_remove (xfs_pag_t cred) +cred_remove (nnpfs_pag_t cred) { hashtabforeach (credhtab, remove_entry, &cred); } diff --git a/usr.sbin/afs/src/arlad/cred.h b/usr.sbin/afs/src/arlad/cred.h index f05a3033727..c0f9bcae09b 100644 --- a/usr.sbin/afs/src/arlad/cred.h +++ b/usr.sbin/afs/src/arlad/cred.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2003 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -35,7 +35,7 @@ * Header for credetial cache */ -/* $KTH: cred.h,v 1.26 2000/10/02 22:31:15 lha Exp $ */ +/* $arla: cred.h,v 1.33 2003/06/10 16:21:11 lha Exp $ */ #ifndef _CRED_H_ #define _CRED_H_ @@ -43,50 +43,79 @@ #include <sys/types.h> #include <time.h> #include <lock.h> -#ifdef KERBEROS +#ifdef HAVE_KRB4 +#ifdef HAVE_OPENSSL +#include <openssl/des.h> +#else #include <des.h> +#endif #include <krb.h> -#endif /* KERBEROS */ +#endif /* HAVE_KRB4 */ #include "bool.h" -#include <xfs/xfs_message.h> +#include <nnpfs/nnpfs_message.h> /* The cred-types we support */ #define CRED_NONE 0 #define CRED_KRB4 1 #define CRED_KRB5 2 -#define CRED_MAX CRED_KRB5 +#define CRED_GK_K5 3 +#define CRED_MAX CRED_GK_K5 #define CRED_ANY (-1) -#ifdef KERBEROS -typedef struct { - CREDENTIALS c; -} krbstruct; -#endif +struct cred_rxkad { + struct ClearToken ct; + size_t ticket_len; + unsigned char ticket[MAXKRB4TICKETLEN]; +}; + +struct cred_rxgk { + int type; + union { + struct { + int32_t kvno; + int32_t enctype; + size_t sessionkey_len; + void *sessionkey; + size_t ticket_len; + void *ticket; + } k5; + } t; +}; typedef struct { - xfs_pag_t cred; + nnpfs_pag_t cred; uid_t uid; int type; int securityindex; long cell; time_t expire; void *cred_data; + void (*cred_free_func)(void *); struct { unsigned killme : 1; } flags; unsigned refcount; + union { + List *list; + Listitem *li; + } pag; } CredCacheEntry; void cred_init (unsigned nentries); CredCacheEntry * -cred_get (long cell, xfs_pag_t cred, int type); +cred_get (long cell, nnpfs_pag_t cred, int type); + +int +cred_list_pag(nnpfs_pag_t, int, + int (*func)(CredCacheEntry *, void *), + void *); void cred_free (CredCacheEntry *ce); CredCacheEntry * -cred_add (xfs_pag_t cred, int type, int securityindex, long cell, +cred_add (nnpfs_pag_t cred, int type, int securityindex, long cell, time_t expire, void *cred_data, size_t cred_data_sz, uid_t uid); @@ -96,12 +125,8 @@ cred_delete (CredCacheEntry *ce); void cred_expire (CredCacheEntry *ce); -#ifdef KERBEROS -CredCacheEntry * cred_add_krb4 (xfs_pag_t cred, uid_t uid, CREDENTIALS *c); -#endif - void cred_status (void); -void cred_remove (xfs_pag_t cred); +void cred_remove (nnpfs_pag_t cred); #endif /* _CRED_H_ */ diff --git a/usr.sbin/afs/src/arlad/darla.c b/usr.sbin/afs/src/arlad/darla.c index fc565b621ec..8e4b87adf6a 100644 --- a/usr.sbin/afs/src/arlad/darla.c +++ b/usr.sbin/afs/src/arlad/darla.c @@ -1,103 +1,104 @@ -/* COPYRIGHT (C) 1998 - * THE REGENTS OF THE UNIVERSITY OF MICHIGAN - * ALL RIGHTS RESERVED - * - * PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS - * AND REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS - * FOR ANY PURPOSE, SO LONG AS THE NAME OF THE UNIVERSITY OF - * MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY - * PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE - * WITHOUT SPECIFIC, WRITTEN PRIOR AUTHORIZATION. IF THE - * ABOVE COPYRIGHT NOTICE OR ANY OTHER IDENTIFICATION OF THE - * UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY - * PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST - * ALSO BE INCLUDED. - * - * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION - * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY - * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF - * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING - * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE - * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE - * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR - * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING - * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN - * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGES. - */ - -#include "arla_local.h" - -RCSID("$KTH: darla.c,v 1.6 2000/02/12 19:23:54 assar Exp $"); - -int DARLA_Open(DARLA_file *Dfp, char *fname, int oflag) -{ - - int fd; - - fd = open(fname, oflag, 0600); - arla_log(ADEBMISC, "DARLA_Open: errno=%d", errno); - if (fd > 0) - { - Dfp->fd = fd; - Dfp->offset=0; - Dfp->log_entries = 0; - } - - return fd; -} - -int DARLA_Close(DARLA_file *Dfp) -{ - int ret; - - ret = close(Dfp->fd); - Dfp->fd = 0; - Dfp->offset =0; - arla_log(ADEBMISC, "DARLA_Close: ret=%d", ret); - return ret; -} - -int DARLA_Read(DARLA_file *Dfp, char *cp, int len) -{ - ssize_t read_size; - - if (Dfp->fd) - { - read_size = read (Dfp->fd, cp, len); - } - else - read_size = 0; - - return read_size; -} - -int DARLA_Write(DARLA_file *Dfp, char *cp, int len) -{ - ssize_t write_size; - - if (Dfp->fd) - { - write_size = write(Dfp->fd, cp, len); - } - else - write_size = 0; - - return write_size; -} - -int DARLA_Seek(DARLA_file *Dfp, int offset, int whence) -{ - - off_t lseek_off; - - if (Dfp->fd) - { - lseek_off = lseek(Dfp->fd, offset, whence); - } - else - lseek_off = 0; - - return lseek_off; -} +OBSOLETE /* COPYRIGHT (C) 1998 +OBSOLETE * THE REGENTS OF THE UNIVERSITY OF MICHIGAN +OBSOLETE * ALL RIGHTS RESERVED +OBSOLETE * +OBSOLETE * PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS +OBSOLETE * AND REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS +OBSOLETE * FOR ANY PURPOSE, SO LONG AS THE NAME OF THE UNIVERSITY OF +OBSOLETE * MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY +OBSOLETE * PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE +OBSOLETE * WITHOUT SPECIFIC, WRITTEN PRIOR AUTHORIZATION. IF THE +OBSOLETE * ABOVE COPYRIGHT NOTICE OR ANY OTHER IDENTIFICATION OF THE +OBSOLETE * UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY +OBSOLETE * PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST +OBSOLETE * ALSO BE INCLUDED. +OBSOLETE * +OBSOLETE * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION +OBSOLETE * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY +OBSOLETE * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF +OBSOLETE * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING +OBSOLETE * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF +OBSOLETE * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE +OBSOLETE * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE +OBSOLETE * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR +OBSOLETE * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING +OBSOLETE * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN +OBSOLETE * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF +OBSOLETE * SUCH DAMAGES. +OBSOLETE */ +OBSOLETE +OBSOLETE #include "arla_local.h" +OBSOLETE +OBSOLETE RCSID("$arla: darla.c,v 1.8 2002/07/23 15:22:51 lha Exp $"); +OBSOLETE +OBSOLETE int DARLA_Open(DARLA_file *Dfp, char *fname, int oflag) +OBSOLETE { +OBSOLETE +OBSOLETE int fd; +OBSOLETE +OBSOLETE fd = open(fname, oflag, 0600); +OBSOLETE if (fd == -1) +OBSOLETE arla_log(ADEBMISC, "DARLA_Open: errno=%d", errno); +OBSOLETE if (fd > 0) +OBSOLETE { +OBSOLETE Dfp->fd = fd; +OBSOLETE Dfp->offset=0; +OBSOLETE Dfp->log_entries = 0; +OBSOLETE } +OBSOLETE +OBSOLETE return fd; +OBSOLETE } +OBSOLETE +OBSOLETE int DARLA_Close(DARLA_file *Dfp) +OBSOLETE { +OBSOLETE int ret; +OBSOLETE +OBSOLETE ret = close(Dfp->fd); +OBSOLETE Dfp->fd = 0; +OBSOLETE Dfp->offset =0; +OBSOLETE arla_log(ADEBMISC, "DARLA_Close: ret=%d", ret); +OBSOLETE return ret; +OBSOLETE } +OBSOLETE +OBSOLETE int DARLA_Read(DARLA_file *Dfp, char *cp, int len) +OBSOLETE { +OBSOLETE ssize_t read_size; +OBSOLETE +OBSOLETE if (Dfp->fd) +OBSOLETE { +OBSOLETE read_size = read (Dfp->fd, cp, len); +OBSOLETE } +OBSOLETE else +OBSOLETE read_size = 0; +OBSOLETE +OBSOLETE return read_size; +OBSOLETE } +OBSOLETE +OBSOLETE int DARLA_Write(DARLA_file *Dfp, char *cp, int len) +OBSOLETE { +OBSOLETE ssize_t write_size; +OBSOLETE +OBSOLETE if (Dfp->fd) +OBSOLETE { +OBSOLETE write_size = write(Dfp->fd, cp, len); +OBSOLETE } +OBSOLETE else +OBSOLETE write_size = 0; +OBSOLETE +OBSOLETE return write_size; +OBSOLETE } +OBSOLETE +OBSOLETE int DARLA_Seek(DARLA_file *Dfp, int offset, int whence) +OBSOLETE { +OBSOLETE +OBSOLETE off_t lseek_off; +OBSOLETE +OBSOLETE if (Dfp->fd) +OBSOLETE { +OBSOLETE lseek_off = lseek(Dfp->fd, offset, whence); +OBSOLETE } +OBSOLETE else +OBSOLETE lseek_off = 0; +OBSOLETE +OBSOLETE return lseek_off; +OBSOLETE } diff --git a/usr.sbin/afs/src/arlad/darla.h b/usr.sbin/afs/src/arlad/darla.h index c95eb730f4e..a22243231ce 100644 --- a/usr.sbin/afs/src/arlad/darla.h +++ b/usr.sbin/afs/src/arlad/darla.h @@ -1,50 +1,50 @@ -/* COPYRIGHT (C) 1998 - * THE REGENTS OF THE UNIVERSITY OF MICHIGAN - * ALL RIGHTS RESERVED - * - * PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS - * AND REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS - * FOR ANY PURPOSE, SO LONG AS THE NAME OF THE UNIVERSITY OF - * MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY - * PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE - * WITHOUT SPECIFIC, WRITTEN PRIOR AUTHORIZATION. IF THE - * ABOVE COPYRIGHT NOTICE OR ANY OTHER IDENTIFICATION OF THE - * UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY - * PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST - * ALSO BE INCLUDED. - * - * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION - * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY - * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF - * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING - * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE - * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE - * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR - * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING - * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN - * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGES. - */ - -/* $KTH: darla.h,v 1.3 1998/12/21 21:54:03 assar Exp $ */ - -#ifndef _DARLA_H -#define _DARLA_H - -#include <lock.h> - -typedef struct _DARLA_file { - int fd; /*file descriptor of the current file */ - long offset; /*current byte offset */ - struct Lock bs_lock; /*lock to synchronize access */ - long log_entries; /*number of entries */ -} DARLA_file; - -int DARLA_Open(DARLA_file *Dfp, char *fname, int oflag); -int DARLA_Close(DARLA_file *Dfp); -int DARLA_Read(DARLA_file *Dfp, char *cp, int len); -int DARLA_Write(DARLA_file *Dfp, char *cp, int len); -int DARLA_Seek(DARLA_file *Dfp, int offset, int whence); - -#endif /* _DARLA_H */ +OBSOLETE /* COPYRIGHT (C) 1998 +OBSOLETE * THE REGENTS OF THE UNIVERSITY OF MICHIGAN +OBSOLETE * ALL RIGHTS RESERVED +OBSOLETE * +OBSOLETE * PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS +OBSOLETE * AND REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS +OBSOLETE * FOR ANY PURPOSE, SO LONG AS THE NAME OF THE UNIVERSITY OF +OBSOLETE * MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY +OBSOLETE * PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE +OBSOLETE * WITHOUT SPECIFIC, WRITTEN PRIOR AUTHORIZATION. IF THE +OBSOLETE * ABOVE COPYRIGHT NOTICE OR ANY OTHER IDENTIFICATION OF THE +OBSOLETE * UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY +OBSOLETE * PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST +OBSOLETE * ALSO BE INCLUDED. +OBSOLETE * +OBSOLETE * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION +OBSOLETE * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY +OBSOLETE * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF +OBSOLETE * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING +OBSOLETE * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF +OBSOLETE * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE +OBSOLETE * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE +OBSOLETE * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR +OBSOLETE * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING +OBSOLETE * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN +OBSOLETE * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF +OBSOLETE * SUCH DAMAGES. +OBSOLETE */ +OBSOLETE +OBSOLETE /* $arla: darla.h,v 1.4 2002/07/23 15:22:52 lha Exp $ */ +OBSOLETE +OBSOLETE #ifndef _DARLA_H +OBSOLETE #define _DARLA_H +OBSOLETE +OBSOLETE #include <lock.h> +OBSOLETE +OBSOLETE typedef struct _DARLA_file { +OBSOLETE int fd; /*file descriptor of the current file */ +OBSOLETE long offset; /*current byte offset */ +OBSOLETE struct Lock bs_lock; /*lock to synchronize access */ +OBSOLETE long log_entries; /*number of entries */ +OBSOLETE } DARLA_file; +OBSOLETE +OBSOLETE int DARLA_Open(DARLA_file *Dfp, char *fname, int oflag); +OBSOLETE int DARLA_Close(DARLA_file *Dfp); +OBSOLETE int DARLA_Read(DARLA_file *Dfp, char *cp, int len); +OBSOLETE int DARLA_Write(DARLA_file *Dfp, char *cp, int len); +OBSOLETE int DARLA_Seek(DARLA_file *Dfp, int offset, int whence); +OBSOLETE +OBSOLETE #endif /* _DARLA_H */ diff --git a/usr.sbin/afs/src/arlad/discon.h b/usr.sbin/afs/src/arlad/discon.h index e0a7413d8f1..b882f0e04a2 100644 --- a/usr.sbin/afs/src/arlad/discon.h +++ b/usr.sbin/afs/src/arlad/discon.h @@ -1,338 +1,338 @@ -/* COPYRIGHT (C) 1998 - * THE REGENTS OF THE UNIVERSITY OF MICHIGAN - * ALL RIGHTS RESERVED - * - * PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS - * AND REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS - * FOR ANY PURPOSE, SO LONG AS THE NAME OF THE UNIVERSITY OF - * MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY - * PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE - * WITHOUT SPECIFIC, WRITTEN PRIOR AUTHORIZATION. IF THE - * ABOVE COPYRIGHT NOTICE OR ANY OTHER IDENTIFICATION OF THE - * UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY - * PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST - * ALSO BE INCLUDED. - * - * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION - * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY - * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF - * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING - * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE - * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE - * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR - * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING - * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN - * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGES. - */ - -/* -** These are defines for the different type of disconnected -** operations stored in the log. -*/ - -#ifndef _DISCONNH -#define _DISCONNH - - -/* these are define for integrity checking */ -#define CHECK_SLOTS (long) 0x1 -#define CHECK_LRUQ (long) 0x2 -#define CHECK_FREEVS (long) 0x4 - -/* values for the dflags in the vcache */ -#define VC_DIRTY 0x01 -#define KEEP_VC 0x04 -#define DBAD_VC 0x08 /* This is a know bad vcache */ -/* this flags is used by GetVSlot to mark when a vcache was read from -** the disk. -*/ -#define READ_DISK 0x10 - -/* Flags for dflags in the fcache */ -#define KEEP_DC 0x01 - -/* Flags in the afs_VindexFlags */ - -#define VC_FREE 0x01 -#define HAS_CCORE 0x02 -/* 0x04 is used by KEEP_VC */ -#define VC_DATAMOD 0x08 -#define VC_FLAG 0x10 -#define VC_CLEARAXS 0x20 -#define VC_HAVECB 0x40 - -/* magic number for data files */ - -#define AFS_DHMAGIC 0x7635fac1 - -/* these are the file name extensions for various errors */ -#define STORE_EXT ".store" -#define RENAME_EXT ".ren" -#define CREATE_EXT ".creat" -#define MKDIR_EXT ".mkdir" -#define LINK_EXT ".link" -#define SYMLINK_EXT ".slink" -#define ORPH_EXT ".orph" - -/* conflicting defs with arla_local.h */ -/*enum discon_modes { - CONNECTED, - DISCONNECTED, - FETCH_ONLY, - PARTIALLY_CONNECTED -};*/ - -#define IS_DISCONNECTED(state) (state == DISCONNECTED) -#define IS_FETCHONLY(state) (state == FETCH_ONLY) -#define IS_PARTIAL(state) (state == PARTIALLY_CONNECTED) -#define IS_CONNECTED(state) (state == CONNECTED) -#define LOG_OPERATIONS(state) ((state == DISCONNECTED) || \ - (state == FETCH_ONLY) || (state == PARTIALLY_CONNECTED)) -#define USE_OPTIMISTIC(state) ((state == DISCONNECTED) || \ - (state == FETCH_ONLY)) - - -/* These are the different levels of error logging */ -#define DISCON_ERR 0 -#define DISCON_NOTICE 1 -#define DISCON_INFO 2 -#define DISCON_DEBUG 3 - -/* pioctl flags */ -#define AFS_DIS_RECON 0 /* normal reconnect */ -#define AFS_DIS_DISCON 1 /* disconnect */ -#define AFS_DIS_PANIC 2 /* die, monster devil, die */ -#define AFS_DIS_RECONTOSS 3 /* reconnect now! */ -#define AFS_DIS_QUERY 4 /* query disconnected state */ -#define AFS_DIS_FETCHONLY 5 /* disconnect, fetch-only mode */ -#define AFS_DIS_PARTIAL 6 /* partially connected mode */ -#define AFS_DIS_DISCONTOSS 7 /* disconnect without discarding callbacks */ - - -/* these are items defined to fhe PSetDOps */ - -typedef enum { GET_BACKUP_LOG_NAME, - SET_USERLOG_LEVEL, - SET_FILELOG_LEVEL, - SET_LOGFILE, - UPDATE_FLAGS, - PING_SERVER, - GET_LOG_NAME, - GIVEUP_CBS, - PRINT_INFO, - VERIFY_VCACHE, - VERIFY_DCACHE } dis_setopt_op_t; - -#if 0 -#define MAX_NAME 255 -#endif - -typedef struct dis_setop_info { - dis_setopt_op_t op; - char data[MAX_NAME]; -} dis_setop_info_t; - - -#ifdef KERNEL - - -#define CELL_DIRTY 0x01 -#define REALLY_BIG 1024 - -struct save_cell { - long cell; /* unique id assigned by venus */ - char cellName[MAX_NAME]; /* char string name of cell */ - short cellHosts[MAXHOSTS]; /* volume *location* hosts for this cell */ - short lcell; /* Associated linked cell */ - short states; /* state flags */ - long fsport; /* file server port */ - long vlport; /* volume server port */ - short cellIndex; /* relative index number per cell */ - short dindex; /* disconnected index */ -}; - -#define SERV_DIRTY 0x01 - -struct save_server { - unsigned int cell; /* cell in which this host resides */ - long host; /* in network byte order, except subsys */ - long portal; /* in network byte order */ - unsigned int random; /* server priority, used for randomizing requests */ - char isDown; /* result of decision if server is down. */ - char vcbCount; /* count of vcbs */ - short dindex; /* disconnected index */ -}; - - -#define VOL_DIRTY 0x01 - -struct save_volume { - long cell; /* the cell in which the volume resides */ - long volume; /* This volume's ID number. */ - char name[MAX_NAME]; /* This volume's name, or 0 if unknown */ - short serverHost[MAXHOSTS]; /* servers serving this volume */ - struct VenusFid dotdot; /* dir to access as .. */ - struct VenusFid mtpoint; /* The mount point for this volume. */ - long rootVnode, rootUnique; /* Volume's root fid */ - long roVol; - long backVol; - long rwVol; /* For r/o vols, original read/write volume. */ - long accessTime; /* last time we used it */ - long copyDate; /* copyDate field, for tracking vol releases */ - char states; /* snuck here for alignment reasons */ - short dindex; -}; - - -#define LLIST_SIZE 1024 - - -#ifndef GET_WRITE -#define GET_WRITE 0x1 -#define GET_READ 0x2 -#define GET_SHARED 0x4 - -#define REL_WRITE 0x10 -#define REL_READ 0x20 -#define REL_SHARED 0x40 - -#define S_TO_W 0x100 -#define W_TO_S 0x200 -#define W_TO_R 0x400 -#define S_TO_R 0x800 -#endif /* GET_WRITE */ - -struct llist { - struct afs_lock *lk; - short operation; - short who; - struct llist * next; - struct llist *prev; -}; - -/* These are definition for the translation flags fields */ - -#define KNOWNBAD 0x20 -#define SYMLINK 0x40 -struct name_trans { - struct VenusFid pfid; - int ntrans_idx; - int oname_idx; - int nname_idx; - int next_nt_idx; - char *old_name; - char *new_name; - struct name_trans *next; -}; - -struct translations { - struct VenusFid oldfid; - struct VenusFid newfid; - u_long flags; - hyper validDV; - int trans_idx; - long callback; - long cbExpires; - int nl_idx; - struct translations *next; - struct name_trans *name_list; -}; - - - -/* - * this struct is used to help speed up finding the number of callbacks for - * each server - */ - -struct serv_cbcount { - long server; - long count; - struct serv_cbcount *next; -}; - -/* Stuff for the link name persistence */ - -#define MAP_ENTS 100 -#define NAME_UNIT 255 -#define NAME_DIRTY 0x1 - -/* header for the name backing file */ -typedef struct map_header { - long magic; /* magic number */ - int num_ents; /* number of names stored */ - char flags; /* flags for in core copy */ -} map_header_t; - -/* commented out */ -/* - * this struct holds all the information pertaining to a certain - * backing store used to keep persistance information - */ -/*typedef struct backing_store { - long bs_inode; - struct osi_dev bs_dev; - char *bs_name; - map_header_t *bs_header; - char *bs_map; - struct afs_lock bs_lock; - struct osi_file *tfile; -} backing_store_t;*/ - -#endif /* KERNEL */ - -/* CacheItems file has a header of type struct afs_fheader (keep aligned properly) */ -struct afs_dheader { - long magic; - long firstCSize; - long otherCSize; - long spare; - long current_op; - enum connected_mode mode; -}; - -#ifdef KERNEL - -#define have_shared_lock(lock) \ - ((((lock)->excl_locked==SHARED_LOCK) && \ - ((lock)->proc == osi_curpid())) ? 1 : 0) - -#define have_write_lock(lock) \ - ((((lock)->excl_locked==WRITE_LOCK) && \ - ((lock)->proc == osi_curpid())) ? 1 : 0) - -extern struct llist *llist; -extern struct llist *cur_llist; - -/* these are function declarations so I can compile with -Wall in gcc, - * not really needed, but help make clean compiles. - */ - -extern int strlen(); -#ifndef AFS_NETBSD_ENV -extern void strcpy(); -#endif /* AFS_NETBSD_ENV */ -extern void bcopy(); -extern int dir_Delete(); -extern int dir_FindBlobs(); -extern int dir_Lookup(); -extern int dir_Create(); -extern int find_file_name(); -extern int afs_create(); -extern int afs_PutDCache(); - -#endif /* KERNEL */ - -#endif /* _DISCONNH */ - - -#ifdef DISCONN -typedef struct _fid_cb { -VenusFid fid; -struct _fid_cb *next; -} fid_cb; -#endif - - +OBSOLETE /* COPYRIGHT (C) 1998 +OBSOLETE * THE REGENTS OF THE UNIVERSITY OF MICHIGAN +OBSOLETE * ALL RIGHTS RESERVED +OBSOLETE * +OBSOLETE * PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS +OBSOLETE * AND REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS +OBSOLETE * FOR ANY PURPOSE, SO LONG AS THE NAME OF THE UNIVERSITY OF +OBSOLETE * MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY +OBSOLETE * PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE +OBSOLETE * WITHOUT SPECIFIC, WRITTEN PRIOR AUTHORIZATION. IF THE +OBSOLETE * ABOVE COPYRIGHT NOTICE OR ANY OTHER IDENTIFICATION OF THE +OBSOLETE * UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY +OBSOLETE * PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST +OBSOLETE * ALSO BE INCLUDED. +OBSOLETE * +OBSOLETE * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION +OBSOLETE * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY +OBSOLETE * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF +OBSOLETE * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING +OBSOLETE * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF +OBSOLETE * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE +OBSOLETE * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE +OBSOLETE * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR +OBSOLETE * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING +OBSOLETE * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN +OBSOLETE * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF +OBSOLETE * SUCH DAMAGES. +OBSOLETE */ +OBSOLETE +OBSOLETE /* +OBSOLETE ** These are defines for the different type of disconnected +OBSOLETE ** operations stored in the log. +OBSOLETE */ +OBSOLETE +OBSOLETE #ifndef _DISCONNH +OBSOLETE #define _DISCONNH +OBSOLETE +OBSOLETE +OBSOLETE /* these are define for integrity checking */ +OBSOLETE #define CHECK_SLOTS (long) 0x1 +OBSOLETE #define CHECK_LRUQ (long) 0x2 +OBSOLETE #define CHECK_FREEVS (long) 0x4 +OBSOLETE +OBSOLETE /* values for the dflags in the vcache */ +OBSOLETE #define VC_DIRTY 0x01 +OBSOLETE #define KEEP_VC 0x04 +OBSOLETE #define DBAD_VC 0x08 /* This is a know bad vcache */ +OBSOLETE /* this flags is used by GetVSlot to mark when a vcache was read from +OBSOLETE ** the disk. +OBSOLETE */ +OBSOLETE #define READ_DISK 0x10 +OBSOLETE +OBSOLETE /* Flags for dflags in the fcache */ +OBSOLETE #define KEEP_DC 0x01 +OBSOLETE +OBSOLETE /* Flags in the afs_VindexFlags */ +OBSOLETE +OBSOLETE #define VC_FREE 0x01 +OBSOLETE #define HAS_CCORE 0x02 +OBSOLETE /* 0x04 is used by KEEP_VC */ +OBSOLETE #define VC_DATAMOD 0x08 +OBSOLETE #define VC_FLAG 0x10 +OBSOLETE #define VC_CLEARAXS 0x20 +OBSOLETE #define VC_HAVECB 0x40 +OBSOLETE +OBSOLETE /* magic number for data files */ +OBSOLETE +OBSOLETE #define AFS_DHMAGIC 0x7635fac1 +OBSOLETE +OBSOLETE /* these are the file name extensions for various errors */ +OBSOLETE #define STORE_EXT ".store" +OBSOLETE #define RENAME_EXT ".ren" +OBSOLETE #define CREATE_EXT ".creat" +OBSOLETE #define MKDIR_EXT ".mkdir" +OBSOLETE #define LINK_EXT ".link" +OBSOLETE #define SYMLINK_EXT ".slink" +OBSOLETE #define ORPH_EXT ".orph" +OBSOLETE +OBSOLETE /* conflicting defs with arla_local.h */ +OBSOLETE /*enum discon_modes { +OBSOLETE CONNECTED, +OBSOLETE DISCONNECTED, +OBSOLETE FETCH_ONLY, +OBSOLETE PARTIALLY_CONNECTED +OBSOLETE };*/ +OBSOLETE +OBSOLETE #define IS_DISCONNECTED(state) (state == DISCONNECTED) +OBSOLETE #define IS_FETCHONLY(state) (state == FETCH_ONLY) +OBSOLETE #define IS_PARTIAL(state) (state == PARTIALLY_CONNECTED) +OBSOLETE #define IS_CONNECTED(state) (state == CONNECTED) +OBSOLETE #define LOG_OPERATIONS(state) ((state == DISCONNECTED) || \ +OBSOLETE (state == FETCH_ONLY) || (state == PARTIALLY_CONNECTED)) +OBSOLETE #define USE_OPTIMISTIC(state) ((state == DISCONNECTED) || \ +OBSOLETE (state == FETCH_ONLY)) +OBSOLETE +OBSOLETE +OBSOLETE /* These are the different levels of error logging */ +OBSOLETE #define DISCON_ERR 0 +OBSOLETE #define DISCON_NOTICE 1 +OBSOLETE #define DISCON_INFO 2 +OBSOLETE #define DISCON_DEBUG 3 +OBSOLETE +OBSOLETE /* pioctl flags */ +OBSOLETE #define AFS_DIS_RECON 0 /* normal reconnect */ +OBSOLETE #define AFS_DIS_DISCON 1 /* disconnect */ +OBSOLETE #define AFS_DIS_PANIC 2 /* die, monster devil, die */ +OBSOLETE #define AFS_DIS_RECONTOSS 3 /* reconnect now! */ +OBSOLETE #define AFS_DIS_QUERY 4 /* query disconnected state */ +OBSOLETE #define AFS_DIS_FETCHONLY 5 /* disconnect, fetch-only mode */ +OBSOLETE #define AFS_DIS_PARTIAL 6 /* partially connected mode */ +OBSOLETE #define AFS_DIS_DISCONTOSS 7 /* disconnect without discarding callbacks */ +OBSOLETE +OBSOLETE +OBSOLETE /* these are items defined to fhe PSetDOps */ +OBSOLETE +OBSOLETE typedef enum { GET_BACKUP_LOG_NAME, +OBSOLETE SET_USERLOG_LEVEL, +OBSOLETE SET_FILELOG_LEVEL, +OBSOLETE SET_LOGFILE, +OBSOLETE UPDATE_FLAGS, +OBSOLETE PING_SERVER, +OBSOLETE GET_LOG_NAME, +OBSOLETE GIVEUP_CBS, +OBSOLETE PRINT_INFO, +OBSOLETE VERIFY_VCACHE, +OBSOLETE VERIFY_DCACHE } dis_setopt_op_t; +OBSOLETE +OBSOLETE #if 0 +OBSOLETE #define MAX_NAME 255 +OBSOLETE #endif +OBSOLETE +OBSOLETE typedef struct dis_setop_info { +OBSOLETE dis_setopt_op_t op; +OBSOLETE char data[MAX_NAME]; +OBSOLETE } dis_setop_info_t; +OBSOLETE +OBSOLETE +OBSOLETE #ifdef KERNEL +OBSOLETE +OBSOLETE +OBSOLETE #define CELL_DIRTY 0x01 +OBSOLETE #define REALLY_BIG 1024 +OBSOLETE +OBSOLETE struct save_cell { +OBSOLETE long cell; /* unique id assigned by venus */ +OBSOLETE char cellName[MAX_NAME]; /* char string name of cell */ +OBSOLETE short cellHosts[MAXHOSTS]; /* volume *location* hosts for this cell */ +OBSOLETE short lcell; /* Associated linked cell */ +OBSOLETE short states; /* state flags */ +OBSOLETE long fsport; /* file server port */ +OBSOLETE long vlport; /* volume server port */ +OBSOLETE short cellIndex; /* relative index number per cell */ +OBSOLETE short dindex; /* disconnected index */ +OBSOLETE }; +OBSOLETE +OBSOLETE #define SERV_DIRTY 0x01 +OBSOLETE +OBSOLETE struct save_server { +OBSOLETE unsigned int cell; /* cell in which this host resides */ +OBSOLETE long host; /* in network byte order, except subsys */ +OBSOLETE long portal; /* in network byte order */ +OBSOLETE unsigned int random; /* server priority, used for randomizing requests */ +OBSOLETE char isDown; /* result of decision if server is down. */ +OBSOLETE char vcbCount; /* count of vcbs */ +OBSOLETE short dindex; /* disconnected index */ +OBSOLETE }; +OBSOLETE +OBSOLETE +OBSOLETE #define VOL_DIRTY 0x01 +OBSOLETE +OBSOLETE struct save_volume { +OBSOLETE long cell; /* the cell in which the volume resides */ +OBSOLETE long volume; /* This volume's ID number. */ +OBSOLETE char name[MAX_NAME]; /* This volume's name, or 0 if unknown */ +OBSOLETE short serverHost[MAXHOSTS]; /* servers serving this volume */ +OBSOLETE struct VenusFid dotdot; /* dir to access as .. */ +OBSOLETE struct VenusFid mtpoint; /* The mount point for this volume. */ +OBSOLETE long rootVnode, rootUnique; /* Volume's root fid */ +OBSOLETE long roVol; +OBSOLETE long backVol; +OBSOLETE long rwVol; /* For r/o vols, original read/write volume. */ +OBSOLETE long accessTime; /* last time we used it */ +OBSOLETE long copyDate; /* copyDate field, for tracking vol releases */ +OBSOLETE char states; /* snuck here for alignment reasons */ +OBSOLETE short dindex; +OBSOLETE }; +OBSOLETE +OBSOLETE +OBSOLETE #define LLIST_SIZE 1024 +OBSOLETE +OBSOLETE +OBSOLETE #ifndef GET_WRITE +OBSOLETE #define GET_WRITE 0x1 +OBSOLETE #define GET_READ 0x2 +OBSOLETE #define GET_SHARED 0x4 +OBSOLETE +OBSOLETE #define REL_WRITE 0x10 +OBSOLETE #define REL_READ 0x20 +OBSOLETE #define REL_SHARED 0x40 +OBSOLETE +OBSOLETE #define S_TO_W 0x100 +OBSOLETE #define W_TO_S 0x200 +OBSOLETE #define W_TO_R 0x400 +OBSOLETE #define S_TO_R 0x800 +OBSOLETE #endif /* GET_WRITE */ +OBSOLETE +OBSOLETE struct llist { +OBSOLETE struct afs_lock *lk; +OBSOLETE short operation; +OBSOLETE short who; +OBSOLETE struct llist * next; +OBSOLETE struct llist *prev; +OBSOLETE }; +OBSOLETE +OBSOLETE /* These are definition for the translation flags fields */ +OBSOLETE +OBSOLETE #define KNOWNBAD 0x20 +OBSOLETE #define SYMLINK 0x40 +OBSOLETE struct name_trans { +OBSOLETE struct VenusFid pfid; +OBSOLETE int ntrans_idx; +OBSOLETE int oname_idx; +OBSOLETE int nname_idx; +OBSOLETE int next_nt_idx; +OBSOLETE char *old_name; +OBSOLETE char *new_name; +OBSOLETE struct name_trans *next; +OBSOLETE }; +OBSOLETE +OBSOLETE struct translations { +OBSOLETE struct VenusFid oldfid; +OBSOLETE struct VenusFid newfid; +OBSOLETE u_long flags; +OBSOLETE hyper validDV; +OBSOLETE int trans_idx; +OBSOLETE long callback; +OBSOLETE long cbExpires; +OBSOLETE int nl_idx; +OBSOLETE struct translations *next; +OBSOLETE struct name_trans *name_list; +OBSOLETE }; +OBSOLETE +OBSOLETE +OBSOLETE +OBSOLETE /* +OBSOLETE * this struct is used to help speed up finding the number of callbacks for +OBSOLETE * each server +OBSOLETE */ +OBSOLETE +OBSOLETE struct serv_cbcount { +OBSOLETE long server; +OBSOLETE long count; +OBSOLETE struct serv_cbcount *next; +OBSOLETE }; +OBSOLETE +OBSOLETE /* Stuff for the link name persistence */ +OBSOLETE +OBSOLETE #define MAP_ENTS 100 +OBSOLETE #define NAME_UNIT 255 +OBSOLETE #define NAME_DIRTY 0x1 +OBSOLETE +OBSOLETE /* header for the name backing file */ +OBSOLETE typedef struct map_header { +OBSOLETE long magic; /* magic number */ +OBSOLETE int num_ents; /* number of names stored */ +OBSOLETE char flags; /* flags for in core copy */ +OBSOLETE } map_header_t; +OBSOLETE +OBSOLETE /* commented out */ +OBSOLETE /* +OBSOLETE * this struct holds all the information pertaining to a certain +OBSOLETE * backing store used to keep persistance information +OBSOLETE */ +OBSOLETE /*typedef struct backing_store { +OBSOLETE long bs_inode; +OBSOLETE struct osi_dev bs_dev; +OBSOLETE char *bs_name; +OBSOLETE map_header_t *bs_header; +OBSOLETE char *bs_map; +OBSOLETE struct afs_lock bs_lock; +OBSOLETE struct osi_file *tfile; +OBSOLETE } backing_store_t;*/ +OBSOLETE +OBSOLETE #endif /* KERNEL */ +OBSOLETE +OBSOLETE /* CacheItems file has a header of type struct afs_fheader (keep aligned properly) */ +OBSOLETE struct afs_dheader { +OBSOLETE long magic; +OBSOLETE long firstCSize; +OBSOLETE long otherCSize; +OBSOLETE long spare; +OBSOLETE long current_op; +OBSOLETE enum connected_mode mode; +OBSOLETE }; +OBSOLETE +OBSOLETE #ifdef KERNEL +OBSOLETE +OBSOLETE #define have_shared_lock(lock) \ +OBSOLETE ((((lock)->excl_locked==SHARED_LOCK) && \ +OBSOLETE ((lock)->proc == osi_curpid())) ? 1 : 0) +OBSOLETE +OBSOLETE #define have_write_lock(lock) \ +OBSOLETE ((((lock)->excl_locked==WRITE_LOCK) && \ +OBSOLETE ((lock)->proc == osi_curpid())) ? 1 : 0) +OBSOLETE +OBSOLETE extern struct llist *llist; +OBSOLETE extern struct llist *cur_llist; +OBSOLETE +OBSOLETE /* these are function declarations so I can compile with -Wall in gcc, +OBSOLETE * not really needed, but help make clean compiles. +OBSOLETE */ +OBSOLETE +OBSOLETE extern int strlen(); +OBSOLETE #ifndef AFS_NETBSD_ENV +OBSOLETE extern void strcpy(); +OBSOLETE #endif /* AFS_NETBSD_ENV */ +OBSOLETE extern void bcopy(); +OBSOLETE extern int dir_Delete(); +OBSOLETE extern int dir_FindBlobs(); +OBSOLETE extern int dir_Lookup(); +OBSOLETE extern int dir_Create(); +OBSOLETE extern int find_file_name(); +OBSOLETE extern int afs_create(); +OBSOLETE extern int afs_PutDCache(); +OBSOLETE +OBSOLETE #endif /* KERNEL */ +OBSOLETE +OBSOLETE #endif /* _DISCONNH */ +OBSOLETE +OBSOLETE +OBSOLETE #ifdef DISCONN +OBSOLETE typedef struct _fid_cb { +OBSOLETE VenusFid fid; +OBSOLETE struct _fid_cb *next; +OBSOLETE } fid_cb; +OBSOLETE #endif +OBSOLETE +OBSOLETE diff --git a/usr.sbin/afs/src/arlad/discon_log.c b/usr.sbin/afs/src/arlad/discon_log.c index c5000e9877e..5323eb9f662 100644 --- a/usr.sbin/afs/src/arlad/discon_log.c +++ b/usr.sbin/afs/src/arlad/discon_log.c @@ -1,482 +1,473 @@ -/* COPYRIGHT (C) 1998 - * THE REGENTS OF THE UNIVERSITY OF MICHIGAN - * ALL RIGHTS RESERVED - * - * PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS - * AND REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS - * FOR ANY PURPOSE, SO LONG AS THE NAME OF THE UNIVERSITY OF - * MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY - * PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE - * WITHOUT SPECIFIC, WRITTEN PRIOR AUTHORIZATION. IF THE - * ABOVE COPYRIGHT NOTICE OR ANY OTHER IDENTIFICATION OF THE - * UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY - * PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST - * ALSO BE INCLUDED. - * - * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION - * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY - * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF - * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING - * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE - * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE - * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR - * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING - * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN - * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGES. - */ - -/* - * This file contains functions that relate to performance statistics - * for disconnected operation. - */ - -#include "arla_local.h" - -RCSID("$KTH: discon_log.c,v 1.8.40.1 2001/06/04 22:16:35 ahltorp Exp $"); - -extern int dlog_mod; -extern long current_op_no; - -extern DARLA_file log_data; - -extern long Log_is_open; - -log_ent_t log_head; - -int DARLA_Open(DARLA_file *Dfp, char *fname, int oflag); -int DARLA_Read(DARLA_file *Dfp, char *cp, int len); -int DARLA_Write(DARLA_file *Dfp, char *cp, int len); -int DARLA_Seek(DARLA_file *Dfp, int offset, int whence); - -#if 0 -/* - * read an entry from the log file described by tfile. The result is - * put into the log_ent data. This return 0 if successful, 1 if - * it failed to some reason ( ie. no more data ). - */ - -int -read_log_ent(DARLA_file * tfile, log_ent_t *in_log) -{ - int len; - char *bp; - - if (DARLA_Read(tfile, (char *) in_log, sizeof (int)) != sizeof(int)) - return 1; - - len = in_log->log_len - sizeof(int); - bp = (char *) in_log + sizeof(int); - - if (DARLA_Read(tfile, bp, len) != len) { - printf("read_log_ent: short read \n"); - return 1; - } - return 0; -} - -void -update_log_ent(offset, flags) -long offset; -int flags; -{ - struct DARLA_file *tfile; - log_ent_t *log_ent; - int code; - - tfile = DARLA_UFSOpen(&log_data.bs_dev, log_data.bs_inode); - if (!tfile) - panic("update_log_ent: failed to open log file"); - - DARLA_Seek(tfile, offset); - - log_ent = (log_ent_t *) malloc(sizeof(log_ent_t)); - code = read_log_ent(tfile, log_ent); - - if (code) { - printf("update_log_ent: failed to read log entry at %d \n", - offset); - } else { - - /* set the log flags */ - log_ent->log_flags |= flags; - - /* write the entry back out */ - DARLA_Seek(tfile, offset); - DARLA_Write(tfile, (char *) log_ent, log_ent->log_len); - } - free(log_ent); - DARLA_Close(tfile); -} -#endif - - -/* write the log entries to disk */ -static long -write_log_ent(int len, log_ent_t *log) -{ - - long new_num; - static int index=0; - - arla_warnx (ADEBDISCONN,"We are writing a log"); - if (!Log_is_open) { - return -1; - } - - if (log_head.next == 0) { - log_head.next = (log_ent_t *) malloc(sizeof(log_ent_t)); - *log_head.next = *log; - log_head.next->next = 0; - } - else { - log->next = log_head.next; - log_head.next = (log_ent_t *) malloc(sizeof(log_ent_t)); - *log_head.next = *log; - } - - ObtainWriteLock(&log_data.bs_lock); - - new_num = 0; - - log->log_opno = new_num; - gettimeofday(&log->log_time, 0); - - log->log_offset = log_data.offset; - log->log_flags = 0; - log->log_index = index++; - - DARLA_Write(&log_data, (char *) log, len); - - ReleaseWriteLock(&log_data.bs_lock); - - return (new_num); -} - -long -log_dis_store(struct vcache *avc) -{ - log_ent_t *store; - long op_no; - - store = (log_ent_t *) malloc(sizeof(log_ent_t)); - - store->log_op = DIS_STORE; - store->st_fid = avc->fid; - store->st_origdv = avc->DataVersion; - store->st_flag = avc->flag; - - /* have to log cred as well */ - store->cred = avc->cred; - - /* figure out the length of a store entry */ - store->log_len = ((char *) &(store->st_origdv)) - ((char *) store) - + sizeof(store->st_origdv); - - op_no = write_log_ent(store->log_len, store); - - free(store); - return op_no; -} - - -/* Log a mkdir operation */ -long -log_dis_mkdir(struct vcache *pvc, struct vcache *dvc, - AFSStoreStatus *attrs, char *name) -{ - log_ent_t *mkdir; - long op_no; - - mkdir = (log_ent_t *) malloc(sizeof(log_ent_t)); - - mkdir->log_op = DIS_MKDIR; - mkdir->md_dirfid = dvc->fid; - /*Ba Wu: the data vers. for child dir*/ - mkdir->md_dversion = dvc->DataVersion; - mkdir->md_parentfid = pvc->fid; - mkdir->cred = pvc->cred; - mkdir->md_vattr = *attrs; - - /* save the name */ - strlcpy((char *) mkdir->md_name, name, sizeof mkdir->md_name); - - /* calculate the length of this record */ - mkdir->log_len = ((char *) mkdir->md_name - (char *) mkdir) - + strlen(name) + 1; - - op_no = write_log_ent(mkdir->log_len, mkdir); - - free(mkdir); - return op_no; -} - - -long -log_dis_create(struct vcache *parent, struct vcache *child, char *name) -{ - log_ent_t *create; - long op_no; - struct vcache *ch; - struct vcache *par; - - ch = child; - par = parent; - ch->DataVersion = child->DataVersion; - - create = (log_ent_t *) malloc(sizeof(log_ent_t)); - - create->log_op = DIS_CREATE; - create->cr_filefid = ch->fid; - create->cr_parentfid = par->fid; - create->cr_origdv = ch->DataVersion; - create->cred = parent->cred; - - strlcpy((char *) create->cr_name, name, sizeof create->cr_name); - - create->log_len = ((char *) create->cr_name - (char *) create) + - strlen(name) + 1; - - op_no = write_log_ent(create->log_len, create); - - free(create); - return op_no; -} - -#if 0 -long -log_dis_remove(struct vcache *avc, FCacheEntry *childentry, char *name) -{ - log_ent_t *remove; - long op_no; - remove = (log_ent_t *) malloc(sizeof(log_ent_t)); - - remove->log_op = DIS_REMOVE; - remove->cred = avc->cred; - remove->rm_filefid = avc->fid; - remove->rm_origdv = avc->DataVersion; - remove->rm_chentry = childentry; - - strlcpy((char *) remove->rm_name, name, sizeof remove->rm_name); - - remove->log_len = ((char *) remove->rm_name - (char *) remove) + - strlen(name) + 1; - - op_no = write_log_ent(remove->log_len, remove); - - free(remove); - arla_log(ADEBDISCONN, "remove: fid.Cell=%ld, fid.fid.Volume=%ld, " - "fid.Unique=%ld", \ - remove->rm_filefid.Cell, - remove->rm_filefid.fid.Volume, - remove->rm_filefid.fid.Unique); - - return op_no; -} - - -long -log_dis_rmdir(struct vcache *dir, FCacheEntry *cce, const char *name) -{ - log_ent_t *rmdir; - long op_no; - - rmdir = malloc(sizeof(log_ent_t)); - - rmdir->log_op = DIS_RMDIR; - rmdir->cred = dir->cred; - rmdir->rd_parentfid = dir->fid; - rmdir->rd_direntry = cce; - - strlcpy((char *) rmdir->rd_name, name, sizeof rmdir->rd_name); - - rmdir->log_len = ((char *) rmdir->rd_name - (char *) rmdir) + - strlen(name) + 1; - - op_no = write_log_ent(rmdir->log_len, rmdir); - - free(rmdir); - return op_no; -} - - -long -log_dis_rename(struct vcache *old_dir, char *old_name, - struct vcache *new_dir, char *new_name) -{ - log_ent_t *rename; - char *cp; - - rename = malloc(sizeof(log_ent_t)); - - rename->log_op = DIS_RENAME; - rename->rn_oparentfid = old_dir->fid; - rename->rn_nparentfid = new_dir->fid; - rename->rn_origdv = old_dir->DataVersion; - rename->rn_overdv = new_dir->DataVersion; - rename->cred = old_dir->cred; - - strlcpy((char *) rename->rn_names, old_name, MAX_NAME); - cp = (char *) rename->rn_names + strlen(old_name) + 1; - - strlcpy((char *) cp, new_name, MAX_NAME); - cp += strlen(new_name) + 1; - - rename->log_len = (char *) cp - (char *) rename; - - write_log_ent(rename->log_len, rename); - - free(rename); - return 0; -} - - - -/* Log a link operation */ -long -log_dis_link(struct vcache *pvc, struct vcache *lvc, char *name) - -{ - log_ent_t *link; - long op_no; - - link = malloc(sizeof(log_ent_t)); - - link->log_op = DIS_LINK; - link->cred = pvc->cred; - link->ln_linkfid = lvc->fid; - link->ln_parentfid = pvc->fid; - - /* save the name */ - strlcpy((char *) link->ln_name, name, sizeof link->ln_name); - /* calculate the length of this record */ - link->log_len = ((char *) link->ln_name - (char *) link) + - strlen(name) + 1; - - op_no = write_log_ent(link->log_len, link); - - free(link); - return op_no; -} - -/* Log a symlink operation */ -long -log_dis_symlink(struct vcache *pvc, struct vcache *cvc, - AFSStoreStatus *attr, char *linkname, char *content) -{ - log_ent_t *slink; - long op_no; - - slink = malloc(sizeof(log_ent_t)); - - slink->log_op = DIS_SYMLINK; - slink->sy_parentfid = pvc->fid; - slink->sy_filefid = cvc->fid; - slink->sy_attr = *attr; - slink->cred = pvc->cred; - - /* copy in the link name */ - strlcpy((char *) slink->sy_name, linkname, sizeof slink->sy_name); - strlcpy((char *) slink->sy_content, content, sizeof slink->sy_content); - - /* calculate the length of this record */ - slink->log_len = ( (char *) slink->sy_content - - (char *) slink) + - strlen(content) + 1; - - op_no = write_log_ent(slink->log_len, slink); - - free(slink); - return op_no; -} -#endif - -/* Log a setattr operation */ -long -log_dis_setattr(struct vcache *tvc, struct xfs_attr *attrs) -{ - log_ent_t *setattr; - long op_no; - - setattr = (log_ent_t *) malloc(sizeof(log_ent_t)); - - setattr->log_op = DIS_SETATTR; - setattr->sa_fid = tvc->fid; - setattr->cred = tvc->cred; - setattr->sa_origdv = tvc->DataVersion; - - setattr->sa_vattr = *attrs; - - /* calculate the length of this record */ - setattr->log_len = ((char *) &setattr->sa_origdv - (char *) setattr) + - sizeof(setattr->sa_origdv); - - op_no = write_log_ent(setattr->log_len, setattr); - - arla_log(ADEBDISCONN, "log_dis_setattr: fid.Cell=0x%x, fid.fid.Volume=0x%x," - "fid.fid.Vnode=0x%x, fid.fid.Unique=0x%x", - tvc->fid.Cell, - tvc->fid.fid.Volume, - tvc->fid.fid.Vnode, - tvc->fid.fid.Unique); - - arla_log(ADEBDISCONN, "log_dis_setattr: writing %d byte log entry."); - - free(setattr); - return op_no; -} - -#if 0 -long -log_dis_nonmutating(struct vcache *tvc, log_ops_t op) -{ -#ifdef LOGNONMUTE - log_ent_t *non_mute; - long op_no; - - non_mute = (log_ent_t *) malloc(sizeof(log_ent_t)); - - non_mute->log_op = op; - non_mute->cred = tvc->cred; - non_mute->nm_fid = tvc->fid; - non_mute->nm_origdv = tvc->DataVersion; - non_mute->log_len = ((char *) &non_mute->nm_origdv - - (char *) non_mute) + sizeof(non_mute->nm_origdv); - - /* XXX lhuston removed for debugging */ - op_no = write_log_ent(non_mute->log_len, non_mute); - - free(non_mute); - return op_no; -#else - return 0; /* 0 was current_op_no */ -#endif -} - - -long -log_dis_access(struct vcache *tvc) -{ - return log_dis_nonmutating(tvc, DIS_ACCESS); -} - -long -log_dis_readdir(struct vcache *tvc) -{ - return log_dis_nonmutating(tvc, DIS_READDIR); -} - -long -log_dis_readlink(struct vcache *tvc) -{ - return log_dis_nonmutating(tvc, DIS_READLINK); -} - -long -log_dis_fsync(struct vcache *tvc) -{ - /* treat an fsync as a store */ - return log_dis_nonmutating(tvc, DIS_FSYNC); -} -#endif +OBSOLETE /* COPYRIGHT (C) 1998 +OBSOLETE * THE REGENTS OF THE UNIVERSITY OF MICHIGAN +OBSOLETE * ALL RIGHTS RESERVED +OBSOLETE * +OBSOLETE * PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS +OBSOLETE * AND REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS +OBSOLETE * FOR ANY PURPOSE, SO LONG AS THE NAME OF THE UNIVERSITY OF +OBSOLETE * MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY +OBSOLETE * PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE +OBSOLETE * WITHOUT SPECIFIC, WRITTEN PRIOR AUTHORIZATION. IF THE +OBSOLETE * ABOVE COPYRIGHT NOTICE OR ANY OTHER IDENTIFICATION OF THE +OBSOLETE * UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY +OBSOLETE * PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST +OBSOLETE * ALSO BE INCLUDED. +OBSOLETE * +OBSOLETE * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION +OBSOLETE * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY +OBSOLETE * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF +OBSOLETE * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING +OBSOLETE * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF +OBSOLETE * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE +OBSOLETE * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE +OBSOLETE * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR +OBSOLETE * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING +OBSOLETE * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN +OBSOLETE * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF +OBSOLETE * SUCH DAMAGES. +OBSOLETE */ +OBSOLETE +OBSOLETE /* +OBSOLETE * This file contains functions that relate to performance statistics +OBSOLETE * for disconnected operation. +OBSOLETE */ +OBSOLETE +OBSOLETE #include "arla_local.h" +OBSOLETE +OBSOLETE RCSID("$arla: discon_log.c,v 1.12 2002/09/07 10:43:05 lha Exp $"); +OBSOLETE +OBSOLETE int Log_is_open; +OBSOLETE DARLA_file log_data; +OBSOLETE +OBSOLETE log_ent_t log_head; +OBSOLETE +OBSOLETE #if 0 +OBSOLETE /* +OBSOLETE * read an entry from the log file described by tfile. The result is +OBSOLETE * put into the log_ent data. This return 0 if successful, 1 if +OBSOLETE * it failed to some reason ( ie. no more data ). +OBSOLETE */ +OBSOLETE +OBSOLETE int +OBSOLETE read_log_ent(DARLA_file * tfile, log_ent_t *in_log) +OBSOLETE { +OBSOLETE int len; +OBSOLETE char *bp; +OBSOLETE +OBSOLETE if (DARLA_Read(tfile, (char *) in_log, sizeof (int)) != sizeof(int)) +OBSOLETE return 1; +OBSOLETE +OBSOLETE len = in_log->log_len - sizeof(int); +OBSOLETE bp = (char *) in_log + sizeof(int); +OBSOLETE +OBSOLETE if (DARLA_Read(tfile, bp, len) != len) { +OBSOLETE printf("read_log_ent: short read \n"); +OBSOLETE return 1; +OBSOLETE } +OBSOLETE return 0; +OBSOLETE } +OBSOLETE +OBSOLETE void +OBSOLETE update_log_ent(offset, flags) +OBSOLETE long offset; +OBSOLETE int flags; +OBSOLETE { +OBSOLETE struct DARLA_file *tfile; +OBSOLETE log_ent_t *log_ent; +OBSOLETE int code; +OBSOLETE +OBSOLETE tfile = DARLA_UFSOpen(&log_data.bs_dev, log_data.bs_inode); +OBSOLETE if (!tfile) +OBSOLETE panic("update_log_ent: failed to open log file"); +OBSOLETE +OBSOLETE DARLA_Seek(tfile, offset); +OBSOLETE +OBSOLETE log_ent = (log_ent_t *) malloc(sizeof(log_ent_t)); +OBSOLETE code = read_log_ent(tfile, log_ent); +OBSOLETE +OBSOLETE if (code) { +OBSOLETE printf("update_log_ent: failed to read log entry at %d \n", +OBSOLETE offset); +OBSOLETE } else { +OBSOLETE +OBSOLETE /* set the log flags */ +OBSOLETE log_ent->log_flags |= flags; +OBSOLETE +OBSOLETE /* write the entry back out */ +OBSOLETE DARLA_Seek(tfile, offset); +OBSOLETE DARLA_Write(tfile, (char *) log_ent, log_ent->log_len); +OBSOLETE } +OBSOLETE free(log_ent); +OBSOLETE DARLA_Close(tfile); +OBSOLETE } +OBSOLETE #endif +OBSOLETE +OBSOLETE +OBSOLETE /* write the log entries to disk */ +OBSOLETE static long +OBSOLETE write_log_ent(int len, log_ent_t *log) +OBSOLETE { +OBSOLETE +OBSOLETE long new_num; +OBSOLETE static int index=0; +OBSOLETE +OBSOLETE arla_warnx (ADEBDISCONN,"We are writing a log"); +OBSOLETE if (!Log_is_open) { +OBSOLETE return -1; +OBSOLETE } +OBSOLETE +OBSOLETE if (log_head.next == 0) { +OBSOLETE log_head.next = (log_ent_t *) malloc(sizeof(log_ent_t)); +OBSOLETE *log_head.next = *log; +OBSOLETE log_head.next->next = 0; +OBSOLETE } +OBSOLETE else { +OBSOLETE log->next = log_head.next; +OBSOLETE log_head.next = (log_ent_t *) malloc(sizeof(log_ent_t)); +OBSOLETE *log_head.next = *log; +OBSOLETE } +OBSOLETE +OBSOLETE ObtainWriteLock(&log_data.bs_lock); +OBSOLETE +OBSOLETE new_num = 0; +OBSOLETE +OBSOLETE log->log_opno = new_num; +OBSOLETE gettimeofday(&log->log_time, 0); +OBSOLETE +OBSOLETE log->log_offset = log_data.offset; +OBSOLETE log->log_flags = 0; +OBSOLETE log->log_index = index++; +OBSOLETE +OBSOLETE DARLA_Write(&log_data, (char *) log, len); +OBSOLETE +OBSOLETE ReleaseWriteLock(&log_data.bs_lock); +OBSOLETE +OBSOLETE return (new_num); +OBSOLETE } +OBSOLETE +OBSOLETE long +OBSOLETE log_dis_store(struct vcache *avc) +OBSOLETE { +OBSOLETE log_ent_t *store; +OBSOLETE long op_no; +OBSOLETE +OBSOLETE store = (log_ent_t *) malloc(sizeof(log_ent_t)); +OBSOLETE +OBSOLETE store->log_op = DIS_STORE; +OBSOLETE store->st_fid = avc->fid; +OBSOLETE store->st_origdv = avc->DataVersion; +OBSOLETE store->st_flag = avc->flag; +OBSOLETE +OBSOLETE /* have to log cred as well */ +OBSOLETE store->cred = avc->cred; +OBSOLETE +OBSOLETE /* figure out the length of a store entry */ +OBSOLETE store->log_len = ((char *) &(store->st_origdv)) - ((char *) store) +OBSOLETE + sizeof(store->st_origdv); +OBSOLETE +OBSOLETE op_no = write_log_ent(store->log_len, store); +OBSOLETE +OBSOLETE free(store); +OBSOLETE return op_no; +OBSOLETE } +OBSOLETE +OBSOLETE +OBSOLETE /* Log a mkdir operation */ +OBSOLETE long +OBSOLETE log_dis_mkdir(struct vcache *pvc, struct vcache *dvc, +OBSOLETE AFSStoreStatus *attrs, char *name) +OBSOLETE { +OBSOLETE log_ent_t *mkdir; +OBSOLETE long op_no; +OBSOLETE +OBSOLETE mkdir = (log_ent_t *) malloc(sizeof(log_ent_t)); +OBSOLETE +OBSOLETE mkdir->log_op = DIS_MKDIR; +OBSOLETE mkdir->md_dirfid = dvc->fid; +OBSOLETE /*Ba Wu: the data vers. for child dir*/ +OBSOLETE mkdir->md_dversion = dvc->DataVersion; +OBSOLETE mkdir->md_parentfid = pvc->fid; +OBSOLETE mkdir->cred = pvc->cred; +OBSOLETE mkdir->md_vattr = *attrs; +OBSOLETE +OBSOLETE /* save the name */ +OBSOLETE strcpy((char *) mkdir->md_name, name); +OBSOLETE +OBSOLETE /* calculate the length of this record */ +OBSOLETE mkdir->log_len = ((char *) mkdir->md_name - (char *) mkdir) +OBSOLETE + strlen(name) + 1; +OBSOLETE +OBSOLETE op_no = write_log_ent(mkdir->log_len, mkdir); +OBSOLETE +OBSOLETE free(mkdir); +OBSOLETE return op_no; +OBSOLETE } +OBSOLETE +OBSOLETE +OBSOLETE long +OBSOLETE log_dis_create(struct vcache *parent, struct vcache *child, char *name) +OBSOLETE { +OBSOLETE log_ent_t *create; +OBSOLETE long op_no; +OBSOLETE struct vcache *ch; +OBSOLETE struct vcache *par; +OBSOLETE +OBSOLETE ch = child; +OBSOLETE par = parent; +OBSOLETE ch->DataVersion = child->DataVersion; +OBSOLETE +OBSOLETE create = (log_ent_t *) malloc(sizeof(log_ent_t)); +OBSOLETE +OBSOLETE create->log_op = DIS_CREATE; +OBSOLETE create->cr_filefid = ch->fid; +OBSOLETE create->cr_parentfid = par->fid; +OBSOLETE create->cr_origdv = ch->DataVersion; +OBSOLETE create->cred = parent->cred; +OBSOLETE +OBSOLETE strcpy((char *) create->cr_name, name); +OBSOLETE +OBSOLETE create->log_len = ((char *) create->cr_name - (char *) create) + +OBSOLETE strlen(name) + 1; +OBSOLETE +OBSOLETE op_no = write_log_ent(create->log_len, create); +OBSOLETE +OBSOLETE free(create); +OBSOLETE return op_no; +OBSOLETE } +OBSOLETE +OBSOLETE #if 0 +OBSOLETE long +OBSOLETE log_dis_remove(struct vcache *avc, FCacheEntry *childentry, char *name) +OBSOLETE { +OBSOLETE log_ent_t *remove; +OBSOLETE long op_no; +OBSOLETE remove = (log_ent_t *) malloc(sizeof(log_ent_t)); +OBSOLETE +OBSOLETE remove->log_op = DIS_REMOVE; +OBSOLETE remove->cred = avc->cred; +OBSOLETE remove->rm_filefid = avc->fid; +OBSOLETE remove->rm_origdv = avc->DataVersion; +OBSOLETE remove->rm_chentry = childentry; +OBSOLETE +OBSOLETE strcpy((char *) remove->rm_name, name); +OBSOLETE +OBSOLETE remove->log_len = ((char *) remove->rm_name - (char *) remove) + +OBSOLETE strlen(name) + 1; +OBSOLETE +OBSOLETE op_no = write_log_ent(remove->log_len, remove); +OBSOLETE +OBSOLETE free(remove); +OBSOLETE arla_log(ADEBDISCONN, "remove: fid.Cell=%ld, fid.fid.Volume=%ld, " +OBSOLETE "fid.Unique=%ld", \ +OBSOLETE remove->rm_filefid.Cell, +OBSOLETE remove->rm_filefid.fid.Volume, +OBSOLETE remove->rm_filefid.fid.Unique); +OBSOLETE +OBSOLETE return op_no; +OBSOLETE } +OBSOLETE +OBSOLETE +OBSOLETE long +OBSOLETE log_dis_rmdir(struct vcache *dir, FCacheEntry *cce, const char *name) +OBSOLETE { +OBSOLETE log_ent_t *rmdir; +OBSOLETE long op_no; +OBSOLETE +OBSOLETE rmdir = malloc(sizeof(log_ent_t)); +OBSOLETE +OBSOLETE rmdir->log_op = DIS_RMDIR; +OBSOLETE rmdir->cred = dir->cred; +OBSOLETE rmdir->rd_parentfid = dir->fid; +OBSOLETE rmdir->rd_direntry = cce; +OBSOLETE +OBSOLETE strcpy((char *) rmdir->rd_name, name); +OBSOLETE +OBSOLETE rmdir->log_len = ((char *) rmdir->rd_name - (char *) rmdir) + +OBSOLETE strlen(name) + 1; +OBSOLETE +OBSOLETE op_no = write_log_ent(rmdir->log_len, rmdir); +OBSOLETE +OBSOLETE free(rmdir); +OBSOLETE return op_no; +OBSOLETE } +OBSOLETE +OBSOLETE +OBSOLETE long +OBSOLETE log_dis_rename(struct vcache *old_dir, char *old_name, +OBSOLETE struct vcache *new_dir, char *new_name) +OBSOLETE { +OBSOLETE log_ent_t *rename; +OBSOLETE char *cp; +OBSOLETE +OBSOLETE rename = malloc(sizeof(log_ent_t)); +OBSOLETE +OBSOLETE rename->log_op = DIS_RENAME; +OBSOLETE rename->rn_oparentfid = old_dir->fid; +OBSOLETE rename->rn_nparentfid = new_dir->fid; +OBSOLETE rename->rn_origdv = old_dir->DataVersion; +OBSOLETE rename->rn_overdv = new_dir->DataVersion; +OBSOLETE rename->cred = old_dir->cred; +OBSOLETE +OBSOLETE strcpy((char *) rename->rn_names, old_name); +OBSOLETE cp = (char *) rename->rn_names + strlen(old_name) + 1; +OBSOLETE +OBSOLETE strcpy((char *) cp, new_name); +OBSOLETE cp += strlen(new_name) + 1; +OBSOLETE +OBSOLETE rename->log_len = (char *) cp - (char *) rename; +OBSOLETE +OBSOLETE write_log_ent(rename->log_len, rename); +OBSOLETE +OBSOLETE free(rename); +OBSOLETE return 0; +OBSOLETE } +OBSOLETE +OBSOLETE +OBSOLETE +OBSOLETE /* Log a link operation */ +OBSOLETE long +OBSOLETE log_dis_link(struct vcache *pvc, struct vcache *lvc, char *name) +OBSOLETE +OBSOLETE { +OBSOLETE log_ent_t *link; +OBSOLETE long op_no; +OBSOLETE +OBSOLETE link = malloc(sizeof(log_ent_t)); +OBSOLETE +OBSOLETE link->log_op = DIS_LINK; +OBSOLETE link->cred = pvc->cred; +OBSOLETE link->ln_linkfid = lvc->fid; +OBSOLETE link->ln_parentfid = pvc->fid; +OBSOLETE +OBSOLETE /* save the name */ +OBSOLETE strcpy((char *) link->ln_name, name); +OBSOLETE /* calculate the length of this record */ +OBSOLETE link->log_len = ((char *) link->ln_name - (char *) link) + +OBSOLETE strlen(name) + 1; +OBSOLETE +OBSOLETE op_no = write_log_ent(link->log_len, link); +OBSOLETE +OBSOLETE free(link); +OBSOLETE return op_no; +OBSOLETE } +OBSOLETE +OBSOLETE /* Log a symlink operation */ +OBSOLETE long +OBSOLETE log_dis_symlink(struct vcache *pvc, struct vcache *cvc, +OBSOLETE AFSStoreStatus *attr, char *linkname, char *content) +OBSOLETE { +OBSOLETE log_ent_t *slink; +OBSOLETE long op_no; +OBSOLETE +OBSOLETE slink = malloc(sizeof(log_ent_t)); +OBSOLETE +OBSOLETE slink->log_op = DIS_SYMLINK; +OBSOLETE slink->sy_parentfid = pvc->fid; +OBSOLETE slink->sy_filefid = cvc->fid; +OBSOLETE slink->sy_attr = *attr; +OBSOLETE slink->cred = pvc->cred; +OBSOLETE +OBSOLETE /* copy in the link name */ +OBSOLETE strcpy((char *) slink->sy_name, linkname); +OBSOLETE strcpy((char *) slink->sy_content, content); +OBSOLETE +OBSOLETE /* calculate the length of this record */ +OBSOLETE slink->log_len = ( (char *) slink->sy_content - +OBSOLETE (char *) slink) + +OBSOLETE strlen(content) + 1; +OBSOLETE +OBSOLETE op_no = write_log_ent(slink->log_len, slink); +OBSOLETE +OBSOLETE free(slink); +OBSOLETE return op_no; +OBSOLETE } +OBSOLETE #endif +OBSOLETE +OBSOLETE /* Log a setattr operation */ +OBSOLETE long +OBSOLETE log_dis_setattr(struct vcache *tvc, struct nnpfs_attr *attrs) +OBSOLETE { +OBSOLETE log_ent_t *setattr; +OBSOLETE long op_no; +OBSOLETE +OBSOLETE setattr = (log_ent_t *) malloc(sizeof(log_ent_t)); +OBSOLETE +OBSOLETE setattr->log_op = DIS_SETATTR; +OBSOLETE setattr->sa_fid = tvc->fid; +OBSOLETE setattr->cred = tvc->cred; +OBSOLETE setattr->sa_origdv = tvc->DataVersion; +OBSOLETE +OBSOLETE setattr->sa_vattr = *attrs; +OBSOLETE +OBSOLETE /* calculate the length of this record */ +OBSOLETE setattr->log_len = ((char *) &setattr->sa_origdv - (char *) setattr) + +OBSOLETE sizeof(setattr->sa_origdv); +OBSOLETE +OBSOLETE op_no = write_log_ent(setattr->log_len, setattr); +OBSOLETE +OBSOLETE arla_log(ADEBDISCONN, "log_dis_setattr: fid.Cell=0x%x, fid.fid.Volume=0x%x," +OBSOLETE "fid.fid.Vnode=0x%x, fid.fid.Unique=0x%x", +OBSOLETE tvc->fid.Cell, +OBSOLETE tvc->fid.fid.Volume, +OBSOLETE tvc->fid.fid.Vnode, +OBSOLETE tvc->fid.fid.Unique); +OBSOLETE +OBSOLETE arla_log(ADEBDISCONN, "log_dis_setattr: writing %d byte log entry."); +OBSOLETE +OBSOLETE free(setattr); +OBSOLETE return op_no; +OBSOLETE } +OBSOLETE +OBSOLETE #if 0 +OBSOLETE long +OBSOLETE log_dis_nonmutating(struct vcache *tvc, log_ops_t op) +OBSOLETE { +OBSOLETE #ifdef LOGNONMUTE +OBSOLETE log_ent_t *non_mute; +OBSOLETE long op_no; +OBSOLETE +OBSOLETE non_mute = (log_ent_t *) malloc(sizeof(log_ent_t)); +OBSOLETE +OBSOLETE non_mute->log_op = op; +OBSOLETE non_mute->cred = tvc->cred; +OBSOLETE non_mute->nm_fid = tvc->fid; +OBSOLETE non_mute->nm_origdv = tvc->DataVersion; +OBSOLETE non_mute->log_len = ((char *) &non_mute->nm_origdv - +OBSOLETE (char *) non_mute) + sizeof(non_mute->nm_origdv); +OBSOLETE +OBSOLETE /* XXX lhuston removed for debugging */ +OBSOLETE op_no = write_log_ent(non_mute->log_len, non_mute); +OBSOLETE +OBSOLETE free(non_mute); +OBSOLETE return op_no; +OBSOLETE #else +OBSOLETE return 0; /* 0 was current_op_no */ +OBSOLETE #endif +OBSOLETE } +OBSOLETE +OBSOLETE +OBSOLETE long +OBSOLETE log_dis_access(struct vcache *tvc) +OBSOLETE { +OBSOLETE return log_dis_nonmutating(tvc, DIS_ACCESS); +OBSOLETE } +OBSOLETE +OBSOLETE long +OBSOLETE log_dis_readdir(struct vcache *tvc) +OBSOLETE { +OBSOLETE return log_dis_nonmutating(tvc, DIS_READDIR); +OBSOLETE } +OBSOLETE +OBSOLETE long +OBSOLETE log_dis_readlink(struct vcache *tvc) +OBSOLETE { +OBSOLETE return log_dis_nonmutating(tvc, DIS_READLINK); +OBSOLETE } +OBSOLETE +OBSOLETE long +OBSOLETE log_dis_fsync(struct vcache *tvc) +OBSOLETE { +OBSOLETE /* treat an fsync as a store */ +OBSOLETE return log_dis_nonmutating(tvc, DIS_FSYNC); +OBSOLETE } +OBSOLETE #endif diff --git a/usr.sbin/afs/src/arlad/discon_log.h b/usr.sbin/afs/src/arlad/discon_log.h index 27638f22523..b35be832e92 100644 --- a/usr.sbin/afs/src/arlad/discon_log.h +++ b/usr.sbin/afs/src/arlad/discon_log.h @@ -1,270 +1,274 @@ -/* COPYRIGHT (C) 1998 - * THE REGENTS OF THE UNIVERSITY OF MICHIGAN - * ALL RIGHTS RESERVED - * - * PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS - * AND REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS - * FOR ANY PURPOSE, SO LONG AS THE NAME OF THE UNIVERSITY OF - * MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY - * PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE - * WITHOUT SPECIFIC, WRITTEN PRIOR AUTHORIZATION. IF THE - * ABOVE COPYRIGHT NOTICE OR ANY OTHER IDENTIFICATION OF THE - * UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY - * PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST - * ALSO BE INCLUDED. - * - * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION - * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY - * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF - * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING - * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE - * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE - * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR - * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING - * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN - * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGES. - */ - -/* - * This file contains all the relevant information pertaining to logging - * for disconnected afs. - */ -/* replace vattr with xfs_attr in the log */ -#include <xfs/xfs_attr.h> -#ifndef _DISCONN_LOG_H - -#define _DISCONN_LOG_H - -#define BUFSIZE 256 - -#define MAX_NAME AFSNAMEMAX - -enum log_ops { - DIS_STORE, - DIS_MKDIR, - DIS_CREATE, - DIS_REMOVE, - DIS_RMDIR, - DIS_RENAME, - DIS_LINK, - DIS_SYMLINK, - DIS_SETATTR, - DIS_FSYNC, - DIS_ACCESS, - DIS_READDIR, - DIS_READLINK, - DIS_INFO, - DIS_START_OPT, - DIS_END_OPT, - DIS_REPLAYED -}; - -typedef enum log_ops log_ops_t; - -/* These are defines for the different log flags that can be set */ -#define LOG_INACTIVE 0x1 /* log no longer needs replay */ -#define LOG_REPLAYED 0x2 /* log entry was replayed */ -#define LOG_OPTIMIZED 0x4 /* log entry was optimized away */ -#define LOG_GENERATED 0x8 /* log entry created by optimizer */ - - -/* defines to make access easier */ -#define st_fid log_data.st.fid -#define st_origdv log_data.st.origdv - -/* added flag option */ -#define st_flag log_data.st.flag - -typedef u_int32_t hyper; - -/* a really stripped down version of CITI's vcache */ -struct vcache { - u_int32_t DataVersion; - struct VenusFid fid; - xfs_cred cred; - u_int flag; /* write flag */ -}; - -typedef struct store_log_data { - struct VenusFid fid; /* fid of the file */ - u_int flag; /* write flag */ - hyper origdv; /* cached data version of file */ -} store_log_data_t; - -/* defines to make access easier */ -#define md_dirfid log_data.md.dirfid -#define md_parentfid log_data.md.parentfid -#define md_vattr log_data.md.vattr -#define md_dversion log_data.md.dversion -#define md_name log_data.md.name - -typedef struct mkdir_log_data { - struct VenusFid dirfid; /* Fid of this dir */ - struct VenusFid parentfid; /* Fid of parent */ - /* struct vattr vattr; attrs to create with */ - AFSStoreStatus vattr; /* log store_status */ /*Ba Wu */ - hyper dversion; /* cached data version of file */ - char name[MAX_NAME]; /* space to store create name */ -} mkdir_log_data_t; - - -/* defines to make access easier */ -#define cr_filefid log_data.cr.filefid -#define cr_parentfid log_data.cr.parentfid -#define cr_vattr log_data.cr.vattr -#define cr_mode log_data.cr.mode -#define cr_exists log_data.cr.exists -#define cr_excl log_data.cr.excl -#define cr_origdv log_data.cr.origdv -#define cr_name log_data.cr.name - -typedef struct create_log_data { - struct VenusFid filefid; /* Fid of this file */ - struct VenusFid parentfid; /* Fid of parent */ - struct xfs_attr vattr; /* attrs to create with */ - int mode; /* mode to create with */ - int exists; /* did file exists */ - int excl; /* is file create exclusive ? */ - hyper origdv; /* cached data version of file */ - char name[MAX_NAME]; /* space to store create name */ -} create_log_data_t; - - - - -/* defines to make access easier */ -#define rm_filefid log_data.rm.filefid -#define rm_chentry log_data.rm.chentry -#define rm_origdv log_data.rm.origdv -#define rm_name log_data.rm.name - -typedef struct remove_log_data { - struct VenusFid filefid; /* Fid of this file */ - /*struct VenusFid parentfid;*/ /* Fid of parent */ - FCacheEntry *chentry; /*The entry for the deleted file*/ - hyper origdv; /* cached data version of file */ - char name[MAX_NAME]; /* space to store remove name */ -} remove_log_data_t; - - - -/* defines to make access easier */ -#define rd_direntry log_data.rd.direntry -#define rd_parentfid log_data.rd.parentfid -#define rd_name log_data.rd.name - -typedef struct rmdir_log_data { - FCacheEntry *direntry; /*Entry of this dir */ - struct VenusFid parentfid; /* Fid of parent */ - char name[MAX_NAME]; /* space to store dir name */ -} rmdir_log_data_t; - - -/* defines to make access easier */ -#define rn_oparentfid log_data.rn.oparentfid -#define rn_nparentfid log_data.rn.nparentfid -#define rn_renamefid log_data.rn.renamefid -#define rn_overfid log_data.rn.overfid -#define rn_origdv log_data.rn.origdv -#define rn_overdv log_data.rn.overdv -#define rn_names log_data.rn.names - -typedef struct rename_log_data { - struct VenusFid oparentfid; /* Fid of parent */ - struct VenusFid nparentfid; /* Fid of parent */ - struct VenusFid renamefid; /* Fid of file being rename */ - struct VenusFid overfid; /* Fid of overwritten file */ - hyper origdv; /* cached data version of file */ - hyper overdv; /* overwritten version of cached data */ - char names[MAX_NAME * 2]; /* space to store dir name */ -} rename_log_data_t; - -/* defines to make access easier */ -#define ln_linkfid log_data.ln.linkfid -#define ln_parentfid log_data.ln.parentfid -#define ln_name log_data.ln.name - -typedef struct link_log_data { - struct VenusFid linkfid; /* Fid of this dir */ - struct VenusFid parentfid; /* Fid of parent */ - char name[MAX_NAME]; /* space to store create name */ -} link_log_data_t; - -/* defines to make access easier */ -#define sy_linkfid log_data.sy.linkfid -#define sy_parentfid log_data.sy.parentfid -#define sy_filefid log_data.sy.filefid -#define sy_attr log_data.sy.attr -#define sy_name log_data.sy.name -#define sy_content log_data.sy.content - - -typedef struct slink_log_data { - struct VenusFid linkfid; /* Fid of this link */ - struct VenusFid parentfid; /* Fid of parent */ - struct VenusFid filefid; /* Fid of file */ - AFSStoreStatus attr; /* attrs to create with */ - char name[MAX_NAME]; /* space to name */ - char content[MAX_NAME]; /* space to new name */ -} slink_log_data_t; - -/* defines to make access easier */ -#define sa_fid log_data.sa.fid -#define sa_vattr log_data.sa.vattr -#define sa_origdv log_data.sa.origdv - -typedef struct setattr_log_data { - struct VenusFid fid; /* operand fid */ - struct xfs_attr vattr; /* attrs to set */ - hyper origdv; /* cached data version number */ -} setattr_log_data_t; - - -/* defines to make access easier */ -#define nm_fid log_data.nm.fid -#define nm_origdv log_data.nm.origdv - -typedef struct nonmute_log_data { - struct VenusFid fid; /* fid */ - hyper origdv; /* cached data version */ -} nonmute_log_data_t; - - - -typedef struct log_ent { - int log_len; /* len of this entry */ - log_ops_t log_op; /* operation */ - long log_opno; /* operation number */ - struct timeval log_time; /* time operation was logged */ - long log_offset; /* offset into the log file */ - short log_flags; /* offset into the log file */ - uid_t log_uid; /* uid of person performing op */ - xfs_cred cred; /* user credential */ - int log_index; /* index for the log */ - struct log_ent *next; /* point to the next one */ - - union { - store_log_data_t st; - mkdir_log_data_t md; - create_log_data_t cr; - remove_log_data_t rm; - rmdir_log_data_t rd; - rename_log_data_t rn; - link_log_data_t ln; - slink_log_data_t sy; - setattr_log_data_t sa; - nonmute_log_data_t nm; - } log_data; -} log_ent_t; - - -long log_dis_create(struct vcache *parent, struct vcache *child, char *name); -long log_dis_store(struct vcache *avc); -long log_dis_setattr(struct vcache *tvc, struct xfs_attr *attrs); -long log_dis_mkdir(struct vcache *pvc, struct vcache *dvc, - AFSStoreStatus *attrs, char *name); - -#endif /* _DISCONN_LOG_H */ - +OBSOLETE /* COPYRIGHT (C) 1998 +OBSOLETE * THE REGENTS OF THE UNIVERSITY OF MICHIGAN +OBSOLETE * ALL RIGHTS RESERVED +OBSOLETE * +OBSOLETE * PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS +OBSOLETE * AND REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS +OBSOLETE * FOR ANY PURPOSE, SO LONG AS THE NAME OF THE UNIVERSITY OF +OBSOLETE * MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY +OBSOLETE * PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE +OBSOLETE * WITHOUT SPECIFIC, WRITTEN PRIOR AUTHORIZATION. IF THE +OBSOLETE * ABOVE COPYRIGHT NOTICE OR ANY OTHER IDENTIFICATION OF THE +OBSOLETE * UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY +OBSOLETE * PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST +OBSOLETE * ALSO BE INCLUDED. +OBSOLETE * +OBSOLETE * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION +OBSOLETE * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY +OBSOLETE * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF +OBSOLETE * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING +OBSOLETE * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF +OBSOLETE * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE +OBSOLETE * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE +OBSOLETE * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR +OBSOLETE * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING +OBSOLETE * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN +OBSOLETE * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF +OBSOLETE * SUCH DAMAGES. +OBSOLETE */ +OBSOLETE +OBSOLETE /* +OBSOLETE * This file contains all the relevant information pertaining to logging +OBSOLETE * for disconnected afs. +OBSOLETE */ +OBSOLETE /* replace vattr with nnpfs_attr in the log */ +OBSOLETE #include <nnpfs/nnpfs_attr.h> +OBSOLETE #ifndef _DISCONN_LOG_H +OBSOLETE +OBSOLETE #define _DISCONN_LOG_H +OBSOLETE +OBSOLETE #define BUFSIZE 256 +OBSOLETE +OBSOLETE #define MAX_NAME AFSNAMEMAX +OBSOLETE +OBSOLETE enum log_ops { +OBSOLETE DIS_STORE, +OBSOLETE DIS_MKDIR, +OBSOLETE DIS_CREATE, +OBSOLETE DIS_REMOVE, +OBSOLETE DIS_RMDIR, +OBSOLETE DIS_RENAME, +OBSOLETE DIS_LINK, +OBSOLETE DIS_SYMLINK, +OBSOLETE DIS_SETATTR, +OBSOLETE DIS_FSYNC, +OBSOLETE DIS_ACCESS, +OBSOLETE DIS_READDIR, +OBSOLETE DIS_READLINK, +OBSOLETE DIS_INFO, +OBSOLETE DIS_START_OPT, +OBSOLETE DIS_END_OPT, +OBSOLETE DIS_REPLAYED +OBSOLETE }; +OBSOLETE +OBSOLETE typedef enum log_ops log_ops_t; +OBSOLETE +OBSOLETE /* These are defines for the different log flags that can be set */ +OBSOLETE #define LOG_INACTIVE 0x1 /* log no longer needs replay */ +OBSOLETE #define LOG_REPLAYED 0x2 /* log entry was replayed */ +OBSOLETE #define LOG_OPTIMIZED 0x4 /* log entry was optimized away */ +OBSOLETE #define LOG_GENERATED 0x8 /* log entry created by optimizer */ +OBSOLETE +OBSOLETE +OBSOLETE /* defines to make access easier */ +OBSOLETE #define st_fid log_data.st.fid +OBSOLETE #define st_origdv log_data.st.origdv +OBSOLETE +OBSOLETE /* added flag option */ +OBSOLETE #define st_flag log_data.st.flag +OBSOLETE +OBSOLETE typedef uint32_t hyper; +OBSOLETE +OBSOLETE /* a really stripped down version of CITI's vcache */ +OBSOLETE struct vcache { +OBSOLETE uint32_t DataVersion; +OBSOLETE struct VenusFid fid; +OBSOLETE nnpfs_cred cred; +OBSOLETE u_int flag; /* write flag */ +OBSOLETE }; +OBSOLETE +OBSOLETE typedef struct store_log_data { +OBSOLETE struct VenusFid fid; /* fid of the file */ +OBSOLETE u_int flag; /* write flag */ +OBSOLETE hyper origdv; /* cached data version of file */ +OBSOLETE } store_log_data_t; +OBSOLETE +OBSOLETE /* defines to make access easier */ +OBSOLETE #define md_dirfid log_data.md.dirfid +OBSOLETE #define md_parentfid log_data.md.parentfid +OBSOLETE #define md_vattr log_data.md.vattr +OBSOLETE #define md_dversion log_data.md.dversion +OBSOLETE #define md_name log_data.md.name +OBSOLETE +OBSOLETE typedef struct mkdir_log_data { +OBSOLETE struct VenusFid dirfid; /* Fid of this dir */ +OBSOLETE struct VenusFid parentfid; /* Fid of parent */ +OBSOLETE /* struct vattr vattr; attrs to create with */ +OBSOLETE AFSStoreStatus vattr; /* log store_status */ /*Ba Wu */ +OBSOLETE hyper dversion; /* cached data version of file */ +OBSOLETE char name[MAX_NAME]; /* space to store create name */ +OBSOLETE } mkdir_log_data_t; +OBSOLETE +OBSOLETE +OBSOLETE /* defines to make access easier */ +OBSOLETE #define cr_filefid log_data.cr.filefid +OBSOLETE #define cr_parentfid log_data.cr.parentfid +OBSOLETE #define cr_vattr log_data.cr.vattr +OBSOLETE #define cr_mode log_data.cr.mode +OBSOLETE #define cr_exists log_data.cr.exists +OBSOLETE #define cr_excl log_data.cr.excl +OBSOLETE #define cr_origdv log_data.cr.origdv +OBSOLETE #define cr_name log_data.cr.name +OBSOLETE +OBSOLETE typedef struct create_log_data { +OBSOLETE struct VenusFid filefid; /* Fid of this file */ +OBSOLETE struct VenusFid parentfid; /* Fid of parent */ +OBSOLETE struct nnpfs_attr vattr; /* attrs to create with */ +OBSOLETE int mode; /* mode to create with */ +OBSOLETE int exists; /* did file exists */ +OBSOLETE int excl; /* is file create exclusive ? */ +OBSOLETE hyper origdv; /* cached data version of file */ +OBSOLETE char name[MAX_NAME]; /* space to store create name */ +OBSOLETE } create_log_data_t; +OBSOLETE +OBSOLETE +OBSOLETE +OBSOLETE +OBSOLETE /* defines to make access easier */ +OBSOLETE #define rm_filefid log_data.rm.filefid +OBSOLETE #define rm_chentry log_data.rm.chentry +OBSOLETE #define rm_origdv log_data.rm.origdv +OBSOLETE #define rm_name log_data.rm.name +OBSOLETE +OBSOLETE typedef struct remove_log_data { +OBSOLETE struct VenusFid filefid; /* Fid of this file */ +OBSOLETE /*struct VenusFid parentfid;*/ /* Fid of parent */ +OBSOLETE FCacheEntry *chentry; /*The entry for the deleted file*/ +OBSOLETE hyper origdv; /* cached data version of file */ +OBSOLETE char name[MAX_NAME]; /* space to store remove name */ +OBSOLETE } remove_log_data_t; +OBSOLETE +OBSOLETE +OBSOLETE +OBSOLETE /* defines to make access easier */ +OBSOLETE #define rd_direntry log_data.rd.direntry +OBSOLETE #define rd_parentfid log_data.rd.parentfid +OBSOLETE #define rd_name log_data.rd.name +OBSOLETE +OBSOLETE typedef struct rmdir_log_data { +OBSOLETE FCacheEntry *direntry; /*Entry of this dir */ +OBSOLETE struct VenusFid parentfid; /* Fid of parent */ +OBSOLETE char name[MAX_NAME]; /* space to store dir name */ +OBSOLETE } rmdir_log_data_t; +OBSOLETE +OBSOLETE +OBSOLETE /* defines to make access easier */ +OBSOLETE #define rn_oparentfid log_data.rn.oparentfid +OBSOLETE #define rn_nparentfid log_data.rn.nparentfid +OBSOLETE #define rn_renamefid log_data.rn.renamefid +OBSOLETE #define rn_overfid log_data.rn.overfid +OBSOLETE #define rn_origdv log_data.rn.origdv +OBSOLETE #define rn_overdv log_data.rn.overdv +OBSOLETE #define rn_names log_data.rn.names +OBSOLETE +OBSOLETE typedef struct rename_log_data { +OBSOLETE struct VenusFid oparentfid; /* Fid of parent */ +OBSOLETE struct VenusFid nparentfid; /* Fid of parent */ +OBSOLETE struct VenusFid renamefid; /* Fid of file being rename */ +OBSOLETE struct VenusFid overfid; /* Fid of overwritten file */ +OBSOLETE hyper origdv; /* cached data version of file */ +OBSOLETE hyper overdv; /* overwritten version of cached data */ +OBSOLETE char names[MAX_NAME * 2]; /* space to store dir name */ +OBSOLETE } rename_log_data_t; +OBSOLETE +OBSOLETE /* defines to make access easier */ +OBSOLETE #define ln_linkfid log_data.ln.linkfid +OBSOLETE #define ln_parentfid log_data.ln.parentfid +OBSOLETE #define ln_name log_data.ln.name +OBSOLETE +OBSOLETE typedef struct link_log_data { +OBSOLETE struct VenusFid linkfid; /* Fid of this dir */ +OBSOLETE struct VenusFid parentfid; /* Fid of parent */ +OBSOLETE char name[MAX_NAME]; /* space to store create name */ +OBSOLETE } link_log_data_t; +OBSOLETE +OBSOLETE /* defines to make access easier */ +OBSOLETE #define sy_linkfid log_data.sy.linkfid +OBSOLETE #define sy_parentfid log_data.sy.parentfid +OBSOLETE #define sy_filefid log_data.sy.filefid +OBSOLETE #define sy_attr log_data.sy.attr +OBSOLETE #define sy_name log_data.sy.name +OBSOLETE #define sy_content log_data.sy.content +OBSOLETE +OBSOLETE +OBSOLETE typedef struct slink_log_data { +OBSOLETE struct VenusFid linkfid; /* Fid of this link */ +OBSOLETE struct VenusFid parentfid; /* Fid of parent */ +OBSOLETE struct VenusFid filefid; /* Fid of file */ +OBSOLETE AFSStoreStatus attr; /* attrs to create with */ +OBSOLETE char name[MAX_NAME]; /* space to name */ +OBSOLETE char content[MAX_NAME]; /* space to new name */ +OBSOLETE } slink_log_data_t; +OBSOLETE +OBSOLETE /* defines to make access easier */ +OBSOLETE #define sa_fid log_data.sa.fid +OBSOLETE #define sa_vattr log_data.sa.vattr +OBSOLETE #define sa_origdv log_data.sa.origdv +OBSOLETE +OBSOLETE typedef struct setattr_log_data { +OBSOLETE struct VenusFid fid; /* operand fid */ +OBSOLETE struct nnpfs_attr vattr; /* attrs to set */ +OBSOLETE hyper origdv; /* cached data version number */ +OBSOLETE } setattr_log_data_t; +OBSOLETE +OBSOLETE +OBSOLETE /* defines to make access easier */ +OBSOLETE #define nm_fid log_data.nm.fid +OBSOLETE #define nm_origdv log_data.nm.origdv +OBSOLETE +OBSOLETE typedef struct nonmute_log_data { +OBSOLETE struct VenusFid fid; /* fid */ +OBSOLETE hyper origdv; /* cached data version */ +OBSOLETE } nonmute_log_data_t; +OBSOLETE +OBSOLETE +OBSOLETE +OBSOLETE typedef struct log_ent { +OBSOLETE int log_len; /* len of this entry */ +OBSOLETE log_ops_t log_op; /* operation */ +OBSOLETE long log_opno; /* operation number */ +OBSOLETE struct timeval log_time; /* time operation was logged */ +OBSOLETE long log_offset; /* offset into the log file */ +OBSOLETE short log_flags; /* offset into the log file */ +OBSOLETE uid_t log_uid; /* uid of person performing op */ +OBSOLETE nnpfs_cred cred; /* user credential */ +OBSOLETE int log_index; /* index for the log */ +OBSOLETE struct log_ent *next; /* point to the next one */ +OBSOLETE +OBSOLETE union { +OBSOLETE store_log_data_t st; +OBSOLETE mkdir_log_data_t md; +OBSOLETE create_log_data_t cr; +OBSOLETE remove_log_data_t rm; +OBSOLETE rmdir_log_data_t rd; +OBSOLETE rename_log_data_t rn; +OBSOLETE link_log_data_t ln; +OBSOLETE slink_log_data_t sy; +OBSOLETE setattr_log_data_t sa; +OBSOLETE nonmute_log_data_t nm; +OBSOLETE } log_data; +OBSOLETE } log_ent_t; +OBSOLETE +OBSOLETE +OBSOLETE long log_dis_create(struct vcache *parent, struct vcache *child, char *name); +OBSOLETE long log_dis_store(struct vcache *avc); +OBSOLETE long log_dis_setattr(struct vcache *tvc, struct nnpfs_attr *attrs); +OBSOLETE long log_dis_mkdir(struct vcache *pvc, struct vcache *dvc, +OBSOLETE AFSStoreStatus *attrs, char *name); +OBSOLETE +OBSOLETE extern int Log_is_open; +OBSOLETE extern DARLA_file log_data; +OBSOLETE extern log_ent_t log_head; +OBSOLETE +OBSOLETE #endif /* _DISCONN_LOG_H */ +OBSOLETE diff --git a/usr.sbin/afs/src/arlad/dynroot.c b/usr.sbin/afs/src/arlad/dynroot.c index 8d2ce16c91b..d82aa669d67 100644 --- a/usr.sbin/afs/src/arlad/dynroot.c +++ b/usr.sbin/afs/src/arlad/dynroot.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1999 - 2003 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -39,19 +39,20 @@ #include <arla_local.h> -RCSID("$KTH: dynroot.c,v 1.13.2.2 2001/05/28 15:19:20 map Exp $"); +RCSID("$arla: dynroot.c,v 1.25 2003/01/20 14:21:02 lha Exp $"); struct create_entry { fbuf *thedir; /* pointer to the fbuf that contains the dir */ AFSFid fid; /* the current fid */ int len; /* num of links in the dir */ + int type; }; -#define DYNROOT_ROOTVOLUME 1 +#define DYNROOT_ROOTVOLUME 1 /* make sure that these */ +#define DYNROOT_ROOTVOLUME_STR "1" /* two are the same */ #define DYNROOT_ROOTDIR 1 #define DYNROOT_UNIQUE 1 -static int32_t dynrootcell = 0; /* this is the dynroocell */ static Bool dynroot_enable = 0; /* is dynroot enabled ? */ static unsigned long last_celldb_version = 0; /* last version of celldb */ @@ -60,34 +61,38 @@ static unsigned long last_celldb_version = 0; /* last version of celldb */ */ static int32_t -cellnum2afs (int cellno) +cellnum2afs (int cellno, int rw) { - return (cellno << 1) + 1; + if (rw) + return (cellno << 2) + 0x2; + else + return (cellno << 2) + 0x1; } static int -afs2cellnum (int32_t afsvnode) +afs2cellnum (int32_t afsvnode, int *rw) { - return (afsvnode - 1) >> 1; + if (afsvnode & 0x2) + *rw = 1; + else + *rw = 0; + return afsvnode >> 2; } /* * helper functions for dynroot_create_root that for - * each `cell' creates a entry in the root directory. + * each `cell' with 'cellid' a entry in the root directory. */ static int -create_entry_func (const cell_entry *cell, void *arg) +create_entry_func (const char *name, uint32_t cellid, int type, void *arg) { struct create_entry *entry = (struct create_entry *) arg; int ret; - if (!cell_dynroot(cell)) - return 0; - - entry->fid.Vnode = cellnum2afs (cell->id); + entry->fid.Vnode = cellnum2afs (cellid, type & DYNROOT_ALIAS_READWRITE); - ret = fdir_creat (entry->thedir, cell->name, entry->fid); + ret = fdir_creat (entry->thedir, name, entry->fid); if (ret) return ret; @@ -97,6 +102,38 @@ create_entry_func (const cell_entry *cell, void *arg) } /* + * Wrapper function for cell_foreach that takes a `cell' instead of a + * string and a cellid. + */ + +static int +create_cell_entry_func (const cell_entry *cell, void *arg) +{ + if (!cell_dynroot(cell)) + return 0; + return create_entry_func(cell->name, cell->id, + DYNROOT_ALIAS_READONLY, arg); +} + +/* + * + */ + +static int +create_alias_entry_func (const char *cellname, const char *alias, + int type, void *arg) +{ + cell_entry *cell; + + cell = cell_get_by_name (cellname); + if (cell == NULL) + return 0; + return create_entry_func(alias, cell->id, type, arg); + +} + + +/* * create the dynroot root directory in `fbuf', return number * of entries in `len'. */ @@ -121,7 +158,11 @@ dynroot_create_root (fbuf *fbuf, size_t *len) entry.fid.Unique = DYNROOT_UNIQUE; entry.len = 0; - ret = cell_foreach (create_entry_func, &entry); + ret = cell_foreach (create_cell_entry_func, &entry); + if (ret) + return ret; + + ret = cell_alias_foreach(create_alias_entry_func, &entry); if (ret) return ret; @@ -139,13 +180,14 @@ dynroot_create_symlink (fbuf *fbuf, int32_t vnode) { char name[MAXPATHLEN]; cell_entry *cell; - int len, ret; + int len, ret, rw = 0; - cell = cell_get_by_id (afs2cellnum (vnode)); + cell = cell_get_by_id (afs2cellnum (vnode, &rw)); if (cell == NULL) return ENOENT; - len = snprintf (name, sizeof(name), "#%s:root.cell.", cell->name); + len = snprintf (name, sizeof(name), "%c%s:root.cell.", + rw ? '%' : '#', cell->name); assert (len > 0 && len <= sizeof (name)); ret = fbuf_truncate (fbuf, len); @@ -166,7 +208,9 @@ dynroot_isvolumep (int cell, const char *volume) { assert (volume); - if (cell == 0 && strcmp (volume, "1") == 0) + if (cell == 0 && + (strcmp (volume, "root.afs") == 0 + || strcmp (volume, DYNROOT_ROOTVOLUME_STR) == 0)) return TRUE; return FALSE; @@ -177,14 +221,14 @@ dynroot_isvolumep (int cell, const char *volume) */ int -dynroot_fetch_vldbN (nvldbentry *entry) +dynroot_fetch_root_vldbN (nvldbentry *entry) { memset (entry, 0, sizeof(*entry)); - strlcpy(entry->name, "root.cell", sizeof(entry->name)); + strlcpy(entry->name, "root.afs", sizeof(entry->name)); entry->nServers = 0; - entry->volumeId[RWVOL] = DYNROOT_ROOTVOLUME; - entry->flags = VLF_RWEXISTS; + entry->volumeId[ROVOL] = DYNROOT_ROOTVOLUME; + entry->flags = VLF_ROEXISTS; return 0; } @@ -196,7 +240,7 @@ dynroot_fetch_vldbN (nvldbentry *entry) static void dynroot_update_entry (FCacheEntry *entry, int32_t filetype, - xfs_pag_t cred) + nnpfs_pag_t cred) { struct timeval tv; AccessEntry *ae; @@ -226,10 +270,10 @@ dynroot_update_entry (FCacheEntry *entry, int32_t filetype, entry->status.ServerModTime = 0; entry->status.Group = 0; entry->status.SyncCount = 0; - entry->status.spare1 = 0; - entry->status.spare2 = 0; - entry->status.spare3 = 0; - entry->status.spare4 = 0; + entry->status.DataVersionHigh= 0; + entry->status.LockCount = 0; + entry->status.LengthHigh = 0; + entry->status.ErrorCode = 0; gettimeofday (&tv, NULL); @@ -259,8 +303,7 @@ dynroot_get_node (FCacheEntry *entry, CredCacheEntry *ce) rootnode = entry->fid.fid.Vnode == DYNROOT_ROOTDIR ? 1 : 0; - if (entry->flags.attrp && - entry->flags.datap && + if (entry->length != 0 && (!rootnode || last_celldb_version == cell_get_version())) return 0; @@ -289,21 +332,20 @@ dynroot_get_node (FCacheEntry *entry, CredCacheEntry *ce) return ret; } + entry->flags.attrp = TRUE; + + dynroot_update_entry (entry, rootnode ? TYPE_DIR : TYPE_LINK, + ce->cred); + entry->status.Length = dir.len; - entry->length = dir.len; + fcache_update_length(entry, dir.len, dir.len); ret = fbuf_end (&dir); close(fd); if (ret) return ret; - dynroot_update_entry (entry, rootnode ? TYPE_DIR : TYPE_LINK, - ce->cred); - - entry->flags.attrp = TRUE; - entry->flags.datap = TRUE; - - entry->tokens |= XFS_ATTR_R|XFS_DATA_R; + entry->tokens |= NNPFS_ATTR_R|NNPFS_DATA_R; return 0; } @@ -339,7 +381,7 @@ dynroot_is_dynrootp (FCacheEntry *entry) assert (entry); if (dynroot_enable && - entry->fid.Cell == dynrootcell && + entry->fid.Cell == DYNROOT_CELLID && entry->fid.fid.Volume == DYNROOT_ROOTVOLUME) return TRUE; @@ -374,7 +416,7 @@ dynroot_setenable (Bool enable) int32_t dynroot_cellid (void) { - return dynrootcell; + return DYNROOT_CELLID; } /* diff --git a/usr.sbin/afs/src/arlad/dynroot.h b/usr.sbin/afs/src/arlad/dynroot.h index 28d9b6445a5..a8c5881af84 100644 --- a/usr.sbin/afs/src/arlad/dynroot.h +++ b/usr.sbin/afs/src/arlad/dynroot.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Kungliga Tekniska Högskolan + * Copyright (c) 1999 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -32,12 +32,12 @@ */ /* - * $KTH: dynroot.h,v 1.2.2.1 2001/05/28 15:19:20 map Exp $ + * $arla: dynroot.h,v 1.5 2002/07/23 15:24:24 lha Exp $ */ #define DYNROOT_DEFAULT 0 -int dynroot_fetch_vldbN (nvldbentry *entry); +int dynroot_fetch_root_vldbN (nvldbentry *entry); Bool dynroot_isvolumep (int cell, const char *volume); diff --git a/usr.sbin/afs/src/arlad/fcache.c b/usr.sbin/afs/src/arlad/fcache.c index 1d7a1af4020..13fb45283de 100644 --- a/usr.sbin/afs/src/arlad/fcache.c +++ b/usr.sbin/afs/src/arlad/fcache.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2003 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,7 +37,11 @@ */ #include "arla_local.h" -RCSID("$KTH: fcache.c,v 1.311.2.20 2001/12/20 16:36:24 mattiasa Exp $") ; +RCSID("$arla: fcache.c,v 1.417 2003/04/08 00:38:09 mattiasa Exp $") ; + +#ifdef __CYGWIN32__ +#include <windows.h> +#endif /* * Prototypes @@ -50,7 +54,7 @@ static int get_attr_bulk (FCacheEntry *parent_entry, CredCacheEntry *ce); static int -resolve_mp (FCacheEntry *e, VenusFid *ret_fid, CredCacheEntry **ce); +resolve_mp (FCacheEntry **e, VenusFid *ret_fid, CredCacheEntry **ce); /* * Local data for this module. @@ -79,11 +83,41 @@ static Heap *invalid_heap; /* low and high-water marks for vnodes and space */ -static u_long lowvnodes, highvnodes, current_vnodes, lowbytes, highbytes; +static u_long highvnodes, lowvnodes, current_vnodes; +static int64_t highbytes, lowbytes; /* current values */ -static u_long usedbytes, usedvnodes, needbytes; +static int64_t usedbytes, needbytes; +static u_long usedvnodes; + +/* Map with recovered nodes */ + +static u_long maxrecovered; + +static char *recovered_map; + +static void +set_recovered(u_long index) +{ + char *p; + u_long oldmax; + + if (index >= maxrecovered) { + oldmax = maxrecovered; + maxrecovered = (index + 16) * 2; + p = realloc(recovered_map, maxrecovered); + if (p == NULL) { + arla_errx(1, ADEBERROR, "fcache: realloc %lu recovered_map failed", + maxrecovered); + } + recovered_map = p; + memset(recovered_map + oldmax, 0, maxrecovered - oldmax); + } + recovered_map[index] = 1; +} + +#define IS_RECOVERED(index) (recovered_map[(index)]) /* * This is how far the cleaner will go to clean out entries. @@ -92,7 +126,7 @@ static u_long usedbytes, usedvnodes, needbytes; * operation. */ -Bool fprioritylevel; +Bool fprioritylevel = FPRIO_DEFAULT; static int node_count; /* XXX */ @@ -135,19 +169,19 @@ static PROCESS invalidator_pid; * Smalltalk emulation */ -u_long +int64_t fcache_highbytes(void) { return highbytes; } -u_long +int64_t fcache_usedbytes(void) { return usedbytes; } -u_long +int64_t fcache_lowbytes(void) { return lowbytes; @@ -171,260 +205,6 @@ fcache_lowvnodes(void) return lowvnodes; } -#define HISTOGRAM_SLOTS 32 -#define STATHASHSIZE 997 - -/* Struct with collected statistics */ -struct collect_stat{ - int64_t starttime; -}; - -struct time_statistics { - u_int32_t measure_type; - u_int32_t host; - u_int32_t partition; - u_int32_t measure_items; /* normed by get_histgram_slots */ - u_int32_t count[HISTOGRAM_SLOTS]; - int64_t measure_items_total[HISTOGRAM_SLOTS]; - int64_t elapsed_time[HISTOGRAM_SLOTS]; -}; - -static unsigned -statistics_hash (void *p) -{ - struct time_statistics *stats = (struct time_statistics*)p; - - return stats->measure_type + stats->host + - stats->partition * 32 * 32 + stats->measure_items * 32; -} - -/* - * Compare two entries. Return 0 if and only if the same. - */ - -static int -statistics_cmp (void *a, void *b) -{ - struct time_statistics *f1 = (struct time_statistics*)a; - struct time_statistics *f2 = (struct time_statistics*)b; - - return f1->measure_type != f2->measure_type - || f1->host != f2->host - || f1->partition != f2->partition - || f1->measure_items != f2->measure_items; -} - -static Hashtab *statistics; - -static int -get_histogram_slot(u_int32_t value) -{ - int i; - - for (i = HISTOGRAM_SLOTS - 1; i > 0; i--) { - if (value >> i) - return i; - } - return 0; -} - -static void -add_time_statistics(u_int32_t measure_type, u_int32_t host, - u_int32_t partition, u_int32_t measure_items, - int64_t elapsed_time) -{ - u_int32_t time_slot; - struct time_statistics *ts; - struct time_statistics *ts2; - - ts = malloc(sizeof(*ts)); - - time_slot = get_histogram_slot(elapsed_time); - ts->measure_type = measure_type; - ts->measure_items = get_histogram_slot(measure_items); - ts->host = host; - ts->partition = partition; - ts2 = hashtabsearch (statistics, (void*)(ts)); - if (ts2) { - ts2->count[time_slot]++; - ts2->elapsed_time[time_slot] += elapsed_time; - ts2->measure_items_total[time_slot] += measure_items; - free(ts); - } else { - memset(ts->count, 0, sizeof(ts->count)); - memset(ts->measure_items_total, 0, sizeof(ts->measure_items_total)); - memset(ts->elapsed_time, 0, sizeof(ts->elapsed_time)); - ts->count[time_slot]++; - ts->elapsed_time[time_slot] += elapsed_time; - ts->measure_items_total[time_slot] += measure_items; - hashtabadd(statistics, ts); - } - - time_slot = get_histogram_slot(elapsed_time); -} - -static void -collectstats_init (void) -{ - statistics = hashtabnew (STATHASHSIZE, statistics_cmp, statistics_hash); - - if (statistics == NULL) - arla_err(1, ADEBINIT, errno, "collectstats_init: cannot malloc"); -} - -static void -collectstats_start (struct collect_stat *p) -{ - struct timeval starttime; - - gettimeofday(&starttime, NULL); - p->starttime = starttime.tv_sec * 1000000LL + starttime.tv_usec; -} - -static void -collectstats_stop (struct collect_stat *p, - FCacheEntry *entry, - ConnCacheEntry *conn, - int measure_type, int measure_items) -{ - u_int32_t host = conn->host; - long partition = -1; - int volumetype; - struct nvldbentry vldbentry; - struct timeval stoptime; - int64_t elapsed_time; - int i; - - gettimeofday(&stoptime, NULL); - - volumetype = volcache_volid2bit (entry->volume, entry->fid.fid.Volume); - vldbentry = entry->volume->entry; - - for (i = 0; i < min(NMAXNSERVERS, vldbentry.nServers); ++i) { - if (host == htonl(vldbentry.serverNumber[i]) && - vldbentry.serverFlags[i] & volumetype) { - partition = vldbentry.serverPartition[i]; - } - } - assert(partition != -1); - elapsed_time = stoptime.tv_sec * 1000000LL + stoptime.tv_usec; - elapsed_time -= p->starttime; - add_time_statistics(measure_type, host, partition, - measure_items, elapsed_time); -} - -struct hostpart { - u_int32_t host; - u_int32_t part; -}; - -static unsigned -hostpart_hash (void *p) -{ - struct hostpart *h = (struct hostpart*)p; - - return h->host * 256 + h->part; -} - -static int -hostpart_cmp (void *a, void *b) -{ - struct hostpart *h1 = (struct hostpart*)a; - struct hostpart *h2 = (struct hostpart*)b; - - return h1->host != h2->host || - h1->part != h2->part; -} - -static Bool -hostpart_addhash (void *ptr, void *arg) -{ - Hashtab *hostparthash = (Hashtab *) arg; - struct time_statistics *s = (struct time_statistics *) ptr; - struct hostpart *h; - - h = malloc(sizeof(*h)); - h->host = s->host; - h->part = s->partition; - - hashtabadd(hostparthash, h); - return FALSE; -} - -struct hostpart_collect_args { - u_int32_t *host; - u_int32_t *part; - int *i; - int max; -}; - -static Bool -hostpart_collect (void *ptr, void *arg) -{ - struct hostpart_collect_args *collect_args = - (struct hostpart_collect_args *) arg; - struct hostpart *h = (struct hostpart *) ptr; - - if (*collect_args->i >= collect_args->max) - return TRUE; - - collect_args->host[*collect_args->i] = h->host; - collect_args->part[*collect_args->i] = h->part; - (*collect_args->i)++; - - return FALSE; -} - -int -collectstats_hostpart(u_int32_t *host, u_int32_t *part, int *n) -{ - Hashtab *hostparthash; - int i; - struct hostpart_collect_args collect_args; - - hostparthash = hashtabnew (100, hostpart_cmp, hostpart_hash); - - hashtabforeach(statistics, hostpart_addhash, hostparthash); - - i = 0; - collect_args.host = host; - collect_args.part = part; - collect_args.i = &i; - collect_args.max = *n; - hashtabforeach(hostparthash, hostpart_collect, &collect_args); - *n = i; - - hashtabrelease(hostparthash); - - return 0; -} - -int -collectstats_getentry(u_int32_t host, u_int32_t part, u_int32_t type, - u_int32_t items_slot, u_int32_t *count, - int64_t *items_total, int64_t *total_time) -{ - struct time_statistics ts; - struct time_statistics *ts2; - - ts.measure_type = type; - ts.measure_items = items_slot; - ts.host = host; - ts.partition = part; - ts2 = hashtabsearch (statistics, (void*)(&ts)); - if (ts2 == NULL) { - memset(count, 0, 4 * 32); - memset(items_total, 0, 8 * 32); - memset(total_time, 0, 8 * 32); - } else { - memcpy(count, ts2->count, 4 * 32); - memcpy(items_total, ts2->measure_items_total, 8 * 32); - memcpy(total_time, ts2->elapsed_time, 8 * 32); - } - - return 0; -} - /* * Counters */ @@ -446,13 +226,10 @@ static struct { static int fcachecmp (void *a, void *b) { - FCacheEntry *f1 = (FCacheEntry*)a; - FCacheEntry *f2 = (FCacheEntry*)b; + FCacheEntry *f1 = (FCacheEntry*)a; + FCacheEntry *f2 = (FCacheEntry*)b; - return f1->fid.Cell != f2->fid.Cell - || f1->fid.fid.Volume != f2->fid.fid.Volume - || f1->fid.fid.Vnode != f2->fid.fid.Vnode - || f1->fid.fid.Unique != f2->fid.fid.Unique; + return VenusFid_cmp(&f1->fid, &f2->fid); } /* @@ -462,10 +239,10 @@ fcachecmp (void *a, void *b) static unsigned fcachehash (void *e) { - FCacheEntry *f = (FCacheEntry*)e; + FCacheEntry *f = (FCacheEntry*)e; - return f->fid.Cell + f->fid.fid.Volume + f->fid.fid.Vnode - + f->fid.fid.Unique; + return f->fid.Cell + f->fid.fid.Volume + f->fid.fid.Vnode + + f->fid.fid.Unique; } /* @@ -490,14 +267,104 @@ recon_hashtabadd(FCacheEntry *entry) void recon_hashtabdel(FCacheEntry *entry) { - hashtabdel(hashtab,entry); + hashtabdel(hashtab,entry); } /* * Globalnames */ -char arlasysname[SYSNAMEMAXLEN]; +char **sysnamelist = NULL; +int sysnamenum = 0; + +/* + * + */ + +static void +fcache_poller_unref(FCacheEntry *e) +{ + AssertExclLocked(&e->lock); + + if (e->poll) { + poller_remove(e->poll); + e->poll = NULL; + } +} + +static void +fcache_poller_reref(FCacheEntry *e, ConnCacheEntry *conn) +{ + PollerEntry *pe = e->poll; + AssertExclLocked(&e->lock); + + e->poll = poller_add_conn(conn); + if (pe) + poller_remove(pe); +} + + +/* + * + */ + +const char * +fcache_getdefsysname (void) +{ + if (sysnamenum == 0) + return "fool-dont-remove-all-sysnames"; + return sysnamelist[0]; +} + +/* + * + */ + +int +fcache_setdefsysname (const char *sysname) +{ + if (sysnamenum == 0) + return fcache_addsysname (sysname); + free (sysnamelist[0]); + sysnamelist[0] = estrdup (sysname); + return 0; +} + +/* + * + */ + +int +fcache_addsysname (const char *sysname) +{ + sysnamenum += 1; + sysnamelist = erealloc (sysnamelist, + sysnamenum * sizeof(char *)); + sysnamelist[sysnamenum - 1] = estrdup(sysname); + return 0; +} + +/* + * + */ + +int +fcache_removesysname (const char *sysname) +{ + int i; + for (i = 0; i < sysnamenum; i++) + if (strcmp (sysnamelist[i], sysname) == 0) + break; + if (i == sysnamenum) + return 1; + free (sysnamelist[i]); + for (;i < sysnamenum; i++) + sysnamelist[i] = sysnamelist[i + 1]; + sysnamenum--; + sysnamelist = erealloc (sysnamelist, + sysnamenum * sizeof(char *)); + return 0; +} /* * return the directory name of the cached file for `entry' @@ -521,6 +388,25 @@ fcache_file_name (FCacheEntry *entry, char *s, size_t len) } /* + * return kernel version of path to the cache file for `entry'. + */ + +int +fcache_conv_file_name (FCacheEntry *entry, char *s, size_t len) +{ +#ifdef __CYGWIN32__ + char buf[1024]; + GetCurrentDirectory(1024, buf); + + return snprintf (s, len, "%s\\%02X\\%02X", + buf, entry->index / 0x100, entry->index % 0x100); +#else + return snprintf (s, len, "%02X/%02X", + entry->index / 0x100, entry->index % 0x100); +#endif +} + +/* * the filename for the extra (converted) directory */ @@ -544,8 +430,7 @@ real_extra_file_name (FCacheEntry *entry, char *s, size_t len) int fcache_extra_file_name (FCacheEntry *entry, char *s, size_t len) { - assert (entry->flags.datap && - entry->flags.extradirp && + assert (entry->flags.extradirp && entry->status.FileType == TYPE_DIR); return real_extra_file_name (entry, s, len); @@ -565,12 +450,16 @@ fcache_fhopen (fcache_cache_handle *handle, int flags) return -1; } +#ifdef __CYGWIN32__ + return -1; +#endif + #if defined(HAVE_GETFH) && defined(HAVE_FHOPEN) { int ret; fhandle_t fh; - memcpy (&fh, &handle->xfs_handle, sizeof(fh)); + memcpy (&fh, &handle->nnpfs_handle, sizeof(fh)); ret = fhopen (&fh, flags); if (ret >= 0) return ret; @@ -581,8 +470,8 @@ fcache_fhopen (fcache_cache_handle *handle, int flags) { struct ViceIoctl vice_ioctl; - vice_ioctl.in = (caddr_t)&handle->xfs_handle; - vice_ioctl.in_size = sizeof(handle->xfs_handle); + vice_ioctl.in = (caddr_t)&handle->nnpfs_handle; + vice_ioctl.in_size = sizeof(handle->nnpfs_handle); vice_ioctl.out = NULL; vice_ioctl.out_size = 0; @@ -603,6 +492,28 @@ int fcache_fhget (char *filename, fcache_cache_handle *handle) { handle->valid = 0; + +#ifdef __CYGWIN32__ + { + int ret, a, b; + char buf[1024]; /* XXX */ + + ret = sscanf(filename, "%02X/%02X", &a, &b); + if (ret != 2) + return EINVAL; + + GetCurrentDirectory(1024, buf); + + /* XXX CACHEHANDLESIZE */ + ret = snprintf ((char *)handle, 80, "%s\\%02X\\%02X", buf, a, b); + + if (ret > 0) + handle->valid = 1; + + return ret; + } +#endif + #if defined(HAVE_GETFH) && defined(HAVE_FHOPEN) { int ret; @@ -610,7 +521,7 @@ fcache_fhget (char *filename, fcache_cache_handle *handle) ret = getfh (filename, &fh); if (ret == 0) { - memcpy (&handle->xfs_handle, &fh, sizeof(fh)); + memcpy (&handle->nnpfs_handle, &fh, sizeof(fh)); handle->valid = 1; } @@ -628,8 +539,8 @@ fcache_fhget (char *filename, fcache_cache_handle *handle) vice_ioctl.in = NULL; vice_ioctl.in_size = 0; - vice_ioctl.out = (caddr_t)&handle->xfs_handle; - vice_ioctl.out_size = sizeof(handle->xfs_handle); + vice_ioctl.out = (caddr_t)&handle->nnpfs_handle; + vice_ioctl.out_size = sizeof(handle->nnpfs_handle); ret = k_pioctl (filename, VIOC_FHGET, &vice_ioctl, 0); if (ret == 0) @@ -647,25 +558,31 @@ fcache_fhget (char *filename, fcache_cache_handle *handle) * create a new cache vnode, assume the entry is locked or private */ -int -fcache_create_file (FCacheEntry *entry) +static int +fcache_create_file (FCacheEntry *entry, int create) { char fname[MAXPATHLEN]; char extra_fname[MAXPATHLEN]; int fd; int ret; + int flags; + + flags = O_RDWR | O_BINARY; + + if (create) + flags |= O_CREAT | O_TRUNC; fcache_file_name (entry, fname, sizeof(fname)); - fd = open (fname, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0666); + fd = open (fname, flags, 0666); if (fd < 0) { - if (errno == ENOENT) { + if (errno == ENOENT && create) { char dname[MAXPATHLEN]; fcache_dir_name (entry, dname, sizeof(dname)); ret = mkdir (dname, 0777); if (ret < 0) arla_err (1, ADEBERROR, errno, "mkdir %s", dname); - fd = open (fname, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0666); + fd = open (fname, flags, 0666); if (fd < 0) arla_err (1, ADEBERROR, errno, "open %s", fname); } else { @@ -692,7 +609,7 @@ fcache_open_file (FCacheEntry *entry, int flag) if (fhopen_working) { ret = fcache_fhopen (&entry->handle, flag); - if (ret < 0 && errno == EINVAL) + if (ret < 0 && (errno == EINVAL || errno == EPERM)) fhopen_working = 0; else return ret; @@ -710,7 +627,7 @@ fcache_open_extra_dir (FCacheEntry *entry, int flag, mode_t mode) { char fname[MAXPATHLEN]; - assert (entry->flags.datap && entry->flags.extradirp && + assert (entry->flags.extradirp && entry->status.FileType == TYPE_DIR); fcache_extra_file_name (entry, fname, sizeof(fname)); @@ -727,7 +644,7 @@ throw_data (FCacheEntry *entry) int fd; struct stat sb; - assert (entry->flags.datap && entry->flags.usedp); + assert (entry->flags.usedp); AssertExclLocked(&entry->lock); fd = fcache_open_file (entry, O_WRONLY); @@ -758,7 +675,8 @@ throw_data (FCacheEntry *entry) usedbytes = entry->length; usedbytes -= entry->length; entry->length = 0; - entry->flags.datap = FALSE; + entry->wanted_length = 0; + entry->fetched_length = 0; entry->flags.extradirp = FALSE; out: @@ -769,10 +687,10 @@ throw_data (FCacheEntry *entry) * A probe function for a file server. */ -static int +int fs_probe (struct rx_connection *conn) { - u_int32_t sec, usec; + uint32_t sec, usec; return RXAFS_GetTime (conn, &sec, &usec); } @@ -791,11 +709,18 @@ throw_entry (FCacheEntry *entry) int ret; assert (entry->flags.usedp); + assert (!entry->flags.kernelp); + AssertExclLocked(&entry->lock); + assert(LockWaiters(&entry->lock) == 0); hashtabdel (hashtab, entry); - if (entry->flags.datap) + /* + * Throw data when there is data, length is a good test since the + * node most not be used (in kernel) when we get here. + */ + if (entry->length) throw_data (entry); if (entry->invalid_ptr != -1) { @@ -803,6 +728,8 @@ throw_entry (FCacheEntry *entry) entry->invalid_ptr = -1; } + fcache_poller_unref(entry); + if (entry->flags.attrp && entry->host) { ce = cred_get (entry->fid.Cell, 0, CRED_NONE); assert (ce != NULL); @@ -811,11 +738,14 @@ throw_entry (FCacheEntry *entry) FS_SERVICE_ID, fs_probe, ce); cred_free (ce); - if (conn != NULL) { + if (conn_isalivep(conn)) { fids.len = cbs.len = 1; fids.val = &entry->fid.fid; cbs.val = &entry->callback; - ret = RXAFS_GiveUpCallBacks (conn->connection, &fids, &cbs); + if (conn_isalivep (conn)) + ret = RXAFS_GiveUpCallBacks(conn->connection, &fids, &cbs); + else + ret = ENETDOWN; conn_free (conn); if (ret) arla_warn (ADEBFCACHE, ret, "RXAFS_GiveUpCallBacks"); @@ -825,6 +755,7 @@ throw_entry (FCacheEntry *entry) volcache_free (entry->volume); entry->volume = NULL; } + assert_not_flag(entry,kernelp); entry->flags.attrp = FALSE; entry->flags.usedp = FALSE; --usedvnodes; @@ -838,7 +769,12 @@ throw_entry (FCacheEntry *entry) static unsigned next_cache_index (void) { - return node_count++; + do { + node_count++; + } while ((node_count < maxrecovered) + && IS_RECOVERED(node_count)); + + return node_count; } /* @@ -876,6 +812,7 @@ create_nodes (char *arg) entries[i].refcount = 0; entries[i].anonaccess = 0; entries[i].cleanergen = 0; + entries[i].poll = NULL; for (j = 0; j < NACCESS; j++) { entries[i].acccache[j].cred = ARLA_NO_AUTH_CRED; entries[i].acccache[j].access = 0; @@ -883,7 +820,7 @@ create_nodes (char *arg) entries[i].length = 0; Lock_Init(&entries[i].lock); entries[i].index = next_cache_index (); - fcache_create_file (&entries[i]); + fcache_create_file (&entries[i], 1); current_vnodes++; @@ -917,7 +854,7 @@ cleaner (char *arg) VenusFid *fids; int cleanerrun = 0; - numnodes = 50; + numnodes = NNPFS_GC_NODES_MAX_HANDLE; fids = malloc (sizeof(*fids) * numnodes); if (fids == NULL) @@ -933,8 +870,8 @@ cleaner (char *arg) "%lu (%lu-%lu) bytes " "%lu needed bytes", usedvnodes, lowvnodes, current_vnodes, highvnodes, - usedbytes, lowbytes, highbytes, - needbytes); + (long)usedbytes, (long)lowbytes, (long)highbytes, + (long)needbytes); cleaner_working = TRUE; @@ -958,17 +895,21 @@ cleaner (char *arg) if (fprioritylevel && entry->priority) continue; + if (entry->cleanergen == cleanerrun) + continue; + entry->cleanergen = cleanerrun; + if (entry->flags.usedp && (usedvnodes > lowvnodes || usedbytes > lowbytes - || (needbytes > highbytes - usedbytes - && !entry->flags.attrusedp)) + || needbytes > highbytes - usedbytes) && entry->refcount == 0 && CheckLock(&entry->lock) == 0) { if (!entry->flags.datausedp - && CheckLock(&entry->lock) == 0 + && !entry->flags.kernelp /* && this_is_a_good_node_to_gc(entry,state) */) { + ObtainWriteLock (&entry->lock); listdel (lrulist, item); throw_entry (entry); @@ -978,15 +919,12 @@ cleaner (char *arg) break; } - if (state == CL_FORCE) { - if (entry->cleanergen == cleanerrun) - continue; - entry->cleanergen = cleanerrun; + if (state == CL_FORCE && entry->flags.kernelp) { fids[cnt++] = entry->fid; if (cnt >= numnodes) { - xfs_send_message_gc_nodes (kernel_fd, cnt, fids); + nnpfs_send_message_gc_nodes (kernel_fd, cnt, fids); IOMGR_Poll(); cnt = 0; } @@ -1004,24 +942,18 @@ cleaner (char *arg) case CL_FORCE: state = CL_COLLECT; if (cnt > 0) { - xfs_send_message_gc_nodes (kernel_fd, cnt, fids); + nnpfs_send_message_gc_nodes (kernel_fd, cnt, fids); IOMGR_Poll(); cnt = 0; } break; case CL_COLLECT: - if (needbytes > highbytes - usedbytes) { - int cleaner_again = 0; - if (!cleaner_again) - goto out; - state = CL_OPPORTUNISTIC; - } else { - goto out; - } + goto out; break; default: abort(); } + cleanerrun++; } } out: @@ -1029,11 +961,11 @@ cleaner (char *arg) arla_warnx(ADEBCLEANER, "cleaner done: " "%lu (%lu-(%lu)-%lu) files, " - "%lu (%lu-%lu) bytes " - "%lu needed bytes", + "%ld (%ld-%ld) bytes " + "%ld needed bytes", usedvnodes, lowvnodes, current_vnodes, highvnodes, - usedbytes, lowbytes, highbytes, - needbytes); + (long)usedbytes, (long)lowbytes, (long)highbytes, + (long)needbytes); cm_check_consistency(); if (needbytes) @@ -1057,8 +989,8 @@ fcache_need_bytes (u_long needed) if (needed + needbytes > highbytes) { arla_warnx (ADEBWARN, "Out of space since there is outstanding requests " - "(%lu needed, %lu outstanding, %lu highbytes", - needed, needbytes, highbytes); + "(%ld needed, %ld outstanding, %ld highbytes)", + (long)needed, (long)needbytes, (long)highbytes); return ENOSPC; } @@ -1069,8 +1001,8 @@ fcache_need_bytes (u_long needed) arla_warnx (ADEBWARN, "Out of space, couldn't get needed bytes after cleaner " "(%lu bytes missing, %lu used, %lu highbytes)", - needed - (highbytes - usedbytes), - usedbytes, highbytes); + (long)(needed - (highbytes - usedbytes)), + (long)usedbytes, (long)highbytes); return ENOSPC; } return 0; @@ -1098,7 +1030,7 @@ invalidator (char *arg) const void *head; struct timeval tv; - arla_warnx(ADEBCLEANER, + arla_warnx(ADEBINVALIDATOR, "running invalidator"); while ((head = heap_head (invalid_heap)) == NULL) @@ -1112,7 +1044,7 @@ invalidator (char *arg) if (tv.tv_sec < entry->callback.ExpirationTime) { unsigned long t = entry->callback.ExpirationTime - tv.tv_sec; - arla_warnx (ADEBCLEANER, + arla_warnx (ADEBINVALIDATOR, "invalidator: sleeping for %lu second(s)", t); IOMGR_Sleep (t); break; @@ -1124,6 +1056,7 @@ invalidator (char *arg) entry->invalid_ptr = -1; if (entry->flags.kernelp) break_callback (entry); + fcache_poller_unref(entry); } ReleaseWriteLock (&entry->lock); } @@ -1152,50 +1085,53 @@ add_to_invalidate (FCacheEntry *e) static FCacheEntry * unlink_lru_entry (void) { - FCacheEntry *entry = NULL; - Listitem *item; + FCacheEntry *entry = NULL; + Listitem *item; - if (highvnodes == usedvnodes) - fcache_need_nodes(); + if (current_vnodes == usedvnodes) + fcache_need_nodes(); - for (;;) { - - assert (!listemptyp (lrulist)); - for (item = listtail (lrulist); - item; - item = listprev (lrulist, item)) { - - entry = (FCacheEntry *)listdata (item); - if (!entry->flags.usedp - && CheckLock(&entry->lock) == 0) { - ObtainWriteLock (&entry->lock); - listdel (lrulist, entry->lru_le); - entry->lru_le = NULL; - return entry; - } - } - - assert (!listemptyp (lrulist)); - for (item = listtail (lrulist); - item; - item = listprev (lrulist, item)) { - - entry = (FCacheEntry *)listdata (item); - if (entry->flags.usedp - && !entry->flags.attrusedp - && entry->refcount == 0 - && CheckLock(&entry->lock) == 0) { - ObtainWriteLock (&entry->lock); - listdel (lrulist, entry->lru_le); - entry->lru_le = NULL; - throw_entry (entry); - return entry; - } - } - - arla_warnx (ADEBFCACHE, "unlink_lru_entry: sleeping"); - fcache_need_nodes(); - } + for (;;) { + + assert (!listemptyp (lrulist)); + for (item = listtail (lrulist); + item; + item = listprev (lrulist, item)) { + + entry = (FCacheEntry *)listdata (item); + if (!entry->flags.usedp + && CheckLock(&entry->lock) == 0) { + assert_not_flag(entry,kernelp); + ObtainWriteLock (&entry->lock); + listdel (lrulist, entry->lru_le); + entry->lru_le = NULL; + return entry; + } + } + + assert (!listemptyp (lrulist)); + for (item = listtail (lrulist); + item; + item = listprev (lrulist, item)) { + + entry = (FCacheEntry *)listdata (item); + if (entry->flags.usedp + && !entry->flags.attrusedp + && !entry->flags.kernelp + && entry->refcount == 0 + && CheckLock(&entry->lock) == 0) { + assert_not_flag(entry,kernelp); + ObtainWriteLock (&entry->lock); + listdel (lrulist, entry->lru_le); + entry->lru_le = NULL; + throw_entry (entry); + return entry; + } + } + + arla_warnx (ADEBFCACHE, "unlink_lru_entry: sleeping"); + fcache_need_nodes(); + } } /* @@ -1221,55 +1157,74 @@ find_free_entry (void) * */ -int -fcache_store_state (void) -{ +struct fstore_context { Listitem *item; - int fd; unsigned n; - u_int32_t u1, u2; +}; - if (lrulist == NULL) { - arla_warnx (ADEBFCACHE, "store_state: lrulist is NULL"); - return 0; - } +static int +fcache_store_entry (struct fcache_store *st, void *ptr) +{ + struct fstore_context *c; + FCacheEntry *entry; - fd = open ("fcache.new", O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666); - if (fd < 0) - return errno; - u1 = FCACHE_MAGIC_COOKIE; - u2 = FCACHE_VERSION; - if (write (fd, &u1, sizeof(u1)) != sizeof(u1) - || write (fd, &u2, sizeof(u2)) != sizeof(u2)) { - int save_errno = errno; + c = (struct fstore_context *)ptr; + if (c->item == NULL) /* check if done ? */ + return STORE_DONE; - close (fd); - return save_errno; - } + entry = (FCacheEntry *)listdata (c->item); + c->item = listprev (lrulist, c->item); + + if (!entry->flags.usedp) + return STORE_SKIP; - n = 0; - for (item = listtail (lrulist); - item; - item = listprev (lrulist, item)) { - FCacheEntry *entry = (FCacheEntry *)listdata (item); + strlcpy(st->cell, cell_num2name(entry->fid.Cell), sizeof(st->cell)); + st->fid = entry->fid.fid; + st->refcount = entry->refcount; + st->length = entry->length; + st->fetched_length = entry->fetched_length; + st->volsync = entry->volsync; + st->status = entry->status; + st->anonaccess = entry->anonaccess; + st->index = entry->index; + st->flags.attrp = entry->flags.attrp; + st->flags.datap = entry->length ? TRUE : FALSE; + st->flags.extradirp = entry->flags.extradirp; + st->flags.mountp = entry->flags.mountp; + st->flags.fake_mp = entry->flags.fake_mp; + st->flags.vol_root = entry->flags.vol_root; + strlcpy(st->parentcell, cell_num2name(entry->parent.Cell), + sizeof(st->parentcell)); + st->parent = entry->parent.fid; + st->priority = entry->priority; + + c->n++; + return STORE_NEXT; +} - if (!entry->flags.usedp) - continue; - if (write (fd, entry, sizeof(*entry)) != sizeof(*entry)) { - int save_errno = errno; +/* + * + */ - close (fd); - return save_errno; - } - ++n; +int +fcache_store_state (void) +{ + struct fstore_context c; + int ret; + + if (lrulist == NULL) { + arla_warnx (ADEBFCACHE, "store_state: lrulist is NULL\n"); + return 0; } - if(close (fd)) - return errno; - if (rename ("fcache.new", "fcache")) - return errno; + c.item = listtail(lrulist); + c.n = 0; - arla_warnx (ADEBFCACHE, "wrote %u entries to fcache", n); + ret = state_store_fcache("fcache", fcache_store_entry, &c); + if (ret) + arla_warn(ADEBWARN, ret, "failed to write fcache state"); + else + arla_warnx (ADEBFCACHE, "wrote %u entries to fcache", c.n); return 0; } @@ -1278,101 +1233,101 @@ fcache_store_state (void) * */ -static void -fcache_recover_state (void) +static int +fcache_recover_entry (struct fcache_store *st, void *ptr) { - int fd; - FCacheEntry tmp; - unsigned n; AFSCallBack broken_callback = {0, 0, CBDROPPED}; - u_int32_t u1, u2; + unsigned *n = (unsigned *)ptr; - fd = open ("fcache", O_RDONLY | O_BINARY, 0); - if (fd < 0) - return; - if (read (fd, &u1, sizeof(u1)) != sizeof(u1) - || read (fd, &u2, sizeof(u2)) != sizeof(u2)) { - close (fd); - return; - } - if (u1 != FCACHE_MAGIC_COOKIE) { - arla_warnx (ADEBFCACHE, "dump file not recognized, ignoring"); - close (fd); - return; - } - if (u2 != FCACHE_VERSION) { - arla_warnx (ADEBFCACHE, "unknown dump file version number %u", u2); - close (fd); - return; - } - - n = 0; - while (read (fd, &tmp, sizeof(tmp)) == sizeof(tmp)) { - CredCacheEntry *ce; - FCacheEntry *e; - int i; - VolCacheEntry *vol; - int res; - int type; + CredCacheEntry *ce; + FCacheEntry *e; + int i; + VolCacheEntry *vol; + int res; + int32_t cellid; - ce = cred_get (tmp.fid.Cell, 0, 0); - assert (ce != NULL); + cellid = cell_name2num(st->cell); + assert (cellid != -1); + + ce = cred_get (cellid, 0, 0); + assert (ce != NULL); + + res = volcache_getbyid (st->fid.Volume, cellid, ce, &vol, NULL); + cred_free (ce); + if (res) + return 0; + assert(vol); + + e = calloc(1, sizeof(FCacheEntry)); + e->invalid_ptr = -1; + Lock_Init(&e->lock); + ObtainWriteLock(&e->lock); + - res = volcache_getbyid (tmp.fid.fid.Volume, tmp.fid.Cell, - ce, &vol, &type); - cred_free (ce); - if (res) - continue; + e->fid.Cell = cellid; + e->fid.fid = st->fid; + e->host = 0; + e->status = st->status; + e->length = st->length; + e->fetched_length = st->fetched_length; + e->callback = broken_callback; + e->volsync = st->volsync; + e->refcount = st->refcount; + + /* Better not restore the rights. pags don't have to be the same */ + for (i = 0; i < NACCESS; ++i) { + e->acccache[i].cred = ARLA_NO_AUTH_CRED; + e->acccache[i].access = ANONE; + } + + e->anonaccess = st->anonaccess; + e->index = st->index; + fcache_create_file(e, 0); + set_recovered(e->index); + e->flags.usedp = TRUE; + e->flags.attrp = st->flags.attrp; + /* st->flags.datap */ + e->flags.attrusedp = FALSE; + e->flags.datausedp = FALSE; + e->flags.kernelp = FALSE; + e->flags.extradirp = st->flags.extradirp; + e->flags.mountp = st->flags.mountp; + e->flags.fake_mp = st->flags.fake_mp; + e->flags.vol_root = st->flags.vol_root; + e->flags.sentenced = FALSE; + e->flags.silly = FALSE; + e->tokens = 0; + e->parent.Cell = cell_name2num(st->parentcell); + assert(e->parent.Cell != -1); + e->parent.fid = st->parent; + e->priority = st->priority; + e->hits = 0; + e->cleanergen = 0; + e->lru_le = listaddhead (lrulist, e); + assert(e->lru_le); + e->volume = vol; + hashtabadd (hashtab, e); + if (e->length) + usedbytes += e->length; + ReleaseWriteLock (&e->lock); + + (*n)++; - e = find_free_entry (); - assert (e != NULL); + return 0; +} - ++n; +/* + * + */ - e->fid = tmp.fid; - e->host = 0; - e->status = tmp.status; - e->length = tmp.length; - e->callback = broken_callback; - e->volsync = tmp.volsync; - e->refcount = tmp.refcount; +static void +fcache_recover_state (void) +{ + unsigned n; - /* Better not restore the rights. pags don't have to be the same */ - for (i = 0; i < NACCESS; ++i) { - e->acccache[i].cred = ARLA_NO_AUTH_CRED; - e->acccache[i].access = ANONE; - } + n = 0; + state_recover_fcache("fcache", fcache_recover_entry, &n); - e->anonaccess = tmp.anonaccess; - e->index = tmp.index; - e->handle = tmp.handle; /* XXX */ - node_count = max(node_count, tmp.index + 1); - e->flags.usedp = TRUE; - e->flags.attrp = tmp.flags.attrp; - e->flags.datap = tmp.flags.datap; - e->flags.attrusedp = FALSE; - e->flags.datausedp = FALSE; - e->flags.kernelp = FALSE; - e->flags.extradirp = tmp.flags.extradirp; - e->flags.mountp = tmp.flags.mountp; - e->flags.fake_mp = tmp.flags.fake_mp; - e->flags.vol_root = tmp.flags.vol_root; - e->flags.sentenced = FALSE; - e->flags.silly = FALSE; - e->tokens = tmp.tokens; - e->parent = tmp.parent; - e->priority = tmp.priority; - e->hits = 0; - e->cleanergen = 0; - e->lru_le = listaddhead (lrulist, e); - assert(e->lru_le); - e->volume = vol; - hashtabadd (hashtab, e); - if (e->flags.datap) - usedbytes += e->length; - ReleaseWriteLock (&e->lock); - } - close (fd); arla_warnx (ADEBFCACHE, "recovered %u entries to fcache", n); current_vnodes = n; } @@ -1384,19 +1339,33 @@ fcache_recover_state (void) */ Bool -findaccess (xfs_pag_t cred, AccessEntry *ae, AccessEntry **pos) +findaccess (nnpfs_pag_t cred, AccessEntry *ae, AccessEntry **pos) { - int i; + int i; + + for(i = 0; i < NACCESS ; ++i) + if(ae[i].cred == cred) { + *pos = &ae[i]; + return TRUE; + } + + i = rand() % NACCESS; + *pos = &ae[i]; + return FALSE; +} + +/* + * + */ - for(i = 0; i < NACCESS ; ++i) - if(ae[i].cred == cred) { - *pos = &ae[i]; - return TRUE; - } - i = rand() % NACCESS; - *pos = &ae[i]; - return FALSE; +static int +fs_rtt_cmp (const void *v1, const void *v2) +{ + struct fs_server_entry *e1 = (struct fs_server_entry *)v1; + struct fs_server_entry *e2 = (struct fs_server_entry *)v2; + + return conn_rtt_cmp(&e1->conn, &e2->conn); } /* @@ -1409,6 +1378,16 @@ init_fs_server_context (fs_server_context *context) context->num_conns = 0; } +static long +find_partition (fs_server_context *context) +{ + int i = context->conns[context->i - 1].ve_ent; + + if (i < 0 || i >= context->ve->entry.nServers) + return 0; + return context->ve->entry.serverPartition[i]; +} + /* * Find the next fileserver for the request in `context'. * Returns a ConnCacheEntry or NULL. @@ -1417,13 +1396,22 @@ init_fs_server_context (fs_server_context *context) ConnCacheEntry * find_next_fs (fs_server_context *context, ConnCacheEntry *prev_conn, - int mark_as_dead) + int error) { - if (mark_as_dead) - conn_dead (prev_conn); + if (error) { + if (host_downp(error)) + conn_dead (prev_conn); + if (volume_downp(error)) + volcache_mark_down (context->ve, + context->conns[context->i - 1].ve_ent, + error); + } else if (prev_conn) { + assert(prev_conn == context->conns[context->i - 1].conn); + volcache_reliable_el(context->ve, context->conns[context->i - 1].ve_ent); + } if (context->i < context->num_conns) - return context->conns[context->i++]; + return context->conns[context->i++].conn; else return NULL; } @@ -1438,19 +1426,21 @@ free_fs_server_context (fs_server_context *context) int i; for (i = 0; i < context->num_conns; ++i) - conn_free (context->conns[i]); + conn_free (context->conns[i].conn); + + if (context->ve) + volcache_process_marks(context->ve); } /* - * Find the first file server housing the volume for `e'. - * The context is saved in `context' and can later be sent to find_next_fs. - * Returns a ConnCacheEntry or NULL. + * Find the the file servers housing the volume for `e' and store it + * in the `context'. */ -ConnCacheEntry * -find_first_fs (FCacheEntry *e, - CredCacheEntry *ce, - fs_server_context *context) +int +init_fs_context (FCacheEntry *e, + CredCacheEntry *ce, + fs_server_context *context) { VolCacheEntry *ve = e->volume; int i; @@ -1462,25 +1452,23 @@ find_first_fs (FCacheEntry *e, memset(context, 0, sizeof(*context)); if (ve == NULL) { - int type; - ret = volcache_getbyid (e->fid.fid.Volume, e->fid.Cell, - ce, &e->volume, &type); + ce, &e->volume, NULL); if (ret) - return NULL; + return ret; ve = e->volume; } ret = volume_make_uptodate (ve, ce); if (ret) - return NULL; + return ret; bit = volcache_volid2bit (ve, e->fid.fid.Volume); if (bit == -1) { /* the volume entry is inconsistent. */ volcache_invalidate_ve (ve); - return NULL; + return ENOENT; } num_clones = 0; @@ -1494,22 +1482,41 @@ find_first_fs (FCacheEntry *e, conn = conn_get (cell, addr, afsport, FS_SERVICE_ID, fs_probe, ce); - if (conn != NULL) { - conn->rtt = rx_PeerOf(conn->connection)->rtt + if (!conn_isalivep (conn)) + conn->rtt = INT_MAX/2 ; + else if (!volcache_reliablep_el(ve, i)) + conn->rtt = INT_MAX/4; + else + conn->rtt = rx_PeerOf(conn->connection)->srtt + rand() % RTT_FUZZ - RTT_FUZZ / 2; - context->conns[num_clones] = conn; - ++num_clones; - } + context->conns[num_clones].conn = conn; + context->conns[num_clones].ve_ent = i; + ++num_clones; } } + if (num_clones == 0) + return ENOENT; + + context->ve = ve; + qsort (context->conns, num_clones, sizeof(*context->conns), - conn_rtt_cmp); + fs_rtt_cmp); context->num_conns = num_clones; context->i = 0; - return find_next_fs (context, NULL, FALSE); + return 0; +} + +/* + * Find the first file server housing the volume for `e'. + */ + +ConnCacheEntry * +find_first_fs (fs_server_context *context) +{ + return find_next_fs (context, NULL, 0); } /* @@ -1520,8 +1527,8 @@ find_first_fs (FCacheEntry *e, void fcache_init (u_long alowvnodes, u_long ahighvnodes, - u_long alowbytes, - u_long ahighbytes, + int64_t alowbytes, + int64_t ahighbytes, Bool recover) { /* @@ -1533,14 +1540,14 @@ fcache_init (u_long alowvnodes, #else fhopen_working = 0; #endif + collectstats_init (); - node_count = 1; /* XXX */ + node_count = 0; lowvnodes = alowvnodes; highvnodes = ahighvnodes; lowbytes = alowbytes; highbytes = ahighbytes; - fprioritylevel = FPRIO_DEFAULT; hashtab = hashtabnew (FCHASHSIZE, fcachecmp, fcachehash); if (hashtab == NULL) @@ -1583,8 +1590,8 @@ fcache_init (u_long alowvnodes, int fcache_reinit(u_long alowvnodes, u_long ahighvnodes, - u_long alowbytes, - u_long ahighbytes) + int64_t alowbytes, + int64_t ahighbytes) { arla_warnx (ADEBFCACHE, "fcache_reinit"); @@ -1664,10 +1671,15 @@ stale (FCacheEntry *e, AFSCallBack callback) e->flags.sentenced = TRUE; else { ObtainWriteLock (&e->lock); + fcache_poller_unref(e); e->callback = callback; - e->tokens = 0; + if (e->flags.kernelp) break_callback (e); + else + e->tokens = 0; + if (e->status.FileType == TYPE_DIR && e->length) + throw_data(e); ReleaseWriteLock (&e->lock); } } @@ -1726,7 +1738,7 @@ fcache_stale_entry (VenusFid fid, AFSCallBack callback) } typedef struct { - xfs_pag_t pag; + nnpfs_pag_t pag; int32_t cell; } fc_purgecred; @@ -1749,7 +1761,7 @@ purge_cred (void *ptr, void *arg) ae[i].cred = ARLA_NO_AUTH_CRED; ae[i].access = ANONE; if (e->flags.kernelp) - install_attr (e, FCACHE2XFSNODE_RIGHT); + install_attr (e, FCACHE2NNPFSNODE_NO_LENGTH); break; } } @@ -1763,7 +1775,7 @@ purge_cred (void *ptr, void *arg) */ void -fcache_purge_cred (xfs_pag_t pag, int32_t cell) +fcache_purge_cred (nnpfs_pag_t pag, int32_t cell) { fc_purgecred cred; @@ -1828,6 +1840,34 @@ fcache_purge_host (u_long host) hashtabforeach (hashtab, purge_host, &host); } + +/* + * If `ptr' is a mountpoint, mark it as stale. + */ + +static Bool +invalidate_mp (void *ptr, void *arg) +{ + FCacheEntry *e = (FCacheEntry *)ptr; + AFSCallBack broken_callback = {0, 0, CBDROPPED}; + + if (e->flags.mountp) + stale (e, broken_callback); + return FALSE; + + +} + +/* + * Invalidate all mountpoints to force the to be reread. + */ + +void +fcache_invalidate_mp (void) +{ + hashtabforeach (hashtab, invalidate_mp, NULL); +} + /* * Mark `entry' as not being used. */ @@ -1903,8 +1943,8 @@ update_entry (FCacheEntry *entry, AFSFetchStatus *status, AFSCallBack *callback, AFSVolSync *volsync, - u_int32_t host, - xfs_pag_t cred) + ConnCacheEntry *conn, + nnpfs_pag_t cred) { struct timeval tv; AccessEntry *ae; @@ -1927,7 +1967,14 @@ update_entry (FCacheEntry *entry, if (entry->volume) volcache_update_volsync (entry->volume, *volsync); } - entry->host = host; + + if (conn) { + fcache_poller_reref(entry, conn); + entry->host = rx_HostOf(rx_PeerOf(conn->connection)); + } else { + fcache_poller_unref(entry); + entry->host = 0; + } entry->anonaccess = status->AnonymousAccess; findaccess (cred, entry->acccache, &ae); @@ -1946,19 +1993,21 @@ update_attr_entry (FCacheEntry *entry, AFSFetchStatus *status, AFSCallBack *callback, AFSVolSync *volsync, - u_int32_t host, - xfs_pag_t cred) + ConnCacheEntry *conn, + nnpfs_pag_t cred) { - if (entry->flags.datap - && entry->status.DataVersion != status->DataVersion) { + if (entry->fetched_length + && entry->status.DataVersion != status->DataVersion + && !entry->flags.datausedp) + { throw_data (entry); - entry->tokens &= ~(XFS_DATA_R|XFS_DATA_W); + entry->tokens &= ~(NNPFS_DATA_R|NNPFS_DATA_W); } update_entry (entry, status, callback, volsync, - host, cred); + conn, cred); - entry->tokens |= XFS_ATTR_R; + entry->tokens |= NNPFS_ATTR_R; entry->flags.attrp = TRUE; } @@ -1967,11 +2016,54 @@ update_attr_entry (FCacheEntry *entry, * Give up all callbacks. */ +static int +giveup_all_callbacks (uint32_t cell, uint32_t host, void *arg) +{ + CredCacheEntry *ce; + ConnCacheEntry *conn; + Listitem *item; + int ret; + + ce = cred_get (cell, 0, CRED_ANY); + assert (ce != NULL); + + conn = conn_get (cell, host, afsport, FS_SERVICE_ID, fs_probe, ce); + cred_free (ce); + + if (!conn_isalivep (conn)) + goto out; + + ret = RXAFS_GiveUpAllCallBacks(conn->connection); + if (ret == 0) { + for (item = listtail(lrulist); + item != NULL; + item = listprev(lrulist, item)) { + FCacheEntry *entry = (FCacheEntry *)listdata(item); + + if (entry->host == host) + entry->flags.attrp = FALSE; + } + } else if (ret != RXGEN_OPCODE) { + struct in_addr in_addr; + + in_addr.s_addr = rx_HostOf(rx_PeerOf(conn->connection)); + arla_warn (ADEBWARN, ret, "GiveUpAllCallBacks %s", + inet_ntoa (in_addr)); + } + + out: + conn_free (conn); + + return 0; +} + int fcache_giveup_all_callbacks (void) { Listitem *item; + poller_foreach(giveup_all_callbacks, NULL); + for (item = listtail(lrulist); item != NULL; item = listprev(lrulist, item)) { @@ -2001,8 +2093,14 @@ fcache_giveup_all_callbacks (void) ret = RXAFS_GiveUpCallBacks (conn->connection, &fids, &cbs); conn_free (conn); - if (ret) - arla_warn (ADEBFCACHE, ret, "RXAFS_GiveUpCallBacks"); + if (ret) { + struct in_addr in_addr; + + in_addr.s_addr = rx_HostOf(rx_PeerOf(conn->connection)); + arla_warn (ADEBFCACHE, ret, "RXAFS_GiveUpCallBacks %s", + inet_ntoa (in_addr)); + } else + entry->flags.attrp = FALSE; } } } @@ -2014,7 +2112,7 @@ fcache_giveup_all_callbacks (void) */ int -fcache_reobtain_callbacks (void) +fcache_reobtain_callbacks (struct nnpfs_cred *cred) { Listitem *item; int ret; @@ -2024,6 +2122,7 @@ fcache_reobtain_callbacks (void) item = listprev(lrulist, item)) { FCacheEntry *entry = (FCacheEntry *)listdata(item); + ObtainWriteLock (&entry->lock); if (entry->flags.usedp && entry->flags.silly == FALSE && entry->host != 0) { @@ -2034,39 +2133,43 @@ fcache_reobtain_callbacks (void) AFSCallBack callback; AFSVolSync volsync; VolCacheEntry *vol; - int type; - ce = cred_get (entry->fid.Cell, 0, CRED_ANY); + ce = cred_get (entry->fid.Cell, cred->pag, CRED_ANY); assert (ce != NULL); conn = conn_get (entry->fid.Cell, entry->host, afsport, FS_SERVICE_ID, fs_probe, ce); + if (!conn_isalivep(conn)) + goto out; /* * does this belong here? */ ret = volcache_getbyid (entry->fid.fid.Volume, - entry->fid.Cell, ce, &vol, &type); + entry->fid.Cell, ce, &vol, NULL); if (ret == 0) entry->volume = vol; - cred_free (ce); - if (conn != NULL) { - ret = RXAFS_FetchStatus (conn->connection, - &entry->fid.fid, - &status, - &callback, - &volsync); - if (ret) - arla_warn (ADEBFCACHE, ret, "RXAFS_FetchStatus"); - else - update_entry (entry, &status, &callback, &volsync, - rx_HostOf(rx_PeerOf (conn->connection)), - ce->cred); - conn_free (conn); - fcache_counter.fetch_attr++; + ret = RXAFS_FetchStatus (conn->connection, + &entry->fid.fid, + &status, + &callback, + &volsync); + if (ret) + arla_warn (ADEBFCACHE, ret, "RXAFS_FetchStatus"); + else { + update_attr_entry (entry, &status, &callback, &volsync, + conn, ce->cred); + if (entry->flags.kernelp) + break_callback (entry); } + fcache_counter.fetch_attr++; + out: + if (conn) + conn_free (conn); + cred_free (ce); } + ReleaseWriteLock (&entry->lock); } return 0; /* XXX */ } @@ -2079,7 +2182,9 @@ static Bool try_next_fs (int error, const VenusFid *fid) { switch (error) { +#ifdef KERBEROS case RXKADUNKNOWNKEY: +#endif case ARLA_CALL_DEAD : case ARLA_INVALID_OPERATION : case ARLA_CALL_TIMEOUT : @@ -2096,7 +2201,7 @@ try_next_fs (int error, const VenusFid *fid) return TRUE; case ARLA_VNOVOL : case ARLA_VMOVED : - if (fid && !volcache_reliable (fid->fid.Volume, fid->Cell)) + if (fid && !volcache_reliablep (fid->fid.Volume, fid->Cell)) volcache_invalidate (fid->fid.Volume, fid->Cell); return TRUE; case 0 : @@ -2107,6 +2212,31 @@ try_next_fs (int error, const VenusFid *fid) } /* + * If the whole file is fetched as we last saw it, lets write down + * the whole file to the fileserver. If the file is shrinking, + * make sure we don't cache non-existing bytes. + */ + +static size_t +new_fetched_length(FCacheEntry *entry, size_t cache_file_size) +{ + size_t have_len; + + AssertExclLocked(&entry->lock); + + if (entry->fetched_length == entry->status.Length) + have_len = cache_file_size; + else { + have_len = entry->fetched_length; + /* have file shrinked ? */ + if (have_len > cache_file_size) + have_len = cache_file_size; + } + + return have_len; +} + +/* * Fetch the attributes for the file in `entry' from the file_server, * using the credentials in `ce' and returning the connection in * `ret_conn' @@ -2123,27 +2253,24 @@ do_read_attr (FCacheEntry *entry, ConnCacheEntry **ret_conn, fs_server_context *ret_context) { - int ret = ARLA_CALL_DEAD; ConnCacheEntry *conn; AFSFetchStatus status; AFSCallBack callback; AFSVolSync volsync; struct collect_stat collectstat; + int ret; AssertExclLocked(&entry->lock); *ret_conn = NULL; - if (connected_mode == DISCONNECTED) { - if (entry->flags.attrp) - return 0; - else - return ENETDOWN; - } + ret = init_fs_context(entry, ce, ret_context); + if (ret) + return ret; - for (conn = find_first_fs (entry, ce, ret_context); + for (conn = find_first_fs (ret_context); conn != NULL; - conn = find_next_fs (ret_context, conn, host_downp (ret))) { + conn = find_next_fs (ret_context, conn, ret)) { collectstats_start(&collectstat); ret = RXAFS_FetchStatus (conn->connection, @@ -2152,15 +2279,16 @@ do_read_attr (FCacheEntry *entry, &callback, &volsync); collectstats_stop(&collectstat, entry, conn, + find_partition(ret_context), STATISTICS_REQTYPE_FETCHSTATUS, 1); arla_warnx (ADEBFCACHE, "trying to fetch status: %d", ret); if (!try_next_fs (ret, &entry->fid)) break; } if (ret) { + arla_warn (ADEBFCACHE, ret, "fetch-status"); if (host_downp(ret)) ret = ENETDOWN; - arla_warn (ADEBFCACHE, ret, "fetch-status"); free_fs_server_context (ret_context); return ret; } @@ -2168,8 +2296,7 @@ do_read_attr (FCacheEntry *entry, fcache_counter.fetch_attr++; update_attr_entry (entry, &status, &callback, &volsync, - rx_HostOf (rx_PeerOf (conn->connection)), - ce->cred); + conn, ce->cred); AssertExclLocked(&entry->lock); @@ -2205,11 +2332,13 @@ read_attr (FCacheEntry *entry, CredCacheEntry *ce) */ static int -read_data (FCacheEntry *entry, ConnCacheEntry *conn, CredCacheEntry *ce) +read_data (FCacheEntry *entry, ConnCacheEntry *conn, CredCacheEntry *ce, + long partition) { struct rx_call *call; int ret = 0; - u_int32_t sizefs; + uint32_t wanted_length, sizefs, nbytes = 0; + int32_t sizediff; int fd; AFSFetchStatus status; AFSCallBack callback; @@ -2225,19 +2354,36 @@ read_data (FCacheEntry *entry, ConnCacheEntry *conn, CredCacheEntry *ce) goto out; } - if (usedbytes + entry->status.Length > highbytes) { - ret = fcache_need_bytes (entry->status.Length); - if (ret) goto out; + /* are we already done ? */ + if (entry->wanted_length <= entry->fetched_length) { + ret = 0; + goto out; + } + + /* figure out how much more then we need we want to fetch */ + wanted_length = stats_fetch_round(conn, partition, entry->wanted_length); + if (wanted_length > entry->status.Length) + wanted_length = entry->status.Length; + + /* we need more space ? */ + if (wanted_length > entry->length) + nbytes = wanted_length - entry->length; + + if (usedbytes + nbytes > highbytes) { + ret = fcache_need_bytes (nbytes); + if (ret) + goto out; } - if (usedbytes + entry->status.Length > highbytes) { + if (usedbytes + nbytes > highbytes) { arla_warnx (ADEBWARN, "Out of space, not enough cache " - "(%d file-length %lu usedbytes)", - entry->status.Length, usedbytes); + "(file-length: %d need bytes: %ld usedbytes: %ld)", + entry->status.Length, (long)nbytes, (long)usedbytes); ret = ENOSPC; goto out; } + /* now go talk to the world */ call = rx_NewCall (conn->connection); if (call == NULL) { arla_warnx (ADEBMISC, "rx_NewCall failed"); @@ -2246,16 +2392,17 @@ read_data (FCacheEntry *entry, ConnCacheEntry *conn, CredCacheEntry *ce) } collectstats_start(&collectstat); - ret = StartRXAFS_FetchData (call, &entry->fid.fid, - 0, entry->status.Length); + ret = StartRXAFS_FetchData (call, &entry->fid.fid, entry->fetched_length, + wanted_length - entry->fetched_length); if(ret) { arla_warn (ADEBFCACHE, ret, "fetch-data"); + rx_EndCall(call,ret); goto out; } ret = rx_Read (call, &sizefs, sizeof(sizefs)); if (ret != sizeof(sizefs)) { - ret = conv_to_arla_errno(rx_Error(call)); + ret = conv_to_arla_errno(rx_GetCallError(call)); arla_warn (ADEBFCACHE, ret, "Error reading length"); rx_EndCall(call, 0); goto out; @@ -2271,14 +2418,14 @@ read_data (FCacheEntry *entry, ConnCacheEntry *conn, CredCacheEntry *ce) goto out; } - if (ftruncate(fd, sizefs) < 0) { + if (ftruncate(fd, entry->status.Length) < 0) { close(fd); ret = errno; rx_EndCall(call, 0); goto out; } - ret = copyrx2fd (call, fd, 0, sizefs); + ret = copyrx2fd (call, fd, entry->fetched_length, sizefs); close (fd); if (ret) { arla_warn (ADEBFCACHE, ret, "copyrx2fd"); @@ -2295,20 +2442,21 @@ read_data (FCacheEntry *entry, ConnCacheEntry *conn, CredCacheEntry *ce) goto out; } collectstats_stop(&collectstat, entry, conn, - STATISTICS_REQTYPE_FETCHDATA, sizefs); + partition, STATISTICS_REQTYPE_FETCHDATA, sizefs); + + entry->fetched_length += sizefs; + sizediff = entry->fetched_length - entry->length; + entry->length = entry->fetched_length; + usedbytes += sizediff; fcache_counter.fetch_data++; update_entry (entry, &status, &callback, &volsync, - rx_HostOf(rx_PeerOf(conn->connection)), - ce->cred); - entry->length = sizefs; - usedbytes += sizefs; /* XXX - sync */ + conn, ce->cred); - entry->flags.datap = TRUE; - entry->tokens |= XFS_DATA_R | XFS_DATA_W | XFS_OPEN_NR | XFS_OPEN_NW; + entry->tokens |= NNPFS_DATA_R | NNPFS_DATA_W | NNPFS_OPEN_NR | NNPFS_OPEN_NW; -out: + out: AssertExclLocked(&entry->lock); return ret; @@ -2322,163 +2470,162 @@ int write_data (FCacheEntry *entry, AFSStoreStatus *storestatus, CredCacheEntry *ce) { - ConnCacheEntry *conn; - struct rx_call *call; - int ret = ARLA_CALL_DEAD; - u_int32_t sizefs; - int fd; - struct stat statinfo; - AFSFetchStatus status; - AFSVolSync volsync; - fs_server_context context; - - AssertExclLocked(&entry->lock); - - /* Don't write data to deleted files */ - if (entry->flags.silly) - return 0; - - fd = fcache_open_file (entry, O_RDWR); - if (fd < 0) { - ret = errno; - arla_warn (ADEBFCACHE, ret, "open cache file %u", - (unsigned)entry->index); - return ret; - } - - if (fstat (fd, &statinfo) < 0) { - ret = errno; - close (fd); - arla_warn (ADEBFCACHE, ret, "stat cache file %u", - (unsigned)entry->index); - return ret; - } - - sizefs = statinfo.st_size; - - fcache_update_length (entry, sizefs); - if (connected_mode != CONNECTED) { - close (fd); - return 0; - } - - for (conn = find_first_fs (entry, ce, &context); - conn != NULL; - conn = find_next_fs (&context, conn, host_downp (ret))) { - - call = rx_NewCall (conn->connection); - if (call == NULL) { - arla_warnx (ADEBMISC, "rx_NewCall failed"); - ret = ENOMEM; - break; - } - - ret = StartRXAFS_StoreData (call, &entry->fid.fid, - storestatus, - 0, - sizefs, - sizefs); - if (host_downp(ret)) { - rx_EndCall(call, ret); - continue; - } else if (ret) { - arla_warn (ADEBFCACHE, ret, "store-data"); - rx_EndCall(call, 0); - break; - } - - ret = copyfd2rx (fd, call, 0, sizefs); - if (ret) { - rx_EndCall(call, ret); - arla_warn (ADEBFCACHE, ret, "copyfd2rx"); - break; - } - - ret = EndRXAFS_StoreData (call, - &status, - &volsync); - if (ret) { - rx_EndCall (call, ret); - arla_warnx (ADEBFCACHE, "EndRXAFS_StoreData"); - break; - } - - ret = rx_EndCall (call, 0); - if (ret) { - arla_warn (ADEBFCACHE, ret, "rx_EndCall"); - } - break; - } - - if (conn != NULL) { - if (ret == 0) { - fcache_counter.store_data++; - update_entry (entry, &status, NULL, &volsync, - rx_HostOf(rx_PeerOf(conn->connection)), - ce->cred); - } else { - ftruncate (fd, 0); - entry->length = 0; - /* undo the work of the fcache_update_size just above the loop */ - usedbytes -= sizefs; - entry->flags.datap = FALSE; - } - } - if (host_downp(ret)) - ret = ENETDOWN; - free_fs_server_context (&context); - AssertExclLocked(&entry->lock); - close (fd); - return ret; -} - -/* - * Truncate the file in `entry' to `size' bytes. - */ - -int -truncate_file (FCacheEntry *entry, off_t size, CredCacheEntry *ce) -{ ConnCacheEntry *conn; struct rx_call *call; - int ret = ARLA_CALL_DEAD; - AFSStoreStatus storestatus; + int ret; + uint32_t sizefs; + size_t have_len; int fd; + struct stat statinfo; AFSFetchStatus status; AFSVolSync volsync; fs_server_context context; + struct collect_stat collectstat; AssertExclLocked(&entry->lock); + /* Don't write data to deleted files */ + if (entry->flags.silly) + return 0; + fd = fcache_open_file (entry, O_RDWR); if (fd < 0) { ret = errno; - arla_warn (ADEBFCACHE, ret, "open fache file %u", + arla_warn (ADEBFCACHE, ret, "open cache file %u", (unsigned)entry->index); return ret; } - if(ftruncate (fd, size) < 0) { + if (fstat (fd, &statinfo) < 0) { ret = errno; - arla_warn (ADEBFCACHE, ret, "ftruncate %ld", (long)size); close (fd); + arla_warn (ADEBFCACHE, ret, "stat cache file %u", + (unsigned)entry->index); return ret; } - + sizefs = statinfo.st_size; + + have_len = new_fetched_length(entry, sizefs); + if (entry->status.Length < have_len) + entry->status.Length = have_len; + + /* + * + */ + + fcache_update_length (entry, have_len, have_len); + if (connected_mode != CONNECTED) { + close (fd); + return 0; + } + + ret = init_fs_context(entry, ce, &context); + if (ret) + return ret; + + for (conn = find_first_fs (&context); + conn != NULL; + conn = find_next_fs (&context, conn, ret)) { + + call = rx_NewCall (conn->connection); + if (call == NULL) { + arla_warnx (ADEBMISC, "rx_NewCall failed"); + ret = ENOMEM; + break; + } + + collectstats_start(&collectstat); + ret = StartRXAFS_StoreData (call, &entry->fid.fid, + storestatus, + 0, + have_len, + entry->status.Length); + if (host_downp(ret)) { + rx_EndCall(call, ret); + continue; + } else if (ret) { + arla_warn (ADEBFCACHE, ret, "store-data"); + rx_EndCall(call, 0); + break; + } + + ret = copyfd2rx (fd, call, 0, have_len); + if (ret) { + rx_EndCall(call, ret); + arla_warn (ADEBFCACHE, ret, "copyfd2rx"); + break; + } + + ret = EndRXAFS_StoreData (call, + &status, + &volsync); + if (ret) { + rx_EndCall (call, ret); + arla_warnx (ADEBFCACHE, "EndRXAFS_StoreData"); + break; + } + + ret = rx_EndCall (call, 0); + if (ret) { + arla_warn (ADEBFCACHE, ret, "rx_EndCall"); + } + collectstats_stop(&collectstat, entry, conn, + find_partition(&context), + STATISTICS_REQTYPE_STOREDATA, sizefs); + break; + } + + if (conn != NULL) { + if (ret == 0) { + fcache_counter.store_data++; + update_entry (entry, &status, NULL, &volsync, + conn, ce->cred); + } else { + ftruncate (fd, 0); + usedbytes -= entry->length; + entry->length = 0; + entry->wanted_length = 0; + entry->fetched_length = 0; + } + } + if (host_downp(ret)) + ret = ENETDOWN; + free_fs_server_context (&context); + AssertExclLocked(&entry->lock); close (fd); + return ret; +} + +/* + * Truncate the file in `entry' to `size' bytes. + */ - if (!entry->flags.datap) - entry->length = 0; +int +truncate_file (FCacheEntry *entry, off_t size, + AFSStoreStatus *storestatus, CredCacheEntry *ce) +{ + fs_server_context context; + ConnCacheEntry *conn; + struct rx_call *call; + AFSFetchStatus status; + AFSVolSync volsync; + size_t have_len; + int ret; - fcache_update_length (entry, size); + AssertExclLocked(&entry->lock); if (connected_mode != CONNECTED) return 0; - ret = ENETDOWN; - for (conn = find_first_fs (entry, ce, &context); + have_len = new_fetched_length(entry, size); + + ret = init_fs_context(entry, ce, &context); + if (ret) + return ret; + + for (conn = find_first_fs (&context); conn != NULL; - conn = find_next_fs (&context, conn, host_downp (ret))) { + conn = find_next_fs (&context, conn, ret)) { call = rx_NewCall (conn->connection); if (call == NULL) { @@ -2487,10 +2634,9 @@ truncate_file (FCacheEntry *entry, off_t size, CredCacheEntry *ce) break; } - storestatus.Mask = 0; ret = StartRXAFS_StoreData (call, &entry->fid.fid, - &storestatus, + storestatus, size, 0, size); @@ -2503,7 +2649,6 @@ truncate_file (FCacheEntry *entry, off_t size, CredCacheEntry *ce) break; } - ret = EndRXAFS_StoreData (call, &status, &volsync); @@ -2514,21 +2659,44 @@ truncate_file (FCacheEntry *entry, off_t size, CredCacheEntry *ce) } ret = rx_EndCall (call, 0); - if (ret) { + if (ret) arla_warn (ADEBFCACHE, ret, "rx_EndCall"); - } + break; } if (ret == 0) { + int fd; + + fd = fcache_open_file (entry, O_RDWR); + if (fd < 0) { + ret = errno; + arla_warn (ADEBFCACHE, ret, "open fache file %u", + (unsigned)entry->index); + return ret; + } + + if(ftruncate (fd, size) < 0) { + ret = errno; + arla_warn (ADEBFCACHE, ret, "ftruncate %ld", (long)size); + close (fd); + return ret; + } + + close (fd); + + fcache_update_length (entry, size, have_len); + fcache_counter.store_data++; update_entry (entry, &status, NULL, &volsync, - rx_HostOf(rx_PeerOf(conn->connection)), - ce->cred); + conn, ce->cred); } + + free_fs_server_context (&context); + if (host_downp(ret)) ret = ENETDOWN; - free_fs_server_context (&context); + AssertExclLocked(&entry->lock); return ret; } @@ -2542,7 +2710,8 @@ write_attr (FCacheEntry *entry, const AFSStoreStatus *store_status, CredCacheEntry *ce) { - int ret = ARLA_CALL_DEAD; + ConnCacheEntry *conn = NULL; + int ret; AFSFetchStatus status; AFSVolSync volsync; @@ -2553,16 +2722,18 @@ write_attr (FCacheEntry *entry, return 0; if (connected_mode == CONNECTED) { - ConnCacheEntry *conn; fs_server_context context; - u_int32_t host = 0; + struct collect_stat collectstat; - for (conn = find_first_fs (entry, ce, &context); - conn != NULL; - conn = find_next_fs (&context, conn, host_downp (ret))) { + ret = init_fs_context(entry, ce, &context); + if (ret) + return ret; - host = rx_HostOf (rx_PeerOf (conn->connection)); + for (conn = find_first_fs (&context); + conn != NULL; + conn = find_next_fs (&context, conn, ret)) { + collectstats_start(&collectstat); ret = RXAFS_StoreStatus (conn->connection, &entry->fid.fid, store_status, @@ -2573,19 +2744,30 @@ write_attr (FCacheEntry *entry, } else if (ret) { arla_warn (ADEBFCACHE, ret, "store-status"); free_fs_server_context (&context); + conn = NULL; goto out; } + conn_ref(conn); break; } + + if (ret == 0) + collectstats_stop(&collectstat, entry, conn, + find_partition(&context), + STATISTICS_REQTYPE_STORESTATUS, 1); + + free_fs_server_context (&context); if (host_downp(ret)) { ret = ENETDOWN; goto out; } + update_entry (entry, &status, NULL, &volsync, conn, ce->cred); - update_entry (entry, &status, NULL, &volsync, host, ce->cred); } else { + assert (conn == NULL); + fcache_counter.store_attr++; if (store_status->Mask & SS_MODTIME) { entry->status.ClientModTime = store_status->ClientModTime; @@ -2599,9 +2781,12 @@ write_attr (FCacheEntry *entry, entry->status.UnixModeBits = store_status->UnixModeBits; if (store_status->Mask & SS_SEGSIZE) entry->status.SegSize = store_status->SegSize; + ret = 0; } -out: + out: + if (conn) + conn_free(conn); AssertExclLocked(&entry->lock); return ret; @@ -2617,26 +2802,27 @@ create_file (FCacheEntry *dir_entry, VenusFid *child_fid, AFSFetchStatus *fetch_attr, CredCacheEntry *ce) { - int ret = ARLA_CALL_DEAD; + ConnCacheEntry *conn = NULL; + int ret; AFSFid OutFid; FCacheEntry *child_entry; AFSFetchStatus status; AFSCallBack callback; AFSVolSync volsync; int fd; - u_int32_t host; AssertExclLocked(&dir_entry->lock); if (connected_mode == CONNECTED) { - ConnCacheEntry *conn; fs_server_context context; - for (conn = find_first_fs (dir_entry, ce, &context); - conn != NULL; - conn = find_next_fs (&context, conn, host_downp (ret))) { + ret = init_fs_context(dir_entry, ce, &context); + if (ret) + return ret; - host = rx_HostOf (rx_PeerOf (conn->connection)); + for (conn = find_first_fs (&context); + conn != NULL; + conn = find_next_fs (&context, conn, ret)) { ret = RXAFS_CreateFile (conn->connection, &dir_entry->fid.fid, @@ -2652,10 +2838,13 @@ create_file (FCacheEntry *dir_entry, } else if (ret) { free_fs_server_context (&context); arla_warn (ADEBFCACHE, ret, "CreateFile"); + conn = NULL; goto out; } + conn_ref(conn); break; } + free_fs_server_context (&context); if (host_downp(ret)) { @@ -2664,10 +2853,15 @@ create_file (FCacheEntry *dir_entry, } update_entry (dir_entry, &status, &callback, &volsync, - host, ce->cred); + conn, ce->cred); + } else { static int fakefid = 1001; + assert(conn == NULL); + + ret = 0; + OutFid.Volume = dir_entry->fid.fid.Volume; OutFid.Vnode = fakefid; OutFid.Unique = fakefid; @@ -2690,12 +2884,10 @@ create_file (FCacheEntry *dir_entry, fetch_attr->ServerModTime = store_attr->ClientModTime; fetch_attr->Group = store_attr->Group; fetch_attr->SyncCount = 0; - fetch_attr->spare1 = 0; - fetch_attr->spare2 = 0; - fetch_attr->spare3 = 0; - fetch_attr->spare4 = 0; - - host = dir_entry->host; + fetch_attr->DataVersionHigh = 0; + fetch_attr->LockCount = 0; + fetch_attr->LengthHigh = 0; + fetch_attr->ErrorCode = 0; } child_fid->Cell = dir_entry->fid.Cell; @@ -2708,7 +2900,7 @@ create_file (FCacheEntry *dir_entry, } update_entry (child_entry, fetch_attr, NULL, NULL, - host, ce->cred); + conn, ce->cred); child_entry->flags.attrp = TRUE; child_entry->flags.kernelp = TRUE; @@ -2732,12 +2924,14 @@ create_file (FCacheEntry *dir_entry, close (fd); child_entry->length = 0; - child_entry->flags.datap = TRUE; - child_entry->tokens |= XFS_ATTR_R | XFS_DATA_R | XFS_DATA_W; + child_entry->tokens |= NNPFS_ATTR_R | NNPFS_DATA_R | NNPFS_DATA_W; fcache_release(child_entry); -out: + out: + if (conn) + conn_free(conn); + AssertExclLocked(&dir_entry->lock); return ret; @@ -2753,25 +2947,27 @@ create_directory (FCacheEntry *dir_entry, VenusFid *child_fid, AFSFetchStatus *fetch_attr, CredCacheEntry *ce) { - int ret = ARLA_CALL_DEAD; + ConnCacheEntry *conn = NULL; + int ret; AFSFid OutFid; FCacheEntry *child_entry; AFSFetchStatus status; AFSCallBack callback; AFSVolSync volsync; - u_int32_t host; + AssertExclLocked(&dir_entry->lock); if (connected_mode == CONNECTED) { - ConnCacheEntry *conn; fs_server_context context; - for (conn = find_first_fs (dir_entry, ce, &context); - conn != NULL; - conn = find_next_fs (&context, conn, host_downp (ret))) { + ret = init_fs_context(dir_entry, ce, &context); + if (ret) + return ret; - host = rx_HostOf(rx_PeerOf(conn->connection)); + for (conn = find_first_fs (&context); + conn != NULL; + conn = find_next_fs (&context, conn, ret)) { ret = RXAFS_MakeDir (conn->connection, &dir_entry->fid.fid, @@ -2788,8 +2984,10 @@ create_directory (FCacheEntry *dir_entry, } else if (ret) { free_fs_server_context (&context); arla_warn (ADEBFCACHE, ret, "MakeDir"); + conn = NULL; goto out; } + conn_ref(conn); break; } free_fs_server_context (&context); @@ -2800,10 +2998,14 @@ create_directory (FCacheEntry *dir_entry, } update_entry (dir_entry, &status, &callback, &volsync, - host, ce->cred); + conn, ce->cred); } else { static int fakedir = 1000; + ret = 0; + + assert(conn == NULL); + OutFid.Volume = dir_entry->fid.fid.Volume; OutFid.Vnode = fakedir; OutFid.Unique = fakedir; @@ -2826,12 +3028,10 @@ create_directory (FCacheEntry *dir_entry, fetch_attr->ServerModTime = store_attr->ClientModTime; fetch_attr->Group = store_attr->Group; fetch_attr->SyncCount = 0; - fetch_attr->spare1 = 0; - fetch_attr->spare2 = 0; - fetch_attr->spare3 = 0; - fetch_attr->spare4 = 0; - - host = dir_entry->host; + fetch_attr->DataVersionHigh = 0; + fetch_attr->LockCount = 0; + fetch_attr->LengthHigh = 0; + fetch_attr->ErrorCode = 0; } child_fid->Cell = dir_entry->fid.Cell; @@ -2843,11 +3043,10 @@ create_directory (FCacheEntry *dir_entry, goto out; } - if(child_entry->flags.datap) - throw_data (child_entry); + assert(child_entry->length == 0); update_entry (child_entry, fetch_attr, NULL, NULL, - host, ce->cred); + conn, ce->cred); child_entry->flags.attrp = TRUE; child_entry->flags.kernelp = TRUE; @@ -2859,12 +3058,13 @@ create_directory (FCacheEntry *dir_entry, goto out; } - child_entry->flags.datap = TRUE; - child_entry->tokens |= XFS_ATTR_R | XFS_DATA_R | XFS_DATA_W; + child_entry->tokens |= NNPFS_ATTR_R | NNPFS_DATA_R | NNPFS_DATA_W; fcache_release(child_entry); -out: + out: + if (conn) + conn_free(conn); AssertExclLocked(&dir_entry->lock); return ret; } @@ -2883,13 +3083,12 @@ create_symlink (FCacheEntry *dir_entry, const char *contents, CredCacheEntry *ce) { - int ret = ARLA_CALL_DEAD; + int ret; ConnCacheEntry *conn; AFSFid OutFid; FCacheEntry *child_entry; AFSVolSync volsync; AFSFetchStatus new_status; - u_int32_t host; fs_server_context context; AssertExclLocked(&dir_entry->lock); @@ -2897,11 +3096,13 @@ create_symlink (FCacheEntry *dir_entry, if (connected_mode != CONNECTED) return EINVAL; - for (conn = find_first_fs (dir_entry, ce, &context); - conn != NULL; - conn = find_next_fs (&context, conn, host_downp (ret))) { + ret = init_fs_context(dir_entry, ce, &context); + if (ret) + return ret; - host = rx_HostOf(rx_PeerOf(conn->connection)); + for (conn = find_first_fs (&context); + conn != NULL; + conn = find_next_fs (&context, conn, ret)) { ret = RXAFS_Symlink (conn->connection, &dir_entry->fid.fid, @@ -2917,8 +3118,10 @@ create_symlink (FCacheEntry *dir_entry, } else if (ret) { arla_warn (ADEBFCACHE, ret, "Symlink"); free_fs_server_context (&context); + conn = NULL; goto out; } + conn_ref(conn); break; } free_fs_server_context (&context); @@ -2929,7 +3132,7 @@ create_symlink (FCacheEntry *dir_entry, } update_entry (dir_entry, &new_status, NULL, &volsync, - host, ce->cred); + conn, ce->cred); child_fid->Cell = dir_entry->fid.Cell; child_fid->fid = OutFid; @@ -2941,7 +3144,7 @@ create_symlink (FCacheEntry *dir_entry, } update_entry (child_entry, fetch_attr, NULL, NULL, - host, ce->cred); + conn, ce->cred); /* * flags.kernelp is set in cm_symlink since the symlink @@ -2950,11 +3153,13 @@ create_symlink (FCacheEntry *dir_entry, */ child_entry->flags.attrp = TRUE; - child_entry->tokens |= XFS_ATTR_R; + child_entry->tokens |= NNPFS_ATTR_R; fcache_release(child_entry); -out: + out: + if (conn) + conn_free(conn); AssertExclLocked(&dir_entry->lock); return ret; } @@ -2969,12 +3174,11 @@ create_link (FCacheEntry *dir_entry, FCacheEntry *existing_entry, CredCacheEntry *ce) { - int ret = 0; - ConnCacheEntry *conn; + ConnCacheEntry *conn = NULL; + int ret; AFSFetchStatus new_status; AFSFetchStatus status; AFSVolSync volsync; - u_int32_t host; fs_server_context context; AssertExclLocked(&dir_entry->lock); @@ -2982,11 +3186,13 @@ create_link (FCacheEntry *dir_entry, if (connected_mode != CONNECTED) return EINVAL; - for (conn = find_first_fs (dir_entry, ce, &context); - conn != NULL; - conn = find_next_fs (&context, conn, host_downp (ret))) { + ret = init_fs_context(dir_entry, ce, &context); + if (ret) + return ret; - host = rx_HostOf(rx_PeerOf(conn->connection)); + for (conn = find_first_fs (&context); + conn != NULL; + conn = find_next_fs (&context, conn, ret)) { ret = RXAFS_Link (conn->connection, &dir_entry->fid.fid, @@ -3000,8 +3206,10 @@ create_link (FCacheEntry *dir_entry, } else if (ret) { free_fs_server_context (&context); arla_warn (ADEBFCACHE, ret, "Link"); + conn = NULL; goto out; } + conn_ref(conn); break; } free_fs_server_context (&context); @@ -3012,12 +3220,14 @@ create_link (FCacheEntry *dir_entry, } update_entry (dir_entry, &status, NULL, &volsync, - host, ce->cred); + conn, ce->cred); update_entry (existing_entry, &new_status, NULL, NULL, - host, ce->cred); + conn, ce->cred); -out: + out: + if (conn) + conn_free(conn); AssertExclLocked(&dir_entry->lock); return ret; } @@ -3029,49 +3239,89 @@ out: int remove_file (FCacheEntry *dir_entry, const char *name, CredCacheEntry *ce) { - int ret = ARLA_CALL_DEAD; + int ret; ConnCacheEntry *conn; AFSFetchStatus status; AFSVolSync volsync; - u_int32_t host; fs_server_context context; AssertExclLocked(&dir_entry->lock); - if (connected_mode != CONNECTED) - return EINVAL; + if (connected_mode == CONNECTED) { - for (conn = find_first_fs (dir_entry, ce, &context); - conn != NULL; - conn = find_next_fs (&context, conn, host_downp (ret))) { + ret = init_fs_context(dir_entry, ce, &context); + if (ret) + return ret; + + for (conn = find_first_fs (&context); + conn != NULL; + conn = find_next_fs (&context, conn, ret)) { + + ret = RXAFS_RemoveFile (conn->connection, + &dir_entry->fid.fid, + name, + &status, + &volsync); + if (host_downp(ret)) { + continue; + } else if (ret) { + free_fs_server_context (&context); + arla_warn (ADEBFCACHE, ret, "RemoveFile"); + conn = NULL; + goto out; + } + conn_ref(conn); + break; + } + free_fs_server_context (&context); + + if (host_downp(ret)) + ret = ENETDOWN; - host = rx_HostOf(rx_PeerOf(conn->connection)); + } else { + fbuf the_fbuf; + VenusFid child_fid; + int fd; - ret = RXAFS_RemoveFile (conn->connection, - &dir_entry->fid.fid, - name, - &status, - &volsync); - if (host_downp(ret)) { - continue; - } else if (ret) { - free_fs_server_context (&context); - arla_warn (ADEBFCACHE, ret, "RemoveFile"); + status = dir_entry->status; + + conn = NULL; + + ret = fcache_get_fbuf (dir_entry, &fd, &the_fbuf, + O_RDONLY, FBUF_READ|FBUF_SHARED); + if (ret) goto out; - } - break; - } - free_fs_server_context (&context); + + ret = fdir_lookup(&the_fbuf, &dir_entry->fid, name, &child_fid); + if (ret == 0) { + FCacheEntry *child_entry = NULL; + uint32_t disco_id = 0; - if (host_downp(ret)) { - ret = ENETDOWN; - goto out; + ret = fcache_find(&child_entry, child_fid); + if (ret == 0) + disco_id = child_entry->disco_id; + + disco_id = disco_unlink(&dir_entry->fid, &child_fid, + name, disco_id); + + if (child_entry) { + child_entry->disco_id = disco_id; + fcache_release(child_entry); + } + ret = 0; + } + + fbuf_end (&the_fbuf); + close (fd); } - update_entry (dir_entry, &status, NULL, &volsync, - host, ce->cred); + if (ret == 0) + update_entry (dir_entry, &status, NULL, &volsync, + conn, ce->cred); -out: + out: + if (conn) + conn_free(conn); AssertExclLocked(&dir_entry->lock); return ret; } @@ -3085,11 +3335,10 @@ remove_directory (FCacheEntry *dir_entry, const char *name, CredCacheEntry *ce) { - int ret = ARLA_CALL_DEAD; + int ret; ConnCacheEntry *conn; AFSFetchStatus status; AFSVolSync volsync; - u_int32_t host; fs_server_context context; AssertExclLocked(&dir_entry->lock); @@ -3097,11 +3346,13 @@ remove_directory (FCacheEntry *dir_entry, if (connected_mode != CONNECTED) return EINVAL; - for (conn = find_first_fs (dir_entry, ce, &context); - conn != NULL; - conn = find_next_fs (&context, conn, host_downp (ret))) { + ret = init_fs_context(dir_entry, ce, &context); + if (ret) + return ret; - host = rx_HostOf(rx_PeerOf(conn->connection)); + for (conn = find_first_fs (&context); + conn != NULL; + conn = find_next_fs (&context, conn, ret)) { ret = RXAFS_RemoveDir (conn->connection, &dir_entry->fid.fid, @@ -3113,8 +3364,10 @@ remove_directory (FCacheEntry *dir_entry, } else if (ret) { free_fs_server_context (&context); arla_warn (ADEBFCACHE, ret, "RemoveDir"); + conn = NULL; goto out; } + conn_ref(conn); break; } free_fs_server_context (&context); @@ -3125,9 +3378,11 @@ remove_directory (FCacheEntry *dir_entry, } update_entry (dir_entry, &status, NULL, &volsync, - host, ce->cred); + conn, ce->cred); -out: + out: + if (conn) + conn_free(conn); AssertExclLocked(&dir_entry->lock); return ret; } @@ -3147,7 +3402,6 @@ rename_file (FCacheEntry *old_dir, ConnCacheEntry *conn; AFSFetchStatus orig_status, new_status; AFSVolSync volsync; - u_int32_t host; fs_server_context context; AssertExclLocked(&old_dir->lock); @@ -3156,11 +3410,13 @@ rename_file (FCacheEntry *old_dir, if (connected_mode != CONNECTED) return EINVAL; - for (conn = find_first_fs (old_dir, ce, &context); - conn != NULL; - conn = find_next_fs (&context, conn, host_downp (ret))) { + ret = init_fs_context(old_dir, ce, &context); + if (ret) + return ret; - host = rx_HostOf(rx_PeerOf(conn->connection)); + for (conn = find_first_fs (&context); + conn != NULL; + conn = find_next_fs (&context, conn, ret)) { ret = RXAFS_Rename (conn->connection, &old_dir->fid.fid, @@ -3175,8 +3431,10 @@ rename_file (FCacheEntry *old_dir, } else if (ret) { free_fs_server_context (&context); arla_warn (ADEBFCACHE, ret, "Rename"); + conn = NULL; goto out; } + conn_ref(conn); break; } free_fs_server_context (&context); @@ -3187,12 +3445,14 @@ rename_file (FCacheEntry *old_dir, } update_entry (old_dir, &orig_status, NULL, &volsync, - host, ce->cred); + conn, ce->cred); update_entry (new_dir, &new_status, NULL, &volsync, - host, ce->cred); + conn, ce->cred); -out: + out: + if (conn) + conn_free(conn); AssertExclLocked(&old_dir->lock); AssertExclLocked(&new_dir->lock); return ret; @@ -3205,60 +3465,49 @@ out: int getroot (VenusFid *res, CredCacheEntry *ce) { - VolCacheEntry *ve; - VenusFid fid; - const char *root_volume = volcache_get_rootvolume (); - int type; - int ret; - const char *this_cell = cell_getthiscell (); - int32_t this_cell_id; - static int busy_wait = 0; - - if (dynroot_enablep()) { - res->Cell = dynroot_cellid (); - res->fid.Volume = dynroot_volumeid (); - res->fid.Vnode = fid.fid.Unique = 1; - - return 0; - } - - this_cell_id = cell_name2num (this_cell); - if (this_cell_id == -1) - arla_errx (1, ADEBERROR, "cell %s does not exist", this_cell); - - while (busy_wait) - LWP_WaitProcess (getroot); - - busy_wait = 1; - ret = volcache_getbyname (root_volume, this_cell_id, ce, &ve, &type); - busy_wait = 0; - LWP_NoYieldSignal (getroot); - if (ret) { - arla_warn (ADEBWARN, ret, - "Cannot find the root volume (%s) in cell %s", - root_volume, this_cell); - return ret; - } - - fid.Cell = this_cell_id; - if (ve->entry.flags & VLF_ROEXISTS) { - fid.fid.Volume = ve->entry.volumeId[ROVOL]; - } else if (ve->entry.flags & VLF_RWEXISTS) { - arla_warnx(ADEBERROR, - "getroot: %s in cell %s is missing a RO clone, not good", - root_volume, this_cell); - fid.fid.Volume = ve->entry.volumeId[RWVOL]; - } else { - arla_errx(1, ADEBERROR, - "getroot: %s in cell %s has no RW or RO clone?", + VolCacheEntry *ve; + VenusFid fid; + const char *root_volume = volcache_get_rootvolume (); + int ret; + const char *this_cell = cell_getthiscell (); + int32_t this_cell_id; + + if (dynroot_enablep()) { + this_cell = "dynroot"; + this_cell_id = dynroot_cellid(); + } else { + this_cell_id = cell_name2num (this_cell); + if (this_cell_id == -1) + arla_errx (1, ADEBERROR, "cell %s does not exist", this_cell); + } + + ret = volcache_getbyname (root_volume, this_cell_id, ce, &ve, NULL); + if (ret) { + arla_warn (ADEBWARN, ret, + "Cannot find the root volume (%s) in cell %s", root_volume, this_cell); - } - fid.fid.Vnode = fid.fid.Unique = 1; + return ret; + } - volcache_free (ve); + fid.Cell = this_cell_id; + if (ve->entry.flags & VLF_ROEXISTS) { + fid.fid.Volume = ve->entry.volumeId[ROVOL]; + } else if (ve->entry.flags & VLF_RWEXISTS) { + arla_warnx(ADEBERROR, + "getroot: %s in cell %s is missing a RO clone, not good", + root_volume, this_cell); + fid.fid.Volume = ve->entry.volumeId[RWVOL]; + } else { + arla_errx(1, ADEBERROR, + "getroot: %s in cell %s has no RW or RO clone?", + root_volume, this_cell); + } + fid.fid.Vnode = fid.fid.Unique = 1; - *res = fid; - return 0; + volcache_free (ve); + + *res = fid; + return 0; } /* @@ -3268,13 +3517,13 @@ getroot (VenusFid *res, CredCacheEntry *ce) static long gettype (int32_t volid, const VolCacheEntry *ve) { - int i; + int i; - for (i = RWVOL; i <= BACKVOL; ++i) - if (ve->entry.volumeId[i] == volid) - return i; - assert (FALSE); - return -1; /* NOT REACHED */ + for (i = RWVOL; i <= BACKVOL; ++i) + if (ve->entry.volumeId[i] == volid) + return i; + assert (FALSE); + return -1; /* NOT REACHED */ } /* @@ -3300,8 +3549,8 @@ fcache_get (FCacheEntry **res, VenusFid fid, CredCacheEntry *ce) { FCacheEntry *old; FCacheEntry *e; - int type, i; - int error; + VolCacheEntry *vol; + int i, error; *res = NULL; @@ -3312,6 +3561,13 @@ fcache_get (FCacheEntry **res, VenusFid fid, CredCacheEntry *ce) return 0; } + error = volcache_getbyid (fid.fid.Volume, fid.Cell, ce, &vol, NULL); + if (error) { + if (connected_mode == DISCONNECTED && error == ENOENT) + return ENETDOWN; + return error; + } + e = find_free_entry (); assert (e != NULL); @@ -3332,6 +3588,8 @@ fcache_get (FCacheEntry **res, VenusFid fid, CredCacheEntry *ce) e->refcount = 0; e->host = 0; e->length = 0; + e->wanted_length = 0; + e->fetched_length = 0; memset (&e->status, 0, sizeof(e->status)); memset (&e->callback, 0, sizeof(e->callback)); memset (&e->volsync, 0, sizeof(e->volsync)); @@ -3341,7 +3599,6 @@ fcache_get (FCacheEntry **res, VenusFid fid, CredCacheEntry *ce) } e->anonaccess = 0; e->flags.usedp = TRUE; - e->flags.datap = FALSE; e->flags.attrp = FALSE; e->flags.attrusedp = FALSE; e->flags.datausedp = FALSE; @@ -3357,26 +3614,13 @@ fcache_get (FCacheEntry **res, VenusFid fid, CredCacheEntry *ce) e->lru_le = listaddhead (lrulist, e); assert(e->lru_le); e->invalid_ptr = -1; - e->volume = NULL; + e->volume = vol; e->priority = fprio_get(fid); e->hits = 0; e->cleanergen = 0; hashtabadd (hashtab, e); - if (connected_mode != DISCONNECTED) { - VolCacheEntry *vol; - - error = volcache_getbyid (fid.fid.Volume, fid.Cell, ce, &vol, &type); - if (error) { - e->volume = NULL; - *res = NULL; - ReleaseWriteLock (&e->lock); - return error; - } - e->volume = vol; - } - *res = e; return 0; } @@ -3441,11 +3685,11 @@ struct bulkstat { }; typedef union { - struct xfs_message_installnode node; - struct xfs_message_installattr attr; -} xfs_message_install_node_attr; + struct nnpfs_message_installnode node; + struct nnpfs_message_installattr attr; +} nnpfs_message_install_node_attr; -static void +static int bulkstat_help_func (VenusFid *fid, const char *name, void *ptr) { struct bulkstat *bs = (struct bulkstat *) ptr; @@ -3455,11 +3699,11 @@ bulkstat_help_func (VenusFid *fid, const char *name, void *ptr) /* Is bs full ? */ if (bs->len > fcache_bulkstatus_num) - return; + return 0; /* Ignore . and .. */ if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) - return; + return 0; /* * Do we have a prefered node, and is this the one. If we don't know @@ -3473,7 +3717,7 @@ bulkstat_help_func (VenusFid *fid, const char *name, void *ptr) bs->names[0] = strdup (name); bs->used = NULL; /* stat everything after this */ } - return; + return 0; } /* @@ -3491,21 +3735,23 @@ bulkstat_help_func (VenusFid *fid, const char *name, void *ptr) "(%d.%d.%d.%d) name: %s", fid->Cell, fid->fid.Volume, fid->fid.Vnode, fid->fid.Unique, name); - return; + return 0; } if (fcache_enable_bulkstatus == 2) { /* cache the name for the installnode */ bs->names[bs->len] = strdup (name); if (bs->names[bs->len] == NULL) - return; + return 0; } else { bs->names[bs->len] = NULL; } bs->fids[bs->len] = fid->fid; - bs->len++; + bs->len++; + + return 0; } /* @@ -3529,7 +3775,7 @@ get_attr_bulk (FCacheEntry *parent_entry, CredCacheEntry *ce) { fs_server_context context; - ConnCacheEntry *conn; + ConnCacheEntry *conn = NULL; struct bulkstat bs; AFSBulkStats stats; AFSVolSync sync; @@ -3539,14 +3785,14 @@ get_attr_bulk (FCacheEntry *parent_entry, AFSCBs cbs; int i; int len; - u_int32_t host; + struct collect_stat collectstat; arla_warnx (ADEBFCACHE, "get_attr_bulk"); if (fcache_enable_bulkstatus == 0) return -1; - if (!parent_entry->flags.datap) { + if (parent_entry->length == 0) { arla_warnx (ADEBFCACHE, "get_attr_bulk: parent doesn't have data"); return -1; } @@ -3587,7 +3833,8 @@ get_attr_bulk (FCacheEntry *parent_entry, ret = fdir_readdir (&the_fbuf, bulkstat_help_func, &bs, - &parent_entry->fid); + parent_entry->fid, + NULL); fbuf_end (&the_fbuf); close (fd); if (ret) @@ -3625,25 +3872,40 @@ get_attr_bulk (FCacheEntry *parent_entry, ret = ARLA_CALL_DEAD; - for (conn = find_first_fs (parent_entry, ce, &context); + ret = init_fs_context(parent_entry, ce, &context); + if (ret) + return ret; + + for (conn = find_first_fs (&context); conn != NULL; - conn = find_next_fs (&context, conn, host_downp (ret))) { + conn = find_next_fs (&context, conn, ret)) { stats.val = NULL; cbs.val = NULL; stats.len = cbs.len = 0; + collectstats_start(&collectstat); ret = RXAFS_BulkStatus (conn->connection, &fids, &stats, &cbs, &sync); + collectstats_stop(&collectstat, parent_entry, conn, + find_partition(&context), + STATISTICS_REQTYPE_BULKSTATUS, fids.len); if (ret) { free (stats.val); free (cbs.val); } - if (!try_next_fs (ret, &parent_entry->fid)) - break; + + if (host_downp(ret)) { + continue; + } else if (ret) { + free_fs_server_context(&context); + arla_warn(ADEBFCACHE, ret, "BulkStatus"); + conn = NULL; + goto out_names; + } + conn_ref(conn); + break; } - if (conn != NULL) - host = rx_HostOf (rx_PeerOf (conn->connection)); free_fs_server_context (&context); if (ret) { @@ -3661,18 +3923,18 @@ get_attr_bulk (FCacheEntry *parent_entry, if (ret == 0) { FCacheEntry *e; + VenusFid fid; fcache_counter.fetch_attr_bulk += len; + fid.Cell = parent_entry->fid.Cell; for (i = 0; i < len && ret == 0; i++) { - if (prefered_entry && i == 0) { + + fid.fid = fids.val[i]; + + if (VenusFid_cmp(prefered_fid, &fid) == 0) { e = prefered_entry; } else { - VenusFid fid; - - fid.Cell = parent_entry->fid.Cell; - fid.fid = fids.val[i]; - e = find_entry_nolock (fid); if (e != NULL && CheckLock(&e->lock) != 0) continue; @@ -3685,7 +3947,7 @@ get_attr_bulk (FCacheEntry *parent_entry, &stats.val[i], &cbs.val[i], &sync, - host, + conn, ce->cred); e->parent = parent_entry->fid; if (prefered_entry != e) { @@ -3699,104 +3961,106 @@ get_attr_bulk (FCacheEntry *parent_entry, */ if (fcache_enable_bulkstatus == 2 && ret == 0) { - xfs_message_install_node_attr msg[AFSCBMAX]; - struct xfs_msg_node *node; - xfs_handle *parent; + nnpfs_message_install_node_attr msg[AFSCBMAX]; + struct nnpfs_msg_node *node; + nnpfs_handle *parent; FCacheEntry *e; VenusFid fid; int j; fid.Cell = parent_entry->fid.Cell; for (i = 0 , j = 0; i < len && ret == 0; i++) { + u_int tokens; fid.fid = fids.val[i]; - if (prefered_entry && i == 0) { + if (VenusFid_cmp(prefered_fid, &fid) == 0) { e = prefered_entry; - ret = 0; } else { e = find_entry_nolock (fid); if (e != NULL && CheckLock(&e->lock) != 0) continue; ret = fcache_get (&e, fid, ce); + if (ret) + break; } - if (ret == 0) { - u_int tokens; - - arla_warnx (ADEBFCACHE, "installing %d.%d.%d\n", - e->fid.fid.Volume, - e->fid.fid.Vnode, - e->fid.fid.Unique); - e->flags.attrusedp = TRUE; - - /* - * Its its already installed, just update with installattr - */ - - e->tokens |= XFS_ATTR_R; - tokens = e->tokens; - if (!e->flags.kernelp || !e->flags.datausedp) - tokens &= ~XFS_DATA_MASK; - - if (e->flags.kernelp) { - msg[j].attr.header.opcode = XFS_MSG_INSTALLATTR; - node = &msg[j].attr.node; - parent = NULL; - } else { - msg[j].node.header.opcode = XFS_MSG_INSTALLNODE; - node = &msg[j].node.node; - parent = &msg[j].node.parent_handle; - e->flags.kernelp = TRUE; - strlcpy (msg[j].node.name, bs.names[i], - sizeof(msg[j].node.name)); - } - node->tokens = tokens; - - /* - * Don't install symlink since they might be - * mount-points. - */ - - if (e->status.FileType != TYPE_LINK) { - fcacheentry2xfsnode (&e->fid, - &e->fid, - &stats.val[i], - node, - parent_entry->acccache, - FCACHE2XFSNODE_ALL); - - if (parent) - *parent = *(struct xfs_handle*) &parent_entry->fid; - j++; - } - if (!(prefered_entry && i == 0)) { - fcache_release(e); - } + + + arla_warnx (ADEBFCACHE, "installing %d.%d.%d\n", + e->fid.fid.Volume, + e->fid.fid.Vnode, + e->fid.fid.Unique); + assert_flag(e,kernelp); + e->flags.attrusedp = TRUE; + + /* + * Its its already installed, just update with installattr + */ + + e->tokens |= NNPFS_ATTR_R; + tokens = e->tokens; + if (!e->flags.kernelp || !e->flags.datausedp) + tokens &= ~NNPFS_DATA_MASK; + + if (e->flags.kernelp) { + msg[j].attr.header.opcode = NNPFS_MSG_INSTALLATTR; + node = &msg[j].attr.node; + parent = NULL; + } else { + msg[j].node.header.opcode = NNPFS_MSG_INSTALLNODE; + node = &msg[j].node.node; + parent = &msg[j].node.parent_handle; + e->flags.kernelp = TRUE; + strlcpy (msg[j].node.name, bs.names[i], + sizeof(msg[j].node.name)); + } + node->tokens = tokens; + + /* + * Don't install symlink since they might be + * mount-points. + */ + + if (e->status.FileType != TYPE_LINK) { + fcacheentry2nnpfsnode (&e->fid, + &e->fid, + &stats.val[i], + node, + parent_entry->acccache, + FCACHE2NNPFSNODE_ALL); + + if (parent) + *parent = *(struct nnpfs_handle*) &parent_entry->fid; + j++; } + if (prefered_entry != e) + fcache_release(e); } /* * Install if there is no error and we have something to install */ - + if (ret == 0 && j != 0) - ret = xfs_send_message_multiple_list (kernel_fd, - (struct xfs_message_header *) msg, - sizeof (msg[0]), - j); + ret = nnpfs_send_message_multiple_list (kernel_fd, + (struct nnpfs_message_header *) msg, + sizeof (msg[0]), + j); /* We have what we wanted, ignore errors */ if (ret && i > 0 && prefered_entry) ret = 0; } - + free (stats.val); free (cbs.val); out_names: - for (i = 0 ; i < bs.len && ret == 0; i++) { + for (i = 0 ; i < bs.len && ret == 0; i++) free (bs.names[i]); - } + + if (conn) + conn_free(conn); arla_warnx (ADEBFCACHE, "get_attr_bulk: returned %d", ret); @@ -3815,12 +4079,10 @@ get_attr_bulk (FCacheEntry *parent_entry, */ int -fcache_verify_attr (FCacheEntry *entry, FCacheEntry *parent_entry, +fcache_verify_attr (FCacheEntry *entry, FCacheEntry *parent, const char *prefered_name, CredCacheEntry* ce) { - FCacheEntry *parent = parent_entry; AccessEntry *ae; - int error; if (dynroot_is_dynrootp (entry)) return dynroot_get_attr (entry, ce); @@ -3840,16 +4102,29 @@ fcache_verify_attr (FCacheEntry *entry, FCacheEntry *parent_entry, * Dont ask fileserver if this file is deleted */ if (entry->flags.silly) { - entry->tokens |= XFS_ATTR_R; + entry->tokens |= NNPFS_ATTR_R; entry->flags.attrp = TRUE; return 0; } + if (connected_mode == DISCONNECTED) { + if (entry->flags.attrp) { + AccessEntry *ae; + findaccess(ce->cred, entry->acccache, &ae); + ae->cred = ce->cred; + ae->access = 0x7f; /* XXXDISCO */ + return 0; + } + else + return ENETDOWN; + } + /* - * If `entry' is a root-node or the parent is + * If there is no parent, `entry' is a root-node, or the parent is * un-initialized, don't bother bulkstatus. */ - if (entry->fid.fid.Vnode != 1 + if (parent != NULL + && entry->fid.fid.Vnode != 1 && entry->fid.fid.Unique != 1 && !entry->flags.mountp && !entry->flags.fake_mp @@ -3858,35 +4133,25 @@ fcache_verify_attr (FCacheEntry *entry, FCacheEntry *parent_entry, && entry->parent.fid.Vnode != 0 && entry->parent.fid.Unique != 0) { - if (parent == NULL) { - arla_warnx (ADEBFCACHE, "fcache_get_attr: getting parent"); - error = fcache_get (&parent, entry->parent, ce); - } else - error = 0; - /* * Check if the entry is used, that means that * there is greater chance that we we'll succeed * when doing bulkstatus. */ - if (error == 0) { - int error2 = -1; - - if (parent->hits++ > fcache_bulkstatus_num && - parent->flags.datausedp) { - - arla_warnx (ADEBFCACHE, - "fcache_get_attr: doing bulk get_attr"); - error2 = get_attr_bulk (parent, - entry, &entry->fid, - prefered_name, ce); - /* magic calculation when we are going to do next bulkstat */ - parent->hits = 0; - } - if (parent_entry == NULL) - fcache_release (parent); - if (error2 == 0) + if (parent->hits++ > fcache_bulkstatus_num && + parent->flags.datausedp) { + int error; + + arla_warnx (ADEBFCACHE, "fcache_get_attr: doing bulk get_attr"); + + error = get_attr_bulk (parent, + entry, &entry->fid, + prefered_name, ce); + /* magic calculation when we are going to do next bulkstat */ + parent->hits = 0; + + if (error == 0) return 0; } } @@ -3917,12 +4182,16 @@ do_read_data (FCacheEntry *e, CredCacheEntry *ce) ConnCacheEntry *conn; if (connected_mode != CONNECTED) - return EINVAL; + return ENETDOWN; + + ret = init_fs_context(e, ce, &context); + if (ret) + return ret; - for (conn = find_first_fs (e, ce, &context); + for (conn = find_first_fs (&context); conn != NULL; - conn = find_next_fs (&context, conn, host_downp (ret))) { - ret = read_data (e, conn, ce); + conn = find_next_fs (&context, conn, ret)) { + ret = read_data (e, conn, ce, find_partition(&context)); if (!try_next_fs (ret, &e->fid)) break; } @@ -3955,7 +4224,7 @@ fcache_verify_data (FCacheEntry *e, CredCacheEntry *ce) return 0; if (e->flags.attrp && uptodatep(e)) { - if (e->flags.datap) { + if (e->wanted_length <= e->fetched_length) { fcache_counter.fetch_data_cached++; return 0; } else @@ -3964,13 +4233,13 @@ fcache_verify_data (FCacheEntry *e, CredCacheEntry *ce) ret = do_read_attr (e, ce, &conn, &context); if (ret) return ret; - if (e->flags.datap) { + if (e->wanted_length <= e->fetched_length) { fcache_counter.fetch_data_cached++; free_fs_server_context (&context); return 0; } } - ret = read_data (e, conn, ce); + ret = read_data (e, conn, ce, find_partition(&context)); free_fs_server_context (&context); return ret; } @@ -3981,50 +4250,55 @@ fcache_verify_data (FCacheEntry *e, CredCacheEntry *ce) */ int -fcache_get_data (FCacheEntry **res, VenusFid *fid, CredCacheEntry **ce) +fcache_get_data (FCacheEntry **e, CredCacheEntry **ce, + size_t wanted_length) { - FCacheEntry *e; int ret; - ret = fcache_get (&e, *fid, *ce); - if (ret) - return ret; - - if (e->flags.fake_mp) { + if ((*e)->flags.fake_mp) { VenusFid new_fid; FCacheEntry *new_root; ret = resolve_mp (e, &new_fid, ce); if (ret) { - fcache_release (e); return ret; } ret = fcache_get (&new_root, new_fid, *ce); if (ret) { - fcache_release (e); return ret; } ret = fcache_verify_attr (new_root, NULL, NULL, *ce); if (ret) { - fcache_release (e); fcache_release (new_root); return ret; } - e->flags.fake_mp = FALSE; - e->flags.mountp = TRUE; - e->status.FileType = TYPE_LINK; - update_fid (*fid, e, new_fid, new_root); - fcache_release (e); - *fid = new_fid; - e = new_root; - install_attr (e, FCACHE2XFSNODE_ALL); + (*e)->flags.fake_mp = FALSE; + (*e)->flags.mountp = TRUE; + (*e)->status.FileType = TYPE_LINK; + update_fid ((*e)->fid, *e, new_fid, new_root); + fcache_release (*e); + *e = new_root; + install_attr (*e, FCACHE2NNPFSNODE_ALL); } - ret = fcache_verify_data (e, *ce); - if (ret == 0) - *res = e; - else - fcache_release (e); + if (wanted_length) { + (*e)->wanted_length = wanted_length; + } else { + /* + * XXX remove this case, attr should either be known already + * here, or we should just fetch `whole file'/next block. + */ + + ret = fcache_verify_attr (*e, NULL, NULL, *ce); + if (ret) { + return ret; + } + if ((*e)->length == 0 || !uptodatep(*e)) { + (*e)->wanted_length = (*e)->status.Length; + } + } + + ret = fcache_verify_data (*e, *ce); return ret; } @@ -4080,7 +4354,7 @@ parse_mountpoint (char *mp, size_t len, int32_t *cell, char **volname) static int find_volume (const char *volname, int32_t cell, CredCacheEntry *ce, char mount_symbol, int parent_type, - u_int32_t *volid, VolCacheEntry **ve) + uint32_t *volid, VolCacheEntry **ve) { int result_type; int this_type; @@ -4114,8 +4388,12 @@ find_volume (const char *volname, int32_t cell, mount_symbol == '#') { if ((*ve)->entry.flags & VLF_ROEXISTS) result_type = ROVOL; - else + else if ((*ve)->entry.flags & VLF_RWEXISTS) result_type = RWVOL; + else { + volcache_free (*ve); + return ENOENT; + } } else { if ((*ve)->entry.flags & VLF_RWEXISTS) result_type = RWVOL; @@ -4147,7 +4425,7 @@ get_root_of_volume (VenusFid *fid, const VenusFid *parent, VenusFid oldfid = *fid; char *volname; int32_t cell; - u_int32_t volid; + uint32_t volid; int res; long parent_type; char mount_symbol; @@ -4242,31 +4520,31 @@ int followmountpoint (VenusFid *fid, const VenusFid *parent, FCacheEntry *parent_e, CredCacheEntry **ce) { - FCacheEntry *e; - int ret; - - /* - * Get the node for `fid' and verify that it's a symbolic link - * with the correct bits. Otherwise, just return the old - * `fid' without any change. - */ - - ret = fcache_get (&e, *fid, *ce); - if (ret) - return ret; - - ret = fcache_verify_attr (e, parent_e, NULL, *ce); - if (ret) { - fcache_release(e); - return ret; - } - - e->parent = *parent; - if (e->flags.mountp) - ret = resolve_mp (e, fid, ce); + FCacheEntry *e; + int ret; + + /* + * Get the node for `fid' and verify that it's a symbolic link + * with the correct bits. Otherwise, just return the old + * `fid' without any change. + */ + + ret = fcache_get (&e, *fid, *ce); + if (ret) + return ret; + + e->parent = *parent; + ret = fcache_verify_attr (e, parent_e, NULL, *ce); + if (ret) { + fcache_release(e); + return ret; + } + + if (e->flags.mountp) + ret = resolve_mp (&e, fid, ce); - fcache_release(e); - return ret; + fcache_release(e); + return ret; } /* @@ -4274,25 +4552,27 @@ followmountpoint (VenusFid *fid, const VenusFid *parent, FCacheEntry *parent_e, */ static int -resolve_mp (FCacheEntry *e, VenusFid *ret_fid, CredCacheEntry **ce) +resolve_mp (FCacheEntry **e, VenusFid *ret_fid, CredCacheEntry **ce) { - VenusFid fid = e->fid; + VenusFid fid = (*e)->fid; int ret; fbuf the_fbuf; char *buf; int fd; - u_int32_t length; + uint32_t length; - assert (e->flags.fake_mp || e->flags.mountp); - AssertExclLocked(&e->lock); + assert ((*e)->flags.fake_mp || (*e)->flags.mountp); + AssertExclLocked(&(*e)->lock); - ret = fcache_verify_data (e, *ce); + (*e)->wanted_length = (*e)->status.Length; + + ret = fcache_verify_data (*e, *ce); if (ret) return ret; - length = e->status.Length; + length = (*e)->status.Length; - fd = fcache_open_file (e, O_RDONLY); + fd = fcache_open_file (*e, O_RDONLY); if (fd < 0) return errno; @@ -4304,7 +4584,8 @@ resolve_mp (FCacheEntry *e, VenusFid *ret_fid, CredCacheEntry **ce) } buf = fbuf_buf (&the_fbuf); - ret = get_root_of_volume (&fid, &e->parent, e->volume, ce, buf, length); + ret = get_root_of_volume (&fid, &(*e)->parent, (*e)->volume, + ce, buf, length); fbuf_end (&the_fbuf); close (fd); @@ -4328,7 +4609,7 @@ print_entry (void *ptr, void *arg) e->fid.fid.Volume, e->fid.fid.Vnode, e->fid.fid.Unique, e->flags.usedp?" used":"", e->flags.attrp?" attr":"", - e->flags.datap?" data":"", + e->length != 0 ?" data":"", e->flags.attrusedp?" attrused":"", e->flags.datausedp?" dataused":"", e->flags.extradirp?" extradir":"", @@ -4353,7 +4634,7 @@ fcache_status (void) arla_log(ADEBVLOG, "%lu (%lu-/%lu)-%lu) files" "%lu (%lu-%lu) bytes\n", usedvnodes, lowvnodes, current_vnodes, highvnodes, - usedbytes, lowbytes, highbytes); + (long)usedbytes, (long)lowbytes, (long)highbytes); hashtabforeach (hashtab, print_entry, NULL); } @@ -4362,14 +4643,17 @@ fcache_status (void) */ void -fcache_update_length (FCacheEntry *e, size_t len) +fcache_update_length (FCacheEntry *e, size_t len, size_t have_len) { AssertExclLocked(&e->lock); assert (len >= e->length || e->length - len <= usedbytes); + assert (have_len <= len); usedbytes = usedbytes - e->length + len; e->length = len; + e->wanted_length = min(have_len,len); + e->fetched_length = have_len; } /* @@ -4400,11 +4684,13 @@ getacl(VenusFid fid, return ret; } - ret = ARLA_CALL_DEAD; + ret = init_fs_context(dire, ce, &context); + if (ret) + return ret; - for (conn = find_first_fs (dire, ce, &context); + for (conn = find_first_fs (&context); conn != NULL; - conn = find_next_fs (&context, conn, host_downp (ret))) { + conn = find_next_fs (&context, conn, ret)) { ret = RXAFS_FetchACL (conn->connection, &fid.fid, opaque, &status, &volsync); @@ -4422,8 +4708,7 @@ getacl(VenusFid fid, if (ret == 0) update_entry (dire, &status, NULL, &volsync, - rx_HostOf(rx_PeerOf(conn->connection)), - ce->cred); + conn, ce->cred); else if (host_downp(ret)) ret = ENETDOWN; @@ -4461,11 +4746,13 @@ setacl(VenusFid fid, return EINVAL; } - ret = ARLA_CALL_DEAD; + ret = init_fs_context(dire, ce, &context); + if (ret) + return ret; - for (conn = find_first_fs (dire, ce, &context); + for (conn = find_first_fs (&context); conn != NULL; - conn = find_next_fs (&context, conn, host_downp (ret))) { + conn = find_next_fs (&context, conn, ret)) { ret = RXAFS_StoreACL (conn->connection, &fid.fid, opaque, &status, &volsync); if (!try_next_fs (ret, &fid)) @@ -4476,8 +4763,7 @@ setacl(VenusFid fid, if (ret == 0) update_entry (dire, &status, NULL, &volsync, - rx_HostOf(rx_PeerOf(conn->connection)), - ce->cred); + conn, ce->cred); else if (host_downp(ret)) ret = ENETDOWN; @@ -4499,7 +4785,7 @@ setacl(VenusFid fid, int getvolstat(VenusFid fid, CredCacheEntry *ce, AFSFetchVolumeStatus *volstat, - char *volumename, + char *volumename, size_t volumenamesz, char *offlinemsg, char *motd) { @@ -4517,11 +4803,13 @@ getvolstat(VenusFid fid, CredCacheEntry *ce, return EINVAL; } - ret = ARLA_CALL_DEAD; + ret = init_fs_context(dire, ce, &context); + if (ret) + return ret; - for (conn = find_first_fs (dire, ce, &context); + for (conn = find_first_fs (&context); conn != NULL; - conn = find_next_fs (&context, conn, host_downp (ret))) { + conn = find_next_fs (&context, conn, ret)) { ret = RXAFS_GetVolumeStatus (conn->connection, fid.fid.Volume, volstat, volumename, offlinemsg, motd); @@ -4533,9 +4821,11 @@ getvolstat(VenusFid fid, CredCacheEntry *ce, free_fs_server_context (&context); if (host_downp(ret)) ret = ENETDOWN; - if (ret == 0 && volumename[0] == '\0') - volcache_getname (fid.fid.Volume, fid.Cell, - volumename, sizeof(volumename)); + if (ret == 0 && volumename[0] == '\0') { + if (volcache_getname (fid.fid.Volume, fid.Cell, + volumename, volumenamesz) == -1) + strlcpy(volumename, "<unknown>", volumenamesz); + } fcache_release (dire); return ret; @@ -4566,11 +4856,13 @@ setvolstat(VenusFid fid, CredCacheEntry *ce, return EINVAL; } - ret = ARLA_CALL_DEAD; + ret = init_fs_context(dire, ce, &context); + if (ret) + return ret; - for (conn = find_first_fs (dire, ce, &context); + for (conn = find_first_fs (&context); conn != NULL; - conn = find_next_fs (&context, conn, host_downp (ret))) { + conn = find_next_fs (&context, conn, ret)) { ret = RXAFS_SetVolumeStatus (conn->connection, fid.fid.Volume, volstat, volumename, offlinemsg, motd); @@ -4632,24 +4924,19 @@ fcache_get_fbuf (FCacheEntry *centry, int *fd, fbuf *fbuf, static Bool sum_node (List *list, Listitem *li, void *arg) { - u_long *a = (u_long *) arg; + int64_t *a = arg; FCacheEntry *e = listdata (li); - if (e->flags.attrp - && e->flags.datap - && !dynroot_is_dynrootp (e)) { - - *a += e->length; - } + *a += e->length; return FALSE; } -u_long +int64_t fcache_calculate_usage (void) { - u_long size = 0; + int64_t size = 0; listiter (lrulist, sum_node, &size); diff --git a/usr.sbin/afs/src/arlad/fcache.h b/usr.sbin/afs/src/arlad/fcache.h index 61b55a05214..35b5a2939e2 100644 --- a/usr.sbin/afs/src/arlad/fcache.h +++ b/usr.sbin/afs/src/arlad/fcache.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995-2000 Kungliga Tekniska Högskolan + * Copyright (c) 1995-2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -35,27 +35,27 @@ * The interface for the file-cache. */ -/* $KTH: fcache.h,v 1.72.2.2 2001/10/02 16:13:07 jimmy Exp $ */ +/* $arla: fcache.h,v 1.97 2003/01/10 03:20:42 lha Exp $ */ #ifndef _FCACHE_H_ #define _FCACHE_H_ -#include <xfs/xfs_message.h> +#include <nnpfs/nnpfs_message.h> #include <fcntl.h> #include <cred.h> #include <heap.h> /* * For each entry in the filecache we save the rights of NACCESS users. - * The value should be the same as MAXRIGHTS from xfs_message.h - * If it isn't you can get some very strange behavior from xfs, so don't + * The value should be the same as MAXRIGHTS from nnpfs_message.h + * If it isn't you can get some very strange behavior from nnpfs, so don't * even try. XXX */ #define NACCESS MAXRIGHTS typedef struct { - xfs_pag_t cred; + nnpfs_pag_t cred; u_long access; } AccessEntry; @@ -70,26 +70,27 @@ enum Access { ANONE = 0x0, typedef struct { Bool valid; - xfs_cache_handle xfs_handle; + nnpfs_cache_handle nnpfs_handle; } fcache_cache_handle; typedef struct { struct Lock lock; /* locking information for this entry */ VenusFid fid; /* The fid of the file for this entry */ unsigned refcount; /* reference count */ - u_int32_t host; /* the source of this entry */ - size_t length; /* length of our cached copy */ + uint32_t host; /* the source of this entry */ + size_t length; /* the cache usage size */ + size_t wanted_length; /* this much data should be fetched */ + size_t fetched_length; /* this much data has been fetched */ AFSFetchStatus status; /* Removed unused stuff later */ AFSCallBack callback; /* Callback to the AFS-server */ AFSVolSync volsync; /* Sync info for ro-volumes */ AccessEntry acccache[NACCESS]; /* cache for the access rights */ - u_int32_t anonaccess; /* the access mask for system:anyuser */ + uint32_t anonaccess; /* the access mask for system:anyuser */ unsigned index; /* this is V%u */ fcache_cache_handle handle; /* handle */ struct { unsigned usedp : 1; /* Is this entry used? */ unsigned attrp : 1; /* Are the attributes in status valid? */ - unsigned datap : 1; /* Is the cache-file valid? */ unsigned attrusedp : 1; /* Attr is used in the kernel */ unsigned datausedp : 1; /* Data is used in the kernel */ unsigned extradirp : 1; /* Has this directory been "converted"? */ @@ -108,6 +109,8 @@ typedef struct { Bool priority; /* is the file worth keeping */ int hits; /* number of lookups */ int cleanergen; /* generation cleaner */ + PollerEntry *poll; /* poller entry */ + uint32_t disco_id; /* id in disconncted log */ } FCacheEntry; /* @@ -115,28 +118,18 @@ typedef struct { */ struct fs_server_context { - ConnCacheEntry *conns[NMAXNSERVERS]; int i; /* current number being probed */ int num_conns; /* number in `conns' */ + VolCacheEntry *ve; /* */ + struct fs_server_entry { + ConnCacheEntry *conn; /* rx connection to server */ + int ve_ent; /* entry in `ve' */ + } conns[NMAXNSERVERS]; }; typedef struct fs_server_context fs_server_context; /* - * This is magic cookie for the dump of the fcache. - * It's supposed not to be able to be confused with an old-style - * dump (with no header) - */ - -#define FCACHE_MAGIC_COOKIE 0xff1201ff - -/* - * current version number of the dump file - */ - -#define FCACHE_VERSION 0x2 - -/* * How far the cleaner will go went cleaning things up. */ @@ -145,15 +138,15 @@ extern Bool fprioritylevel; void fcache_init (u_long alowvnodes, u_long ahighvnodes, - u_long alowbytes, - u_long ahighbytes, + int64_t alowbytes, + int64_t ahighbytes, Bool recover); int fcache_reinit(u_long alowvnodes, u_long ahighvnodes, - u_long alowbytes, - u_long ahighbytes); + int64_t alowbytes, + int64_t ahighbytes); void fcache_purge_volume (VenusFid fid); @@ -162,22 +155,25 @@ void fcache_purge_host (u_long host); void -fcache_purge_cred (xfs_pag_t cred, int32_t cell); +fcache_purge_cred (nnpfs_pag_t cred, int32_t cell); void fcache_stale_entry (VenusFid fid, AFSCallBack callback); +void +fcache_invalidate_mp (void); + int fcache_file_name (FCacheEntry *entry, char *s, size_t len); int -fcache_dir_name (FCacheEntry *entry, char *s, size_t len); +fcache_conv_file_name (FCacheEntry *entry, char *s, size_t len); int -fcache_extra_file_name (FCacheEntry *entry, char *s, size_t len); +fcache_dir_name (FCacheEntry *entry, char *s, size_t len); int -fcache_create_file (FCacheEntry *entry); +fcache_extra_file_name (FCacheEntry *entry, char *s, size_t len); int fcache_open_file (FCacheEntry *entry, int flag); @@ -192,7 +188,8 @@ int write_data (FCacheEntry *entry, AFSStoreStatus *status, CredCacheEntry *ce); int -truncate_file (FCacheEntry *entry, off_t size, CredCacheEntry *ce); +truncate_file (FCacheEntry *entry, off_t size, + AFSStoreStatus *status, CredCacheEntry *ce); int write_attr (FCacheEntry *entry, const AFSStoreStatus *status, @@ -249,7 +246,8 @@ int fcache_find (FCacheEntry **res, VenusFid fid); int -fcache_get_data (FCacheEntry **res, VenusFid *fid, CredCacheEntry **ce); +fcache_get_data (FCacheEntry **e, CredCacheEntry **ce, + size_t wanted_length); int fcache_verify_attr (FCacheEntry *entry, FCacheEntry *parent_entry, @@ -279,7 +277,7 @@ setacl(VenusFid fid, CredCacheEntry *ce, int getvolstat(VenusFid fid, CredCacheEntry *ce, AFSFetchVolumeStatus *volstat, - char *volumename, + char *volumename, size_t volumenamesz, char *offlinemsg, char *motd); @@ -290,13 +288,13 @@ setvolstat(VenusFid fid, CredCacheEntry *ce, char *offlinemsg, char *motd); -u_long +int64_t fcache_highbytes(void); -u_long +int64_t fcache_usedbytes(void); -u_long +int64_t fcache_lowbytes(void); u_long @@ -318,25 +316,28 @@ int fcache_giveup_all_callbacks (void); int -fcache_reobtain_callbacks (void); +fcache_reobtain_callbacks (struct nnpfs_cred *cred); /* XXX - this shouldn't be public, but getrights in inter.c needs it */ int read_attr (FCacheEntry *, CredCacheEntry *); Bool -findaccess (xfs_pag_t cred, AccessEntry *ae, AccessEntry **pos); +findaccess (nnpfs_pag_t cred, AccessEntry *ae, AccessEntry **pos); void fcache_unused(FCacheEntry *entry); void -fcache_update_length (FCacheEntry *entry, size_t len); +fcache_update_length (FCacheEntry *entry, size_t len, size_t have_len); + +int +init_fs_context (FCacheEntry *e, + CredCacheEntry *ce, + fs_server_context *context); ConnCacheEntry * -find_first_fs (FCacheEntry *e, - CredCacheEntry *ce, - fs_server_context *context); +find_first_fs (fs_server_context *context); ConnCacheEntry * find_next_fs (fs_server_context *context, @@ -356,7 +357,7 @@ int fcache_get_fbuf (FCacheEntry *centry, int *fd, fbuf *fbuf, int open_flags, int fbuf_flags); -u_long +int64_t fcache_calculate_usage (void); const VenusFid * @@ -365,12 +366,19 @@ fcache_realfid (const FCacheEntry *entry); void fcache_mark_as_mountpoint (FCacheEntry *entry); +const char * +fcache_getdefsysname (void); + +int +fcache_addsysname (const char *sysname); + +int +fcache_removesysname (const char *sysname); + int -collectstats_hostpart(u_int32_t *host, u_int32_t *part, int *n); +fcache_setdefsysname (const char *sysname); int -collectstats_getentry(u_int32_t host, u_int32_t part, u_int32_t type, - u_int32_t items_slot, u_int32_t *count, - int64_t *items_total, int64_t *total_time); +fs_probe (struct rx_connection *conn); #endif /* _FCACHE_H_ */ diff --git a/usr.sbin/afs/src/arlad/fprio.c b/usr.sbin/afs/src/arlad/fprio.c index b24b36104df..57a075eb91a 100644 --- a/usr.sbin/afs/src/arlad/fprio.c +++ b/usr.sbin/afs/src/arlad/fprio.c @@ -37,7 +37,7 @@ #include "arla_local.h" #include <kafs.h> -RCSID("$KTH: fprio.c,v 1.9 2000/10/02 22:31:43 lha Exp $"); +RCSID("$arla: fprio.c,v 1.12 2002/10/02 00:54:21 lha Exp $"); /* Hashtable of entries by name */ static Hashtab *fpriohashtab; @@ -199,9 +199,11 @@ fprio_readin(char *file) if (f == NULL) return -1; - while(fgets(line, sizeof(line)-1, f) != NULL) { + while(fgets(line, sizeof(line), f) != NULL) { lineno++; + line[strcspn(line, "\n")] = '\0'; + if (line[0] == '#') continue; @@ -256,7 +258,7 @@ fprio_print_entry (void *ptr, void *arg) { struct fpriorityentry *n = (struct fpriorityentry *)ptr; const char *cell = cell_num2name(n->fid.Cell); - char *comment; + const char *comment; if (cell == NULL) /* If we cant find the cell comment it out */ comment = "#"; diff --git a/usr.sbin/afs/src/arlad/fprio.h b/usr.sbin/afs/src/arlad/fprio.h index b2b297efafa..1be5dde884e 100644 --- a/usr.sbin/afs/src/arlad/fprio.h +++ b/usr.sbin/afs/src/arlad/fprio.h @@ -35,7 +35,7 @@ * Our cache of volume information. */ -/* $KTH: fprio.h,v 1.6 2000/10/02 22:31:48 lha Exp $ */ +/* $arla: fprio.h,v 1.6 2000/10/02 22:31:48 lha Exp $ */ #ifndef _FPRIO_ #define _FPRIO_ diff --git a/usr.sbin/afs/src/arlad/fs_errors.h b/usr.sbin/afs/src/arlad/fs_errors.h index 2955f118a63..b7c07c3f9cb 100644 --- a/usr.sbin/afs/src/arlad/fs_errors.h +++ b/usr.sbin/afs/src/arlad/fs_errors.h @@ -31,12 +31,17 @@ * SUCH DAMAGE. */ -/* $KTH: fs_errors.h,v 1.10 2000/11/26 21:54:19 lha Exp $ */ +/* $arla: fs_errors.h,v 1.12 2003/03/06 00:39:29 lha Exp $ */ #ifndef _FS_ERRORS_H_ #define _FS_ERRORS_H_ 1 #include <rx/rx.h> +#include <uae.h> + +#if !defined(__GNUC__) && !defined(__attribute__) +#define __attribute__(x) +#endif #define VICE_SPECIAL_ERRORS 101 @@ -97,7 +102,7 @@ conv_to_arla_errno(int error) else if (error <= RX_MIN_ERROR && error >= RX_MAX_ERROR) return ARLA_SPECIAL_RX_ERROR_ADD - error; /* RX code are negative */ else - return error; + return uae_error_to_errno(error); } #endif /* _FS_ERRORS_H_ */ diff --git a/usr.sbin/afs/src/arlad/hpux-subr.c b/usr.sbin/afs/src/arlad/hpux-subr.c index b729b40f654..48747db4b3d 100644 --- a/usr.sbin/afs/src/arlad/hpux-subr.c +++ b/usr.sbin/afs/src/arlad/hpux-subr.c @@ -37,7 +37,7 @@ #define _INCLUDE_HPUX_SOURCE #include "arla_local.h" -RCSID("$KTH: hpux-subr.c,v 1.26 2000/10/14 19:58:07 map Exp $"); +RCSID("$arla: hpux-subr.c,v 1.28 2002/03/06 21:56:59 tol Exp $"); static long blocksize = 1024; /* XXX */ @@ -63,7 +63,7 @@ flushbuf (void *vargs) (((sizeof(struct dirent)+ (strlen((dp)->d_name)+1)) +3) & ~3) #endif -static void +static int write_dirent(VenusFid *fid, const char *name, void *arg) { struct dirent dirent, *real; @@ -86,9 +86,10 @@ write_dirent(VenusFid *fid, const char *name, void *arg) real->d_off = args->off; #endif args->last = real; + return 0; } -Result +int conv_dir (FCacheEntry *e, CredCacheEntry *ce, u_int tokens, fcache_cache_handle *cache_handle, char *cache_name, size_t cache_name_sz) diff --git a/usr.sbin/afs/src/arlad/inter.c b/usr.sbin/afs/src/arlad/inter.c index 48731d72504..9b77b8bc42c 100644 --- a/usr.sbin/afs/src/arlad/inter.c +++ b/usr.sbin/afs/src/arlad/inter.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -36,9 +36,9 @@ */ #include "arla_local.h" -RCSID("$KTH: inter.c,v 1.110.2.3 2001/06/05 01:27:05 ahltorp Exp $") ; +RCSID("$arla: inter.c,v 1.138 2003/01/10 03:05:44 lha Exp $") ; -#include <xfs/xfs_message.h> +#include <nnpfs/nnpfs_message.h> Bool cm_consistencyp = FALSE; @@ -127,11 +127,7 @@ log_operation (const char *fmt, ...) return; va_start (args, fmt); -#ifdef USE_MMAPTIME - mmaptime_gettimeofday (&now, NULL); -#else gettimeofday (&now, NULL); -#endif fprintf (log_fp, "%lu.%lu ", (unsigned long)now.tv_sec, (unsigned long)now.tv_usec); @@ -160,8 +156,7 @@ cm_check_consistency (void) { static unsigned int log_times = 0; static unsigned int file_times = 0; - u_long calc_size; - u_long real_size; + int64_t calc_size, real_size; char newname[MAXPATHLEN]; if (cm_consistencyp == FALSE) @@ -172,8 +167,9 @@ cm_check_consistency (void) if (calc_size != real_size) { log_operation ("consistency check not guaranteed " - "(calc: %d, real: %d), aborting\n", - (int) calc_size, (int) real_size); + "(calc: %d, real: %d, diff %d), aborting\n", + (int) calc_size, (int) real_size, + (int)(calc_size - real_size)); cm_store_state (); abort(); } @@ -195,77 +191,56 @@ cm_check_consistency (void) /* * The interface to the open-routine. - * This means that the file should be in the local cache and that the - * cache manager should recall that some process has this file opened - * for reading and/or writing. - * We do no checking here. Should we? */ -Result -cm_open (VenusFid *fid, - CredCacheEntry **ce, - u_int tokens, - fcache_cache_handle *cache_handle, - char *cache_name, - size_t cache_name_sz) +int +cm_open (FCacheEntry *entry, CredCacheEntry *ce, u_int tokens) { - FCacheEntry *entry; - Result ret; u_long mask; - int error; - - error = fcache_get_data (&entry, fid, ce); - if (error) { - ret.res = -1; - ret.error = error; - return ret; - } + int error = 0; switch(tokens) { - case XFS_DATA_R: - /* case XFS_OPEN_NR: - case XFS_OPEN_SR: */ + case NNPFS_DATA_R: +#if 0 + case NNPFS_OPEN_NR: + case NNPFS_OPEN_SR: +#endif mask = AREAD; break; - case XFS_DATA_W: + case NNPFS_DATA_W: mask = AWRITE; break; - case XFS_OPEN_NW: + case NNPFS_OPEN_NW: mask = AREAD | AWRITE; + tokens |= NNPFS_DATA_R | NNPFS_DATA_W; break; default: arla_warnx (ADEBCM, "cm_open(): unknown token: %d, assuming AREAD", tokens); mask = AREAD; -/* assert(FALSE); */ + tokens |= NNPFS_DATA_R; +#if 0 + assert(FALSE); +#endif } - if (checkright (entry, mask, *ce)) { -#if 0 + if (checkright (entry, mask, ce)) { assert(entry->flags.attrusedp); -#endif entry->flags.datausedp = TRUE; entry->tokens |= tokens; - ret.res = 0; - ret.error = 0; - ret.tokens = entry->tokens; - *cache_handle = entry->handle; - fcache_file_name (entry, cache_name, cache_name_sz); - log_operation ("open (%ld,%lu,%lu,%lu) %u\n", - fid->Cell, - fid->fid.Volume, fid->fid.Vnode, fid->fid.Unique, + entry->fid.Cell, + entry->fid.fid.Volume, + entry->fid.fid.Vnode, + entry->fid.fid.Unique, mask); - } else { - ret.res = -1; - ret.error = EACCES; - } - fcache_release(entry); + } else + error = EACCES; cm_check_consistency(); - return ret; + return error; } /* @@ -273,115 +248,83 @@ cm_open (VenusFid *fid, * back to the server. */ -Result -cm_close (VenusFid fid, int flag, AFSStoreStatus *status, CredCacheEntry* ce) +int +cm_close (FCacheEntry *entry, int flag, + AFSStoreStatus *status, CredCacheEntry* ce) { - FCacheEntry *entry; - Result ret; - int error; + int error = 0; - error = fcache_get (&entry, fid, ce); - if (error) { - ret.res = -1; - ret.error = error; - return ret; - } - - if (flag & XFS_WRITE) { - if (flag & XFS_FSYNC) + if (flag & NNPFS_WRITE) { + if (flag & NNPFS_FSYNC) status->Mask |= SS_FSYNC; error = write_data (entry, status, ce); if (error) { - fcache_release(entry); arla_warn (ADEBCM, error, "writing back file"); - ret.res = -1; - ret.error = error; - return ret; + return error; } } log_operation ("close (%ld,%lu,%lu,%lu) %d\n", - fid.Cell, fid.fid.Volume, fid.fid.Vnode, fid.fid.Unique, - flag); - fcache_release(entry); - ret.res = 0; - ret.error = 0; + entry->fid.Cell, + entry->fid.fid.Volume, + entry->fid.fid.Vnode, + entry->fid.fid.Unique, + flag); cm_check_consistency(); - return ret; + return error; } /* * getattr - read the attributes from this file. */ -Result -cm_getattr (VenusFid fid, - AFSFetchStatus *attr, - VenusFid *realfid, +int +cm_getattr (FCacheEntry *entry, CredCacheEntry *ce, AccessEntry **ae) { - FCacheEntry *entry; - Result ret; - int error; + int error = 0; arla_warnx (ADEBCM, "cm_getattr"); assert (ae); - error = fcache_get (&entry, fid, ce); - if (error) { - ret.res = -1; - ret.error = error; - return ret; - } - AssertExclLocked(&entry->lock); error = fcache_verify_attr (entry, NULL, NULL, ce); - if (error) { - fcache_release(entry); - ret.res = -1; - ret.error = error; - return ret; - } + if (error) + return error; arla_warnx (ADEBCM, "cm_getattr: done get attr"); if (checkright (entry, entry->status.FileType == TYPE_FILE ? AREAD : 0, ce)) { - *attr = entry->status; - ret.res = 0; - ret.error = 0; entry->flags.attrusedp = TRUE; entry->flags.kernelp = TRUE; *ae = entry->acccache; log_operation ("getattr (%ld,%lu,%lu,%lu)\n", - fid.Cell, fid.fid.Volume, fid.fid.Vnode, fid.fid.Unique); + entry->fid.Cell, + entry->fid.fid.Volume, + entry->fid.fid.Vnode, + entry->fid.fid.Unique); } else { *ae = NULL; - ret.res = -1; - ret.error = EACCES; + error = EACCES; } - *realfid = *fcache_realfid (entry); - ret.tokens = entry->tokens; if (!entry->flags.datausedp) - ret.tokens &= ~(XFS_DATA_MASK | XFS_OPEN_MASK); - fcache_release(entry); + entry->tokens &= ~(NNPFS_DATA_MASK | NNPFS_OPEN_MASK); - arla_warnx (ADEBCM, "cm_getattr: return: %d.%d", ret.res, ret.error); + arla_warnx (ADEBCM, "cm_getattr: return: %d", error); cm_check_consistency(); - AssertNotExclLocked(&entry->lock); - - return ret; + return error; } /* @@ -389,136 +332,93 @@ cm_getattr (VenusFid fid, * sent to the FS. */ -Result -cm_setattr (VenusFid fid, AFSStoreStatus *attr, CredCacheEntry* ce) +int +cm_setattr (FCacheEntry *entry, AFSStoreStatus *attr, CredCacheEntry* ce) { - FCacheEntry *entry; - Result ret; - int error; - - error = fcache_get (&entry, fid, ce); - if (error) { - ret.res = -1; - ret.error = error; - return ret; - } + int error = 0; error = fcache_verify_attr (entry, NULL, NULL, ce); - if (error) { - fcache_release(entry); - ret.res = -1; - ret.error = error; - return ret; - } + if (error) + return error; + if (checkright (entry, AWRITE, ce)) { arla_warnx (ADEBCM, "cm_setattr: Writing status"); - ret.res = write_attr (entry, attr, ce); - ret.error = ret.res; + error = write_attr (entry, attr, ce); log_operation ("setattr (%ld,%lu,%lu,%lu)\n", - fid.Cell, fid.fid.Volume, fid.fid.Vnode, fid.fid.Unique); + entry->fid.Cell, + entry->fid.fid.Volume, + entry->fid.fid.Vnode, + entry->fid.fid.Unique); + } else + error = EACCES; - } else { - ret.res = -1; - ret.error = EACCES; - } - fcache_release(entry); cm_check_consistency(); - return ret; + return error; } /* * ftruncate - make the specified file have a specified size */ -Result -cm_ftruncate (VenusFid fid, off_t size, CredCacheEntry* ce) +int +cm_ftruncate (FCacheEntry *entry, off_t size, + AFSStoreStatus *storestatus, CredCacheEntry* ce) { - FCacheEntry *entry; - Result ret; - int error; - - error = fcache_get (&entry, fid, ce); - if (error) { - ret.res = -1; - ret.error = error; - return ret; - } + int error = 0; error = fcache_verify_attr (entry, NULL, NULL, ce); - if (error) { - fcache_release(entry); - ret.res = -1; - ret.error = error; - return ret; - } + if (error) + return error; if (size) { error = fcache_verify_data (entry, ce); - if (error) { - fcache_release (entry); - ret.res = -1; - ret.error = error; - return ret; - } + if (error) + return error; } if (checkright (entry, AWRITE, ce)) { - ret.res = truncate_file (entry, size, ce); - ret.error = ret.res; + error = truncate_file (entry, size, storestatus, ce); log_operation ("ftruncate (%ld,%lu,%lu,%lu) %lu\n", - fid.Cell, fid.fid.Volume, fid.fid.Vnode, fid.fid.Unique, - (unsigned long)size); - } else { - ret.res = -1; - ret.error = EACCES; - } - fcache_release(entry); + entry->fid.Cell, + entry->fid.fid.Volume, + entry->fid.fid.Vnode, + entry->fid.fid.Unique, + (unsigned long)size); + } else + error = EACCES; + cm_check_consistency(); - return ret; + return error; } /* * access - check if user is allowed to perform operation. */ -Result -cm_access (VenusFid fid, int mode, CredCacheEntry* ce) +int +cm_access (FCacheEntry *entry, int mode, CredCacheEntry* ce) { - FCacheEntry *entry; - Result ret; - int error; - - error = fcache_get (&entry, fid, ce); - if (error) { - ret.res = -1; - ret.error = error; - return ret; - } + int error = 0; error = fcache_verify_attr (entry, NULL, NULL, ce); - if (error) { - fcache_release(entry); - ret.res = -1; - ret.error = error; - return ret; - } + if (error) + return error; - if (checkright (entry, AWRITE, ce)) { - ret.res = 0; /**/ - ret.error = 0; - } else { - ret.res = -1; - ret.error = EACCES; - } + if (checkright (entry, AWRITE, ce)) + error = 0; + else + error = EACCES; log_operation ("access (%ld,%lu,%lu,%lu)\n", - fid.Cell, fid.fid.Volume, fid.fid.Vnode, fid.fid.Unique); + entry->fid.Cell, + entry->fid.fid.Volume, + entry->fid.fid.Vnode, + entry->fid.fid.Unique); - fcache_release(entry); cm_check_consistency(); - return ret; + return error; } /* @@ -569,46 +469,40 @@ expand_sys (char *dest, size_t dst_sz, const char *src, * about mount points (which are followed iff follow_mount_point). */ -Result -cm_lookup (VenusFid *dir_fid, +int +cm_lookup (FCacheEntry **entry, const char *name, VenusFid *res, CredCacheEntry** ce, int follow_mount_point) { char tmp_name[MAXPATHLEN]; - FCacheEntry *entry; - Result ret; - int error; + int error = 0; + + error = fcache_get_data(entry, ce, 0); + if (error) + return error; if (strstr (name, "@sys") != NULL) { - if (expand_sys (tmp_name, sizeof(tmp_name), name, - "@sys", arlasysname) >= sizeof(tmp_name)) { - ret.res = -1; - ret.error = ENAMETOOLONG; - return ret; + int i; + + for (i = 0; i < sysnamenum; i++) { + int size = expand_sys (tmp_name, sizeof(tmp_name), name, + "@sys", sysnamelist[i]); + if (size >= sizeof(tmp_name)) + continue; + error = adir_lookup (*entry, tmp_name, res); + if (error == 0) + break; } - name = tmp_name; - } - - error = fcache_get_data(&entry, dir_fid, ce); - if (error) { - ret.res = -1; - ret.error = error; - return ret; - } + if (i == sysnamenum) + error = ENOENT; - error = adir_lookup (entry, name, res); - if (error) { - fcache_release(entry); - ret.res = -1; - ret.error = error; - return ret; - } + } else + error = adir_lookup (*entry, name, res); - ret.res = 0; - ret.error = 0; - ret.tokens = 0; + if (error) + return error; /* * The ".." at the top of a volume just points to the volume root, @@ -620,178 +514,127 @@ cm_lookup (VenusFid *dir_fid, if (strcmp(".", name) == 0) { - error = fcache_verify_attr (entry, NULL, NULL, *ce); - if (error) { - ret.res = -1; - ret.error = error; + error = fcache_verify_attr (*entry, NULL, NULL, *ce); + if (error) goto out; - } - *res = *dir_fid; - ret.tokens = entry->tokens; - } else if ((strcmp("..", name) == 0 && VenusFid_cmp(dir_fid, res) == 0)) { + *res = (*entry)->fid; + } else if (strcmp("..", name) == 0 + && VenusFid_cmp(&(*entry)->fid, res) == 0) { - error = fcache_verify_attr (entry, NULL, NULL, *ce); - if (error) { - ret.res = -1; - ret.error = error; + error = fcache_verify_attr (*entry, NULL, NULL, *ce); + if (error) goto out; - } - *res = entry->volume->parent_fid; /* entry->parent */ - ret.tokens = entry->tokens; + *res = (*entry)->volume->parent_fid; /* entry->parent */ } else if (follow_mount_point) { - error = followmountpoint (res, dir_fid, entry, ce); - if (error) { - ret.res = -1; - ret.error = error; + error = followmountpoint (res, &(*entry)->fid, *entry, ce); + if (error) goto out; - } } out: - fcache_release(entry); - log_operation ("lookup (%ld,%lu,%lu,%lu) %s\n", - dir_fid->Cell, - dir_fid->fid.Volume, - dir_fid->fid.Vnode, - dir_fid->fid.Unique, + (*entry)->fid.Cell, + (*entry)->fid.fid.Volume, + (*entry)->fid.fid.Vnode, + (*entry)->fid.fid.Unique, name); cm_check_consistency(); - return ret; + return error; } /* * Create this file and more. */ -Result -cm_create (VenusFid *dir_fid, const char *name, AFSStoreStatus *store_attr, +int +cm_create (FCacheEntry **dir, const char *name, AFSStoreStatus *store_attr, VenusFid *res, AFSFetchStatus *fetch_attr, CredCacheEntry **ce) { - FCacheEntry *dire; - Result ret; - int error; + int error = 0; - error = fcache_get_data (&dire, dir_fid, ce); - if (error) { - ret.res = -1; - ret.error = error; - return ret; - } + error = fcache_get_data (dir, ce, 0); + if (error) + return error; + + if (checkright (*dir, AINSERT, *ce)) { + error = create_file (*dir, name, store_attr, + res, fetch_attr, *ce); + if (error == 0) + error = adir_creat (*dir, name, res->fid); + } else + error = EACCES; - if (checkright (dire, AINSERT, *ce)) { - error = create_file (dire, name, store_attr, - res, fetch_attr, *ce); - if (error) { - ret.res = -1; - ret.error = error; - } else { - error = adir_creat (dire, name, res->fid); - if (error) { - ret.res = -1; - ret.error = error; - } else { - ret.res = 0; - ret.error = 0; - } - } - } else { - ret.res = -1; - ret.error = EACCES; - } log_operation ("create (%ld,%lu,%lu,%lu) %s\n", - dir_fid->Cell, - dir_fid->fid.Volume, dir_fid->fid.Vnode, dir_fid->fid.Unique, - name); + (*dir)->fid.Cell, + (*dir)->fid.fid.Volume, + (*dir)->fid.fid.Vnode, + (*dir)->fid.fid.Unique, + name); - fcache_release(dire); cm_check_consistency(); - return ret; + return error; } /* * Create a new directory */ -Result -cm_mkdir (VenusFid *dir_fid, const char *name, +int +cm_mkdir (FCacheEntry **dir, const char *name, AFSStoreStatus *store_attr, VenusFid *res, AFSFetchStatus *fetch_attr, CredCacheEntry **ce) { - FCacheEntry *dire; - Result ret; - int error; + int error = 0; - error = fcache_get_data (&dire, dir_fid, ce); - if (error) { - ret.res = -1; - ret.error = error; - return ret; - } + error = fcache_get_data (dir, ce, 0); + if (error) + return error; - if (checkright (dire, AINSERT, *ce)) { - error = create_directory (dire, name, store_attr, - res, fetch_attr, *ce); - if (error) { - ret.res = -1; - ret.error = error; - } else { - error = adir_creat (dire, name, res->fid); - if (error) { - ret.res = -1; - ret.error = error; - } else { - ret.res = 0; - ret.error = 0; - } - } - } else { - ret.res = -1; - ret.error = EACCES; - } + if (checkright (*dir, AINSERT, *ce)) { + error = create_directory (*dir, name, store_attr, + res, fetch_attr, *ce); + if (error == 0) + error = adir_creat (*dir, name, res->fid); + + } else + error = EACCES; log_operation ("mkdir (%ld,%lu,%lu,%lu) %s\n", - dir_fid->Cell, - dir_fid->fid.Volume, - dir_fid->fid.Vnode, - dir_fid->fid.Unique, + (*dir)->fid.Cell, + (*dir)->fid.fid.Volume, + (*dir)->fid.fid.Vnode, + (*dir)->fid.fid.Unique, name); - ReleaseWriteLock (&dire->lock); cm_check_consistency(); - return ret; + return error; } /* * Create a symlink */ -Result -cm_symlink (VenusFid *dir_fid, +int +cm_symlink (FCacheEntry **dir, const char *name, AFSStoreStatus *store_attr, VenusFid *res, VenusFid *realfid, AFSFetchStatus *fetch_attr, const char *contents, CredCacheEntry **ce) { - FCacheEntry *dire, *symlink_entry; - Result ret; - int error; + FCacheEntry *symlink_entry; + int error = 0; - error = fcache_get_data (&dire, dir_fid, ce); - if (error) { - ret.res = -1; - ret.error = error; - return ret; - } + error = fcache_get_data (dir, ce, 0); + if (error) + return error; - if (!checkright (dire, AINSERT, *ce)) { - ret.res = -1; - ret.error = EACCES; + if (!checkright (*dir, AINSERT, *ce)) { + error = EACCES; goto out; } @@ -804,48 +647,34 @@ cm_symlink (VenusFid *dir_fid, && store_attr->UnixModeBits == 0644) store_attr->UnixModeBits = 0755; - error = create_symlink (dire, name, store_attr, + error = create_symlink (*dir, name, store_attr, res, fetch_attr, contents, *ce); - if (error) { - ret.res = -1; - ret.error = error; + if (error) goto out; - } - error = adir_creat (dire, name, res->fid); - if (error) { - ret.res = -1; - ret.error = error; + error = adir_creat (*dir, name, res->fid); + if (error) goto out; - } - error = followmountpoint(res, dir_fid, NULL, ce); - if (error) { - ret.res = -1; - ret.error = error; + error = followmountpoint(res, &(*dir)->fid, NULL, ce); + if (error) goto out; - } /* * If the new symlink is a mountpoint and it points * to dir_fid we will deadlock if we look it up. */ - if (VenusFid_cmp (res, dir_fid) != 0) { + if (VenusFid_cmp (res, &(*dir)->fid) != 0) { error = fcache_get (&symlink_entry, *res, *ce); - if (error) { - ret.res = -1; - ret.error = error; + if (error) goto out; - } - error = fcache_verify_attr (symlink_entry, NULL, NULL, *ce); + error = fcache_verify_attr (symlink_entry, *dir, name, *ce); if (error) { fcache_release (symlink_entry); - ret.res = -1; - ret.error = error; goto out; } @@ -856,174 +685,132 @@ cm_symlink (VenusFid *dir_fid, fcache_release (symlink_entry); } else { - *fetch_attr = dire->status; - *realfid = *fcache_realfid (dire); + *fetch_attr = (*dir)->status; + *realfid = *fcache_realfid (*dir); } - ret.res = 0; - ret.error = 0; - log_operation ("symlink (%ld,%lu,%lu,%lu) %s %s\n", - dir_fid->Cell, - dir_fid->fid.Volume, - dir_fid->fid.Vnode, - dir_fid->fid.Unique, + (*dir)->fid.Cell, + (*dir)->fid.fid.Volume, + (*dir)->fid.fid.Vnode, + (*dir)->fid.fid.Unique, name, contents); out: - fcache_release(dire); cm_check_consistency(); - return ret; + return error; } /* * Create a hard link. */ -Result -cm_link (VenusFid *dir_fid, +int +cm_link (FCacheEntry **dir, const char *name, VenusFid existing_fid, AFSFetchStatus *existing_status, CredCacheEntry **ce) { - FCacheEntry *dire, *file; - Result ret; - int error; + FCacheEntry *file; + int error = 0; - error = fcache_get_data (&dire, dir_fid, ce); - if (error) { - ret.res = -1; - ret.error = error; - return ret; - } + error = fcache_get_data (dir, ce, 0); + if (error) + return error; error = fcache_get (&file, existing_fid, *ce); - if (error) { - fcache_release(dire); - ret.res = -1; - ret.error = error; - return ret; - } + if (error) + return error; - error = fcache_verify_attr (file, NULL, NULL, *ce); - if (error) { - ret.res = -1; - ret.error = error; + error = fcache_verify_attr (file, *dir, NULL, *ce); + if (error) goto out; - } - if (checkright (dire, AINSERT, *ce)) { - error = create_link (dire, name, file, *ce); - if (error) { - ret.res = -1; - ret.error = error; - } else { - error = adir_creat (dire, name, existing_fid.fid); - if (error) { - ret.res = -1; - ret.error = error; - } else { - *existing_status = file->status; - ret.res = 0; - ret.error = 0; - } - } - } else { - ret.res = -1; - ret.error = EACCES; - } + if (checkright (*dir, AINSERT, *ce)) { + error = create_link (*dir, name, file, *ce); + if (error == 0) { + error = adir_creat (*dir, name, existing_fid.fid); + if (error == 0) + *existing_status = file->status; + } + } else + error = EACCES; + log_operation ("link (%ld,%lu,%lu,%lu) (%ld,%lu,%lu,%lu) %s\n", - dir_fid->Cell, - dir_fid->fid.Volume, dir_fid->fid.Vnode, dir_fid->fid.Unique, - existing_fid.Cell, - existing_fid.fid.Volume, - existing_fid.fid.Vnode, - existing_fid.fid.Unique, - name); + (*dir)->fid.Cell, + (*dir)->fid.fid.Volume, + (*dir)->fid.fid.Vnode, + (*dir)->fid.fid.Unique, + existing_fid.Cell, + existing_fid.fid.Volume, + existing_fid.fid.Vnode, + existing_fid.fid.Unique, + name); out: - fcache_release(dire); fcache_release(file); cm_check_consistency(); - return ret; + return error; } /* * generic function for both remove and rmdir */ -static Result -sub_remove (VenusFid *dir_fid, const char *name, CredCacheEntry **ce, +static int +sub_remove (FCacheEntry **dir, const char *name, CredCacheEntry **ce, const char *operation, int (*func)(FCacheEntry *fe, const char *name, CredCacheEntry *ce)) { - FCacheEntry *dire; - Result ret; - int error; - - error = fcache_get_data (&dire, dir_fid, ce); - if (error) { - ret.res = -1; - ret.error = error; - return ret; - } - - if (checkright (dire, ADELETE, *ce)) { - error = (*func) (dire, name, *ce); - if (error) { - ret.res = -1; - ret.error = error; - } else { - error = adir_remove (dire, name); - if (error) { - ret.res = -1; - ret.error = error; - } else { - ret.res = 0; - ret.error = 0; - } - } - } else { - ret.res = -1; - ret.error = EACCES; - } + int error = 0; + + error = fcache_get_data (dir, ce, 0); + if (error) + return error; + + if (checkright (*dir, ADELETE, *ce)) { + error = (*func) (*dir, name, *ce); + if (error == 0) + error = adir_remove (*dir, name); + } else + error = EACCES; + log_operation ("%s (%ld,%lu,%lu,%lu) %s\n", operation, - dir_fid->Cell, - dir_fid->fid.Volume, - dir_fid->fid.Vnode, - dir_fid->fid.Unique, + (*dir)->fid.Cell, + (*dir)->fid.fid.Volume, + (*dir)->fid.fid.Vnode, + (*dir)->fid.fid.Unique, name); - fcache_release(dire); cm_check_consistency(); - return ret; + return error; } /* - * Remove the file named `name' in the directory `dir_fid'. + * Remove the file named `name' in the directory `dir'. */ -Result -cm_remove(VenusFid *dir_fid, +int +cm_remove(FCacheEntry **dir, const char *name, CredCacheEntry **ce) { - return sub_remove (dir_fid, name, ce, "remove", remove_file); + return sub_remove (dir, name, ce, "remove", remove_file); } /* - * Remove the directory named `name' in the directory `dir_fid'. + * Remove the directory named `name' in the directory `dir'. */ -Result -cm_rmdir(VenusFid *dir_fid, +int +cm_rmdir(FCacheEntry **dir, const char *name, CredCacheEntry **ce) { - return sub_remove (dir_fid, name, ce, "rmdir", remove_directory); + return sub_remove (dir, name, ce, "rmdir", remove_directory); } /* @@ -1036,11 +823,11 @@ potential_update_dir(FCacheEntry *child_entry, const VenusFid *new_parent_fid, FCacheEntry *parent_entry, int *update_child, - CredCacheEntry *ce) + CredCacheEntry **ce) { int error; - error = fcache_verify_attr (child_entry, parent_entry, NULL, ce); + error = fcache_verify_attr (child_entry, parent_entry, NULL, *ce); if (error) return error; @@ -1052,7 +839,7 @@ potential_update_dir(FCacheEntry *child_entry, int fd; fbuf the_fbuf; - error = fcache_verify_data (child_entry, ce); /* XXX - check fake_mp */ + error = fcache_get_data(&child_entry, ce, 0); /* XXX - check fake_mp */ if (error) return error; @@ -1078,137 +865,241 @@ potential_update_dir(FCacheEntry *child_entry, * set child_fid to the fid of the moved object. */ -Result -cm_rename(VenusFid *old_parent_fid, const char *old_name, - VenusFid *new_parent_fid, const char *new_name, +int +cm_rename(FCacheEntry **old_dir, const char *old_name, + FCacheEntry **new_dir, const char *new_name, VenusFid *child_fid, int *update_child, CredCacheEntry **ce) { - FCacheEntry *old_dir; - FCacheEntry *new_dir; - Result ret; - int error; - int diff_dir; - + int error = 0; + VenusFid new_fid, old_fid; + *update_child = 0; /* old parent dir */ - error = fcache_get_data (&old_dir, old_parent_fid, ce); - if (error) { - ret.res = -1; - ret.error = error; - return ret; + error = fcache_get_data (old_dir, ce, 0); + if (error) + return error; + + /* new parent dir */ + + error = fcache_get_data (new_dir, ce, 0); + if (error) + return error; + + if (!checkright (*old_dir, ADELETE, *ce) + || !checkright (*new_dir, AINSERT, *ce)) { + error = EACCES; + goto out; } + + error = rename_file (*old_dir, old_name, *new_dir, new_name, *ce); + if (error) + goto out; - diff_dir = VenusFid_cmp (old_parent_fid, new_parent_fid); + /* + * Lookup the old name (to get the fid of the new name) + */ + + error = adir_lookup (*old_dir, old_name, &new_fid); + + if (error) + goto out; + + *child_fid = new_fid; + + if (VenusFid_cmp (&(*old_dir)->fid, &(*new_dir)->fid)) { + FCacheEntry *child_entry; + + error = fcache_get (&child_entry, *child_fid, *ce); + if (error) + goto out; + + child_entry->parent = (*new_dir)->fid; + + error = potential_update_dir (child_entry, &(*new_dir)->fid, + *new_dir, update_child, ce); + fcache_release (child_entry); + if (error) + goto out; + } + + /* + * Lookup the new name, if it exists we need to silly + * rename it was just killed on the fileserver. + * XXXDISCO remember mark this node as dead + */ - /* new parent dir */ + error = adir_lookup (*new_dir, new_name, &old_fid); + if (error == 0) { + FCacheEntry *old_entry; - if (diff_dir) { - error = fcache_get_data (&new_dir, new_parent_fid, ce); - if (error) { - fcache_release(old_dir); - ret.res = -1; - ret.error = error; - return ret; + error = fcache_find (&old_entry, old_fid); + if (error == 0) { + old_entry->flags.silly = TRUE; + fcache_release (old_entry); } - } else { - new_dir = old_dir; + adir_remove (*new_dir, new_name); } + + /* + * Now do the rename, ie create the new name and remove + * the old name. + */ + + error = adir_creat (*new_dir, new_name, new_fid.fid) + || adir_remove (*old_dir, old_name); + + log_operation ("rename (%ld,%lu,%lu,%lu) (%ld,%lu,%lu,%lu) %s %s\n", + (*old_dir)->fid.Cell, + (*old_dir)->fid.fid.Volume, + (*old_dir)->fid.fid.Vnode, + (*old_dir)->fid.fid.Unique, + (*new_dir)->fid.Cell, + (*new_dir)->fid.fid.Volume, + (*new_dir)->fid.fid.Vnode, + (*new_dir)->fid.fid.Unique, + old_name, new_name); + + out: + cm_check_consistency(); + return error; +} - if (checkright (old_dir, ADELETE, *ce) - && checkright (new_dir, AINSERT, *ce)) { +/* + * An emulation of kernel lookup, convert (fid, name) into + * (res). Strips away leading /afs, removes double slashes, + * and resolves symlinks. + * Return 0 for success, otherwise -1. + */ + +int +cm_walk (VenusFid fid, + const char *name, + VenusFid *res) +{ + VenusFid cwd = fid; + char *base; + VenusFid file; + FCacheEntry *entry; + FCacheEntry *dentry; + int error; + char symlink[MAXPATHLEN]; + char store_name[MAXPATHLEN]; + char *fname; + CredCacheEntry *ce; + + ce = cred_get (fid.Cell, getuid(), CRED_ANY); + + strlcpy(store_name, name, sizeof(store_name)); + fname = store_name; + + do { + /* set things up so that fname points to the remainder of the path, + * whereas base points to the whatever preceeds the first / + */ + base = fname; + fname = strchr(fname, '/'); + if (fname) { + /* deal with repeated adjacent / chars by eliminating the + * duplicates. + */ + while (*fname == '/') { + *fname = '\0'; + fname++; + } + } - error = rename_file (old_dir, old_name, new_dir, new_name, *ce); - if (error) { - ret.res = -1; - ret.error = error; - } else { - VenusFid new_fid, old_fid; - - /* - * Lookup the old name (to get the fid of the new name) - */ - - error = adir_lookup (old_dir, old_name, &new_fid); - + /* deal with absolute pathnames first. */ + if (*base == '\0') { + error = getroot(&cwd, ce); if (error) { - ret.res = -1; - ret.error = error; - goto out; + arla_warn(ADEBWARN, error, "getroot"); + cred_free(ce); + return -1; } - *child_fid = new_fid; - - if (diff_dir) { - FCacheEntry *child_entry; - - error = fcache_get (&child_entry, *child_fid, *ce); - if (error) { - ret.res = -1; - ret.error = error; - goto out; - } - - child_entry->parent = *new_parent_fid; - - error = potential_update_dir (child_entry, new_parent_fid, - new_dir, update_child, *ce); - fcache_release (child_entry); - if (error) { - ret.res = -1; - ret.error = error; - goto out; - } + if (fname) { + if (strncmp("afs",fname,3) == 0) { + fname += 3; + } + continue; + } else { + break; } + } + error = fcache_get(&dentry, cwd, ce); + if (error) { + arla_warn (ADEBWARN, error, "fcache_get"); + cred_free(ce); + return -1; + } + error = cm_lookup (&dentry, base, &file, &ce, TRUE); + if (error) { + fcache_release(dentry); + arla_warn (ADEBWARN, error, "lookup(%s)", base); + cred_free(ce); + return -1; + } + fcache_release(dentry); + error = fcache_get(&entry, file, ce); + if (error) { + arla_warn (ADEBWARN, error, "fcache_get"); + cred_free(ce); + return -1; + } + + error = fcache_get_data (&entry, &ce, 0); + if (error) { + fcache_release(entry); + arla_warn (ADEBWARN, error, "fcache_get_data"); + cred_free(ce); + return -1; + } + + /* handle symlinks here */ + if (entry->status.FileType == TYPE_LINK) { + int len; + int fd; - /* - * Lookup the new name, if it exists we need to clear it out. - * XXX Should we check the lnkcount and clear it from fcache ? - */ - - error = adir_lookup (new_dir, new_name, &old_fid); - if (error == 0) - adir_remove (new_dir, new_name); - - /* - * Now do the rename, ie create the new name and remove - * the old name. + fd = fcache_open_file (entry, O_RDONLY); + /* read the symlink and null-terminate it */ + if (fd < 0) { + fcache_release(entry); + arla_warn (ADEBWARN, errno, "fcache_open_file"); + cred_free(ce); + return -1; + } + len = read (fd, symlink, sizeof(symlink)); + close (fd); + if (len <= 0) { + fcache_release(entry); + arla_warnx (ADEBWARN, "cannot read symlink"); + cred_free(ce); + return -1; + } + symlink[len] = '\0'; + /* if we're not at the end (i.e. fname is not null), take + * the expansion of the symlink and append fname to it. */ - - error = adir_creat (new_dir, new_name, new_fid.fid) - || adir_remove (old_dir, old_name); - - if (error) { - ret.res = -1; - ret.error = error; - } else { - ret.res = 0; - ret.error = 0; + if (fname != NULL) { + strcat (symlink, "/"); + strcat (symlink, fname); } + strlcpy(store_name, symlink, sizeof(store_name)); + fname = store_name; + } else { + /* if not a symlink, just update cwd */ + cwd = entry->fid; } - } else { - ret.res = -1; - ret.error = EACCES; - } - - log_operation ("rename (%ld,%lu,%lu,%lu) (%ld,%lu,%lu,%lu) %s %s\n", - old_parent_fid->Cell, - old_parent_fid->fid.Volume, - old_parent_fid->fid.Vnode, - old_parent_fid->fid.Unique, - new_parent_fid->Cell, - new_parent_fid->fid.Volume, - new_parent_fid->fid.Vnode, - new_parent_fid->fid.Unique, - old_name, new_name); - - out: - fcache_release(old_dir); - if (diff_dir) - fcache_release(new_dir); - cm_check_consistency(); - return ret; + fcache_release(entry); + + /* the *fname condition below deals with a trailing / in a + * path-name */ + } while (fname != NULL && *fname); + *res = cwd; + cred_free(ce); + return 0; } diff --git a/usr.sbin/afs/src/arlad/inter.h b/usr.sbin/afs/src/arlad/inter.h index a0a209b5ea3..e5ba3e60aa8 100644 --- a/usr.sbin/afs/src/arlad/inter.h +++ b/usr.sbin/afs/src/arlad/inter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -35,92 +35,85 @@ * The interface to the cache manager. */ -/* $KTH: inter.h,v 1.24 2000/11/28 01:42:15 lha Exp $ */ +/* $arla: inter.h,v 1.36 2003/01/09 16:40:10 lha Exp $ */ #ifndef _INTER_H_ #define _INTER_H_ #include <cred.h> -/* - * This is the return value of all these operations. - * Iff res == -1, the error reason should be errno. - */ - -typedef struct { - int res; /* result */ - int error; /* error if res == -1 */ - u_int tokens; /* resulting tokens (if res == 0) */ -} Result; - void cm_init (void); void cm_store_state (void); -Result -cm_open (VenusFid *fid, CredCacheEntry **ce, u_int tokens, - fcache_cache_handle *, char *, size_t); +int +cm_open (FCacheEntry *entry, CredCacheEntry *ce, u_int tokens); -Result -cm_close (VenusFid fid, int flag, AFSStoreStatus *, CredCacheEntry *ce); +int +cm_close (FCacheEntry *entry, int flag, AFSStoreStatus *status, + CredCacheEntry* ce); -Result -cm_getattr (VenusFid fid, - AFSFetchStatus *attr, - VenusFid *real_fid, +int +cm_getattr (FCacheEntry *entry, CredCacheEntry *ce, AccessEntry **ae); -Result -cm_setattr (VenusFid fid, AFSStoreStatus *attr, CredCacheEntry *ce); +int +cm_setattr (FCacheEntry *entry, AFSStoreStatus *attr, CredCacheEntry *ce); -Result -cm_ftruncate (VenusFid fid, off_t size, CredCacheEntry *ce); +int +cm_ftruncate (FCacheEntry *entry, off_t size, + AFSStoreStatus *storeattr, CredCacheEntry *ce); -Result -cm_access (VenusFid fid, int mode, CredCacheEntry *ce); +int +cm_access (FCacheEntry *entry, int mode, CredCacheEntry *ce); -Result -cm_lookup (VenusFid *dir_fid, const char *name, VenusFid *res, +int +cm_lookup (FCacheEntry **entry, const char *name, VenusFid *res, CredCacheEntry **ce, int follow_mount_point); -Result -cm_create (VenusFid *dir_fid, const char *name, AFSStoreStatus *store_attr, +int +cm_create (FCacheEntry **dir, const char *name, AFSStoreStatus *store_attr, VenusFid *res, AFSFetchStatus *fetch_attr, CredCacheEntry **ce); -Result -cm_mkdir (VenusFid *dir_fid, const char *name, AFSStoreStatus *store_attr, +int +cm_mkdir (FCacheEntry **dir, const char *name, AFSStoreStatus *store_attr, VenusFid *res, AFSFetchStatus *fetch_attr, CredCacheEntry **ce); -Result -cm_remove (VenusFid *dir_fid, const char *name, CredCacheEntry **ce); +int +cm_remove (FCacheEntry **dir, const char *name, CredCacheEntry **ce); -Result -cm_rmdir (VenusFid *dir_fid, const char *name, CredCacheEntry **ce); +int +cm_rmdir (FCacheEntry **dir, const char *name, CredCacheEntry **ce); -Result -cm_link (VenusFid *dir_fid, const char *name, +int +cm_link (FCacheEntry **dir, const char *name, VenusFid existing_fid, AFSFetchStatus *existing_status, CredCacheEntry **ce); -Result -cm_symlink (VenusFid *dir_fid, const char *name, +int +cm_symlink (FCacheEntry **dir, const char *name, AFSStoreStatus *store_attr, VenusFid *res, VenusFid *real_fid, AFSFetchStatus *fetch_attr, const char *contents, CredCacheEntry **ce); -Result -cm_rename(VenusFid *old_parent_fid, const char *old_name, - VenusFid *new_parent_fid, const char *new_name, +int +cm_rename(FCacheEntry **old_dir, const char *old_name, + FCacheEntry **new_dir, const char *new_name, VenusFid *child_fid, int *update_child, CredCacheEntry **ce); +int +cm_walk (VenusFid fid, + const char *name, + VenusFid *res); + void cm_check_consistency (void); diff --git a/usr.sbin/afs/src/arlad/irix-subr.c b/usr.sbin/afs/src/arlad/irix-subr.c index 7fdd9a55803..b967eeae48f 100644 --- a/usr.sbin/afs/src/arlad/irix-subr.c +++ b/usr.sbin/afs/src/arlad/irix-subr.c @@ -33,7 +33,7 @@ #define _KERNEL #include "arla_local.h" -RCSID("$KTH: irix-subr.c,v 1.25 2000/10/14 19:58:09 map Exp $"); +RCSID("$arla: irix-subr.c,v 1.27 2002/03/06 21:57:00 tol Exp $"); static long blocksize = 1024; /* XXX */ @@ -52,7 +52,7 @@ flushbuf (void *vargs) args->last = NULL; } -static void +static int write_dirent(VenusFid *fid, const char *name, void *arg) { struct dirent64 dirent, *real; @@ -72,9 +72,10 @@ write_dirent(VenusFid *fid, const char *name, void *arg) args->off += real->d_reclen; real->d_off = args->off; args->last = real; + return 0; } -Result +int conv_dir (FCacheEntry *e, CredCacheEntry *ce, u_int tokens, fcache_cache_handle *cache_handle, char *cache_name, size_t cache_name_sz) diff --git a/usr.sbin/afs/src/arlad/kernel.c b/usr.sbin/afs/src/arlad/kernel.c index fd0e7b886b9..ca547cd0908 100644 --- a/usr.sbin/afs/src/arlad/kernel.c +++ b/usr.sbin/afs/src/arlad/kernel.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -32,7 +32,7 @@ */ #include "arla_local.h" -RCSID("$KTH: kernel.c,v 1.27.2.1 2001/03/12 12:22:41 lha Exp $"); +RCSID("$arla: kernel.c,v 1.35 2003/01/10 17:33:44 tol Exp $"); /* * The fd we use to talk with the kernel on. @@ -74,24 +74,24 @@ kernel_usedworkers(void) static int process_message (int msg_length, char *msg) { - struct xfs_message_header *header; - char *p; - int cnt; - - cnt = 0; - for (p = msg; - msg_length > 0; - p += header->size, msg_length -= header->size) { - header = (struct xfs_message_header *)p; - xfs_message_receive (kernel_fd, header, header->size); - ++cnt; - } - if (cnt < sizeof(recv_count)/sizeof(recv_count[0])) - ++recv_count[cnt]; - else - ++recv_count_overflow; + struct nnpfs_message_header *header; + char *p; + int cnt; + + cnt = 0; + for (p = msg; + msg_length > 0; + p += header->size, msg_length -= header->size) { + header = (struct nnpfs_message_header *)p; + nnpfs_message_receive (kernel_fd, header, header->size); + ++cnt; + } + if (cnt < sizeof(recv_count)/sizeof(recv_count[0])) + ++recv_count[cnt]; + else + ++recv_count_overflow; - return 0; + return 0; } /* no threads available to handle messages */ @@ -103,6 +103,7 @@ static int overload = FALSE; */ struct worker { + char name[10]; char data[MAX_XMSG_SIZE]; PROCESS pid; int msg_length; @@ -135,7 +136,7 @@ PROCESS version_pid; static void version_thread (void *foo) { - xfs_probe_version (kernel_fd, XFS_VERSION); + nnpfs_probe_version (kernel_fd, NNPFS_VERSION); } /* @@ -163,14 +164,14 @@ tcp_open (const char *filename) } addr.sin_family = AF_INET; - addr.sin_addr.s_addr = 0x7f000001; /* 127.0.0.1 */ + addr.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */ addr.sin_port = htons(port); ret = connect (s, (struct sockaddr *)&addr, sizeof(addr)); if (ret < 0) { arla_warn (ADEBWARN, errno, "tcp_open: connect failed"); - return ret; + return s; } - return ret; + return s; } static int @@ -195,7 +196,7 @@ tcp_read (int fd, void *data, size_t len) slen = ntohl(slen); if (len < slen) { arla_warnx (ADEBWARN, - "tcp_read: recv a too large messsage %d", + "tcp_read: recv a too large message %d", slen); return -1; } @@ -205,14 +206,23 @@ tcp_read (int fd, void *data, size_t len) static ssize_t tcp_write (int fd, const void *data, size_t len) { + int ret; int32_t slen = htonl(len); char out_len[4]; + memcpy (out_len, &slen, sizeof(len)); if (send (fd, out_len, sizeof(len), 0) != sizeof(out_len)) { arla_warn (ADEBWARN, errno, "tcp_write: failed to write length"); return -1; } - return send (fd, data, len, 0) == len ? len : -1; + ret = send (fd, data, len, 0); + if (ret != len) { + arla_warn (ADEBWARN, errno, "tcp_write: failed to write msg (%d)", + ret); + return -1; + } + + return ret; } /* @@ -272,7 +282,7 @@ null_write (int fd, const void *msg, size_t len) */ struct kern_interface { - char *prefix; + const char *prefix; int (*open) (const char *filename); ssize_t (*read) (int fd, void *msg, size_t len); ssize_t (*write) (int fd, const void *msg, size_t len); @@ -347,68 +357,70 @@ kernel_opendevice (const char *dev) void kernel_interface (struct kernel_args *args) { - int i; + int i; - assert (kernel_fd >= 0); + assert (kernel_fd >= 0); - workers = malloc (sizeof(*workers) * args->num_workers); - if (workers == NULL) - arla_err (1, ADEBERROR, errno, "malloc %lu failed", - (unsigned long)sizeof(*workers) * args->num_workers); + workers = malloc (sizeof(*workers) * args->num_workers); + if (workers == NULL) + arla_err (1, ADEBERROR, errno, "malloc %lu failed", + (unsigned long)sizeof(*workers) * args->num_workers); - workers_high = args->num_workers; - workers_used = 0; + workers_high = args->num_workers; + workers_used = 0; for (i = 0; i < args->num_workers; ++i) { - workers[i].busyp = 0; - workers[i].number = i; - if (LWP_CreateProcess (sub_thread, WORKER_STACKSIZE, 1, - (char *)&workers[i], - "worker", &workers[i].pid)) - arla_errx (1, ADEBERROR, "CreateProcess of worker failed"); - } - - if (LWP_CreateProcess (version_thread, WORKER_STACKSIZE, 1, - NULL, - "version", &version_pid)) - arla_errx (1, ADEBERROR, "CreateProcess of version thread failed"); - - arla_warnx(ADEBKERNEL, "Arla: selecting on fd: %d", kernel_fd); - - for (;;) { - fd_set readset; - int ret; + workers[i].busyp = 0; + workers[i].number = i; + snprintf(workers[i].name, sizeof(workers[i].name), "worker %d", i); + + if (LWP_CreateProcess (sub_thread, WORKER_STACKSIZE, 1, + (char *)&workers[i], + workers[i].name, &workers[i].pid)) + arla_errx (1, ADEBERROR, "CreateProcess of worker failed"); + } + + if (LWP_CreateProcess (version_thread, WORKER_STACKSIZE, 1, + NULL, + "version", &version_pid)) + arla_errx (1, ADEBERROR, "CreateProcess of version thread failed"); + + arla_warnx(ADEBKERNEL, "Arla: selecting on fd: %d", kernel_fd); + + for (;;) { + fd_set readset; + int ret; - FD_ZERO(&readset); - FD_SET(kernel_fd, &readset); - - ret = IOMGR_Select (kernel_fd + 1, &readset, NULL, NULL, NULL); - - if (ret < 0) - arla_warn (ADEBKERNEL, errno, "select"); - else if (ret == 0) - arla_warnx (ADEBKERNEL, - "Arla: select returned with 0. strange."); - else if (FD_ISSET(kernel_fd, &readset)) { - for (i = 0; i < args->num_workers; ++i) { - if (workers[i].busyp == 0) { - ret = kern_read (kernel_fd, workers[i].data, - sizeof(workers[i].data)); - if (ret <= 0) { - arla_warn (ADEBWARN, errno, "read"); - } else { - workers[i].msg_length = ret; - LWP_SignalProcess (&workers[i]); - } - break; - } - } - if (i == args->num_workers) { - arla_warnx (ADEBWARN, "kernel: all %u workers busy", - args->num_workers); - overload = TRUE; - LWP_WaitProcess(&overload); - } - } - } + FD_ZERO(&readset); + FD_SET(kernel_fd, &readset); + + ret = IOMGR_Select (kernel_fd + 1, &readset, NULL, NULL, NULL); + + if (ret < 0) + arla_warn (ADEBKERNEL, errno, "select"); + else if (ret == 0) + arla_warnx (ADEBKERNEL, + "Arla: select returned with 0. strange."); + else if (FD_ISSET(kernel_fd, &readset)) { + for (i = 0; i < args->num_workers; ++i) { + if (workers[i].busyp == 0) { + ret = kern_read (kernel_fd, workers[i].data, + sizeof(workers[i].data)); + if (ret <= 0) { + arla_warn (ADEBWARN, errno, "read"); + } else { + workers[i].msg_length = ret; + LWP_SignalProcess (&workers[i]); + } + break; + } + } + if (i == args->num_workers) { + arla_warnx (ADEBWARN, "kernel: all %u workers busy", + args->num_workers); + overload = TRUE; + LWP_WaitProcess(&overload); + } + } + } } diff --git a/usr.sbin/afs/src/arlad/kernel.h b/usr.sbin/afs/src/arlad/kernel.h index 3c9c856a590..7d24d14638f 100644 --- a/usr.sbin/afs/src/arlad/kernel.h +++ b/usr.sbin/afs/src/arlad/kernel.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $KTH: kernel.h,v 1.8 2000/10/02 22:32:26 lha Exp $ */ +/* $arla: kernel.h,v 1.9 2002/07/24 06:04:29 lha Exp $ */ #ifndef _KERNEL_H_ #define _KERNEL_H_ diff --git a/usr.sbin/afs/src/arlad/messages.c b/usr.sbin/afs/src/arlad/messages.c index a3007c84857..a686caa4d7f 100644 --- a/usr.sbin/afs/src/arlad/messages.c +++ b/usr.sbin/afs/src/arlad/messages.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995-2001 Kungliga Tekniska Högskolan + * Copyright (c) 1995-2003 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -32,9 +32,9 @@ */ #include "arla_local.h" -RCSID("$KTH: messages.c,v 1.231.2.12 2001/10/19 04:25:52 ahltorp Exp $"); +RCSID("$arla: messages.c,v 1.318 2003/06/10 04:23:31 lha Exp $"); -#include <xfs/xfs_message.h> +#include <nnpfs/nnpfs_message.h> #ifdef HAVE_SYS_IOCTL_H #include <sys/ioctl.h> @@ -43,101 +43,93 @@ RCSID("$KTH: messages.c,v 1.231.2.12 2001/10/19 04:25:52 ahltorp Exp $"); #include "messages.h" -/* XXX */ -int Log_is_open; -DARLA_file log_data; +static int +nnpfs_message_getroot (int, struct nnpfs_message_getroot*, u_int); static int -xfs_message_getroot (int, struct xfs_message_getroot*, u_int); +nnpfs_message_getnode (int, struct nnpfs_message_getnode*, u_int); static int -xfs_message_getnode (int, struct xfs_message_getnode*, u_int); +nnpfs_message_getattr (int, struct nnpfs_message_getattr*, u_int); static int -xfs_message_getattr (int, struct xfs_message_getattr*, u_int); +nnpfs_message_open (int, struct nnpfs_message_open*, u_int); static int -xfs_message_getdata (int, struct xfs_message_getdata*, u_int); +nnpfs_message_getdata (int, struct nnpfs_message_getdata*, u_int); static int -xfs_message_inactivenode (int,struct xfs_message_inactivenode*,u_int); +nnpfs_message_inactivenode (int,struct nnpfs_message_inactivenode*,u_int); static int -xfs_message_putdata (int fd, struct xfs_message_putdata *h, u_int size); +nnpfs_message_putdata (int fd, struct nnpfs_message_putdata *h, u_int size); static int -xfs_message_putattr (int fd, struct xfs_message_putattr *h, u_int size); +nnpfs_message_putattr (int fd, struct nnpfs_message_putattr *h, u_int size); static int -xfs_message_create (int fd, struct xfs_message_create *h, u_int size); +nnpfs_message_create (int fd, struct nnpfs_message_create *h, u_int size); static int -xfs_message_mkdir (int fd, struct xfs_message_mkdir *h, u_int size); +nnpfs_message_mkdir (int fd, struct nnpfs_message_mkdir *h, u_int size); static int -xfs_message_link (int fd, struct xfs_message_link *h, u_int size); +nnpfs_message_link (int fd, struct nnpfs_message_link *h, u_int size); static int -xfs_message_symlink (int fd, struct xfs_message_symlink *h, u_int size); +nnpfs_message_symlink (int fd, struct nnpfs_message_symlink *h, u_int size); static int -xfs_message_remove (int fd, struct xfs_message_remove *h, u_int size); +nnpfs_message_remove (int fd, struct nnpfs_message_remove *h, u_int size); static int -xfs_message_rmdir (int fd, struct xfs_message_rmdir *h, u_int size); +nnpfs_message_rmdir (int fd, struct nnpfs_message_rmdir *h, u_int size); static int -xfs_message_rename (int fd, struct xfs_message_rename *h, u_int size); +nnpfs_message_rename (int fd, struct nnpfs_message_rename *h, u_int size); static int -xfs_message_pioctl (int fd, struct xfs_message_pioctl *h, u_int size) ; - - -xfs_message_function rcvfuncs[] = { -NULL, /* version */ -(xfs_message_function)xfs_message_wakeup, /* wakeup */ -(xfs_message_function)xfs_message_getroot, /* getroot */ -NULL, /* installroot */ -(xfs_message_function)xfs_message_getnode, /* getnode */ -NULL, /* installnode */ -(xfs_message_function)xfs_message_getattr, /* getattr */ -NULL, /* installattr */ -(xfs_message_function)xfs_message_getdata, /* getdata */ -NULL, /* installdata */ -(xfs_message_function)xfs_message_inactivenode, /* inactivenode */ -NULL, /* invalidnode */ -(xfs_message_function)xfs_message_getdata, /* open */ -(xfs_message_function)xfs_message_putdata, /* put_data */ -(xfs_message_function)xfs_message_putattr, /* put attr */ -(xfs_message_function)xfs_message_create, /* create */ -(xfs_message_function)xfs_message_mkdir, /* mkdir */ -(xfs_message_function)xfs_message_link, /* link */ -(xfs_message_function)xfs_message_symlink, /* symlink */ -(xfs_message_function)xfs_message_remove, /* remove */ -(xfs_message_function)xfs_message_rmdir, /* rmdir */ -(xfs_message_function)xfs_message_rename, /* rename */ -(xfs_message_function)xfs_message_pioctl, /* pioctl */ -NULL, /* wakeup_data */ -NULL, /* updatefid */ -NULL, /* advlock */ -NULL /* gc nodes */ -}; +nnpfs_message_pioctl (int fd, struct nnpfs_message_pioctl *h, u_int size) ; + +static u_char +afsrights2nnpfsrights(u_long, uint32_t, uint32_t); +static int +possibly_have_network(void); /* - * Return 0 if ``fid1'' eq ``fid2''. + * */ -int -VenusFid_cmp (const VenusFid *fid1, const VenusFid *fid2) -{ - if (fid1->Cell == fid2->Cell && - fid1->fid.Volume == fid2->fid.Volume && - fid1->fid.Vnode == fid2->fid.Vnode && - fid1->fid.Unique == fid2->fid.Unique) - return 0; - return 1; -} +nnpfs_message_function rcvfuncs[] = { + NULL, /* version */ + (nnpfs_message_function)nnpfs_message_wakeup, /* wakeup */ + (nnpfs_message_function)nnpfs_message_getroot, /* getroot */ + NULL, /* installroot */ + (nnpfs_message_function)nnpfs_message_getnode, /* getnode */ + NULL, /* installnode */ + (nnpfs_message_function)nnpfs_message_getattr, /* getattr */ + NULL, /* installattr */ + (nnpfs_message_function)nnpfs_message_getdata, /* getdata */ + NULL, /* installdata */ + (nnpfs_message_function)nnpfs_message_inactivenode, /* inactivenode */ + NULL, /* invalidnode */ + (nnpfs_message_function)nnpfs_message_open, /* open */ + (nnpfs_message_function)nnpfs_message_putdata, /* put_data */ + (nnpfs_message_function)nnpfs_message_putattr, /* put attr */ + (nnpfs_message_function)nnpfs_message_create, /* create */ + (nnpfs_message_function)nnpfs_message_mkdir, /* mkdir */ + (nnpfs_message_function)nnpfs_message_link, /* link */ + (nnpfs_message_function)nnpfs_message_symlink, /* symlink */ + (nnpfs_message_function)nnpfs_message_remove, /* remove */ + (nnpfs_message_function)nnpfs_message_rmdir, /* rmdir */ + (nnpfs_message_function)nnpfs_message_rename, /* rename */ + (nnpfs_message_function)nnpfs_message_pioctl, /* pioctl */ + NULL, /* wakeup_data */ + NULL, /* updatefid */ + NULL, /* advlock */ + NULL /* gc nodes */ +}; /* @@ -151,43 +143,64 @@ afsfid2inode (const VenusFid *fid) } /* - * AFSFetchStatus -> xfs_attr + * AFSFetchStatus -> nnpfs_attr + * Setting everything except for length and mode. */ static void -afsstatus2xfs_attr (AFSFetchStatus *status, - const VenusFid *fid, - struct xfs_attr *attr) -{ - attr->valid = XA_V_NONE; - switch (status->FileType) { - case TYPE_FILE : - XA_SET_MODE(attr, S_IFREG); - XA_SET_TYPE(attr, XFS_FILE_REG); - XA_SET_NLINK(attr, status->LinkCount); - break; - case TYPE_DIR : - XA_SET_MODE(attr, S_IFDIR); - XA_SET_TYPE(attr, XFS_FILE_DIR); - XA_SET_NLINK(attr, status->LinkCount); - break; - case TYPE_LINK : - XA_SET_MODE(attr, S_IFLNK); - XA_SET_TYPE(attr, XFS_FILE_LNK); - XA_SET_NLINK(attr, status->LinkCount); - break; - default : - arla_warnx (ADEBMSG, "afsstatus2xfs_attr: default"); - abort (); - } - XA_SET_SIZE(attr, status->Length); - XA_SET_UID(attr,status->Owner); - XA_SET_GID(attr, status->Group); - attr->xa_mode |= status->UnixModeBits; - XA_SET_ATIME(attr, status->ClientModTime); - XA_SET_MTIME(attr, status->ClientModTime); - XA_SET_CTIME(attr, status->ClientModTime); - XA_SET_FILEID(attr, afsfid2inode(fid)); +afsstatus2nnpfs_attr (AFSFetchStatus *status, + const VenusFid *fid, + struct nnpfs_attr *attr, + int flags) +{ + int mode; + + attr->valid = XA_V_NONE; + switch (status->FileType) { + case TYPE_FILE : + mode = S_IFREG; + XA_SET_TYPE(attr, NNPFS_FILE_REG); + break; + case TYPE_DIR : + mode = S_IFDIR; + XA_SET_TYPE(attr, NNPFS_FILE_DIR); + break; + case TYPE_LINK : + mode = S_IFLNK; + XA_SET_TYPE(attr, NNPFS_FILE_LNK); + break; + default : + arla_warnx (ADEBMSG, "afsstatus2nnpfs_attr: default"); + abort (); + } + XA_SET_NLINK(attr, status->LinkCount); + if (flags & FCACHE2NNPFSNODE_LENGTH) + XA_SET_SIZE(attr, status->Length); + XA_SET_UID(attr,status->Owner); + XA_SET_GID(attr, status->Group); + XA_SET_ATIME(attr, status->ClientModTime); + XA_SET_MTIME(attr, status->ClientModTime); + XA_SET_CTIME(attr, status->ClientModTime); + XA_SET_FILEID(attr, afsfid2inode(fid)); + + /* XXX this is wrong, need to keep track of `our` ae for this req */ + if (fake_stat) { + u_char rights; + + rights = afsrights2nnpfsrights(status->CallerAccess, + status->FileType, + status->UnixModeBits); + + if (rights & NNPFS_RIGHT_R) + mode |= 0444; + if (rights & NNPFS_RIGHT_W) + mode |= 0222; + if (rights & NNPFS_RIGHT_X) + mode |= 0111; + } else + mode |= status->UnixModeBits; + + XA_SET_MODE(attr, mode); } /* @@ -198,52 +211,51 @@ afsstatus2xfs_attr (AFSFetchStatus *status, */ static u_char -afsrights2xfsrights(u_long ar, u_int32_t FileType, u_int32_t UnixModeBits) +afsrights2nnpfsrights(u_long ar, uint32_t FileType, uint32_t UnixModeBits) { u_char ret = 0; if (FileType == TYPE_DIR) { if (ar & ALIST) - ret |= XFS_RIGHT_R | XFS_RIGHT_X; + ret |= NNPFS_RIGHT_R | NNPFS_RIGHT_X; if (ar & (AINSERT | ADELETE)) - ret |= XFS_RIGHT_W; + ret |= NNPFS_RIGHT_W; } else { if (FileType == TYPE_LINK && (ar & ALIST)) - ret |= XFS_RIGHT_R; + ret |= NNPFS_RIGHT_R; if ((ar & AREAD) && (UnixModeBits & S_IRUSR)) - ret |= XFS_RIGHT_R; + ret |= NNPFS_RIGHT_R; if ((ar & AWRITE) && (UnixModeBits & S_IWUSR)) - ret |= XFS_RIGHT_W; + ret |= NNPFS_RIGHT_W; if ((ar & AREAD) && (UnixModeBits & S_IXUSR)) - ret |= XFS_RIGHT_X; + ret |= NNPFS_RIGHT_X; } return ret; } void -fcacheentry2xfsnode (const VenusFid *fid, - const VenusFid *statfid, - AFSFetchStatus *status, - struct xfs_msg_node *node, - AccessEntry *ae, - int flags) +fcacheentry2nnpfsnode (const VenusFid *fid, + const VenusFid *statfid, + AFSFetchStatus *status, + struct nnpfs_msg_node *node, + AccessEntry *ae, + int flags) { int i; memcpy (&node->handle, fid, sizeof(*fid)); - if (flags & FCACHE2XFSNODE_ATTR) - afsstatus2xfs_attr (status, statfid, &node->attr); - if (flags & FCACHE2XFSNODE_RIGHT) { - node->anonrights = afsrights2xfsrights(status->AnonymousAccess, - status->FileType, - status->UnixModeBits); - for (i = 0; i < NACCESS; i++) { - node->id[i] = ae[i].cred; - node->rights[i] = afsrights2xfsrights(ae[i].access, - status->FileType, - status->UnixModeBits); - } + + afsstatus2nnpfs_attr (status, statfid, &node->attr, flags); + + node->anonrights = afsrights2nnpfsrights(status->AnonymousAccess, + status->FileType, + status->UnixModeBits); + for (i = 0; i < NACCESS; i++) { + node->id[i] = ae[i].cred; + node->rights[i] = afsrights2nnpfsrights(ae[i].access, + status->FileType, + status->UnixModeBits); } } @@ -252,8 +264,8 @@ fcacheentry2xfsnode (const VenusFid *fid, */ int -xfs_attr2afsstorestatus(struct xfs_attr *xa, - AFSStoreStatus *storestatus) +nnpfs_attr2afsstorestatus(struct nnpfs_attr *xa, + AFSStoreStatus *storestatus) { int mask = 0; @@ -288,11 +300,13 @@ xfs_attr2afsstorestatus(struct xfs_attr *xa, */ static int -try_again (int *ret, CredCacheEntry **ce, xfs_cred *cred, const VenusFid *fid) +try_again (int *ret, CredCacheEntry **ce, nnpfs_cred *cred, const VenusFid *fid) { switch (*ret) { #ifdef KERBEROS case RXKADEXPIRED : + case RXKADBADTICKET: + case RXKADBADKEY: case RXKADUNKNOWNKEY: { int32_t cell = (*ce)->cell; @@ -317,7 +331,7 @@ try_again (int *ret, CredCacheEntry **ce, xfs_cred *cred, const VenusFid *fid) return FALSE; case ARLA_VMOVED : case ARLA_VNOVOL : - if (fid && !volcache_reliable (fid->fid.Volume, fid->Cell)) { + if (fid && !volcache_reliablep (fid->fid.Volume, fid->Cell)) { return TRUE; } else { *ret = ENOENT; @@ -359,13 +373,15 @@ try_again (int *ret, CredCacheEntry **ce, xfs_cred *cred, const VenusFid *fid) */ static int -message_get_data (FCacheEntry **entry, VenusFid *fid, - struct xfs_cred *cred, CredCacheEntry **ce) +message_get_data (FCacheEntry **entry, + struct nnpfs_cred *cred, + CredCacheEntry **ce, + size_t wanted_length) { int ret; do { - ret = fcache_get_data (entry, fid, ce); - } while (try_again (&ret, ce, cred, fid)); + ret = fcache_get_data (entry, ce, wanted_length); + } while (try_again (&ret, ce, cred, &(*entry)->fid)); return ret; } @@ -374,1463 +390,1675 @@ message_get_data (FCacheEntry **entry, VenusFid *fid, */ static int -xfs_message_getroot (int fd, struct xfs_message_getroot *h, u_int size) -{ - struct xfs_message_installroot msg; - int ret = 0; - VenusFid root_fid; - VenusFid real_fid; - AFSFetchStatus status; - Result res; - CredCacheEntry *ce; - AccessEntry *ae; - struct xfs_message_header *h0 = NULL; - size_t h0_len = 0; - int32_t cell_id = cell_name2num(cell_getthiscell()); - - ce = cred_get (cell_id, h->cred.pag, CRED_ANY); - assert (ce != NULL); - do { - ret = getroot (&root_fid, ce); - - if (ret == 0) { - res = cm_getattr(root_fid, &status, &real_fid, ce, &ae); - if (res.res) - ret = res.error; - else - ret = res.res; - } - } while (try_again (&ret, &ce, &h->cred, &root_fid)); - - if (ret == 0) { - fcacheentry2xfsnode (&root_fid, &real_fid, - &status, &msg.node, ae, - FCACHE2XFSNODE_ALL); - - msg.node.tokens = res.tokens & ~XFS_DATA_MASK; - msg.header.opcode = XFS_MSG_INSTALLROOT; - h0 = (struct xfs_message_header *)&msg; - h0_len = sizeof(msg); - } - - cred_free (ce); - xfs_send_message_wakeup_multiple (fd, - h->header.sequence_num, - ret, - h0, h0_len, - NULL, 0); - return 0; +nnpfs_message_getroot (int fd, struct nnpfs_message_getroot *h, u_int size) +{ + struct nnpfs_message_installroot msg; + int ret = 0; + VenusFid root_fid; + CredCacheEntry *ce; + AccessEntry *ae; + FCacheEntry *entry = NULL; + struct nnpfs_message_header *h0 = NULL; + size_t h0_len = 0; + int32_t cell_id = cell_name2num(cell_getthiscell()); + + ce = cred_get (cell_id, h->cred.pag, CRED_ANY); + assert (ce != NULL); + do { + ret = getroot (&root_fid, ce); + } while (try_again (&ret, &ce, &h->cred, &root_fid)); + + if (ret) + goto out; + + ret = fcache_get(&entry, root_fid, ce); + if (ret) + goto out; + + do { + ret = cm_getattr(entry, ce, &ae); + } while (try_again (&ret, &ce, &h->cred, &root_fid)); + + if (ret == 0) { + fcacheentry2nnpfsnode (&root_fid, fcache_realfid(entry), + &entry->status, &msg.node, ae, + FCACHE2NNPFSNODE_ALL); + + entry->tokens |= NNPFS_ATTR_R; + msg.node.tokens = entry->tokens & ~NNPFS_DATA_MASK; + msg.header.opcode = NNPFS_MSG_INSTALLROOT; + h0 = (struct nnpfs_message_header *)&msg; + h0_len = sizeof(msg); + } + + out: + nnpfs_send_message_wakeup_multiple (fd, + h->header.sequence_num, + ret, + h0, h0_len, + NULL, 0); + if (entry) + fcache_release(entry); + cred_free (ce); + + return 0; } static int -xfs_message_getnode (int fd, struct xfs_message_getnode *h, u_int size) -{ - struct xfs_message_installnode msg; - VenusFid *dirfid = (VenusFid *)&h->parent_handle; - VenusFid fid; - VenusFid real_fid; - Result res; - AFSFetchStatus status; - CredCacheEntry *ce; - AccessEntry *ae; - struct xfs_message_header *h0 = NULL; - size_t h0_len = 0; - int ret; - const VenusFid *report_fid = NULL; - - - arla_warnx (ADEBMSG, "getnode (%ld.%lu.%lu.%lu) \"%s\"", - (long)dirfid->Cell, (unsigned long)dirfid->fid.Volume, - (unsigned long)dirfid->fid.Vnode, - (unsigned long)dirfid->fid.Unique, h->name); - - ce = cred_get (dirfid->Cell, h->cred.pag, CRED_ANY); - assert (ce != NULL); - - report_fid = dirfid; - do { - res = cm_lookup (dirfid, h->name, &fid, &ce, TRUE); - if (res.res == 0) { - res = cm_getattr (fid, &status, &real_fid, ce, &ae); - report_fid = &fid; - } - - if (res.res) - ret = res.error; - else - ret = res.res; - } while (try_again (&ret, &ce, &h->cred, report_fid)); - - if (ret == 0) { - fcacheentry2xfsnode (&fid, &real_fid, &status, &msg.node, ae, - FCACHE2XFSNODE_ALL); - - msg.node.tokens = res.tokens & ~XFS_DATA_MASK; - msg.parent_handle = h->parent_handle; - strlcpy (msg.name, h->name, sizeof(msg.name)); - - msg.header.opcode = XFS_MSG_INSTALLNODE; - h0 = (struct xfs_message_header *)&msg; - h0_len = sizeof(msg); - } - - cred_free (ce); - xfs_send_message_wakeup_multiple (fd, - h->header.sequence_num, - ret, - h0, h0_len, - NULL, 0); - return 0; +nnpfs_message_getnode (int fd, struct nnpfs_message_getnode *h, u_int size) +{ + struct nnpfs_message_installnode msg; + VenusFid *dirfid = (VenusFid *)&h->parent_handle; + VenusFid fid; + VenusFid real_fid; + AFSFetchStatus status; + CredCacheEntry *ce; + AccessEntry *ae; + FCacheEntry *entry = NULL; + FCacheEntry *dentry = NULL; + struct nnpfs_message_header *h0 = NULL; + size_t h0_len = 0; + int ret; + + arla_warnx (ADEBMSG, "getnode (%ld.%lu.%lu.%lu) \"%s\"", + (long)dirfid->Cell, (unsigned long)dirfid->fid.Volume, + (unsigned long)dirfid->fid.Vnode, + (unsigned long)dirfid->fid.Unique, h->name); + + ce = cred_get (dirfid->Cell, h->cred.pag, CRED_ANY); + assert (ce != NULL); + + ret = fcache_get(&dentry, *dirfid, ce); + if (ret) + goto out; + + assert_flag(dentry,kernelp); + + do { + ret = cm_lookup (&dentry, h->name, &fid, &ce, TRUE); + *dirfid = dentry->fid; + } while (try_again (&ret, &ce, &h->cred, dirfid)); + + if (ret) + goto out; + + fcache_release(dentry); + dentry = NULL; + + ret = fcache_get(&entry, fid, ce); + if (ret) + goto out; + + do { + ret = cm_getattr (entry, ce, &ae); + status = entry->status; + real_fid = *fcache_realfid(entry); + } while (try_again (&ret, &ce, &h->cred, &fid)); + + if (ret == 0) { + fcacheentry2nnpfsnode (&fid, &real_fid, &status, &msg.node, ae, + FCACHE2NNPFSNODE_ALL); + + entry->tokens |= NNPFS_ATTR_R; + msg.node.tokens = entry->tokens & ~NNPFS_DATA_MASK; + msg.parent_handle = h->parent_handle; + strlcpy (msg.name, h->name, sizeof(msg.name)); + + msg.header.opcode = NNPFS_MSG_INSTALLNODE; + h0 = (struct nnpfs_message_header *)&msg; + h0_len = sizeof(msg); + } + out: + nnpfs_send_message_wakeup_multiple (fd, + h->header.sequence_num, + ret, + h0, h0_len, + NULL, 0); + if (entry) + fcache_release(entry); + if (dentry) + fcache_release(dentry); + cred_free (ce); + + return 0; } static int -xfs_message_getattr (int fd, struct xfs_message_getattr *h, u_int size) -{ - struct xfs_message_installattr msg; - VenusFid *fid; - VenusFid real_fid; - AFSFetchStatus status; - Result res; - CredCacheEntry *ce; - AccessEntry *ae; - struct xfs_message_header *h0 = NULL; - size_t h0_len = 0; - int ret; - - fid = (VenusFid *)&h->handle; - arla_warnx (ADEBMSG, "getattr (%ld.%lu.%lu.%lu)", - (long)fid->Cell, (unsigned long)fid->fid.Volume, - (unsigned long)fid->fid.Vnode, - (unsigned long)fid->fid.Unique); - ce = cred_get (fid->Cell, h->cred.pag, CRED_ANY); - assert (ce != NULL); - - do { - res = cm_getattr (*fid, &status, &real_fid, ce, &ae); - if (res.res) - ret = res.error; - else - ret = res.res; - } while (try_again (&ret, &ce, &h->cred, fid)); - - if (ret == 0) { - fcacheentry2xfsnode (fid, &real_fid, &status, &msg.node, ae, - FCACHE2XFSNODE_ALL); - - msg.node.tokens = res.tokens; - msg.header.opcode = XFS_MSG_INSTALLATTR; - h0 = (struct xfs_message_header *)&msg; - h0_len = sizeof(msg); - } +nnpfs_message_getattr (int fd, struct nnpfs_message_getattr *h, u_int size) +{ + struct nnpfs_message_installattr msg; + VenusFid fid; + CredCacheEntry *ce; + AccessEntry *ae; + FCacheEntry *entry = NULL; + struct nnpfs_message_header *h0 = NULL; + size_t h0_len = 0; + int ret; + + fid = *(VenusFid *)&h->handle; + arla_warnx (ADEBMSG, "getattr (%ld.%lu.%lu.%lu)", + (long)fid.Cell, (unsigned long)fid.fid.Volume, + (unsigned long)fid.fid.Vnode, + (unsigned long)fid.fid.Unique); + ce = cred_get (fid.Cell, h->cred.pag, CRED_ANY); + assert (ce != NULL); + + ret = fcache_get(&entry, fid, ce); + if (ret) + goto out; + + assert_flag(entry,kernelp); - cred_free (ce); - xfs_send_message_wakeup_multiple (fd, - h->header.sequence_num, - ret, - h0, h0_len, - NULL, 0); + do { + ret = cm_getattr (entry, ce, &ae); + } while (try_again (&ret, &ce, &h->cred, &fid)); + + if (ret) + goto out; + + fcacheentry2nnpfsnode (&fid, fcache_realfid(entry), + &entry->status, &msg.node, ae, + FCACHE2NNPFSNODE_ALL); + + entry->tokens |= NNPFS_ATTR_R; + msg.node.tokens = entry->tokens; + msg.header.opcode = NNPFS_MSG_INSTALLATTR; + h0 = (struct nnpfs_message_header *)&msg; + h0_len = sizeof(msg); + + out: + nnpfs_send_message_wakeup_multiple (fd, + h->header.sequence_num, + ret, + h0, h0_len, + NULL, 0); + if (entry) + fcache_release(entry); + cred_free (ce); - return 0; + return 0; } static int -xfs_message_putattr (int fd, struct xfs_message_putattr *h, u_int size) -{ - struct xfs_message_installattr msg; - VenusFid *fid; - AFSStoreStatus status; - AFSFetchStatus fetch_status; - Result res; - CredCacheEntry *ce; - AccessEntry *ae; - VenusFid real_fid; - struct xfs_message_header *h0 = NULL; - size_t h0_len = 0; - int ret; - struct vcache log_cache; - FCacheEntry *fce; - int log_err; - - fid = (VenusFid *)&h->handle; - arla_warnx (ADEBMSG, "putattr (%ld.%lu.%lu.%lu)", - (long)fid->Cell, (unsigned long)fid->fid.Volume, - (unsigned long)fid->fid.Vnode, - (unsigned long)fid->fid.Unique); - xfs_attr2afsstorestatus(&h->attr, &status); - ce = cred_get (fid->Cell, h->cred.pag, CRED_ANY); - assert (ce != NULL); - - if (connected_mode != CONNECTED) { - ret = fcache_find (&fce, *fid); - ReleaseWriteLock (&fce->lock); - - log_cache.fid = *fid; - log_cache.DataVersion = fce->status.DataVersion; - log_cache.cred = h->cred; - } - - do { - res.res = 0; - if (XA_VALID_SIZE(&h->attr)) - res = cm_ftruncate (*fid, h->attr.xa_size, ce); - - if (res.res == 0) - res = cm_setattr(*fid, &status, ce); - - if (res.res) - ret = res.error; - else - ret = res.res; - } while (try_again (&ret, &ce, &h->cred, fid)); - - if (ret == 0) { - do { - res = cm_getattr (*fid, &fetch_status, &real_fid, ce, &ae); - if (res.res) - ret = res.error; - else - ret = res.res; - } while (try_again (&ret, &ce, &h->cred, fid)); - - if (ret == 0) { - fcacheentry2xfsnode (fid, &real_fid, - &fetch_status, &msg.node, ae, - FCACHE2XFSNODE_ALL); - - msg.node.tokens = res.tokens; - msg.header.opcode = XFS_MSG_INSTALLATTR; - h0 = (struct xfs_message_header *)&msg; - h0_len = sizeof(msg); - } - } - - if (connected_mode != CONNECTED && ret == 0) { - log_err = log_dis_setattr (&log_cache, &(h->attr)); - } - - cred_free (ce); - xfs_send_message_wakeup_multiple (fd, - h->header.sequence_num, - ret, - h0, h0_len, - NULL, 0); - return 0; +nnpfs_message_putattr (int fd, struct nnpfs_message_putattr *h, u_int size) +{ + struct nnpfs_message_installattr msg; + VenusFid fid; + AFSStoreStatus status; + CredCacheEntry *ce; + AccessEntry *ae; + struct nnpfs_message_header *h0 = NULL; + size_t h0_len = 0; + int ret; + + FCacheEntry *entry = NULL; + + fid = *(VenusFid *)&h->handle; + arla_warnx (ADEBMSG, "putattr (%ld.%lu.%lu.%lu)", + (long)fid.Cell, (unsigned long)fid.fid.Volume, + (unsigned long)fid.fid.Vnode, + (unsigned long)fid.fid.Unique); + nnpfs_attr2afsstorestatus(&h->attr, &status); + ce = cred_get (fid.Cell, h->cred.pag, CRED_ANY); + assert (ce != NULL); + + if (connected_mode != CONNECTED) { + ret = fcache_find (&entry, fid); + if (ret) { + ret = ENETDOWN; + goto out; + } + } else { + ret = fcache_get(&entry, fid, ce); + if (ret) + goto out; + } + + assert_flag(entry,kernelp); + + /* + * We can't bits update at the same time as same time as we store + * data since then fileserver will hate us with we are part of + * system:administrators. This was fixed in openafs-1.2.7 + */ + + if (XA_VALID_SIZE(&h->attr)) { + AFSStoreStatus null_status; + memset(&null_status, 0, sizeof(null_status)); + do { + ret = cm_ftruncate (entry, h->attr.xa_size, &status, ce); + } while (try_again (&ret, &ce, &h->cred, &fid)); + } + + if (ret) + goto out; + + if (status.Mask) { + do { + ret = cm_setattr(entry, &status, ce); + } while (try_again (&ret, &ce, &h->cred, &fid)); + } + + if (ret) + goto out; + + do { + ret = cm_getattr (entry, ce, &ae); + } while (try_again (&ret, &ce, &h->cred, &fid)); + + + if (ret) + goto out; + + fcacheentry2nnpfsnode (&fid, fcache_realfid(entry), + &entry->status, &msg.node, ae, + FCACHE2NNPFSNODE_ALL); + + entry->tokens |= NNPFS_ATTR_R; + msg.node.tokens = entry->tokens; + msg.header.opcode = NNPFS_MSG_INSTALLATTR; + h0 = (struct nnpfs_message_header *)&msg; + h0_len = sizeof(msg); + + if (ret) + goto out; + + if (connected_mode != CONNECTED) + entry->disco_id = disco_store_status(&fid, &status, entry->disco_id); + + out: + nnpfs_send_message_wakeup_multiple (fd, + h->header.sequence_num, + ret, + h0, h0_len, + NULL, 0); + if (entry) + fcache_release(entry); + cred_free (ce); + + return 0; } static int -xfs_message_create (int fd, struct xfs_message_create *h, u_int size) -{ - VenusFid *parent_fid, child_fid; - AFSStoreStatus store_status; - AFSFetchStatus fetch_status; - Result res; - CredCacheEntry *ce; - int ret; - struct xfs_message_installdata msg1; - struct xfs_message_installnode msg2; - struct xfs_message_installdata msg3; - struct xfs_message_header *h0 = NULL; - size_t h0_len = 0; - struct xfs_message_header *h1 = NULL; - size_t h1_len = 0; - struct xfs_message_header *h2 = NULL; - size_t h2_len = 0; - FCacheEntry *dir_entry = NULL; - FCacheEntry *child_entry = NULL; - fcache_cache_handle cache_handle; - - parent_fid = (VenusFid *)&h->parent_handle; - arla_warnx (ADEBMSG, "create (%ld.%lu.%lu.%lu) \"%s\"", - (long)parent_fid->Cell, - (unsigned long)parent_fid->fid.Volume, - (unsigned long)parent_fid->fid.Vnode, - (unsigned long)parent_fid->fid.Unique, h->name); - - xfs_attr2afsstorestatus(&h->attr, &store_status); - if (connected_mode != CONNECTED) { - if (!(store_status.Mask & SS_OWNER)) { - store_status.Owner = h->cred.uid; - store_status.Mask |= SS_OWNER; - } - if (!(store_status.Mask & SS_MODTIME)) { - struct timeval now; - - gettimeofday (&now, NULL); - - store_status.ClientModTime = now.tv_sec; - store_status.Mask |= SS_MODTIME; - } - } - ce = cred_get (parent_fid->Cell, h->cred.pag, CRED_ANY); - assert (ce != NULL); - - do { - res = cm_create(parent_fid, h->name, &store_status, - &child_fid, &fetch_status, &ce); - - if (res.res) - ret = res.error; - else - ret = res.res; - } while (try_again (&ret, &ce, &h->cred, parent_fid)); - - if (res.res == 0) { - - ret = message_get_data (&dir_entry, parent_fid, &h->cred, &ce); - if (ret) - goto out; - - res = conv_dir (dir_entry, ce, 0, - &cache_handle, - msg1.cache_name, - sizeof(msg1.cache_name)); - if (res.res == -1) { - ret = res.error; - goto out; - } - msg1.cache_handle = cache_handle.xfs_handle; - msg1.flag = 0; - if (cache_handle.valid) - msg1.flag |= XFS_ID_HANDLE_VALID; - - msg1.node.tokens = res.tokens; - - fcacheentry2xfsnode (parent_fid, - fcache_realfid(dir_entry), - &dir_entry->status, - &msg1.node, - dir_entry->acccache, - FCACHE2XFSNODE_ALL); - - ret = message_get_data (&child_entry, &child_fid, &h->cred, &ce); - if (ret) - goto out; - - msg3.cache_handle = child_entry->handle.xfs_handle; - fcache_file_name (child_entry, +nnpfs_message_create (int fd, struct nnpfs_message_create *h, u_int size) +{ + VenusFid parent_fid, child_fid; + AFSStoreStatus store_status; + AFSFetchStatus fetch_status; + CredCacheEntry *ce; + int ret; + struct nnpfs_message_installdata msg1; + struct nnpfs_message_installnode msg2; + struct nnpfs_message_installdata msg3; + struct nnpfs_message_header *h0 = NULL; + size_t h0_len = 0; + struct nnpfs_message_header *h1 = NULL; + size_t h1_len = 0; + struct nnpfs_message_header *h2 = NULL; + size_t h2_len = 0; + FCacheEntry *dir_entry = NULL; + FCacheEntry *child_entry = NULL; + fcache_cache_handle cache_handle; + + parent_fid = *(VenusFid *)&h->parent_handle; + arla_warnx (ADEBMSG, "create (%ld.%lu.%lu.%lu) \"%s\"", + (long)parent_fid.Cell, + (unsigned long)parent_fid.fid.Volume, + (unsigned long)parent_fid.fid.Vnode, + (unsigned long)parent_fid.fid.Unique, h->name); + + nnpfs_attr2afsstorestatus(&h->attr, &store_status); + if (connected_mode != CONNECTED) { + if (!(store_status.Mask & SS_OWNER)) { + store_status.Owner = h->cred.uid; + store_status.Mask |= SS_OWNER; + } + if (!(store_status.Mask & SS_GROUP)) { + store_status.Group = 0; + store_status.Mask |= SS_GROUP; + } + if (!(store_status.Mask & SS_MODTIME)) { + struct timeval now; + + gettimeofday (&now, NULL); + + store_status.ClientModTime = now.tv_sec; + store_status.Mask |= SS_MODTIME; + } + } + ce = cred_get (parent_fid.Cell, h->cred.pag, CRED_ANY); + assert (ce != NULL); + + ret = fcache_get(&dir_entry, parent_fid, ce); + if (ret) + goto out; + + assert_flag(dir_entry,kernelp); + + do { + ret = cm_create(&dir_entry, h->name, &store_status, + &child_fid, &fetch_status, &ce); + } while (try_again (&ret, &ce, &h->cred, &dir_entry->fid)); + + if (ret) + goto out; + + ret = message_get_data (&dir_entry, &h->cred, &ce, 0); + if (ret) + goto out; + + ret = conv_dir (dir_entry, ce, 0, + &cache_handle, + msg1.cache_name, + sizeof(msg1.cache_name)); + if (ret) + goto out; + + msg1.cache_handle = cache_handle.nnpfs_handle; + msg1.flag = 0; + if (cache_handle.valid) + msg1.flag |= NNPFS_ID_HANDLE_VALID; + + dir_entry->tokens |= NNPFS_ATTR_R; + msg1.node.tokens = dir_entry->tokens; + + fcacheentry2nnpfsnode (&dir_entry->fid, + fcache_realfid(dir_entry), + &dir_entry->status, + &msg1.node, + dir_entry->acccache, + FCACHE2NNPFSNODE_ALL); + + ret = fcache_get(&child_entry, child_fid, ce); + if (ret) + goto out; + /* XXX remove this, we don't want to fetch data from the fileserver */ + ret = message_get_data (&child_entry, &h->cred, &ce, 0); + if (ret) { + fcache_release(child_entry); + goto out; + } + child_fid = child_entry->fid; + + msg3.cache_handle = child_entry->handle.nnpfs_handle; + fcache_conv_file_name (child_entry, msg3.cache_name, sizeof(msg3.cache_name)); - msg3.flag = 0; - if (cache_handle.valid) - msg3.flag |= XFS_ID_HANDLE_VALID; + msg3.flag = 0; + if (cache_handle.valid) + msg3.flag |= NNPFS_ID_HANDLE_VALID; + + child_entry->flags.kernelp = TRUE; + child_entry->flags.attrusedp = TRUE; + child_entry->flags.datausedp = TRUE; + assert_flag(dir_entry,kernelp); + assert_flag(dir_entry,attrusedp); + dir_entry->flags.datausedp = TRUE; + + msg1.offset = child_entry->fetched_length; + msg1.header.opcode = NNPFS_MSG_INSTALLDATA; + h0 = (struct nnpfs_message_header *)&msg1; + h0_len = sizeof(msg1); + + fcacheentry2nnpfsnode (&child_fid, &child_fid, + &fetch_status, &msg2.node, dir_entry->acccache, + FCACHE2NNPFSNODE_ALL); + + child_entry->tokens |= NNPFS_ATTR_R | NNPFS_DATA_R | NNPFS_DATA_W; + msg2.node.tokens = child_entry->tokens & ~(NNPFS_DATA_MASK); + msg2.parent_handle = h->parent_handle; + strlcpy (msg2.name, h->name, sizeof(msg2.name)); + + msg2.header.opcode = NNPFS_MSG_INSTALLNODE; + h1 = (struct nnpfs_message_header *)&msg2; + h1_len = sizeof(msg2); + + msg3.node = msg2.node; + msg3.node.tokens = child_entry->tokens; + msg3.offset = child_entry->fetched_length; + msg3.header.opcode = NNPFS_MSG_INSTALLDATA; + + h2 = (struct nnpfs_message_header *)&msg3; + h2_len = sizeof(msg3); + + if (connected_mode != CONNECTED) + child_entry->disco_id = disco_create_file(&parent_fid, &child_fid, + h->name, &store_status); + + out: + nnpfs_send_message_wakeup_multiple (fd, + h->header.sequence_num, + ret, + h0, h0_len, + h1, h1_len, + h2, h2_len, + NULL, 0); + if (dir_entry) + fcache_release(dir_entry); + if (child_entry) + fcache_release(child_entry); + cred_free (ce); - child_entry->flags.kernelp = TRUE; - child_entry->flags.attrusedp = TRUE; - child_entry->flags.datausedp = TRUE; -#if 0 - assert(dir_entry->flags.attrusedp); -#endif - dir_entry->flags.datausedp = TRUE; - - msg1.header.opcode = XFS_MSG_INSTALLDATA; - h0 = (struct xfs_message_header *)&msg1; - h0_len = sizeof(msg1); - - fcacheentry2xfsnode (&child_fid, &child_fid, - &fetch_status, &msg2.node, dir_entry->acccache, - FCACHE2XFSNODE_ALL); - - msg2.node.tokens = XFS_ATTR_R - | XFS_OPEN_NW | XFS_OPEN_NR - | XFS_DATA_R | XFS_DATA_W; - msg2.parent_handle = h->parent_handle; - strlcpy (msg2.name, h->name, sizeof(msg2.name)); - - msg2.header.opcode = XFS_MSG_INSTALLNODE; - h1 = (struct xfs_message_header *)&msg2; - h1_len = sizeof(msg2); - - msg3.node = msg2.node; - msg3.header.opcode = XFS_MSG_INSTALLDATA; - - h2 = (struct xfs_message_header *)&msg3; - h2_len = sizeof(msg3); - } - - if (connected_mode != CONNECTED && res.res == 0) { - struct vcache log_ent_parent, log_ent_child; - - log_ent_parent.fid = *parent_fid; - log_ent_parent.DataVersion = dir_entry->status.DataVersion; - log_ent_parent.cred = h->cred; - - log_ent_child.fid = child_fid; - log_ent_child.DataVersion = 1; - - log_dis_create (&log_ent_parent, &log_ent_child, h->name); - } - -out: - if (dir_entry) - fcache_release(dir_entry); - if (child_entry) - fcache_release(child_entry); - cred_free (ce); - xfs_send_message_wakeup_multiple (fd, - h->header.sequence_num, - ret, - h0, h0_len, - h1, h1_len, - h2, h2_len, - NULL, 0); - - return ret; + return ret; } static int -xfs_message_mkdir (int fd, struct xfs_message_mkdir *h, u_int size) -{ - VenusFid *parent_fid, child_fid; - AFSStoreStatus store_status; - AFSFetchStatus fetch_status; - Result res; - CredCacheEntry *ce; - int ret; - struct xfs_message_installdata msg1; - struct xfs_message_installnode msg2; - struct xfs_message_installdata msg3; - FCacheEntry *dir_entry = NULL; - FCacheEntry *child_entry = NULL; - - struct xfs_message_header *h0 = NULL; - size_t h0_len = 0; - struct xfs_message_header *h1 = NULL; - size_t h1_len = 0; - struct xfs_message_header *h2 = NULL; - size_t h2_len = 0; - fcache_cache_handle cache_handle; - - struct vcache log_ent_parent, log_ent_child; - FCacheEntry parent_entry; - AFSStoreStatus log_store_status; +nnpfs_message_mkdir (int fd, struct nnpfs_message_mkdir *h, u_int size) +{ + VenusFid parent_fid, child_fid; + AFSStoreStatus store_status; + AFSFetchStatus fetch_status; + CredCacheEntry *ce; + int ret; + struct nnpfs_message_installdata msg1; + struct nnpfs_message_installnode msg2; + struct nnpfs_message_installdata msg3; + FCacheEntry *dir_entry = NULL; + FCacheEntry *child_entry = NULL; + + struct nnpfs_message_header *h0 = NULL; + size_t h0_len = 0; + struct nnpfs_message_header *h1 = NULL; + size_t h1_len = 0; + struct nnpfs_message_header *h2 = NULL; + size_t h2_len = 0; + fcache_cache_handle cache_handle; #if 0 - parent_fid = fid_translate((VenusFid *)&h->parent_handle); + parent_fid = *fid_translate((VenusFid *)&h->parent_handle); #else - parent_fid = (VenusFid *)&h->parent_handle; -#endif - arla_warnx (ADEBMSG, "mkdir (%ld.%lu.%lu.%lu) \"%s\"", - (long)parent_fid->Cell, (unsigned long)parent_fid->fid.Volume, - (unsigned long)parent_fid->fid.Vnode, - (unsigned long)parent_fid->fid.Unique, h->name); - - ce = cred_get (parent_fid->Cell, h->cred.pag, CRED_ANY); - assert (ce != NULL); - - xfs_attr2afsstorestatus(&h->attr, &store_status); - if (connected_mode != CONNECTED) { - if (!(store_status.Mask & SS_OWNER)) { - store_status.Owner = h->cred.uid; - store_status.Mask |= SS_OWNER; - } - if (!(store_status.Mask & SS_MODTIME)) { - struct timeval now; - - gettimeofday (&now, NULL); - - store_status.ClientModTime = now.tv_sec; - store_status.Mask |= SS_MODTIME; - } - } - - do { - res = cm_mkdir(parent_fid, h->name, &store_status, - &child_fid, &fetch_status, &ce); - if (res.res) - ret = res.error; - else - ret = res.res; - } while(try_again (&ret, &ce, &h->cred, parent_fid)); - - if (res.res == 0) { - - ret = message_get_data (&dir_entry, parent_fid, &h->cred, &ce); - if (ret) - goto out; - - res = conv_dir (dir_entry, ce, 0, - &cache_handle, - msg1.cache_name, - sizeof(msg1.cache_name)); - if (res.res == -1) { - ret = res.error; - goto out; - } - msg1.cache_handle = cache_handle.xfs_handle; - msg1.flag = 0; - if (cache_handle.valid) - msg1.flag |= XFS_ID_HANDLE_VALID; - msg1.node.tokens = res.tokens; - - fcacheentry2xfsnode (parent_fid, - fcache_realfid(dir_entry), - &dir_entry->status, &msg1.node, - dir_entry->acccache, - FCACHE2XFSNODE_ALL); - - msg1.header.opcode = XFS_MSG_INSTALLDATA; - h0 = (struct xfs_message_header *)&msg1; - h0_len = sizeof(msg1); - - ret = message_get_data (&child_entry, &child_fid, &h->cred, &ce); - if (ret) - goto out; - - res = conv_dir (child_entry, ce, 0, - &cache_handle, - msg3.cache_name, - sizeof(msg3.cache_name)); - if (res.res == -1) { - ret = res.error; - goto out; - } - msg3.cache_handle = cache_handle.xfs_handle; - msg3.flag = 0; - if (cache_handle.valid) - msg3.flag |= XFS_ID_HANDLE_VALID; - - child_entry->flags.attrusedp = TRUE; - child_entry->flags.datausedp = TRUE; -#if 0 - assert(dir_entry->flags.attrusedp); + parent_fid = *(VenusFid *)&h->parent_handle; #endif - dir_entry->flags.datausedp = TRUE; - - msg2.node.tokens = res.tokens; - - fcacheentry2xfsnode (&child_fid, &child_fid, - &child_entry->status, &msg2.node, - dir_entry->acccache, - FCACHE2XFSNODE_ALL); - - msg2.parent_handle = h->parent_handle; - strlcpy (msg2.name, h->name, sizeof(msg2.name)); - - msg2.header.opcode = XFS_MSG_INSTALLNODE; - h1 = (struct xfs_message_header *)&msg2; - h1_len = sizeof(msg2); - - msg3.header.opcode = XFS_MSG_INSTALLDATA; - msg3.node = msg2.node; - h2 = (struct xfs_message_header *)&msg3; - h2_len = sizeof(msg3); - if (connected_mode != CONNECTED) - parent_entry = *dir_entry; - } - - if (connected_mode != CONNECTED) { - log_ent_parent.fid = *parent_fid; - log_ent_parent.DataVersion = parent_entry.status.DataVersion; - log_ent_parent.cred = h->cred; - log_store_status = store_status; - log_ent_child.fid = child_fid; - log_ent_child.DataVersion = 1; - log_dis_mkdir (&log_ent_parent, &log_ent_child, &log_store_status, - h->name); - } - -out: - if (child_entry) - fcache_release(child_entry); - if (dir_entry) - fcache_release(dir_entry); - cred_free (ce); - xfs_send_message_wakeup_multiple (fd, - h->header.sequence_num, - ret, - h0, h0_len, - h1, h1_len, - h2, h2_len, - NULL, 0); - - return ret; -} + arla_warnx (ADEBMSG, "mkdir (%ld.%lu.%lu.%lu) \"%s\"", + (long)parent_fid.Cell, (unsigned long)parent_fid.fid.Volume, + (unsigned long)parent_fid.fid.Vnode, + (unsigned long)parent_fid.fid.Unique, h->name); -static int -xfs_message_link (int fd, struct xfs_message_link *h, u_int size) -{ - VenusFid *parent_fid, *existing_fid; - AFSFetchStatus fetch_status; - Result res; - CredCacheEntry *ce; - int ret; - struct xfs_message_installdata msg1; - struct xfs_message_installnode msg2; - struct xfs_message_header *h0 = NULL; - size_t h0_len = 0; - struct xfs_message_header *h1 = NULL; - size_t h1_len = 0; - fcache_cache_handle cache_handle; - - parent_fid = (VenusFid *)&h->parent_handle; - existing_fid = (VenusFid *)&h->from_handle; - arla_warnx (ADEBMSG, "link (%ld.%lu.%lu.%lu) (%ld.%lu.%lu.%lu) \"%s\"", - (long)parent_fid->Cell, (unsigned long)parent_fid->fid.Volume, - (unsigned long)parent_fid->fid.Vnode, - (unsigned long)parent_fid->fid.Unique, - (long)existing_fid->Cell, - (unsigned long)existing_fid->fid.Volume, - (unsigned long)existing_fid->fid.Vnode, - (unsigned long)existing_fid->fid.Unique, - h->name); - - ce = cred_get (parent_fid->Cell, h->cred.pag, CRED_ANY); - assert (ce != NULL); - - do { - res = cm_link (parent_fid, h->name, *existing_fid, - &fetch_status, &ce); - if (res.res) - ret = res.error; - else - ret = res.res; - } while (try_again (&ret, &ce, &h->cred, parent_fid)); - - if (res.res == 0) { - FCacheEntry *dir_entry; - - ret = message_get_data (&dir_entry, parent_fid, &h->cred, &ce); - if (ret) - goto out; - - res = conv_dir (dir_entry, ce, 0, - &cache_handle, - msg1.cache_name, - sizeof(msg1.cache_name)); - if (res.res == -1) { - fcache_release(dir_entry); - ret = res.error; - goto out; - } - msg1.cache_handle = cache_handle.xfs_handle; - msg1.flag = 0; - if (cache_handle.valid) - msg1.flag |= XFS_ID_HANDLE_VALID; - msg1.node.tokens = res.tokens; -#if 0 - assert(dir_entry->flags.attrusedp); -#endif - dir_entry->flags.datausedp = TRUE; + ce = cred_get (parent_fid.Cell, h->cred.pag, CRED_ANY); + assert (ce != NULL); - fcacheentry2xfsnode (parent_fid, - fcache_realfid(dir_entry), - &dir_entry->status, &msg1.node, - dir_entry->acccache, - FCACHE2XFSNODE_ALL); + nnpfs_attr2afsstorestatus(&h->attr, &store_status); + if (connected_mode != CONNECTED) { + if (!(store_status.Mask & SS_OWNER)) { + store_status.Owner = h->cred.uid; + store_status.Mask |= SS_OWNER; + } + if (!(store_status.Mask & SS_MODTIME)) { + struct timeval now; - msg1.header.opcode = XFS_MSG_INSTALLDATA; - h0 = (struct xfs_message_header *)&msg1; - h0_len = sizeof(msg1); + gettimeofday (&now, NULL); - fcacheentry2xfsnode (existing_fid, existing_fid, - &fetch_status, &msg2.node, - dir_entry->acccache, - FCACHE2XFSNODE_ALL); - fcache_release(dir_entry); + store_status.ClientModTime = now.tv_sec; + store_status.Mask |= SS_MODTIME; + } + } - msg2.node.tokens = XFS_ATTR_R; /* XXX */ - msg2.parent_handle = h->parent_handle; - strlcpy (msg2.name, h->name, sizeof(msg2.name)); + ret = fcache_get(&dir_entry, parent_fid, ce); + if (ret) + goto out; + + assert_flag(dir_entry,kernelp); - msg2.header.opcode = XFS_MSG_INSTALLNODE; - h1 = (struct xfs_message_header *)&msg2; - h1_len = sizeof(msg2); - } + do { + ret = cm_mkdir(&dir_entry, h->name, &store_status, + &child_fid, &fetch_status, &ce); + } while(try_again (&ret, &ce, &h->cred, &dir_entry->fid)); + + if (ret) + goto out; + + ret = message_get_data (&dir_entry, &h->cred, &ce, 0); + if (ret) + goto out; + + ret = conv_dir (dir_entry, ce, 0, + &cache_handle, + msg1.cache_name, + sizeof(msg1.cache_name)); + if (ret) + goto out; + + msg1.cache_handle = cache_handle.nnpfs_handle; + msg1.flag = 0; + if (cache_handle.valid) + msg1.flag |= NNPFS_ID_HANDLE_VALID; + dir_entry->tokens |= NNPFS_ATTR_R; + msg1.node.tokens = dir_entry->tokens; + + fcacheentry2nnpfsnode (&dir_entry->fid, + fcache_realfid(dir_entry), + &dir_entry->status, &msg1.node, + dir_entry->acccache, + FCACHE2NNPFSNODE_ALL); + + msg1.offset = dir_entry->fetched_length; + msg1.header.opcode = NNPFS_MSG_INSTALLDATA; + h0 = (struct nnpfs_message_header *)&msg1; + h0_len = sizeof(msg1); + + ret = fcache_get(&child_entry, child_fid, ce); + if (ret) + goto out; + ret = message_get_data (&child_entry, &h->cred, &ce, 0); + if (ret) + goto out; + + child_fid = child_entry->fid; + + ret = conv_dir (child_entry, ce, 0, + &cache_handle, + msg3.cache_name, + sizeof(msg3.cache_name)); + if (ret) + goto out; + + msg3.cache_handle = cache_handle.nnpfs_handle; + msg3.flag = 0; + if (cache_handle.valid) + msg3.flag |= NNPFS_ID_HANDLE_VALID; + + assert_flag(child_entry,kernelp); + child_entry->flags.attrusedp = TRUE; + child_entry->flags.datausedp = TRUE; + assert_flag(dir_entry,kernelp); + assert_flag(dir_entry,attrusedp); + dir_entry->flags.datausedp = TRUE; + + child_entry->tokens |= NNPFS_ATTR_R; + msg2.node.tokens = child_entry->tokens & ~(NNPFS_DATA_MASK); + + fcacheentry2nnpfsnode (&child_fid, &child_fid, + &child_entry->status, &msg2.node, + dir_entry->acccache, + FCACHE2NNPFSNODE_ALL); + + msg2.parent_handle = h->parent_handle; + strlcpy (msg2.name, h->name, sizeof(msg2.name)); + + msg2.header.opcode = NNPFS_MSG_INSTALLNODE; + h1 = (struct nnpfs_message_header *)&msg2; + h1_len = sizeof(msg2); + + msg3.header.opcode = NNPFS_MSG_INSTALLDATA; + msg3.offset = child_entry->fetched_length; + msg3.node = msg2.node; + msg3.node.tokens = child_entry->tokens; + h2 = (struct nnpfs_message_header *)&msg3; + h2_len = sizeof(msg3); + + if (connected_mode != CONNECTED) + child_entry->disco_id = disco_create_dir(&parent_fid, &child_fid, + h->name, &store_status); + + out: + nnpfs_send_message_wakeup_multiple (fd, + h->header.sequence_num, + ret, + h0, h0_len, + h1, h1_len, + h2, h2_len, + NULL, 0); + if (child_entry) + fcache_release(child_entry); + if (dir_entry) + fcache_release(dir_entry); + cred_free (ce); -out: - cred_free (ce); - xfs_send_message_wakeup_multiple (fd, - h->header.sequence_num, - ret, - h0, h0_len, - h1, h1_len, - NULL, 0); + return ret; +} - return ret; +static int +nnpfs_message_link (int fd, struct nnpfs_message_link *h, u_int size) +{ + VenusFid parent_fid, existing_fid; + AFSFetchStatus fetch_status; + CredCacheEntry *ce; + int ret; + struct nnpfs_message_installdata msg1; + struct nnpfs_message_installnode msg2; + struct nnpfs_message_header *h0 = NULL; + size_t h0_len = 0; + struct nnpfs_message_header *h1 = NULL; + size_t h1_len = 0; + fcache_cache_handle cache_handle; + FCacheEntry *dir_entry = NULL; + + parent_fid = *(VenusFid *)&h->parent_handle; + existing_fid = *(VenusFid *)&h->from_handle; + arla_warnx (ADEBMSG, "link (%ld.%lu.%lu.%lu) (%ld.%lu.%lu.%lu) \"%s\"", + (long)parent_fid.Cell, (unsigned long)parent_fid.fid.Volume, + (unsigned long)parent_fid.fid.Vnode, + (unsigned long)parent_fid.fid.Unique, + (long)existing_fid.Cell, + (unsigned long)existing_fid.fid.Volume, + (unsigned long)existing_fid.fid.Vnode, + (unsigned long)existing_fid.fid.Unique, + h->name); + + ce = cred_get (parent_fid.Cell, h->cred.pag, CRED_ANY); + assert (ce != NULL); + + ret = fcache_get(&dir_entry, parent_fid, ce); + if (ret) + goto out; + + assert_flag(dir_entry,kernelp); + + do { + ret = cm_link (&dir_entry, h->name, existing_fid, + &fetch_status, &ce); + } while (try_again (&ret, &ce, &h->cred, &dir_entry->fid)); + + if (ret) + goto out; + + ret = message_get_data (&dir_entry, &h->cred, &ce, 0); + if (ret) + goto out; + + ret = conv_dir (dir_entry, ce, 0, + &cache_handle, + msg1.cache_name, + sizeof(msg1.cache_name)); + if (ret == -1) + goto out; + + msg1.cache_handle = cache_handle.nnpfs_handle; + msg1.flag = 0; + if (cache_handle.valid) + msg1.flag |= NNPFS_ID_HANDLE_VALID; + dir_entry->tokens |= NNPFS_ATTR_R; + msg1.node.tokens = dir_entry->tokens; + assert_flag(dir_entry,kernelp); + assert_flag(dir_entry,attrusedp); + dir_entry->flags.datausedp = TRUE; + + fcacheentry2nnpfsnode (&dir_entry->fid, + fcache_realfid(dir_entry), + &dir_entry->status, &msg1.node, + dir_entry->acccache, + FCACHE2NNPFSNODE_ALL); + + msg1.offset = dir_entry->fetched_length; + msg1.header.opcode = NNPFS_MSG_INSTALLDATA; + h0 = (struct nnpfs_message_header *)&msg1; + h0_len = sizeof(msg1); + + fcacheentry2nnpfsnode (&existing_fid, &existing_fid, + &fetch_status, &msg2.node, + dir_entry->acccache, + FCACHE2NNPFSNODE_ALL); + + msg2.node.tokens = NNPFS_ATTR_R; /* XXX */ + msg2.parent_handle = h->parent_handle; + strlcpy (msg2.name, h->name, sizeof(msg2.name)); + + msg2.header.opcode = NNPFS_MSG_INSTALLNODE; + h1 = (struct nnpfs_message_header *)&msg2; + h1_len = sizeof(msg2); + + out: + nnpfs_send_message_wakeup_multiple (fd, + h->header.sequence_num, + ret, + h0, h0_len, + h1, h1_len, + NULL, 0); + if (dir_entry) + fcache_release(dir_entry); + cred_free (ce); + + return ret; } static int -xfs_message_symlink (int fd, struct xfs_message_symlink *h, u_int size) -{ - VenusFid *parent_fid, child_fid, real_fid; - AFSStoreStatus store_status; - AFSFetchStatus fetch_status; - Result res; - CredCacheEntry *ce; - int ret; - struct xfs_message_installdata msg1; - struct xfs_message_installnode msg2; - struct xfs_message_header *h0 = NULL; - size_t h0_len = 0; - struct xfs_message_header *h1 = NULL; - size_t h1_len = 0; - fcache_cache_handle cache_handle; - - parent_fid = (VenusFid *)&h->parent_handle; - arla_warnx (ADEBMSG, "symlink (%ld.%lu.%lu.%lu) \"%s\"", - (long)parent_fid->Cell, (unsigned long)parent_fid->fid.Volume, - (unsigned long)parent_fid->fid.Vnode, - (unsigned long)parent_fid->fid.Unique, h->name); - - ce = cred_get (parent_fid->Cell, h->cred.pag, CRED_ANY); - assert (ce != NULL); - - xfs_attr2afsstorestatus(&h->attr, &store_status); - - do { - res = cm_symlink(parent_fid, h->name, &store_status, - &child_fid, &real_fid, - &fetch_status, - h->contents, &ce); - ret = res.error; - } while (try_again (&ret, &ce, &h->cred, parent_fid)); +nnpfs_message_symlink (int fd, struct nnpfs_message_symlink *h, u_int size) +{ + VenusFid parent_fid, child_fid, real_fid; + AFSStoreStatus store_status; + AFSFetchStatus fetch_status; + CredCacheEntry *ce; + int ret; + struct nnpfs_message_installdata msg1; + struct nnpfs_message_installnode msg2; + struct nnpfs_message_header *h0 = NULL; + size_t h0_len = 0; + struct nnpfs_message_header *h1 = NULL; + size_t h1_len = 0; + fcache_cache_handle cache_handle; + FCacheEntry *dir_entry = NULL; + + parent_fid = *(VenusFid *)&h->parent_handle; + arla_warnx (ADEBMSG, "symlink (%ld.%lu.%lu.%lu) \"%s\"", + (long)parent_fid.Cell, (unsigned long)parent_fid.fid.Volume, + (unsigned long)parent_fid.fid.Vnode, + (unsigned long)parent_fid.fid.Unique, h->name); + + ce = cred_get (parent_fid.Cell, h->cred.pag, CRED_ANY); + assert (ce != NULL); + + nnpfs_attr2afsstorestatus(&h->attr, &store_status); + + ret = fcache_get(&dir_entry, parent_fid, ce); + if (ret) + goto out; + + assert_flag(dir_entry,kernelp); + + do { + ret = cm_symlink(&dir_entry, h->name, &store_status, + &child_fid, &real_fid, + &fetch_status, + h->contents, &ce); + } while (try_again (&ret, &ce, &h->cred, &dir_entry->fid)); - cred_free (ce); - ce = cred_get (parent_fid->Cell, h->cred.pag, CRED_ANY); - assert (ce != NULL); - - if (res.res == 0) { - FCacheEntry *dir_entry; - - ret = message_get_data (&dir_entry, parent_fid, &h->cred, &ce); - if (ret) - goto out; - - res = conv_dir (dir_entry, ce, 0, - &cache_handle, - msg1.cache_name, - sizeof(msg1.cache_name)); - if (res.res == -1) { - fcache_release(dir_entry); - ret = res.error; - goto out; - } - msg1.cache_handle = cache_handle.xfs_handle; - msg1.flag = 0; - if (cache_handle.valid) - msg1.flag |= XFS_ID_HANDLE_VALID; - msg1.node.tokens = res.tokens; -#if 0 - assert(dir_entry->flags.attrusedp); -#endif - dir_entry->flags.datausedp = TRUE; + cred_free (ce); + ce = cred_get (dir_entry->fid.Cell, h->cred.pag, CRED_ANY); + assert (ce != NULL); - fcacheentry2xfsnode (parent_fid, - fcache_realfid(dir_entry), - &dir_entry->status, &msg1.node, - dir_entry->acccache, - FCACHE2XFSNODE_ALL); - - msg1.header.opcode = XFS_MSG_INSTALLDATA; - h0 = (struct xfs_message_header *)&msg1; - h0_len = sizeof(msg1); - - fcacheentry2xfsnode (&child_fid, &real_fid, - &fetch_status, &msg2.node, - dir_entry->acccache, - FCACHE2XFSNODE_ALL); - fcache_release(dir_entry); - - msg2.node.tokens = XFS_ATTR_R; /* XXX */ - msg2.parent_handle = h->parent_handle; - strlcpy (msg2.name, h->name, sizeof(msg2.name)); - - msg2.header.opcode = XFS_MSG_INSTALLNODE; - h1 = (struct xfs_message_header *)&msg2; - h1_len = sizeof(msg2); - } - -out: - cred_free (ce); - xfs_send_message_wakeup_multiple (fd, - h->header.sequence_num, - ret, - h0, h0_len, - h1, h1_len, - NULL, 0); - return ret; + if (ret) + goto out; + + ret = message_get_data (&dir_entry, &h->cred, &ce, 0); + if (ret) + goto out; + + ret = conv_dir (dir_entry, ce, 0, + &cache_handle, + msg1.cache_name, + sizeof(msg1.cache_name)); + if (ret) + goto out; + + msg1.cache_handle = cache_handle.nnpfs_handle; + msg1.flag = 0; + if (cache_handle.valid) + msg1.flag |= NNPFS_ID_HANDLE_VALID; + dir_entry->tokens |= NNPFS_ATTR_R; + msg1.node.tokens = dir_entry->tokens; + assert_flag(dir_entry,kernelp); + assert_flag(dir_entry,attrusedp); + dir_entry->flags.datausedp = TRUE; + + fcacheentry2nnpfsnode (&dir_entry->fid, + fcache_realfid(dir_entry), + &dir_entry->status, &msg1.node, + dir_entry->acccache, + FCACHE2NNPFSNODE_ALL); + + msg1.offset = dir_entry->fetched_length; + msg1.header.opcode = NNPFS_MSG_INSTALLDATA; + h0 = (struct nnpfs_message_header *)&msg1; + h0_len = sizeof(msg1); + + fcacheentry2nnpfsnode (&child_fid, &real_fid, + &fetch_status, &msg2.node, + dir_entry->acccache, + FCACHE2NNPFSNODE_ALL); + + msg2.node.tokens = NNPFS_ATTR_R; /* XXX */ + msg2.parent_handle = h->parent_handle; + strlcpy (msg2.name, h->name, sizeof(msg2.name)); + + msg2.header.opcode = NNPFS_MSG_INSTALLNODE; + h1 = (struct nnpfs_message_header *)&msg2; + h1_len = sizeof(msg2); + + out: + nnpfs_send_message_wakeup_multiple (fd, + h->header.sequence_num, + ret, + h0, h0_len, + h1, h1_len, + NULL, 0); + if (dir_entry) + fcache_release(dir_entry); + cred_free (ce); + + return ret; } /* - * Handle the XFS remove message in `h', that is, remove name + * Handle the NNPFS remove message in `h', that is, remove name * `h->name' in directory `h->parent' with the creds from `h->cred'. */ static int -xfs_message_remove (int fd, struct xfs_message_remove *h, u_int size) -{ - VenusFid *parent_fid; - VenusFid fid; - Result res; - CredCacheEntry *ce; - int ret; - struct xfs_message_installdata msg1; - struct xfs_message_installattr msg2; - struct xfs_message_header *h0 = NULL; - size_t h0_len = 0; - struct xfs_message_header *h1 = NULL; - size_t h1_len = 0; - FCacheEntry *limbo_entry = NULL; - unsigned link_count; - FCacheEntry *dir_entry = NULL; - AFSFetchStatus limbo_status; - fcache_cache_handle cache_handle; - - parent_fid = (VenusFid *)&h->parent_handle; - arla_warnx (ADEBMSG, "remove (%ld.%lu.%lu.%lu) \"%s\"", - (long)parent_fid->Cell, (unsigned long)parent_fid->fid.Volume, - (unsigned long)parent_fid->fid.Vnode, - (unsigned long)parent_fid->fid.Unique, h->name); - - ce = cred_get (parent_fid->Cell, h->cred.pag, CRED_ANY); - assert (ce != NULL); - - do { - res = cm_lookup (parent_fid, h->name, &fid, &ce, FALSE); - if (res.res) - ret = res.error; - else - ret = res.res; - } while (try_again (&ret, &ce, &h->cred, parent_fid)); - - if (ret) - goto out; - - /* - * Fetch the linkcount of the to be removed node - */ - - ret = fcache_get (&limbo_entry, fid, ce); - if (ret) - goto out; - - ret = fcache_verify_attr (limbo_entry, NULL, NULL, ce); - if (ret) - goto out; - limbo_status = limbo_entry->status; - link_count = limbo_status.LinkCount; - - fcache_release (limbo_entry); - limbo_entry = NULL; - - /* - * Do the actual work - */ - - do { - res = cm_remove(parent_fid, h->name, &ce); - if (res.res) - ret = res.error; - else - ret = res.res; - } while (try_again (&ret, &ce, &h->cred, parent_fid)); - - if (ret == 0) { - - ret = message_get_data (&dir_entry, parent_fid, &h->cred, &ce); - if (ret) - goto out; - - if (!dir_entry->flags.extradirp - || dir_remove_name (dir_entry, h->name, - &cache_handle, - msg1.cache_name, - sizeof(msg1.cache_name))) { - res = conv_dir (dir_entry, ce, 0, - &cache_handle, - msg1.cache_name, - sizeof(msg1.cache_name)); - if (res.res == -1) { - ret = res.error; - goto out; - } - } - msg1.cache_handle = cache_handle.xfs_handle; - msg1.flag = XFS_ID_INVALID_DNLC; - if (cache_handle.valid) - msg1.flag |= XFS_ID_HANDLE_VALID; - msg1.node.tokens = res.tokens | XFS_DATA_R; - - fcacheentry2xfsnode (parent_fid, - fcache_realfid(dir_entry), - &dir_entry->status, &msg1.node, - dir_entry->acccache, - FCACHE2XFSNODE_ALL); - - msg1.header.opcode = XFS_MSG_INSTALLDATA; - h0 = (struct xfs_message_header *)&msg1; - h0_len = sizeof(msg1); - - /* - * Set datausedp since we push data to kernel in out: - */ - -#if 0 - assert(dir_entry->flags.attrusedp); -#endif - dir_entry->flags.datausedp = TRUE; - - /* - * Make sure that if the removed node is in the - * kernel it has the right linkcount since some - * might hold a reference to it. - */ - - ret = fcache_get (&limbo_entry, fid, ce); - if (ret) - goto out; - - /* - * Now insert the limbo entry to get right linkcount - */ - - ret = fcache_verify_attr (limbo_entry, dir_entry, NULL, ce); - if (ret == 0) - limbo_status = limbo_entry->status; - ret = 0; - - /* Only a silly rename when this is the last file */ - if (link_count == 1) - limbo_entry->flags.silly = TRUE; - - msg2.header.opcode = XFS_MSG_INSTALLATTR; - msg2.node.tokens = limbo_entry->tokens; - if (!limbo_entry->flags.datausedp) - msg2.node.tokens &= ~XFS_DATA_MASK; +nnpfs_message_remove (int fd, struct nnpfs_message_remove *h, u_int size) +{ + VenusFid parent_fid; + VenusFid fid; + CredCacheEntry *ce; + int ret; + struct nnpfs_message_installdata msg1; + struct nnpfs_message_installattr msg2; + struct nnpfs_message_header *h0 = NULL; + size_t h0_len = 0; + struct nnpfs_message_header *h1 = NULL; + size_t h1_len = 0; + FCacheEntry *limbo_entry = NULL; + unsigned link_count; + FCacheEntry *dir_entry = NULL; + AFSFetchStatus limbo_status; + fcache_cache_handle cache_handle; + + parent_fid = *(VenusFid *)&h->parent_handle; + arla_warnx (ADEBMSG, "remove (%ld.%lu.%lu.%lu) \"%s\"", + (long)parent_fid.Cell, (unsigned long)parent_fid.fid.Volume, + (unsigned long)parent_fid.fid.Vnode, + (unsigned long)parent_fid.fid.Unique, h->name); + + ce = cred_get (parent_fid.Cell, h->cred.pag, CRED_ANY); + assert (ce != NULL); + + ret = fcache_get(&dir_entry, parent_fid, ce); + if (ret) + goto out; + + assert_flag(dir_entry,kernelp); + + do { + ret = cm_lookup (&dir_entry, h->name, &fid, &ce, FALSE); + } while (try_again (&ret, &ce, &h->cred, &dir_entry->fid)); + + if (ret) + goto out; - if (link_count == 1 && limbo_status.LinkCount == 1) + /* + * Fetch the linkcount of the to be removed node + */ + + ret = fcache_get (&limbo_entry, fid, ce); + if (ret) + goto out; + + ret = fcache_verify_attr (limbo_entry, dir_entry, h->name, ce); + if (ret) + goto out; + limbo_status = limbo_entry->status; + link_count = limbo_status.LinkCount; + + fcache_release (limbo_entry); + limbo_entry = NULL; + + /* + * Do the actual work + */ + + do { + ret = cm_remove(&dir_entry, h->name, &ce); + } while (try_again (&ret, &ce, &h->cred, &dir_entry->fid)); + + if (ret) + goto out; + + ret = message_get_data (&dir_entry, &h->cred, &ce, 0); + if (ret) + goto out; + + if (!dir_entry->flags.extradirp + || dir_remove_name (dir_entry, h->name, + &cache_handle, + msg1.cache_name, + sizeof(msg1.cache_name))) { + ret = conv_dir (dir_entry, ce, 0, + &cache_handle, + msg1.cache_name, + sizeof(msg1.cache_name)); + if (ret) + goto out; + } + msg1.cache_handle = cache_handle.nnpfs_handle; + msg1.flag = NNPFS_ID_INVALID_DNLC; + if (cache_handle.valid) + msg1.flag |= NNPFS_ID_HANDLE_VALID; + dir_entry->tokens |= NNPFS_ATTR_R; + msg1.node.tokens = dir_entry->tokens | NNPFS_DATA_R; + + fcacheentry2nnpfsnode (&dir_entry->fid, + fcache_realfid(dir_entry), + &dir_entry->status, &msg1.node, + dir_entry->acccache, + FCACHE2NNPFSNODE_ALL); + + msg1.offset = dir_entry->fetched_length; + msg1.header.opcode = NNPFS_MSG_INSTALLDATA; + h0 = (struct nnpfs_message_header *)&msg1; + h0_len = sizeof(msg1); + + /* + * Set datausedp since we push data to kernel in out: + */ + + assert(dir_entry->flags.attrusedp); + dir_entry->flags.datausedp = TRUE; + + /* + * Make sure that if the removed node is in the kernel it has the + * right linkcount since some might hold a reference to it. + */ + + ret = fcache_get (&limbo_entry, fid, ce); + if (ret) + goto out; + + if (limbo_entry->flags.kernelp) { + /* + * Now insert the limbo entry to get right linkcount + */ + + ret = fcache_verify_attr (limbo_entry, dir_entry, NULL, ce); + if (ret == 0) + limbo_status = limbo_entry->status; + ret = 0; + + /* Only a silly rename when this is the last file */ + if (link_count == 1) + limbo_entry->flags.silly = TRUE; + + msg2.header.opcode = NNPFS_MSG_INSTALLATTR; + limbo_entry->tokens |= NNPFS_ATTR_R; + msg2.node.tokens = limbo_entry->tokens; + if (!limbo_entry->flags.datausedp) + msg2.node.tokens &= ~NNPFS_DATA_MASK; + + if (link_count == 1 && limbo_status.LinkCount == 1) --limbo_status.LinkCount; - fcacheentry2xfsnode (&fid, - fcache_realfid(limbo_entry), - &limbo_status, - &msg2.node, - limbo_entry->acccache, - FCACHE2XFSNODE_ALL); - - h1 = (struct xfs_message_header *)&msg2; - h1_len = sizeof(msg2); - - } - -out: - if (dir_entry) - fcache_release(dir_entry); - if (limbo_entry) - fcache_release (limbo_entry); - cred_free (ce); - xfs_send_message_wakeup_multiple (fd, - h->header.sequence_num, - ret, - h0, h0_len, - h1, h1_len, - NULL, 0); - return ret; + fcacheentry2nnpfsnode (&fid, + fcache_realfid(limbo_entry), + &limbo_status, + &msg2.node, + limbo_entry->acccache, + FCACHE2NNPFSNODE_ALL); + + h1 = (struct nnpfs_message_header *)&msg2; + h1_len = sizeof(msg2); + } + + out: + nnpfs_send_message_wakeup_multiple (fd, + h->header.sequence_num, + ret, + h0, h0_len, + h1, h1_len, + NULL, 0); + if (dir_entry) + fcache_release(dir_entry); + if (limbo_entry) + fcache_release (limbo_entry); + cred_free (ce); + + return ret; } static int -xfs_message_rmdir (int fd, struct xfs_message_rmdir *h, u_int size) -{ - VenusFid *parent_fid, fid; - Result res; - CredCacheEntry *ce; - int ret; - struct xfs_message_installdata msg0; - struct xfs_message_header *h0 = NULL; - size_t h0_len = 0; - struct xfs_message_installattr msg1; - struct xfs_message_header *h1 = NULL; - size_t h1_len = 0; - FCacheEntry *limbo_entry = NULL; - FCacheEntry *dir_entry = NULL; - unsigned link_count = 0; - fcache_cache_handle cache_handle; - - parent_fid = (VenusFid *)&h->parent_handle; - arla_warnx (ADEBMSG, "rmdir (%ld.%lu.%lu.%lu) \"%s\"", - (long)parent_fid->Cell, (unsigned long)parent_fid->fid.Volume, - (unsigned long)parent_fid->fid.Vnode, - (unsigned long)parent_fid->fid.Unique, h->name); - - ce = cred_get (parent_fid->Cell, h->cred.pag, CRED_ANY); - assert (ce != NULL); - - /* - * Fetch the child-entry fid. - */ - - do { - res = cm_lookup (parent_fid, h->name, &fid, &ce, FALSE); - if (res.res) - ret = res.error; - else - ret = res.res; - } while (try_again (&ret, &ce, &h->cred, parent_fid)); - - if (ret) - goto out; - - /* - * Need to get linkcount for silly rename. - */ - - ret = fcache_get (&limbo_entry, fid, ce); - if (ret) - goto out; - - ret = fcache_verify_attr (limbo_entry, NULL, NULL, ce); - if (ret) - goto out; - link_count = limbo_entry->status.LinkCount; - - fcache_release (limbo_entry); - limbo_entry = NULL; - - /* - * Do the actual work - */ - - do { - res = cm_rmdir(parent_fid, h->name, &ce); - if (res.res) - ret = res.error; - else - ret = res.res; - } while (try_again (&ret, &ce, &h->cred, parent_fid)); - - if (res.res == 0) { - - ret = message_get_data (&dir_entry, parent_fid, &h->cred, &ce); - if (ret) - goto out; - - if (!dir_entry->flags.extradirp - || dir_remove_name (dir_entry, h->name, - &cache_handle, - msg0.cache_name, - sizeof(msg0.cache_name))) { - res = conv_dir (dir_entry, ce, 0, - &cache_handle, - msg0.cache_name, - sizeof(msg0.cache_name)); - if (res.res == -1) { - ret = res.error; - goto out; - } - } - msg0.cache_handle = cache_handle.xfs_handle; - msg0.flag = XFS_ID_INVALID_DNLC; - if (cache_handle.valid) - msg0.flag |= XFS_ID_HANDLE_VALID; - - msg0.node.tokens = res.tokens; - - fcacheentry2xfsnode (parent_fid, - fcache_realfid(dir_entry), - &dir_entry->status, &msg0.node, - dir_entry->acccache, - FCACHE2XFSNODE_ALL); - - msg0.header.opcode = XFS_MSG_INSTALLDATA; - h0 = (struct xfs_message_header *)&msg0; - h0_len = sizeof(msg0); - - ret = fcache_get (&limbo_entry, fid, ce); - if (ret) - goto out; - - /* Only silly rename when this is the last reference. */ - - if (link_count == 2) - limbo_entry->flags.silly = TRUE; - - if (limbo_entry->flags.kernelp) { - - ret = fcache_verify_attr (limbo_entry, NULL, NULL, ce); - if (ret) - goto out; - - msg1.header.opcode = XFS_MSG_INSTALLATTR; - msg1.node.tokens = limbo_entry->tokens; - if (!limbo_entry->flags.datausedp) - msg1.node.tokens &= ~XFS_DATA_MASK; - - if (link_count == 2 && limbo_entry->status.LinkCount == 2) - limbo_entry->status.LinkCount = 0; - fcacheentry2xfsnode (&fid, - fcache_realfid(limbo_entry), - &limbo_entry->status, - &msg1.node, - limbo_entry->acccache, - FCACHE2XFSNODE_ALL); - - h1 = (struct xfs_message_header *)&msg1; - h1_len = sizeof(msg1); - } -#if 0 - assert(dir_entry->flags.attrusedp); -#endif - dir_entry->flags.datausedp = TRUE; - } +nnpfs_message_rmdir (int fd, struct nnpfs_message_rmdir *h, u_int size) +{ + VenusFid parent_fid, fid; + CredCacheEntry *ce; + int ret; + struct nnpfs_message_installdata msg0; + struct nnpfs_message_header *h0 = NULL; + size_t h0_len = 0; + struct nnpfs_message_installattr msg1; + struct nnpfs_message_header *h1 = NULL; + size_t h1_len = 0; + FCacheEntry *limbo_entry = NULL; + FCacheEntry *dir_entry = NULL; + unsigned link_count = 0; + fcache_cache_handle cache_handle; + + parent_fid = *(VenusFid *)&h->parent_handle; + arla_warnx (ADEBMSG, "rmdir (%ld.%lu.%lu.%lu) \"%s\"", + (long)parent_fid.Cell, (unsigned long)parent_fid.fid.Volume, + (unsigned long)parent_fid.fid.Vnode, + (unsigned long)parent_fid.fid.Unique, h->name); + + ce = cred_get (parent_fid.Cell, h->cred.pag, CRED_ANY); + assert (ce != NULL); + + /* + * Fetch the child-entry fid. + */ + + ret = fcache_get(&dir_entry, parent_fid, ce); + if (ret) + goto out; + + assert_flag(dir_entry,kernelp); + + do { + ret = cm_lookup (&dir_entry, h->name, &fid, &ce, FALSE); + } while (try_again (&ret, &ce, &h->cred, &dir_entry->fid)); + + if (ret) + goto out; + + if (VenusFid_cmp(&dir_entry->fid, &fid) == 0) { + ret = EINVAL; + goto out; + } + + /* + * Need to get linkcount for silly rename. + */ + + ret = fcache_get (&limbo_entry, fid, ce); + if (ret) + goto out; + + ret = fcache_verify_attr (limbo_entry, dir_entry, h->name, ce); + if (ret) + goto out; + link_count = limbo_entry->status.LinkCount; + + fcache_release (limbo_entry); + limbo_entry = NULL; + + /* + * Do the actual work + */ -out: - if (dir_entry) - fcache_release(dir_entry); - if (limbo_entry) - fcache_release (limbo_entry); + do { + ret = cm_rmdir(&dir_entry, h->name, &ce); + } while (try_again (&ret, &ce, &h->cred, &dir_entry->fid)); + + if (ret) + goto out; + + ret = message_get_data (&dir_entry, &h->cred, &ce, 0); + if (ret) + goto out; + + if (!dir_entry->flags.extradirp + || dir_remove_name (dir_entry, h->name, + &cache_handle, + msg0.cache_name, + sizeof(msg0.cache_name))) { + ret = conv_dir (dir_entry, ce, 0, + &cache_handle, + msg0.cache_name, + sizeof(msg0.cache_name)); + if (ret) + goto out; + } + msg0.cache_handle = cache_handle.nnpfs_handle; + msg0.flag = NNPFS_ID_INVALID_DNLC; + if (cache_handle.valid) + msg0.flag |= NNPFS_ID_HANDLE_VALID; + + dir_entry->tokens |= NNPFS_ATTR_R; + msg0.node.tokens = dir_entry->tokens; + + fcacheentry2nnpfsnode (&dir_entry->fid, + fcache_realfid(dir_entry), + &dir_entry->status, &msg0.node, + dir_entry->acccache, + FCACHE2NNPFSNODE_ALL); + + msg0.offset = dir_entry->fetched_length; + msg0.header.opcode = NNPFS_MSG_INSTALLDATA; + h0 = (struct nnpfs_message_header *)&msg0; + h0_len = sizeof(msg0); - cred_free (ce); - xfs_send_message_wakeup_multiple (fd, - h->header.sequence_num, - ret, - h0, h0_len, - h1, h1_len, - NULL, 0); - return ret; + ret = fcache_get (&limbo_entry, fid, ce); + if (ret) + goto out; + + /* Only silly rename when this is the last reference. */ + + if (link_count == 2) + limbo_entry->flags.silly = TRUE; + + if (limbo_entry->flags.kernelp) { + + ret = fcache_verify_attr (limbo_entry, dir_entry, NULL, ce); + if (ret) + goto out; + + msg1.header.opcode = NNPFS_MSG_INSTALLATTR; + limbo_entry->tokens |= NNPFS_ATTR_R; + msg1.node.tokens = limbo_entry->tokens; + if (!limbo_entry->flags.datausedp) + msg1.node.tokens &= ~NNPFS_DATA_MASK; + + if (link_count == 2 && limbo_entry->status.LinkCount == 2) + limbo_entry->status.LinkCount = 0; + fcacheentry2nnpfsnode (&fid, + fcache_realfid(limbo_entry), + &limbo_entry->status, + &msg1.node, + limbo_entry->acccache, + FCACHE2NNPFSNODE_ALL); + + h1 = (struct nnpfs_message_header *)&msg1; + h1_len = sizeof(msg1); + } + assert_flag(dir_entry,kernelp); + assert_flag(dir_entry,attrusedp); + dir_entry->flags.datausedp = TRUE; + + out: + nnpfs_send_message_wakeup_multiple (fd, + h->header.sequence_num, + ret, + h0, h0_len, + h1, h1_len, + NULL, 0); + if (dir_entry) + fcache_release(dir_entry); + if (limbo_entry) + fcache_release (limbo_entry); + + cred_free (ce); + + return ret; } static int -xfs_message_rename (int fd, struct xfs_message_rename *h, u_int size) -{ - VenusFid *old_parent_fid; - VenusFid *new_parent_fid; - VenusFid child_fid; - Result res; - CredCacheEntry *ce; - int ret; - struct xfs_message_installdata msg1; - struct xfs_message_installdata msg2; - struct xfs_message_installdata msg3; - struct xfs_message_header *h0 = NULL; - size_t h0_len = 0; - struct xfs_message_header *h1 = NULL; - size_t h1_len = 0; - struct xfs_message_header *h2 = NULL; - size_t h2_len = 0; - FCacheEntry *old_entry = NULL; - FCacheEntry *new_entry = NULL; - FCacheEntry *child_entry = NULL; - int update_child = 0; - fcache_cache_handle cache_handle; - - old_parent_fid = (VenusFid *)&h->old_parent_handle; - new_parent_fid = (VenusFid *)&h->new_parent_handle; - arla_warnx (ADEBMSG, - "rename (%ld.%lu.%lu.%lu) (%ld.%lu.%lu.%lu) \"%s\" \"%s\"", - (long)old_parent_fid->Cell, - (unsigned long)old_parent_fid->fid.Volume, - (unsigned long)old_parent_fid->fid.Vnode, - (unsigned long)old_parent_fid->fid.Unique, - (long)new_parent_fid->Cell, - (unsigned long)new_parent_fid->fid.Volume, - (unsigned long)new_parent_fid->fid.Vnode, - (unsigned long)new_parent_fid->fid.Unique, - h->old_name, - h->new_name); - - ce = cred_get (old_parent_fid->Cell, h->cred.pag, CRED_ANY); - assert (ce != NULL); - - do { - res = cm_rename(old_parent_fid, h->old_name, - new_parent_fid, h->new_name, - &child_fid, &update_child, &ce); - if (res.res) - ret = res.error; - else - ret = res.res; - } while (try_again (&ret, &ce, &h->cred, old_parent_fid)); - - if (res.res == 0) { - - ret = message_get_data (&old_entry, old_parent_fid, &h->cred, &ce); - if (ret) - goto out; - - if (!old_entry->flags.extradirp - || dir_remove_name (old_entry, h->old_name, - &cache_handle, - msg1.cache_name, - sizeof(msg1.cache_name))) { - res = conv_dir (old_entry, ce, 0, - &cache_handle, - msg1.cache_name, - sizeof(msg1.cache_name)); - if (res.res == -1) { - ret = res.error; - goto out; - } - } - msg1.cache_handle = cache_handle.xfs_handle; - msg1.flag = XFS_ID_INVALID_DNLC; - if (cache_handle.valid) - msg1.flag |= XFS_ID_HANDLE_VALID; - - msg1.node.tokens = res.tokens; - - fcacheentry2xfsnode (old_parent_fid, - fcache_realfid(old_entry), - &old_entry->status, &msg1.node, - old_entry->acccache, - FCACHE2XFSNODE_ALL); - - msg1.header.opcode = XFS_MSG_INSTALLDATA; - h0 = (struct xfs_message_header *)&msg1; - h0_len = sizeof(msg1); - - - /* - * If the new parent is the same as the old parent, reuse - */ - - if (VenusFid_cmp(new_parent_fid, old_parent_fid) == 0) { - new_entry = old_entry; - old_entry = NULL; - } else { - ret = fcache_get (&new_entry, *new_parent_fid, ce); - if (ret) - goto out; - } +nnpfs_message_rename (int fd, struct nnpfs_message_rename *h, u_int size) +{ + VenusFid old_parent_fid; + VenusFid new_parent_fid; + VenusFid child_fid; + CredCacheEntry *ce; + int ret; + struct nnpfs_message_installdata msg1; + struct nnpfs_message_installdata msg2; + struct nnpfs_message_installdata msg3; + struct nnpfs_message_header *h0 = NULL; + size_t h0_len = 0; + struct nnpfs_message_header *h1 = NULL; + size_t h1_len = 0; + struct nnpfs_message_header *h2 = NULL; + size_t h2_len = 0; + FCacheEntry *old_entry = NULL; + FCacheEntry *new_entry = NULL; + FCacheEntry *child_entry = NULL; + int update_child = 0; + fcache_cache_handle cache_handle; + int diff_dir = 0; + + old_parent_fid = *(VenusFid *)&h->old_parent_handle; + new_parent_fid = *(VenusFid *)&h->new_parent_handle; + arla_warnx (ADEBMSG, + "rename (%ld.%lu.%lu.%lu) (%ld.%lu.%lu.%lu) \"%s\" \"%s\"", + (long)old_parent_fid.Cell, + (unsigned long)old_parent_fid.fid.Volume, + (unsigned long)old_parent_fid.fid.Vnode, + (unsigned long)old_parent_fid.fid.Unique, + (long)new_parent_fid.Cell, + (unsigned long)new_parent_fid.fid.Volume, + (unsigned long)new_parent_fid.fid.Vnode, + (unsigned long)new_parent_fid.fid.Unique, + h->old_name, + h->new_name); + + ce = cred_get (old_parent_fid.Cell, h->cred.pag, CRED_ANY); + assert (ce != NULL); + + diff_dir = VenusFid_cmp (&old_parent_fid, &new_parent_fid); + + ret = fcache_get(&old_entry, old_parent_fid, ce); + if (ret) + goto out; + + assert_flag(old_entry,kernelp); + + if (diff_dir) { + ret = fcache_get(&new_entry, new_parent_fid, ce); + if (ret) + goto out; + } else { + new_entry = old_entry; + } + + assert_flag(new_entry,kernelp); + + do { + ret = cm_rename(&old_entry, h->old_name, + &new_entry, h->new_name, + &child_fid, &update_child, &ce); + } while (try_again (&ret, &ce, &h->cred, &old_entry->fid)); + + if (ret) + goto out; + + ret = message_get_data (&old_entry, &h->cred, &ce, 0); + if (ret) + goto out; + + if (!old_entry->flags.extradirp + || dir_remove_name (old_entry, h->old_name, + &cache_handle, + msg1.cache_name, + sizeof(msg1.cache_name))) { + ret = conv_dir (old_entry, ce, 0, + &cache_handle, + msg1.cache_name, + sizeof(msg1.cache_name)); + if (ret) + goto out; + } + msg1.cache_handle = cache_handle.nnpfs_handle; + msg1.flag = NNPFS_ID_INVALID_DNLC; + if (cache_handle.valid) + msg1.flag |= NNPFS_ID_HANDLE_VALID; + + old_entry->tokens |= NNPFS_ATTR_R; + msg1.node.tokens = old_entry->tokens; + + fcacheentry2nnpfsnode (&old_entry->fid, + fcache_realfid(old_entry), + &old_entry->status, &msg1.node, + old_entry->acccache, + FCACHE2NNPFSNODE_ALL); + + msg1.offset = old_entry->fetched_length; + msg1.header.opcode = NNPFS_MSG_INSTALLDATA; + h0 = (struct nnpfs_message_header *)&msg1; + h0_len = sizeof(msg1); + + ret = fcache_get_data (&new_entry, &ce, 0); /* XXX - fake_mp? */ + if (ret) + goto out; + + ret = conv_dir (new_entry, ce, 0, + &cache_handle, + msg2.cache_name, + sizeof(msg2.cache_name)); + if (ret) + goto out; + + msg2.cache_handle = cache_handle.nnpfs_handle; + msg2.flag = NNPFS_ID_INVALID_DNLC; + if (cache_handle.valid) + msg2.flag |= NNPFS_ID_HANDLE_VALID; + + new_entry->tokens |= NNPFS_ATTR_R; + msg2.node.tokens = new_entry->tokens; + + fcacheentry2nnpfsnode (&new_entry->fid, + fcache_realfid(new_entry), + &new_entry->status, &msg2.node, + new_entry->acccache, + FCACHE2NNPFSNODE_ALL); + + msg2.offset = new_entry->fetched_length; + msg2.header.opcode = NNPFS_MSG_INSTALLDATA; + h1 = (struct nnpfs_message_header *)&msg2; + h1_len = sizeof(msg2); + + if (old_entry) { + assert_flag(old_entry,kernelp); + assert_flag(old_entry,attrusedp); + old_entry->flags.datausedp = TRUE; + } + assert_flag(new_entry,kernelp); + assert_flag(new_entry,attrusedp); + new_entry->flags.datausedp = TRUE; + + if (update_child) { + ret = fcache_get(&child_entry, child_fid, ce); + if (ret) + goto out; + ret = message_get_data (&child_entry, &h->cred, &ce, 0); + if (ret) { + fcache_release(child_entry); + goto out; + } + child_fid = child_entry->fid; - ret = fcache_verify_data (new_entry, ce); /* XXX - fake_mp? */ - if (ret) - goto out; + ret = conv_dir (child_entry, ce, 0, + &cache_handle, + msg3.cache_name, + sizeof(msg3.cache_name)); + if (ret) + goto out; + + msg3.cache_handle = cache_handle.nnpfs_handle; + msg3.flag = NNPFS_ID_INVALID_DNLC; + if (cache_handle.valid) + msg3.flag |= NNPFS_ID_HANDLE_VALID; - res = conv_dir (new_entry, ce, 0, - &cache_handle, - msg2.cache_name, - sizeof(msg2.cache_name)); - if (res.res == -1) { - ret = res.error; - goto out; - } - msg2.cache_handle = cache_handle.xfs_handle; - msg2.flag = XFS_ID_INVALID_DNLC; - if (cache_handle.valid) - msg2.flag |= XFS_ID_HANDLE_VALID; - - msg2.node.tokens = res.tokens; + child_entry->tokens |= NNPFS_ATTR_R; + msg3.node.tokens = child_entry->tokens; - fcacheentry2xfsnode (new_parent_fid, - fcache_realfid(new_entry), - &new_entry->status, &msg2.node, - new_entry->acccache, - FCACHE2XFSNODE_ALL); + fcacheentry2nnpfsnode (&child_fid, + fcache_realfid(child_entry), + &child_entry->status, &msg3.node, + child_entry->acccache, + FCACHE2NNPFSNODE_ALL); - msg2.header.opcode = XFS_MSG_INSTALLDATA; - h1 = (struct xfs_message_header *)&msg2; - h1_len = sizeof(msg2); + msg3.offset = child_entry->fetched_length; + msg3.header.opcode = NNPFS_MSG_INSTALLDATA; + h2 = (struct nnpfs_message_header *)&msg3; + h2_len = sizeof(msg3); + } - if (old_entry) { -#if 0 - assert(old_entry->flags.attrusedp); -#endif - old_entry->flags.datausedp = TRUE; - } -#if 0 - assert(new_entry->flags.attrusedp); -#endif - new_entry->flags.datausedp = TRUE; - - if (update_child) { - ret = message_get_data (&child_entry, &child_fid, &h->cred, &ce); - if (ret) - goto out; - - res = conv_dir (child_entry, ce, 0, - &cache_handle, - msg3.cache_name, - sizeof(msg3.cache_name)); - if (res.res == -1) { - ret = res.error; - goto out; - } - msg3.cache_handle = cache_handle.xfs_handle; - msg3.flag = XFS_ID_INVALID_DNLC; - if (cache_handle.valid) - msg3.flag |= XFS_ID_HANDLE_VALID; - - msg3.node.tokens = res.tokens; - - fcacheentry2xfsnode (&child_fid, - fcache_realfid(child_entry), - &child_entry->status, &msg3.node, - child_entry->acccache, - FCACHE2XFSNODE_ALL); - - msg3.header.opcode = XFS_MSG_INSTALLDATA; - h2 = (struct xfs_message_header *)&msg3; - h2_len = sizeof(msg3); - } - } - -out: - if (old_entry) fcache_release(old_entry); - if (new_entry) fcache_release(new_entry); - if (child_entry) fcache_release(child_entry); + out: + nnpfs_send_message_wakeup_multiple (fd, + h->header.sequence_num, + ret, + h0, h0_len, + h1, h1_len, + NULL, 0); + if (old_entry) fcache_release(old_entry); + if (new_entry && diff_dir) fcache_release(new_entry); + if (child_entry) fcache_release(child_entry); - cred_free (ce); - xfs_send_message_wakeup_multiple (fd, - h->header.sequence_num, - ret, - h0, h0_len, - h1, h1_len, - NULL, 0); + cred_free (ce); - return ret; + return ret; } static int -xfs_message_putdata (int fd, struct xfs_message_putdata *h, u_int size) -{ - VenusFid *fid; - Result res; - CredCacheEntry *ce; - int ret; - AFSStoreStatus status; - struct vcache log_cache; - FCacheEntry *fce; - int log_err; - - fid = (VenusFid *)&h->handle; - arla_warnx (ADEBMSG, "putdata (%ld.%lu.%lu.%lu)", - (long)fid->Cell, (unsigned long)fid->fid.Volume, - (unsigned long)fid->fid.Vnode, - (unsigned long)fid->fid.Unique); - - xfs_attr2afsstorestatus(&h->attr, &status); - - ce = cred_get (fid->Cell, h->cred.pag, CRED_ANY); - assert (ce != NULL); - - if (connected_mode != CONNECTED) { - ret = fcache_find (&fce, *fid); - - ReleaseWriteLock (&fce->lock); - - log_cache.fid = *fid; - log_cache.cred = h->cred; - } - - do { - res = cm_close(*fid, h->flag, &status, ce); - if (res.res) - ret = res.error; - else - ret = res.res; - } while (try_again (&ret, &ce, &h->cred, fid)); +nnpfs_message_putdata (int fd, struct nnpfs_message_putdata *h, u_int size) +{ + VenusFid fid; + CredCacheEntry *ce; + int ret; + AFSStoreStatus status; + FCacheEntry *entry = NULL; + + fid = *(VenusFid *)&h->handle; + arla_warnx (ADEBMSG, "putdata (%ld.%lu.%lu.%lu)", + (long)fid.Cell, (unsigned long)fid.fid.Volume, + (unsigned long)fid.fid.Vnode, + (unsigned long)fid.fid.Unique); + + nnpfs_attr2afsstorestatus(&h->attr, &status); + + ce = cred_get (fid.Cell, h->cred.pag, CRED_ANY); + assert (ce != NULL); + + if (connected_mode != CONNECTED) { + ret = fcache_find (&entry, fid); + if (ret) { + ret = ENETDOWN; + goto out; + } + } else { + ret = fcache_get (&entry, fid, ce); + if (ret) + goto out; + } + + assert_flag(entry,kernelp); + + do { + ret = cm_close(entry, h->flag, &status, ce); + } while (try_again (&ret, &ce, &h->cred, &fid)); + + if (ret) { + arla_warn (ADEBMSG, ret, "nnpfs_message_putdata: cm_close"); + goto out; + } + + if (connected_mode != CONNECTED) + entry->disco_id = disco_store_data(&fid, &status, entry->disco_id); + + out: + if (entry) + fcache_release(entry); + cred_free (ce); + nnpfs_send_message_wakeup (fd, h->header.sequence_num, ret); + return 0; +} + +static void +prefetch_data(FCacheEntry **e, CredCacheEntry **ce) +{ + FCacheEntry *entry = *e; + int ret = 0; + + if (entry->status.FileType != TYPE_FILE) + return; + + if (entry->status.Length > entry->fetched_length) { + size_t offset; + + offset = entry->fetched_length + stats_prefetch(NULL, -1); + if (offset > entry->status.Length) + offset = entry->status.Length; + arla_warnx (ADEBMSG, " prefetching to %lu", (unsigned long)offset); + ret = fcache_get_data (e, ce, offset); + arla_warnx (ADEBMSG, " prefetched returned %d", ret); + } + + return; +} + +static int +nnpfs_message_open (int fd, struct nnpfs_message_open *h, u_int size) +{ + struct nnpfs_message_installdata msg; + FCacheEntry *entry = NULL; + CredCacheEntry *ce; + AccessEntry *ae; + VenusFid fid; + int ret; + + fid = *(VenusFid *)&h->handle; + arla_warnx (ADEBMSG, "open (%ld.%lu.%lu.%lu)", + (long)fid.Cell, (unsigned long)fid.fid.Volume, + (unsigned long)fid.fid.Vnode, + (unsigned long)fid.fid.Unique); + + ce = cred_get (fid.Cell, h->cred.pag, CRED_ANY); + assert (ce != NULL); + + ret = fcache_get(&entry, fid, ce); + if (ret) + goto out; + + assert_flag(entry,kernelp); + + tryagain: + + ret = cm_getattr (entry, ce, &ae); + + if (try_again (&ret, &ce, &h->cred, &fid)) + goto tryagain; + if (ret) + goto out; + + msg.flag = 0; + + if (entry->status.FileType == TYPE_DIR) { + fcache_cache_handle cache_handle; + + if (h->tokens & NNPFS_DATA_W) { + ret = EACCES; + goto out; + } + + ret = fcache_get_data (&entry, &ce, entry->status.Length); + if (try_again (&ret, &ce, &h->cred, &fid)) + goto tryagain; + if (ret) + goto out; + fid = entry->fid; + + fcacheentry2nnpfsnode (&fid, fcache_realfid(entry), + &entry->status, &msg.node, ae, + FCACHE2NNPFSNODE_ALL); + + ret = conv_dir (entry, ce, h->tokens, + &cache_handle, + msg.cache_name, + sizeof(msg.cache_name)); + + if (ret) + goto out; + + entry->tokens |= h->tokens; + entry->tokens |= NNPFS_ATTR_R; + msg.node.tokens = entry->tokens; + msg.flag = NNPFS_ID_INVALID_DNLC; + msg.cache_handle = cache_handle.nnpfs_handle; + if (cache_handle.valid) + msg.flag |= NNPFS_ID_HANDLE_VALID; + msg.offset = entry->fetched_length; - if (ret == 0) { - if (connected_mode != CONNECTED) { - log_cache.DataVersion = ++fce->status.DataVersion; - log_err = log_dis_store (&log_cache); - } - } else { - arla_warn (ADEBMSG, ret, "xfs_message_putdata: cm_close"); - } + assert_flag(entry,kernelp); + entry->flags.attrusedp = TRUE; + entry->flags.datausedp = TRUE; + + } else { + ret = cm_open (entry, ce, h->tokens); + if (try_again (&ret, &ce, &h->cred, &fid)) + goto tryagain; + if (ret) + goto out; + + fcache_conv_file_name (entry, msg.cache_name, sizeof(msg.cache_name)); + + msg.cache_handle = entry->handle.nnpfs_handle; + entry->tokens |= NNPFS_ATTR_R | NNPFS_DATA_R; + msg.node.tokens = entry->tokens; + msg.offset = entry->fetched_length; + fcacheentry2nnpfsnode (&fid, fcache_realfid(entry), + &entry->status, &msg.node, ae, + FCACHE2NNPFSNODE_ALL); + if (entry->handle.valid) + msg.flag |= NNPFS_ID_HANDLE_VALID; + } + + msg.header.opcode = NNPFS_MSG_INSTALLDATA; - cred_free (ce); - xfs_send_message_wakeup (fd, h->header.sequence_num, ret); - return 0; + nnpfs_send_message_wakeup_multiple (fd, + h->header.sequence_num, + ret, + &msg, sizeof(msg), + NULL, 0); + + prefetch_data(&entry, &ce); + + fcache_release(entry); + cred_free (ce); + return ret; + + out: + + if (entry) + fcache_release(entry); + cred_free (ce); + nnpfs_send_message_wakeup_multiple (fd, + h->header.sequence_num, + ret, + NULL, 0); + return ret; } static int -xfs_message_getdata (int fd, struct xfs_message_getdata *h, u_int size) -{ - struct xfs_message_installdata msg; - VenusFid *fid; - VenusFid real_fid; - Result res; - AFSFetchStatus status; - CredCacheEntry *ce; - int ret; - AccessEntry *ae; - struct xfs_message_header *h0 = NULL; - size_t h0_len = 0; - fcache_cache_handle cache_handle; - - fid = (VenusFid *)&h->handle; - arla_warnx (ADEBMSG, "getdata (%ld.%lu.%lu.%lu)", - (long)fid->Cell, (unsigned long)fid->fid.Volume, - (unsigned long)fid->fid.Vnode, - (unsigned long)fid->fid.Unique); - - ce = cred_get (fid->Cell, h->cred.pag, CRED_ANY); - assert (ce != NULL); - - do { - res = cm_getattr (*fid, &status, &real_fid, ce, &ae); - if (res.res) - ret = res.error; - else - ret = res.res; - } while (try_again (&ret, &ce, &h->cred, fid)); - - if (ret == 0) { - if (status.FileType == TYPE_DIR) { - FCacheEntry *entry; - - ret = message_get_data (&entry, fid, &h->cred, &ce); - if (ret) - goto out; - - fcacheentry2xfsnode (fid, fcache_realfid(entry), - &entry->status, &msg.node, ae, - FCACHE2XFSNODE_ALL); - - res = conv_dir (entry, ce, h->tokens, - &cache_handle, - msg.cache_name, - sizeof(msg.cache_name)); - if (res.res) - ret = res.error; - - if (ret == 0) { - msg.node.tokens = res.tokens; - msg.cache_handle = cache_handle.xfs_handle; - msg.flag = XFS_ID_INVALID_DNLC; - if (cache_handle.valid) - msg.flag |= XFS_ID_HANDLE_VALID; - - entry->flags.attrusedp = TRUE; - entry->flags.datausedp = TRUE; - } - fcache_release(entry); - } else { - do { - res = cm_open (fid, &ce, h->tokens, &cache_handle, - msg.cache_name, sizeof(msg.cache_name)); - if (res.res) - ret = res.error; - else - ret = res.res; - } while (try_again (&ret, &ce, &h->cred, fid)); - if (ret == 0) { - msg.cache_handle = cache_handle.xfs_handle; - msg.flag = 0; - if (cache_handle.valid) - msg.flag |= XFS_ID_HANDLE_VALID; - msg.node.tokens = res.tokens; - fcacheentry2xfsnode (fid, &real_fid, - &status, &msg.node, ae, - FCACHE2XFSNODE_ALL); - } - } - } - - if (ret == 0) { - msg.header.opcode = XFS_MSG_INSTALLDATA; - h0 = (struct xfs_message_header *)&msg; - h0_len = sizeof(msg); - } - -out: - cred_free (ce); - xfs_send_message_wakeup_multiple (fd, - h->header.sequence_num, - ret, - h0, h0_len, - NULL, 0); - - return ret; +nnpfs_message_getdata (int fd, struct nnpfs_message_getdata *h, u_int size) +{ + struct nnpfs_message_installdata msg; + VenusFid fid; + CredCacheEntry *ce; + int ret; + AccessEntry *ae; + size_t offset; + FCacheEntry *entry = NULL; + + fid = *(VenusFid *)&h->handle; + arla_warnx (ADEBMSG, "getdata (%ld.%lu.%lu.%lu)", + (long)fid.Cell, (unsigned long)fid.fid.Volume, + (unsigned long)fid.fid.Vnode, + (unsigned long)fid.fid.Unique); + + ce = cred_get (fid.Cell, h->cred.pag, CRED_ANY); + assert (ce != NULL); + + ret = fcache_get(&entry, fid, ce); + if (ret) + goto out; + + assert_flag(entry,kernelp); + + tryagain: + + ret = cm_getattr (entry, ce, &ae); + + if (try_again (&ret, &ce, &h->cred, &fid)) + goto tryagain; + if (ret) + goto out; + + if (entry->status.FileType == TYPE_DIR) { + offset = entry->status.Length; + } else { + offset = h->offset; + if (offset > entry->status.Length) + offset = entry->status.Length; + } + + arla_warnx (ADEBMSG, " requested to byte %lu fetching to byte %lu", + (unsigned long)h->offset, (unsigned long)offset); + + ret = fcache_get_data (&entry, &ce, offset); + if (try_again (&ret, &ce, &h->cred, &fid)) + goto tryagain; + if (ret) + goto out; + + if (entry->status.FileType == TYPE_DIR) { + fcache_cache_handle cache_handle; + + ret = conv_dir (entry, ce, h->tokens, + &cache_handle, + msg.cache_name, + sizeof(msg.cache_name)); + if (ret) + goto out; + msg.cache_handle = cache_handle.nnpfs_handle; + msg.flag = NNPFS_ID_INVALID_DNLC; + if (cache_handle.valid) + msg.flag |= NNPFS_ID_HANDLE_VALID; + } else { + fcache_conv_file_name(entry, msg.cache_name, sizeof(msg.cache_name)); + msg.cache_handle = entry->handle.nnpfs_handle; + msg.flag = 0; + if (entry->handle.valid) + msg.flag |= NNPFS_ID_HANDLE_VALID; + } + + entry->flags.datausedp = TRUE; + entry->tokens |= NNPFS_ATTR_R | NNPFS_DATA_R; + if (h->tokens & NNPFS_DATA_W) + entry->tokens |= NNPFS_DATA_W; + msg.node.tokens = entry->tokens; + arla_warnx (ADEBMSG, " got %lu", + (unsigned long)entry->fetched_length); + msg.offset = entry->fetched_length; + fcacheentry2nnpfsnode (&entry->fid, fcache_realfid(entry), + &entry->status, &msg.node, ae, + FCACHE2NNPFSNODE_ALL); + + msg.header.opcode = NNPFS_MSG_INSTALLDATA; + + nnpfs_send_message_wakeup_multiple (fd, + h->header.sequence_num, + ret, + &msg, sizeof(msg), + NULL, 0); + + prefetch_data(&entry, &ce); + + fcache_release(entry); + cred_free (ce); + return ret; + + out: + if (entry) + fcache_release(entry); + cred_free (ce); + nnpfs_send_message_wakeup_multiple (fd, + h->header.sequence_num, + ret, + NULL, 0); + + return ret; } /* @@ -1841,30 +2069,38 @@ out: void break_callback (FCacheEntry *entry) { - struct xfs_message_invalidnode msg; - enum { CALLBACK_BREAK_WARN = 100 }; - static int failed_callbacks_break = 0; - int ret; - - assert (entry->flags.kernelp); - - msg.header.opcode = XFS_MSG_INVALIDNODE; - memcpy (&msg.handle, &entry->fid, sizeof(entry->fid)); - ret = xfs_message_send (kernel_fd, (struct xfs_message_header *)&msg, - sizeof(msg)); - if (ret) { - arla_warnx (ADEBMSG, "break_callback: (%ld.%lu.%lu.%lu) failed", - (long)entry->fid.Cell, - (unsigned long)entry->fid.fid.Volume, - (unsigned long)entry->fid.fid.Vnode, - (unsigned long)entry->fid.fid.Unique); - ++failed_callbacks_break; - if (failed_callbacks_break > CALLBACK_BREAK_WARN) { - arla_warnx (ADEBWARN, "break_callback: have failed %d times", - failed_callbacks_break); - failed_callbacks_break = 0; - } - } + struct nnpfs_message_invalidnode msg; + enum { CALLBACK_BREAK_WARN = 100 }; + static int failed_callbacks_break = 0; + int ret; + + assert_flag(entry,kernelp); + + /* + * Throw away tokens for all directories and unused entries. + * needs to be same as NNPFS_MSG_INVALIDNODE processing in + * nnpfs + */ + if (entry->status.FileType == TYPE_DIR || !entry->flags.datausedp) + entry->tokens = 0; + + msg.header.opcode = NNPFS_MSG_INVALIDNODE; + memcpy (&msg.handle, &entry->fid, sizeof(entry->fid)); + ret = nnpfs_message_send (kernel_fd, (struct nnpfs_message_header *)&msg, + sizeof(msg)); + if (ret) { + arla_warnx (ADEBMSG, "break_callback: (%ld.%lu.%lu.%lu) failed", + (long)entry->fid.Cell, + (unsigned long)entry->fid.fid.Volume, + (unsigned long)entry->fid.fid.Vnode, + (unsigned long)entry->fid.fid.Unique); + ++failed_callbacks_break; + if (failed_callbacks_break > CALLBACK_BREAK_WARN) { + arla_warnx (ADEBWARN, "break_callback: have failed %d times", + failed_callbacks_break); + failed_callbacks_break = 0; + } + } } /* @@ -1874,32 +2110,34 @@ break_callback (FCacheEntry *entry) void install_attr (FCacheEntry *e, int flags) { - struct xfs_message_installattr msg; - - memset (&msg, 0, sizeof(msg)); - msg.header.opcode = XFS_MSG_INSTALLATTR; - fcacheentry2xfsnode (&e->fid, fcache_realfid(e), &e->status, &msg.node, - e->acccache, flags); - msg.node.tokens = e->tokens; - if (!e->flags.datausedp) - msg.node.tokens &= ~XFS_DATA_MASK; - - xfs_message_send (kernel_fd, (struct xfs_message_header *)&msg, - sizeof(msg)); + struct nnpfs_message_installattr msg; + + memset (&msg, 0, sizeof(msg)); + msg.header.opcode = NNPFS_MSG_INSTALLATTR; + fcacheentry2nnpfsnode (&e->fid, fcache_realfid(e), &e->status, &msg.node, + e->acccache, flags); + e->tokens |= NNPFS_ATTR_R; + msg.node.tokens = e->tokens; + if (!e->flags.datausedp) + msg.node.tokens &= ~NNPFS_DATA_MASK; + + nnpfs_message_send (kernel_fd, (struct nnpfs_message_header *)&msg, + sizeof(msg)); } void update_fid(VenusFid oldfid, FCacheEntry *old_entry, VenusFid newfid, FCacheEntry *new_entry) { - struct xfs_message_updatefid msg; + struct nnpfs_message_updatefid msg; - msg.header.opcode = XFS_MSG_UPDATEFID; + msg.header.opcode = NNPFS_MSG_UPDATEFID; memcpy (&msg.old_handle, &oldfid, sizeof(oldfid)); memcpy (&msg.new_handle, &newfid, sizeof(newfid)); - xfs_message_send (kernel_fd, (struct xfs_message_header *)&msg, - sizeof(msg)); + nnpfs_message_send (kernel_fd, (struct nnpfs_message_header *)&msg, + sizeof(msg)); if (new_entry != NULL) { + assert_flag(new_entry,kernelp); new_entry->flags.kernelp = TRUE; new_entry->flags.attrusedp = TRUE; } @@ -1911,39 +2149,42 @@ update_fid(VenusFid oldfid, FCacheEntry *old_entry, } static int -xfs_message_inactivenode (int fd, struct xfs_message_inactivenode *h, - u_int size) -{ - FCacheEntry *entry; - VenusFid *fid; - int ret; - CredCacheEntry *ce; - - fid = (VenusFid *)&h->handle; - arla_warnx (ADEBMSG, "inactivenode (%ld.%lu.%lu.%lu)", - (long)fid->Cell, (unsigned long)fid->fid.Volume, - (unsigned long)fid->fid.Vnode, - (unsigned long)fid->fid.Unique); - - ce = cred_get (fid->Cell, 0, CRED_NONE); - assert (ce != NULL); - - ret = fcache_get (&entry, *fid, ce); - cred_free (ce); - - if (ret) { - arla_warnx (ADEBMSG, "xfs_message_inactivenode: node not found"); - return 0; - } - if (h->flag & XFS_NOREFS) - fcache_unused (entry); - if (h->flag & XFS_DELETE) { - entry->flags.kernelp = FALSE; - entry->flags.datausedp = FALSE; - entry->flags.attrusedp = FALSE; - } - fcache_release(entry); - return 0; +nnpfs_message_inactivenode (int fd, struct nnpfs_message_inactivenode *h, + u_int size) +{ + FCacheEntry *entry; + VenusFid *fid; + int ret; + CredCacheEntry *ce; + + fid = (VenusFid *)&h->handle; + arla_warnx (ADEBMSG, "inactivenode (%ld.%lu.%lu.%lu)", + (long)fid->Cell, (unsigned long)fid->fid.Volume, + (unsigned long)fid->fid.Vnode, + (unsigned long)fid->fid.Unique); + + ce = cred_get (fid->Cell, 0, CRED_NONE); + assert (ce != NULL); + + ret = fcache_get (&entry, *fid, ce); + cred_free (ce); + + if (ret) { + arla_warnx (ADEBMSG, "nnpfs_message_inactivenode: node not found"); + return 0; + } + + assert_flag(entry,kernelp); + + if (h->flag & NNPFS_NOREFS) + fcache_unused (entry); + if (h->flag & NNPFS_DELETE) { + entry->flags.kernelp = FALSE; + entry->flags.datausedp = FALSE; + entry->flags.attrusedp = FALSE; + } + fcache_release(entry); + return 0; } /* @@ -1951,7 +2192,7 @@ xfs_message_inactivenode (int fd, struct xfs_message_inactivenode *h, */ static Bool -all_powerful_p (const xfs_cred *cred) +all_powerful_p (const nnpfs_cred *cred) { return cred->uid == 0; } @@ -1961,7 +2202,7 @@ all_powerful_p (const xfs_cred *cred) */ static int -viocflushvolume (int fd, struct xfs_message_pioctl *h, u_int size) +viocflushvolume (int fd, struct nnpfs_message_pioctl *h, u_int size) { VenusFid fid ; @@ -1987,7 +2228,7 @@ viocflushvolume (int fd, struct xfs_message_pioctl *h, u_int size) */ static int -viocgetacl(int fd, struct xfs_message_pioctl *h, u_int size) +viocgetacl(int fd, struct nnpfs_message_pioctl *h, u_int size) { VenusFid fid; AFSOpaque opaque; @@ -1995,7 +2236,7 @@ viocgetacl(int fd, struct xfs_message_pioctl *h, u_int size) int error; if (!h->handle.a && !h->handle.b && !h->handle.c && !h->handle.d) - return xfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); fid.Cell = h->handle.a; fid.fid.Volume = h->handle.b; @@ -2014,8 +2255,8 @@ viocgetacl(int fd, struct xfs_message_pioctl *h, u_int size) cred_free (ce); - xfs_send_message_wakeup_data (fd, h->header.sequence_num, error, - opaque.val, opaque.len); + nnpfs_send_message_wakeup_data (fd, h->header.sequence_num, error, + opaque.val, opaque.len); if (error == 0) free (opaque.val); return 0; @@ -2026,7 +2267,7 @@ viocgetacl(int fd, struct xfs_message_pioctl *h, u_int size) */ static int -viocsetacl(int fd, struct xfs_message_pioctl *h, u_int size) +viocsetacl(int fd, struct nnpfs_message_pioctl *h, u_int size) { VenusFid fid; AFSOpaque opaque; @@ -2035,14 +2276,14 @@ viocsetacl(int fd, struct xfs_message_pioctl *h, u_int size) int error; if (!h->handle.a && !h->handle.b && !h->handle.c && !h->handle.d) - return xfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); if (h->insize > AFSOPAQUEMAX || h->insize == 0) - return xfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); opaque.val = malloc(h->insize); if(opaque.val == NULL) - return xfs_send_message_wakeup (fd, h->header.sequence_num, ENOMEM); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, ENOMEM); fid.Cell = h->handle.a; fid.fid.Volume = h->handle.b; @@ -2060,7 +2301,7 @@ viocsetacl(int fd, struct xfs_message_pioctl *h, u_int size) } while (try_again (&error, &ce, &h->cred, &fid)); if (error == 0) { - install_attr (e, FCACHE2XFSNODE_ALL); + install_attr (e, FCACHE2NNPFSNODE_ALL); fcache_release (e); } else if (error != EACCES) error = EINVAL; @@ -2068,7 +2309,7 @@ viocsetacl(int fd, struct xfs_message_pioctl *h, u_int size) cred_free (ce); free (opaque.val); - xfs_send_message_wakeup_data (fd, h->header.sequence_num, error, NULL, 0); + nnpfs_send_message_wakeup_data (fd, h->header.sequence_num, error, NULL, 0); return 0; } @@ -2077,7 +2318,7 @@ viocsetacl(int fd, struct xfs_message_pioctl *h, u_int size) */ static int -viocgetvolstat(int fd, struct xfs_message_pioctl *h, u_int size) +viocgetvolstat(int fd, struct nnpfs_message_pioctl *h, u_int size) { VenusFid fid; CredCacheEntry *ce; @@ -2090,7 +2331,7 @@ viocgetvolstat(int fd, struct xfs_message_pioctl *h, u_int size) int error; if (!h->handle.a && !h->handle.b && !h->handle.c && !h->handle.d) - return xfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); fid.Cell = h->handle.a; fid.fid.Volume = h->handle.b; @@ -2107,7 +2348,7 @@ viocgetvolstat(int fd, struct xfs_message_pioctl *h, u_int size) do { error = getvolstat (fid, ce, &volstat, - volumename, + volumename, sizeof(volumename), offlinemsg, motd); } while (try_again (&error, &ce, &h->cred, &fid)); @@ -2147,8 +2388,8 @@ viocgetvolstat(int fd, struct xfs_message_pioctl *h, u_int size) outsize++; } - xfs_send_message_wakeup_data (fd, h->header.sequence_num, error, - out, outsize); + nnpfs_send_message_wakeup_data (fd, h->header.sequence_num, error, + out, outsize); return 0; } @@ -2157,7 +2398,7 @@ viocgetvolstat(int fd, struct xfs_message_pioctl *h, u_int size) */ static int -viocsetvolstat(int fd, struct xfs_message_pioctl *h, u_int size) +viocsetvolstat(int fd, struct nnpfs_message_pioctl *h, u_int size) { VenusFid fid; CredCacheEntry *ce; @@ -2223,8 +2464,8 @@ viocsetvolstat(int fd, struct xfs_message_pioctl *h, u_int size) cred_free (ce); - xfs_send_message_wakeup_data (fd, h->header.sequence_num, error, - NULL, 0); + nnpfs_send_message_wakeup_data (fd, h->header.sequence_num, error, + NULL, 0); return 0; } @@ -2248,10 +2489,16 @@ get_mount_point (VenusFid fid, if (fid.fid.Volume == 0 && fid.fid.Vnode == 0 && fid.fid.Unique == 0) return EINVAL; - error = fcache_get_data(&dentry, &fid, ce); + error = fcache_get(&dentry, fid, *ce); if (error) return error; + error = fcache_get_data(&dentry, ce, 0); + if (error) { + fcache_release(dentry); + return error; + } + error = adir_lookup(dentry, filename, &mp_fid); fcache_release(dentry); if (error) @@ -2261,7 +2508,7 @@ get_mount_point (VenusFid fid, if (error) return error; - error = fcache_verify_attr (mp_entry, NULL, NULL, *ce); + error = fcache_verify_attr (mp_entry, dentry, filename, *ce); if (error) { fcache_release(mp_entry); return error; @@ -2284,21 +2531,21 @@ get_mount_point (VenusFid fid, */ static int -read_mount_point (FCacheEntry *mp_entry, CredCacheEntry *ce, +read_mount_point (FCacheEntry **mp_entry, CredCacheEntry **ce, int *fd, fbuf *the_fbuf) { int error; char *buf; - error = fcache_verify_data (mp_entry, ce); + error = fcache_get_data (mp_entry, ce, 0); if (error) return error; - *fd = fcache_open_file (mp_entry, O_RDONLY); + *fd = fcache_open_file (*mp_entry, O_RDONLY); if (*fd < 0) return errno; - error = fbuf_create (the_fbuf, *fd, mp_entry->status.Length, + error = fbuf_create (the_fbuf, *fd, (*mp_entry)->status.Length, FBUF_READ|FBUF_WRITE|FBUF_PRIVATE); if (error) { close (*fd); @@ -2320,7 +2567,7 @@ read_mount_point (FCacheEntry *mp_entry, CredCacheEntry *ce, */ static int -vioc_afs_stat_mt_pt(int fd, struct xfs_message_pioctl *h, u_int size) +vioc_afs_stat_mt_pt(int fd, struct nnpfs_message_pioctl *h, u_int size) { VenusFid fid; int error; @@ -2343,14 +2590,14 @@ vioc_afs_stat_mt_pt(int fd, struct xfs_message_pioctl *h, u_int size) error = get_mount_point (fid, h->msg, &ce, &e); if (error) { cred_free(ce); - return xfs_send_message_wakeup (fd, h->header.sequence_num, error); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, error); } - error = read_mount_point (e, ce, &mp_fd, &the_fbuf); + error = read_mount_point (&e, &ce, &mp_fd, &the_fbuf); if (error) { fcache_release (e); cred_free(ce); - return xfs_send_message_wakeup (fd, h->header.sequence_num, error); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, error); } /* @@ -2362,8 +2609,8 @@ vioc_afs_stat_mt_pt(int fd, struct xfs_message_pioctl *h, u_int size) buf = (unsigned char *)the_fbuf.buf; buf[the_fbuf.len-1] = '\0'; - xfs_send_message_wakeup_data (fd, h->header.sequence_num, error, - buf, the_fbuf.len); + nnpfs_send_message_wakeup_data (fd, h->header.sequence_num, error, + buf, the_fbuf.len); fbuf_end (&the_fbuf); close (mp_fd); fcache_release (e); @@ -2378,12 +2625,12 @@ vioc_afs_stat_mt_pt(int fd, struct xfs_message_pioctl *h, u_int size) */ static int -vioc_afs_delete_mt_pt(int fd, struct xfs_message_pioctl *h, u_int size) +vioc_afs_delete_mt_pt(int fd, struct nnpfs_message_pioctl *h, u_int size) { VenusFid fid; int error = 0; CredCacheEntry *ce; - struct xfs_message_remove remove_msg; + struct nnpfs_message_remove remove_msg; FCacheEntry *entry; h->msg[min(h->insize, sizeof(h->msg)-1)] = '\0'; @@ -2399,7 +2646,7 @@ vioc_afs_delete_mt_pt(int fd, struct xfs_message_pioctl *h, u_int size) error = get_mount_point (fid, h->msg, &ce, &entry); cred_free (ce); if (error) - return xfs_send_message_wakeup (fd, h->header.sequence_num, error); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, error); fcache_release(entry); remove_msg.header = h->header; @@ -2408,11 +2655,11 @@ vioc_afs_delete_mt_pt(int fd, struct xfs_message_pioctl *h, u_int size) strlcpy(remove_msg.name, h->msg, sizeof(remove_msg.name)); remove_msg.cred = h->cred; - return xfs_message_remove (fd, &remove_msg, sizeof(remove_msg)); + return nnpfs_message_remove (fd, &remove_msg, sizeof(remove_msg)); } static int -viocwhereis(int fd, struct xfs_message_pioctl *h, u_int size) +viocwhereis(int fd, struct nnpfs_message_pioctl *h, u_int size) { VenusFid fid; CredCacheEntry *ce; @@ -2423,7 +2670,7 @@ viocwhereis(int fd, struct xfs_message_pioctl *h, u_int size) int bit; if (!h->handle.a && !h->handle.b && !h->handle.c && !h->handle.d) - return xfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); fid.Cell = h->handle.a; fid.fid.Volume = h->handle.b; @@ -2436,13 +2683,13 @@ viocwhereis(int fd, struct xfs_message_pioctl *h, u_int size) error = fcache_get(&e, fid, ce); if (error) { cred_free(ce); - return xfs_send_message_wakeup (fd, h->header.sequence_num, error); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, error); } error = fcache_verify_attr (e, NULL, NULL, ce); if (error) { fcache_release(e); cred_free(ce); - return xfs_send_message_wakeup (fd, h->header.sequence_num, error); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, error); } bit = volcache_volid2bit (e->volume, fid.fid.Volume); @@ -2450,7 +2697,7 @@ viocwhereis(int fd, struct xfs_message_pioctl *h, u_int size) if (bit == -1) { fcache_release(e); cred_free(ce); - return xfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); } memset(addresses, 0, sizeof(addresses)); @@ -2460,8 +2707,8 @@ viocwhereis(int fd, struct xfs_message_pioctl *h, u_int size) if ((e->volume->entry.serverFlags[i] & bit) && addr != 0) addresses[j++] = addr; } - xfs_send_message_wakeup_data (fd, h->header.sequence_num, error, - addresses, sizeof(long) * j); + nnpfs_send_message_wakeup_data (fd, h->header.sequence_num, error, + addresses, sizeof(long) * j); fcache_release(e); cred_free (ce); @@ -2474,7 +2721,7 @@ viocwhereis(int fd, struct xfs_message_pioctl *h, u_int size) */ static int -vioc_get_cell(int fd, struct xfs_message_pioctl *h, u_int size) +vioc_get_cell(int fd, struct nnpfs_message_pioctl *h, u_int size) { int i; int32_t index; @@ -2488,12 +2735,12 @@ vioc_get_cell(int fd, struct xfs_message_pioctl *h, u_int size) index = *((int32_t *) h->msg); cellname = cell_num2name(index); if (cellname == NULL) - return xfs_send_message_wakeup (fd, h->header.sequence_num, EDOM); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, EDOM); dbservers = cell_dbservers_by_id (index, &num_dbservers); if (dbservers == NULL) - return xfs_send_message_wakeup (fd, h->header.sequence_num, EDOM); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, EDOM); memset(out, 0, sizeof(out)); cellname_len = min(strlen(cellname), MAXPATHLEN - 1); @@ -2501,12 +2748,12 @@ vioc_get_cell(int fd, struct xfs_message_pioctl *h, u_int size) out[8 * sizeof(int32_t) + cellname_len] = '\0'; outsize = 8 * sizeof(int32_t) + cellname_len + 1; for (i = 0; i < min(num_dbservers, 8); ++i) { - u_int32_t addr = dbservers[i].addr.s_addr; + uint32_t addr = dbservers[i].addr.s_addr; memcpy (&out[i * sizeof(int32_t)], &addr, sizeof(int32_t)); } - xfs_send_message_wakeup_data (fd, h->header.sequence_num, 0, - out, outsize); + nnpfs_send_message_wakeup_data (fd, h->header.sequence_num, 0, + out, outsize); return 0; } @@ -2516,26 +2763,26 @@ vioc_get_cell(int fd, struct xfs_message_pioctl *h, u_int size) */ static int -vioc_get_cellstatus(int fd, struct xfs_message_pioctl *h, u_int size) +vioc_get_cellstatus(int fd, struct nnpfs_message_pioctl *h, u_int size) { char *cellname; int32_t cellid; - u_int32_t out = 0; + uint32_t out = 0; cellname = h->msg; cellname[h->insize-1] = '\0'; cellid = cell_name2num (cellname); if (cellid == -1) - return xfs_send_message_wakeup (fd, h->header.sequence_num, ENOENT); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, ENOENT); if (cellid == 0) out |= CELLSTATUS_PRIMARY; if (cell_issuid_by_num (cellid)) out |= CELLSTATUS_SETUID; - xfs_send_message_wakeup_data (fd, h->header.sequence_num, 0, - &out, sizeof(out)); + nnpfs_send_message_wakeup_data (fd, h->header.sequence_num, 0, + &out, sizeof(out)); return 0; } @@ -2545,33 +2792,33 @@ vioc_get_cellstatus(int fd, struct xfs_message_pioctl *h, u_int size) */ static int -vioc_set_cellstatus(int fd, struct xfs_message_pioctl *h, u_int size) +vioc_set_cellstatus(int fd, struct nnpfs_message_pioctl *h, u_int size) { int32_t cellid; char *cellname; - u_int32_t in = 0; + uint32_t in = 0; int ret; if (!all_powerful_p (&h->cred)) - return xfs_send_message_wakeup (fd, h->header.sequence_num, EACCES); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, EACCES); if (h->insize < sizeof (in) + 2) /* terminating NUL and one char */ - return xfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); cellname = h->msg + sizeof (in); cellname[h->insize-1-sizeof(in)] = '\0'; cellid = cell_name2num (cellname); if (cellid == -1) - return xfs_send_message_wakeup (fd, h->header.sequence_num, ENOENT); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, ENOENT); if (in & CELLSTATUS_SETUID) { ret = cell_setsuid_by_num (cellid); if (ret) - return xfs_send_message_wakeup (fd, h->header.sequence_num,EINVAL); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num,EINVAL); } - xfs_send_message_wakeup (fd, h->header.sequence_num, 0); + nnpfs_send_message_wakeup (fd, h->header.sequence_num, 0); return 0; } @@ -2581,46 +2828,46 @@ vioc_set_cellstatus(int fd, struct xfs_message_pioctl *h, u_int size) */ static int -vioc_new_cell(int fd, struct xfs_message_pioctl *h, u_int size) +vioc_new_cell(int fd, struct nnpfs_message_pioctl *h, u_int size) { const char *cellname; cell_entry *ce; int count, i; - u_int32_t *hp; + uint32_t *hp; cell_db_entry *dbs; if (!all_powerful_p (&h->cred)) - return xfs_send_message_wakeup (fd, h->header.sequence_num, EPERM); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, EPERM); if (h->insize < 9) - return xfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); - hp = (u_int32_t *)h->msg; + hp = (uint32_t *)h->msg; for (count = 0; *hp != 0; ++hp) ++count; dbs = malloc (count * sizeof(*dbs)); if (dbs == NULL) - return xfs_send_message_wakeup (fd, h->header.sequence_num, ENOMEM); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, ENOMEM); memset(dbs, 0, count * sizeof(*dbs)); - hp = (u_int32_t *)h->msg; + hp = (uint32_t *)h->msg; for (i = 0; i < count; ++i) { dbs[i].name = NULL; dbs[i].addr.s_addr = hp[i]; dbs[i].timeout = 0; } - cellname = h->msg + 8 * sizeof(u_int32_t); + cellname = h->msg + 8 * sizeof(uint32_t); ce = cell_get_by_name (cellname); if (ce == NULL) { ce = cell_new_dynamic (cellname); if (ce == NULL) { free (dbs); - return xfs_send_message_wakeup (fd, h->header.sequence_num, - ENOMEM); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, + ENOMEM); } } else { free (ce->dbservers); @@ -2629,7 +2876,7 @@ vioc_new_cell(int fd, struct xfs_message_pioctl *h, u_int size) ce->ndbservers = count; ce->dbservers = dbs; - return xfs_send_message_wakeup (fd, h->header.sequence_num, 0); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, 0); } #ifdef KERBEROS @@ -2639,35 +2886,33 @@ vioc_new_cell(int fd, struct xfs_message_pioctl *h, u_int size) */ static int -token_for_cell (int fd, struct xfs_message_pioctl *h, u_int size, +token_for_cell (int fd, struct nnpfs_message_pioctl *h, u_int size, CredCacheEntry *ce) { - struct ClearToken ct; - char buf[2048]; - size_t len; + char buf[NNPFS_MSG_MAX_DATASIZE]; + size_t len, cell_len; char *p = buf; - u_int32_t tmp; - krbstruct *kstruct = (krbstruct *)ce->cred_data; - CREDENTIALS *cred = &kstruct->c; + uint32_t tmp; + struct cred_rxkad *cred = (struct cred_rxkad *)ce->cred_data; const char *cell = cell_num2name (ce->cell); - ct.AuthHandle = cred->kvno; - memcpy (ct.HandShakeKey, cred->session, sizeof(cred->session)); - ct.ViceId = ce->uid; - ct.BeginTimestamp = cred->issue_date + 1; - ct.EndTimestamp = ce->expire; + cell_len = strlen(cell); - tmp = cred->ticket_st.length; + len = 4 + cred->ticket_len + 4 + sizeof(cred->ct) + 4 + cell_len; + if (len > sizeof(buf)) + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); + + tmp = cred->ticket_len; memcpy (p, &tmp, sizeof(tmp)); p += sizeof(tmp); - memcpy (p, cred->ticket_st.dat, tmp); + memcpy (p, cred->ticket, tmp); p += tmp; - tmp = sizeof(ct); + tmp = sizeof(cred->ct); memcpy (p, &tmp, sizeof(tmp)); p += sizeof(tmp); - memcpy (p, &ct, sizeof(ct)); - p += sizeof(ct); - tmp = strlen(cell); + memcpy (p, &cred->ct, sizeof(cred->ct)); + p += sizeof(cred->ct); + tmp = 0; memcpy (p, &tmp, sizeof(tmp)); p += sizeof(tmp); strlcpy (p, cell, buf + sizeof buf - cell); @@ -2675,65 +2920,79 @@ token_for_cell (int fd, struct xfs_message_pioctl *h, u_int size, len = p - buf; - memset (&ct, 0, sizeof(ct)); - cred_free (ce); - xfs_send_message_wakeup_data (fd, h->header.sequence_num, 0, - buf, len); + nnpfs_send_message_wakeup_data (fd, h->header.sequence_num, 0, + buf, len); return 0; } +struct get_tok { + int32_t counter; + int32_t cell; +}; + +static int +gettok_func(CredCacheEntry *ce, void *ptr) +{ + struct get_tok *gt = ptr; + + if (gt->counter == 0) { + gt->cell = ce->cell; + return 1; + } + + gt->counter--; + return 0; +} + + /* * Handle the GETTOK message in `h' */ static int -viocgettok (int fd, struct xfs_message_pioctl *h, u_int size) +viocgettok (int fd, struct nnpfs_message_pioctl *h, u_int size) { + CredCacheEntry *ce; + int32_t cell_id; + if (h->insize == 0) { - int32_t cell_id = cell_name2num(cell_getthiscell()); - CredCacheEntry *ce = cred_get (cell_id, h->cred.pag, CRED_KRB4); + cell_id = cell_name2num(cell_getthiscell()); + } else if (h->insize == sizeof(uint32_t)) { + struct get_tok gt; + int32_t n; - if (ce == NULL) { - xfs_send_message_wakeup (fd, h->header.sequence_num, ENOTCONN); + memcpy (&n, h->msg, sizeof(n)); + + if (n < 0) { + nnpfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); return 0; } - return token_for_cell (fd, h, size, ce); - } else if (h->insize == sizeof(u_int32_t)) { - u_int32_t n; - int i, c; - int found; - CredCacheEntry *ce = NULL; - memcpy (&n, h->msg, sizeof(n)); + gt.counter = n; + gt.cell = -1; - i = 0; - c = 0; - found = 0; - while (!found && i <= n) { - if (cell_num2name(c) == NULL) - break; + cred_list_pag(h->cred.pag, CRED_KRB4, gettok_func, >); - ce = cred_get (c++, h->cred.pag, CRED_KRB4); - if (ce != NULL) { - if (i == n) { - found = 1; - } else { - cred_free (ce); - ++i; - } - } - } - if (!found) { - xfs_send_message_wakeup (fd, h->header.sequence_num, EDOM); + if (gt.cell == -1) { + nnpfs_send_message_wakeup (fd, h->header.sequence_num, EDOM); return 0; } - return token_for_cell (fd, h, size, ce); + + cell_id = gt.cell; } else { - xfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); + nnpfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); + return 0; } - return 0; + + ce = cred_get (cell_id, h->cred.pag, CRED_KRB4); + if (ce == NULL) { + nnpfs_send_message_wakeup (fd, h->header.sequence_num, ENOTCONN); + return 0; + } + + return token_for_cell (fd, h, size, ce); } /* @@ -2741,70 +3000,203 @@ viocgettok (int fd, struct xfs_message_pioctl *h, u_int size) */ static int -viocsettok (int fd, struct xfs_message_pioctl *h, u_int size) +viocsettok (int fd, struct nnpfs_message_pioctl *h, u_int size) { - struct ClearToken ct; - CREDENTIALS c; + struct cred_rxkad cred; long cell; + char realm[256]; int32_t sizeof_x; char *t = h->msg; /* someone probed us */ - if (h->insize == 0) { + if (h->insize == 0) + return EINVAL; + if (h->insize < 4) return EINVAL; - } /* Get ticket_st */ memcpy(&sizeof_x, t, sizeof(sizeof_x)) ; - c.ticket_st.length = sizeof_x ; + cred.ticket_len = sizeof_x; arla_warnx (ADEBMSG, "ticket_st has size %d", sizeof_x); t += sizeof(sizeof_x) ; - memcpy(c.ticket_st.dat, t, sizeof_x) ; + /* data used + datalen + cleartoken's length field */ + if ((t - (char *)h->msg) + sizeof_x + 4 > h->insize) + return EINVAL; + if (sizeof_x > sizeof(cred.ticket)) + return EINVAL; + + memcpy(cred.ticket, t, sizeof_x) ; t += sizeof_x ; - + /* Get ClearToken */ memcpy(&sizeof_x, t, sizeof(sizeof_x)) ; t += sizeof(sizeof_x) ; - - memcpy(&ct, t, sizeof_x) ; + + /* data used + datalen + cell's length field */ + if ((t - (char *)h->msg) + sizeof_x + 4 > h->insize) + return EINVAL; + + memcpy(&cred.ct, t, sizeof_x) ; t += sizeof_x ; /* Get primary cell ? */ memcpy(&sizeof_x, t, sizeof(sizeof_x)) ; t += sizeof(sizeof_x) ; - + /* Get Cellname */ - strncpy(c.realm, t, REALM_SZ) ; - c.realm[REALM_SZ-1] = '\0' ; + strlcpy(realm, t, min(h->insize - (t - (char *)h->msg), sizeof(realm))); + strlwr(realm); - /* Make this a sane world again */ - c.kvno = ct.AuthHandle; - memcpy (c.session, ct.HandShakeKey, sizeof(c.session)); - c.issue_date = ct.BeginTimestamp - 1; - - cell = cell_name2num(strlwr(c.realm)); + cell = cell_name2num(realm); if (cell == -1) return ENOENT; conn_clearcred (CONN_CS_ALL, cell, h->cred.pag, 2); fcache_purge_cred(h->cred.pag, cell); - cred_add (h->cred.pag, CRED_KRB4, 2, cell, ct.EndTimestamp, - &c, sizeof(c), ct.ViceId); + cred_add (h->cred.pag, CRED_KRB4, 2, cell, cred.ct.EndTimestamp, + &cred, sizeof(cred), cred.ct.ViceId); return 0; } static int -viocunlog (int fd, struct xfs_message_pioctl *h, u_int size) +viocunlog (int fd, struct nnpfs_message_pioctl *h, u_int size) { - xfs_pag_t cred = h->cred.pag; + nnpfs_pag_t cred = h->cred.pag; cred_remove(cred); fcache_purge_cred(cred, -1); return 0; } +#if defined(HAVE_KRB5) && defined(WITH_RXGK) + +/* + * handle rxgk kerberos 5 authenticator + * + * format: + * int32_t ticket_len + * char krb5_ticket[]; + * int32_t kvno; + * int32_t krb5_enctype; + * int32_t viceid; + * int32_t sessionkey_len; + * char sessionkey[]; + * int64_t start_time; + * int64_t expiration_time; + * char cell[] + */ + +size_t k5ticket_limit_size = 40 * 1024; + +static int +k5settok (int fd, struct nnpfs_message_pioctl *h, u_int size) +{ + struct cred_rxgk c; + char cellname[256]; + uint32_t sizeof_x; + uint64_t endtime; + int32_t viceid; + long cell; + char *t = h->msg; + int insize = h->insize; + + if (insize < 4) + return EINVAL; + + memcpy(&sizeof_x, t, sizeof(sizeof_x)) ; + arla_warnx (ADEBMSG, "ticket has size %d", sizeof_x); + t += sizeof(sizeof_x) ; + + if (sizeof_x < k5ticket_limit_size || sizeof_x > insize) + return EINVAL; + + c.type = CRED_GK_K5; + + c.t.k5.ticket = malloc(sizeof_x); + if (c.t.k5.ticket == NULL) + return ENOMEM; + + memcpy(c.t.k5.ticket, t, sizeof_x); + insize -= sizeof_x; + t += sizeof_x; + + if (h->insize < 4 + 4 + 4 + 4) { + free(c.t.k5.ticket); + return EINVAL; + } + + memcpy(&sizeof_x, t, sizeof(sizeof_x)); + t += sizeof(sizeof_x); insize -= sizeof(sizeof_x); + c.t.k5.enctype = sizeof_x; + + memcpy(&sizeof_x, t, sizeof(sizeof_x)); + t += sizeof(sizeof_x); insize -= sizeof(sizeof_x); + c.t.k5.kvno = sizeof_x; + + memcpy(&sizeof_x, t, sizeof(sizeof_x)); + t += sizeof(sizeof_x); insize -= sizeof(sizeof_x); + viceid = sizeof_x; + + memcpy(&sizeof_x, t, sizeof(sizeof_x)); + t += sizeof(sizeof_x); insize -= sizeof(sizeof_x); + c.t.k5.sessionkey_len = sizeof_x; + + if (sizeof_x < k5ticket_limit_size || sizeof_x > insize) { + free(c.t.k5.ticket); + return EINVAL; + } + + c.t.k5.sessionkey = malloc(c.t.k5.sessionkey_len); + if (c.t.k5.sessionkey == NULL) { + free(c.t.k5.ticket); + return EINVAL; + } + + memcpy(c.t.k5.sessionkey, t, c.t.k5.sessionkey_len); + t += c.t.k5.sessionkey_len; + insize -= c.t.k5.sessionkey_len; + + + if (insize < 8 + 8 + 1) { + free(c.t.k5.sessionkey); + free(c.t.k5.ticket); + return EINVAL; + } + + t += 8; + insize -= 8; + + memcpy(&endtime, t, sizeof(endtime)); + t += 8; + insize -= 8; + + if (insize > sizeof(cellname) || t[insize - 1] != '\0') { + free(c.t.k5.sessionkey); + free(c.t.k5.ticket); + return EINVAL; + } + + strlcpy(cellname, t, sizeof(cellname)); + + cell = cell_name2num(strlwr(cellname)); + + if (cell == -1) { + free(c.t.k5.sessionkey); + free(c.t.k5.ticket); + return ENOENT; + } + + conn_clearcred (CONN_CS_ALL, cell, h->cred.pag, 2); + fcache_purge_cred(h->cred.pag, cell); + cred_add (h->cred.pag, CRED_GK_K5, 2, cell, (time_t)endtime, + &c, sizeof(c), viceid); + return 0; +} + +#endif /* HAVE_KRB5 && WITH_RXGK */ + #endif /* KERBEROS */ /* @@ -2812,7 +3204,7 @@ viocunlog (int fd, struct xfs_message_pioctl *h, u_int size) */ static int -viocflush (int fd, struct xfs_message_pioctl *h, u_int size) +viocflush (int fd, struct nnpfs_message_pioctl *h, u_int size) { VenusFid fid ; AFSCallBack broken_callback = {0, 0, CBDROPPED}; @@ -2834,7 +3226,7 @@ viocflush (int fd, struct xfs_message_pioctl *h, u_int size) } static int -viocconnect(int fd, struct xfs_message_pioctl *h, u_int size) +viocconnect(int fd, struct nnpfs_message_pioctl *h, u_int size) { char *p = h->msg; int32_t tmp; @@ -2852,6 +3244,16 @@ viocconnect(int fd, struct xfs_message_pioctl *h, u_int size) ret = tmp; + /* check permission */ + switch (tmp) { + case CONNMODE_PROBE: + break; + default: + if (!all_powerful_p(&h->cred)) + return EPERM; + break; + } + switch(tmp) { case CONNMODE_PROBE: switch(connected_mode) { @@ -2865,31 +3267,27 @@ viocconnect(int fd, struct xfs_message_pioctl *h, u_int size) } break; case CONNMODE_CONN: - if (Log_is_open) { - DARLA_Close(&log_data); - Log_is_open = 0; + case CONNMODE_CONN_WITHCALLBACKS: + disco_closelog(); + + cmcb_reinit(); + + if (disco_need_integrate()) + disco_reintegrate(h->cred.pag); + + if (tmp == CONNMODE_CONN_WITHCALLBACKS) + fcache_reobtain_callbacks (&h->cred); -#if 0 - do_replay("discon_log", log_data.log_entries, 0); -#endif - } - if (connected_mode == DISCONNECTED) { - connected_mode = CONNECTED ; - fcache_reobtain_callbacks (); - } connected_mode = CONNECTED ; break; case CONNMODE_FETCH: + disco_openlog(); connected_mode = FETCH_ONLY ; break; case CONNMODE_DISCONN: - ret = DARLA_Open(&log_data, ARLACACHEDIR"/discon_log", - O_WRONLY | O_CREAT | O_BINARY); - if (ret < 0) { - arla_warn (ADEBERROR, errno, "DARLA_Open"); - } else { - Log_is_open = 1; - } + disco_openlog(); + if (possibly_have_network()) + fcache_giveup_all_callbacks(); connected_mode = DISCONNECTED; break; default: @@ -2898,16 +3296,16 @@ viocconnect(int fd, struct xfs_message_pioctl *h, u_int size) } } - xfs_send_message_wakeup_data (fd, h->header.sequence_num, error, - &ret, sizeof(ret)); + nnpfs_send_message_wakeup_data (fd, h->header.sequence_num, error, + &ret, sizeof(ret)); return 0; } static int -getrxkcrypt(int fd, struct xfs_message_pioctl *h, u_int size) +getrxkcrypt(int fd, struct nnpfs_message_pioctl *h, u_int size) { - if (h->outsize == sizeof(u_int32_t)) { - u_int32_t n; + if (h->outsize == sizeof(uint32_t)) { + uint32_t n; #ifdef KERBEROS if (conn_rxkad_level == rxkad_crypt) @@ -2916,23 +3314,26 @@ getrxkcrypt(int fd, struct xfs_message_pioctl *h, u_int size) #endif n = 0; - return xfs_send_message_wakeup_data (fd, - h->header.sequence_num, - 0, - &n, - sizeof(n)); + return nnpfs_send_message_wakeup_data (fd, + h->header.sequence_num, + 0, + &n, + sizeof(n)); } else - return xfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); } static int -setrxkcrypt(int fd, struct xfs_message_pioctl *h, u_int size) +setrxkcrypt(int fd, struct nnpfs_message_pioctl *h, u_int size) { #ifdef KERBEROS int error = 0; - if (h->insize == sizeof(u_int32_t)) { - u_int32_t n; + if (!all_powerful_p(&h->cred)) + return EPERM; + + if (h->insize == sizeof(uint32_t)) { + uint32_t n; memcpy (&n, h->msg, sizeof(n)); @@ -2943,7 +3344,7 @@ setrxkcrypt(int fd, struct xfs_message_pioctl *h, u_int size) else error = EINVAL; if (error == 0) - conn_clearcred (CONN_CS_NONE, 0, -1, -1); + conn_clearcred (CONN_CS_SECIDX, 0, -1, 2); } else error = EINVAL; return error; @@ -2953,11 +3354,11 @@ setrxkcrypt(int fd, struct xfs_message_pioctl *h, u_int size) } /* - * XXX - this function sometimes does a wakeup_data and then an ordinary wakeup is sent in xfs_message_pioctl + * XXX - this function sometimes does a wakeup_data and then an ordinary wakeup is sent in nnpfs_message_pioctl */ static int -vioc_fpriostatus (int fd, struct xfs_message_pioctl *h, u_int size) +vioc_fpriostatus (int fd, struct nnpfs_message_pioctl *h, u_int size) { struct vioc_fprio *fprio; int error = 0; @@ -2973,6 +3374,8 @@ vioc_fpriostatus (int fd, struct xfs_message_pioctl *h, u_int size) fid.fid.Vnode = fprio->Vnode ; fid.fid.Unique = fprio->Unique ; + if (!all_powerful_p(&h->cred)) + return EPERM; #if 0 switch(fprio->cmd) { @@ -2985,11 +3388,11 @@ vioc_fpriostatus (int fd, struct xfs_message_pioctl *h, u_int size) } prio = fprio_get(fid); - xfs_send_message_wakeup_data (fd, - h->header.sequence_num, - 0, - &prio, - sizeof(prio)); + nnpfs_send_message_wakeup_data (fd, + h->header.sequence_num, + 0, + &prio, + sizeof(prio)); break; } @@ -2998,7 +3401,7 @@ vioc_fpriostatus (int fd, struct xfs_message_pioctl *h, u_int size) fprio_remove(fid); error = 0; } else if (fprio->prio < FPRIO_MIN || - fprio->prio > FPRIO_MAX) + fprio->prio > FPRIO_MAX) error = EINVAL; else { fprio_set(fid, fprio->prio); @@ -3011,11 +3414,11 @@ vioc_fpriostatus (int fd, struct xfs_message_pioctl *h, u_int size) break; } - xfs_send_message_wakeup_data (fd, - h->header.sequence_num, - 0, - &fprioritylevel, - sizeof(fprioritylevel)); + nnpfs_send_message_wakeup_data (fd, + h->header.sequence_num, + 0, + &fprioritylevel, + sizeof(fprioritylevel)); error = 0; break; case FPRIO_SETMAX: @@ -3036,14 +3439,14 @@ vioc_fpriostatus (int fd, struct xfs_message_pioctl *h, u_int size) } static int -viocgetfid (int fd, struct xfs_message_pioctl *h, u_int size) +viocgetfid (int fd, struct nnpfs_message_pioctl *h, u_int size) { - return xfs_send_message_wakeup_data(fd, h->header.sequence_num, 0, - &h->handle, sizeof(VenusFid)); + return nnpfs_send_message_wakeup_data(fd, h->header.sequence_num, 0, + &h->handle, sizeof(VenusFid)); } static int -viocvenuslog (int fd, struct xfs_message_pioctl *h, u_int size) +viocvenuslog (int fd, struct nnpfs_message_pioctl *h, u_int size) { if (!all_powerful_p(&h->cred)) return EPERM; @@ -3052,6 +3455,7 @@ viocvenuslog (int fd, struct xfs_message_pioctl *h, u_int size) volcache_status (); cred_status (); fcache_status (); + cell_status (stderr); #if 0 fprio_status (); #endif @@ -3066,69 +3470,84 @@ viocvenuslog (int fd, struct xfs_message_pioctl *h, u_int size) */ static int -vioc_afs_sysname (int fd, struct xfs_message_pioctl *h, u_int size) +vioc_afs_sysname (int fd, struct nnpfs_message_pioctl *h, u_int size) { char *t = h->msg; int32_t parm = *((int32_t *)t); if (parm) { + char t_sysname[SYSNAMEMAXLEN]; + int size; + if (!all_powerful_p (&h->cred)) - return xfs_send_message_wakeup (fd, - h->header.sequence_num, - EPERM); + return nnpfs_send_message_wakeup (fd, + h->header.sequence_num, + EPERM); t += sizeof(int32_t); arla_warnx (ADEBMSG, "VIOC_AFS_SYSNAME: setting sysname: %s", t); - memcpy(arlasysname, t, h->insize); - arlasysname[h->insize] = '\0'; - return xfs_send_message_wakeup(fd, h->header.sequence_num, 0); + + size = min(h->insize, SYSNAMEMAXLEN); + + memcpy(t_sysname, t, size); + t_sysname[size - 1] = '\0'; + + fcache_setdefsysname (t_sysname); + + return nnpfs_send_message_wakeup(fd, h->header.sequence_num, 0); } else { char *buf; - size_t sysname_len = strlen (arlasysname); + const char *sysname = fcache_getdefsysname (); + size_t sysname_len = strlen (sysname); int ret; buf = malloc (sysname_len + 4 + 1); if (buf == NULL) - return xfs_send_message_wakeup (fd, h->header.sequence_num, ENOMEM); - *((u_int32_t *)buf) = sysname_len; - memcpy (buf + 4, arlasysname, sysname_len); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, + ENOMEM); + /* Return always 1 as we do not support sysname lists. */ + /* Historically the value of this uint32 has been success/failure. */ + /* OpenAFS' utilities treat this value as the number of elements */ + /* in a list of returned sysnames. It was never meant to be buflen.*/ + *((uint32_t *)buf) = 1; + memcpy (buf + 4, sysname, sysname_len); buf[sysname_len + 4] = '\0'; - ret = xfs_send_message_wakeup_data (fd, h->header.sequence_num, 0, - buf, sysname_len + 5); + ret = nnpfs_send_message_wakeup_data (fd, h->header.sequence_num, 0, + buf, sysname_len + 5); free (buf); return ret; } } static int -viocfilecellname (int fd, struct xfs_message_pioctl *h, u_int size) +viocfilecellname (int fd, struct nnpfs_message_pioctl *h, u_int size) { char *cellname; cellname = (char *) cell_num2name(h->handle.a); if (cellname) - return xfs_send_message_wakeup_data(fd, h->header.sequence_num, 0, - cellname, strlen(cellname)+1); + return nnpfs_send_message_wakeup_data(fd, h->header.sequence_num, 0, + cellname, strlen(cellname)+1); else - return xfs_send_message_wakeup_data(fd, h->header.sequence_num, EINVAL, - NULL, 0); + return nnpfs_send_message_wakeup_data(fd, h->header.sequence_num, EINVAL, + NULL, 0); } static int -viocgetwscell (int fd, struct xfs_message_pioctl *h, u_int size) +viocgetwscell (int fd, struct nnpfs_message_pioctl *h, u_int size) { char *cellname; cellname = (char*) cell_getthiscell(); - return xfs_send_message_wakeup_data(fd, h->header.sequence_num, 0, - cellname, strlen(cellname)+1); + return nnpfs_send_message_wakeup_data(fd, h->header.sequence_num, 0, + cellname, strlen(cellname)+1); } static int -viocsetcachesize (int fd, struct xfs_message_pioctl *h, u_int size) +viocsetcachesize (int fd, struct nnpfs_message_pioctl *h, u_int size) { - u_int32_t *s = (u_int32_t *)h->msg; + uint32_t *s = (uint32_t *)h->msg; if (!all_powerful_p (&h->cred)) return EPERM; @@ -3144,24 +3563,24 @@ viocsetcachesize (int fd, struct xfs_message_pioctl *h, u_int size) * * in: flags - bitmask (1 - dont ping, use cached data, 2 - check fsservers only) * cell - string (optional) - * out: hosts - u_int32_t number of hosts, followed by list of hosts being down. + * out: hosts - uint32_t number of hosts, followed by list of hosts being down. */ static int -viocckserv (int fd, struct xfs_message_pioctl *h, u_int size) +viocckserv (int fd, struct nnpfs_message_pioctl *h, u_int size) { int32_t cell = cell_name2num (cell_getthiscell()); int flags = 0; int num_entries; - u_int32_t hosts[CKSERV_MAXSERVERS + 1]; + uint32_t hosts[CKSERV_MAXSERVERS + 1]; int msg_size; if (h->insize < sizeof(int32_t)) - return xfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); memset (hosts, 0, sizeof(hosts)); - flags = *(u_int32_t *)h->msg; + flags = *(uint32_t *)h->msg; flags &= CKSERV_DONTPING|CKSERV_FSONLY; if (h->insize > sizeof(int32_t)) { @@ -3169,7 +3588,7 @@ viocckserv (int fd, struct xfs_message_pioctl *h, u_int size) cell = cell_name2num (((char *)h->msg) + sizeof(int32_t)); if (cell == -1) - return xfs_send_message_wakeup (fd, h->header.sequence_num, ENOENT); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, ENOENT); } num_entries = CKSERV_MAXSERVERS; @@ -3178,8 +3597,8 @@ viocckserv (int fd, struct xfs_message_pioctl *h, u_int size) hosts[0] = num_entries; msg_size = sizeof(hosts[0]) * (num_entries + 1); - return xfs_send_message_wakeup_data (fd, h->header.sequence_num, 0, - hosts, msg_size); + return nnpfs_send_message_wakeup_data (fd, h->header.sequence_num, 0, + hosts, msg_size); } @@ -3188,9 +3607,9 @@ viocckserv (int fd, struct xfs_message_pioctl *h, u_int size) */ static int -viocgetcacheparms (int fd, struct xfs_message_pioctl *h, u_int size) +viocgetcacheparms (int fd, struct nnpfs_message_pioctl *h, u_int size) { - u_int32_t parms[16]; + uint32_t parms[16]; memset(parms, 0, sizeof(parms)); parms[0] = fcache_highbytes() / 1024; @@ -3203,8 +3622,8 @@ viocgetcacheparms (int fd, struct xfs_message_pioctl *h, u_int size) parms[7] = fcache_lowvnodes(); h->outsize = sizeof(parms); - return xfs_send_message_wakeup_data(fd, h->header.sequence_num, 0, - parms, sizeof(parms)); + return nnpfs_send_message_wakeup_data(fd, h->header.sequence_num, 0, + parms, sizeof(parms)); } /* @@ -3212,17 +3631,17 @@ viocgetcacheparms (int fd, struct xfs_message_pioctl *h, u_int size) */ static int -viocaviator (int fd, struct xfs_message_pioctl *h, u_int size) +viocaviator (int fd, struct nnpfs_message_pioctl *h, u_int size) { - u_int32_t parms[16]; + uint32_t parms[16]; memset(parms, 0, sizeof(parms)); parms[0] = kernel_highworkers(); parms[1] = kernel_usedworkers(); h->outsize = sizeof(parms); - return xfs_send_message_wakeup_data(fd, h->header.sequence_num, 0, - parms, sizeof(parms)); + return nnpfs_send_message_wakeup_data(fd, h->header.sequence_num, 0, + parms, sizeof(parms)); } /* @@ -3230,30 +3649,30 @@ viocaviator (int fd, struct xfs_message_pioctl *h, u_int size) */ static int -vioc_arladebug (int fd, struct xfs_message_pioctl *h, u_int size) +vioc_arladebug (int fd, struct nnpfs_message_pioctl *h, u_int size) { if (h->insize != 0) { if (h->insize < sizeof(int32_t)) - return xfs_send_message_wakeup (fd, h->header.sequence_num, - EINVAL); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, + EINVAL); if (!all_powerful_p (&h->cred)) - return xfs_send_message_wakeup (fd, h->header.sequence_num, - EPERM); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, + EPERM); arla_log_set_level_num (*((int32_t *)h->msg)); } if (h->outsize != 0) { int32_t debug_level; if (h->outsize < sizeof(int32_t)) - return xfs_send_message_wakeup (fd, h->header.sequence_num, - EINVAL); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, + EINVAL); debug_level = arla_log_get_level_num (); - return xfs_send_message_wakeup_data (fd, h->header.sequence_num, - 0, &debug_level, - sizeof(debug_level)); + return nnpfs_send_message_wakeup_data (fd, h->header.sequence_num, + 0, &debug_level, + sizeof(debug_level)); } - return xfs_send_message_wakeup (fd, h->header.sequence_num, 0); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, 0); } /* @@ -3261,19 +3680,19 @@ vioc_arladebug (int fd, struct xfs_message_pioctl *h, u_int size) */ static int -vioc_gcpags (int fd, struct xfs_message_pioctl *h, u_int size) +vioc_gcpags (int fd, struct nnpfs_message_pioctl *h, u_int size) { return 0; } /* - * + * Break the callback of the specified fid */ static int -vioc_calculate_cache (int fd, struct xfs_message_pioctl *h, u_int size) +vioc_calculate_cache (int fd, struct nnpfs_message_pioctl *h, u_int size) { - u_int32_t parms[16]; + uint32_t parms[16]; memset(parms, 0, sizeof(parms)); @@ -3289,8 +3708,8 @@ vioc_calculate_cache (int fd, struct xfs_message_pioctl *h, u_int size) "diskusage = %d, usedbytes = %d", parms[0], parms[1]); - return xfs_send_message_wakeup_data (fd, h->header.sequence_num, 0, - &parms, sizeof(parms)); + return nnpfs_send_message_wakeup_data (fd, h->header.sequence_num, 0, + &parms, sizeof(parms)); } /* @@ -3298,7 +3717,7 @@ vioc_calculate_cache (int fd, struct xfs_message_pioctl *h, u_int size) */ static int -vioc_breakcallback(int fd, struct xfs_message_pioctl *h, u_int size) +vioc_breakcallback(int fd, struct nnpfs_message_pioctl *h, u_int size) { int error; VenusFid fid; @@ -3341,27 +3760,35 @@ vioc_breakcallback(int fd, struct xfs_message_pioctl *h, u_int size) */ static int -statistics_hostpart(int fd, struct xfs_message_pioctl *h, u_int size) +vioc_ckback(int fd, struct nnpfs_message_pioctl *h, u_int size) { - u_int32_t host[100]; - u_int32_t part[100]; - u_int32_t outparms[512]; + volcache_invalidate_all (); + fcache_invalidate_mp (); + return 0; +} + +static int +statistics_hostpart(int fd, struct nnpfs_message_pioctl *h, u_int size) +{ + uint32_t host[100]; + uint32_t part[100]; + uint32_t outparms[512]; int n; int outsize; int maxslots; int i; - if (h->outsize < sizeof(u_int32_t)) - return xfs_send_message_wakeup (fd, h->header.sequence_num, - EINVAL); + if (h->outsize < sizeof(uint32_t)) + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, + EINVAL); n = 100; collectstats_hostpart(host, part, &n); - maxslots = (h->outsize / sizeof(u_int32_t) - 1) / 2; + maxslots = (h->outsize / sizeof(uint32_t) - 1) / 2; if (n > maxslots) n = maxslots; - outsize = (n * 2 + 1) * sizeof(u_int32_t); + outsize = (n * 2 + 1) * sizeof(uint32_t); outparms[0] = n; for (i = 0; i < n; i++) { @@ -3369,33 +3796,33 @@ statistics_hostpart(int fd, struct xfs_message_pioctl *h, u_int size) outparms[i*2 + 2] = part[i]; } - return xfs_send_message_wakeup_data (fd, h->header.sequence_num, 0, - (char *) &outparms, outsize); + return nnpfs_send_message_wakeup_data (fd, h->header.sequence_num, 0, + (char *) &outparms, outsize); } static int -statistics_entry(int fd, struct xfs_message_pioctl *h, u_int size) -{ - u_int32_t *request = (u_int32_t *) h->msg; - u_int32_t host; - u_int32_t part; - u_int32_t type; - u_int32_t items_slot; - u_int32_t count[32]; +statistics_entry(int fd, struct nnpfs_message_pioctl *h, u_int size) +{ + uint32_t *request = (uint32_t *) h->msg; + uint32_t host; + uint32_t part; + uint32_t type; + uint32_t items_slot; + uint32_t count[32]; int64_t items_total[32]; int64_t total_time[32]; - u_int32_t outparms[160]; + uint32_t outparms[160]; int i; int j; - if (h->insize < sizeof(u_int32_t) * 5) { - return xfs_send_message_wakeup (fd, h->header.sequence_num, - EINVAL); + if (h->insize < sizeof(uint32_t) * 5) { + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, + EINVAL); } - if (h->outsize < sizeof(u_int32_t) * 160) { - return xfs_send_message_wakeup (fd, h->header.sequence_num, - EINVAL); + if (h->outsize < sizeof(uint32_t) * 160) { + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, + EINVAL); } host = request[1]; @@ -3418,33 +3845,76 @@ statistics_entry(int fd, struct xfs_message_pioctl *h, u_int size) memcpy(&outparms[j], &total_time[i], 8); j+=2; } - return xfs_send_message_wakeup_data (fd, h->header.sequence_num, 0, - (char *) &outparms, sizeof(outparms)); + return nnpfs_send_message_wakeup_data (fd, h->header.sequence_num, 0, + (char *) &outparms, sizeof(outparms)); } static int -aioc_statistics(int fd, struct xfs_message_pioctl *h, u_int size) +aioc_statistics(int fd, struct nnpfs_message_pioctl *h, u_int size) { - u_int32_t opcode; + uint32_t opcode; if (!all_powerful_p (&h->cred)) - return xfs_send_message_wakeup (fd, h->header.sequence_num, - EPERM); + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, + EPERM); - if (h->insize < sizeof(u_int32_t)) - return xfs_send_message_wakeup (fd, h->header.sequence_num, - EPERM); + if (h->insize < sizeof(opcode)) + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, + EPERM); - opcode = *((int32_t *)h->msg); + memcpy(&opcode, &h->msg, sizeof(opcode)); - if (opcode == 0) { + switch (opcode) { + case STATISTICS_OPCODE_LIST: return statistics_hostpart(fd, h, size); - } else if (opcode == 1) { + case STATISTICS_OPCODE_GETENTRY: return statistics_entry(fd, h, size); - } else { - return xfs_send_message_wakeup (fd, h->header.sequence_num, - EINVAL); + default: + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, + EINVAL); + } +} + + +static int +aioc_getcacheparam(int fd, struct nnpfs_message_pioctl *h, u_int size) +{ + int32_t opcode; + int64_t val; + int error = 0; + + if (h->insize < sizeof(opcode) || h->outsize < sizeof(int64_t)) + return nnpfs_send_message_wakeup (fd, h->header.sequence_num, + EINVAL); + + memcpy(&opcode, &h->msg, sizeof(opcode)); + + switch(opcode) { + case GETCACHEPARAMS_OPCODE_HIGHBYTES: + val = fcache_highbytes(); + break; + case GETCACHEPARAMS_OPCODE_USEDBYTES: + val = fcache_usedbytes(); + break; + case GETCACHEPARAMS_OPCODE_LOWBYTES: + val = fcache_lowbytes(); + break; + case GETCACHEPARAMS_OPCODE_HIGHVNODES: + val = fcache_highvnodes(); + break; + case GETCACHEPARAMS_OPCODE_USEDVNODES: + val = fcache_usedvnodes(); + break; + case GETCACHEPARAMS_OPCODE_LOWVNODES: + val = fcache_lowvnodes(); + break; + default: + error = EINVAL; + break; } + + return nnpfs_send_message_wakeup_data (fd, h->header.sequence_num, 0, + (char *) &val, sizeof(val)); } @@ -3453,7 +3923,7 @@ aioc_statistics(int fd, struct xfs_message_pioctl *h, u_int size) */ static int -xfs_message_pioctl (int fd, struct xfs_message_pioctl *h, u_int size) +nnpfs_message_pioctl (int fd, struct nnpfs_message_pioctl *h, u_int size) { int error; @@ -3467,6 +3937,18 @@ xfs_message_pioctl (int fd, struct xfs_message_pioctl *h, u_int size) #endif error = viocsettok (fd, h, size); break; + +#if defined(HAVE_KRB5) && defined(WITH_RXGK) +#ifdef AFSCOMMONIOC_GKK5SETTOK_32 + case AFSCOMMONIOC_GKK5SETTOK_32: + case AFSCOMMONIOC_GKK5SETTOK_64: +#else + case AFSCOMMONIOC_GKK5SETTOK: +#endif + error = k5settok(fd, h, size); + break; +#endif /* HAVE_KRB5 && WITH_RXGK */ + #ifdef VIOCGETTOK_32 case VIOCGETTOK_32: case VIOCGETTOK_64: @@ -3722,9 +4204,10 @@ xfs_message_pioctl (int fd, struct xfs_message_pioctl *h, u_int size) #else case VIOCCKBACK : #endif + error = vioc_ckback (fd, h, size); break; -#ifdef VIOCCKBACK_32 +#ifdef AIOC_STATISTICS_32 case AIOC_STATISTICS_32: case AIOC_STATISTICS_64: #else @@ -3732,13 +4215,77 @@ xfs_message_pioctl (int fd, struct xfs_message_pioctl *h, u_int size) #endif return aioc_statistics (fd, h, size); +#ifdef AIOC_GETCACHEPARAMS_32 + case AIOC_GETCACHEPARAMS_32: + case AIOC_GETCACHEPARAMS_64: +#else + case AIOC_GETCACHEPARAMS: +#endif + return aioc_getcacheparam(fd, h, size); + default: arla_warnx (ADEBMSG, "unknown pioctl call %d", h->opcode); error = EINVAL ; } - xfs_send_message_wakeup (fd, h->header.sequence_num, error); + nnpfs_send_message_wakeup (fd, h->header.sequence_num, error); return 0; } + +/* + * Return non-zero if there is a possibility that we have a network + * connectivity. Can't tell the existence of network, just the lack of. + * + * Ignore lookback interfaces and known loopback addresses. + */ + +static int +possibly_have_network(void) +{ + struct ifaddrs *ifa, *ifa0; + int found_addr = 0; + + if (getifaddrs(&ifa0) != 0) + return 1; /* well we don't really have a clue, do we ? */ + + for (ifa = ifa0; ifa != NULL && !found_addr; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == NULL) + continue; + +#if IFF_LOOPBACK + if (ifa->ifa_flags & IFF_LOOPBACK) + continue; +#endif + + switch (ifa->ifa_addr->sa_family) { + case AF_INET: { + struct sockaddr_in *sin = (struct sockaddr_in *)ifa->ifa_addr; + if (sin->sin_addr.s_addr == htonl(0x7f000001)) + continue; + if (sin->sin_addr.s_addr == htonl(0)) + continue; + found_addr = 1; + break; + } +#ifdef RX_SUPPORT_INET6 + case AF_INET6: + /* + * XXX avoid link local and local loopback addresses since + * those are not allowed in VLDB + */ + found_addr = 1; + break; +#endif + default: + break; + } + } + freeifaddrs(ifa0); + + /* if we found an acceptable address, good for us */ + if (found_addr) + return 1; + return 0; +} diff --git a/usr.sbin/afs/src/arlad/messages.h b/usr.sbin/afs/src/arlad/messages.h index 893bebbd9a7..c20fd712ec1 100644 --- a/usr.sbin/afs/src/arlad/messages.h +++ b/usr.sbin/afs/src/arlad/messages.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -35,36 +35,36 @@ * */ -/* $KTH: messages.h,v 1.17 2001/01/07 18:32:49 lha Exp $ */ +/* $arla: messages.h,v 1.24 2002/09/07 10:43:22 lha Exp $ */ #ifndef _MESSAGES_H_ #define _MESSAGES_H_ -void xfs_message_init (void); -int xfs_message_receive (int fd, struct xfs_message_header *h, u_int size); +void nnpfs_message_init (void); +int nnpfs_message_receive (int fd, struct nnpfs_message_header *h, u_int size); void break_callback (FCacheEntry *e); void install_attr (FCacheEntry *e, int flags); long afsfid2inode(const VenusFid *fid); int -xfs_attr2afsstorestatus(struct xfs_attr *xa, +nnpfs_attr2afsstorestatus(struct nnpfs_attr *xa, AFSStoreStatus *storestatus); void update_fid(VenusFid oldfid, FCacheEntry *old_entry, VenusFid newfid, FCacheEntry *new_entry); -enum { FCACHE2XFSNODE_ATTR = 1, - FCACHE2XFSNODE_RIGHT = 2 } ; +enum { FCACHE2NNPFSNODE_LENGTH = 1 } ; /* allow update of filedata */ -#define FCACHE2XFSNODE_ALL (FCACHE2XFSNODE_ATTR|FCACHE2XFSNODE_RIGHT) +#define FCACHE2NNPFSNODE_NO_LENGTH 0 +#define FCACHE2NNPFSNODE_ALL (FCACHE2NNPFSNODE_LENGTH) void -fcacheentry2xfsnode (const VenusFid *fid, +fcacheentry2nnpfsnode (const VenusFid *fid, const VenusFid *statfid, AFSFetchStatus *status, - struct xfs_msg_node *node, + struct nnpfs_msg_node *node, AccessEntry *ae, int flags); diff --git a/usr.sbin/afs/src/arlad/reconnect.c b/usr.sbin/afs/src/arlad/reconnect.c index f60b6ee1ab5..d9641d8dc47 100644 --- a/usr.sbin/afs/src/arlad/reconnect.c +++ b/usr.sbin/afs/src/arlad/reconnect.c @@ -1,2207 +1,2213 @@ -/* COPYRIGHT (C) 1998 - * THE REGENTS OF THE UNIVERSITY OF MICHIGAN - * ALL RIGHTS RESERVED - * - * PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS - * AND REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS - * FOR ANY PURPOSE, SO LONG AS THE NAME OF THE UNIVERSITY OF - * MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY - * PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE - * WITHOUT SPECIFIC, WRITTEN PRIOR AUTHORIZATION. IF THE - * ABOVE COPYRIGHT NOTICE OR ANY OTHER IDENTIFICATION OF THE - * UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY - * PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST - * ALSO BE INCLUDED. - * - * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION - * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY - * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF - * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING - * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE - * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE - * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR - * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING - * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN - * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGES. - */ - -/* - * Do merging of the files that changed with we was in disconnected mode - */ - -#if 0 - -#include "arla_local.h" - -RCSID("$KTH: reconnect.c,v 1.30.2.1 2001/06/04 22:16:39 ahltorp Exp $"); - -static int reconnect_nonmute(struct vcache *, int, struct timeval); -static int reconnect_putattr(struct vcache *, struct xfs_attr *); -static int reconnect_putdata(struct vcache *); -static int reconnect_remove(struct vcache *, FCacheEntry *childentry, char *); -static int reconnect_rename(struct vcache *, struct vcache *, char *, char *); -static int reconnect_rmdir(struct vcache *vcp, FCacheEntry *childEntry, - char *name); -static int reconnect_mkdir(struct vcache *parent, struct vcache *curdir, - AFSStoreStatus *store_status, char *name); -static int reconnect_link(struct vcache *parent, struct vcache *existing, - char *name); -static int reconnect_symlink(struct vcache *parent, struct vcache *child, - AFSStoreStatus *store_attr, char *name, - char *contents); -static int reconnect_create(struct vcache *parent, struct vcache *child, - char *name); -static int reconnect_mut_chk(FCacheEntry *fce, CredCacheEntry *ce, - int version); - -static int check_log_todo(log_ent_t * , VenusFid *, VenusFid *); -static int is_done_before(int no); -static void add_done_list(int no); -static void clear_log_entry(void); -static void clear_index_list(void); - -typedef struct _fid_trans{ - VenusFid logged_fid; - VenusFid fetched_fid; - struct _fid_trans *next, *prev; -} fid_trans; - -typedef struct _fid_keep{ - char name[MAX_NAME]; - AFSFid kept_fid; - struct _fid_keep *next; -} fid_keep; - -typedef struct _index_list{ - int index; - struct _index_list * next; -} index_list; - -fid_trans *fid_AD_head, *fid_AD_tail; -fid_keep *fid_KP_head; -index_list * index_head; -extern log_ent_t log_head; - - -/* - * - */ - -static void -set_fid_value(VenusFid *new, VenusFid *old) -{ - if(old==0) { - new->fid.Volume = 0; - new->fid.Vnode = 0; - new->fid.Unique = 0; - } else { - new->fid.Volume = old->fid.Volume; - new->fid.Vnode = old->fid.Vnode; - new->fid.Unique = old->fid.Unique; - } -} - -/* - * - */ - -void -do_replay(char *log_file, int log_entries, VenusFid *changed_fid) -{ - int fd, len, i; - log_ent_t *cur_log; - struct vcache vc, vc_new; - char *name, *name_new; - fid_trans *fid_tmp; - fid_keep * fid_KP_tail; - VenusFid new_fid; - - int count=1; /* Used to record how may actions we have done*/ - - fid_AD_tail = fid_AD_head; - cur_log = (log_ent_t *) malloc(sizeof(log_ent_t)); - fd = open(log_file, O_RDWR | O_BINARY); - - set_fid_value(&new_fid , 0); - - while (read(fd, cur_log, sizeof(int))){ - - if (cur_log->log_len < sizeof(*cur_log) - sizeof(cur_log->log_data) || - cur_log->log_len > sizeof(log_ent_t)) { - arla_log(ADEBDISCONN, "do_replay: corrupt log entry, log_len %d", - cur_log->log_len); - goto terminate; - } - - len = cur_log->log_len - sizeof(int); - - if (!read(fd, ((char *)cur_log + sizeof(int)), len)){ - arla_log(ADEBDISCONN, "do_replay: read bad log entry..."); - goto terminate; - } - - arla_log(ADEBDISCONN, - "do_replay: read %d bytes of log entry.", - cur_log->log_len); - - if (is_done_before(cur_log->log_index)==1) - continue; /* the log entry has been executed */ - else { - if (changed_fid !=0) { - int is_log_todo = 0; - - is_log_todo = check_log_todo(cur_log, changed_fid, &new_fid); - if (is_log_todo ==0) - continue; /* This log should not be executed */ - } - } - - add_done_list(cur_log->log_index); - - /* big case/switch statement to switch log_op */ - switch (cur_log->log_op){ - - case DIS_STORE: - vc.fid = cur_log->st_fid; - vc.DataVersion = cur_log->st_origdv-1; - vc.flag = cur_log->st_flag; - vc.cred = cur_log->cred; - arla_log(ADEBDISCONN, - "%d action is to do_replay: **replay** (putdata) op...", - count++); - reconnect_putdata(&vc); - break; - case DIS_SETATTR: - vc.fid = cur_log->sa_fid; - vc.DataVersion = cur_log->sa_origdv; - vc.flag = 0; - vc.cred = cur_log->cred; - arla_log(ADEBDISCONN, - "%d action is to do_replay: **replay** (putattr) op...", - count++); - reconnect_putattr(&vc, &(cur_log->sa_vattr)); - break; - case DIS_REMOVE: { - FCacheEntry *childentry; - vc.fid = cur_log->rm_filefid; - vc.DataVersion = cur_log->rm_origdv; - vc.flag = 0; - vc.cred = cur_log->cred; - childentry = cur_log->rm_chentry; - name = cur_log->rm_name; - arla_log(ADEBDISCONN, - "%d action is to do_replay: **replay** " - "(file remove) op...", - count++); - reconnect_remove(&vc, childentry, name); - break; - } - case DIS_RMDIR: { - FCacheEntry *child; - vc.fid = cur_log->rd_parentfid; - name = cur_log->rd_name; - vc.cred = cur_log->cred; - child = cur_log->rd_direntry; - arla_log (ADEBDISCONN, - "%d action is to do_replay: **rmdir** " - "(directory remove) op...", - count++); - reconnect_rmdir(&vc, child, name); - break; - } - case DIS_RENAME: - vc.fid = cur_log->rn_oparentfid; - vc.DataVersion = cur_log->rn_origdv; - vc.flag = 0; - vc.cred = cur_log->cred; - vc_new.fid = cur_log->rn_nparentfid; - vc_new.DataVersion = cur_log->rn_overdv; - vc_new.flag = 0; - vc_new.cred = cur_log->cred; - name = cur_log->rn_names; - for (i=0; *(name+i)!='\0';++i); - name_new = name+i+1; - arla_log(ADEBDISCONN, - "%d action is to do_replay: **replay** (rename) op...", - count++); - reconnect_rename(&vc, &vc_new, name, name_new); - break; - case DIS_MKDIR: { - AFSStoreStatus store_status; - vc.fid = cur_log->md_parentfid; - vc.cred = cur_log->cred; - store_status = cur_log->md_vattr; - vc_new.fid = cur_log->md_dirfid; - /*Ba Wu: child's data vers*/ - vc_new.DataVersion = cur_log->md_dversion; - name = cur_log->md_name; - arla_log(ADEBDISCONN, - "%d action is to DO_Replay: **replay** (mkdir) op...", - count++); - reconnect_mkdir(&vc, &vc_new, &store_status, name); - break; - } - case DIS_LINK: - vc.cred = cur_log->cred; - vc.fid = cur_log->ln_parentfid; - vc_new.fid = cur_log->ln_linkfid; - name = cur_log->ln_name; - arla_log(ADEBDISCONN, - "%d action is to do_replay: **replay** (link) op...", - count++); - reconnect_link(&vc, &vc_new, name); - break; - case DIS_SYMLINK: { - char *new_name; - AFSStoreStatus store_attr; - - vc.fid = cur_log->sy_parentfid; - vc.cred = cur_log->cred; - name = cur_log->sy_name; - new_name = cur_log->sy_content; - vc_new.fid = cur_log->sy_filefid; - store_attr = cur_log->sy_attr; - arla_log(ADEBDISCONN, - "%d action is to do_replay: **replay** (symlink) op...", - count++); - reconnect_symlink(&vc, &vc_new, &store_attr, name, new_name); - break; - } - case DIS_CREATE: - vc.fid = cur_log->cr_parentfid; - vc.cred = cur_log->cred; - - vc_new.fid = cur_log->cr_filefid; - vc_new.DataVersion = cur_log->cr_origdv; - arla_log(ADEBDISCONN, - "%d action is to DO_Replay: **replay** (create) op...", - count++); - name = cur_log->cr_name; - reconnect_create(&vc, &vc_new, name); - break; - case DIS_ACCESS: - vc.fid = cur_log->nm_fid; - vc.DataVersion = cur_log->nm_origdv; - vc.cred = cur_log->cred; - arla_log(ADEBDISCONN, - "%d action is to do_replay: **replay** (nonmutating) op", - count++); - reconnect_nonmute(&vc, cur_log->log_op, cur_log->log_time); - break; - - default: - arla_log(ADEBDISCONN, - "%d action is to do_replay: skipping the current op=%d", - count++,cur_log->log_op); - } - } - - if (changed_fid ==0) { - clear_index_list(); /* clean all index when after discon */ - clear_log_entry(); - /* clean up, remove all associative data structures */ - fid_AD_tail = fid_AD_head; - while(fid_AD_tail) - { - fid_tmp = fid_AD_tail->next; - free(fid_AD_tail); - fid_AD_tail = fid_tmp; - } - /* SWW Qiyue 28: We need to reset head to 0*/ - fid_AD_head = 0; - fid_KP_tail = fid_KP_head; - while(fid_KP_tail) - { - fid_keep *fid_tmp; - - fid_tmp = fid_KP_tail->next; - free(fid_KP_tail); - fid_KP_tail = fid_tmp; - } - - fid_KP_head = 0; - } - i = ftruncate (fd, 0); - assert (i == 0); - - terminate: - - arla_warnx (ADEBDISCONN,"We have done total %d replays",count-1); - close(fd); - free(cur_log); - return; -} - -/* - * - */ - -static int -check_rm_fid (VenusFid v1, VenusFid v2) -{ - if(v1.fid.Vnode == v2.fid.Vnode && - v1.fid.Volume == v2.fid.Volume && - v1.fid.Unique == v2.fid.Unique ) - return 1; - else - return 0; -} - -/* - * - */ - -static int -check_log_fid(struct vcache vc, VenusFid *fid) -{ - log_ent_t *temp = log_head.next; - - if (vc.fid.fid.Vnode == fid->fid.Vnode && - vc.fid.fid.Volume == fid->fid.Volume && - vc.fid.fid.Unique == fid->fid.Unique) - return 1; - - while (temp!=0) { - switch(temp->log_op) { - case DIS_RENAME: - if (check_rm_fid(temp->rn_oparentfid,*fid)==1) - return 1; - default: - temp = temp->next; - break; - } - } - return 0; -} - -/* - * - */ - -static int -check_log_todo(log_ent_t * cur_log , VenusFid *fid, VenusFid *newfid) -{ - VenusFid *lookfid; - struct vcache vc, vc_new; - int will_do = 0; - - if (newfid->fid.Vnode ==0 && - newfid->fid.Volume == 0 && - newfid->fid.Unique ==0) - lookfid = fid; - else - lookfid = newfid; /* For create and putdata */ - - switch (cur_log->log_op){ - case DIS_STORE: - vc.fid = cur_log->st_fid; - will_do = check_log_fid(vc, lookfid); - if (will_do==1) { - set_fid_value(newfid, 0); - return 1; - } - break; - case DIS_SETATTR: - vc.fid = cur_log->sa_fid; - will_do = check_log_fid(vc, lookfid); - if (will_do==1) { - set_fid_value(newfid , &cur_log->sa_fid); - return 1; - } - break; - case DIS_REMOVE: - vc.fid = cur_log->rm_filefid; - will_do = check_log_fid(vc, lookfid); - if (will_do==1) { - return 1; - } - break; - case DIS_RMDIR: - vc.fid = cur_log->rd_parentfid; - will_do = check_log_fid(vc, lookfid); - if (will_do==1) { - return 1; - } - break; - case DIS_RENAME: - vc.fid = cur_log->rn_oparentfid; - will_do = check_log_fid(vc, lookfid); - if (will_do==1) { - return 1; - } - vc_new.fid = cur_log->rn_nparentfid; - will_do = check_log_fid(vc_new, lookfid); - if (will_do==1) { - return 1; - } - break; - case DIS_MKDIR: - vc.fid = cur_log->md_parentfid; - will_do = check_log_fid(vc, lookfid); - if (will_do==1) { - return 1; - } - break; - case DIS_LINK: - break; - case DIS_SYMLINK: - will_do = check_log_fid(vc, lookfid); - if (will_do==1) { - return 1; - } - break; - case DIS_CREATE: - vc.fid = cur_log->cr_parentfid; - will_do = check_log_fid(vc, lookfid); - if (will_do==1) { - set_fid_value(newfid , &cur_log->cr_filefid); - return 1; - } - break; - case DIS_FSYNC: - case DIS_ACCESS: - case DIS_READDIR: - case DIS_READLINK: - case DIS_INFO: - case DIS_START_OPT: - case DIS_END_OPT: - case DIS_REPLAYED: - /* A no op */ - break; - } - return 0; -} - - -#if 0 - -/* - * - */ - -void -keepfid_newrename(char *name, - AFSFid fid) -{ - if (fid_KP_head == 0) { - fid_KP_head = (fid_keep *)malloc(sizeof(fid_keep)); - assert(fid_KP_head); - - strlcpy(fid_KP_head->name, name, sizeof(fid_KP_head->name)); - fid_KP_head->kept_fid = fid; - fid_KP_head->next = 0; - } - else { - fid_keep *temp; - - temp = (fid_keep *)malloc(sizeof(fid_keep)); - assert(temp); - - strlcpy(temp->name, name, sizeof(temp->name)); - temp->kept_fid = fid; - temp->next = fid_KP_head->next; - fid_KP_head->next = temp; - } -} - -#endif - -/* - * - */ - -static int -find_venus (char *name, VenusFid *fid) -{ - fid_keep *fid_temp; - - if(fid_KP_head == 0 ) - return 1; /*error */ - - fid_temp = fid_KP_head; - - while(fid_temp) { - if (strcmp(fid_temp->name,name) == 0) { - fid->fid.Volume = fid_temp->kept_fid.Volume; - fid->fid.Vnode = fid_temp->kept_fid.Vnode; - fid->fid.Unique = fid_temp->kept_fid.Unique; - return 0; - } - fid_temp = fid_temp->next; - } - arla_warnx (ADEBDISCONN, "find_venus: *PANIC* not found fid for %s", name); - return 1; -} - - -/* - * - */ - -VenusFid * -fid_translate(VenusFid *fid_in) -{ - fid_trans *fid_tmp; - VenusFid *fid_ret; - - if (!fid_AD_head) - return fid_in; - - fid_tmp = fid_AD_head; - - while(fid_tmp){ - - fid_ret=&fid_tmp->logged_fid; - - if ((fid_ret->Cell == fid_in->Cell) && - (fid_ret->fid.Volume == fid_in->fid.Volume) && - (fid_ret->fid.Vnode == fid_in->fid.Vnode) && - (fid_ret->fid.Unique == fid_in->fid.Unique)) - return &fid_tmp->fetched_fid; - - fid_tmp = fid_tmp->next; - } - return fid_in; -} - -/* - * - */ - -static void -clear_index_list(void) -{ - index_list *temp=index_head; - - while(temp!=0) { - index_list *tmp; - - tmp = temp->next; - free(temp); - temp = tmp; - } - index_head = 0; -} - -/* - * - */ - -static void -clear_log_entry(void) -{ - log_ent_t *temp=log_head.next; - - while(temp!=0) { - log_ent_t *tmp; - - tmp = temp->next; - free(temp); - temp = tmp; - } - log_head.next = 0; -} - -/* - * - */ - -static int -is_done_before(int no) -{ - index_list * temp = index_head; - - while(temp !=0) { - if (temp->index == no) - return 1; - else - temp = temp->next; - } - return 0; -} - -/* - * - */ - -static void -add_done_list(int no) -{ - if (!index_head) { - index_head = (index_list *)malloc(sizeof(index_list)); - assert(index_head); - index_head->index = no; - index_head->next = 0; - } else { - index_list * temp; - temp = (index_list *) malloc(sizeof(index_list)); - assert(temp); - temp->next = index_head->next; - index_head->next = temp; - temp->index = no; - } -} - -/* - * - */ - -static void -alloc_fid_trans(VenusFid *logged_fid) -{ - if (!fid_AD_head) - { - /*SWW Qiyue 28 Make sure we have the memory*/ - fid_AD_head = (fid_trans *) malloc(sizeof(fid_trans)); - assert(fid_AD_head); - - fid_AD_head->prev=fid_AD_head->next = 0; - fid_AD_tail = fid_AD_head; - fid_AD_tail->logged_fid = *logged_fid; - - } else{ - - /*SWW Qiyue 28 Make sure we have the memory*/ - fid_AD_tail->next = (fid_trans *) malloc(sizeof(fid_trans)); - assert(fid_AD_tail->next); - - fid_AD_tail->next->prev = fid_AD_tail; - fid_AD_tail->next->next = 0; - fid_AD_tail = fid_AD_tail->next; /*Ba ba: move tail ahead */ - fid_AD_tail->logged_fid = *logged_fid; - } -} - -/* - * - */ - -static void -fill_fid_trans (VenusFid *fetched_fid) -{ - fid_AD_tail->fetched_fid = *fetched_fid; -} - -/* - * - */ - -#if 0 -void -update_entry_flag (FCacheEntry *entry) -{ - entry->flags.attrp = FALSE; - entry->flags.datap = FALSE; -} -#endif - -/* - * - */ - -int reconnect_nonmute(struct vcache *vcp, int op, struct timeval log_time) -{ - FCacheEntry *fce, fce_fetched; - CredCacheEntry *ce; - int error; - VenusFid *fid; -#if 0 - ConnCacheEntry *conn; -#endif - - arla_warnx (ADEBDISCONN, - "Start of reconnect_nonmute by sww"); /*SWW Qiyue 25*/ - - fid = &(vcp->fid); - if (fid->Cell == -1) /* newly created file, skip reconnect */ - return 0; - - error = fcache_find(&fce, *fid); - /* assert(fce); */ - if (error) /* nonmute op on nonexisting data */ - { - arla_log(ADEBDISCONN, - "reconnect: nonmute op %d performed on cache " - "entry no longer exist locally!", - op); - return -1; - } - - arla_log(ADEBDISCONN, - "reconnect: DISCONNECTED nonmute " - "on fid.Cell=0x%x, fid.fid.Volume= 0x%x, fid.fid.Vnode=0x%x, " - "fid.fid.Unique=0x%x", fid->Cell, - fid->fid.Volume, - fid->fid.Vnode, - fid->fid.Unique); - - ce = cred_get (fid->Cell, vcp->cred.pag, CRED_ANY); - assert (ce != NULL); - error = 0; - - /* setting some stuff so do_read_attr would work */ - fce->flags.attrp = TRUE; - fce->callback.CallBackType = 2; - fce_fetched = *fce; - /*conn = findconn (fce, ce);*/ - - error = read_attr(&fce_fetched, ce); - - arla_log(ADEBDISCONN, - "reconnect: logged DataVersion=%d, " - "fetched DataVersion=%d", - vcp->DataVersion, - fce_fetched.status.DataVersion); - - if (vcp->DataVersion < fce_fetched.status.DataVersion) - { - if (log_time.tv_usec >= fce_fetched.status.ServerModTime) - arla_log(ADEBDISCONN, - "Warning: nonmutating operation %d read stale data!", - op); - else if (log_time.tv_usec <= fce_fetched.status.ServerModTime && - (vcp->DataVersion +1) == fce_fetched.status.DataVersion) - arla_log(ADEBDISCONN, - "Notice: file modified once after nonmutating " - "operation %d.", - op); - else - arla_log(ADEBDISCONN, - "Warning: nonmutating operation %d might have read " - "stale data!", op); - } - - ReleaseWriteLock(&fce->lock); - cred_free(ce); - /*conn_free(conn);*/ - - return error; -} - -/* - * - */ - -int reconnect_remove(struct vcache *vcp, FCacheEntry *childentry, char *name) -{ - FCacheEntry *fce; - CredCacheEntry *ce; - int error; - VenusFid *fid, tempfid; /* Ba san: to check the deletion of file*/ - Result res; - int isupdate; - - ConnCacheEntry *conn; - fs_server_context context; - AFSFetchStatus status; - AFSVolSync volsync; - char tmp[2 * sizeof(int) + 2]; - fcache_cache_handle cache_handle; - - fid = &(vcp->fid); /* points to the VenusFid structure */ - fid = fid_translate(fid); - - arla_log(ADEBDISCONN, "reconnect: DISCONNECTED remove on " - "fid.Cell=0x%x, fid.fid. Volume= 0x%x, fid.fid.Vnode=0x%x, " - "fid.fid.Unique=0x%x", - fid->Cell, fid->fid.Volume, fid->fid.Vnode, fid->fid.Unique); - - /* ObtainWriteLock called in fcache_find */ - error = fcache_find(&fce, *fid); - assert (error == 0); - - ce = cred_get (fid->Cell, vcp->cred.pag, CRED_ANY); - assert (ce != NULL); - - if (connected_mode != CONNMODE_PARCONNECTED) { - ObtainWriteLock(&childentry->lock); - isupdate = reconnect_mut_chk(childentry, ce, - childentry->status.DataVersion); - ReleaseWriteLock(&childentry->lock); - - if (isupdate) - { - fcache_cache_handle cache_handle; - - arla_log(ADEBDISCONN, - "reconnect_remove: can't remove because file modified!"); - cred_free(ce); - adir_creat (fce, name, childentry->fid.fid); - childentry->flags.attrp = FALSE; - ReleaseWriteLock(&fce->lock); - conv_dir (fce, ce, 0, &cache_handle, tmp, sizeof(tmp)); - ReleaseWriteLock(&fce->lock); - return -1; - } - } /* Ba ershi: we dont need to do it in parconn */ - - res.res = 0; - - AssertExclLocked(&fce->lock); - - conn = find_first_fs (fce, ce, &context); - if (conn == NULL) { - arla_log (ADEBDISCONN, "find_first_fs failed", fce->index); - cred_free(ce); - ReleaseWriteLock(&fce->lock); - return ENETDOWN; - } - -/* Ba san: check the file exists - - ReleaseWriteLock(&fce->lock); - error = adir_lookup(fce->fid, name, &tempfid, NULL, &ce); - assert (error == 0); - ObtainWriteLock(&fce->lock); */ - - res.res = RXAFS_RemoveFile (conn->connection, - &fce->fid.fid, - name, - &status, - &volsync); - if (res.res) { - arla_log (ADEBDISCONN, "Could not RemoveFile: %s (%d)", - koerr_gettext(res.res), res.res); - goto out; - } - - arla_warnx (ADEBDISCONN,"In reconnect_remove: Remove the file %s",name); - -/* Ba san: Chcek the deletion of the file */ - ReleaseWriteLock(&fce->lock); - error = adir_lookup(&fce->fid, name, &tempfid, NULL, &ce); - ObtainWriteLock(&fce->lock); - - if (error == 0) { - int result; - - arla_warnx (ADEBDISCONN, - "In reconnect_remove: file %s needs to be deleted", - name); - result = adir_remove (fce,name); - assert ( result == 0); - } /* This is for the file produced during disconnect mode, - if error==ENOENT then the file is created during connect mode*/ - - - fce->status = status; - fce->volsync = volsync; - childentry->host = 0; /* Ba shiliu dont get callback */ - - volcache_update_volsync (fce->volume, fce->volsync); - conv_dir (fce, ce, 0, &cache_handle, tmp, sizeof(tmp)); - - out: - - cred_free(ce); - free_fs_server_context(&context); - ReleaseWriteLock(&fce->lock); - return error; -} - -/* - * - */ - -int -reconnect_rmdir(struct vcache *vcp, FCacheEntry *childEntry, char *name) -{ - FCacheEntry *fce; - CredCacheEntry *ce; - int error; - VenusFid *fid, tempfid; /* Ba san: to check the deletion of file*/ - Result res; - char tmp[2 * sizeof(int) + 2]; - int ret = 0; - Result tempres; - fcache_cache_handle cache_handle; - - ConnCacheEntry *conn; - fs_server_context context; - AFSFetchStatus status; - AFSVolSync volsync; - - fid = &(vcp->fid); /* points to the VenusFid structure */ - fid = fid_translate(fid); - - ret = fcache_find(&fce, *fid); - assert (ret == 0); - - ce = cred_get (fid->Cell, vcp->cred.pag, CRED_ANY); - assert (ce != NULL); - - AssertExclLocked(&fce->lock); - - conn = find_first_fs (fce, ce, &context); - if (conn == NULL) { - arla_log (ADEBDISCONN, "find_first_fs failed", fce->index); - cred_free(ce); - ReleaseWriteLock(&fce->lock); - return ENETDOWN; - } - - ret = RXAFS_RemoveDir (conn->connection, - &fce->fid.fid, - name, - &status, - &volsync); - if (ret) { - arla_log (ADEBDISCONN, - "Could not RemoveDir : %s (%d)", - koerr_gettext(res.res),res.res); - goto out; - } - -/* Ba san: Chcek the deletion of the file */ - ReleaseWriteLock(&fce->lock); - error = adir_lookup(&fce->fid, name, &tempfid, NULL, &ce); - ObtainWriteLock(&fce->lock); - - if (error == 0) { - int result; - - arla_warnx (ADEBDISCONN, - "In reconnect_rmdir: file %s needs to be deleted",name); - result = adir_remove (fce,name); - assert ( result == 0); - } /* This is for the file produced during disconnect mode, - if error==ENOENT then the file is created during connect mode*/ - - fce->status = status; - fce->volsync = volsync; - - volcache_update_volsync (fce->volume, fce->volsync); - - tempres = conv_dir(fce, ce, 0, &cache_handle, tmp, sizeof(tmp)); - - childEntry->host = 0; /*Ba shiqi: no callback for this entry*/ - - out: - - cred_free(ce); - free_fs_server_context(&context); - ReleaseWriteLock(&fce->lock); - return error; -} - -/* - * - */ - -static int -reconnect_mut_chk(FCacheEntry *fce, CredCacheEntry *ce, int version) -{ - ConnCacheEntry *conn; - fs_server_context context; - FCacheEntry fetched = *fce; - int ret; - - AFSFetchStatus status; - AFSCallBack callback; - AFSVolSync volsync; - - AssertExclLocked(&fetched.lock); - -/*SWW Aug 01: >= is changed into > */ - conn = find_first_fs (&fetched, ce, &context); - if (conn == NULL) { - arla_log (ADEBDISCONN, "find_first_fs failed", fce->index); - return ENETDOWN; - } - - ret = RXAFS_FetchStatus (conn->connection, - &fce->fid.fid, - &status, - &callback, - &volsync); - if (ret) { - if (ret == -1) - ret = ENETDOWN; - free_fs_server_context(&context); - arla_warn (ADEBFCACHE, ret, "fetch-status"); - return ret; - } - - if (status.DataVersion > version) - { - arla_log(ADEBDISCONN, "reconnect_mut_chk: concurrent writes detected!"); - return 1; - } - free_fs_server_context(&context); - return 0; -} - -/* - * - */ - -static void -fcache_backfile_name(char *name, size_t len) -{ - static int no = 1; - - snprintf (name, len, "%04X",no++); - strlcat (name, "bak", len); -} - -/* - * - */ - -static void -copy_cached_file(int from, int to) -{ - char name_from[2 * sizeof(int) + 1], name_to[2 * sizeof(int) + 1]; - int fd_from, n, fd_to; - char buf[BUFSIZE]; - - snprintf (name_from, sizeof(name_from), "%04X", from); - snprintf (name_to, sizeof(name_to), "%04X", to); - - fd_from = open(name_from,O_RDONLY | O_BINARY); - fd_to = open(name_to, O_WRONLY | O_CREAT | O_BINARY | O_TRUNC, 0600); - - while((n = read(fd_from, buf, BUFSIZE)) > 0) - write(fd_to, buf, n); - -#if 0 - if(fstat(fd_to, &statinfo)<0) { - arla_warnx(ADEBDISCONN,"ERROR"); - } -#endif - - close(fd_from); - close(fd_to); -} - -/* - * - */ - -static void -reconnect_update_fid (FCacheEntry *entry, VenusFid oldfid) -{ - if (entry->flags.kernelp) - update_fid (oldfid, NULL, entry->fid, entry); -} - -/* - * - */ - -static int -reconnect_mut_newfile(FCacheEntry **fcep, xfs_pag_t cred,VenusFid *new_fid) -{ - - FCacheEntry *parent_fce; - u_long host; - char name[2 * sizeof(int) + 3 + 1], tmp[2 * sizeof(int) + 2]; - AFSStoreStatus store_attr; - AFSFetchStatus fetch_attr; - CredCacheEntry *ce; - AccessEntry *ae; - VenusFid newfid; - int ret; - int from, to; - fcache_cache_handle cache_handle; - - ret = fcache_find (&parent_fce, (*fcep)->parent); - assert (ret == 0); - - host = (*fcep)->host; - - ce = cred_get((*fcep)->parent.Cell, cred, CRED_ANY); - - fcache_backfile_name (name, sizeof(name)); - - store_attr.Mask = 8; - store_attr.ClientModTime = 430144; - store_attr.Owner = 1957724; - store_attr.Group = 21516; - store_attr.UnixModeBits = 420; - store_attr.SegSize = 0; - - create_file(parent_fce, name, &store_attr, &newfid, &fetch_attr, ce); - - (*fcep)->flags.datap = FALSE; /* Ba shiqi: we need to get the old from FS*/ - *new_fid = newfid; - from = (*fcep)->index; - ret = fcache_find(fcep, newfid); - assert (ret == 0); - to = (*fcep)->index; - (*fcep)->host = host; - (*fcep)->flags.attrp = TRUE; - (*fcep)->flags.datap = TRUE; - findaccess(ce->cred, (*fcep)->acccache, &ae); /*Ba shijiu obtain access */ - ae->cred = ce->cred; - ae->access = (*fcep)->status.CallerAccess; - - ReleaseWriteLock(&(*fcep)->lock); - - copy_cached_file(from, to); - ret = adir_creat (parent_fce, name, newfid.fid); - assert (ret ==0); - conv_dir (parent_fce, ce, 0, &cache_handle, tmp, sizeof(tmp)); - ReleaseWriteLock(&parent_fce->lock); - - return 0; -} - - -/* - * - */ - -int reconnect_putattr(struct vcache *vcp, struct xfs_attr *xap) -{ - - ConnCacheEntry *conn; - fs_server_context context; - struct rx_call *call; - VenusFid *fid; - CredCacheEntry *ce; - FCacheEntry *fce, *tempce; - AFSFetchStatus status; - Result res; - u_int32_t sizefs; - AFSStoreStatus storestatus; - AFSVolSync volsync; - int ret; - - fid = &(vcp->fid); /* points to the VenusFid structure */ - fid = fid_translate(fid); - -#if 0 - arla_log(ADEBDISCONN, "reconnect: DISCONNECTED write on fid.Cell=0x%x, " - "fid.fid.Volume= 0x%x, fid.fid.Vnode=0x%x, fid.fid.Unique=0x%x", - fid->Cell, - fid->fid.Volume, - fid->fid.Vnode, - fid->fid.Unique); -#endif - - ce = cred_get (fid->Cell, vcp->cred.pag, CRED_ANY); - assert (ce != NULL); - res.res = 0; - -#if 0 -/* Ba shier: should we send the file back to server? */ - if (XA_VALID_SIZE(xap)){ - res = cm_ftruncate (*fid, xap->xa_size, ce); - } -#endif - - ret = fcache_find(&fce, *fid); - assert (ret == 0); - tempce = fce; - - sizefs=fce->status.Length; - -#if 0 /* XXX */ - /* some people have written to the file while we are disconnected */ - /* we have to give it a different name on the server */ - if (reconnect_mut_chk(fce, ce, vcp->DataVersion)) - { - VenusFid new_fid; - - alloc_fid_trans(fid); - reconnect_mut_newfile(&fce,vcp->cred.pag,&new_fid); - fce->status.Length = sizefs; - fce->length = sizefs; - ReleaseWriteLock(&tempce->lock); - fill_fid_trans(&new_fid); - tempce->flags.attrp = FALSE; - tempce->flags.kernelp = FALSE; - } -#endif - - /* code from truncate file XXX join */ - conn = find_first_fs (fce, ce, &context); - if (conn == NULL) { - arla_log (ADEBDISCONN, "find_first_fs failed."); - ReleaseWriteLock(&fce->lock); - cred_free(ce); - return ENETDOWN; - } - - if (fce->status.FileType != TYPE_DIR) { - - call = rx_NewCall (conn->connection); - if (call == NULL) { - arla_log (ADEBDISCONN, "Cannot call"); - res.res = ENOMEM; - goto out; - } - - storestatus.Mask = 0; - res.res = StartRXAFS_StoreData (call, - &(fce->fid.fid), - &storestatus, - 0, 0, fce->status.Length); - if(res.res) { - arla_log (ADEBDISCONN, "Could not start store, %s (%d)", - koerr_gettext(res.res), res.res); - rx_EndCall(call, 0); - goto out; - } - - sizefs = htonl (sizefs); - if (rx_Write (call, &sizefs, sizeof(sizefs)) != sizeof(sizefs)) { - res.res = conv_to_arla_errno(rx_Error(call)); - arla_log (ADEBDISCONN, "Error writing length: %d", res.res); - rx_EndCall(call, 0); - goto out; - } - - if (rx_Write (call, 0, 0) != 0) { - res.res = conv_to_arla_errno(rx_Error(call)); - arla_log (ADEBDISCONN, "Error writing: %d", res.res); - rx_EndCall(call, 0); - goto out; - } - - res.res = rx_EndCall (call, EndRXAFS_StoreData (call, - &status, - &volsync)); - if (res.res) { - arla_log (ADEBDISCONN, "Error rx_EndCall: %s (%d)", - koerr_gettext(res.res), res.res); - goto out; - } - - fce->status = status; - fce->volsync = volsync; - - volcache_update_volsync (fce->volume, fce->volsync); - - } - /* code from write_attr XXX join */ - xfs_attr2afsstorestatus(xap, &storestatus); - - res.res = RXAFS_StoreStatus (conn->connection, - &fce->fid.fid, - &storestatus, - &status, - &volsync); - if (res.res) { - arla_log (ADEBDISCONN, "Could not make store-status call, %s (%d)", - koerr_gettext(res.res), res.res); - goto out; - } - arla_log(ADEBDISCONN, - "write_attr: status.Length = %d", status.Length); - fce->status = status; - fce->volsync = volsync; - - volcache_update_volsync (fce->volume, fce->volsync); - - out: - - free_fs_server_context(&context); - ReleaseWriteLock(&fce->lock); - cred_free(ce); - return res.res; -} - -/* - * - */ - -static int -reconnect_putdata(struct vcache *vcp) -{ - VenusFid *fid; - FCacheEntry *fce; - CredCacheEntry *ce; - Result res; - - u_int32_t sizefs; - int fd = -1; - struct rx_call *call; - ConnCacheEntry *conn; - fs_server_context context; - struct stat statinfo; - AFSStoreStatus storestatus; - AFSFetchStatus status; - AFSVolSync volsync; - int ret; - - fid = &(vcp->fid); /* points to the VenusFid structure */ - arla_log(ADEBDISCONN, "reconnect: putdata before fid_translate, " - "fid->Cell=0x%x, fid->fid.Volume=0x%x, fid->fid.Vnode=0x%x, " - "fid->fid.Unique=0x%x", - fid->Cell, - fid->fid.Volume, - fid->fid.Vnode, - fid->fid.Unique); - - fid = fid_translate(fid); - - arla_log(ADEBDISCONN, "reconnect: putdata after fid_translate, " - "fid->Cell=0x%x, fid->fid.Volume=0x%x, fid->fid.Vnode=0x%x, " - "fid->fid.Unique=0x%x", - fid->Cell, - fid->fid.Volume, - fid->fid.Vnode, - fid->fid.Unique); - - - ce = cred_get (fid->Cell, vcp->cred.pag, CRED_ANY); - assert (ce != NULL); - - ret = fcache_find (&fce, *fid); - assert (ret == 0); - -#if 0 - isupdate = reconnect_mut_chk(fce, ce, vcp->DataVersion); - if (isupdate) - { - arla_log(ADEBDISCONN, - "reconnect_putdata: send data back because " - "the file was modified!"); - cred_free(ce); - ReleaseWriteLock(&fce->lock); - reconnect_mut_newfile(&fce, vcp->cred.pag); - return -1; - } - - if (reconnect_mut_chk (fce, ce)) { - arla_log (ADEBDISCONN, "Reconnect_putdata: can not send the file" - "to FS becausethis file has been modified!"); - ReleaseWriteLock(&fce->lock); - return -1; - } -#endif - - /* code taken from write_data XXX join */ - AssertExclLocked(&fce->lock); - - conn = find_first_fs (fce, ce, &context); - if (conn == NULL) { - arla_log (ADEBDISCONN, "find_first_fs failed"); - ReleaseWriteLock(&fce->lock); - cred_free(ce); - return ENETDOWN; - } - - fd = fcache_open_file (fce, O_RDONLY); - if (fd < 0) { - arla_log (ADEBDISCONN, "open %u failed", fce->index); - res.res = errno; - goto out; - } - - if (fstat (fd, &statinfo) < 0) { - arla_log (ADEBDISCONN, "Cannot stat file %u", fce->index); - res.res = errno; - goto out; - } - - sizefs = statinfo.st_size; - - call = rx_NewCall (conn->connection); - if (call == NULL) { - arla_log (ADEBDISCONN, "Cannot call"); - res.res = ENOMEM; - goto out; - } - - storestatus.Mask = 0; /* Dont save anything */ - res.res = StartRXAFS_StoreData (call, &fce->fid.fid, - &storestatus, - 0, - sizefs, - sizefs); - if (res.res) { - arla_log (ADEBDISCONN, "Could not start store, %s (%d)", - koerr_gettext(res.res), res.res); - rx_EndCall(call, 0); - goto out; - } - - res.res = copyfd2rx (fd, call, 0, sizefs); - if (res.res) { - rx_EndCall(call, res.res); - arla_log (ADEBDISCONN, "copyfd2rx failed: %d", res.res); - goto out; - } - - res.res = rx_EndCall (call, EndRXAFS_StoreData (call, - &status, - &volsync)); - if (res.res) { - arla_log (ADEBDISCONN, "Error rx_EndCall: %s (%d)", - koerr_gettext(res.res), res.res); - goto out; - } - if (status.DataVersion > fce->status.DataVersion) - arla_log(ADEBDISCONN, - "reconnect: putdata, server incremented DataVersion!"); - - fce->status = status; - fce->volsync = volsync; - - volcache_update_volsync (fce->volume, fce->volsync); - - out: - - ReleaseWriteLock(&fce->lock); - if (fd != -1) - close (fd); - free_fs_server_context (&context); - - cred_free(ce); - return res.res; -} - -/* - * - */ - -int reconnect_rename(struct vcache *vcp_old, struct vcache *vcp_new, - char *name_old, char *name_new) -{ - - FCacheEntry *fce_old, *fce_new; - CredCacheEntry *ce; - VenusFid *fid_old, *fid_new,foo_fid,*tempnew_fid; - int error; - - int ret = 0; - Result res; - char tmp[2 * sizeof(int) + 2]; - int isnewpar = 0; - ConnCacheEntry *conn; - fs_server_context context; - AFSFetchStatus orig_status, new_status; - AFSVolSync volsync; - fcache_cache_handle cache_handle; - - fid_old = &vcp_old->fid; - fid_old = fid_translate(fid_old); - - ret = fcache_find (&fce_old, *fid_old); - assert (ret == 0); - - /* ReleaseWriteLock(&fce_old->lock); SWW Qiyue 28 Maybe we dont need it*/ - assert(fce_old); - arla_log(ADEBDISCONN, "reconnect: old rename on Cell=0x%x, " - "fid.Volume= 0x%x, fid.Vnode=0x%x, fid.Unique=0x%x", - fce_old->fid.Cell, - fce_old->fid.fid.Volume, - fce_old->fid.fid.Vnode, - fce_old->fid.fid.Unique); - - fid_new = tempnew_fid = &vcp_new->fid; - fid_new = fid_translate(fid_new); - - if (tempnew_fid->fid.Volume != fid_new->fid.Volume || - tempnew_fid->fid.Vnode != fid_new->fid.Vnode || - tempnew_fid->fid.Unique != fid_new->fid.Unique) - isnewpar = 1; - -/*Ba ba: the parent dir was created during disconnected */ - - if (fid_old->fid.Volume == fid_new->fid.Volume && - fid_old->fid.Vnode == fid_new->fid.Vnode && - fid_old->fid.Unique == fid_new->fid.Unique ) - ReleaseWriteLock(&fce_old->lock); /* old and new are the same*/ - - ret = fcache_find (&fce_new, *fid_new); - assert (ret == 0); - - arla_log(ADEBDISCONN, "reconnect: new rename on Cell=0x%x, " - "fid.Volume= 0x%x, fid.Vnode=0x%x, fid.Unique=0x%x", - fce_new->fid.Cell, - fce_new->fid.fid.Volume, - fce_new->fid.fid.Vnode, - fce_new->fid.fid.Unique); - - - - arla_log(ADEBDISCONN, - "reconnect_rename: fce_old = 0x%x, fce_new = 0x%x", - fce_old, fce_new); - - ce = cred_get (vcp_old->fid.Cell, vcp_old->cred.pag, CRED_ANY); - assert (ce != NULL); - - AssertExclLocked(&fce_old->lock); - AssertExclLocked(&fce_new->lock); - - conn = find_first_fs (fce_old, ce, &context); - if (conn == NULL) { - arla_log (ADEBDISCONN, "find_first_fs failed"); - ReleaseWriteLock(&fce_new->lock); - - if (fid_old->fid.Volume != fid_new->fid.Volume || - fid_old->fid.Vnode != fid_new->fid.Vnode || - fid_old->fid.Unique != fid_new->fid.Unique ) - ReleaseWriteLock(&fce_old->lock); /* old and new are the same*/ - - cred_free(ce); - return ENETDOWN; - } - - error = RXAFS_Rename (conn->connection, - &fce_old->fid.fid, - name_old, - &fce_new->fid.fid, - name_new, - &orig_status, - &new_status, - &volsync); - - if (error) { - arla_log (ADEBDISCONN, "Could not Rename: %s (%d)", koerr_gettext(error), error); - goto out; } - - fce_old->status = orig_status; - fce_new->status = new_status; - - fce_old->volsync = fce_new->volsync = volsync; - - volcache_update_volsync (fce_old->volume, fce_old->volsync); - - -/*SWW Aug 01 */ - arla_warnx (ADEBDISCONN, - "reconnect_rename: we delete the old one %s volumn=0x%x, " - "vnode=0x%x,unique=0x%x", - name_old,fce_old->fid.fid.Volume, - fce_old->fid.fid.Vnode, - fce_old->fid.fid.Unique); - -/*Ba Yi: get the VenuseFid for new file */ - #if 0 - if (fid_old->fid.Volume == fid_new->fid.Volume && - fid_old->fid.Vnode == fid_new->fid.Vnode && - fid_old->fid.Unique == fid_new->fid.Unique ) ; -#endif - ReleaseWriteLock(&fce_old->lock); /* old and new are the same*/ - - error = adir_lookup (&fce_old->fid, name_old, &foo_fid, NULL, &ce); - -#if 0 - if (fid_old->fid.Volume == fid_new->fid.Volume && - fid_old->fid.Vnode == fid_new->fid.Vnode && - fid_old->fid.Unique == fid_new->fid.Unique ); -#endif - ObtainWriteLock (&fce_old->lock); - -/*Ba San: delete the old which was created during dis */ - if (error == 0) { - arla_warnx (ADEBDISCONN,"reconnect_rename: we delete the old one %s " - "volumn=0x%x,vnode=0x%x,unique=0x%x", - name_old, - foo_fid.fid.Volume, - foo_fid.fid.Vnode, - foo_fid.fid.Unique); - - adir_remove(fce_old,name_old); - adir_remove(fce_new,name_new); - - res = conv_dir (fce_old, ce, 0, &cache_handle, tmp, sizeof(tmp)); - - } else { - /* if found delete it */ -/*Ba San: try to find the previous VenuseFid for old name */ - if (error == ENOENT) { -#if 0 - if (fid_old->fid.Volume == fid_new->fid.Volume && - fid_old->fid.Vnode == fid_new->fid.Vnode && - fid_old->fid.Unique == fid_new->fid.Unique ); -#endif - ReleaseWriteLock(&fce_new->lock); - - error = adir_lookup (&fce_new->fid, name_new, &foo_fid, NULL, &ce); - -#if 0 - if (fid_old->fid.Volume == fid_new->fid.Volume && - fid_old->fid.Vnode == fid_new->fid.Vnode && - fid_old->fid.Unique == fid_new->fid.Unique ); -#endif - ObtainWriteLock (&fce_new->lock); - if (error == 0) /*Ba Si: We need delete the faked new */ - adir_remove(fce_new,name_new); - else if (error == ENOENT) { - int venusret; - - venusret = find_venus (name_new,&foo_fid); - assert (venusret==0); - arla_warnx (ADEBDISCONN,"I MUST WRITE A PROGRAM HERE"); - if (isnewpar == 1) { - - arla_warnx(ADEBDISCONN,"In reconnect_rename: " - "new Volume=0x%x,Vnode=0x%x,Unique=0x%x", - fce_new->fid.fid.Volume, - fce_new->fid.fid.Vnode, - fce_new->fid.fid.Unique); -#if 0 - error = adir_creat(fce_new, name_new, foo_fid.fid); -#endif - } - } - } - } - - arla_warnx (ADEBDISCONN,"reconnect_rename: we add the new one %s " - "volumn=0x%x,vnode=0x%x,unique=0x%x", - name_new, - foo_fid.fid.Volume, - foo_fid.fid.Vnode, - foo_fid.fid.Unique); - error = adir_creat (fce_new, name_new, foo_fid.fid); - res = conv_dir (fce_new, ce, 0, &cache_handle, tmp, sizeof(tmp)); - -/* Aug 1 */ - - out: - - free_fs_server_context (&context); - - ReleaseWriteLock(&fce_new->lock); - - if (fid_old->fid.Volume != fid_new->fid.Volume || - fid_old->fid.Vnode != fid_new->fid.Vnode || - fid_old->fid.Unique != fid_new->fid.Unique ) - ReleaseWriteLock(&fce_old->lock); /* old and new are the same*/ - - cred_free(ce); - return error; -} - -/* - * - */ - -int reconnect_create(struct vcache *parent, struct vcache *child, char *name) -{ - - ConnCacheEntry *conn; - fs_server_context context; - VenusFid *parent_fid; - VenusFid *child_fid; - VenusFid fakeFid; - - CredCacheEntry *ce; - FCacheEntry *parentEntry; - FCacheEntry *childEntry; - - AFSFetchStatus fetch_attr; - AFSStoreStatus store_attr; - - AFSFetchStatus status; - AFSCallBack callback; - AFSVolSync volsync; - int ret; - char tmp[2 * sizeof(int) + 2]; - fcache_cache_handle cache_handle; - int32_t type; - - parent_fid = &(parent->fid); /* points to the VenusFid structure */ - child_fid = &(child->fid); - fakeFid = *child_fid; - - /*Ba Liu: the parent dir may be created during dison mode*/ - parent_fid = fid_translate(parent_fid); - - ce = cred_get (parent->fid.Cell, parent->cred.pag, CRED_ANY); - assert (ce != NULL); - - ret = fcache_find (&parentEntry, *parent_fid); - assert (ret == 0); - -#if 0 - is_change = reconnect_mut_chk(parentEntry, - ce, - parentEntry->status.DataVersion); -#endif - -/*SWW Qiyue 30 delete the old file entry in dir */ - arla_warnx (ADEBDISCONN, - "reconnect_rename: we delete the old one volumn=0x%x, " - "vnode=0x%x,unique=0x%x", - parentEntry->fid.fid.Volume, - parentEntry->fid.fid.Vnode, - parentEntry->fid.fid.Unique); - - adir_remove(parentEntry,name); - - conn = find_first_fs (parentEntry, ce, &context); - if (conn == NULL) { - arla_log (ADEBDISCONN, "find_first_fs failed"); - ReleaseWriteLock(&parentEntry->lock); - ReleaseWriteLock(&childEntry->lock); - free_fs_server_context(&context); - cred_free(ce); - return ENETDOWN; - } - - ret = fcache_find (&childEntry, *child_fid); - assert (ret == 0); - - recon_hashtabdel(childEntry); - -#if 0 - fetch_attr = &childEntry->status; -#endif - - store_attr.Mask = 8; - store_attr.ClientModTime = childEntry->status.ClientModTime; - store_attr.Owner = childEntry->status.Owner; - store_attr.Group = childEntry->status.Group; - store_attr.UnixModeBits = childEntry->status.UnixModeBits; - store_attr.SegSize = childEntry->status.SegSize; - - arla_log(ADEBDISCONN, - "reconnect: create before RXAFS_CreateFile, " - "Cell=0x%x, fid.Volume= 0x%x, fid.Vnode=0x%x, fid.Unique=0x%x", - childEntry->fid.Cell, - childEntry->fid.fid.Volume, - childEntry->fid.fid.Vnode, - childEntry->fid.fid.Unique); - - alloc_fid_trans(&childEntry->fid); - - - ret = RXAFS_CreateFile (conn->connection, - &(parentEntry->fid.fid), - name, &store_attr, - &(childEntry->fid.fid), &fetch_attr, - &status, - &callback, - &volsync); - - if (ret) { - if (ret == 17) { - ReleaseWriteLock(&parentEntry->lock); - reconnect_mut_newfile(&childEntry, - parent->cred.pag, - &childEntry->fid); - ObtainWriteLock(&parentEntry->lock); - fill_fid_trans(&childEntry->fid); - recon_hashtabadd(childEntry); - childEntry->host = rx_HostOf (rx_PeerOf (conn->connection)); - reconnect_update_fid (childEntry, fakeFid); - } else { - arla_log (ADEBDISCONN, "Could not CreateFile: %s (%d)", - koerr_gettext(ret), ret); - } - goto out; - } - - parentEntry->status = status; - parentEntry->callback = callback; - parentEntry->volsync = volsync; - - childEntry->fid.Cell = parentEntry->fid.Cell; - - arla_log(ADEBDISCONN, "reconnect: create after RXAFS_CreateFile, " - "Cell=0x%x, fid.Volume= 0x%x, fid .Vnode=0x%x, fid.Unique=0x%x", - childEntry->fid.Cell, - childEntry->fid.fid.Volume, - childEntry->fid.fid.Vnode, - childEntry->fid.fid.Unique); - - fill_fid_trans(&childEntry->fid); - -#if 0 - ReleaseWriteLock(&childEntry->lock); -#endif - - - ret = volcache_getbyid (childEntry->fid.fid.Volume, - childEntry->fid.Cell, - ce, - &childEntry->volume, - &type); - - recon_hashtabadd(childEntry); - - arla_log(ADEBDISCONN, - "reconnect: create after volcache_getbyid, Cell=0x%x, " - "fid.Volume= 0x%x, fid .Vnode=0x%x, fid.Unique=0x%x", - childEntry->fid.Cell, - childEntry->fid.fid.Volume, - childEntry->fid.fid.Vnode, - childEntry->fid.fid.Unique); - -/* SWW Qiyue 30: add the new file entry in dir */ - arla_warnx (ADEBDISCONN,"reconnect_rename: we add the new one " - "volumn=0x%x,vnode=0x%x,unique=0x%x", - parentEntry->fid.fid.Volume, - parentEntry->fid.fid.Vnode, - parentEntry->fid.fid.Unique); - - adir_creat (parentEntry, name, childEntry->fid.fid); - - childEntry->status = fetch_attr; - - childEntry->flags.attrp = TRUE; - childEntry->flags.kernelp = TRUE; - - childEntry->flags.datap = TRUE; - childEntry->tokens |= XFS_ATTR_R | XFS_DATA_R | XFS_DATA_W; - - if (parentEntry->volume == NULL) - ret = volcache_getbyid (parentEntry->fid.fid.Volume, - parentEntry->fid.Cell, - ce, - &parentEntry->volume, - &type); - - volcache_update_volsync (parentEntry->volume, parentEntry->volsync); - - - -/*SWW Qiyue 28: Set the host for child entry */ - - childEntry->host = rx_HostOf (rx_PeerOf (conn->connection)); - assert(childEntry->host); - -/*SWW Qiyue 29: */ - arla_warnx (ADEBDISCONN, - "Replace fid.Volume=0x%x,Vnode=0x%x,Unique=0x%x with " - "Volume=0x%x,Vnode=0x%x,Unqiue=0x%x", - fakeFid.fid.Volume, - fakeFid.fid.Vnode, - fakeFid.fid.Unique, - childEntry->fid.fid.Volume, - childEntry->fid.fid.Vnode, - childEntry->fid.fid.Unique); - - reconnect_update_fid (childEntry, fakeFid); - - conv_dir(parentEntry, ce, 0, &cache_handle, tmp, sizeof(tmp)); - - ReleaseWriteLock(&childEntry->lock); - - out: - - ReleaseWriteLock(&parentEntry->lock); - ReleaseWriteLock(&childEntry->lock); - free_fs_server_context(&context); - cred_free(ce); - return ret; -} - -/* - * - */ - -int reconnect_mkdir(struct vcache *parent, struct vcache *curdir, - AFSStoreStatus *store_status, char *name) -{ - ConnCacheEntry *conn; - fs_server_context context; - CredCacheEntry *ce; - VenusFid *parent_fid; - VenusFid *child_fid; - VenusFid fakeFid; - - FCacheEntry *parentEntry, *childEntry, *tempEntry, *tempparEntry; - Result tempres; - int ret = 0; - int tempret = 0; - struct timeval tv; - char tmp[2 * sizeof(int) + 2]; - - AFSFid Outfid; /* Ba Wu: These are used to get the info from FS*/ - AFSFetchStatus fetch_attr; - AFSFetchStatus status; - AFSCallBack callback; - AFSVolSync volsync; - fcache_cache_handle cache_handle; - int32_t type; - - parent_fid = &(parent->fid); /* points to the VenusFid structure */ - child_fid = &(curdir->fid); - fakeFid = *child_fid; - - parent_fid = fid_translate(parent_fid); - - ce = cred_get (parent->fid.Cell, parent->cred.pag, CRED_ANY); - assert (ce != NULL); - - ret = fcache_find (&parentEntry, *parent_fid); - assert (ret == 0); - - tempparEntry = parentEntry; - -/*Ba ba: used to check whether name can be find Deleted !!! - ReleaseWriteLock(&parentEntry->lock); - tempret = adir_lookup (parentEntry->fid , name , &foo_fid , NULL, ce); */ -/*Ba ba: used to check whether name can be find Deleted !!! */ - - /*Ba Wu Remove the dir name from itsparent dir */ - tempret = adir_remove(parentEntry,name); - conn = find_first_fs (parentEntry, ce, &context); - if (conn == NULL) { - arla_log (ADEBDISCONN,"Cannot make this connection"); - ReleaseWriteLock(&parentEntry->lock); - ReleaseWriteLock(&childEntry->lock); - cred_free(ce); - return ENETDOWN; - } - - ret = fcache_find(&childEntry, *child_fid);/*Ba Wu: remove the newly created dir */ - assert (ret == 0); - - recon_hashtabdel(childEntry); - - alloc_fid_trans(&childEntry->fid); - - gettimeofday(&tv, NULL); - - ret = RXAFS_MakeDir (conn->connection, - &parentEntry->fid.fid, - name, - store_status, - &Outfid, - &fetch_attr, - &status, - &callback, - &volsync); - - if (ret) { - arla_log (ADEBDISCONN, "Could not CreateFile: %s (%d)", - koerr_gettext(ret), ret); - goto out; - } - - parentEntry->status = status; - parentEntry->callback = callback; - parentEntry->callback.ExpirationTime += tv.tv_sec; - parentEntry->volsync = volsync; - - childEntry->fid.Cell = parentEntry->fid.Cell; - childEntry->fid.fid = Outfid; - childEntry->status = fetch_attr; - childEntry->flags.attrp = TRUE; - childEntry->flags.kernelp = TRUE; - childEntry->flags.datap = TRUE; - childEntry->tokens |= XFS_ATTR_R | XFS_DATA_R | XFS_DATA_W; - - fill_fid_trans(&childEntry->fid); - - ret = volcache_getbyid (childEntry->fid.fid.Volume, - childEntry->fid.Cell, - ce, - &childEntry->volume, - &type); - - recon_hashtabadd(childEntry); - -/*Ba ba: Need to change later!!! */ -#if 0 - ReleaseWriteLock(&tempparEntry->lock); - tempret = adir_changefid (tempparEntry->fid ,name, &Outfid, ce); - ReleaseWriteLock(&tempparEntry->lock); - tempret = adir_lookup (tempparEntry->fid ,name, &foo_fid, NULL, ce); -#endif - - tempret = adir_creat (parentEntry, name, childEntry->fid.fid); - - childEntry->host = rx_HostOf (rx_PeerOf (conn->connection)); - assert(childEntry->host); - - reconnect_update_fid(childEntry, fakeFid); - - tempres = conv_dir(parentEntry, ce, 0, &cache_handle, - tmp, sizeof(tmp)); - - ReleaseWriteLock(&childEntry->lock); - - /*SWW Qiyue 29: This should be deleted later */ - ret = fcache_find (&tempEntry, childEntry->fid); - - assert (ret == 0); - ReleaseWriteLock(&tempEntry->lock); - - out: - - ReleaseWriteLock(&parentEntry->lock); - ReleaseWriteLock(&childEntry->lock); - free_fs_server_context(&context); - cred_free(ce); - return ret; -} - -/* - * - */ - -int reconnect_link(struct vcache *parent, struct vcache *existing, - char *name) -{ - ConnCacheEntry *conn; - fs_server_context context; - CredCacheEntry *ce; - VenusFid *parent_fid; - VenusFid *existing_fid; - char tmp[2 * sizeof(int) + 2]; - int ret = 0; - FCacheEntry *dir_entry,*existing_entry; - Result res; - - AFSFetchStatus new_status; - AFSFetchStatus status; - AFSVolSync volsync; - fcache_cache_handle cache_handle; - - - parent_fid = &(parent->fid); - existing_fid = &(existing->fid); - - parent_fid = fid_translate(parent_fid); - - ce = cred_get (parent->fid.Cell, parent->cred.pag, CRED_ANY); - assert (ce != NULL); - - ret = fcache_find (&dir_entry, *parent_fid); - assert (ret == 0); - - ret = fcache_find (&existing_entry, *existing_fid); - assert (ret == 0); - - conn = find_first_fs (dir_entry, ce, &context); - if (conn == NULL) { - arla_log (ADEBDISCONN,"Cannot make this connection"); - ReleaseWriteLock(&dir_entry->lock); - ReleaseWriteLock(&existing_entry->lock); - cred_free(ce); - return ENETDOWN; - } - - ret = RXAFS_Link (conn->connection, - &dir_entry->fid.fid, - name, - &existing_entry->fid.fid, - &new_status, - &status, - &volsync); - if (ret) { - arla_warn (ADEBFCACHE, ret, "Link"); - goto out; - } - - dir_entry->status = status; - dir_entry->volsync = volsync; - - existing_entry->status = new_status; - - volcache_update_volsync (dir_entry->volume, dir_entry->volsync); - - res = conv_dir (dir_entry, ce, 0, &cache_handle, tmp, sizeof(tmp)); - - out: - ReleaseWriteLock(&dir_entry->lock); - ReleaseWriteLock(&existing_entry->lock); - cred_free(ce); - free_fs_server_context (&context); - return ret; -} - -/* - * - */ - -int reconnect_symlink(struct vcache *parent, struct vcache *child, - AFSStoreStatus *store_attr, char *name, - char *contents) -{ - ConnCacheEntry *conn; - fs_server_context context; - CredCacheEntry *ce; - VenusFid *parent_fid, *child_fid, fakeFid; - char tmp[2 * sizeof(int) + 2]; - int ret = 0; - FCacheEntry *dir_entry, *childEntry; - Result res; - - AFSFetchStatus fetch_attr, new_status; - AFSVolSync volsync; - fcache_cache_handle cache_handle; - int32_t type; - - parent_fid = &(parent->fid); - child_fid = &(child->fid); - fakeFid = *child_fid; - parent_fid = fid_translate(parent_fid); - - ce = cred_get (parent->fid.Cell, parent->cred.pag, CRED_ANY); - assert (ce != NULL); - - ret = fcache_find (&dir_entry, *parent_fid); - assert (ret == 0); - - adir_remove(dir_entry,name); - - ret = fcache_find (&childEntry, *child_fid); - assert (ret == 0); - - recon_hashtabdel(childEntry); - - assert(ret==0); - conn = find_first_fs (dir_entry, ce, &context); - if (conn == NULL) { - arla_log (ADEBDISCONN,"Cannot make this connection"); - ReleaseWriteLock(&dir_entry->lock); - ReleaseWriteLock(&childEntry->lock); - cred_free(ce); - return ENOMEM; - } - - alloc_fid_trans(&childEntry->fid); - - ret = RXAFS_Symlink (conn->connection, - &dir_entry->fid.fid, - name, - contents, - store_attr, - &(childEntry->fid.fid), - &fetch_attr, - &new_status, - &volsync); - if (ret) { - arla_warn (ADEBFCACHE, ret, "Symlink"); - goto out; - } - - child_fid->Cell = dir_entry->fid.Cell; - - fill_fid_trans (&childEntry->fid); - ret = volcache_getbyid (childEntry->fid.fid.Volume, - childEntry->fid.Cell, - ce, - &childEntry->volume, - &type); - - recon_hashtabadd (childEntry); - - adir_creat(dir_entry, name, childEntry->fid.fid); - - childEntry->status = fetch_attr; - childEntry->flags.attrp = TRUE; - childEntry->flags.kernelp = TRUE; - childEntry->tokens |= XFS_ATTR_R; - volcache_update_volsync (dir_entry->volume, dir_entry->volsync); - - childEntry->host = rx_HostOf (rx_PeerOf (conn->connection)); - assert(childEntry->host); - - reconnect_update_fid(childEntry, fakeFid); - res = conv_dir (dir_entry, ce, 0, &cache_handle, tmp, sizeof(tmp)); - - out: - ReleaseWriteLock(&dir_entry->lock); - ReleaseWriteLock(&childEntry->lock); - free_fs_server_context(&context); - cred_free(ce); - return ret; -} - -#endif +OBSOLETE /* COPYRIGHT (C) 1998 +OBSOLETE * THE REGENTS OF THE UNIVERSITY OF MICHIGAN +OBSOLETE * ALL RIGHTS RESERVED +OBSOLETE * +OBSOLETE * PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS +OBSOLETE * AND REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS +OBSOLETE * FOR ANY PURPOSE, SO LONG AS THE NAME OF THE UNIVERSITY OF +OBSOLETE * MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY +OBSOLETE * PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE +OBSOLETE * WITHOUT SPECIFIC, WRITTEN PRIOR AUTHORIZATION. IF THE +OBSOLETE * ABOVE COPYRIGHT NOTICE OR ANY OTHER IDENTIFICATION OF THE +OBSOLETE * UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY +OBSOLETE * PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST +OBSOLETE * ALSO BE INCLUDED. +OBSOLETE * +OBSOLETE * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION +OBSOLETE * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY +OBSOLETE * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF +OBSOLETE * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING +OBSOLETE * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF +OBSOLETE * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE +OBSOLETE * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE +OBSOLETE * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR +OBSOLETE * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING +OBSOLETE * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN +OBSOLETE * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF +OBSOLETE * SUCH DAMAGES. +OBSOLETE */ +OBSOLETE +OBSOLETE /* +OBSOLETE * Do merging of the files that changed with we was in disconnected mode +OBSOLETE */ +OBSOLETE +OBSOLETE #if 0 +OBSOLETE +OBSOLETE #include "arla_local.h" +OBSOLETE +OBSOLETE RCSID("$arla: reconnect.c,v 1.37 2002/09/07 10:43:27 lha Exp $"); +OBSOLETE +OBSOLETE static int reconnect_nonmute(struct vcache *, int, struct timeval); +OBSOLETE static int reconnect_putattr(struct vcache *, struct nnpfs_attr *); +OBSOLETE static int reconnect_putdata(struct vcache *); +OBSOLETE static int reconnect_remove(struct vcache *, FCacheEntry *childentry, char *); +OBSOLETE static int reconnect_rename(struct vcache *, struct vcache *, char *, char *); +OBSOLETE static int reconnect_rmdir(struct vcache *vcp, FCacheEntry *childEntry, +OBSOLETE char *name); +OBSOLETE static int reconnect_mkdir(struct vcache *parent, struct vcache *curdir, +OBSOLETE AFSStoreStatus *store_status, char *name); +OBSOLETE static int reconnect_link(struct vcache *parent, struct vcache *existing, +OBSOLETE char *name); +OBSOLETE static int reconnect_symlink(struct vcache *parent, struct vcache *child, +OBSOLETE AFSStoreStatus *store_attr, char *name, +OBSOLETE char *contents); +OBSOLETE static int reconnect_create(struct vcache *parent, struct vcache *child, +OBSOLETE char *name); +OBSOLETE static int reconnect_mut_chk(FCacheEntry *fce, CredCacheEntry *ce, +OBSOLETE int version); +OBSOLETE +OBSOLETE static int check_log_todo(log_ent_t * , VenusFid *, VenusFid *); +OBSOLETE static int is_done_before(int no); +OBSOLETE static void add_done_list(int no); +OBSOLETE static void clear_log_entry(void); +OBSOLETE static void clear_index_list(void); +OBSOLETE +OBSOLETE typedef struct _fid_trans{ +OBSOLETE VenusFid logged_fid; +OBSOLETE VenusFid fetched_fid; +OBSOLETE struct _fid_trans *next, *prev; +OBSOLETE } fid_trans; +OBSOLETE +OBSOLETE typedef struct _fid_keep{ +OBSOLETE char name[MAX_NAME]; +OBSOLETE AFSFid kept_fid; +OBSOLETE struct _fid_keep *next; +OBSOLETE } fid_keep; +OBSOLETE +OBSOLETE typedef struct _index_list{ +OBSOLETE int index; +OBSOLETE struct _index_list * next; +OBSOLETE } index_list; +OBSOLETE +OBSOLETE fid_trans *fid_AD_head, *fid_AD_tail; +OBSOLETE fid_keep *fid_KP_head; +OBSOLETE index_list * index_head; +OBSOLETE extern log_ent_t log_head; +OBSOLETE +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE static void +OBSOLETE set_fid_value(VenusFid *new, VenusFid *old) +OBSOLETE { +OBSOLETE if(old==0) { +OBSOLETE new->fid.Volume = 0; +OBSOLETE new->fid.Vnode = 0; +OBSOLETE new->fid.Unique = 0; +OBSOLETE } else { +OBSOLETE new->fid.Volume = old->fid.Volume; +OBSOLETE new->fid.Vnode = old->fid.Vnode; +OBSOLETE new->fid.Unique = old->fid.Unique; +OBSOLETE } +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE void +OBSOLETE do_replay(char *log_file, int log_entries, VenusFid *changed_fid) +OBSOLETE { +OBSOLETE int fd, len, i; +OBSOLETE log_ent_t *cur_log; +OBSOLETE struct vcache vc, vc_new; +OBSOLETE char *name, *name_new; +OBSOLETE fid_trans *fid_tmp; +OBSOLETE fid_keep * fid_KP_tail; +OBSOLETE VenusFid new_fid; +OBSOLETE +OBSOLETE int count=1; /* Used to record how may actions we have done*/ +OBSOLETE +OBSOLETE fid_AD_tail = fid_AD_head; +OBSOLETE cur_log = (log_ent_t *) malloc(sizeof(log_ent_t)); +OBSOLETE fd = open(log_file, O_RDWR | O_BINARY); +OBSOLETE +OBSOLETE set_fid_value(&new_fid , 0); +OBSOLETE +OBSOLETE while (read(fd, cur_log, sizeof(int))){ +OBSOLETE +OBSOLETE if (cur_log->log_len < sizeof(*cur_log) - sizeof(cur_log->log_data) || +OBSOLETE cur_log->log_len > sizeof(log_ent_t)) { +OBSOLETE arla_log(ADEBDISCONN, "do_replay: corrupt log entry, log_len %d", +OBSOLETE cur_log->log_len); +OBSOLETE goto terminate; +OBSOLETE } +OBSOLETE +OBSOLETE len = cur_log->log_len - sizeof(int); +OBSOLETE +OBSOLETE if (!read(fd, ((char *)cur_log + sizeof(int)), len)){ +OBSOLETE arla_log(ADEBDISCONN, "do_replay: read bad log entry..."); +OBSOLETE goto terminate; +OBSOLETE } +OBSOLETE +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "do_replay: read %d bytes of log entry.", +OBSOLETE cur_log->log_len); +OBSOLETE +OBSOLETE if (is_done_before(cur_log->log_index)==1) +OBSOLETE continue; /* the log entry has been executed */ +OBSOLETE else { +OBSOLETE if (changed_fid !=0) { +OBSOLETE int is_log_todo = 0; +OBSOLETE +OBSOLETE is_log_todo = check_log_todo(cur_log, changed_fid, &new_fid); +OBSOLETE if (is_log_todo ==0) +OBSOLETE continue; /* This log should not be executed */ +OBSOLETE } +OBSOLETE } +OBSOLETE +OBSOLETE add_done_list(cur_log->log_index); +OBSOLETE +OBSOLETE /* big case/switch statement to switch log_op */ +OBSOLETE switch (cur_log->log_op){ +OBSOLETE +OBSOLETE case DIS_STORE: +OBSOLETE vc.fid = cur_log->st_fid; +OBSOLETE vc.DataVersion = cur_log->st_origdv-1; +OBSOLETE vc.flag = cur_log->st_flag; +OBSOLETE vc.cred = cur_log->cred; +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "%d action is to do_replay: **replay** (putdata) op...", +OBSOLETE count++); +OBSOLETE reconnect_putdata(&vc); +OBSOLETE break; +OBSOLETE case DIS_SETATTR: +OBSOLETE vc.fid = cur_log->sa_fid; +OBSOLETE vc.DataVersion = cur_log->sa_origdv; +OBSOLETE vc.flag = 0; +OBSOLETE vc.cred = cur_log->cred; +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "%d action is to do_replay: **replay** (putattr) op...", +OBSOLETE count++); +OBSOLETE reconnect_putattr(&vc, &(cur_log->sa_vattr)); +OBSOLETE break; +OBSOLETE case DIS_REMOVE: { +OBSOLETE FCacheEntry *childentry; +OBSOLETE vc.fid = cur_log->rm_filefid; +OBSOLETE vc.DataVersion = cur_log->rm_origdv; +OBSOLETE vc.flag = 0; +OBSOLETE vc.cred = cur_log->cred; +OBSOLETE childentry = cur_log->rm_chentry; +OBSOLETE name = cur_log->rm_name; +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "%d action is to do_replay: **replay** " +OBSOLETE "(file remove) op...", +OBSOLETE count++); +OBSOLETE reconnect_remove(&vc, childentry, name); +OBSOLETE break; +OBSOLETE } +OBSOLETE case DIS_RMDIR: { +OBSOLETE FCacheEntry *child; +OBSOLETE vc.fid = cur_log->rd_parentfid; +OBSOLETE name = cur_log->rd_name; +OBSOLETE vc.cred = cur_log->cred; +OBSOLETE child = cur_log->rd_direntry; +OBSOLETE arla_log (ADEBDISCONN, +OBSOLETE "%d action is to do_replay: **rmdir** " +OBSOLETE "(directory remove) op...", +OBSOLETE count++); +OBSOLETE reconnect_rmdir(&vc, child, name); +OBSOLETE break; +OBSOLETE } +OBSOLETE case DIS_RENAME: +OBSOLETE vc.fid = cur_log->rn_oparentfid; +OBSOLETE vc.DataVersion = cur_log->rn_origdv; +OBSOLETE vc.flag = 0; +OBSOLETE vc.cred = cur_log->cred; +OBSOLETE vc_new.fid = cur_log->rn_nparentfid; +OBSOLETE vc_new.DataVersion = cur_log->rn_overdv; +OBSOLETE vc_new.flag = 0; +OBSOLETE vc_new.cred = cur_log->cred; +OBSOLETE name = cur_log->rn_names; +OBSOLETE for (i=0; *(name+i)!='\0';++i); +OBSOLETE name_new = name+i+1; +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "%d action is to do_replay: **replay** (rename) op...", +OBSOLETE count++); +OBSOLETE reconnect_rename(&vc, &vc_new, name, name_new); +OBSOLETE break; +OBSOLETE case DIS_MKDIR: { +OBSOLETE AFSStoreStatus store_status; +OBSOLETE vc.fid = cur_log->md_parentfid; +OBSOLETE vc.cred = cur_log->cred; +OBSOLETE store_status = cur_log->md_vattr; +OBSOLETE vc_new.fid = cur_log->md_dirfid; +OBSOLETE /*Ba Wu: child's data vers*/ +OBSOLETE vc_new.DataVersion = cur_log->md_dversion; +OBSOLETE name = cur_log->md_name; +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "%d action is to DO_Replay: **replay** (mkdir) op...", +OBSOLETE count++); +OBSOLETE reconnect_mkdir(&vc, &vc_new, &store_status, name); +OBSOLETE break; +OBSOLETE } +OBSOLETE case DIS_LINK: +OBSOLETE vc.cred = cur_log->cred; +OBSOLETE vc.fid = cur_log->ln_parentfid; +OBSOLETE vc_new.fid = cur_log->ln_linkfid; +OBSOLETE name = cur_log->ln_name; +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "%d action is to do_replay: **replay** (link) op...", +OBSOLETE count++); +OBSOLETE reconnect_link(&vc, &vc_new, name); +OBSOLETE break; +OBSOLETE case DIS_SYMLINK: { +OBSOLETE char *new_name; +OBSOLETE AFSStoreStatus store_attr; +OBSOLETE +OBSOLETE vc.fid = cur_log->sy_parentfid; +OBSOLETE vc.cred = cur_log->cred; +OBSOLETE name = cur_log->sy_name; +OBSOLETE new_name = cur_log->sy_content; +OBSOLETE vc_new.fid = cur_log->sy_filefid; +OBSOLETE store_attr = cur_log->sy_attr; +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "%d action is to do_replay: **replay** (symlink) op...", +OBSOLETE count++); +OBSOLETE reconnect_symlink(&vc, &vc_new, &store_attr, name, new_name); +OBSOLETE break; +OBSOLETE } +OBSOLETE case DIS_CREATE: +OBSOLETE vc.fid = cur_log->cr_parentfid; +OBSOLETE vc.cred = cur_log->cred; +OBSOLETE +OBSOLETE vc_new.fid = cur_log->cr_filefid; +OBSOLETE vc_new.DataVersion = cur_log->cr_origdv; +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "%d action is to DO_Replay: **replay** (create) op...", +OBSOLETE count++); +OBSOLETE name = cur_log->cr_name; +OBSOLETE reconnect_create(&vc, &vc_new, name); +OBSOLETE break; +OBSOLETE case DIS_ACCESS: +OBSOLETE vc.fid = cur_log->nm_fid; +OBSOLETE vc.DataVersion = cur_log->nm_origdv; +OBSOLETE vc.cred = cur_log->cred; +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "%d action is to do_replay: **replay** (nonmutating) op", +OBSOLETE count++); +OBSOLETE reconnect_nonmute(&vc, cur_log->log_op, cur_log->log_time); +OBSOLETE break; +OBSOLETE +OBSOLETE default: +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "%d action is to do_replay: skipping the current op=%d", +OBSOLETE count++,cur_log->log_op); +OBSOLETE } +OBSOLETE } +OBSOLETE +OBSOLETE if (changed_fid ==0) { +OBSOLETE clear_index_list(); /* clean all index when after discon */ +OBSOLETE clear_log_entry(); +OBSOLETE /* clean up, remove all associative data structures */ +OBSOLETE fid_AD_tail = fid_AD_head; +OBSOLETE while(fid_AD_tail) +OBSOLETE { +OBSOLETE fid_tmp = fid_AD_tail->next; +OBSOLETE free(fid_AD_tail); +OBSOLETE fid_AD_tail = fid_tmp; +OBSOLETE } +OBSOLETE /* SWW Qiyue 28: We need to reset head to 0*/ +OBSOLETE fid_AD_head = 0; +OBSOLETE fid_KP_tail = fid_KP_head; +OBSOLETE while(fid_KP_tail) +OBSOLETE { +OBSOLETE fid_keep *fid_tmp; +OBSOLETE +OBSOLETE fid_tmp = fid_KP_tail->next; +OBSOLETE free(fid_KP_tail); +OBSOLETE fid_KP_tail = fid_tmp; +OBSOLETE } +OBSOLETE +OBSOLETE fid_KP_head = 0; +OBSOLETE } +OBSOLETE i = ftruncate (fd, 0); +OBSOLETE assert (i == 0); +OBSOLETE +OBSOLETE terminate: +OBSOLETE +OBSOLETE arla_warnx (ADEBDISCONN,"We have done total %d replays",count-1); +OBSOLETE close(fd); +OBSOLETE free(cur_log); +OBSOLETE return; +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE static int +OBSOLETE check_rm_fid (VenusFid v1, VenusFid v2) +OBSOLETE { +OBSOLETE if(v1.fid.Vnode == v2.fid.Vnode && +OBSOLETE v1.fid.Volume == v2.fid.Volume && +OBSOLETE v1.fid.Unique == v2.fid.Unique ) +OBSOLETE return 1; +OBSOLETE else +OBSOLETE return 0; +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE static int +OBSOLETE check_log_fid(struct vcache vc, VenusFid *fid) +OBSOLETE { +OBSOLETE log_ent_t *temp = log_head.next; +OBSOLETE +OBSOLETE if (vc.fid.fid.Vnode == fid->fid.Vnode && +OBSOLETE vc.fid.fid.Volume == fid->fid.Volume && +OBSOLETE vc.fid.fid.Unique == fid->fid.Unique) +OBSOLETE return 1; +OBSOLETE +OBSOLETE while (temp!=0) { +OBSOLETE switch(temp->log_op) { +OBSOLETE case DIS_RENAME: +OBSOLETE if (check_rm_fid(temp->rn_oparentfid,*fid)==1) +OBSOLETE return 1; +OBSOLETE default: +OBSOLETE temp = temp->next; +OBSOLETE break; +OBSOLETE } +OBSOLETE } +OBSOLETE return 0; +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE static int +OBSOLETE check_log_todo(log_ent_t * cur_log , VenusFid *fid, VenusFid *newfid) +OBSOLETE { +OBSOLETE VenusFid *lookfid; +OBSOLETE struct vcache vc, vc_new; +OBSOLETE int will_do = 0; +OBSOLETE +OBSOLETE if (newfid->fid.Vnode ==0 && +OBSOLETE newfid->fid.Volume == 0 && +OBSOLETE newfid->fid.Unique ==0) +OBSOLETE lookfid = fid; +OBSOLETE else +OBSOLETE lookfid = newfid; /* For create and putdata */ +OBSOLETE +OBSOLETE switch (cur_log->log_op){ +OBSOLETE case DIS_STORE: +OBSOLETE vc.fid = cur_log->st_fid; +OBSOLETE will_do = check_log_fid(vc, lookfid); +OBSOLETE if (will_do==1) { +OBSOLETE set_fid_value(newfid, 0); +OBSOLETE return 1; +OBSOLETE } +OBSOLETE break; +OBSOLETE case DIS_SETATTR: +OBSOLETE vc.fid = cur_log->sa_fid; +OBSOLETE will_do = check_log_fid(vc, lookfid); +OBSOLETE if (will_do==1) { +OBSOLETE set_fid_value(newfid , &cur_log->sa_fid); +OBSOLETE return 1; +OBSOLETE } +OBSOLETE break; +OBSOLETE case DIS_REMOVE: +OBSOLETE vc.fid = cur_log->rm_filefid; +OBSOLETE will_do = check_log_fid(vc, lookfid); +OBSOLETE if (will_do==1) { +OBSOLETE return 1; +OBSOLETE } +OBSOLETE break; +OBSOLETE case DIS_RMDIR: +OBSOLETE vc.fid = cur_log->rd_parentfid; +OBSOLETE will_do = check_log_fid(vc, lookfid); +OBSOLETE if (will_do==1) { +OBSOLETE return 1; +OBSOLETE } +OBSOLETE break; +OBSOLETE case DIS_RENAME: +OBSOLETE vc.fid = cur_log->rn_oparentfid; +OBSOLETE will_do = check_log_fid(vc, lookfid); +OBSOLETE if (will_do==1) { +OBSOLETE return 1; +OBSOLETE } +OBSOLETE vc_new.fid = cur_log->rn_nparentfid; +OBSOLETE will_do = check_log_fid(vc_new, lookfid); +OBSOLETE if (will_do==1) { +OBSOLETE return 1; +OBSOLETE } +OBSOLETE break; +OBSOLETE case DIS_MKDIR: +OBSOLETE vc.fid = cur_log->md_parentfid; +OBSOLETE will_do = check_log_fid(vc, lookfid); +OBSOLETE if (will_do==1) { +OBSOLETE return 1; +OBSOLETE } +OBSOLETE break; +OBSOLETE case DIS_LINK: +OBSOLETE break; +OBSOLETE case DIS_SYMLINK: +OBSOLETE will_do = check_log_fid(vc, lookfid); +OBSOLETE if (will_do==1) { +OBSOLETE return 1; +OBSOLETE } +OBSOLETE break; +OBSOLETE case DIS_CREATE: +OBSOLETE vc.fid = cur_log->cr_parentfid; +OBSOLETE will_do = check_log_fid(vc, lookfid); +OBSOLETE if (will_do==1) { +OBSOLETE set_fid_value(newfid , &cur_log->cr_filefid); +OBSOLETE return 1; +OBSOLETE } +OBSOLETE break; +OBSOLETE case DIS_FSYNC: +OBSOLETE case DIS_ACCESS: +OBSOLETE case DIS_READDIR: +OBSOLETE case DIS_READLINK: +OBSOLETE case DIS_INFO: +OBSOLETE case DIS_START_OPT: +OBSOLETE case DIS_END_OPT: +OBSOLETE case DIS_REPLAYED: +OBSOLETE /* A no op */ +OBSOLETE break; +OBSOLETE } +OBSOLETE return 0; +OBSOLETE } +OBSOLETE +OBSOLETE +OBSOLETE #if 0 +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE void +OBSOLETE keepfid_newrename(char *name, +OBSOLETE AFSFid fid) +OBSOLETE { +OBSOLETE if (fid_KP_head == 0) { +OBSOLETE fid_KP_head = (fid_keep *)malloc(sizeof(fid_keep)); +OBSOLETE assert(fid_KP_head); +OBSOLETE +OBSOLETE strcpy(fid_KP_head->name, name); +OBSOLETE fid_KP_head->kept_fid = fid; +OBSOLETE fid_KP_head->next = 0; +OBSOLETE } +OBSOLETE else { +OBSOLETE fid_keep *temp; +OBSOLETE +OBSOLETE temp = (fid_keep *)malloc(sizeof(fid_keep)); +OBSOLETE assert(temp); +OBSOLETE +OBSOLETE strcpy(temp->name, name); +OBSOLETE temp->name[strlen(name)] = '\0'; +OBSOLETE temp->kept_fid = fid; +OBSOLETE temp->next = fid_KP_head->next; +OBSOLETE fid_KP_head->next = temp; +OBSOLETE } +OBSOLETE } +OBSOLETE +OBSOLETE #endif +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE static int +OBSOLETE find_venus (char *name, VenusFid *fid) +OBSOLETE { +OBSOLETE fid_keep *fid_temp; +OBSOLETE +OBSOLETE if(fid_KP_head == 0 ) +OBSOLETE return 1; /*error */ +OBSOLETE +OBSOLETE fid_temp = fid_KP_head; +OBSOLETE +OBSOLETE while(fid_temp) { +OBSOLETE if (strcmp(fid_temp->name,name) == 0) { +OBSOLETE fid->fid.Volume = fid_temp->kept_fid.Volume; +OBSOLETE fid->fid.Vnode = fid_temp->kept_fid.Vnode; +OBSOLETE fid->fid.Unique = fid_temp->kept_fid.Unique; +OBSOLETE return 0; +OBSOLETE } +OBSOLETE fid_temp = fid_temp->next; +OBSOLETE } +OBSOLETE arla_warnx (ADEBDISCONN, "find_venus: *PANIC* not found fid for %s", name); +OBSOLETE return 1; +OBSOLETE } +OBSOLETE +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE VenusFid * +OBSOLETE fid_translate(VenusFid *fid_in) +OBSOLETE { +OBSOLETE fid_trans *fid_tmp; +OBSOLETE VenusFid *fid_ret; +OBSOLETE +OBSOLETE if (!fid_AD_head) +OBSOLETE return fid_in; +OBSOLETE +OBSOLETE fid_tmp = fid_AD_head; +OBSOLETE +OBSOLETE while(fid_tmp){ +OBSOLETE +OBSOLETE fid_ret=&fid_tmp->logged_fid; +OBSOLETE +OBSOLETE if ((fid_ret->Cell == fid_in->Cell) && +OBSOLETE (fid_ret->fid.Volume == fid_in->fid.Volume) && +OBSOLETE (fid_ret->fid.Vnode == fid_in->fid.Vnode) && +OBSOLETE (fid_ret->fid.Unique == fid_in->fid.Unique)) +OBSOLETE return &fid_tmp->fetched_fid; +OBSOLETE +OBSOLETE fid_tmp = fid_tmp->next; +OBSOLETE } +OBSOLETE return fid_in; +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE static void +OBSOLETE clear_index_list(void) +OBSOLETE { +OBSOLETE index_list *temp=index_head; +OBSOLETE +OBSOLETE while(temp!=0) { +OBSOLETE index_list *tmp; +OBSOLETE +OBSOLETE tmp = temp->next; +OBSOLETE free(temp); +OBSOLETE temp = tmp; +OBSOLETE } +OBSOLETE index_head = 0; +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE static void +OBSOLETE clear_log_entry(void) +OBSOLETE { +OBSOLETE log_ent_t *temp=log_head.next; +OBSOLETE +OBSOLETE while(temp!=0) { +OBSOLETE log_ent_t *tmp; +OBSOLETE +OBSOLETE tmp = temp->next; +OBSOLETE free(temp); +OBSOLETE temp = tmp; +OBSOLETE } +OBSOLETE log_head.next = 0; +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE static int +OBSOLETE is_done_before(int no) +OBSOLETE { +OBSOLETE index_list * temp = index_head; +OBSOLETE +OBSOLETE while(temp !=0) { +OBSOLETE if (temp->index == no) +OBSOLETE return 1; +OBSOLETE else +OBSOLETE temp = temp->next; +OBSOLETE } +OBSOLETE return 0; +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE static void +OBSOLETE add_done_list(int no) +OBSOLETE { +OBSOLETE if (!index_head) { +OBSOLETE index_head = (index_list *)malloc(sizeof(index_list)); +OBSOLETE assert(index_head); +OBSOLETE index_head->index = no; +OBSOLETE index_head->next = 0; +OBSOLETE } else { +OBSOLETE index_list * temp; +OBSOLETE temp = (index_list *) malloc(sizeof(index_list)); +OBSOLETE assert(temp); +OBSOLETE temp->next = index_head->next; +OBSOLETE index_head->next = temp; +OBSOLETE temp->index = no; +OBSOLETE } +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE static void +OBSOLETE alloc_fid_trans(VenusFid *logged_fid) +OBSOLETE { +OBSOLETE if (!fid_AD_head) +OBSOLETE { +OBSOLETE /*SWW Qiyue 28 Make sure we have the memory*/ +OBSOLETE fid_AD_head = (fid_trans *) malloc(sizeof(fid_trans)); +OBSOLETE assert(fid_AD_head); +OBSOLETE +OBSOLETE fid_AD_head->prev=fid_AD_head->next = 0; +OBSOLETE fid_AD_tail = fid_AD_head; +OBSOLETE fid_AD_tail->logged_fid = *logged_fid; +OBSOLETE +OBSOLETE } else{ +OBSOLETE +OBSOLETE /*SWW Qiyue 28 Make sure we have the memory*/ +OBSOLETE fid_AD_tail->next = (fid_trans *) malloc(sizeof(fid_trans)); +OBSOLETE assert(fid_AD_tail->next); +OBSOLETE +OBSOLETE fid_AD_tail->next->prev = fid_AD_tail; +OBSOLETE fid_AD_tail->next->next = 0; +OBSOLETE fid_AD_tail = fid_AD_tail->next; /*Ba ba: move tail ahead */ +OBSOLETE fid_AD_tail->logged_fid = *logged_fid; +OBSOLETE } +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE static void +OBSOLETE fill_fid_trans (VenusFid *fetched_fid) +OBSOLETE { +OBSOLETE fid_AD_tail->fetched_fid = *fetched_fid; +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE #if 0 +OBSOLETE void +OBSOLETE update_entry_flag (FCacheEntry *entry) +OBSOLETE { +OBSOLETE entry->flags.attrp = FALSE; +OBSOLETE entry->flags.datap = FALSE; +OBSOLETE } +OBSOLETE #endif +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE int reconnect_nonmute(struct vcache *vcp, int op, struct timeval log_time) +OBSOLETE { +OBSOLETE FCacheEntry *fce, fce_fetched; +OBSOLETE CredCacheEntry *ce; +OBSOLETE int error; +OBSOLETE VenusFid *fid; +OBSOLETE #if 0 +OBSOLETE ConnCacheEntry *conn; +OBSOLETE #endif +OBSOLETE +OBSOLETE arla_warnx (ADEBDISCONN, +OBSOLETE "Start of reconnect_nonmute by sww"); /*SWW Qiyue 25*/ +OBSOLETE +OBSOLETE fid = &(vcp->fid); +OBSOLETE if (fid->Cell == -1) /* newly created file, skip reconnect */ +OBSOLETE return 0; +OBSOLETE +OBSOLETE error = fcache_find(&fce, *fid); +OBSOLETE /* assert(fce); */ +OBSOLETE if (error) /* nonmute op on nonexisting data */ +OBSOLETE { +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "reconnect: nonmute op %d performed on cache " +OBSOLETE "entry no longer exist locally!", +OBSOLETE op); +OBSOLETE return -1; +OBSOLETE } +OBSOLETE +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "reconnect: DISCONNECTED nonmute " +OBSOLETE "on fid.Cell=0x%x, fid.fid.Volume= 0x%x, fid.fid.Vnode=0x%x, " +OBSOLETE "fid.fid.Unique=0x%x", fid->Cell, +OBSOLETE fid->fid.Volume, +OBSOLETE fid->fid.Vnode, +OBSOLETE fid->fid.Unique); +OBSOLETE +OBSOLETE ce = cred_get (fid->Cell, vcp->cred.pag, CRED_ANY); +OBSOLETE assert (ce != NULL); +OBSOLETE error = 0; +OBSOLETE +OBSOLETE /* setting some stuff so do_read_attr would work */ +OBSOLETE fce->flags.attrp = TRUE; +OBSOLETE fce->callback.CallBackType = 2; +OBSOLETE fce_fetched = *fce; +OBSOLETE /*conn = findconn (fce, ce);*/ +OBSOLETE +OBSOLETE error = read_attr(&fce_fetched, ce); +OBSOLETE +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "reconnect: logged DataVersion=%d, " +OBSOLETE "fetched DataVersion=%d", +OBSOLETE vcp->DataVersion, +OBSOLETE fce_fetched.status.DataVersion); +OBSOLETE +OBSOLETE if (vcp->DataVersion < fce_fetched.status.DataVersion) +OBSOLETE { +OBSOLETE if (log_time.tv_usec >= fce_fetched.status.ServerModTime) +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "Warning: nonmutating operation %d read stale data!", +OBSOLETE op); +OBSOLETE else if (log_time.tv_usec <= fce_fetched.status.ServerModTime && +OBSOLETE (vcp->DataVersion +1) == fce_fetched.status.DataVersion) +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "Notice: file modified once after nonmutating " +OBSOLETE "operation %d.", +OBSOLETE op); +OBSOLETE else +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "Warning: nonmutating operation %d might have read " +OBSOLETE "stale data!", op); +OBSOLETE } +OBSOLETE +OBSOLETE ReleaseWriteLock(&fce->lock); +OBSOLETE cred_free(ce); +OBSOLETE /*conn_free(conn);*/ +OBSOLETE +OBSOLETE return error; +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE int reconnect_remove(struct vcache *vcp, FCacheEntry *childentry, char *name) +OBSOLETE { +OBSOLETE FCacheEntry *fce; +OBSOLETE CredCacheEntry *ce; +OBSOLETE int error; +OBSOLETE VenusFid *fid, tempfid; /* Ba san: to check the deletion of file*/ +OBSOLETE Result res; +OBSOLETE int isupdate; +OBSOLETE +OBSOLETE ConnCacheEntry *conn; +OBSOLETE fs_server_context context; +OBSOLETE AFSFetchStatus status; +OBSOLETE AFSVolSync volsync; +OBSOLETE char tmp[2 * sizeof(int) + 2]; +OBSOLETE fcache_cache_handle cache_handle; +OBSOLETE +OBSOLETE fid = &(vcp->fid); /* points to the VenusFid structure */ +OBSOLETE fid = fid_translate(fid); +OBSOLETE +OBSOLETE arla_log(ADEBDISCONN, "reconnect: DISCONNECTED remove on " +OBSOLETE "fid.Cell=0x%x, fid.fid. Volume= 0x%x, fid.fid.Vnode=0x%x, " +OBSOLETE "fid.fid.Unique=0x%x", +OBSOLETE fid->Cell, fid->fid.Volume, fid->fid.Vnode, fid->fid.Unique); +OBSOLETE +OBSOLETE /* ObtainWriteLock called in fcache_find */ +OBSOLETE error = fcache_find(&fce, *fid); +OBSOLETE assert (error == 0); +OBSOLETE +OBSOLETE ce = cred_get (fid->Cell, vcp->cred.pag, CRED_ANY); +OBSOLETE assert (ce != NULL); +OBSOLETE +OBSOLETE if (connected_mode != CONNMODE_PARCONNECTED) { +OBSOLETE ObtainWriteLock(&childentry->lock); +OBSOLETE isupdate = reconnect_mut_chk(childentry, ce, +OBSOLETE childentry->status.DataVersion); +OBSOLETE ReleaseWriteLock(&childentry->lock); +OBSOLETE +OBSOLETE if (isupdate) +OBSOLETE { +OBSOLETE fcache_cache_handle cache_handle; +OBSOLETE +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "reconnect_remove: can't remove because file modified!"); +OBSOLETE cred_free(ce); +OBSOLETE adir_creat (fce, name, childentry->fid.fid); +OBSOLETE childentry->flags.attrp = FALSE; +OBSOLETE ReleaseWriteLock(&fce->lock); +OBSOLETE conv_dir (fce, ce, 0, &cache_handle, tmp, sizeof(tmp)); +OBSOLETE ReleaseWriteLock(&fce->lock); +OBSOLETE return -1; +OBSOLETE } +OBSOLETE } /* Ba ershi: we dont need to do it in parconn */ +OBSOLETE +OBSOLETE res.res = 0; +OBSOLETE +OBSOLETE AssertExclLocked(&fce->lock); +OBSOLETE +OBSOLETE conn = find_first_fs (fce, ce, &context); +OBSOLETE if (conn == NULL) { +OBSOLETE arla_log (ADEBDISCONN, "find_first_fs failed", fce->index); +OBSOLETE cred_free(ce); +OBSOLETE ReleaseWriteLock(&fce->lock); +OBSOLETE return ENETDOWN; +OBSOLETE } +OBSOLETE +OBSOLETE /* Ba san: check the file exists +OBSOLETE +OBSOLETE ReleaseWriteLock(&fce->lock); +OBSOLETE error = adir_lookup(fce->fid, name, &tempfid, NULL, &ce); +OBSOLETE assert (error == 0); +OBSOLETE ObtainWriteLock(&fce->lock); */ +OBSOLETE +OBSOLETE res.res = RXAFS_RemoveFile (conn->connection, +OBSOLETE &fce->fid.fid, +OBSOLETE name, +OBSOLETE &status, +OBSOLETE &volsync); +OBSOLETE if (res.res) { +OBSOLETE arla_log (ADEBDISCONN, "Could not RemoveFile: %s (%d)", +OBSOLETE koerr_gettext(res.res), res.res); +OBSOLETE goto out; +OBSOLETE } +OBSOLETE +OBSOLETE arla_warnx (ADEBDISCONN,"In reconnect_remove: Remove the file %s",name); +OBSOLETE +OBSOLETE /* Ba san: Chcek the deletion of the file */ +OBSOLETE ReleaseWriteLock(&fce->lock); +OBSOLETE error = adir_lookup(&fce->fid, name, &tempfid, NULL, &ce); +OBSOLETE ObtainWriteLock(&fce->lock); +OBSOLETE +OBSOLETE if (error == 0) { +OBSOLETE int result; +OBSOLETE +OBSOLETE arla_warnx (ADEBDISCONN, +OBSOLETE "In reconnect_remove: file %s needs to be deleted", +OBSOLETE name); +OBSOLETE result = adir_remove (fce,name); +OBSOLETE assert ( result == 0); +OBSOLETE } /* This is for the file produced during disconnect mode, +OBSOLETE if error==ENOENT then the file is created during connect mode*/ +OBSOLETE +OBSOLETE +OBSOLETE fce->status = status; +OBSOLETE fce->volsync = volsync; +OBSOLETE childentry->host = 0; /* Ba shiliu dont get callback */ +OBSOLETE +OBSOLETE volcache_update_volsync (fce->volume, fce->volsync); +OBSOLETE conv_dir (fce, ce, 0, &cache_handle, tmp, sizeof(tmp)); +OBSOLETE +OBSOLETE out: +OBSOLETE +OBSOLETE cred_free(ce); +OBSOLETE free_fs_server_context(&context); +OBSOLETE ReleaseWriteLock(&fce->lock); +OBSOLETE return error; +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE int +OBSOLETE reconnect_rmdir(struct vcache *vcp, FCacheEntry *childEntry, char *name) +OBSOLETE { +OBSOLETE FCacheEntry *fce; +OBSOLETE CredCacheEntry *ce; +OBSOLETE int error; +OBSOLETE VenusFid *fid, tempfid; /* Ba san: to check the deletion of file*/ +OBSOLETE Result res; +OBSOLETE char tmp[2 * sizeof(int) + 2]; +OBSOLETE int ret = 0; +OBSOLETE Result tempres; +OBSOLETE fcache_cache_handle cache_handle; +OBSOLETE +OBSOLETE ConnCacheEntry *conn; +OBSOLETE fs_server_context context; +OBSOLETE AFSFetchStatus status; +OBSOLETE AFSVolSync volsync; +OBSOLETE +OBSOLETE fid = &(vcp->fid); /* points to the VenusFid structure */ +OBSOLETE fid = fid_translate(fid); +OBSOLETE +OBSOLETE ret = fcache_find(&fce, *fid); +OBSOLETE assert (ret == 0); +OBSOLETE +OBSOLETE ce = cred_get (fid->Cell, vcp->cred.pag, CRED_ANY); +OBSOLETE assert (ce != NULL); +OBSOLETE +OBSOLETE AssertExclLocked(&fce->lock); +OBSOLETE +OBSOLETE conn = find_first_fs (fce, ce, &context); +OBSOLETE if (conn == NULL) { +OBSOLETE arla_log (ADEBDISCONN, "find_first_fs failed", fce->index); +OBSOLETE cred_free(ce); +OBSOLETE ReleaseWriteLock(&fce->lock); +OBSOLETE return ENETDOWN; +OBSOLETE } +OBSOLETE +OBSOLETE ret = RXAFS_RemoveDir (conn->connection, +OBSOLETE &fce->fid.fid, +OBSOLETE name, +OBSOLETE &status, +OBSOLETE &volsync); +OBSOLETE if (ret) { +OBSOLETE arla_log (ADEBDISCONN, +OBSOLETE "Could not RemoveDir : %s (%d)", +OBSOLETE koerr_gettext(res.res),res.res); +OBSOLETE goto out; +OBSOLETE } +OBSOLETE +OBSOLETE /* Ba san: Chcek the deletion of the file */ +OBSOLETE ReleaseWriteLock(&fce->lock); +OBSOLETE error = adir_lookup(&fce->fid, name, &tempfid, NULL, &ce); +OBSOLETE ObtainWriteLock(&fce->lock); +OBSOLETE +OBSOLETE if (error == 0) { +OBSOLETE int result; +OBSOLETE +OBSOLETE arla_warnx (ADEBDISCONN, +OBSOLETE "In reconnect_rmdir: file %s needs to be deleted",name); +OBSOLETE result = adir_remove (fce,name); +OBSOLETE assert ( result == 0); +OBSOLETE } /* This is for the file produced during disconnect mode, +OBSOLETE if error==ENOENT then the file is created during connect mode*/ +OBSOLETE +OBSOLETE fce->status = status; +OBSOLETE fce->volsync = volsync; +OBSOLETE +OBSOLETE volcache_update_volsync (fce->volume, fce->volsync); +OBSOLETE +OBSOLETE tempres = conv_dir(fce, ce, 0, &cache_handle, tmp, sizeof(tmp)); +OBSOLETE +OBSOLETE childEntry->host = 0; /*Ba shiqi: no callback for this entry*/ +OBSOLETE +OBSOLETE out: +OBSOLETE +OBSOLETE cred_free(ce); +OBSOLETE free_fs_server_context(&context); +OBSOLETE ReleaseWriteLock(&fce->lock); +OBSOLETE return error; +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE static int +OBSOLETE reconnect_mut_chk(FCacheEntry *fce, CredCacheEntry *ce, int version) +OBSOLETE { +OBSOLETE ConnCacheEntry *conn; +OBSOLETE fs_server_context context; +OBSOLETE FCacheEntry fetched = *fce; +OBSOLETE int ret; +OBSOLETE +OBSOLETE AFSFetchStatus status; +OBSOLETE AFSCallBack callback; +OBSOLETE AFSVolSync volsync; +OBSOLETE +OBSOLETE AssertExclLocked(&fetched.lock); +OBSOLETE +OBSOLETE /*SWW Aug 01: >= is changed into > */ +OBSOLETE conn = find_first_fs (&fetched, ce, &context); +OBSOLETE if (conn == NULL) { +OBSOLETE arla_log (ADEBDISCONN, "find_first_fs failed", fce->index); +OBSOLETE return ENETDOWN; +OBSOLETE } +OBSOLETE +OBSOLETE ret = RXAFS_FetchStatus (conn->connection, +OBSOLETE &fce->fid.fid, +OBSOLETE &status, +OBSOLETE &callback, +OBSOLETE &volsync); +OBSOLETE if (ret) { +OBSOLETE if (ret == -1) +OBSOLETE ret = ENETDOWN; +OBSOLETE free_fs_server_context(&context); +OBSOLETE arla_warn (ADEBFCACHE, ret, "fetch-status"); +OBSOLETE return ret; +OBSOLETE } +OBSOLETE +OBSOLETE if (status.DataVersion > version) +OBSOLETE { +OBSOLETE arla_log(ADEBDISCONN, "reconnect_mut_chk: concurrent writes detected!"); +OBSOLETE return 1; +OBSOLETE } +OBSOLETE free_fs_server_context(&context); +OBSOLETE return 0; +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE static void +OBSOLETE fcache_backfile_name(char *name, size_t len) +OBSOLETE { +OBSOLETE static int no = 1; +OBSOLETE +OBSOLETE snprintf (name, len, "%04X",no++); +OBSOLETE strcat (name, "bak"); +OBSOLETE name[strlen(name)+1] = '\0'; +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE static void +OBSOLETE copy_cached_file(int from, int to) +OBSOLETE { +OBSOLETE char name_from[2 * sizeof(int) + 1], name_to[2 * sizeof(int) + 1]; +OBSOLETE int fd_from, n, fd_to; +OBSOLETE char buf[BUFSIZE]; +OBSOLETE +OBSOLETE snprintf (name_from, sizeof(name_from), "%04X", from); +OBSOLETE snprintf (name_to, sizeof(name_to), "%04X", to); +OBSOLETE +OBSOLETE fd_from = open(name_from,O_RDONLY | O_BINARY, 0); +OBSOLETE fd_to = open(name_to, O_WRONLY | O_CREAT | O_BINARY | O_TRUNC, 0600); +OBSOLETE +OBSOLETE while((n = read(fd_from, buf, BUFSIZE)) > 0) +OBSOLETE write(fd_to, buf, n); +OBSOLETE +OBSOLETE #if 0 +OBSOLETE if(fstat(fd_to, &statinfo)<0) { +OBSOLETE arla_warnx(ADEBDISCONN,"ERROR"); +OBSOLETE } +OBSOLETE #endif +OBSOLETE +OBSOLETE close(fd_from); +OBSOLETE close(fd_to); +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE static void +OBSOLETE reconnect_update_fid (FCacheEntry *entry, VenusFid oldfid) +OBSOLETE { +OBSOLETE if (entry->flags.kernelp) +OBSOLETE update_fid (oldfid, NULL, entry->fid, entry); +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE static int +OBSOLETE reconnect_mut_newfile(FCacheEntry **fcep, nnpfs_pag_t cred,VenusFid *new_fid) +OBSOLETE { +OBSOLETE +OBSOLETE FCacheEntry *parent_fce; +OBSOLETE u_long host; +OBSOLETE char name[2 * sizeof(int) + 3 + 1], tmp[2 * sizeof(int) + 2]; +OBSOLETE AFSStoreStatus store_attr; +OBSOLETE AFSFetchStatus fetch_attr; +OBSOLETE CredCacheEntry *ce; +OBSOLETE AccessEntry *ae; +OBSOLETE VenusFid newfid; +OBSOLETE int ret; +OBSOLETE int from, to; +OBSOLETE fcache_cache_handle cache_handle; +OBSOLETE +OBSOLETE ret = fcache_find (&parent_fce, (*fcep)->parent); +OBSOLETE assert (ret == 0); +OBSOLETE +OBSOLETE host = (*fcep)->host; +OBSOLETE +OBSOLETE ce = cred_get((*fcep)->parent.Cell, cred, CRED_ANY); +OBSOLETE +OBSOLETE fcache_backfile_name (name, sizeof(name)); +OBSOLETE +OBSOLETE store_attr.Mask = 8; +OBSOLETE store_attr.ClientModTime = 430144; +OBSOLETE store_attr.Owner = 1957724; +OBSOLETE store_attr.Group = 21516; +OBSOLETE store_attr.UnixModeBits = 420; +OBSOLETE store_attr.SegSize = 0; +OBSOLETE +OBSOLETE create_file(parent_fce, name, &store_attr, &newfid, &fetch_attr, ce); +OBSOLETE +OBSOLETE (*fcep)->flags.datap = FALSE; /* Ba shiqi: we need to get the old from FS*/ +OBSOLETE *new_fid = newfid; +OBSOLETE from = (*fcep)->index; +OBSOLETE ret = fcache_find(fcep, newfid); +OBSOLETE assert (ret == 0); +OBSOLETE to = (*fcep)->index; +OBSOLETE (*fcep)->host = host; +OBSOLETE (*fcep)->flags.attrp = TRUE; +OBSOLETE (*fcep)->flags.datap = TRUE; +OBSOLETE findaccess(ce->cred, (*fcep)->acccache, &ae); /*Ba shijiu obtain access */ +OBSOLETE ae->cred = ce->cred; +OBSOLETE ae->access = (*fcep)->status.CallerAccess; +OBSOLETE +OBSOLETE ReleaseWriteLock(&(*fcep)->lock); +OBSOLETE +OBSOLETE copy_cached_file(from, to); +OBSOLETE ret = adir_creat (parent_fce, name, newfid.fid); +OBSOLETE assert (ret ==0); +OBSOLETE conv_dir (parent_fce, ce, 0, &cache_handle, tmp, sizeof(tmp)); +OBSOLETE ReleaseWriteLock(&parent_fce->lock); +OBSOLETE +OBSOLETE return 0; +OBSOLETE } +OBSOLETE +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE int reconnect_putattr(struct vcache *vcp, struct nnpfs_attr *xap) +OBSOLETE { +OBSOLETE +OBSOLETE ConnCacheEntry *conn; +OBSOLETE fs_server_context context; +OBSOLETE struct rx_call *call; +OBSOLETE VenusFid *fid; +OBSOLETE CredCacheEntry *ce; +OBSOLETE FCacheEntry *fce, *tempce; +OBSOLETE AFSFetchStatus status; +OBSOLETE Result res; +OBSOLETE uint32_t sizefs; +OBSOLETE AFSStoreStatus storestatus; +OBSOLETE AFSVolSync volsync; +OBSOLETE int ret; +OBSOLETE +OBSOLETE fid = &(vcp->fid); /* points to the VenusFid structure */ +OBSOLETE fid = fid_translate(fid); +OBSOLETE +OBSOLETE #if 0 +OBSOLETE arla_log(ADEBDISCONN, "reconnect: DISCONNECTED write on fid.Cell=0x%x, " +OBSOLETE "fid.fid.Volume= 0x%x, fid.fid.Vnode=0x%x, fid.fid.Unique=0x%x", +OBSOLETE fid->Cell, +OBSOLETE fid->fid.Volume, +OBSOLETE fid->fid.Vnode, +OBSOLETE fid->fid.Unique); +OBSOLETE #endif +OBSOLETE +OBSOLETE ce = cred_get (fid->Cell, vcp->cred.pag, CRED_ANY); +OBSOLETE assert (ce != NULL); +OBSOLETE res.res = 0; +OBSOLETE +OBSOLETE #if 0 +OBSOLETE /* Ba shier: should we send the file back to server? */ +OBSOLETE if (XA_VALID_SIZE(xap)){ +OBSOLETE AFSStoreStatus storestatus; +OBSOLETE memset(&storestatus, 0, sizeof(storestatus)); +OBSOLETE storestatus.Mask = 0; +OBSOLETE +OBSOLETE res = cm_ftruncate (*fid, xap->xa_size, &storestatus, ce); +OBSOLETE } +OBSOLETE #endif +OBSOLETE +OBSOLETE ret = fcache_find(&fce, *fid); +OBSOLETE assert (ret == 0); +OBSOLETE tempce = fce; +OBSOLETE +OBSOLETE sizefs=fce->status.Length; +OBSOLETE +OBSOLETE #if 0 /* XXX */ +OBSOLETE /* some people have written to the file while we are disconnected */ +OBSOLETE /* we have to give it a different name on the server */ +OBSOLETE if (reconnect_mut_chk(fce, ce, vcp->DataVersion)) +OBSOLETE { +OBSOLETE VenusFid new_fid; +OBSOLETE +OBSOLETE alloc_fid_trans(fid); +OBSOLETE reconnect_mut_newfile(&fce,vcp->cred.pag,&new_fid); +OBSOLETE fce->status.Length = sizefs; +OBSOLETE fce->length = sizefs; +OBSOLETE ReleaseWriteLock(&tempce->lock); +OBSOLETE fill_fid_trans(&new_fid); +OBSOLETE tempce->flags.attrp = FALSE; +OBSOLETE tempce->flags.kernelp = FALSE; +OBSOLETE } +OBSOLETE #endif +OBSOLETE +OBSOLETE /* code from truncate file XXX join */ +OBSOLETE conn = find_first_fs (fce, ce, &context); +OBSOLETE if (conn == NULL) { +OBSOLETE arla_log (ADEBDISCONN, "find_first_fs failed."); +OBSOLETE ReleaseWriteLock(&fce->lock); +OBSOLETE cred_free(ce); +OBSOLETE return ENETDOWN; +OBSOLETE } +OBSOLETE +OBSOLETE if (fce->status.FileType != TYPE_DIR) { +OBSOLETE +OBSOLETE call = rx_NewCall (conn->connection); +OBSOLETE if (call == NULL) { +OBSOLETE arla_log (ADEBDISCONN, "Cannot call"); +OBSOLETE res.res = ENOMEM; +OBSOLETE goto out; +OBSOLETE } +OBSOLETE +OBSOLETE storestatus.Mask = 0; +OBSOLETE res.res = StartRXAFS_StoreData (call, +OBSOLETE &(fce->fid.fid), +OBSOLETE &storestatus, +OBSOLETE 0, 0, fce->status.Length); +OBSOLETE if(res.res) { +OBSOLETE arla_log (ADEBDISCONN, "Could not start store, %s (%d)", +OBSOLETE koerr_gettext(res.res), res.res); +OBSOLETE rx_EndCall(call, 0); +OBSOLETE goto out; +OBSOLETE } +OBSOLETE +OBSOLETE sizefs = htonl (sizefs); +OBSOLETE if (rx_Write (call, &sizefs, sizeof(sizefs)) != sizeof(sizefs)) { +OBSOLETE res.res = conv_to_arla_errno(rx_GetCallError(call)); +OBSOLETE arla_log (ADEBDISCONN, "Error writing length: %d", res.res); +OBSOLETE rx_EndCall(call, 0); +OBSOLETE goto out; +OBSOLETE } +OBSOLETE +OBSOLETE if (rx_Write (call, 0, 0) != 0) { +OBSOLETE res.res = conv_to_arla_errno(rx_GetCallError(call)); +OBSOLETE arla_log (ADEBDISCONN, "Error writing: %d", res.res); +OBSOLETE rx_EndCall(call, 0); +OBSOLETE goto out; +OBSOLETE } +OBSOLETE +OBSOLETE res.res = rx_EndCall (call, EndRXAFS_StoreData (call, +OBSOLETE &status, +OBSOLETE &volsync)); +OBSOLETE if (res.res) { +OBSOLETE arla_log (ADEBDISCONN, "Error rx_EndCall: %s (%d)", +OBSOLETE koerr_gettext(res.res), res.res); +OBSOLETE goto out; +OBSOLETE } +OBSOLETE +OBSOLETE fce->status = status; +OBSOLETE fce->volsync = volsync; +OBSOLETE +OBSOLETE volcache_update_volsync (fce->volume, fce->volsync); +OBSOLETE +OBSOLETE } +OBSOLETE /* code from write_attr XXX join */ +OBSOLETE nnpfs_attr2afsstorestatus(xap, &storestatus); +OBSOLETE +OBSOLETE res.res = RXAFS_StoreStatus (conn->connection, +OBSOLETE &fce->fid.fid, +OBSOLETE &storestatus, +OBSOLETE &status, +OBSOLETE &volsync); +OBSOLETE if (res.res) { +OBSOLETE arla_log (ADEBDISCONN, "Could not make store-status call, %s (%d)", +OBSOLETE koerr_gettext(res.res), res.res); +OBSOLETE goto out; +OBSOLETE } +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "write_attr: status.Length = %d", status.Length); +OBSOLETE fce->status = status; +OBSOLETE fce->volsync = volsync; +OBSOLETE +OBSOLETE volcache_update_volsync (fce->volume, fce->volsync); +OBSOLETE +OBSOLETE out: +OBSOLETE +OBSOLETE free_fs_server_context(&context); +OBSOLETE ReleaseWriteLock(&fce->lock); +OBSOLETE cred_free(ce); +OBSOLETE return res.res; +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE static int +OBSOLETE reconnect_putdata(struct vcache *vcp) +OBSOLETE { +OBSOLETE VenusFid *fid; +OBSOLETE FCacheEntry *fce; +OBSOLETE CredCacheEntry *ce; +OBSOLETE Result res; +OBSOLETE +OBSOLETE uint32_t sizefs; +OBSOLETE int fd = -1; +OBSOLETE struct rx_call *call; +OBSOLETE ConnCacheEntry *conn; +OBSOLETE fs_server_context context; +OBSOLETE struct stat statinfo; +OBSOLETE AFSStoreStatus storestatus; +OBSOLETE AFSFetchStatus status; +OBSOLETE AFSVolSync volsync; +OBSOLETE int ret; +OBSOLETE +OBSOLETE fid = &(vcp->fid); /* points to the VenusFid structure */ +OBSOLETE arla_log(ADEBDISCONN, "reconnect: putdata before fid_translate, " +OBSOLETE "fid->Cell=0x%x, fid->fid.Volume=0x%x, fid->fid.Vnode=0x%x, " +OBSOLETE "fid->fid.Unique=0x%x", +OBSOLETE fid->Cell, +OBSOLETE fid->fid.Volume, +OBSOLETE fid->fid.Vnode, +OBSOLETE fid->fid.Unique); +OBSOLETE +OBSOLETE fid = fid_translate(fid); +OBSOLETE +OBSOLETE arla_log(ADEBDISCONN, "reconnect: putdata after fid_translate, " +OBSOLETE "fid->Cell=0x%x, fid->fid.Volume=0x%x, fid->fid.Vnode=0x%x, " +OBSOLETE "fid->fid.Unique=0x%x", +OBSOLETE fid->Cell, +OBSOLETE fid->fid.Volume, +OBSOLETE fid->fid.Vnode, +OBSOLETE fid->fid.Unique); +OBSOLETE +OBSOLETE +OBSOLETE ce = cred_get (fid->Cell, vcp->cred.pag, CRED_ANY); +OBSOLETE assert (ce != NULL); +OBSOLETE +OBSOLETE ret = fcache_find (&fce, *fid); +OBSOLETE assert (ret == 0); +OBSOLETE +OBSOLETE #if 0 +OBSOLETE isupdate = reconnect_mut_chk(fce, ce, vcp->DataVersion); +OBSOLETE if (isupdate) +OBSOLETE { +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "reconnect_putdata: send data back because " +OBSOLETE "the file was modified!"); +OBSOLETE cred_free(ce); +OBSOLETE ReleaseWriteLock(&fce->lock); +OBSOLETE reconnect_mut_newfile(&fce, vcp->cred.pag); +OBSOLETE return -1; +OBSOLETE } +OBSOLETE +OBSOLETE if (reconnect_mut_chk (fce, ce)) { +OBSOLETE arla_log (ADEBDISCONN, "Reconnect_putdata: can not send the file" +OBSOLETE "to FS becausethis file has been modified!"); +OBSOLETE ReleaseWriteLock(&fce->lock); +OBSOLETE return -1; +OBSOLETE } +OBSOLETE #endif +OBSOLETE +OBSOLETE /* code taken from write_data XXX join */ +OBSOLETE AssertExclLocked(&fce->lock); +OBSOLETE +OBSOLETE conn = find_first_fs (fce, ce, &context); +OBSOLETE if (conn == NULL) { +OBSOLETE arla_log (ADEBDISCONN, "find_first_fs failed"); +OBSOLETE ReleaseWriteLock(&fce->lock); +OBSOLETE cred_free(ce); +OBSOLETE return ENETDOWN; +OBSOLETE } +OBSOLETE +OBSOLETE fd = fcache_open_file (fce, O_RDONLY); +OBSOLETE if (fd < 0) { +OBSOLETE arla_log (ADEBDISCONN, "open %u failed", fce->index); +OBSOLETE res.res = errno; +OBSOLETE goto out; +OBSOLETE } +OBSOLETE +OBSOLETE if (fstat (fd, &statinfo) < 0) { +OBSOLETE arla_log (ADEBDISCONN, "Cannot stat file %u", fce->index); +OBSOLETE res.res = errno; +OBSOLETE goto out; +OBSOLETE } +OBSOLETE +OBSOLETE sizefs = statinfo.st_size; +OBSOLETE +OBSOLETE call = rx_NewCall (conn->connection); +OBSOLETE if (call == NULL) { +OBSOLETE arla_log (ADEBDISCONN, "Cannot call"); +OBSOLETE res.res = ENOMEM; +OBSOLETE goto out; +OBSOLETE } +OBSOLETE +OBSOLETE storestatus.Mask = 0; /* Dont save anything */ +OBSOLETE res.res = StartRXAFS_StoreData (call, &fce->fid.fid, +OBSOLETE &storestatus, +OBSOLETE 0, +OBSOLETE sizefs, +OBSOLETE sizefs); +OBSOLETE if (res.res) { +OBSOLETE arla_log (ADEBDISCONN, "Could not start store, %s (%d)", +OBSOLETE koerr_gettext(res.res), res.res); +OBSOLETE rx_EndCall(call, 0); +OBSOLETE goto out; +OBSOLETE } +OBSOLETE +OBSOLETE res.res = copyfd2rx (fd, call, 0, sizefs); +OBSOLETE if (res.res) { +OBSOLETE rx_EndCall(call, res.res); +OBSOLETE arla_log (ADEBDISCONN, "copyfd2rx failed: %d", res.res); +OBSOLETE goto out; +OBSOLETE } +OBSOLETE +OBSOLETE res.res = rx_EndCall (call, EndRXAFS_StoreData (call, +OBSOLETE &status, +OBSOLETE &volsync)); +OBSOLETE if (res.res) { +OBSOLETE arla_log (ADEBDISCONN, "Error rx_EndCall: %s (%d)", +OBSOLETE koerr_gettext(res.res), res.res); +OBSOLETE goto out; +OBSOLETE } +OBSOLETE if (status.DataVersion > fce->status.DataVersion) +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "reconnect: putdata, server incremented DataVersion!"); +OBSOLETE +OBSOLETE fce->status = status; +OBSOLETE fce->volsync = volsync; +OBSOLETE +OBSOLETE volcache_update_volsync (fce->volume, fce->volsync); +OBSOLETE +OBSOLETE out: +OBSOLETE +OBSOLETE ReleaseWriteLock(&fce->lock); +OBSOLETE if (fd != -1) +OBSOLETE close (fd); +OBSOLETE free_fs_server_context (&context); +OBSOLETE +OBSOLETE cred_free(ce); +OBSOLETE return res.res; +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE int reconnect_rename(struct vcache *vcp_old, struct vcache *vcp_new, +OBSOLETE char *name_old, char *name_new) +OBSOLETE { +OBSOLETE +OBSOLETE FCacheEntry *fce_old, *fce_new; +OBSOLETE CredCacheEntry *ce; +OBSOLETE VenusFid *fid_old, *fid_new,foo_fid,*tempnew_fid; +OBSOLETE int error; +OBSOLETE +OBSOLETE int ret = 0; +OBSOLETE Result res; +OBSOLETE char tmp[2 * sizeof(int) + 2]; +OBSOLETE int isnewpar = 0; +OBSOLETE ConnCacheEntry *conn; +OBSOLETE fs_server_context context; +OBSOLETE AFSFetchStatus orig_status, new_status; +OBSOLETE AFSVolSync volsync; +OBSOLETE fcache_cache_handle cache_handle; +OBSOLETE +OBSOLETE fid_old = &vcp_old->fid; +OBSOLETE fid_old = fid_translate(fid_old); +OBSOLETE +OBSOLETE ret = fcache_find (&fce_old, *fid_old); +OBSOLETE assert (ret == 0); +OBSOLETE +OBSOLETE /* ReleaseWriteLock(&fce_old->lock); SWW Qiyue 28 Maybe we dont need it*/ +OBSOLETE assert(fce_old); +OBSOLETE arla_log(ADEBDISCONN, "reconnect: old rename on Cell=0x%x, " +OBSOLETE "fid.Volume= 0x%x, fid.Vnode=0x%x, fid.Unique=0x%x", +OBSOLETE fce_old->fid.Cell, +OBSOLETE fce_old->fid.fid.Volume, +OBSOLETE fce_old->fid.fid.Vnode, +OBSOLETE fce_old->fid.fid.Unique); +OBSOLETE +OBSOLETE fid_new = tempnew_fid = &vcp_new->fid; +OBSOLETE fid_new = fid_translate(fid_new); +OBSOLETE +OBSOLETE if (tempnew_fid->fid.Volume != fid_new->fid.Volume || +OBSOLETE tempnew_fid->fid.Vnode != fid_new->fid.Vnode || +OBSOLETE tempnew_fid->fid.Unique != fid_new->fid.Unique) +OBSOLETE isnewpar = 1; +OBSOLETE +OBSOLETE /*Ba ba: the parent dir was created during disconnected */ +OBSOLETE +OBSOLETE if (fid_old->fid.Volume == fid_new->fid.Volume && +OBSOLETE fid_old->fid.Vnode == fid_new->fid.Vnode && +OBSOLETE fid_old->fid.Unique == fid_new->fid.Unique ) +OBSOLETE ReleaseWriteLock(&fce_old->lock); /* old and new are the same*/ +OBSOLETE +OBSOLETE ret = fcache_find (&fce_new, *fid_new); +OBSOLETE assert (ret == 0); +OBSOLETE +OBSOLETE arla_log(ADEBDISCONN, "reconnect: new rename on Cell=0x%x, " +OBSOLETE "fid.Volume= 0x%x, fid.Vnode=0x%x, fid.Unique=0x%x", +OBSOLETE fce_new->fid.Cell, +OBSOLETE fce_new->fid.fid.Volume, +OBSOLETE fce_new->fid.fid.Vnode, +OBSOLETE fce_new->fid.fid.Unique); +OBSOLETE +OBSOLETE +OBSOLETE +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "reconnect_rename: fce_old = 0x%x, fce_new = 0x%x", +OBSOLETE fce_old, fce_new); +OBSOLETE +OBSOLETE ce = cred_get (vcp_old->fid.Cell, vcp_old->cred.pag, CRED_ANY); +OBSOLETE assert (ce != NULL); +OBSOLETE +OBSOLETE AssertExclLocked(&fce_old->lock); +OBSOLETE AssertExclLocked(&fce_new->lock); +OBSOLETE +OBSOLETE conn = find_first_fs (fce_old, ce, &context); +OBSOLETE if (conn == NULL) { +OBSOLETE arla_log (ADEBDISCONN, "find_first_fs failed"); +OBSOLETE ReleaseWriteLock(&fce_new->lock); +OBSOLETE +OBSOLETE if (fid_old->fid.Volume != fid_new->fid.Volume || +OBSOLETE fid_old->fid.Vnode != fid_new->fid.Vnode || +OBSOLETE fid_old->fid.Unique != fid_new->fid.Unique ) +OBSOLETE ReleaseWriteLock(&fce_old->lock); /* old and new are the same*/ +OBSOLETE +OBSOLETE cred_free(ce); +OBSOLETE return ENETDOWN; +OBSOLETE } +OBSOLETE +OBSOLETE error = RXAFS_Rename (conn->connection, +OBSOLETE &fce_old->fid.fid, +OBSOLETE name_old, +OBSOLETE &fce_new->fid.fid, +OBSOLETE name_new, +OBSOLETE &orig_status, +OBSOLETE &new_status, +OBSOLETE &volsync); +OBSOLETE +OBSOLETE if (error) { +OBSOLETE arla_log (ADEBDISCONN, "Could not Rename: %s (%d)", koerr_gettext(error), error); +OBSOLETE goto out; } +OBSOLETE +OBSOLETE fce_old->status = orig_status; +OBSOLETE fce_new->status = new_status; +OBSOLETE +OBSOLETE fce_old->volsync = fce_new->volsync = volsync; +OBSOLETE +OBSOLETE volcache_update_volsync (fce_old->volume, fce_old->volsync); +OBSOLETE +OBSOLETE +OBSOLETE /*SWW Aug 01 */ +OBSOLETE arla_warnx (ADEBDISCONN, +OBSOLETE "reconnect_rename: we delete the old one %s volumn=0x%x, " +OBSOLETE "vnode=0x%x,unique=0x%x", +OBSOLETE name_old,fce_old->fid.fid.Volume, +OBSOLETE fce_old->fid.fid.Vnode, +OBSOLETE fce_old->fid.fid.Unique); +OBSOLETE +OBSOLETE /*Ba Yi: get the VenuseFid for new file */ +OBSOLETE #if 0 +OBSOLETE if (fid_old->fid.Volume == fid_new->fid.Volume && +OBSOLETE fid_old->fid.Vnode == fid_new->fid.Vnode && +OBSOLETE fid_old->fid.Unique == fid_new->fid.Unique ) ; +OBSOLETE #endif +OBSOLETE ReleaseWriteLock(&fce_old->lock); /* old and new are the same*/ +OBSOLETE +OBSOLETE error = adir_lookup (&fce_old->fid, name_old, &foo_fid, NULL, &ce); +OBSOLETE +OBSOLETE #if 0 +OBSOLETE if (fid_old->fid.Volume == fid_new->fid.Volume && +OBSOLETE fid_old->fid.Vnode == fid_new->fid.Vnode && +OBSOLETE fid_old->fid.Unique == fid_new->fid.Unique ); +OBSOLETE #endif +OBSOLETE ObtainWriteLock (&fce_old->lock); +OBSOLETE +OBSOLETE /*Ba San: delete the old which was created during dis */ +OBSOLETE if (error == 0) { +OBSOLETE arla_warnx (ADEBDISCONN,"reconnect_rename: we delete the old one %s " +OBSOLETE "volumn=0x%x,vnode=0x%x,unique=0x%x", +OBSOLETE name_old, +OBSOLETE foo_fid.fid.Volume, +OBSOLETE foo_fid.fid.Vnode, +OBSOLETE foo_fid.fid.Unique); +OBSOLETE +OBSOLETE adir_remove(fce_old,name_old); +OBSOLETE adir_remove(fce_new,name_new); +OBSOLETE +OBSOLETE res = conv_dir (fce_old, ce, 0, &cache_handle, tmp, sizeof(tmp)); +OBSOLETE +OBSOLETE } else { +OBSOLETE /* if found delete it */ +OBSOLETE /*Ba San: try to find the previous VenuseFid for old name */ +OBSOLETE if (error == ENOENT) { +OBSOLETE #if 0 +OBSOLETE if (fid_old->fid.Volume == fid_new->fid.Volume && +OBSOLETE fid_old->fid.Vnode == fid_new->fid.Vnode && +OBSOLETE fid_old->fid.Unique == fid_new->fid.Unique ); +OBSOLETE #endif +OBSOLETE ReleaseWriteLock(&fce_new->lock); +OBSOLETE +OBSOLETE error = adir_lookup (&fce_new->fid, name_new, &foo_fid, NULL, &ce); +OBSOLETE +OBSOLETE #if 0 +OBSOLETE if (fid_old->fid.Volume == fid_new->fid.Volume && +OBSOLETE fid_old->fid.Vnode == fid_new->fid.Vnode && +OBSOLETE fid_old->fid.Unique == fid_new->fid.Unique ); +OBSOLETE #endif +OBSOLETE ObtainWriteLock (&fce_new->lock); +OBSOLETE if (error == 0) /*Ba Si: We need delete the faked new */ +OBSOLETE adir_remove(fce_new,name_new); +OBSOLETE else if (error == ENOENT) { +OBSOLETE int venusret; +OBSOLETE +OBSOLETE venusret = find_venus (name_new,&foo_fid); +OBSOLETE assert (venusret==0); +OBSOLETE arla_warnx (ADEBDISCONN,"I MUST WRITE A PROGRAM HERE"); +OBSOLETE if (isnewpar == 1) { +OBSOLETE +OBSOLETE arla_warnx(ADEBDISCONN,"In reconnect_rename: " +OBSOLETE "new Volume=0x%x,Vnode=0x%x,Unique=0x%x", +OBSOLETE fce_new->fid.fid.Volume, +OBSOLETE fce_new->fid.fid.Vnode, +OBSOLETE fce_new->fid.fid.Unique); +OBSOLETE #if 0 +OBSOLETE error = adir_creat(fce_new, name_new, foo_fid.fid); +OBSOLETE #endif +OBSOLETE } +OBSOLETE } +OBSOLETE } +OBSOLETE } +OBSOLETE +OBSOLETE arla_warnx (ADEBDISCONN,"reconnect_rename: we add the new one %s " +OBSOLETE "volumn=0x%x,vnode=0x%x,unique=0x%x", +OBSOLETE name_new, +OBSOLETE foo_fid.fid.Volume, +OBSOLETE foo_fid.fid.Vnode, +OBSOLETE foo_fid.fid.Unique); +OBSOLETE error = adir_creat (fce_new, name_new, foo_fid.fid); +OBSOLETE res = conv_dir (fce_new, ce, 0, &cache_handle, tmp, sizeof(tmp)); +OBSOLETE +OBSOLETE /* Aug 1 */ +OBSOLETE +OBSOLETE out: +OBSOLETE +OBSOLETE free_fs_server_context (&context); +OBSOLETE +OBSOLETE ReleaseWriteLock(&fce_new->lock); +OBSOLETE +OBSOLETE if (fid_old->fid.Volume != fid_new->fid.Volume || +OBSOLETE fid_old->fid.Vnode != fid_new->fid.Vnode || +OBSOLETE fid_old->fid.Unique != fid_new->fid.Unique ) +OBSOLETE ReleaseWriteLock(&fce_old->lock); /* old and new are the same*/ +OBSOLETE +OBSOLETE cred_free(ce); +OBSOLETE return error; +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE int reconnect_create(struct vcache *parent, struct vcache *child, char *name) +OBSOLETE { +OBSOLETE +OBSOLETE ConnCacheEntry *conn; +OBSOLETE fs_server_context context; +OBSOLETE VenusFid *parent_fid; +OBSOLETE VenusFid *child_fid; +OBSOLETE VenusFid fakeFid; +OBSOLETE +OBSOLETE CredCacheEntry *ce; +OBSOLETE FCacheEntry *parentEntry; +OBSOLETE FCacheEntry *childEntry; +OBSOLETE +OBSOLETE AFSFetchStatus fetch_attr; +OBSOLETE AFSStoreStatus store_attr; +OBSOLETE +OBSOLETE AFSFetchStatus status; +OBSOLETE AFSCallBack callback; +OBSOLETE AFSVolSync volsync; +OBSOLETE int ret; +OBSOLETE char tmp[2 * sizeof(int) + 2]; +OBSOLETE fcache_cache_handle cache_handle; +OBSOLETE int32_t type; +OBSOLETE +OBSOLETE parent_fid = &(parent->fid); /* points to the VenusFid structure */ +OBSOLETE child_fid = &(child->fid); +OBSOLETE fakeFid = *child_fid; +OBSOLETE +OBSOLETE /*Ba Liu: the parent dir may be created during dison mode*/ +OBSOLETE parent_fid = fid_translate(parent_fid); +OBSOLETE +OBSOLETE ce = cred_get (parent->fid.Cell, parent->cred.pag, CRED_ANY); +OBSOLETE assert (ce != NULL); +OBSOLETE +OBSOLETE ret = fcache_find (&parentEntry, *parent_fid); +OBSOLETE assert (ret == 0); +OBSOLETE +OBSOLETE #if 0 +OBSOLETE is_change = reconnect_mut_chk(parentEntry, +OBSOLETE ce, +OBSOLETE parentEntry->status.DataVersion); +OBSOLETE #endif +OBSOLETE +OBSOLETE /*SWW Qiyue 30 delete the old file entry in dir */ +OBSOLETE arla_warnx (ADEBDISCONN, +OBSOLETE "reconnect_rename: we delete the old one volumn=0x%x, " +OBSOLETE "vnode=0x%x,unique=0x%x", +OBSOLETE parentEntry->fid.fid.Volume, +OBSOLETE parentEntry->fid.fid.Vnode, +OBSOLETE parentEntry->fid.fid.Unique); +OBSOLETE +OBSOLETE adir_remove(parentEntry,name); +OBSOLETE +OBSOLETE conn = find_first_fs (parentEntry, ce, &context); +OBSOLETE if (conn == NULL) { +OBSOLETE arla_log (ADEBDISCONN, "find_first_fs failed"); +OBSOLETE ReleaseWriteLock(&parentEntry->lock); +OBSOLETE ReleaseWriteLock(&childEntry->lock); +OBSOLETE free_fs_server_context(&context); +OBSOLETE cred_free(ce); +OBSOLETE return ENETDOWN; +OBSOLETE } +OBSOLETE +OBSOLETE ret = fcache_find (&childEntry, *child_fid); +OBSOLETE assert (ret == 0); +OBSOLETE +OBSOLETE recon_hashtabdel(childEntry); +OBSOLETE +OBSOLETE #if 0 +OBSOLETE fetch_attr = &childEntry->status; +OBSOLETE #endif +OBSOLETE +OBSOLETE store_attr.Mask = 8; +OBSOLETE store_attr.ClientModTime = childEntry->status.ClientModTime; +OBSOLETE store_attr.Owner = childEntry->status.Owner; +OBSOLETE store_attr.Group = childEntry->status.Group; +OBSOLETE store_attr.UnixModeBits = childEntry->status.UnixModeBits; +OBSOLETE store_attr.SegSize = childEntry->status.SegSize; +OBSOLETE +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "reconnect: create before RXAFS_CreateFile, " +OBSOLETE "Cell=0x%x, fid.Volume= 0x%x, fid.Vnode=0x%x, fid.Unique=0x%x", +OBSOLETE childEntry->fid.Cell, +OBSOLETE childEntry->fid.fid.Volume, +OBSOLETE childEntry->fid.fid.Vnode, +OBSOLETE childEntry->fid.fid.Unique); +OBSOLETE +OBSOLETE alloc_fid_trans(&childEntry->fid); +OBSOLETE +OBSOLETE +OBSOLETE ret = RXAFS_CreateFile (conn->connection, +OBSOLETE &(parentEntry->fid.fid), +OBSOLETE name, &store_attr, +OBSOLETE &(childEntry->fid.fid), &fetch_attr, +OBSOLETE &status, +OBSOLETE &callback, +OBSOLETE &volsync); +OBSOLETE +OBSOLETE if (ret) { +OBSOLETE if (ret == 17) { +OBSOLETE ReleaseWriteLock(&parentEntry->lock); +OBSOLETE reconnect_mut_newfile(&childEntry, +OBSOLETE parent->cred.pag, +OBSOLETE &childEntry->fid); +OBSOLETE ObtainWriteLock(&parentEntry->lock); +OBSOLETE fill_fid_trans(&childEntry->fid); +OBSOLETE recon_hashtabadd(childEntry); +OBSOLETE childEntry->host = rx_HostOf (rx_PeerOf (conn->connection)); +OBSOLETE reconnect_update_fid (childEntry, fakeFid); +OBSOLETE } else { +OBSOLETE arla_log (ADEBDISCONN, "Could not CreateFile: %s (%d)", +OBSOLETE koerr_gettext(ret), ret); +OBSOLETE } +OBSOLETE goto out; +OBSOLETE } +OBSOLETE +OBSOLETE parentEntry->status = status; +OBSOLETE parentEntry->callback = callback; +OBSOLETE parentEntry->volsync = volsync; +OBSOLETE +OBSOLETE childEntry->fid.Cell = parentEntry->fid.Cell; +OBSOLETE +OBSOLETE arla_log(ADEBDISCONN, "reconnect: create after RXAFS_CreateFile, " +OBSOLETE "Cell=0x%x, fid.Volume= 0x%x, fid .Vnode=0x%x, fid.Unique=0x%x", +OBSOLETE childEntry->fid.Cell, +OBSOLETE childEntry->fid.fid.Volume, +OBSOLETE childEntry->fid.fid.Vnode, +OBSOLETE childEntry->fid.fid.Unique); +OBSOLETE +OBSOLETE fill_fid_trans(&childEntry->fid); +OBSOLETE +OBSOLETE #if 0 +OBSOLETE ReleaseWriteLock(&childEntry->lock); +OBSOLETE #endif +OBSOLETE +OBSOLETE +OBSOLETE ret = volcache_getbyid (childEntry->fid.fid.Volume, +OBSOLETE childEntry->fid.Cell, +OBSOLETE ce, +OBSOLETE &childEntry->volume, +OBSOLETE &type); +OBSOLETE +OBSOLETE recon_hashtabadd(childEntry); +OBSOLETE +OBSOLETE arla_log(ADEBDISCONN, +OBSOLETE "reconnect: create after volcache_getbyid, Cell=0x%x, " +OBSOLETE "fid.Volume= 0x%x, fid .Vnode=0x%x, fid.Unique=0x%x", +OBSOLETE childEntry->fid.Cell, +OBSOLETE childEntry->fid.fid.Volume, +OBSOLETE childEntry->fid.fid.Vnode, +OBSOLETE childEntry->fid.fid.Unique); +OBSOLETE +OBSOLETE /* SWW Qiyue 30: add the new file entry in dir */ +OBSOLETE arla_warnx (ADEBDISCONN,"reconnect_rename: we add the new one " +OBSOLETE "volumn=0x%x,vnode=0x%x,unique=0x%x", +OBSOLETE parentEntry->fid.fid.Volume, +OBSOLETE parentEntry->fid.fid.Vnode, +OBSOLETE parentEntry->fid.fid.Unique); +OBSOLETE +OBSOLETE adir_creat (parentEntry, name, childEntry->fid.fid); +OBSOLETE +OBSOLETE childEntry->status = fetch_attr; +OBSOLETE +OBSOLETE childEntry->flags.attrp = TRUE; +OBSOLETE childEntry->flags.kernelp = TRUE; +OBSOLETE +OBSOLETE childEntry->flags.datap = TRUE; +OBSOLETE childEntry->tokens |= NNPFS_ATTR_R | NNPFS_DATA_R | NNPFS_DATA_W; +OBSOLETE +OBSOLETE if (parentEntry->volume == NULL) +OBSOLETE ret = volcache_getbyid (parentEntry->fid.fid.Volume, +OBSOLETE parentEntry->fid.Cell, +OBSOLETE ce, +OBSOLETE &parentEntry->volume, +OBSOLETE &type); +OBSOLETE +OBSOLETE volcache_update_volsync (parentEntry->volume, parentEntry->volsync); +OBSOLETE +OBSOLETE +OBSOLETE +OBSOLETE /*SWW Qiyue 28: Set the host for child entry */ +OBSOLETE +OBSOLETE childEntry->host = rx_HostOf (rx_PeerOf (conn->connection)); +OBSOLETE assert(childEntry->host); +OBSOLETE +OBSOLETE /*SWW Qiyue 29: */ +OBSOLETE arla_warnx (ADEBDISCONN, +OBSOLETE "Replace fid.Volume=0x%x,Vnode=0x%x,Unique=0x%x with " +OBSOLETE "Volume=0x%x,Vnode=0x%x,Unqiue=0x%x", +OBSOLETE fakeFid.fid.Volume, +OBSOLETE fakeFid.fid.Vnode, +OBSOLETE fakeFid.fid.Unique, +OBSOLETE childEntry->fid.fid.Volume, +OBSOLETE childEntry->fid.fid.Vnode, +OBSOLETE childEntry->fid.fid.Unique); +OBSOLETE +OBSOLETE reconnect_update_fid (childEntry, fakeFid); +OBSOLETE +OBSOLETE conv_dir(parentEntry, ce, 0, &cache_handle, tmp, sizeof(tmp)); +OBSOLETE +OBSOLETE ReleaseWriteLock(&childEntry->lock); +OBSOLETE +OBSOLETE out: +OBSOLETE +OBSOLETE ReleaseWriteLock(&parentEntry->lock); +OBSOLETE ReleaseWriteLock(&childEntry->lock); +OBSOLETE free_fs_server_context(&context); +OBSOLETE cred_free(ce); +OBSOLETE return ret; +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE int reconnect_mkdir(struct vcache *parent, struct vcache *curdir, +OBSOLETE AFSStoreStatus *store_status, char *name) +OBSOLETE { +OBSOLETE ConnCacheEntry *conn; +OBSOLETE fs_server_context context; +OBSOLETE CredCacheEntry *ce; +OBSOLETE VenusFid *parent_fid; +OBSOLETE VenusFid *child_fid; +OBSOLETE VenusFid fakeFid; +OBSOLETE +OBSOLETE FCacheEntry *parentEntry, *childEntry, *tempEntry, *tempparEntry; +OBSOLETE Result tempres; +OBSOLETE int ret = 0; +OBSOLETE int tempret = 0; +OBSOLETE struct timeval tv; +OBSOLETE char tmp[2 * sizeof(int) + 2]; +OBSOLETE +OBSOLETE AFSFid Outfid; /* Ba Wu: These are used to get the info from FS*/ +OBSOLETE AFSFetchStatus fetch_attr; +OBSOLETE AFSFetchStatus status; +OBSOLETE AFSCallBack callback; +OBSOLETE AFSVolSync volsync; +OBSOLETE fcache_cache_handle cache_handle; +OBSOLETE int32_t type; +OBSOLETE +OBSOLETE parent_fid = &(parent->fid); /* points to the VenusFid structure */ +OBSOLETE child_fid = &(curdir->fid); +OBSOLETE fakeFid = *child_fid; +OBSOLETE +OBSOLETE parent_fid = fid_translate(parent_fid); +OBSOLETE +OBSOLETE ce = cred_get (parent->fid.Cell, parent->cred.pag, CRED_ANY); +OBSOLETE assert (ce != NULL); +OBSOLETE +OBSOLETE ret = fcache_find (&parentEntry, *parent_fid); +OBSOLETE assert (ret == 0); +OBSOLETE +OBSOLETE tempparEntry = parentEntry; +OBSOLETE +OBSOLETE /*Ba ba: used to check whether name can be find Deleted !!! +OBSOLETE ReleaseWriteLock(&parentEntry->lock); +OBSOLETE tempret = adir_lookup (parentEntry->fid , name , &foo_fid , NULL, ce); */ +OBSOLETE /*Ba ba: used to check whether name can be find Deleted !!! */ +OBSOLETE +OBSOLETE /*Ba Wu Remove the dir name from itsparent dir */ +OBSOLETE tempret = adir_remove(parentEntry,name); +OBSOLETE conn = find_first_fs (parentEntry, ce, &context); +OBSOLETE if (conn == NULL) { +OBSOLETE arla_log (ADEBDISCONN,"Cannot make this connection"); +OBSOLETE ReleaseWriteLock(&parentEntry->lock); +OBSOLETE ReleaseWriteLock(&childEntry->lock); +OBSOLETE cred_free(ce); +OBSOLETE return ENETDOWN; +OBSOLETE } +OBSOLETE +OBSOLETE ret = fcache_find(&childEntry, *child_fid);/*Ba Wu: remove the newly created dir */ +OBSOLETE assert (ret == 0); +OBSOLETE +OBSOLETE recon_hashtabdel(childEntry); +OBSOLETE +OBSOLETE alloc_fid_trans(&childEntry->fid); +OBSOLETE +OBSOLETE gettimeofday(&tv, NULL); +OBSOLETE +OBSOLETE ret = RXAFS_MakeDir (conn->connection, +OBSOLETE &parentEntry->fid.fid, +OBSOLETE name, +OBSOLETE store_status, +OBSOLETE &Outfid, +OBSOLETE &fetch_attr, +OBSOLETE &status, +OBSOLETE &callback, +OBSOLETE &volsync); +OBSOLETE +OBSOLETE if (ret) { +OBSOLETE arla_log (ADEBDISCONN, "Could not CreateFile: %s (%d)", +OBSOLETE koerr_gettext(ret), ret); +OBSOLETE goto out; +OBSOLETE } +OBSOLETE +OBSOLETE parentEntry->status = status; +OBSOLETE parentEntry->callback = callback; +OBSOLETE parentEntry->callback.ExpirationTime += tv.tv_sec; +OBSOLETE parentEntry->volsync = volsync; +OBSOLETE +OBSOLETE childEntry->fid.Cell = parentEntry->fid.Cell; +OBSOLETE childEntry->fid.fid = Outfid; +OBSOLETE childEntry->status = fetch_attr; +OBSOLETE childEntry->flags.attrp = TRUE; +OBSOLETE childEntry->flags.kernelp = TRUE; +OBSOLETE childEntry->flags.datap = TRUE; +OBSOLETE childEntry->tokens |= NNPFS_ATTR_R | NNPFS_DATA_R | NNPFS_DATA_W; +OBSOLETE +OBSOLETE fill_fid_trans(&childEntry->fid); +OBSOLETE +OBSOLETE ret = volcache_getbyid (childEntry->fid.fid.Volume, +OBSOLETE childEntry->fid.Cell, +OBSOLETE ce, +OBSOLETE &childEntry->volume, +OBSOLETE &type); +OBSOLETE +OBSOLETE recon_hashtabadd(childEntry); +OBSOLETE +OBSOLETE /*Ba ba: Need to change later!!! */ +OBSOLETE #if 0 +OBSOLETE ReleaseWriteLock(&tempparEntry->lock); +OBSOLETE tempret = adir_changefid (tempparEntry->fid ,name, &Outfid, ce); +OBSOLETE ReleaseWriteLock(&tempparEntry->lock); +OBSOLETE tempret = adir_lookup (tempparEntry->fid ,name, &foo_fid, NULL, ce); +OBSOLETE #endif +OBSOLETE +OBSOLETE tempret = adir_creat (parentEntry, name, childEntry->fid.fid); +OBSOLETE +OBSOLETE childEntry->host = rx_HostOf (rx_PeerOf (conn->connection)); +OBSOLETE assert(childEntry->host); +OBSOLETE +OBSOLETE reconnect_update_fid(childEntry, fakeFid); +OBSOLETE +OBSOLETE tempres = conv_dir(parentEntry, ce, 0, &cache_handle, +OBSOLETE tmp, sizeof(tmp)); +OBSOLETE +OBSOLETE ReleaseWriteLock(&childEntry->lock); +OBSOLETE +OBSOLETE /*SWW Qiyue 29: This should be deleted later */ +OBSOLETE ret = fcache_find (&tempEntry, childEntry->fid); +OBSOLETE +OBSOLETE assert (ret == 0); +OBSOLETE ReleaseWriteLock(&tempEntry->lock); +OBSOLETE +OBSOLETE out: +OBSOLETE +OBSOLETE ReleaseWriteLock(&parentEntry->lock); +OBSOLETE ReleaseWriteLock(&childEntry->lock); +OBSOLETE free_fs_server_context(&context); +OBSOLETE cred_free(ce); +OBSOLETE return ret; +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE int reconnect_link(struct vcache *parent, struct vcache *existing, +OBSOLETE char *name) +OBSOLETE { +OBSOLETE ConnCacheEntry *conn; +OBSOLETE fs_server_context context; +OBSOLETE CredCacheEntry *ce; +OBSOLETE VenusFid *parent_fid; +OBSOLETE VenusFid *existing_fid; +OBSOLETE char tmp[2 * sizeof(int) + 2]; +OBSOLETE int ret = 0; +OBSOLETE FCacheEntry *dir_entry,*existing_entry; +OBSOLETE Result res; +OBSOLETE +OBSOLETE AFSFetchStatus new_status; +OBSOLETE AFSFetchStatus status; +OBSOLETE AFSVolSync volsync; +OBSOLETE fcache_cache_handle cache_handle; +OBSOLETE +OBSOLETE +OBSOLETE parent_fid = &(parent->fid); +OBSOLETE existing_fid = &(existing->fid); +OBSOLETE +OBSOLETE parent_fid = fid_translate(parent_fid); +OBSOLETE +OBSOLETE ce = cred_get (parent->fid.Cell, parent->cred.pag, CRED_ANY); +OBSOLETE assert (ce != NULL); +OBSOLETE +OBSOLETE ret = fcache_find (&dir_entry, *parent_fid); +OBSOLETE assert (ret == 0); +OBSOLETE +OBSOLETE ret = fcache_find (&existing_entry, *existing_fid); +OBSOLETE assert (ret == 0); +OBSOLETE +OBSOLETE conn = find_first_fs (dir_entry, ce, &context); +OBSOLETE if (conn == NULL) { +OBSOLETE arla_log (ADEBDISCONN,"Cannot make this connection"); +OBSOLETE ReleaseWriteLock(&dir_entry->lock); +OBSOLETE ReleaseWriteLock(&existing_entry->lock); +OBSOLETE cred_free(ce); +OBSOLETE return ENETDOWN; +OBSOLETE } +OBSOLETE +OBSOLETE ret = RXAFS_Link (conn->connection, +OBSOLETE &dir_entry->fid.fid, +OBSOLETE name, +OBSOLETE &existing_entry->fid.fid, +OBSOLETE &new_status, +OBSOLETE &status, +OBSOLETE &volsync); +OBSOLETE if (ret) { +OBSOLETE arla_warn (ADEBFCACHE, ret, "Link"); +OBSOLETE goto out; +OBSOLETE } +OBSOLETE +OBSOLETE dir_entry->status = status; +OBSOLETE dir_entry->volsync = volsync; +OBSOLETE +OBSOLETE existing_entry->status = new_status; +OBSOLETE +OBSOLETE volcache_update_volsync (dir_entry->volume, dir_entry->volsync); +OBSOLETE +OBSOLETE res = conv_dir (dir_entry, ce, 0, &cache_handle, tmp, sizeof(tmp)); +OBSOLETE +OBSOLETE out: +OBSOLETE ReleaseWriteLock(&dir_entry->lock); +OBSOLETE ReleaseWriteLock(&existing_entry->lock); +OBSOLETE cred_free(ce); +OBSOLETE free_fs_server_context (&context); +OBSOLETE return ret; +OBSOLETE } +OBSOLETE +OBSOLETE /* +OBSOLETE * +OBSOLETE */ +OBSOLETE +OBSOLETE int reconnect_symlink(struct vcache *parent, struct vcache *child, +OBSOLETE AFSStoreStatus *store_attr, char *name, +OBSOLETE char *contents) +OBSOLETE { +OBSOLETE ConnCacheEntry *conn; +OBSOLETE fs_server_context context; +OBSOLETE CredCacheEntry *ce; +OBSOLETE VenusFid *parent_fid, *child_fid, fakeFid; +OBSOLETE char tmp[2 * sizeof(int) + 2]; +OBSOLETE int ret = 0; +OBSOLETE FCacheEntry *dir_entry, *childEntry; +OBSOLETE Result res; +OBSOLETE +OBSOLETE AFSFetchStatus fetch_attr, new_status; +OBSOLETE AFSVolSync volsync; +OBSOLETE fcache_cache_handle cache_handle; +OBSOLETE int32_t type; +OBSOLETE +OBSOLETE parent_fid = &(parent->fid); +OBSOLETE child_fid = &(child->fid); +OBSOLETE fakeFid = *child_fid; +OBSOLETE parent_fid = fid_translate(parent_fid); +OBSOLETE +OBSOLETE ce = cred_get (parent->fid.Cell, parent->cred.pag, CRED_ANY); +OBSOLETE assert (ce != NULL); +OBSOLETE +OBSOLETE ret = fcache_find (&dir_entry, *parent_fid); +OBSOLETE assert (ret == 0); +OBSOLETE +OBSOLETE adir_remove(dir_entry,name); +OBSOLETE +OBSOLETE ret = fcache_find (&childEntry, *child_fid); +OBSOLETE assert (ret == 0); +OBSOLETE +OBSOLETE recon_hashtabdel(childEntry); +OBSOLETE +OBSOLETE assert(ret==0); +OBSOLETE conn = find_first_fs (dir_entry, ce, &context); +OBSOLETE if (conn == NULL) { +OBSOLETE arla_log (ADEBDISCONN,"Cannot make this connection"); +OBSOLETE ReleaseWriteLock(&dir_entry->lock); +OBSOLETE ReleaseWriteLock(&childEntry->lock); +OBSOLETE cred_free(ce); +OBSOLETE return ENOMEM; +OBSOLETE } +OBSOLETE +OBSOLETE alloc_fid_trans(&childEntry->fid); +OBSOLETE +OBSOLETE ret = RXAFS_Symlink (conn->connection, +OBSOLETE &dir_entry->fid.fid, +OBSOLETE name, +OBSOLETE contents, +OBSOLETE store_attr, +OBSOLETE &(childEntry->fid.fid), +OBSOLETE &fetch_attr, +OBSOLETE &new_status, +OBSOLETE &volsync); +OBSOLETE if (ret) { +OBSOLETE arla_warn (ADEBFCACHE, ret, "Symlink"); +OBSOLETE goto out; +OBSOLETE } +OBSOLETE +OBSOLETE child_fid->Cell = dir_entry->fid.Cell; +OBSOLETE +OBSOLETE fill_fid_trans (&childEntry->fid); +OBSOLETE ret = volcache_getbyid (childEntry->fid.fid.Volume, +OBSOLETE childEntry->fid.Cell, +OBSOLETE ce, +OBSOLETE &childEntry->volume, +OBSOLETE &type); +OBSOLETE +OBSOLETE recon_hashtabadd (childEntry); +OBSOLETE +OBSOLETE adir_creat(dir_entry, name, childEntry->fid.fid); +OBSOLETE +OBSOLETE childEntry->status = fetch_attr; +OBSOLETE childEntry->flags.attrp = TRUE; +OBSOLETE childEntry->flags.kernelp = TRUE; +OBSOLETE childEntry->tokens |= NNPFS_ATTR_R; +OBSOLETE volcache_update_volsync (dir_entry->volume, dir_entry->volsync); +OBSOLETE +OBSOLETE childEntry->host = rx_HostOf (rx_PeerOf (conn->connection)); +OBSOLETE assert(childEntry->host); +OBSOLETE +OBSOLETE reconnect_update_fid(childEntry, fakeFid); +OBSOLETE res = conv_dir (dir_entry, ce, 0, &cache_handle, tmp, sizeof(tmp)); +OBSOLETE +OBSOLETE out: +OBSOLETE ReleaseWriteLock(&dir_entry->lock); +OBSOLETE ReleaseWriteLock(&childEntry->lock); +OBSOLETE free_fs_server_context(&context); +OBSOLETE cred_free(ce); +OBSOLETE return ret; +OBSOLETE } +OBSOLETE +OBSOLETE #endif diff --git a/usr.sbin/afs/src/arlad/reconnect.h b/usr.sbin/afs/src/arlad/reconnect.h index 5698517e0c8..a1509a94d99 100644 --- a/usr.sbin/afs/src/arlad/reconnect.h +++ b/usr.sbin/afs/src/arlad/reconnect.h @@ -1,41 +1,41 @@ -/* COPYRIGHT (C) 1998 - * THE REGENTS OF THE UNIVERSITY OF MICHIGAN - * ALL RIGHTS RESERVED - * - * PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS - * AND REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS - * FOR ANY PURPOSE, SO LONG AS THE NAME OF THE UNIVERSITY OF - * MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY - * PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE - * WITHOUT SPECIFIC, WRITTEN PRIOR AUTHORIZATION. IF THE - * ABOVE COPYRIGHT NOTICE OR ANY OTHER IDENTIFICATION OF THE - * UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY - * PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST - * ALSO BE INCLUDED. - * - * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION - * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY - * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF - * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING - * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE - * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE - * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR - * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING - * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN - * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGES. - */ - -/* $KTH: reconnect.h,v 1.4 1999/05/29 18:43:35 assar Exp $ */ - -#ifndef _RECONNECT_H -#define _RECONNECT_H - -void -do_replay(char *log_file, int log_entries, VenusFid *changed_fid); - -VenusFid * -fid_translate(VenusFid *fid_in); - -#endif /* _RECONNECT_H */ +OBSOLETE /* COPYRIGHT (C) 1998 +OBSOLETE * THE REGENTS OF THE UNIVERSITY OF MICHIGAN +OBSOLETE * ALL RIGHTS RESERVED +OBSOLETE * +OBSOLETE * PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS +OBSOLETE * AND REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS +OBSOLETE * FOR ANY PURPOSE, SO LONG AS THE NAME OF THE UNIVERSITY OF +OBSOLETE * MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY +OBSOLETE * PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE +OBSOLETE * WITHOUT SPECIFIC, WRITTEN PRIOR AUTHORIZATION. IF THE +OBSOLETE * ABOVE COPYRIGHT NOTICE OR ANY OTHER IDENTIFICATION OF THE +OBSOLETE * UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY +OBSOLETE * PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST +OBSOLETE * ALSO BE INCLUDED. +OBSOLETE * +OBSOLETE * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION +OBSOLETE * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY +OBSOLETE * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF +OBSOLETE * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING +OBSOLETE * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF +OBSOLETE * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE +OBSOLETE * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE +OBSOLETE * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR +OBSOLETE * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING +OBSOLETE * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN +OBSOLETE * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF +OBSOLETE * SUCH DAMAGES. +OBSOLETE */ +OBSOLETE +OBSOLETE /* $arla: reconnect.h,v 1.5 2002/07/23 15:22:57 lha Exp $ */ +OBSOLETE +OBSOLETE #ifndef _RECONNECT_H +OBSOLETE #define _RECONNECT_H +OBSOLETE +OBSOLETE void +OBSOLETE do_replay(char *log_file, int log_entries, VenusFid *changed_fid); +OBSOLETE +OBSOLETE VenusFid * +OBSOLETE fid_translate(VenusFid *fid_in); +OBSOLETE +OBSOLETE #endif /* _RECONNECT_H */ diff --git a/usr.sbin/afs/src/arlad/service.h b/usr.sbin/afs/src/arlad/service.h index 64517e3fa44..dbc5ee47f8a 100644 --- a/usr.sbin/afs/src/arlad/service.h +++ b/usr.sbin/afs/src/arlad/service.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $KTH: service.h,v 1.11 2000/10/06 23:50:58 lha Exp $ */ +/* $arla: service.h,v 1.12 2002/07/24 06:05:22 lha Exp $ */ /* * Service IDs diff --git a/usr.sbin/afs/src/arlad/solaris-subr.c b/usr.sbin/afs/src/arlad/solaris-subr.c index 3d6680e7ba1..6192c9da53a 100644 --- a/usr.sbin/afs/src/arlad/solaris-subr.c +++ b/usr.sbin/afs/src/arlad/solaris-subr.c @@ -32,7 +32,7 @@ */ #include "arla_local.h" -RCSID("$KTH: solaris-subr.c,v 1.33 2000/10/27 07:44:18 lha Exp $"); +RCSID("$arla: solaris-subr.c,v 1.35 2002/03/06 21:57:02 tol Exp $"); static long blocksize = DIRBUF; @@ -62,7 +62,7 @@ flushbuf (void *vargs) (((sizeof(struct dirent64)+ (strlen(name)+1)) + \ LARGEFILE_ALIGN) & ~LARGEFILE_ALIGN) -static void +static int write_dirent(VenusFid *fid, const char *name, void *arg) { struct dirent64 *real; @@ -85,9 +85,10 @@ write_dirent(VenusFid *fid, const char *name, void *arg) args->off += real->d_reclen; real->d_off = args->off; args->last = real; + return 0; } -Result +int conv_dir (FCacheEntry *e, CredCacheEntry *ce, u_int tokens, fcache_cache_handle *cache_handle, char *cache_name, size_t cache_name_sz) diff --git a/usr.sbin/afs/src/arlad/subr.c b/usr.sbin/afs/src/arlad/subr.c index 298ef8a21ac..b7486fa87dd 100644 --- a/usr.sbin/afs/src/arlad/subr.c +++ b/usr.sbin/afs/src/arlad/subr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -32,7 +32,7 @@ */ #include "arla_local.h" -RCSID("$KTH: subr.c,v 1.7 2000/10/14 19:58:12 map Exp $"); +RCSID("$arla: subr.c,v 1.12 2002/09/07 10:43:30 lha Exp $"); /* * come up with a good inode number for `name', `fid' in `parent' @@ -64,7 +64,7 @@ dentry2ino (const char *name, const VenusFid *fid, const FCacheEntry *parent) * Assume `e' has valid data. */ -Result +int conv_dir_sub (FCacheEntry *e, CredCacheEntry *ce, u_int tokens, fcache_cache_handle *cache_handle, char *cache_name, size_t cache_name_sz, @@ -73,42 +73,37 @@ conv_dir_sub (FCacheEntry *e, CredCacheEntry *ce, u_int tokens, size_t blocksize) { struct write_dirent_args args; - Result res; int ret; int fd; fbuf the_fbuf; e->flags.extradirp = TRUE; fcache_extra_file_name (e, cache_name, cache_name_sz); - res.tokens = e->tokens |= XFS_DATA_R | XFS_OPEN_NR; + e->tokens |= NNPFS_DATA_R | NNPFS_OPEN_NR; args.fd = open (cache_name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666); if (args.fd == -1) { - res.res = -1; - res.error = errno; - arla_warn (ADEBWARN, errno, "open %s", cache_name); - return res; + ret = errno; + arla_warn (ADEBWARN, ret, "open %s", cache_name); + return ret; } ret = fcache_fhget (cache_name, cache_handle); args.off = 0; args.buf = (char *)malloc (blocksize); if (args.buf == NULL) { - arla_warn (ADEBWARN, errno, "malloc %u", (unsigned)blocksize); - res.res = -1; - res.error = errno; + ret = errno; + arla_warn (ADEBWARN, ret, "malloc %u", (unsigned)blocksize); close (args.fd); - return res; + return ret; } ret = fcache_get_fbuf (e, &fd, &the_fbuf, O_RDONLY, FBUF_READ|FBUF_PRIVATE); if (ret) { - res.res = -1; - res.error = ret; close (args.fd); free (args.buf); - return res; + return ret; } args.ptr = args.buf; @@ -116,7 +111,8 @@ conv_dir_sub (FCacheEntry *e, CredCacheEntry *ce, u_int tokens, args.e = e; args.ce = ce; - fdir_readdir (&the_fbuf, func, (void *)&args, &e->fid); + /* translate to local dir format, write in args.fd */ + fdir_readdir (&the_fbuf, func, (void *)&args, e->fid, NULL); fbuf_end (&the_fbuf); close (fd); @@ -124,8 +120,8 @@ conv_dir_sub (FCacheEntry *e, CredCacheEntry *ce, u_int tokens, if (args.last) (*flush_func) (&args); free (args.buf); - res.res = close (args.fd); - if (res.res) - res.error = errno; - return res; + ret = close (args.fd); + if (ret) + ret = errno; + return ret; } diff --git a/usr.sbin/afs/src/arlad/subr.h b/usr.sbin/afs/src/arlad/subr.h index 47bd0bbafd4..3b780d1d1f7 100644 --- a/usr.sbin/afs/src/arlad/subr.h +++ b/usr.sbin/afs/src/arlad/subr.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -35,7 +35,7 @@ * Header with prototypes for OS-specific functions. */ -/* $KTH: subr.h,v 1.11 2000/10/14 19:58:13 map Exp $ */ +/* $arla: subr.h,v 1.13 2002/07/24 06:07:04 lha Exp $ */ #ifndef _SUBR_H_ #define _SUBR_H_ @@ -59,11 +59,11 @@ struct write_dirent_args { ino_t dentry2ino (const char *name, const VenusFid *fid, const FCacheEntry *parent); -Result +int conv_dir (FCacheEntry *e, CredCacheEntry *ce, u_int tokens, fcache_cache_handle *, char *, size_t); -Result +int conv_dir_sub (FCacheEntry *e, CredCacheEntry *ce, u_int tokens, fcache_cache_handle *cache_handle, char *cache_name, size_t cache_name_sz, diff --git a/usr.sbin/afs/src/arlad/sunos-subr.c b/usr.sbin/afs/src/arlad/sunos-subr.c index 59d3ba77be3..e20a53c5549 100644 --- a/usr.sbin/afs/src/arlad/sunos-subr.c +++ b/usr.sbin/afs/src/arlad/sunos-subr.c @@ -33,7 +33,7 @@ #define _KERNEL #include "arla_local.h" -RCSID("$KTH: sunos-subr.c,v 1.30 2000/10/14 19:58:14 map Exp $"); +RCSID("$arla: sunos-subr.c,v 1.32 2002/03/06 21:57:04 tol Exp $"); static long blocksize = 1024; /* XXX */ @@ -52,7 +52,7 @@ flushbuf (void *vargs) args->last = NULL; } -static void +static int write_dirent(VenusFid *fid, const char *name, void *arg) { struct dirent dirent, *real; @@ -73,9 +73,10 @@ write_dirent(VenusFid *fid, const char *name, void *arg) args->off += real->d_reclen; real->d_off = args->off; args->last = real; + return 0; } -Result +int conv_dir (FCacheEntry *e, CredCacheEntry *ce, u_int tokens, fcache_cache_handle *cache_handle, char *cache_name, size_t cache_name_sz) diff --git a/usr.sbin/afs/src/arlad/unknown-subr.c b/usr.sbin/afs/src/arlad/unknown-subr.c index b782f05b17e..a373c9f181c 100644 --- a/usr.sbin/afs/src/arlad/unknown-subr.c +++ b/usr.sbin/afs/src/arlad/unknown-subr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2003 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -32,7 +32,12 @@ */ #include "arla_local.h" -RCSID("$KTH: unknown-subr.c,v 1.9 2000/10/14 19:58:15 map Exp $"); + +#ifdef __CYGWIN32__ +#include <windows.h> +#endif + +RCSID("$arla: unknown-subr.c,v 1.13 2003/01/10 03:05:49 lha Exp $"); int dir_remove_name (FCacheEntry *e, const char *filename, @@ -42,14 +47,16 @@ dir_remove_name (FCacheEntry *e, const char *filename, return 0; } - -Result +int conv_dir (FCacheEntry *e, CredCacheEntry *ce, u_int tokens, fcache_cache_handle *cache_handle, char *cache_name, size_t cache_name_sz) { - Result res; + + assert (e->status.FileType == TYPE_DIR); - res.res = 0; - return res; + fcache_conv_file_name(e, cache_name, cache_name_sz); + + e->tokens |= NNPFS_DATA_R | NNPFS_OPEN_NR; + return 0; } diff --git a/usr.sbin/afs/src/arlad/volcache.c b/usr.sbin/afs/src/arlad/volcache.c index dd5ff49fae5..cbccbf48b72 100644 --- a/usr.sbin/afs/src/arlad/volcache.c +++ b/usr.sbin/afs/src/arlad/volcache.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -36,7 +36,9 @@ */ #include "arla_local.h" -RCSID("$KTH: volcache.c,v 1.95.2.4 2001/03/04 05:11:19 lha Exp $") ; +RCSID("$arla: volcache.c,v 1.116 2003/04/10 15:49:13 lha Exp $") ; + +static int volcache_timeout = VOLCACHE_TIMEOUT; static const char *root_volume_name = "root.afs"; @@ -181,9 +183,11 @@ create_new_entries (unsigned n) VolCacheEntry *entries; int i; - entries = (VolCacheEntry *)calloc (n, sizeof(VolCacheEntry)); + entries = (VolCacheEntry *)malloc (n * sizeof(VolCacheEntry)); if (entries == NULL) - arla_errx (1, ADEBERROR, "volcache: calloc failed"); + arla_errx (1, ADEBERROR, "volcache: malloc failed"); + memset(entries, 0, n * sizeof(VolCacheEntry)); + for (i = 0; i < n; ++i) { entries[i].cell = -1; entries[i].li = listaddtail (lrulist, &entries[i]); @@ -234,6 +238,7 @@ recycle_entry (VolCacheEntry *e) memset (&e->volsync, 0, sizeof(e->volsync)); e->flags.validp = FALSE; e->flags.stablep = FALSE; + memset (&e->status, 0, sizeof(e->status)); memset (&e->name_ptr, 0, sizeof(e->name_ptr)); memset (&e->num_ptr, 0, sizeof(e->num_ptr)); } @@ -276,12 +281,69 @@ get_free_entry (void) */ static Bool +clones_exists (VolCacheEntry *e) +{ + int i; + + for (i = 0; i < MAXTYPES; ++i) + if (e->num_ptr[i].ptr != NULL) + return TRUE; + return FALSE; +} + +/* + * + */ + +void +volcache_process_marks (VolCacheEntry *ve) +{ + int i, status, inval; + + inval = 0; + + for (i = 0; i < ve->entry.nServers; i++) { + status = ve->status[i]; + if (status & (VOLCACHE_NOVOL|VOLCACHE_UNAVAILABLE)) { + /* already checked ? */ + if (status & VOLCACHE_CHECKED) + continue; + ve->status[i] |= VOLCACHE_CHECKED; + if (ve->flags.stablep) + inval = 1; + } + } + if (inval) + volcache_invalidate_ve(ve); +} + +/* + * + */ + +static void +volcache_remove_marks (VolCacheEntry *ve) +{ + int i; + + for (i = 0; i < NMAXNSERVERS; i++) + ve->status[i] = 0; +} + +/* + * + */ + +static Bool volume_uptodatep (VolCacheEntry *e) { if (connected_mode != CONNECTED) - return TRUE; + return e->flags.validp ? TRUE : FALSE; - return e->flags.validp; + if (time(NULL) > e->timeout) + return FALSE; + + return e->flags.validp && clones_exists(e) == TRUE; } /* @@ -289,7 +351,7 @@ volume_uptodatep (VolCacheEntry *e) */ static VolCacheEntry * -getbyid (u_int32_t volid, int32_t cell, int *type) +getbyid (uint32_t volid, int32_t cell, int *type) { struct num_ptr *n; struct num_ptr key; @@ -310,7 +372,7 @@ getbyid (u_int32_t volid, int32_t cell, int *type) */ static VolCacheEntry * -getbyname (const char *volname, int32_t cell, int *type) +getbyname (const char *volname, int32_t cell) { struct name_ptr *n; struct name_ptr key; @@ -325,83 +387,186 @@ getbyname (const char *volname, int32_t cell, int *type) } /* + * Add a clone to `e' of type `type' with suffix `slot_type' in slot + * slot_type + */ + +static void +add_clone (VolCacheEntry *e, int type) +{ + struct num_ptr *num_ptr = &e->num_ptr[type]; + + num_ptr->cell = e->cell; + num_ptr->vol = e->entry.volumeId[type]; + num_ptr->ptr = e; + num_ptr->type = type; + hashtabadd (volidhashtab, (void *) num_ptr); +} + +/* + * Add all types of the volume entry `e' to volid hashtable. If there + * isn't a RW volume, use the RO as the RW. + */ + +static void +add_clones_to_hashtab (VolCacheEntry *e) +{ + if (e->entry.flags & VLF_RWEXISTS) + add_clone (e, RWVOL); + if (e->entry.flags & VLF_ROEXISTS) + add_clone (e, ROVOL); + if (e->entry.flags & VLF_BOEXISTS) + add_clone (e, BACKVOL); +} + +/* * */ static void -volcache_recover_state (void) +remove_clone (VolCacheEntry *e, int type) { - int fd; - VolCacheEntry tmp; - unsigned n; - u_int32_t u1, u2; - Listitem *item; + struct num_ptr *num_ptr = &e->num_ptr[type]; - fd = open ("volcache", O_RDONLY | O_BINARY, 0); - if (fd < 0) - return; - if (read (fd, &u1, sizeof(u1)) != sizeof(u1) - || read (fd, &u2, sizeof(u2)) != sizeof(u2)) { - close (fd); - return; - } - if (u1 != VOLCACHE_MAGIC_COOKIE) { - arla_warnx (ADEBVOLCACHE, "dump file not recognized, ignoring"); - close (fd); - return; - } - if (u2 != VOLCACHE_VERSION) { - arla_warnx (ADEBVOLCACHE, "unknown dump file version number %u", u2); - close (fd); - return; + if (num_ptr->ptr) { + hashtabdel (volidhashtab, (void *) num_ptr); + num_ptr->ptr = NULL; } +} - n = 0; - while (read (fd, &tmp, sizeof(tmp)) == sizeof(tmp)) { - VolCacheEntry *e = get_free_entry (); - int i; - - ++n; - - e->entry = tmp.entry; - e->volsync = tmp.volsync; - e->cell = tmp.cell; - e->refcount = tmp.refcount; - e->vol_refs = 0; - e->mp_fid = tmp.mp_fid; - e->parent_fid = tmp.parent_fid; - e->parent = NULL; - if (tmp.name_ptr.ptr != NULL) { - e->name_ptr.cell = tmp.name_ptr.cell; - strlcpy (e->name_ptr.name, tmp.name_ptr.name, - sizeof(e->name_ptr.name)); - e->name_ptr.ptr = e; - hashtabadd (volnamehashtab, (void *)&e->name_ptr); - } +static void +remove_clones_from_hashtab (VolCacheEntry *e) +{ + int i; + for (i = 0; i < MAXTYPES; ++i) + remove_clone(e, i); +} - for (i = 0; i < MAXTYPES; ++i) { - if (tmp.num_ptr[i].ptr != NULL) { - e->num_ptr[i].cell = tmp.num_ptr[i].cell; - e->num_ptr[i].vol = tmp.num_ptr[i].vol; - e->num_ptr[i].ptr = e; - hashtabadd (volidhashtab, (void *)&e->num_ptr[i]); - } - } - e->flags.validp = FALSE; - e->flags.stablep = FALSE; +/* + * + */ + +static void +add_name_to_hashtab (VolCacheEntry *e) +{ + e->name_ptr.cell = e->cell; + strlcpy (e->name_ptr.name, e->entry.name, sizeof(e->name_ptr.name)); + e->name_ptr.ptr = e; + hashtabadd (volnamehashtab, (void *)&e->name_ptr); +} + +/* + * + */ + + +static void +update_entry(VolCacheEntry *e, nvldbentry *entry) +{ + e->flags.stablep = cmp_nvldbentry (entry, &e->entry) == 0; + e->flags.validp = TRUE; + e->entry = *entry; + + if (e->flags.stablep == FALSE) { + volcache_remove_marks (e); + remove_clones_from_hashtab (e); + add_clones_to_hashtab (e); } +} + +/* + * + */ + +struct vstore_context { + Listitem *item; + unsigned n; +}; + +/* + * + */ + +static int +volcache_recover_entry (struct volcache_store *st, void *ptr) +{ + VolCacheEntry *e = get_free_entry (); + struct vstore_context *c = (struct vstore_context *)ptr; + + e->cell = cell_name2num (st->cell); + assert (e->cell != -1); + e->entry = st->entry; + e->volsync = st->volsync; + e->refcount = st->refcount; + + add_name_to_hashtab (e); + add_clones_to_hashtab (e); + + c->n++; + + return 0; +} + +/* + * + */ + +static void +volcache_recover_state (void) +{ + struct vstore_context c; + Listitem *item; + + c.n = 0; + c.item = NULL; + + state_recover_volcache ("volcache", volcache_recover_entry, &c); + for(item = listhead (lrulist); item; item = listnext (lrulist, item)) { VolCacheEntry *e = (VolCacheEntry *)listdata(item); - VolCacheEntry *parent = getbyid (e->parent_fid.fid.Volume, - e->parent_fid.Cell, - NULL); + VolCacheEntry *parent; + + if (e->cell == -1) + continue; + + parent = getbyid (e->parent_fid.fid.Volume, + e->parent_fid.Cell, + NULL); if (parent != NULL) volcache_volref (e, parent); } - close (fd); - arla_warnx (ADEBVOLCACHE, "recovered %u entries to volcache", n); + arla_warnx (ADEBVOLCACHE, "recovered %u entries to volcache", c.n); +} + +/* + * + */ + +static int +volcache_store_entry (struct volcache_store *st, void *ptr) +{ + struct vstore_context *c; + VolCacheEntry *e; + + c = (struct vstore_context *)ptr; + if (c->item == NULL) /* check if done ? */ + return STORE_DONE; + + e = (VolCacheEntry *)listdata (c->item); + c->item = listprev (lrulist, c->item); + + if (e->cell == -1) + return STORE_SKIP; + + strlcpy(st->cell, cell_num2name(e->cell), sizeof(st->cell)); + st->entry = e->entry; + st->volsync = e->volsync; + st->refcount = e->refcount; + + c->n++; + return STORE_NEXT; } /* @@ -411,44 +576,17 @@ volcache_recover_state (void) int volcache_store_state (void) { - Listitem *item; - int fd; - unsigned n; - u_int32_t u1, u2; - - fd = open ("volcache.new", O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666); - if (fd < 0) - return errno; - u1 = VOLCACHE_MAGIC_COOKIE; - u2 = VOLCACHE_VERSION; - if (write (fd, &u1, sizeof(u1)) != sizeof(u1) - || write (fd, &u2, sizeof(u2)) != sizeof(u2)) { - int save_errno = errno; - - close (fd); - return save_errno; - } - n = 0; - for (item = listtail (lrulist); - item; - item = listprev (lrulist, item)) { - VolCacheEntry *entry = (VolCacheEntry *)listdata (item); + struct vstore_context c; + int ret; - if (entry->cell == -1) - continue; - if (write (fd, entry, sizeof(*entry)) != sizeof(*entry)) { - close (fd); - return errno; - } - ++n; - } + c.item = listtail (lrulist); + c.n = 0; - if(close (fd)) - return errno; - if (rename ("volcache.new", "volcache")) - return errno; - - arla_warnx (ADEBVOLCACHE, "wrote %u entries to volcache", n); + ret = state_store_volcache("volcache", volcache_store_entry, &c); + if (ret) + arla_warn(ADEBWARN, ret, "failed to store volcache state"); + else + arla_warnx (ADEBVOLCACHE, "wrote %u entries to volcache", c.n); return 0; } @@ -479,72 +617,32 @@ volcache_init (unsigned nentries, Bool recover) } /* - * Add a clone to `e' of type `type' with suffix `slot_type' in slot - * slot_type - */ - -static void -add_clone (VolCacheEntry *e, int type, int suffix_type) -{ - struct num_ptr *num_ptr = &e->num_ptr[type]; - - if (type == suffix_type) { - num_ptr->cell = e->cell; - num_ptr->vol = e->entry.volumeId[type]; - num_ptr->ptr = e; - num_ptr->type = type; - hashtabadd (volidhashtab, (void *) num_ptr); - } -} - -/* - * - */ - -static void -add_to_hashtab (VolCacheEntry *e) -{ - e->name_ptr.cell = e->cell; - strlcpy (e->name_ptr.name, e->entry.name, sizeof(e->name_ptr.name)); - e->name_ptr.ptr = e; - hashtabadd (volnamehashtab, (void *)&e->name_ptr); - - if (e->entry.flags & VLF_RWEXISTS) - add_clone (e, RWVOL, RWVOL); - else - add_clone (e, ROVOL, RWVOL); - if (e->entry.flags & VLF_ROEXISTS) - add_clone (e, ROVOL, ROVOL); - if (e->entry.flags & VLF_BOEXISTS) - add_clone (e, BACKVOL, BACKVOL); -} - -/* * */ static int -get_info_common (VolCacheEntry *e) +get_info_common (VolCacheEntry *e, nvldbentry *entry) { - if (e->entry.flags & VLF_DFSFILESET) + if (entry->flags & VLF_DFSFILESET) arla_warnx (ADEBWARN, "get_info: %s is really a DFS volume. " "This might not work", - e->entry.name); - - if ((e->entry.volumeId[RWVOL] == e->entry.volumeId[ROVOL] && - e->entry.flags & VLF_RWEXISTS && e->entry.flags & VLF_ROEXISTS) || - (e->entry.volumeId[ROVOL] == e->entry.volumeId[BACKVOL] && - e->entry.flags & VLF_ROEXISTS && e->entry.flags & VLF_BOEXISTS) || - (e->entry.volumeId[RWVOL] == e->entry.volumeId[BACKVOL] && - e->entry.flags & VLF_RWEXISTS && e->entry.flags & VLF_BOEXISTS)) { + entry->name); + + if ((entry->volumeId[RWVOL] == entry->volumeId[ROVOL] && + entry->flags & VLF_RWEXISTS && entry->flags & VLF_ROEXISTS) || + (entry->volumeId[ROVOL] == entry->volumeId[BACKVOL] && + entry->flags & VLF_ROEXISTS && entry->flags & VLF_BOEXISTS) || + (entry->volumeId[RWVOL] == entry->volumeId[BACKVOL] && + entry->flags & VLF_RWEXISTS && entry->flags & VLF_BOEXISTS)) { - arla_warnx (ADEBERROR, "get_info: same id on diffrent volumes: %s", - e->entry.name); - return -1; + arla_warnx (ADEBERROR, "get_info: same id on different volumes: %s", + entry->name); + return ENOENT; } e->flags.validp = TRUE; + e->timeout = volcache_timeout + time(NULL); return 0; } @@ -561,12 +659,14 @@ vl_probe (struct rx_connection *conn) /* * Get all the db servers for `e->cell', sort them in order by rtt * (with some fuzz) and try to retrieve the entry for `name'. + * Fill in the vldb entry in `entry'. * * Return 0 if succesful, else error. */ static int -get_info_loop (VolCacheEntry *e, const char *name, int32_t cell, +get_info_loop (VolCacheEntry *e, nvldbentry *entry, + const char *name, int32_t cell, CredCacheEntry *ce) { const cell_db_entry *db_servers; @@ -578,9 +678,12 @@ get_info_loop (VolCacheEntry *e, const char *name, int32_t cell, Bool try_again; if (dynroot_isvolumep (cell, name)) { - dynroot_fetch_vldbN (&e->entry); + dynroot_fetch_root_vldbN (entry); return 0; } + + if (connected_mode == DISCONNECTED) + return ENETDOWN; db_servers = cell_dbservers_by_id (cell, &num_db_servers); if (db_servers == NULL || num_db_servers == 0) { @@ -601,11 +704,12 @@ get_info_loop (VolCacheEntry *e, const char *name, int32_t cell, conn = conn_get (cell, db_servers[i].addr.s_addr, afsvldbport, VLDB_SERVICE_ID, vl_probe, ce); - if (conn != NULL) { - conn->rtt = rx_PeerOf(conn->connection)->rtt + if (conn_isalivep (conn)) + conn->rtt = rx_PeerOf(conn->connection)->srtt + rand() % RTT_FUZZ - RTT_FUZZ / 2; - conns[j++] = conn; - } + else + conn->rtt = INT_MAX / 2; + conns[j++] = conn; } num_working_db_servers = j; @@ -619,19 +723,18 @@ get_info_loop (VolCacheEntry *e, const char *name, int32_t cell, retry: if (try_again) { if (conns[i]->flags.old) { - vldbentry entry; + vldbentry oldentry; error = VL_GetEntryByName (conns[i]->connection, - name, &entry); + name, &oldentry); if (error == 0) - vldb2vldbN(&entry, &e->entry); + vldb2vldbN(&oldentry, entry); } else error = VL_GetEntryByNameN (conns[i]->connection, - name, &e->entry); + name, entry); switch (error) { case 0 : - sanitize_nvldbentry (&e->entry); + sanitize_nvldbentry (entry); try_again = FALSE; - e->last_fetch = time(NULL); break; case VL_NOENT : error = ENOENT; @@ -643,6 +746,8 @@ get_info_loop (VolCacheEntry *e, const char *name, int32_t cell, break; case RXKADSEALEDINCON: case RXKADUNKNOWNKEY: + case RXKADBADTICKET: + case RXKADBADKEY: try_again = FALSE; break; #endif @@ -685,17 +790,18 @@ get_info_loop (VolCacheEntry *e, const char *name, int32_t cell, */ static int -get_info_byid (VolCacheEntry *e, u_int32_t id, int32_t cell, +get_info_byid (VolCacheEntry *e, nvldbentry *entry, + uint32_t id, int32_t cell, CredCacheEntry *ce) { int error; char s[11]; snprintf (s, sizeof(s), "%u", id); - error = get_info_loop (e, s, cell, ce); + error = get_info_loop (e, entry, s, cell, ce); if (error) return error; - return get_info_common (e); + return get_info_common (e, entry); } @@ -705,12 +811,13 @@ get_info_byid (VolCacheEntry *e, u_int32_t id, int32_t cell, */ static int -get_info_byname (VolCacheEntry *e, const char *volname, int32_t cell, +get_info_byname (VolCacheEntry *e, nvldbentry *entry, + const char *volname, int32_t cell, CredCacheEntry *ce) { int error; - error = get_info_loop (e, volname, cell, ce); + error = get_info_loop (e, entry, volname, cell, ce); if (error) return error; @@ -720,13 +827,13 @@ get_info_byname (VolCacheEntry *e, const char *volname, int32_t cell, * we're not going to be able to find the volume in question. */ - if (strcmp(volname, e->entry.name) != 0) { + if (strcmp(volname, entry->name) != 0) { arla_warnx (ADEBWARN, "get_info: different volnames: %s - %s", - volname, e->entry.name); + volname, entry->name); - if (strlcpy (e->entry.name, volname, - sizeof(e->entry.name)) >= sizeof(e->entry.name)) { + if (strlcpy (entry->name, volname, + sizeof(entry->name)) >= sizeof(entry->name)) { arla_warnx (ADEBWARN, "get_info: too long volume (%.*s)", (int)strlen(volname), volname); @@ -734,7 +841,7 @@ get_info_byname (VolCacheEntry *e, const char *volname, int32_t cell, } } - return get_info_common (e); + return get_info_common (e, entry); } /* @@ -750,40 +857,24 @@ add_entry_byname (VolCacheEntry **ret, const char *volname, e = get_free_entry (); - e->cell = cell; - e->refcount = 0; - e->vol_refs = 0; + e->cell = cell; + e->refcount = 0; + e->vol_refs = 0; + e->flags.lookupp = 1; + strlcpy(e->entry.name, volname, sizeof(e->entry.name)); + + add_name_to_hashtab (e); - error = get_info_byname (e, volname, cell, ce); + error = get_info_byname (e, &e->entry, volname, cell, ce); if (error == 0) { - add_to_hashtab (e); *ret = e; + add_clones_to_hashtab (e); } - return error; -} - -/* - * Add an entry for (volname, cell) to the hash table. - */ - -static int -add_entry_byid (VolCacheEntry **ret, u_int32_t id, - int32_t cell, CredCacheEntry *ce) -{ - int error; - VolCacheEntry *e; - e = get_free_entry (); - - e->cell = cell; - e->refcount = 0; - e->vol_refs = 0; + e->flags.lookupp = 0; + if (e->flags.waiting) + LWP_NoYieldSignal (e); - error = get_info_byid (e, id, cell, ce); - if (error == 0) { - add_to_hashtab (e); - *ret = e; - } return error; } @@ -794,79 +885,116 @@ add_entry_byid (VolCacheEntry **ret, u_int32_t id, int volcache_getbyname (const char *volname, int32_t cell, CredCacheEntry *ce, - VolCacheEntry **e, int *type) + VolCacheEntry **e, int *ret_type) { - int error = 0; + int type, error; char real_volname[VLDB_MAXNAMELEN]; strlcpy (real_volname, volname, sizeof(real_volname)); - *type = volname_canonicalize (real_volname); + type = volname_canonicalize (real_volname); + if (ret_type) + *ret_type = type; for(;;) { - *e = getbyname (real_volname, cell, type); + *e = getbyname (real_volname, cell); if (*e == NULL) { error = add_entry_byname (e, real_volname, cell, ce); if (error) return error; continue; } - - volcache_ref (*e); - if (volume_uptodatep (*e)) { - return 0; - } else { - VolCacheEntry tmp_ve; - error = get_info_byname (&tmp_ve, real_volname, cell, ce); - if (error) { + if ((*e)->flags.lookupp) { + (*e)->flags.waiting = 1; + volcache_ref (*e); + LWP_WaitProcess (*e); + if (!(*e)->flags.validp) { volcache_free (*e); - return error; + return ENOENT; } - (*e)->flags.stablep = cmp_nvldbentry (&tmp_ve.entry, - &(*e)->entry) == 0; - (*e)->flags.validp = TRUE; - (*e)->entry = tmp_ve.entry; + } else + volcache_ref (*e); + + if (volume_uptodatep (*e)) { + error = 0; + break; + } else { + nvldbentry tmp_e; + + error = get_info_byname (*e, &tmp_e, real_volname, cell, ce); + if (error) + break; + update_entry(*e, &tmp_e); + break; } } + + if (error) + (*e)->flags.validp = 0; + if ((*e)->flags.waiting) + LWP_NoYieldSignal (*e); + (*e)->flags.lookupp = 0; + (*e)->flags.waiting = 0; + if (error) { + volcache_free (*e); + *e = NULL; + } + return error; } /* * Retrieve the entry for (volume-id, cell). If it's not in the cache, - * add it. + * there is no good way of adding it, and thus fail. */ int -volcache_getbyid (u_int32_t volid, int32_t cell, CredCacheEntry *ce, +volcache_getbyid (uint32_t volid, int32_t cell, CredCacheEntry *ce, VolCacheEntry **e, int *type) { int error = 0; for(;;) { *e = getbyid (volid, cell, type); - if (*e == NULL) { - error = add_entry_byid (e, volid, cell, ce); - if (error) - return error; - continue; - } - volcache_ref(*e); + if (*e == NULL) + return ENOENT; + + if ((*e)->flags.lookupp) { + (*e)->flags.waiting = 1; + volcache_ref (*e); + LWP_WaitProcess (*e); + if (!(*e)->flags.validp) { + volcache_free (*e); + return ENOENT; + } + } else + volcache_ref (*e); + if (volume_uptodatep (*e)) { - return 0; + error = 0; + break; } else { - VolCacheEntry tmp_ve; + nvldbentry tmp_e; - error = get_info_byid (&tmp_ve, volid, cell, ce); - if (error) { - volcache_free(*e); - return error; - } - (*e)->flags.stablep = cmp_nvldbentry (&tmp_ve.entry, - &(*e)->entry) == 0; - (*e)->flags.validp = TRUE; - (*e)->entry = tmp_ve.entry; + error = get_info_byid (*e, &tmp_e, volid, cell, ce); + if (error) + break; + update_entry(*e, &tmp_e); + break; } } -} + if (error) + (*e)->flags.validp = 0; + if ((*e)->flags.waiting) + LWP_NoYieldSignal (*e); + (*e)->flags.lookupp = 0; + (*e)->flags.waiting = 0; + if (error) { + volcache_free (*e); + *e = NULL; + } + return error; +} + /* * Invalidate the volume entry `ve' */ @@ -878,6 +1006,25 @@ volcache_invalidate_ve (VolCacheEntry *ve) ve->flags.stablep = FALSE; } +static Bool +inval (void *ptr, void *arg) +{ + struct num_ptr *n = (struct num_ptr *)ptr; + VolCacheEntry *e = n->ptr; + + volcache_invalidate_ve (e); + return FALSE; +} + +/* + * Invalidate all volume entries + */ + +void +volcache_invalidate_all (void) +{ + hashtabforeach (volidhashtab, inval, NULL); +} /* * invalidate this volume if id == data->id @@ -886,7 +1033,7 @@ volcache_invalidate_ve (VolCacheEntry *ve) static Bool invalidate_vol (void *ptr, void *arg) { - u_int32_t id = *((u_int32_t *)arg); + uint32_t id = *((uint32_t *)arg); struct num_ptr *n = (struct num_ptr *)ptr; VolCacheEntry *e = n->ptr; @@ -902,7 +1049,7 @@ invalidate_vol (void *ptr, void *arg) */ void -volcache_invalidate (u_int32_t id, int32_t cell) +volcache_invalidate (uint32_t id, int32_t cell) { if (cell == -1) { hashtabforeach (volidhashtab, invalidate_vol, &id); @@ -914,18 +1061,81 @@ volcache_invalidate (u_int32_t id, int32_t cell) } /* + * + */ + +Bool +volume_downp (int error) +{ + switch (error) { + case ARLA_VNOVOL: + case ARLA_VMOVED: + return TRUE; + default: + return FALSE; + } +} + +/* + * + */ + +void +volcache_mark_down (VolCacheEntry *ve, int i, int error) +{ + int type; + + assert(i < NMAXNSERVERS && i < ve->entry.nServers); + + switch (error) { + case ARLA_VNOVOL: + case ARLA_VMOVED: + type = VOLCACHE_NOVOL; + break; + default: + type = VOLCACHE_UNAVAILABLE; + break; + } + + ve->status[i] |= type; +} + + +/* + * + */ + +Bool +volcache_reliablep_el (VolCacheEntry *ve, int i) +{ + assert(i < NMAXNSERVERS && i < ve->entry.nServers); + + if (ve->status[i] == 0) + return TRUE; + return FALSE; +} + +void +volcache_reliable_el (VolCacheEntry *ve, int i) +{ + assert(i < NMAXNSERVERS && i < ve->entry.nServers); + ve->status[i] = 0; +} + +/* * Return TRUE if this should be considered reliable (if it's validp, * stablep and fresh). */ Bool -volcache_reliable (u_int32_t id, int32_t cell) +volcache_reliablep (uint32_t id, int32_t cell) { VolCacheEntry *e = getbyid (id, cell, NULL); return e != NULL - && e->flags.validp && e->flags.stablep - && (time(NULL) - e->last_fetch) < VOLCACHE_OLD; + && e->flags.validp + && e->flags.stablep + && time(NULL) < e->timeout; } /* @@ -1034,11 +1244,17 @@ print_entry (void *ptr, void *arg) int volume_make_uptodate (VolCacheEntry *e, CredCacheEntry *ce) { + nvldbentry tmp_e; + int ret; + if (connected_mode != CONNECTED || volume_uptodatep (e)) return 0; - return get_info_byname (e, e->entry.name, e->cell, ce); + ret = get_info_byname (e, &tmp_e, e->entry.name, e->cell, ce); + if (ret == 0) + update_entry(e, &tmp_e); + return ret; } /* @@ -1047,7 +1263,7 @@ volume_make_uptodate (VolCacheEntry *e, CredCacheEntry *ce) */ int -volcache_getname (u_int32_t id, int32_t cell, +volcache_getname (uint32_t id, int32_t cell, char *name, size_t name_sz) { int type; @@ -1065,7 +1281,7 @@ volcache_getname (u_int32_t id, int32_t cell, */ int -volcache_volid2bit (const VolCacheEntry *ve, u_int32_t volid) +volcache_volid2bit (const VolCacheEntry *ve, uint32_t volid) { int bit = -1; diff --git a/usr.sbin/afs/src/arlad/volcache.h b/usr.sbin/afs/src/arlad/volcache.h index d923587ebca..4032bf9df0c 100644 --- a/usr.sbin/afs/src/arlad/volcache.h +++ b/usr.sbin/afs/src/arlad/volcache.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -35,7 +35,7 @@ * Our cache of volume information. */ -/* $KTH: volcache.h,v 1.28.2.2 2001/02/12 12:53:02 assar Exp $ */ +/* $arla: volcache.h,v 1.36 2002/05/15 22:31:16 lha Exp $ */ #ifndef _VOLCACHE_ #define _VOLCACHE_ @@ -51,7 +51,7 @@ struct num_ptr { int32_t cell; - u_int32_t vol; + uint32_t vol; struct volcacheentry *ptr; int32_t type; }; @@ -72,7 +72,6 @@ struct volcacheentry { int32_t cell; unsigned refcount; /* number of files refererring this */ unsigned vol_refs; /* number of volumes refing this */ - time_t last_fetch; Listitem *li; VenusFid mp_fid; /* pointing to this volume */ VenusFid parent_fid; /* .. of this volume */ @@ -80,26 +79,21 @@ struct volcacheentry { struct { unsigned validp : 1; unsigned stablep : 1; + unsigned lookupp : 1; + unsigned waiting : 1; } flags; struct name_ptr name_ptr; struct num_ptr num_ptr[MAXTYPES]; + time_t timeout; + int status[NMAXNSERVERS]; }; -typedef struct volcacheentry VolCacheEntry; - -/* - * This is magic cookie for the dump of the volcache. - * It's supposed not to be able to be confused with an old-style - * dump (with no header) - */ - -#define VOLCACHE_MAGIC_COOKIE 0x00120100 - -/* - * current version number of the dump file - */ +enum { VOLCACHE_NOVOL = 1, /* server claim there is no volume */ + VOLCACHE_UNAVAILABLE = 2, /* server failed to respond */ + VOLCACHE_CHECKED = 4 /* error-condition already processed */ +}; -#define VOLCACHE_VERSION 0x3 +typedef struct volcacheentry VolCacheEntry; const char *volcache_get_rootvolume (void); @@ -113,7 +107,7 @@ int volcache_getbyname (const char *volname, VolCacheEntry **e, int *type); -int volcache_getbyid (u_int32_t id, +int volcache_getbyid (uint32_t id, int32_t cell, CredCacheEntry *ce, VolCacheEntry **e, @@ -129,15 +123,26 @@ void volcache_volref (VolCacheEntry *e, VolCacheEntry *parent); void volcache_volfree (VolCacheEntry *e); -void volcache_invalidate (u_int32_t id, int32_t cell); +void volcache_invalidate (uint32_t id, int32_t cell); void volcache_invalidate_ve (VolCacheEntry *ve); +void volcache_invalidate_all (void); + int volume_make_uptodate (VolCacheEntry *e, CredCacheEntry *ce); -Bool volcache_reliable (u_int32_t id, int32_t cell); +Bool volume_downp (int error); + +void volcache_mark_down (VolCacheEntry *ve, int i, int error); -int volcache_getname (u_int32_t id, int32_t cell, char *, size_t); +void volcache_process_marks (VolCacheEntry *e); + +Bool volcache_reliablep_el (VolCacheEntry *ve, int i); +Bool volcache_reliablep (uint32_t id, int32_t cell); + +int volcache_getname (uint32_t id, int32_t cell, char *, size_t); + +void volcache_reliable_el (VolCacheEntry *ve, int i); void volcache_status (void); @@ -145,8 +150,10 @@ int volcache_store_state (void); int -volcache_volid2bit (const VolCacheEntry *ve, u_int32_t volid); +volcache_volid2bit (const VolCacheEntry *ve, uint32_t volid); enum { VOLCACHE_OLD = 120 }; +enum { VOLCACHE_TIMEOUT = 600 }; + #endif /* _VOLCACHE_ */ |