From: Sam Hartman Date: Sun, 14 Oct 2001 18:43:31 +0000 (+0000) Subject: Merge conflicts X-Git-Tag: debian/1.2.2-1~5 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=96253cd278aa1a6992ed9a888d12e26eb8e0de1a;p=packages%2Fo%2Fopenafs.git Merge conflicts --- diff --git a/Makefile.in b/Makefile.in index 37ddfb1bc..3297bdb43 100644 --- a/Makefile.in +++ b/Makefile.in @@ -308,7 +308,9 @@ login: project kauth rxkad alpha_dux* ) \ ${COMPILE_PART1} sia ${COMPILE_PART2} ;; \ sun4x_55 ) \ - ${COMPILE_PART1} login ${COMPILE_PART2} ;; \ + ${COMPILE_PART1} login ${COMPILE_PART2} ;; \ + parisc_linux24) \ + echo Skipping pam/login for parisc_linux24 ;; \ sun4x_* | hp_ux11* | *linux* | *fbsd* ) \ ${COMPILE_PART1} pam ${COMPILE_PART2} ;; \ ppc_darwin* | *_obsd* ) \ @@ -368,6 +370,11 @@ libafs_tree: libafs_setup ${KERNELDIR} ${INSTALL} -c src/config/Makefile.${SYS_NAME}.in libafs_tree/config ${INSTALL} -c src/config/afsconfig.h.in libafs_tree/config ${INSTALL} -c -f -ns configure-libafs libafs_tree/configure + case ${SYS_NAME} in \ + *linux*) \ + ${INSTALL} -c src/config/make_vnode.pl libafs_tree/config ; \ + ${INSTALL} -c src/afs/LINUX/osi_vfs.hin libafs_tree/afs ;; \ + esac libuafs: libuafs_setup ${UKERNELDIR} set -x; \ diff --git a/src/afs/LINUX/osi_module.c b/src/afs/LINUX/osi_module.c index f04fcd8b6..1282877b4 100644 --- a/src/afs/LINUX/osi_module.c +++ b/src/afs/LINUX/osi_module.c @@ -14,7 +14,7 @@ #include #include "../afs/param.h" -RCSID("$Header: /tmp/cvstemp/openafs/src/afs/LINUX/osi_module.c,v 1.7 2001/09/11 15:47:37 hartmans Exp $"); +RCSID("$Header: /tmp/cvstemp/openafs/src/afs/LINUX/osi_module.c,v 1.8 2001/10/14 18:43:26 hartmans Exp $"); #include "../afs/sysincludes.h" #include "../afs/afsincludes.h" @@ -320,7 +320,7 @@ module_exit(afs_cleanup); static long get_page_offset(void) { -#if defined(AFS_PPC_LINUX22_ENV) || defined(AFS_SPARC64_LINUX20_ENV) || defined(AFS_SPARC_LINUX20_ENV) || defined(AFS_ALPHA_LINUX20_ENV) || defined(AFS_S390_LINUX22_ENV) || defined(AFS_IA64_LINUX20_ENV) +#if defined(AFS_PPC_LINUX22_ENV) || defined(AFS_SPARC64_LINUX20_ENV) || defined(AFS_SPARC_LINUX20_ENV) || defined(AFS_ALPHA_LINUX20_ENV) || defined(AFS_S390_LINUX22_ENV) || defined(AFS_IA64_LINUX20_ENV) || defined(AFS_PARISC_LINUX24_ENV) return PAGE_OFFSET; #else struct task_struct *p; diff --git a/src/afs/LINUX/osi_vfs.h b/src/afs/LINUX/osi_vfs.h deleted file mode 100644 index b5f92e125..000000000 --- a/src/afs/LINUX/osi_vfs.h +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright 2000, International Business Machines Corporation and others. - * All Rights Reserved. - * - * This software has been released under the terms of the IBM Public - * License. For details, see the LICENSE file in the top-level source - * directory or online at http://www.openafs.org/dl/license10.html - */ - -/* - * Linux interpretations of vnode and vfs structs. - * - * The Linux "inode" has been abstracted to the fs independent part to avoid - * wasting 100+bytes per vnode. - */ - -#ifndef OSI_VFS_H_ -#define OSI_VFS_H_ - -/* The vnode should match the current implementation of the fs independent - * part of the Linux inode. - */ -/* The first cut is to continue to use a separate vnode pool. */ -typedef struct vnode { - struct list_head i_hash; - struct list_head i_list; - struct list_head i_dentry; -#if defined(AFS_LINUX24_ENV) - struct list_head i_dirty_buffers; -#endif -#if defined(STRUCT_INODE_HAS_I_DIRTY_DATA_BUFFERS) - struct list_head i_dirty_data_buffers; -#endif - unsigned long i_ino; - unsigned int i_count; - kdev_t i_dev; - umode_t i_mode; - nlink_t i_nlink; - uid_t i_uid; - gid_t i_gid; - kdev_t i_rdev; -#if defined(AFS_LINUX24_ENV) || defined(pgoff2loff) - loff_t i_size; -#else - off_t i_size; -#endif - time_t i_atime; - time_t i_mtime; - time_t i_ctime; - unsigned long i_blksize; - unsigned long i_blocks; - unsigned long i_version; -#if !defined(AFS_LINUX24_ENV) - unsigned long i_nrpages; -#endif -#ifdef STRUCT_INODE_HAS_I_BYTES - unsigned short i_bytes; -#endif - struct semaphore i_sem; -#ifdef STRUCT_INODE_HAS_I_TRUNCATE_SEM - struct rw_semaphore i_truncate_sem; -#endif -#if defined(AFS_LINUX24_ENV) - struct semaphore i_zombie; -#else - struct semaphore i_atomic_write; -#endif - struct inode_operations *i_op; -#if defined(AFS_LINUX24_ENV) - struct file_operations *i_fop; -#endif - struct super_block *i_sb; -#if defined(AFS_LINUX24_ENV) - wait_queue_head_t i_wait; -#else - struct wait_queue *i_wait; -#endif - struct file_lock *i_flock; -#if defined(AFS_LINUX24_ENV) - struct address_space *i_mapping; - struct address_space i_data; -#else - struct vm_area_struct *i_mmap; -#if defined(STRUCT_INODE_HAS_I_MMAP_SHARED) - struct vm_area_struct *i_mmap_shared; -#endif - struct page *i_pages; -#endif -#if defined(STRUCT_INODE_HAS_I_MAPPING_OVERLOAD) - int i_mapping_overload; -#endif - struct dquot *i_dquot[MAXQUOTAS]; -#if defined(AFS_LINUX24_ENV) - struct pipe_inode_info *i_pipe; - struct block_device *i_bdev; -#if defined(STRUCT_INODE_HAS_I_CDEV) - struct char_device *i_cdev; -#endif - unsigned long i_dnotify_mask; - struct dnotify_struct *i_dnotify; -#endif - - unsigned long i_state; - - unsigned int i_flags; -#if !defined(AFS_LINUX24_ENV) - unsigned char i_pipe; -#endif - unsigned char i_sock; - -#if defined(AFS_LINUX24_ENV) - atomic_t i_writecount; -#else - int i_writecount; -#endif - unsigned int i_attr_flags; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,10) - __u32 i_generation; -#endif -#ifdef notdef - union { - struct pipe_inode_info pipe_i; - struct minix_inode_info minix_i; - struct ext2_inode_info ext2_i; - struct hpfs_inode_info hpfs_i; - struct ntfs_inode_info ntfs_i; - struct msdos_inode_info msdos_i; - struct umsdos_inode_info umsdos_i; - struct iso_inode_info isofs_i; - struct nfs_inode_info nfs_i; - struct sysv_inode_info sysv_i; - struct affs_inode_info affs_i; - struct ufs_inode_info ufs_i; - struct romfs_inode_info romfs_i; - struct coda_inode_info coda_i; - struct smb_inode_info smbfs_i; - struct hfs_inode_info hfs_i; - struct adfs_inode_info adfs_i; - struct qnx4_inode_info qnx4_i; - struct socket socket_i; - void *generic_ip; - } u; -#endif -} vnode_t; - -/* Map vnode fields to inode fields. */ -#define i_number i_ino -#define v_count i_count -#define v_op i_op -#if defined(AFS_LINUX24_ENV) -#define v_fop i_fop -#endif -#define v_type i_mode -#define v_vfsp i_sb -#define vfs_vnodecovered s_covered - -/* v_type bits map to mode bits: */ -#define VNON 0 -#define VREG S_IFREG -#define VDIR S_IFDIR -#define VBLK S_IFBLK -#define VCHR S_IFCHR -#define VLNK S_IFLNK -#define VSOCK S_IFSOCK - -/* vcexcl - used only by afs_create */ -enum vcexcl { EXCL, NONEXCL } ; - -/* afs_open and afs_close needs to distinguish these cases */ -#define FWRITE O_WRONLY|O_RDWR|O_APPEND -#define FTRUNC O_TRUNC - - -#define IO_APPEND O_APPEND -#define FSYNC O_SYNC - -#define VTOI(V) ((struct inode*)V) -#define VN_HOLD(V) ((vnode_t*)V)->i_count++; -#define VN_RELE(V) osi_iput((struct inode *)V); -#define VFS_STATFS(V, S) ((V)->s_op->statfs)((V), (S), sizeof(*(S))) - - - -/* Various mode bits */ -#define VWRITE S_IWUSR -#define VREAD S_IRUSR -#define VEXEC S_IXUSR -#define VSUID S_ISUID -#define VSGID S_ISGID - - -#define vfs super_block - -typedef struct vattr { - int va_type; /* One of v_types above. */ - size_t va_size; - unsigned long va_blocks; - unsigned long va_blocksize; - int va_mask; /* AT_xxx operation to perform. */ - umode_t va_mode; /* mode bits. */ - uid_t va_uid; - gid_t va_gid; - int va_fsid; /* Not used? */ - dev_t va_rdev; - ino_t va_nodeid; /* Inode number */ - nlink_t va_nlink; /* link count for file. */ - struct timeval va_atime; - struct timeval va_mtime; - struct timeval va_ctime; -} vattr_t; - -#define VATTR_NULL(A) memset(A, 0, sizeof(struct vattr)) - - -/* va_masks - these should match their respective ATTR_xxx #defines in fs.h. - * afs_notify_change has to use the attr bits in both the Linux and AFS - * meanings. The glue layer code uses the ATTR_xxx style names. - */ -#define AT_SIZE ATTR_SIZE -#define AT_MODE ATTR_MODE -#define AT_UID ATTR_UID -#define AT_GID ATTR_GID -#define AT_MTIME ATTR_MTIME - - -#define vnodeops inode_operations - -#endif /* OSI_VFS_H_ */ diff --git a/src/afs/VNOPS/afs_vnop_lookup.c b/src/afs/VNOPS/afs_vnop_lookup.c index 96fa4474b..4aa7a1094 100644 --- a/src/afs/VNOPS/afs_vnop_lookup.c +++ b/src/afs/VNOPS/afs_vnop_lookup.c @@ -22,7 +22,7 @@ #include #include "../afs/param.h" -RCSID("$Header: /tmp/cvstemp/openafs/src/afs/VNOPS/afs_vnop_lookup.c,v 1.8 2001/09/11 15:47:38 hartmans Exp $"); +RCSID("$Header: /tmp/cvstemp/openafs/src/afs/VNOPS/afs_vnop_lookup.c,v 1.9 2001/10/14 18:43:27 hartmans Exp $"); #include "../afs/sysincludes.h" /* Standard vendor system headers */ #include "../afs/afsincludes.h" /* Afs-based standard headers */ @@ -353,7 +353,7 @@ extern int BlobScan(afs_int32 *afile, afs_int32 ablob); * CForeign bit set. */ struct vcache * BStvc = (struct vcache *) 0; -void afs_DoBulkStat(adp, dirCookie, areqp) +int afs_DoBulkStat(adp, dirCookie, areqp) struct vcache *adp; long dirCookie; struct vrequest *areqp; @@ -397,6 +397,7 @@ void afs_DoBulkStat(adp, dirCookie, areqp) struct volume *volp=0; /* volume ptr */ struct VenusFid dotdot; int flagIndex; /* First file with bulk fetch flag set */ + int inlinebulk=0; /* Did we use InlineBulk RPC or not? */ XSTATS_DECLS /* first compute some basic parameters. We dont want to prefetch more @@ -607,8 +608,20 @@ tagain: #ifdef RX_ENABLE_LOCKS AFS_GUNLOCK(); #endif /* RX_ENABLE_LOCKS */ - code = RXAFS_BulkStatus(tcp->id, &fidParm, &statParm, &cbParm, - &volSync); +#ifdef notdef + code = RXAFS_InlineBulkStatus(tcp->id, &fidParm, &statParm, + &cbParm, &volSync); + if (code == RXGEN_OPCODE) { +#endif + code = RXAFS_BulkStatus(tcp->id, &fidParm, &statParm, &cbParm, + &volSync); + inlinebulk=0; +#ifdef notdef + } else { + inlinebulk=1; + } +#endif + #ifdef RX_ENABLE_LOCKS AFS_GLOCK(); #endif /* RX_ENABLE_LOCKS */ @@ -680,6 +693,8 @@ tagain: * We also have to take into account racing token revocations. */ for(i=0; ierrorCode) + continue; afid.Cell = adp->fid.Cell; afid.Fid.Volume = adp->fid.Fid.Volume; afid.Fid.Vnode = fidsp[i].Vnode; @@ -846,8 +861,20 @@ tagain: if ( volp ) afs_PutVolume(volp, READ_LOCK); + /* If we did the InlineBulk RPC pull out the return code */ + if (inlinebulk) { + if ((&statsp[0])->errorCode) { + afs_Analyze(tcp, (&statsp[0])->errorCode, &adp->fid, areqp, + AFS_STATS_FS_RPCIDX_BULKSTATUS, SHARED_LOCK, + (struct cell *)0); + code = (&statsp[0])->errorCode; + } + } else { + code = 0; + } osi_FreeLargeSpace(statMemp); osi_FreeLargeSpace(cbfMemp); + return code; } /* was: (AFS_DEC_ENV) || defined(AFS_OSF30_ENV) || defined(AFS_NCR_ENV) */ @@ -885,6 +912,7 @@ afs_lookup(adp, aname, avcp, acred) char *tname = (char *)0; register struct vcache *tvc=0; register afs_int32 code; + register afs_int32 bulkcode = 0; int pass = 0, hit = 0; long dirCookie; extern afs_int32 afs_mariner; /*Writing activity to log?*/ @@ -892,6 +920,7 @@ afs_lookup(adp, aname, avcp, acred) afs_hyper_t versionNo; int no_read_access = 0; struct sysname_info sysState; /* used only for @sys checking */ + int dynrootRetry = 1; AFS_STATCNT(afs_lookup); #ifdef AFS_OSF_ENV @@ -903,7 +932,7 @@ afs_lookup(adp, aname, avcp, acred) *avcp = (struct vcache *) 0; /* Since some callers don't initialize it */ if (code = afs_InitReq(&treq, acred)) { - goto done; + goto done; } /* come back to here if we encounter a non-existent object in a read-only @@ -911,10 +940,12 @@ afs_lookup(adp, aname, avcp, acred) redo: *avcp = (struct vcache *) 0; /* Since some callers don't initialize it */ + bulkcode = 0; if (!(adp->states & CStatd)) { - if (code = afs_VerifyVCache2(adp, &treq)) - goto done; + if (code = afs_VerifyVCache2(adp, &treq)) { + goto done; + } } else code = 0; @@ -947,7 +978,7 @@ afs_lookup(adp, aname, avcp, acred) *avcp = tvc; code = (tvc ? 0 : ENOENT); hit = 1; - if (tvc && !tvc->vrefCount) { + if (tvc && !VREFCOUNT(tvc)) { osi_Panic("TT1"); } if (code) { @@ -980,13 +1011,13 @@ afs_lookup(adp, aname, avcp, acred) ObtainReadLock(&afs_xvcache); osi_vnhold(adp, 0); ReleaseReadLock(&afs_xvcache); - code = 0; - *avcp = tvc = adp; - hit = 1; - if (adp && !adp->vrefCount) { + code = 0; + *avcp = tvc = adp; + hit = 1; + if (adp && !VREFCOUNT(adp)) { osi_Panic("TT2"); } - goto done; + goto done; } Check_AtSys(adp, aname, &sysState, &treq); @@ -1090,9 +1121,27 @@ afs_lookup(adp, aname, avcp, acred) } tname = sysState.name; - ReleaseReadLock(&adp->lock); afs_PutDCache(tdc); + if (code == ENOENT && afs_IsDynroot(adp) && dynrootRetry) { + struct cell *tcell; + + ReleaseReadLock(&adp->lock); + dynrootRetry = 0; + if (*tname == '.') + tcell = afs_GetCellByName(tname + 1, READ_LOCK); + else + tcell = afs_GetCellByName(tname, READ_LOCK); + if (tcell) { + afs_PutCell(tcell, READ_LOCK); + afs_RefreshDynroot(); + if (tname != aname && tname) osi_FreeLargeSpace(tname); + goto redo; + } + } else { + ReleaseReadLock(&adp->lock); + } + /* new fid has same cell and volume */ tfid.Cell = adp->fid.Cell; tfid.Fid.Volume = adp->fid.Fid.Volume; @@ -1110,7 +1159,7 @@ afs_lookup(adp, aname, avcp, acred) /* prefetch some entries, if the dir is currently open. The variable * dirCookie tells us where to start prefetching from. */ - if (AFSDOBULK && adp->opens > 0 && !(adp->states & CForeign)) { + if (AFSDOBULK && adp->opens > 0 && !(adp->states & CForeign) && !afs_IsDynroot(adp)) { afs_int32 retry; /* if the entry is not in the cache, or is in the cache, * but hasn't been statd, then do a bulk stat operation. @@ -1122,23 +1171,26 @@ afs_lookup(adp, aname, avcp, acred) ReleaseReadLock(&afs_xvcache); } while (tvc && retry); - if (!tvc || !(tvc->states & CStatd)) { - afs_DoBulkStat(adp, dirCookie, &treq); - } + if (!tvc || !(tvc->states & CStatd)) + bulkcode = afs_DoBulkStat(adp, dirCookie, &treq); + else + bulkcode = 0; /* if the vcache isn't usable, release it */ if (tvc && !(tvc->states & CStatd)) { afs_PutVCache(tvc); tvc = (struct vcache *) 0; } + } else { + tvc = (struct vcache *) 0; + bulkcode = 0; } - else tvc = (struct vcache *) 0; - + /* now get the status info, if we don't already have it */ /* This is kind of weird, but we might wind up accidentally calling * RXAFS_Lookup because we happened upon a file which legitimately * has a 0 uniquifier. That is the result of allowing unique to wrap - * to 0. This was fixed in AFS 3.4. For CForeigh, Unique == 0 means that + * to 0. This was fixed in AFS 3.4. For CForeign, Unique == 0 means that * the file has not yet been looked up. */ if (!tvc) { @@ -1147,10 +1199,10 @@ afs_lookup(adp, aname, avcp, acred) tvc = afs_LookupVCache(&tfid, &treq, &cached, WRITE_LOCK, adp, tname); } - if (!tvc) { /* lookup failed or wasn't called */ - tvc = afs_GetVCache(&tfid, &treq, &cached, (struct vcache*)0, - WRITE_LOCK); - } + if (!tvc && !bulkcode) { /* lookup failed or wasn't called */ + tvc = afs_GetVCache(&tfid, &treq, &cached, (struct vcache*)0, + WRITE_LOCK); + } } /* if !tvc */ } /* sub-block just to reduce stack usage */ @@ -1174,6 +1226,7 @@ afs_lookup(adp, aname, avcp, acred) ReleaseWriteLock(&tvc->lock); if (code) { + afs_PutVCache(tvc, WRITE_LOCK); if (tvolp) afs_PutVolume(tvolp, WRITE_LOCK); goto done; } @@ -1225,7 +1278,7 @@ afs_lookup(adp, aname, avcp, acred) } } *avcp = tvc; - if (tvc && !tvc->vrefCount) { + if (tvc && !VREFCOUNT(tvc)) { osi_Panic("TT3"); } code = 0; @@ -1293,6 +1346,7 @@ done: #endif } } + if (bulkcode) code = bulkcode; else code = afs_CheckCode(code, &treq, 19); if (code) { /* If there is an error, make sure *avcp is null. diff --git a/src/afs/afs.h b/src/afs/afs.h index 9ed8343a3..d1918d536 100644 --- a/src/afs/afs.h +++ b/src/afs/afs.h @@ -189,6 +189,7 @@ struct afs_cbr { #define CNoSUID 2 /* 1 if no suid progs can run from this cell */ #define CHasVolRef 16 /* Volumes were referenced in this cell*/ #define CLinkedCell 32 +#define CAlias 64 /* This cell entry is an alias */ struct cell { struct afs_q lruq; /* lru q next and prev */ @@ -201,6 +202,7 @@ struct cell { short states; /* state flags */ short cellIndex; /* relative index number per cell */ time_t timeout; /* data expire time, if non-zero */ + struct cell *alias; /* what this cell is an alias for */ }; #define afs_PutCell(cellp, locktype) @@ -522,6 +524,18 @@ struct SimpleLocks { #define vrefCount v.v_usecount #endif /* AFS_FBSD_ENV */ +#ifdef AFS_LINUX24_ENV +#define VREFCOUNT(v) atomic_read(&((vnode_t *) v)->v_count) +#define VREFCOUNT_SET(v, c) atomic_set(&((vnode_t *) v)->v_count, c) +#define VREFCOUNT_DEC(v) atomic_dec(&((vnode_t *) v)->v_count) +#define VREFCOUNT_INC(v) atomic_inc(&((vnode_t *) v)->v_count) +#else +#define VREFCOUNT(v) ((v)->vrefCount) +#define VREFCOUNT_SET(v, c) (v)->vrefCount = c; +#define VREFCOUNT_DEC(v) (v)->vrefCount--; +#define VREFCOUNT_INC(v) (v)->vrefCount++; +#endif + #define AFS_MAXDV 0x7fffffff /* largest dataversion number */ #define AFS_NOTRUNC 0x7fffffff /* largest dataversion number */ @@ -946,6 +960,7 @@ extern struct brequest afs_brs[NBRS]; /* request structures */ extern struct cell *afs_GetCell(); extern struct cell *afs_GetCellByName(); +extern struct cell *afs_GetCellByIndex(); extern struct unixuser *afs_GetUser(); extern struct volume *afs_GetVolume(); extern struct volume *afs_GetVolumeByName(); @@ -978,6 +993,17 @@ extern void afs_shutdown(); /* afs_osifile.c */ extern void shutdown_osifile(); +/* afs_dynroot.c */ +extern int afs_IsDynrootFid(); +extern void afs_GetDynrootFid(); +extern int afs_IsDynroot(); +extern void afs_RefreshDynroot(); +extern void afs_GetDynroot(); +extern void afs_PutDynroot(); +extern int afs_DynrootNewVnode(); +extern int afs_SetDynrootEnable(); +extern int afs_GetDynrootEnable(); + /* Performance hack - we could replace VerifyVCache2 with the appropriate * GetVCache incantation, and could eliminate even this code from afs_UFSRead @@ -1036,6 +1062,7 @@ extern int afs_CacheTooFull; * afs_GetDownD wakes those processes once the cache is 95% full * (CM_CACHESIZEDRAINEDPCT). */ +extern void afs_MaybeWakeupTruncateDaemon(); extern void afs_CacheTruncateDaemon(); extern int afs_WaitForCacheDrain; #define CM_MAXDISCARDEDCHUNKS 16 /* # of chunks */ @@ -1051,19 +1078,6 @@ extern int afs_WaitForCacheDrain; afs_freeDCCount - afs_discardDCCount < \ ((100-CM_DCACHECOUNTFREEPCT)*afs_cacheFiles)/100) -#define afs_MaybeWakeupTruncateDaemon() \ - do { \ - if (!afs_CacheTooFull && afs_CacheIsTooFull()) { \ - afs_CacheTooFull = 1; \ - if (!afs_TruncateDaemonRunning) { \ - afs_osi_Wakeup((char *)afs_CacheTruncateDaemon); \ - } \ - } else if (!afs_TruncateDaemonRunning && \ - afs_blocksDiscarded > CM_MAXDISCARDEDCHUNKS) { \ - afs_osi_Wakeup((char *)afs_CacheTruncateDaemon); \ - } \ - } while (0) - /* Handy max length of a numeric string. */ #define CVBS 12 /* max afs_int32 is 2^32 ~ 4*10^9, +1 for NULL, +luck */ diff --git a/src/afs/afs_call.c b/src/afs/afs_call.c index d9310d35d..13d04f8ca 100644 --- a/src/afs/afs_call.c +++ b/src/afs/afs_call.c @@ -10,7 +10,7 @@ #include #include "../afs/param.h" -RCSID("$Header: /tmp/cvstemp/openafs/src/afs/afs_call.c,v 1.7 2001/09/11 15:47:35 hartmans Exp $"); +RCSID("$Header: /tmp/cvstemp/openafs/src/afs/afs_call.c,v 1.8 2001/10/14 18:43:24 hartmans Exp $"); #include "../afs/sysincludes.h" /* Standard vendor system headers */ #include "../afs/afsincludes.h" /* Afs-based standard headers */ @@ -609,13 +609,25 @@ long parm, parm2, parm3, parm4, parm5, parm6; int cellLen = (sizeArg & 0xffff0000) >> 16; afs_int32 *kmsg = afs_osi_Alloc(kmsgLen); char *cellname = afs_osi_Alloc(cellLen); + + AFS_COPYIN((afs_int32 *)parm2, cellname, cellLen, code); AFS_COPYIN((afs_int32 *)parm3, kmsg, kmsgLen, code); - if (!code) code = afs_AfsdbHandler(cellname, cellLen, kmsg); + if (!code) { + code = afs_AfsdbHandler(cellname, cellLen, kmsg); + if (*cellname == 1) *cellname = 0; + if (code == -2) { /* Shutting down? */ + *cellname = 1; + code = 0; + } + } if (!code) AFS_COPYOUT(cellname, (char *)parm2, cellLen, code); afs_osi_Free(kmsg, kmsgLen); afs_osi_Free(cellname, cellLen); } #endif + else if (parm == AFSOP_SET_DYNROOT) { + code = afs_SetDynrootEnable(parm2); + } else code = EINVAL; @@ -935,6 +947,7 @@ asmlinkage int afs_syscall(long syscall, long parm1, long parm2, long parm3, long linux_ret=0; long *retval = &linux_ret; long eparm[4]; /* matches AFSCALL_ICL in fstrace.c */ + /* eparm is also used by AFSCALL_CALL in afsd.c */ #else #if defined(UKERNEL) Afs_syscall () @@ -995,7 +1008,7 @@ Afs_syscall () uap->parm1 = parm1; uap->parm2 = parm2; uap->parm3 = parm3; - if (syscall == AFSCALL_ICL) { + if (syscall == AFSCALL_ICL || syscall == AFSCALL_CALL) { AFS_COPYIN((char*)parm4, (char*)eparm, sizeof(eparm), code); uap->parm4 = eparm[0]; uap->parm5 = eparm[1]; @@ -1201,6 +1214,12 @@ afs_shutdown() afs_osi_Wakeup((char*)&afs_CacheTruncateDaemon); afs_osi_Sleep(&afs_termState); } +#ifdef AFS_AFSDB_ENV + afs_warn("AFSDB... "); + afs_StopAfsdb(); + while (afs_termState == AFSOP_STOP_AFSDB) + afs_osi_Sleep(&afs_termState); +#endif #if defined(AFS_SUN5_ENV) || defined(RXK_LISTENER_ENV) afs_warn("RxEvent... "); /* cancel rx event deamon */ diff --git a/src/afs/afs_daemons.c b/src/afs/afs_daemons.c index c56dcd414..abd2307ef 100644 --- a/src/afs/afs_daemons.c +++ b/src/afs/afs_daemons.c @@ -10,7 +10,7 @@ #include #include "../afs/param.h" -RCSID("$Header: /tmp/cvstemp/openafs/src/afs/afs_daemons.c,v 1.5 2001/09/11 15:47:35 hartmans Exp $"); +RCSID("$Header: /tmp/cvstemp/openafs/src/afs/afs_daemons.c,v 1.6 2001/10/14 18:43:25 hartmans Exp $"); #include "../afs/sysincludes.h" /* Standard vendor system headers */ #include "../afs/afsincludes.h" /* Afs-based standard headers */ @@ -268,6 +268,7 @@ void afs_Daemon() { afs_CheckRootVolume () { char rootVolName[32]; register struct volume *tvp; + int usingDynroot = afs_GetDynrootEnable(); AFS_STATCNT(afs_CheckRootVolume); if (*afs_rootVolumeName == 0) { @@ -276,7 +277,12 @@ afs_CheckRootVolume () { else { strcpy(rootVolName, afs_rootVolumeName); } - tvp = afs_GetVolumeByName(rootVolName, LOCALCELL, 1, (struct vrequest *) 0, READ_LOCK); + if (usingDynroot) { + afs_GetDynrootFid(&afs_rootFid); + tvp = afs_GetVolume(&afs_rootFid, (struct vrequest *) 0, READ_LOCK); + } else { + tvp = afs_GetVolumeByName(rootVolName, LOCALCELL, 1, (struct vrequest *) 0, READ_LOCK); + } if (!tvp) { char buf[128]; int len = strlen(rootVolName); @@ -288,23 +294,25 @@ afs_CheckRootVolume () { } } if (tvp) { - int volid = (tvp->roVol? tvp->roVol : tvp->volume); - afs_rootFid.Cell = LOCALCELL; - if (afs_rootFid.Fid.Volume && afs_rootFid.Fid.Volume != volid - && afs_globalVp) { - /* If we had a root fid before and it changed location we reset - * the afs_globalVp so that it will be reevaluated. - * Just decrement the reference count. This only occurs during - * initial cell setup and can panic the machine if we set the - * count to zero and fs checkv is executed when the current - * directory is /afs. - */ - AFS_FAST_RELE(afs_globalVp); - afs_globalVp = 0; + if (!usingDynroot) { + int volid = (tvp->roVol? tvp->roVol : tvp->volume); + afs_rootFid.Cell = LOCALCELL; + if (afs_rootFid.Fid.Volume && afs_rootFid.Fid.Volume != volid + && afs_globalVp) { + /* If we had a root fid before and it changed location we reset + * the afs_globalVp so that it will be reevaluated. + * Just decrement the reference count. This only occurs during + * initial cell setup and can panic the machine if we set the + * count to zero and fs checkv is executed when the current + * directory is /afs. + */ + AFS_FAST_RELE(afs_globalVp); + afs_globalVp = 0; + } + afs_rootFid.Fid.Volume = volid; + afs_rootFid.Fid.Vnode = 1; + afs_rootFid.Fid.Unique = 1; } - afs_rootFid.Fid.Volume = volid; - afs_rootFid.Fid.Vnode = 1; - afs_rootFid.Fid.Unique = 1; afs_initState = 300; /* won */ afs_osi_Wakeup(&afs_initState); afs_PutVolume(tvp, READ_LOCK); diff --git a/src/afs/afs_pioctl.c b/src/afs/afs_pioctl.c index 450cd8b3e..45b44f45c 100644 --- a/src/afs/afs_pioctl.c +++ b/src/afs/afs_pioctl.c @@ -10,7 +10,7 @@ #include #include "../afs/param.h" -RCSID("$Header: /tmp/cvstemp/openafs/src/afs/afs_pioctl.c,v 1.9 2001/09/11 15:47:35 hartmans Exp $"); +RCSID("$Header: /tmp/cvstemp/openafs/src/afs/afs_pioctl.c,v 1.10 2001/10/14 18:43:25 hartmans Exp $"); #include "../afs/sysincludes.h" /* Standard vendor system headers */ #include "../afs/afsincludes.h" /* Afs-based standard headers */ @@ -2295,7 +2295,7 @@ static PNewCell(avc, afun, areq, ain, aout, ainSize, aoutSize, acred) } linkedstate |= CNoSUID; /* setuid is disabled by default for fs newcell */ - code = afs_NewCell(newcell, cellHosts, linkedstate, linkedcell, fsport, vlport, (int)0); + code = afs_NewCell(newcell, cellHosts, linkedstate, linkedcell, fsport, vlport, (int)0, (char *) 0); return code; } @@ -2560,13 +2560,13 @@ struct AFS_UCRED *acred; for(i = 0; i < VCSIZE; i++) { for(tvc = afs_vhashT[i]; tvc; tvc=tvc->hnext) { if (tvc->fid.Fid.Volume == volume && tvc->fid.Cell == cell) { -#if defined(AFS_SGI_ENV) || defined(AFS_ALPHA_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV) +#if defined(AFS_SGI_ENV) || defined(AFS_ALPHA_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV) VN_HOLD((struct vnode *)tvc); #else #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) osi_vnhold(tvc, 0); #else - tvc->vrefCount++; + VREFCOUNT_INC(tvc); #endif #endif ReleaseReadLock(&afs_xvcache); diff --git a/src/afsd/afs.conf.linux b/src/afsd/afs.conf.linux index a7b19c9de..cb558927f 100644 --- a/src/afsd/afs.conf.linux +++ b/src/afsd/afs.conf.linux @@ -16,9 +16,20 @@ test -f /etc/openafs/afs.conf.client && . /etc/openafs/afs.conf.client AFS_SERVER=off # AFS client configuration options: +XXLARGE="-stat 4000 -dcache 4000 -daemons 6 -volumes 256 -files 50000" +XLARGE="-stat 3600 -dcache 3600 -daemons 5 -volumes 196 -files 50000" LARGE="-stat 2800 -dcache 2400 -daemons 5 -volumes 128" MEDIUM="-stat 2000 -dcache 800 -daemons 3 -volumes 70" SMALL="-stat 300 -dcache 100 -daemons 2 -volumes 50" + +# cachesize and according options are set by /afs/rc.d/init.d/afs +# * if you set CACHESIZE to "AUTOMATIC", it will automatically be chosen +# deduced by parition sizes (does not work if your cache is on / or /usr) +# * if you set OPTIONS to "AUTOMATIC", the init script will choose a set +# of options based on the cache size +# otherwise the values specified here will be used. So be careful! +# Note: if you leave these as-is, no changes are made. +CACHESIZE= OPTIONS=$MEDIUM # Should we support afsdb? diff --git a/src/libafs/Makefile.common b/src/libafs/Makefile.common index dc869c28d..9f1afd2ac 100644 --- a/src/libafs/Makefile.common +++ b/src/libafs/Makefile.common @@ -55,6 +55,7 @@ AFSAOBJS = \ afs_daemons.o \ afs_dcache.o \ afs_dir.o \ + afs_dynroot.o \ afs_init.o \ afs_lock.o \ afs_mariner.o \ @@ -152,6 +153,8 @@ afs_conn.o: $(AFS)/afs_conn.c $(CRULE2); afs_dcache.o: $(AFS)/afs_dcache.c $(CRULE2); +afs_dynroot.o: $(AFS)/afs_dynroot.c + $(CRULE2); afs_init.o: $(AFS)/afs_init.c $(CRULE2); afs_mariner.o: $(AFS)/afs_mariner.c diff --git a/src/libafs/MakefileProto.LINUX.in b/src/libafs/MakefileProto.LINUX.in index 3df987cd0..1ecd276b4 100644 --- a/src/libafs/MakefileProto.LINUX.in +++ b/src/libafs/MakefileProto.LINUX.in @@ -81,6 +81,11 @@ CCFLAGS = -O2 -fomit-frame-pointer -fno-strength-reduce \ -fno-strict-aliasing -fsigned-char -msoft-float -pipe \ -fno-builtin -ffixed-r2 DEFINES = -D__KERNEL__ -D__powerpc__ -DKERNEL -D_KERNEL -DMODULE ${SMP_DEF} + +CCFLAGS = -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -fno-strength-reduce \ + -fno-strict-aliasing -fsigned-char -mno-space-regs -mfast-indirect-calls \ + -mdisable-fpregs -ffunction-sections -march=1.1 -mschedule=7100 +DEFINES = -D__KERNEL__ -D__linux__ -DKERNEL -D_KERNEL -DMODULE ${SMP_DEF} CCFLAGS = -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe \ -ffixed-r13 -mfixed-range=f10-f15,f32-f127 -falign-functions=32 -mb-step diff --git a/src/ptserver/ptserver.c b/src/ptserver/ptserver.c index bdac38b37..5985db9e9 100644 --- a/src/ptserver/ptserver.c +++ b/src/ptserver/ptserver.c @@ -10,7 +10,7 @@ #include #include -RCSID("$Header: /tmp/cvstemp/openafs/src/ptserver/ptserver.c,v 1.6 2001/09/20 06:47:47 hartmans Exp $"); +RCSID("$Header: /tmp/cvstemp/openafs/src/ptserver/ptserver.c,v 1.7 2001/10/14 18:43:29 hartmans Exp $"); #include #ifdef AFS_AIX32_ENV @@ -25,6 +25,13 @@ RCSID("$Header: /tmp/cvstemp/openafs/src/ptserver/ptserver.c,v 1.6 2001/09/20 06 #include #include #endif +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif #include #include #include diff --git a/src/rx/rx.c b/src/rx/rx.c index 340754c88..fb0769849 100644 --- a/src/rx/rx.c +++ b/src/rx/rx.c @@ -16,7 +16,7 @@ #include #endif -RCSID("$Header: /tmp/cvstemp/openafs/src/rx/rx.c,v 1.8 2001/09/11 15:48:34 hartmans Exp $"); +RCSID("$Header: /tmp/cvstemp/openafs/src/rx/rx.c,v 1.9 2001/10/14 18:43:29 hartmans Exp $"); #ifdef KERNEL #include "../afs/sysincludes.h" @@ -3460,7 +3460,7 @@ struct rx_packet *rxi_ReceiveAckPacket(call, np, istack) /* if the ack packet has a receivelen field hanging off it, * update our state */ - if ( np->length >= rx_AckDataSize(ap->nAcks) +sizeof(afs_int32)) { + if ( np->length >= rx_AckDataSize(ap->nAcks) + 2*sizeof(afs_int32)) { afs_uint32 tSize; /* If the ack packet has a "recommended" size that is less than diff --git a/src/rx/rx_packet.c b/src/rx/rx_packet.c index ed498d643..0bcc8349e 100644 --- a/src/rx/rx_packet.c +++ b/src/rx/rx_packet.c @@ -14,7 +14,7 @@ #include #endif -RCSID("$Header: /tmp/cvstemp/openafs/src/rx/rx_packet.c,v 1.5 2001/09/11 15:48:35 hartmans Exp $"); +RCSID("$Header: /tmp/cvstemp/openafs/src/rx/rx_packet.c,v 1.6 2001/10/14 18:43:30 hartmans Exp $"); #ifdef KERNEL #if defined(UKERNEL) @@ -272,7 +272,7 @@ static struct rx_packet * allocCBuf(int class) queue_Remove(c); if (!(c->flags & RX_PKTFLAG_FREE)) osi_Panic("rxi_AllocPacket: packet not free\n"); - c->flags &= ~RX_PKTFLAG_FREE; + c->flags = 0; /* clear RX_PKTFLAG_FREE, initialize the rest */ c->header.flags = 0; #ifdef KERNEL @@ -631,7 +631,7 @@ struct rx_packet *rxi_AllocPacketNoLock(class) dpf(("Alloc %x, class %d\n", p, class)); queue_Remove(p); - p->flags &= ~RX_PKTFLAG_FREE; + p->flags = 0; /* clear RX_PKTFLAG_FREE, initialize the rest */ p->header.flags = 0; /* have to do this here because rx_FlushWrite fiddles with the iovs in @@ -788,8 +788,8 @@ int rxi_ReadPacket(socket, p, host, port) * our problems caused by the lack of a length field in the rx header. * Use the extra buffer that follows the localdata in each packet * structure. */ - savelen = p->wirevec[p->niovecs].iov_len; - p->wirevec[p->niovecs].iov_len += RX_EXTRABUFFERSIZE; + savelen = p->wirevec[p->niovecs-1].iov_len; + p->wirevec[p->niovecs-1].iov_len += RX_EXTRABUFFERSIZE; memset((char *)&msg, 0, sizeof(msg)); msg.msg_name = (char *) &from; @@ -799,7 +799,7 @@ int rxi_ReadPacket(socket, p, host, port) nbytes = rxi_Recvmsg(socket, &msg, 0); /* restore the vec to its correct state */ - p->wirevec[p->niovecs].iov_len = savelen; + p->wirevec[p->niovecs-1].iov_len = savelen; p->length = (nbytes - RX_HEADER_SIZE); if ((nbytes > tlen) || (p->length & 0x8000)) { /* Bogus packet */ @@ -1854,18 +1854,29 @@ register struct rx_packet *p; register afs_uint32 *buf = (afs_uint32*)(p->wirevec[0].iov_base); /* MTUXXX */ afs_uint32 temp; - p->header.epoch = ntohl(*buf++); - p->header.cid = ntohl(*buf++); - p->header.callNumber = ntohl(*buf++); - p->header.seq = ntohl(*buf++); - p->header.serial = ntohl(*buf++); - temp = ntohl(*buf++); + p->header.epoch = ntohl(*buf); + buf++; + p->header.cid = ntohl(*buf); + buf++; + p->header.callNumber = ntohl(*buf); + buf++; + p->header.seq = ntohl(*buf); + buf++; + p->header.serial = ntohl(*buf); + buf++; + + temp = ntohl(*buf); + buf++; + /* C will truncate byte fields to bytes for me */ p->header.type = temp>>24; p->header.flags = temp>>16; p->header.userStatus = temp>>8; p->header.securityIndex = temp>>0; - temp = ntohl(*buf++); + + temp = ntohl(*buf); + buf++; + p->header.serviceId = (temp&0xffff); p->header.spare = temp>>16; /* Note: top 16 bits of this last word are the security checksum */ diff --git a/src/util/dirpath.c b/src/util/dirpath.c index 231976cf6..0ff988283 100644 --- a/src/util/dirpath.c +++ b/src/util/dirpath.c @@ -10,7 +10,7 @@ #include #include -RCSID("$Header: /tmp/cvstemp/openafs/src/util/dirpath.c,v 1.10 2001/09/11 15:48:47 hartmans Exp $"); +RCSID("$Header: /tmp/cvstemp/openafs/src/util/dirpath.c,v 1.11 2001/10/14 18:43:30 hartmans Exp $"); #include #include @@ -222,6 +222,11 @@ static void initDirPathArray(void) strcpy(dirPathArray[AFSDIR_CLIENT_VICE_DIRPATH_ID], afsClntDirPath); pathp = dirPathArray[AFSDIR_CLIENT_ETC_DIRPATH_ID]; +#ifdef AFS_DARWIN_ENV + if (access(AFSDIR_ALTERNATE_CLIENT_ETC_DIR, F_OK) == 0) + AFSDIR_CLIENT_DIRPATH(pathp, AFSDIR_ALTERNATE_CLIENT_ETC_DIR); + else +#endif AFSDIR_CLIENT_DIRPATH(pathp, AFSDIR_CLIENT_ETC_DIR); #endif /* AFS_NT40_ENV */ diff --git a/src/viced/afsfileprocs.c b/src/viced/afsfileprocs.c index 8cd104bc1..168876861 100644 --- a/src/viced/afsfileprocs.c +++ b/src/viced/afsfileprocs.c @@ -28,7 +28,7 @@ #include #include -RCSID("$Header: /tmp/cvstemp/openafs/src/viced/afsfileprocs.c,v 1.5 2001/09/20 06:47:47 hartmans Exp $"); +RCSID("$Header: /tmp/cvstemp/openafs/src/viced/afsfileprocs.c,v 1.6 2001/10/14 18:43:31 hartmans Exp $"); #include #include @@ -523,7 +523,7 @@ SRXAFS_FetchData (tcon, Fid, Pos, Len, OutStatus, CallBack, Sync) /* Check whether the caller has permission access to fetch the data */ if (errorCode = Check_PermissionRights(targetptr, client, rights, - CHK_FETCHDATA, 0)) + CHK_FETCHDATA, 0)) goto Bad_FetchData; /* @@ -783,8 +783,8 @@ Bad_FetchACL: * This routine is called exclusively by SRXAFS_FetchStatus(), and should be * merged into it when possible. */ -SAFSS_FetchStatus (tcon, Fid, OutStatus, CallBack, Sync) - struct rx_connection *tcon; /* Rx connection handle */ +SAFSS_FetchStatus (tcall, Fid, OutStatus, CallBack, Sync) + struct rx_call *tcall; struct AFSFid *Fid; /* Fid of target file */ struct AFSFetchStatus *OutStatus; /* Returned status for the fid */ struct AFSCallBack *CallBack; /* if r/w, callback promise for Fid */ @@ -799,6 +799,7 @@ SAFSS_FetchStatus (tcon, Fid, OutStatus, CallBack, Sync) afs_int32 rights, anyrights; /* rights for this and any user */ struct client *t_client; /* tmp ptr to client data */ struct in_addr logHostAddr; /* host ip holder for inet_ntoa */ + struct rx_connection *tcon = rx_ConnectionOf(tcall); /* Get ptr to client data for user Id for logging */ t_client = (struct client *) rx_GetSpecific(tcon, rxcon_client_key); @@ -824,8 +825,11 @@ SAFSS_FetchStatus (tcon, Fid, OutStatus, CallBack, Sync) /* Are we allowed to fetch Fid's status? */ if (targetptr->disk.type != vDirectory) { if (errorCode = Check_PermissionRights(targetptr, client, rights, - CHK_FETCHSTATUS, 0)) - goto Bad_FetchStatus; + CHK_FETCHSTATUS, 0)) { + if (rx_GetCallAbortCode(tcall) == errorCode) + rx_SetCallAbortCode(tcall, 0); + goto Bad_FetchStatus; + } } /* set OutStatus From the Fid */ @@ -924,9 +928,12 @@ SRXAFS_BulkStatus(tcon, Fids, OutStats, CallBacks, Sync) /* Are we allowed to fetch Fid's status? */ if (targetptr->disk.type != vDirectory) { - if (errorCode = Check_PermissionRights(targetptr, client, rights, - CHK_FETCHSTATUS, 0)) - goto Bad_BulkStatus; + if (errorCode = Check_PermissionRights(targetptr, client, rights, + CHK_FETCHSTATUS, 0)) { + if (rx_GetCallAbortCode(tcall) == errorCode) + rx_SetCallAbortCode(tcall, 0); + goto Bad_BulkStatus; + } } /* set OutStatus From the Fid */ @@ -984,6 +991,155 @@ Audit_and_Return: } /*SRXAFS_BulkStatus*/ +SRXAFS_InlineBulkStatus(tcon, Fids, OutStats, CallBacks, Sync) + struct rx_connection *tcon; + struct AFSCBFids *Fids; + struct AFSBulkStats *OutStats; + struct AFSCBs *CallBacks; + struct AFSVolSync *Sync; +{ + register int i; + afs_int32 nfiles; + Vnode * targetptr = 0; /* pointer to vnode to fetch */ + Vnode * parentwhentargetnotdir = 0; /* parent vnode if targetptr is a file */ + int errorCode = 0; /* return code to caller */ + Volume * volptr = 0; /* pointer to the volume */ + struct client *client; /* pointer to the client data */ + afs_int32 rights, anyrights; /* rights for this and any user */ + register struct AFSFid *tfid; /* file id we're dealing with now */ + struct rx_call *tcall = (struct rx_call *) tcon; + AFSFetchStatus *tstatus; +#if FS_STATS_DETAILED + struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */ + struct timeval opStartTime, + opStopTime; /* Start/stop times for RPC op*/ + struct timeval elapsedTime; /* Transfer time */ + + /* + * Set our stats pointer, remember when the RPC operation started, and + * tally the operation. + */ + opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_BULKSTATUS]); + FS_LOCK + (opP->numOps)++; + FS_UNLOCK + TM_GetTimeOfDay(&opStartTime, 0); +#endif /* FS_STATS_DETAILED */ + + ViceLog(1, ("SAFS_InlineBulkStatus\n")); + FS_LOCK + AFSCallStats.TotalCalls++; + FS_UNLOCK + + nfiles = Fids->AFSCBFids_len; /* # of files in here */ + if (nfiles <= 0) { /* Sanity check */ + errorCode = EINVAL; + goto Audit_and_Return; + } + + /* allocate space for return output parameters */ + OutStats->AFSBulkStats_val = (struct AFSFetchStatus *) + malloc(nfiles * sizeof(struct AFSFetchStatus)); + OutStats->AFSBulkStats_len = nfiles; + CallBacks->AFSCBs_val = (struct AFSCallBack *) + malloc(nfiles * sizeof(struct AFSCallBack)); + CallBacks->AFSCBs_len = nfiles; + + if (errorCode = CallPreamble((struct rx_call **) &tcon, ACTIVECALL)) { + goto Bad_InlineBulkStatus; + } + + tfid = Fids->AFSCBFids_val; + for (i=0; iAFSBulkStats_val[i]; + tstatus->errorCode = errorCode; + parentwhentargetnotdir = (Vnode *) 0; + targetptr = (Vnode *) 0; + volptr = (Volume *) 0; + continue; + } + + /* set volume synchronization information, but only once per call */ + if (i == nfiles) + SetVolumeSync(Sync, volptr); + + /* Are we allowed to fetch Fid's status? */ + if (targetptr->disk.type != vDirectory) { + if (errorCode = Check_PermissionRights(targetptr, client, rights, + CHK_FETCHSTATUS, 0)) { + tstatus = &OutStats->AFSBulkStats_val[i]; + tstatus->errorCode = errorCode; + PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0, volptr); + parentwhentargetnotdir = (Vnode *) 0; + targetptr = (Vnode *) 0; + volptr = (Volume *) 0; + continue; + } + } + + /* set OutStatus From the Fid */ + GetStatus(targetptr, &OutStats->AFSBulkStats_val[i], + rights, anyrights, parentwhentargetnotdir); + + /* If a r/w volume, also set the CallBack state */ + if (VolumeWriteable(volptr)) + SetCallBackStruct(AddBulkCallBack(client->host, tfid), + &CallBacks->AFSCBs_val[i]); + else { + struct AFSFid myFid; + memset(&myFid, 0, sizeof(struct AFSFid)); + myFid.Volume = tfid->Volume; + SetCallBackStruct(AddVolCallBack(client->host, &myFid), + &CallBacks->AFSCBs_val[i]); + } + + /* put back the file ID and volume */ + PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0, volptr); + parentwhentargetnotdir = (Vnode *) 0; + targetptr = (Vnode *) 0; + volptr = (Volume *) 0; + } + +Bad_InlineBulkStatus: + /* Update and store volume/vnode and parent vnodes back */ + PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *)0, volptr); + CallPostamble(tcon); + +#if FS_STATS_DETAILED + TM_GetTimeOfDay(&opStopTime, 0); + if (errorCode == 0) { + FS_LOCK + (opP->numSuccesses)++; + fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime); + fs_stats_AddTo((opP->sumTime), elapsedTime); + fs_stats_SquareAddTo((opP->sqrTime), elapsedTime); + if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) { + fs_stats_TimeAssign((opP->minTime), elapsedTime); + } + if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) { + fs_stats_TimeAssign((opP->maxTime), elapsedTime); + } + FS_UNLOCK + } + +#endif /* FS_STATS_DETAILED */ + +Audit_and_Return: + ViceLog(2, ("SAFS_InlineBulkStatus returns %d\n", errorCode)); + osi_auditU (tcall, InlineBulkFetchStatusEvent, errorCode, AUD_FIDS, Fids, AUD_END); + return 0; + +} /*SRXAFS_InlineBulkStatus*/ + + SRXAFS_FetchStatus (tcon, Fid, OutStatus, CallBack, Sync) struct AFSVolSync *Sync; struct rx_connection *tcon; /* Rx connection handle */ @@ -1014,7 +1170,7 @@ SRXAFS_FetchStatus (tcon, Fid, OutStatus, CallBack, Sync) if (code = CallPreamble((struct rx_call **) &tcon, ACTIVECALL)) goto Bad_FetchStatus; - code = SAFSS_FetchStatus (tcon, Fid, OutStatus, CallBack, Sync); + code = SAFSS_FetchStatus (tcall, Fid, OutStatus, CallBack, Sync); Bad_FetchStatus: CallPostamble(tcon); @@ -2380,15 +2536,15 @@ SAFSS_Symlink (tcon, DirFid, Name, LinkContents, InStatus, OutFid, OutFidStatus, } /* - * If we're creating a mount point (owner mode bits sans x bit), we must - * have administer access to the directory, too. Always allow sysadmins + * If we're creating a mount point (any x bits clear), we must have + * administer access to the directory, too. Always allow sysadmins * to do this. */ - if ((InStatus->Mask & AFS_SETMODE) && !(InStatus->UnixModeBits & 0100)) { + if ((InStatus->Mask & AFS_SETMODE) && !(InStatus->UnixModeBits & 0111)) { /* - * We have a symlink, 'cause we're trying to set the Unix mode bits - * to something without the owner x bits (default mode bits if - * AFS_SETMODE is false is 0777) + * We have a mountpoint, 'cause we're trying to set the Unix mode + * bits to something with some x bits missing (default mode bits + * if AFS_SETMODE is false is 0777) */ if (VanillaUser(client) && !(rights & PRSFS_ADMINISTER)) { errorCode = EACCES; @@ -6213,8 +6369,8 @@ void GetStatus(targetptr, status, rights, anyrights, parentptr) { /* initialize return status from a vnode */ status->InterfaceVersion = 1; - status->SyncCounter = status->dataVersionHigh = status->spare2 = - status->spare3 = status->spare4 = 0; + status->SyncCounter = status->dataVersionHigh = status->lockCount = + status->spare3 = status->errorCode = 0; if (targetptr->disk.type == vFile) status->FileType = File; else if (targetptr->disk.type == vDirectory) @@ -6237,7 +6393,8 @@ void GetStatus(targetptr, status, rights, anyrights, parentptr) status->SegSize = 0; status->ServerModTime = targetptr->disk.serverModifyTime; status->Group = targetptr->disk.group; - status->spare2 = targetptr->disk.lock.lockCount; + status->lockCount = targetptr->disk.lock.lockCount; + status->errorCode = 0; } /*GetStatus*/ diff --git a/src/vol/partition.c b/src/vol/partition.c index d5177180a..e25678b39 100644 --- a/src/vol/partition.c +++ b/src/vol/partition.c @@ -18,7 +18,7 @@ #include #include -RCSID("$Header: /tmp/cvstemp/openafs/src/vol/partition.c,v 1.8 2001/09/20 06:47:48 hartmans Exp $"); +RCSID("$Header: /tmp/cvstemp/openafs/src/vol/partition.c,v 1.9 2001/10/14 18:43:31 hartmans Exp $"); #include #ifdef AFS_NT40_ENV @@ -196,11 +196,13 @@ static void VInitPartition_r(char *path, char *devname, Device dev) dp->next = 0; strcpy(dp->name, path); #if defined(AFS_NAMEI_ENV) && !defined(AFS_NT40_ENV) -#ifdef AFS_SUN5_ENV - strcpy(dp->devName, devname); -#else /* AFS_SUN5_ENV */ + /* Create a lockfile for the partition, of the form /vicepa/Lock/vicepa */ strcpy(dp->devName, path); -#endif + strcat(dp->devName, "/"); + strcat(dp->devName, "Lock"); + mkdir(dp->devName, 0700); + strcat(dp->devName, path); + close(open(dp->devName, O_RDWR | O_CREAT, 0600)); dp->device = volutil_GetPartitionID(path); #else strcpy(dp->devName, devname); @@ -312,6 +314,59 @@ int VCheckPartition(part, devname) return 0; } + +/* VIsAlwaysAttach() checks whether a /vicepX directory should always be + * attached (return value 1), or only attached when it is a separately + * mounted partition (return value 0). For non-NAMEI environments, it + * always returns 0. + */ +static int VIsAlwaysAttach(part) + char *part; +{ +#ifdef AFS_NAMEI_ENV + struct stat st; + char checkfile[256]; + int ret; + + if (strncmp(part, VICE_PARTITION_PREFIX, VICE_PREFIX_SIZE)) + return 0; + + strncpy(checkfile, part, 100); + strcat(checkfile, "/"); + strcat(checkfile, VICE_ALWAYSATTACH_FILE); + + ret = stat(checkfile, &st); + return (ret < 0) ? 0 : 1; +#else /* AFS_NAMEI_ENV */ + return 0; +#endif /* AFS_NAMEI_ENV */ +} + +/* VAttachPartitions2() looks for and attaches /vicepX partitions + * where a special file (VICE_ALWAYSATTACH_FILE) exists. This is + * used to attach /vicepX directories which aren't on dedicated + * partitions, in the NAMEI fileserver. + */ +void VAttachPartitions2() { +#ifdef AFS_NAMEI_ENV + DIR *dirp; + struct dirent *de; + char pname[32]; + + dirp = opendir("/"); + while (de = readdir(dirp)) { + strcpy(pname, "/"); + strncat(pname, de->d_name, 20); + pname[sizeof(pname)-1] = '\0'; + + /* Only keep track of "/vicepx" partitions since automounter + may hose us */ + if (VIsAlwaysAttach(pname)) + VCheckPartition(pname, ""); + } + closedir(dirp); +#endif /* AFS_NAMEI_ENV */ +} #endif /* AFS_NT40_ENV */ #ifdef AFS_SUN5_ENV @@ -332,11 +387,18 @@ int VAttachPartitions(void) (strncmp(mnt.mnt_mntopts, "ro,ignore",9) ==0)) continue; + /* If we're going to always attach this partition, do it later. */ + if (VIsAlwaysAttach(mnt.mnt_mountp)) + continue; + if (VCheckPartition(mnt.mnt_mountp, mnt.mnt_special) < 0 ) errors ++; } - (void) fclose(mntfile); + (void) fclose(mntfile); + + /* Process the always-attach partitions, if any. */ + VAttachPartitions2(); return errors ; } @@ -356,12 +418,19 @@ int VAttachPartitions(void) while (mntent = getmntent(mfd)) { if (!hasmntopt(mntent, MNTOPT_RW)) continue; + /* If we're going to always attach this partition, do it later. */ + if (VIsAlwaysAttach(mntent->mnt_dir)) + continue; + if (VCheckPartition(mntent->mnt_dir, mntent->mnt_fsname) < 0 ) errors ++; } endmntent(mfd); + /* Process the always-attach partitions, if any. */ + VAttachPartitions2(); + return errors ; } #endif @@ -449,11 +518,18 @@ int VAttachPartitions(void) } #endif + /* If we're going to always attach this partition, do it later. */ + if (VIsAlwaysAttach(part)) + continue; + if (VCheckPartition(part, vmt2dataptr(vmountp, VMT_OBJECT)) < 0 ) errors ++; } - return errors ; + /* Process the always-attach partitions, if any. */ + VAttachPartitions2(); + + return errors ; } #endif #if defined(AFS_DUX40_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) @@ -470,11 +546,18 @@ int VAttachPartitions(void) while (fsent = getfsent()) { if (strcmp(fsent->fs_type, "rw") != 0) continue; + /* If we're going to always attach this partition, do it later. */ + if (VIsAlwaysAttach(fsent->fs_file)) + continue; + if (VCheckPartition(fsent->fs_file, fsent->fs_spec) < 0 ) errors ++; } endfsent(); + /* Process the always-attach partitions, if any. */ + VAttachPartitions2(); + return errors ; } #endif @@ -644,11 +727,18 @@ int VAttachPartitions(void) } } while (mntent = getmntent(mfd)) { + /* If we're going to always attach this partition, do it later. */ + if (VIsAlwaysAttach(mntent->mnt_dir)) + continue; + if (VCheckPartition(mntent->mnt_dir, mntent->mnt_fsname) < 0 ) errors ++; } endmntent(mfd); + /* Process the always-attach partitions, if any. */ + VAttachPartitions2(); + return errors ; } #endif /* AFS_LINUX22_ENV */ @@ -1001,7 +1091,7 @@ void VLockPartition_r(char *name) assert (lockf(dp->lock_fd, F_LOCK, 0) != -1); #else assert (flock(dp->lock_fd, LOCK_EX) == 0); -#endif /* defined(AFS_AIX_ENV) */ +#endif /* defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV) */ #endif }