Bug Summary

File:afs/VNOPS/afs_vnop_dirops.c
Location:line 172, column 6
Description:Dereference of null pointer

Annotated Source Code

1/*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
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
8 */
9
10/*
11 * afs_vnop_dirops.c - make and remove directories
12 *
13 * Implements:
14 *
15 * afs_mkdir
16 * afs_rmdir
17 *
18 */
19
20#include <afsconfig.h>
21#include "afs/param.h"
22
23
24#include "afs/sysincludes.h" /* Standard vendor system headers */
25#include "afsincludes.h" /* Afs-based standard headers */
26#include "afs/afs_stats.h" /* statistics */
27#include "afs/afs_cbqueue.h"
28#include "afs/nfsclient.h"
29#include "afs/afs_osidnlc.h"
30
31extern afs_rwlock_t afs_xvcache;
32extern afs_rwlock_t afs_xcbhash;
33
34/* don't set CDirty in here because RPC is called synchronously */
35
36int
37afs_mkdir(OSI_VC_DECL(adp)struct vcache *adp, char *aname, struct vattr *attrs,
38 struct vcache **avcp, afs_ucred_t *acred)
39{
40 struct vrequest treq;
41 afs_int32 code;
42 struct afs_conn *tc;
43 struct rx_connection *rxconn;
44 struct VenusFid newFid;
45 struct dcache *tdc;
46 struct dcache *new_dc;
47 afs_size_t offset, len;
48 struct vcache *tvc;
49 struct AFSStoreStatus InStatus;
50 struct AFSFetchStatus OutFidStatus, OutDirStatus;
51 struct AFSCallBack CallBack;
52 struct AFSVolSync tsync;
53 afs_int32 now;
54 struct afs_fakestat_state fakestate;
55 XSTATS_DECLSstruct afs_stats_opTimingData *opP = ((void *)0); osi_timeval_t
opStartTime = { 0, 0}, opStopTime, elapsedTime
;
56 OSI_VC_CONVERT(adp);
57
58 AFS_STATCNT(afs_mkdir)((afs_cmstats.callInfo.C_afs_mkdir)++);
59 afs_Trace2(afs_iclSetp, CM_TRACE_MKDIR, ICL_TYPE_POINTER, adp,(((afs_iclSetp) && (afs_iclSetp->states & 2)) ?
afs_icl_Event2(afs_iclSetp, (701087829L), (1<<24)+((2)
<<18)+((4)<<12), (long)(adp), (long)(aname)) : 0)
60 ICL_TYPE_STRING, aname)(((afs_iclSetp) && (afs_iclSetp->states & 2)) ?
afs_icl_Event2(afs_iclSetp, (701087829L), (1<<24)+((2)
<<18)+((4)<<12), (long)(adp), (long)(aname)) : 0)
;
61
62 if ((code = afs_InitReq(&treq, acred)))
1
Taking false branch
63 goto done2;
64 afs_InitFakeStat(&fakestate);
65
66 if (strlen(aname) > AFSNAMEMAX256) {
2
Taking false branch
67 code = ENAMETOOLONG63;
68 goto done3;
69 }
70
71 if (!afs_ENameOK(aname)) {
3
Taking false branch
72 code = EINVAL22;
73 goto done3;
74 }
75
76 AFS_DISCON_LOCK()do { ; if (!((&afs_discon_lock)->excl_locked & 2))
((&afs_discon_lock)->readers_reading)++; else Afs_Lock_Obtain
(&afs_discon_lock, 1); (&afs_discon_lock)->pid_last_reader
= (((__curthread())->td_proc)->p_pid ); } while (0)
;
77
78 code = afs_EvalFakeStat(&adp, &fakestate, &treq);
79 if (code)
4
Taking false branch
80 goto done;
81 code = afs_VerifyVCache(adp, &treq)(((adp)->f.states & 0x00000001) ? 0 : afs_VerifyVCache2
((adp),&treq))
;
82 if (code)
5
Taking false branch
83 goto done;
84
85 /** If the volume is read-only, return error without making an RPC to the
86 * fileserver
87 */
88 if (adp->f.states & CRO0x00000004) {
6
Taking false branch
89 code = EROFS30;
90 goto done;
91 }
92
93 if (AFS_IS_DISCONNECTED(afs_is_disconnected) && !AFS_IS_DISCON_RW(afs_is_discon_rw)) {
7
Taking false branch
94 /*printf("Network is down in afs_mkdir\n");*/
95 code = ENETDOWN50;
96 goto done;
97 }
98 InStatus.Mask = AFS_SETMODTIME1 | AFS_SETMODE8 | AFS_SETGROUP4;
99 InStatus.ClientModTime = osi_Time()time_second;
100 InStatus.UnixModeBits = attrs->va_mode & 0xffff; /* only care about protection bits */
101 InStatus.Group = (afs_int32) afs_cr_gid(acred)((acred)->cr_groups[0]);
102 tdc = afs_GetDCache(adp, (afs_size_t) 0, &treq, &offset, &len, 1);
103 ObtainWriteLock(&adp->lock, 153)do { ; if (!(&adp->lock)->excl_locked && !(
&adp->lock)->readers_reading) (&adp->lock) ->
excl_locked = 2; else Afs_Lock_Obtain(&adp->lock, 2);
(&adp->lock)->pid_writer = (((__curthread())->td_proc
)->p_pid ); (&adp->lock)->src_indicator = 153; }
while (0)
;
104
105 if (!AFS_IS_DISCON_RW(afs_is_discon_rw)) {
8
Taking false branch
106 do {
107 tc = afs_Conn(&adp->f.fid, &treq, SHARED_LOCK4, &rxconn);
108 if (tc) {
109 XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_MAKEDIR)opP = &(afs_stats_cmfullperf.rpc.fsRPCTimes[11]); microtime
(&opStartTime);
;
110 now = osi_Time()time_second;
111 RX_AFS_GUNLOCK()do { (void)0; _mtx_unlock_flags(((&afs_global_mtx)), (0),
"/home/wollman/openafs/src/afs/VNOPS/afs_vnop_dirops.c", 111
); } while (0)
;
112 code =
113 RXAFS_MakeDir(rxconn,
114 (struct AFSFid *)&adp->f.fid.Fid,
115 aname,
116 &InStatus,
117 (struct AFSFid *)&newFid.Fid,
118 &OutFidStatus,
119 &OutDirStatus,
120 &CallBack,
121 &tsync);
122 RX_AFS_GLOCK()do { (void)0; _mtx_lock_flags(((&afs_global_mtx)), (0), "/home/wollman/openafs/src/afs/VNOPS/afs_vnop_dirops.c"
, 122); (void)0; } while (0)
;
123 XSTATS_END_TIMEmicrotime(&opStopTime); (opP->numOps)++; if (!code) { (
opP->numSuccesses)++; { if (opStopTime.tv_usec < opStartTime
.tv_usec) { opStopTime.tv_usec += 1000000; opStopTime.tv_sec -=
1; } elapsedTime.tv_sec = opStopTime.tv_sec - opStartTime.tv_sec
; elapsedTime.tv_usec = opStopTime.tv_usec - opStartTime.tv_usec
; }; { (opP->sumTime).tv_sec += elapsedTime.tv_sec; (opP->
sumTime).tv_usec += elapsedTime.tv_usec; if ((opP->sumTime
).tv_usec > 1000000) { (opP->sumTime).tv_usec -= 1000000
; (opP->sumTime).tv_sec++; } }; { if(elapsedTime.tv_sec >
0 ) { (opP->sqrTime).tv_sec += elapsedTime.tv_sec * elapsedTime
.tv_sec + 2 * elapsedTime.tv_sec * elapsedTime.tv_usec /1000000
; (opP->sqrTime).tv_usec += (2 * elapsedTime.tv_sec * elapsedTime
.tv_usec) % 1000000 + (elapsedTime.tv_usec / 1000)*(elapsedTime
.tv_usec / 1000) + 2 * (elapsedTime.tv_usec / 1000) * (elapsedTime
.tv_usec % 1000) / 1000 + (((elapsedTime.tv_usec % 1000) >
707) ? 1 : 0); } else { (opP->sqrTime).tv_usec += (elapsedTime
.tv_usec / 1000)*(elapsedTime.tv_usec / 1000) + 2 * (elapsedTime
.tv_usec / 1000) * (elapsedTime.tv_usec % 1000) / 1000 + (((elapsedTime
.tv_usec % 1000) > 707) ? 1 : 0); } if ((opP->sqrTime).
tv_usec > 1000000) { (opP->sqrTime).tv_usec -= 1000000;
(opP->sqrTime).tv_sec++; } }; if (((elapsedTime.tv_sec <
(opP->minTime).tv_sec) ? 1 : (elapsedTime.tv_sec > (opP
->minTime).tv_sec) ? 0 : (elapsedTime.tv_usec < (opP->
minTime).tv_usec) ? 1 : 0)) { { (opP->minTime).tv_sec = elapsedTime
.tv_sec; (opP->minTime).tv_usec = elapsedTime.tv_usec; }; }
if (((elapsedTime.tv_sec > (opP->maxTime).tv_sec) ? 1 :
(elapsedTime.tv_sec < (opP->maxTime).tv_sec) ? 0 : (elapsedTime
.tv_usec > (opP->maxTime).tv_usec) ? 1 : 0)) { { (opP->
maxTime).tv_sec = elapsedTime.tv_sec; (opP->maxTime).tv_usec
= elapsedTime.tv_usec; }; } }
;
124 CallBack.ExpirationTime += now;
125 /* DON'T forget to Set the callback value... */
126 } else
127 code = -1;
128 } while (afs_Analyze
129 (tc, rxconn, code, &adp->f.fid, &treq, AFS_STATS_FS_RPCIDX_MAKEDIR11,
130 SHARED_LOCK4, NULL((void *)0)));
131
132 if (code) {
133 if (code < 0) {
134 ObtainWriteLock(&afs_xcbhash, 490)do { ; if (!(&afs_xcbhash)->excl_locked && !(&
afs_xcbhash)->readers_reading) (&afs_xcbhash) -> excl_locked
= 2; else Afs_Lock_Obtain(&afs_xcbhash, 2); (&afs_xcbhash
)->pid_writer = (((__curthread())->td_proc)->p_pid )
; (&afs_xcbhash)->src_indicator = 490; } while (0)
;
135 afs_DequeueCallback(adp);
136 adp->f.states &= ~CStatd0x00000001;
137 ReleaseWriteLock(&afs_xcbhash)do { ; (&afs_xcbhash)->excl_locked &= ~2; if ((&
afs_xcbhash)->wait_states) Afs_Lock_ReleaseR(&afs_xcbhash
); (&afs_xcbhash)->pid_writer=0; } while (0)
;
138 osi_dnlc_purgedp(adp);
139 }
140 ReleaseWriteLock(&adp->lock)do { ; (&adp->lock)->excl_locked &= ~2; if ((&
adp->lock)->wait_states) Afs_Lock_ReleaseR(&adp->
lock); (&adp->lock)->pid_writer=0; } while (0)
;
141 if (tdc)
142 afs_PutDCache(tdc);
143 goto done;
144 }
145
146 } else {
147 /* Disconnected. */
148
149 /* We have the dir entry now, we can use it while disconnected. */
150 if (adp->mvid == NULL((void *)0)) {
9
Taking false branch
151 /* If not mount point, generate a new fid. */
152 newFid.Cell = adp->f.fid.Cell;
153 newFid.Fid.Volume = adp->f.fid.Fid.Volume;
154 afs_GenFakeFid(&newFid, VDIR, 1);
155 }
156 /* XXX: If mount point???*/
157
158 /* Operations with the actual dir's cache entry are further
159 * down, where the dir entry gets created.
160 */
161 } /* if (!AFS_IS_DISCON_RW) */
162
163 /* otherwise, we should see if we can make the change to the dir locally */
164 if (tdc)
10
Taking false branch
165 ObtainWriteLock(&tdc->lock, 632)do { ; if (!(&tdc->lock)->excl_locked && !(
&tdc->lock)->readers_reading) (&tdc->lock) ->
excl_locked = 2; else Afs_Lock_Obtain(&tdc->lock, 2);
(&tdc->lock)->pid_writer = (((__curthread())->td_proc
)->p_pid ); (&tdc->lock)->src_indicator = 632; }
while (0)
;
166 if (AFS_IS_DISCON_RW(afs_is_discon_rw) || afs_LocalHero(adp, tdc, &OutDirStatus, 1)) {
11
Taking true branch
167 /* we can do it locally */
168 ObtainWriteLock(&afs_xdcache, 294)do { ; if (!(&afs_xdcache)->excl_locked && !(&
afs_xdcache)->readers_reading) (&afs_xdcache) -> excl_locked
= 2; else Afs_Lock_Obtain(&afs_xdcache, 2); (&afs_xdcache
)->pid_writer = (((__curthread())->td_proc)->p_pid )
; (&afs_xdcache)->src_indicator = 294; } while (0)
;
169 code = afs_dir_Create(tdc, aname, &newFid.Fid);
170 ReleaseWriteLock(&afs_xdcache)do { ; (&afs_xdcache)->excl_locked &= ~2; if ((&
afs_xdcache)->wait_states) Afs_Lock_ReleaseR(&afs_xdcache
); (&afs_xdcache)->pid_writer=0; } while (0)
;
171 if (code) {
12
Taking true branch
172 ZapDCE(tdc)do { (tdc)->f.fid.Fid.Unique = 0; afs_indexUnique[(tdc)->
index] = 0; (tdc)->dflags |= 0x02; } while(0)
; /* surprise error -- use invalid value */
13
Within the expansion of the macro 'ZapDCE':
a
Dereference of null pointer
173 DZap(tdc);
174 }
175 }
176 if (tdc) {
177 ReleaseWriteLock(&tdc->lock)do { ; (&tdc->lock)->excl_locked &= ~2; if ((&
tdc->lock)->wait_states) Afs_Lock_ReleaseR(&tdc->
lock); (&tdc->lock)->pid_writer=0; } while (0)
;
178 afs_PutDCache(tdc);
179 }
180
181 if (AFS_IS_DISCON_RW(afs_is_discon_rw))
182 /* We will have to settle with the local link count. */
183 adp->f.m.LinkCount++;
184 else
185 adp->f.m.LinkCount = OutDirStatus.LinkCount;
186 newFid.Cell = adp->f.fid.Cell;
187 newFid.Fid.Volume = adp->f.fid.Fid.Volume;
188 ReleaseWriteLock(&adp->lock)do { ; (&adp->lock)->excl_locked &= ~2; if ((&
adp->lock)->wait_states) Afs_Lock_ReleaseR(&adp->
lock); (&adp->lock)->pid_writer=0; } while (0)
;
189 if (AFS_IS_DISCON_RW(afs_is_discon_rw)) {
190 /* When disconnected, we have to create the full dir here. */
191
192 /* Generate a new vcache and fill it. */
193 tvc = afs_NewVCache(&newFid, NULL((void *)0));
194 if (tvc) {
195 *avcp = tvc;
196 } else {
197 code = ENOENT2;
198 goto done;
199 }
200
201 ObtainWriteLock(&tvc->lock, 738)do { ; if (!(&tvc->lock)->excl_locked && !(
&tvc->lock)->readers_reading) (&tvc->lock) ->
excl_locked = 2; else Afs_Lock_Obtain(&tvc->lock, 2);
(&tvc->lock)->pid_writer = (((__curthread())->td_proc
)->p_pid ); (&tvc->lock)->src_indicator = 738; }
while (0)
;
202 afs_GenDisconStatus(adp, tvc, &newFid, attrs, &treq, VDIR);
203 ReleaseWriteLock(&tvc->lock)do { ; (&tvc->lock)->excl_locked &= ~2; if ((&
tvc->lock)->wait_states) Afs_Lock_ReleaseR(&tvc->
lock); (&tvc->lock)->pid_writer=0; } while (0)
;
204
205 /* And now make an empty dir, containing . and .. : */
206 /* Get a new dcache for it first. */
207 new_dc = afs_GetDCache(tvc, (afs_size_t) 0, &treq, &offset, &len, 1);
208 if (!new_dc) {
209 /* printf("afs_mkdir: can't get new dcache for dir.\n"); */
210 code = ENOENT2;
211 goto done;
212 }
213
214 ObtainWriteLock(&afs_xdcache, 739)do { ; if (!(&afs_xdcache)->excl_locked && !(&
afs_xdcache)->readers_reading) (&afs_xdcache) -> excl_locked
= 2; else Afs_Lock_Obtain(&afs_xdcache, 2); (&afs_xdcache
)->pid_writer = (((__curthread())->td_proc)->p_pid )
; (&afs_xdcache)->src_indicator = 739; } while (0)
;
215 code = afs_dir_MakeDir(new_dc,
216 (afs_int32 *) &newFid.Fid,
217 (afs_int32 *) &adp->f.fid.Fid);
218 ReleaseWriteLock(&afs_xdcache)do { ; (&afs_xdcache)->excl_locked &= ~2; if ((&
afs_xdcache)->wait_states) Afs_Lock_ReleaseR(&afs_xdcache
); (&afs_xdcache)->pid_writer=0; } while (0)
;
219 /* if (code) printf("afs_mkdir: afs_dirMakeDir code = %u\n", code); */
220
221 afs_PutDCache(new_dc);
222
223 ObtainWriteLock(&tvc->lock, 731)do { ; if (!(&tvc->lock)->excl_locked && !(
&tvc->lock)->readers_reading) (&tvc->lock) ->
excl_locked = 2; else Afs_Lock_Obtain(&tvc->lock, 2);
(&tvc->lock)->pid_writer = (((__curthread())->td_proc
)->p_pid ); (&tvc->lock)->src_indicator = 731; }
while (0)
;
224 /* Update length in the vcache. */
225 tvc->f.m.Length = new_dc->f.chunkBytes;
226
227 afs_DisconAddDirty(tvc, VDisconCreate0x00004000, 1);
228 ReleaseWriteLock(&tvc->lock)do { ; (&tvc->lock)->excl_locked &= ~2; if ((&
tvc->lock)->wait_states) Afs_Lock_ReleaseR(&tvc->
lock); (&tvc->lock)->pid_writer=0; } while (0)
;
229 } else {
230 /* now we're done with parent dir, create the real dir's cache entry */
231 tvc = afs_GetVCache(&newFid, &treq, NULL((void *)0), NULL((void *)0));
232 if (tvc) {
233 code = 0;
234 *avcp = tvc;
235 } else
236 code = ENOENT2;
237 } /* if (AFS_DISCON_RW) */
238
239 done:
240 AFS_DISCON_UNLOCK()do { ; if (!(--((&afs_discon_lock)->readers_reading)) &&
(&afs_discon_lock)->wait_states) Afs_Lock_ReleaseW(&
afs_discon_lock) ; if ( (&afs_discon_lock)->pid_last_reader
== (((__curthread())->td_proc)->p_pid ) ) (&afs_discon_lock
)->pid_last_reader =0; } while (0)
;
241 done3:
242 afs_PutFakeStat(&fakestate);
243 code = afs_CheckCode(code, &treq, 26);
244 done2:
245 return code;
246}
247
248
249int
250/* don't set CDirty in here because RPC is called synchronously */
251#if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV)
252afs_rmdir(OSI_VC_DECL(adp)struct vcache *adp, char *aname, struct vnode *cdirp,
253 afs_ucred_t *acred)
254#else
255afs_rmdir(OSI_VC_DECL(adp)struct vcache *adp, char *aname, afs_ucred_t *acred)
256#endif
257{
258 struct vrequest treq;
259 struct dcache *tdc;
260 struct vcache *tvc = NULL((void *)0);
261 afs_int32 code;
262 struct afs_conn *tc;
263 afs_size_t offset, len;
264 struct AFSFetchStatus OutDirStatus;
265 struct AFSVolSync tsync;
266 struct afs_fakestat_state fakestate;
267 struct rx_connection *rxconn;
268 XSTATS_DECLSstruct afs_stats_opTimingData *opP = ((void *)0); osi_timeval_t
opStartTime = { 0, 0}, opStopTime, elapsedTime
;
269 OSI_VC_CONVERT(adp);
270
271 AFS_STATCNT(afs_rmdir)((afs_cmstats.callInfo.C_afs_rmdir)++);
272
273 afs_Trace2(afs_iclSetp, CM_TRACE_RMDIR, ICL_TYPE_POINTER, adp,(((afs_iclSetp) && (afs_iclSetp->states & 2)) ?
afs_icl_Event2(afs_iclSetp, (701087830L), (1<<24)+((2)
<<18)+((4)<<12), (long)(adp), (long)(aname)) : 0)
274 ICL_TYPE_STRING, aname)(((afs_iclSetp) && (afs_iclSetp->states & 2)) ?
afs_icl_Event2(afs_iclSetp, (701087830L), (1<<24)+((2)
<<18)+((4)<<12), (long)(adp), (long)(aname)) : 0)
;
275
276 if ((code = afs_InitReq(&treq, acred)))
277 goto done2;
278 afs_InitFakeStat(&fakestate);
279
280 if (strlen(aname) > AFSNAMEMAX256) {
281 code = ENAMETOOLONG63;
282 goto done;
283 }
284
285 AFS_DISCON_LOCK()do { ; if (!((&afs_discon_lock)->excl_locked & 2))
((&afs_discon_lock)->readers_reading)++; else Afs_Lock_Obtain
(&afs_discon_lock, 1); (&afs_discon_lock)->pid_last_reader
= (((__curthread())->td_proc)->p_pid ); } while (0)
;
286
287 code = afs_EvalFakeStat(&adp, &fakestate, &treq);
288 if (code)
289 goto done;
290
291 code = afs_VerifyVCache(adp, &treq)(((adp)->f.states & 0x00000001) ? 0 : afs_VerifyVCache2
((adp),&treq))
;
292 if (code)
293 goto done;
294
295 /** If the volume is read-only, return error without making an RPC to the
296 * fileserver
297 */
298 if (adp->f.states & CRO0x00000004) {
299 code = EROFS30;
300 goto done;
301 }
302
303 if (AFS_IS_DISCONNECTED(afs_is_disconnected) && !AFS_IS_DISCON_RW(afs_is_discon_rw)) {
304 /* Disconnected read only mode. */
305 code = ENETDOWN50;
306 goto done;
307 }
308
309 tdc = afs_GetDCache(adp, (afs_size_t) 0, &treq, &offset, &len, 1); /* test for error below */
310 ObtainWriteLock(&adp->lock, 154)do { ; if (!(&adp->lock)->excl_locked && !(
&adp->lock)->readers_reading) (&adp->lock) ->
excl_locked = 2; else Afs_Lock_Obtain(&adp->lock, 2);
(&adp->lock)->pid_writer = (((__curthread())->td_proc
)->p_pid ); (&adp->lock)->src_indicator = 154; }
while (0)
;
311 if (tdc)
312 ObtainSharedLock(&tdc->lock, 633)do { ; if (!(&tdc->lock)->excl_locked) (&tdc->
lock) -> excl_locked = 4; else Afs_Lock_Obtain(&tdc->
lock, 4); (&tdc->lock)->pid_writer = (((__curthread
())->td_proc)->p_pid ); (&tdc->lock)->src_indicator
= 633; } while (0)
;
313 if (tdc && (adp->f.states & CForeign0x00002000)) {
314 struct VenusFid unlinkFid;
315
316 unlinkFid.Fid.Vnode = 0;
317 code = afs_dir_Lookup(tdc, aname, &unlinkFid.Fid);
318 if (code == 0) {
319 afs_int32 cached = 0;
320
321 unlinkFid.Cell = adp->f.fid.Cell;
322 unlinkFid.Fid.Volume = adp->f.fid.Fid.Volume;
323 if (unlinkFid.Fid.Unique == 0) {
324 tvc =
325 afs_LookupVCache(&unlinkFid, &treq, &cached, adp, aname);
326 } else {
327 ObtainReadLock(&afs_xvcache)do { ; if (!((&afs_xvcache)->excl_locked & 2)) ((&
afs_xvcache)->readers_reading)++; else Afs_Lock_Obtain(&
afs_xvcache, 1); (&afs_xvcache)->pid_last_reader = (((
__curthread())->td_proc)->p_pid ); } while (0)
;
328 tvc = afs_FindVCache(&unlinkFid, 0, 1 /* do xstats */ );
329 ReleaseReadLock(&afs_xvcache)do { ; if (!(--((&afs_xvcache)->readers_reading)) &&
(&afs_xvcache)->wait_states) Afs_Lock_ReleaseW(&afs_xvcache
) ; if ( (&afs_xvcache)->pid_last_reader == (((__curthread
())->td_proc)->p_pid ) ) (&afs_xvcache)->pid_last_reader
=0; } while (0)
;
330 }
331 }
332 }
333
334 if (!AFS_IS_DISCON_RW(afs_is_discon_rw)) {
335 /* Not disconnected, can connect to server. */
336 do {
337 tc = afs_Conn(&adp->f.fid, &treq, SHARED_LOCK4, &rxconn);
338 if (tc) {
339 XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_REMOVEDIR)opP = &(afs_stats_cmfullperf.rpc.fsRPCTimes[12]); microtime
(&opStartTime);
;
340 RX_AFS_GUNLOCK()do { (void)0; _mtx_unlock_flags(((&afs_global_mtx)), (0),
"/home/wollman/openafs/src/afs/VNOPS/afs_vnop_dirops.c", 340
); } while (0)
;
341 code =
342 RXAFS_RemoveDir(rxconn,
343 (struct AFSFid *)&adp->f.fid.Fid,
344 aname,
345 &OutDirStatus,
346 &tsync);
347 RX_AFS_GLOCK()do { (void)0; _mtx_lock_flags(((&afs_global_mtx)), (0), "/home/wollman/openafs/src/afs/VNOPS/afs_vnop_dirops.c"
, 347); (void)0; } while (0)
;
348 XSTATS_END_TIMEmicrotime(&opStopTime); (opP->numOps)++; if (!code) { (
opP->numSuccesses)++; { if (opStopTime.tv_usec < opStartTime
.tv_usec) { opStopTime.tv_usec += 1000000; opStopTime.tv_sec -=
1; } elapsedTime.tv_sec = opStopTime.tv_sec - opStartTime.tv_sec
; elapsedTime.tv_usec = opStopTime.tv_usec - opStartTime.tv_usec
; }; { (opP->sumTime).tv_sec += elapsedTime.tv_sec; (opP->
sumTime).tv_usec += elapsedTime.tv_usec; if ((opP->sumTime
).tv_usec > 1000000) { (opP->sumTime).tv_usec -= 1000000
; (opP->sumTime).tv_sec++; } }; { if(elapsedTime.tv_sec >
0 ) { (opP->sqrTime).tv_sec += elapsedTime.tv_sec * elapsedTime
.tv_sec + 2 * elapsedTime.tv_sec * elapsedTime.tv_usec /1000000
; (opP->sqrTime).tv_usec += (2 * elapsedTime.tv_sec * elapsedTime
.tv_usec) % 1000000 + (elapsedTime.tv_usec / 1000)*(elapsedTime
.tv_usec / 1000) + 2 * (elapsedTime.tv_usec / 1000) * (elapsedTime
.tv_usec % 1000) / 1000 + (((elapsedTime.tv_usec % 1000) >
707) ? 1 : 0); } else { (opP->sqrTime).tv_usec += (elapsedTime
.tv_usec / 1000)*(elapsedTime.tv_usec / 1000) + 2 * (elapsedTime
.tv_usec / 1000) * (elapsedTime.tv_usec % 1000) / 1000 + (((elapsedTime
.tv_usec % 1000) > 707) ? 1 : 0); } if ((opP->sqrTime).
tv_usec > 1000000) { (opP->sqrTime).tv_usec -= 1000000;
(opP->sqrTime).tv_sec++; } }; if (((elapsedTime.tv_sec <
(opP->minTime).tv_sec) ? 1 : (elapsedTime.tv_sec > (opP
->minTime).tv_sec) ? 0 : (elapsedTime.tv_usec < (opP->
minTime).tv_usec) ? 1 : 0)) { { (opP->minTime).tv_sec = elapsedTime
.tv_sec; (opP->minTime).tv_usec = elapsedTime.tv_usec; }; }
if (((elapsedTime.tv_sec > (opP->maxTime).tv_sec) ? 1 :
(elapsedTime.tv_sec < (opP->maxTime).tv_sec) ? 0 : (elapsedTime
.tv_usec > (opP->maxTime).tv_usec) ? 1 : 0)) { { (opP->
maxTime).tv_sec = elapsedTime.tv_sec; (opP->maxTime).tv_usec
= elapsedTime.tv_usec; }; } }
;
349 } else
350 code = -1;
351 } while (afs_Analyze
352 (tc, rxconn, code, &adp->f.fid, &treq, AFS_STATS_FS_RPCIDX_REMOVEDIR12,
353 SHARED_LOCK4, NULL((void *)0)));
354
355 if (code) {
356 if (tdc) {
357 ReleaseSharedLock(&tdc->lock)do { ; (&tdc->lock)->excl_locked &= ~(4 | 2); if
((&tdc->lock)->wait_states) Afs_Lock_ReleaseR(&
tdc->lock); (&tdc->lock)->pid_writer=0; } while (
0)
;
358 afs_PutDCache(tdc);
359 }
360
361 if (code < 0) {
362 ObtainWriteLock(&afs_xcbhash, 491)do { ; if (!(&afs_xcbhash)->excl_locked && !(&
afs_xcbhash)->readers_reading) (&afs_xcbhash) -> excl_locked
= 2; else Afs_Lock_Obtain(&afs_xcbhash, 2); (&afs_xcbhash
)->pid_writer = (((__curthread())->td_proc)->p_pid )
; (&afs_xcbhash)->src_indicator = 491; } while (0)
;
363 afs_DequeueCallback(adp);
364 adp->f.states &= ~CStatd0x00000001;
365 ReleaseWriteLock(&afs_xcbhash)do { ; (&afs_xcbhash)->excl_locked &= ~2; if ((&
afs_xcbhash)->wait_states) Afs_Lock_ReleaseR(&afs_xcbhash
); (&afs_xcbhash)->pid_writer=0; } while (0)
;
366 osi_dnlc_purgedp(adp);
367 }
368 ReleaseWriteLock(&adp->lock)do { ; (&adp->lock)->excl_locked &= ~2; if ((&
adp->lock)->wait_states) Afs_Lock_ReleaseR(&adp->
lock); (&adp->lock)->pid_writer=0; } while (0)
;
369 goto done;
370 }
371
372 /* here if rpc worked; update the in-core link count */
373 adp->f.m.LinkCount = OutDirStatus.LinkCount;
374
375 } else {
376 /* Disconnected. */
377
378 if (!tdc) {
379 ReleaseWriteLock(&adp->lock)do { ; (&adp->lock)->excl_locked &= ~2; if ((&
adp->lock)->wait_states) Afs_Lock_ReleaseR(&adp->
lock); (&adp->lock)->pid_writer=0; } while (0)
;
380 /* printf("afs_rmdir: No local dcache!\n"); */
381 code = ENETDOWN50;
382 goto done;
383 }
384
385 if (!tvc) {
386 /* Find the vcache. */
387 struct VenusFid tfid;
388
389 tfid.Cell = adp->f.fid.Cell;
390 tfid.Fid.Volume = adp->f.fid.Fid.Volume;
391 code = afs_dir_Lookup(tdc, aname, &tfid.Fid);
392
393 ObtainSharedLock(&afs_xvcache, 764)do { ; if (!(&afs_xvcache)->excl_locked) (&afs_xvcache
) -> excl_locked = 4; else Afs_Lock_Obtain(&afs_xvcache
, 4); (&afs_xvcache)->pid_writer = (((__curthread())->
td_proc)->p_pid ); (&afs_xvcache)->src_indicator = 764
; } while (0)
;
394 tvc = afs_FindVCache(&tfid, 0, 1 /* do xstats */ );
395 ReleaseSharedLock(&afs_xvcache)do { ; (&afs_xvcache)->excl_locked &= ~(4 | 2); if
((&afs_xvcache)->wait_states) Afs_Lock_ReleaseR(&
afs_xvcache); (&afs_xvcache)->pid_writer=0; } while (0
)
;
396
397 if (!tvc) {
398 /* printf("afs_rmdir: Can't find dir's vcache!\n"); */
399 ReleaseSharedLock(&tdc->lock)do { ; (&tdc->lock)->excl_locked &= ~(4 | 2); if
((&tdc->lock)->wait_states) Afs_Lock_ReleaseR(&
tdc->lock); (&tdc->lock)->pid_writer=0; } while (
0)
;
400 afs_PutDCache(tdc); /* drop ref count */
401 ReleaseWriteLock(&adp->lock)do { ; (&adp->lock)->excl_locked &= ~2; if ((&
adp->lock)->wait_states) Afs_Lock_ReleaseR(&adp->
lock); (&adp->lock)->pid_writer=0; } while (0)
;
402 code = ENETDOWN50;
403 goto done;
404 }
405 }
406
407 if (tvc->f.m.LinkCount > 2) {
408 /* This dir contains more than . and .., thus it can't be
409 * deleted.
410 */
411 ReleaseSharedLock(&tdc->lock)do { ; (&tdc->lock)->excl_locked &= ~(4 | 2); if
((&tdc->lock)->wait_states) Afs_Lock_ReleaseR(&
tdc->lock); (&tdc->lock)->pid_writer=0; } while (
0)
;
412 afs_PutDCache(tdc);
413 afs_PutVCache(tvc);
414 ReleaseWriteLock(&adp->lock)do { ; (&adp->lock)->excl_locked &= ~2; if ((&
adp->lock)->wait_states) Afs_Lock_ReleaseR(&adp->
lock); (&adp->lock)->pid_writer=0; } while (0)
;
415 code = ENOTEMPTY66;
416 goto done;
417 }
418
419 /* Make a shadow copy of the parent dir (if not done already).
420 * If we were created locally, then we don't need to have a shadow
421 * directory (as there's no server state to remember)
422 */
423 if (!adp->f.shadow.vnode && !(adp->f.ddirty_flags & VDisconCreate0x00004000)) {
424 afs_MakeShadowDir(adp, tdc);
425 }
426
427 adp->f.m.LinkCount--;
428 } /* if (!AFS_IS_DISCON_RW) */
429
430 if (tdc)
431 UpgradeSToWLock(&tdc->lock, 634)do { ; if (!(&tdc->lock)->readers_reading) (&tdc
->lock)->excl_locked = 2; else Afs_Lock_Obtain(&tdc
->lock, 6); (&tdc->lock)->pid_writer = (((__curthread
())->td_proc)->p_pid ); (&tdc->lock)->src_indicator
= 634; } while (0)
;
432 if (AFS_IS_DISCON_RW(afs_is_discon_rw) || afs_LocalHero(adp, tdc, &OutDirStatus, 1)) {
433 /* we can do it locally */
434 code = afs_dir_Delete(tdc, aname);
435 if (code) {
436 ZapDCE(tdc)do { (tdc)->f.fid.Fid.Unique = 0; afs_indexUnique[(tdc)->
index] = 0; (tdc)->dflags |= 0x02; } while(0)
; /* surprise error -- invalid value */
437 DZap(tdc);
438 }
439 }
440 if (tdc) {
441 ReleaseWriteLock(&tdc->lock)do { ; (&tdc->lock)->excl_locked &= ~2; if ((&
tdc->lock)->wait_states) Afs_Lock_ReleaseR(&tdc->
lock); (&tdc->lock)->pid_writer=0; } while (0)
;
442 afs_PutDCache(tdc); /* drop ref count */
443 }
444
445 if (tvc)
446 osi_dnlc_purgedp(tvc); /* get rid of any entries for this directory */
447 else
448 osi_dnlc_remove(adp, aname, 0);
449
450 if (tvc) {
451 ObtainWriteLock(&tvc->lock, 155)do { ; if (!(&tvc->lock)->excl_locked && !(
&tvc->lock)->readers_reading) (&tvc->lock) ->
excl_locked = 2; else Afs_Lock_Obtain(&tvc->lock, 2);
(&tvc->lock)->pid_writer = (((__curthread())->td_proc
)->p_pid ); (&tvc->lock)->src_indicator = 155; }
while (0)
;
452 tvc->f.states &= ~CUnique0x00001000; /* For the dfs xlator */
453 if (AFS_IS_DISCON_RW(afs_is_discon_rw)) {
454 if (tvc->f.ddirty_flags & VDisconCreate0x00004000) {
455 /* If we we were created whilst disconnected, removal doesn't
456 * need to get logged. Just go away gracefully */
457 afs_DisconRemoveDirty(tvc);
458 } else {
459 afs_DisconAddDirty(tvc, VDisconRemove0x00002000, 1);
460 }
461 }
462 ReleaseWriteLock(&tvc->lock)do { ; (&tvc->lock)->excl_locked &= ~2; if ((&
tvc->lock)->wait_states) Afs_Lock_ReleaseR(&tvc->
lock); (&tvc->lock)->pid_writer=0; } while (0)
;
463 afs_PutVCache(tvc);
464 }
465 ReleaseWriteLock(&adp->lock)do { ; (&adp->lock)->excl_locked &= ~2; if ((&
adp->lock)->wait_states) Afs_Lock_ReleaseR(&adp->
lock); (&adp->lock)->pid_writer=0; } while (0)
;
466 /* don't worry about link count since dirs can not be hardlinked */
467 code = 0;
468
469 done:
470 AFS_DISCON_UNLOCK()do { ; if (!(--((&afs_discon_lock)->readers_reading)) &&
(&afs_discon_lock)->wait_states) Afs_Lock_ReleaseW(&
afs_discon_lock) ; if ( (&afs_discon_lock)->pid_last_reader
== (((__curthread())->td_proc)->p_pid ) ) (&afs_discon_lock
)->pid_last_reader =0; } while (0)
;
471 afs_PutFakeStat(&fakestate);
472 code = afs_CheckCode(code, &treq, 27);
473 done2:
474 return code;
475}