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"
22 #include "afs/sysincludes.h" /* Standard vendor system headers */
23 #include "afsincludes.h" /* Afs-based standard headers */
24 #include "afs/afs_stats.h" /* statistics */
25 #include "afs/afs_cbqueue.h"
26 #include "afs/nfsclient.h"
27 #include "afs/afs_osidnlc.h"
31 /* given a vnode ptr, open flags and credentials, open the file. No access
32 * checks are done here, instead they're done by afs_create or afs_access,
33 * both called by the vn_open call.
37 afs_open(bhv_desc_t *bhv, struct vcache **avcp, afs_int32 aflags, struct AFS_UCRED *acred)
39 afs_open(struct vcache **avcp, afs_int32 aflags, struct AFS_UCRED *acred)
42 register afs_int32 code;
46 struct afs_fakestat_state fakestate;
48 AFS_STATCNT(afs_open);
49 if ((code = afs_InitReq(&treq, acred))) return code;
51 /* avcpp can be, but is not necesarily, bhp's vnode. */
52 tvc = VTOAFS(BHV_TO_VNODE(bhv));
56 afs_Trace2(afs_iclSetp, CM_TRACE_OPEN, ICL_TYPE_POINTER, tvc,
57 ICL_TYPE_INT32, aflags);
58 afs_InitFakeStat(&fakestate);
59 code = afs_EvalFakeStat(&tvc, &fakestate, &treq);
61 code = afs_VerifyVCache(tvc, &treq);
63 if (aflags & (FWRITE | FTRUNC)) writing = 1;
65 if (vType(tvc) == VDIR) {
72 if (!afs_AccessOK(tvc,
73 ((tvc->states & CForeign) ? PRSFS_READ: PRSFS_LOOKUP),
74 &treq, CHECK_MODE_BITS)) {
82 if (AFS_NFSXLATORREQ(acred) && (aflags & FREAD)) {
83 if (!afs_AccessOK(tvc, PRSFS_READ, &treq,
84 CHECK_MODE_BITS|CMB_ALLOW_EXEC_AS_READ)) {
91 if (aflags & FRSHARE) {
94 * Apparently it is possible for a file to get mapped without
95 * either VNOP_MAP or VNOP_RDWR being called, if (1) it is a
96 * sharable library, and (2) it has already been loaded. We must
97 * ensure that the credp is up to date. We detect the situation
98 * by checking for O_RSHARE at open time.
101 * We keep the caller's credentials since an async daemon will
102 * handle the request at some point. We assume that the same
103 * credentials will be used.
105 ObtainWriteLock(&tvc->lock,140);
106 if (!tvc->credp || (tvc->credp != acred)) {
109 struct ucred *crp = tvc->credp;
115 ReleaseWriteLock(&tvc->lock);
118 /* normal file or symlink */
119 osi_FlushText(tvc); /* only needed to flush text if text locked last time */
120 #if defined(AFS_SUN_ENV) || defined(AFS_ALPHA_ENV) || defined(AFS_SUN5_ENV)
121 afs_BozonLock(&tvc->pvnLock, tvc);
123 osi_FlushPages(tvc, acred);
124 #if defined(AFS_SUN_ENV) || defined(AFS_ALPHA_ENV) || defined(AFS_SUN5_ENV)
125 afs_BozonUnlock(&tvc->pvnLock, tvc);
128 /* set date on file if open in O_TRUNC mode */
129 if (aflags & FTRUNC) {
130 /* this fixes touch */
131 ObtainWriteLock(&tvc->lock,123);
132 tvc->m.Date = osi_Time();
133 tvc->states |= CDirty;
134 ReleaseWriteLock(&tvc->lock);
136 ObtainReadLock(&tvc->lock);
137 if (writing) tvc->execsOrWriters++;
139 #if defined(AFS_SGI_ENV)
140 if (writing && tvc->cred == NULL) {
145 ReleaseReadLock(&tvc->lock);
147 afs_PutFakeStat(&fakestate);
148 code = afs_CheckCode(code, &treq, 4); /* avoid AIX -O bug */
150 afs_Trace2(afs_iclSetp, CM_TRACE_OPEN, ICL_TYPE_POINTER, tvc,
151 ICL_TYPE_INT32, 999999);