2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
17 #include <afsconfig.h>
18 #include "afs/param.h"
21 #include "afs/sysincludes.h" /* Standard vendor system headers */
22 #include "afsincludes.h" /* Afs-based standard headers */
23 #include "afs/afs_stats.h" /* statistics */
24 #include "afs/afs_cbqueue.h"
25 #include "afs/nfsclient.h"
26 #include "afs/afs_osidnlc.h"
30 /* given a vnode ptr, open flags and credentials, open the file. No access
31 * checks are done here, instead they're done by afs_create or afs_access,
32 * both called by the vn_open call.
36 afs_open(bhv_desc_t * bhv, struct vcache **avcp, afs_int32 aflags,
39 afs_open(struct vcache **avcp, afs_int32 aflags, afs_ucred_t *acred)
42 register afs_int32 code;
46 struct afs_fakestat_state fakestate;
48 AFS_STATCNT(afs_open);
49 if ((code = afs_InitReq(&treq, acred)))
52 /* avcpp can be, but is not necesarily, bhp's vnode. */
53 tvc = VTOAFS(BHV_TO_VNODE(bhv));
57 afs_Trace2(afs_iclSetp, CM_TRACE_OPEN, ICL_TYPE_POINTER, tvc,
58 ICL_TYPE_INT32, aflags);
59 afs_InitFakeStat(&fakestate);
63 code = afs_EvalFakeStat(&tvc, &fakestate, &treq);
66 code = afs_VerifyVCache(tvc, &treq);
70 ObtainReadLock(&tvc->lock);
73 if (AFS_IS_DISCONNECTED && (afs_DCacheMissingChunks(tvc) != 0)) {
74 ReleaseReadLock(&tvc->lock);
75 printf("Network is down in afs_open: missing chunks\n");
81 ReleaseReadLock(&tvc->lock);
83 if (aflags & (FWRITE | FTRUNC))
87 if (vType(tvc) == VDIR) {
94 (tvc, ((tvc->f.states & CForeign) ? PRSFS_READ : PRSFS_LOOKUP),
95 &treq, CHECK_MODE_BITS)) {
97 printf("afs_Open: no access for dir\n");
103 if (AFS_NFSXLATORREQ(acred) && (aflags & FREAD)) {
105 (tvc, PRSFS_READ, &treq,
106 CHECK_MODE_BITS | CMB_ALLOW_EXEC_AS_READ)) {
113 if (aflags & FRSHARE) {
116 * Apparently it is possible for a file to get mapped without
117 * either VNOP_MAP or VNOP_RDWR being called, if (1) it is a
118 * sharable library, and (2) it has already been loaded. We must
119 * ensure that the credp is up to date. We detect the situation
120 * by checking for O_RSHARE at open time.
123 * We keep the caller's credentials since an async daemon will
124 * handle the request at some point. We assume that the same
125 * credentials will be used.
127 ObtainWriteLock(&tvc->lock, 140);
128 if (!tvc->credp || (tvc->credp != acred)) {
131 struct ucred *crp = tvc->credp;
137 ReleaseWriteLock(&tvc->lock);
140 /* normal file or symlink */
141 osi_FlushText(tvc); /* only needed to flush text if text locked last time */
142 #ifdef AFS_BOZONLOCK_ENV
143 afs_BozonLock(&tvc->pvnLock, tvc);
145 osi_FlushPages(tvc, acred);
146 #ifdef AFS_BOZONLOCK_ENV
147 afs_BozonUnlock(&tvc->pvnLock, tvc);
150 /* set date on file if open in O_TRUNC mode */
151 if (aflags & FTRUNC) {
152 /* this fixes touch */
153 ObtainWriteLock(&tvc->lock, 123);
154 tvc->f.m.Date = osi_Time();
155 tvc->f.states |= CDirty;
156 ReleaseWriteLock(&tvc->lock);
158 ObtainReadLock(&tvc->lock);
160 tvc->execsOrWriters++;
162 #if defined(AFS_SGI_ENV)
163 if (writing && tvc->cred == NULL) {
168 ReleaseReadLock(&tvc->lock);
169 if ((afs_preCache != 0) && (writing == 0) && (vType(tvc) != VDIR) &&
171 register struct dcache *tdc;
172 afs_size_t offset, len;
174 tdc = afs_GetDCache(tvc, 0, &treq, &offset, &len, 1);
176 ObtainSharedLock(&tdc->mflock, 865);
177 if (!(tdc->mflags & DFFetchReq)) {
180 /* start the daemon (may already be running, however) */
181 UpgradeSToWLock(&tdc->mflock, 666);
182 tdc->mflags |= DFFetchReq; /* guaranteed to be cleared by BKG or
184 /* last parm (1) tells bkg daemon to do an afs_PutDCache when it
185 is done, since we don't want to wait for it to finish before
188 bp = afs_BQueue(BOP_FETCH, tvc, B_DONTWAIT, 0, acred,
189 (afs_size_t) 0, (afs_size_t) 1, tdc);
191 tdc->mflags &= ~DFFetchReq;
193 ReleaseWriteLock(&tdc->mflock);
195 ReleaseSharedLock(&tdc->mflock);
199 afs_PutFakeStat(&fakestate);
202 code = afs_CheckCode(code, &treq, 4); /* avoid AIX -O bug */
204 afs_Trace2(afs_iclSetp, CM_TRACE_OPEN, ICL_TYPE_POINTER, tvc,
205 ICL_TYPE_INT32, 999999);