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
)
43 struct vrequest
*treq
= NULL
;
46 struct afs_fakestat_state fakestate
;
48 AFS_STATCNT(afs_open
);
49 if ((code
= afs_CreateReq(&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
);
72 if (AFS_IS_DISCONNECTED
&& (afs_DCacheMissingChunks(tvc
) != 0)) {
73 ReleaseReadLock(&tvc
->lock
);
74 /* printf("Network is down in afs_open: missing chunks\n"); */
79 ReleaseReadLock(&tvc
->lock
);
81 if (aflags
& (FWRITE
| FTRUNC
))
85 if (vType(tvc
) == VDIR
) {
92 (tvc
, ((tvc
->f
.states
& CForeign
) ? PRSFS_READ
: PRSFS_LOOKUP
),
93 treq
, CHECK_MODE_BITS
)) {
95 /* printf("afs_Open: no access for dir\n"); */
101 if (AFS_NFSXLATORREQ(acred
) && (aflags
& FREAD
)) {
103 (tvc
, PRSFS_READ
, treq
,
104 CHECK_MODE_BITS
| CMB_ALLOW_EXEC_AS_READ
)) {
111 if (aflags
& FRSHARE
) {
114 * Apparently it is possible for a file to get mapped without
115 * either VNOP_MAP or VNOP_RDWR being called, if (1) it is a
116 * sharable library, and (2) it has already been loaded. We must
117 * ensure that the credp is up to date. We detect the situation
118 * by checking for O_RSHARE at open time.
121 * We keep the caller's credentials since an async daemon will
122 * handle the request at some point. We assume that the same
123 * credentials will be used.
125 ObtainWriteLock(&tvc
->lock
, 140);
126 if (!tvc
->credp
|| (tvc
->credp
!= acred
)) {
129 struct ucred
*crp
= tvc
->credp
;
135 ReleaseWriteLock(&tvc
->lock
);
138 /* normal file or symlink */
139 osi_FlushText(tvc
); /* only needed to flush text if text locked last time */
140 osi_FlushPages(tvc
, acred
);
142 /* set date on file if open in O_TRUNC mode */
143 if (aflags
& FTRUNC
) {
144 /* this fixes touch */
145 ObtainWriteLock(&tvc
->lock
, 123);
146 tvc
->f
.m
.Date
= osi_Time();
147 tvc
->f
.states
|= CDirty
;
148 ReleaseWriteLock(&tvc
->lock
);
150 ObtainReadLock(&tvc
->lock
);
152 tvc
->execsOrWriters
++;
154 #if defined(AFS_SGI_ENV) || defined (AFS_LINUX26_ENV)
155 if (writing
&& tvc
->cred
== NULL
) {
160 ReleaseReadLock(&tvc
->lock
);
161 if ((afs_preCache
!= 0) && (writing
== 0) && (vType(tvc
) != VDIR
) &&
164 afs_size_t offset
, len
;
166 tdc
= afs_GetDCache(tvc
, 0, treq
, &offset
, &len
, 1);
168 ObtainSharedLock(&tdc
->mflock
, 865);
169 if (!(tdc
->mflags
& DFFetchReq
)) {
172 /* start the daemon (may already be running, however) */
173 UpgradeSToWLock(&tdc
->mflock
, 666);
174 tdc
->mflags
|= DFFetchReq
; /* guaranteed to be cleared by BKG or
176 /* last parm (1) tells bkg daemon to do an afs_PutDCache when it
177 is done, since we don't want to wait for it to finish before
180 bp
= afs_BQueue(BOP_FETCH
, tvc
, B_DONTWAIT
, 0, acred
,
181 (afs_size_t
) 0, (afs_size_t
) 1, tdc
,
182 (void *)0, (void *)0);
184 tdc
->mflags
&= ~DFFetchReq
;
186 ReleaseWriteLock(&tdc
->mflock
);
188 ReleaseSharedLock(&tdc
->mflock
);
193 afs_PutFakeStat(&fakestate
);
196 code
= afs_CheckCode(code
, treq
, 4); /* avoid AIX -O bug */
197 afs_DestroyReq(treq
);
199 afs_Trace2(afs_iclSetp
, CM_TRACE_OPEN
, ICL_TYPE_POINTER
, tvc
,
200 ICL_TYPE_INT32
, 999999);