Bug Summary

File:afs/VNOPS/afs_vnop_rename.c
Location:line 295, column 7
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 * Implements:
12 * afsrename
13 * afs_rename
14 *
15 */
16
17#include <afsconfig.h>
18#include "afs/param.h"
19
20
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"
27
28extern afs_rwlock_t afs_xcbhash;
29
30/* Note that we don't set CDirty here, this is OK because the rename
31 * RPC is called synchronously. */
32
33int
34afsrename(struct vcache *aodp, char *aname1, struct vcache *andp,
35 char *aname2, afs_ucred_tstruct usr_ucred *acred, struct vrequest *areq)
36{
37 struct afs_conn *tc;
38 afs_int32 code = 0;
39 afs_int32 returnCode;
40 int oneDir, doLocally;
41 afs_size_t offset, len;
42 struct VenusFid unlinkFid, fileFid;
43 struct vcache *tvc;
44 struct dcache *tdc1, *tdc2;
45 struct AFSFetchStatus OutOldDirStatus, OutNewDirStatus;
46 struct AFSVolSync tsync;
47 struct rx_connection *rxconn;
48 XSTATS_DECLSstruct afs_stats_opTimingData *opP = ((void *)0); osi_timeval_t
opStartTime = { 0, 0}, opStopTime, elapsedTime
;
49 AFS_STATCNT(afs_rename)((afs_cmstats.callInfo.C_afs_rename)++);
50 afs_Trace4(afs_iclSetp, CM_TRACE_RENAME, ICL_TYPE_POINTER, aodp,(((afs_iclSetp) && (afs_iclSetp->states & 2)) ?
afs_icl_Event4(afs_iclSetp, (701087828L), (1<<24)+((2)
<<18)+((4)<<12)+((2)<<6)+(4), (long)(aodp),
(long)(aname1), (long)(andp), (long)(aname2)) : 0)
51 ICL_TYPE_STRING, aname1, ICL_TYPE_POINTER, andp,(((afs_iclSetp) && (afs_iclSetp->states & 2)) ?
afs_icl_Event4(afs_iclSetp, (701087828L), (1<<24)+((2)
<<18)+((4)<<12)+((2)<<6)+(4), (long)(aodp),
(long)(aname1), (long)(andp), (long)(aname2)) : 0)
52 ICL_TYPE_STRING, aname2)(((afs_iclSetp) && (afs_iclSetp->states & 2)) ?
afs_icl_Event4(afs_iclSetp, (701087828L), (1<<24)+((2)
<<18)+((4)<<12)+((2)<<6)+(4), (long)(aodp),
(long)(aname1), (long)(andp), (long)(aname2)) : 0)
;
53
54 if (strlen(aname1) > AFSNAMEMAX256 || strlen(aname2) > AFSNAMEMAX256) {
1
Taking false branch
55 code = ENAMETOOLONG63;
56 goto done;
57 }
58
59 /* verify the latest versions of the stat cache entries */
60 tagain:
61 code = afs_VerifyVCache(aodp, areq)(((aodp)->f.states & 0x00000001) ? 0 : afs_VerifyVCache2
((aodp),areq))
;
62 if (code)
2
Taking false branch
15
Taking false branch
28
Taking false branch
41
Taking false branch
63 goto done;
64 code = afs_VerifyVCache(andp, areq)(((andp)->f.states & 0x00000001) ? 0 : afs_VerifyVCache2
((andp),areq))
;
65 if (code)
3
Taking false branch
16
Taking false branch
29
Taking false branch
42
Taking false branch
66 goto done;
67
68 /* lock in appropriate order, after some checks */
69 if (aodp->f.fidusr_fid.Cell != andp->f.fidusr_fid.Cell
4
Taking false branch
17
Taking false branch
30
Taking false branch
43
Taking false branch
70 || aodp->f.fidusr_fid.Fid.Volume != andp->f.fidusr_fid.Fid.Volume) {
71 code = EXDEV18;
72 goto done;
73 }
74 oneDir = 0;
75 code = 0;
76 if (andp->f.fidusr_fid.Fid.Vnode == aodp->f.fidusr_fid.Fid.Vnode) {
5
Taking false branch
18
Taking false branch
31
Taking false branch
44
Taking false branch
77 if (!strcmp(aname1, aname2)) {
78 /* Same directory and same name; this is a noop and just return success
79 * to save cycles and follow posix standards */
80
81 code = 0;
82 goto done;
83 }
84
85 if (AFS_IS_DISCONNECTED(afs_is_disconnected) && !AFS_IS_DISCON_RW(afs_is_discon_rw)) {
86 code = ENETDOWN50;
87 goto done;
88 }
89
90 ObtainWriteLock(&andp->lock, 147)do { ; if (!(&andp->lock)->excl_locked && !
(&andp->lock)->readers_reading) (&andp->lock
) -> excl_locked = 2; else Afs_Lock_Obtain(&andp->lock
, 2); (&andp->lock)->pid_writer = (get_user_struct(
)->u_procp->p_pid ); (&andp->lock)->src_indicator
= 147; } while (0)
;
91 tdc1 = afs_GetDCache(aodp, (afs_size_t) 0, areq, &offset, &len, 0);
92 if (!tdc1) {
93 code = ENOENT2;
94 } else {
95 ObtainWriteLock(&tdc1->lock, 643)do { ; if (!(&tdc1->lock)->excl_locked && !
(&tdc1->lock)->readers_reading) (&tdc1->lock
) -> excl_locked = 2; else Afs_Lock_Obtain(&tdc1->lock
, 2); (&tdc1->lock)->pid_writer = (get_user_struct(
)->u_procp->p_pid ); (&tdc1->lock)->src_indicator
= 643; } while (0)
;
96 }
97 tdc2 = tdc1;
98 oneDir = 1; /* only one dude locked */
99 } else if ((andp->f.states & CRO0x00000004) || (aodp->f.states & CRO0x00000004)) {
6
Taking false branch
19
Taking false branch
32
Taking false branch
45
Taking false branch
100 code = EROFS30;
101 goto done;
102 } else if (andp->f.fidusr_fid.Fid.Vnode < aodp->f.fidusr_fid.Fid.Vnode) {
7
Taking false branch
20
Taking false branch
33
Taking false branch
46
Taking false branch
103 ObtainWriteLock(&andp->lock, 148)do { ; if (!(&andp->lock)->excl_locked && !
(&andp->lock)->readers_reading) (&andp->lock
) -> excl_locked = 2; else Afs_Lock_Obtain(&andp->lock
, 2); (&andp->lock)->pid_writer = (get_user_struct(
)->u_procp->p_pid ); (&andp->lock)->src_indicator
= 148; } while (0)
; /* lock smaller one first */
104 ObtainWriteLock(&aodp->lock, 149)do { ; if (!(&aodp->lock)->excl_locked && !
(&aodp->lock)->readers_reading) (&aodp->lock
) -> excl_locked = 2; else Afs_Lock_Obtain(&aodp->lock
, 2); (&aodp->lock)->pid_writer = (get_user_struct(
)->u_procp->p_pid ); (&aodp->lock)->src_indicator
= 149; } while (0)
;
105 tdc2 = afs_FindDCache(andp, (afs_size_t) 0);
106 if (tdc2)
107 ObtainWriteLock(&tdc2->lock, 644)do { ; if (!(&tdc2->lock)->excl_locked && !
(&tdc2->lock)->readers_reading) (&tdc2->lock
) -> excl_locked = 2; else Afs_Lock_Obtain(&tdc2->lock
, 2); (&tdc2->lock)->pid_writer = (get_user_struct(
)->u_procp->p_pid ); (&tdc2->lock)->src_indicator
= 644; } while (0)
;
108 tdc1 = afs_GetDCache(aodp, (afs_size_t) 0, areq, &offset, &len, 0);
109 if (tdc1)
110 ObtainWriteLock(&tdc1->lock, 645)do { ; if (!(&tdc1->lock)->excl_locked && !
(&tdc1->lock)->readers_reading) (&tdc1->lock
) -> excl_locked = 2; else Afs_Lock_Obtain(&tdc1->lock
, 2); (&tdc1->lock)->pid_writer = (get_user_struct(
)->u_procp->p_pid ); (&tdc1->lock)->src_indicator
= 645; } while (0)
;
111 else
112 code = ENOENT2;
113 } else {
114 ObtainWriteLock(&aodp->lock, 150)do { ; if (!(&aodp->lock)->excl_locked && !
(&aodp->lock)->readers_reading) (&aodp->lock
) -> excl_locked = 2; else Afs_Lock_Obtain(&aodp->lock
, 2); (&aodp->lock)->pid_writer = (get_user_struct(
)->u_procp->p_pid ); (&aodp->lock)->src_indicator
= 150; } while (0)
; /* lock smaller one first */
115 ObtainWriteLock(&andp->lock, 557)do { ; if (!(&andp->lock)->excl_locked && !
(&andp->lock)->readers_reading) (&andp->lock
) -> excl_locked = 2; else Afs_Lock_Obtain(&andp->lock
, 2); (&andp->lock)->pid_writer = (get_user_struct(
)->u_procp->p_pid ); (&andp->lock)->src_indicator
= 557; } while (0)
;
116 tdc1 = afs_GetDCache(aodp, (afs_size_t) 0, areq, &offset, &len, 0);
117 if (tdc1)
8
Taking true branch
21
Taking true branch
34
Taking true branch
47
Taking true branch
118 ObtainWriteLock(&tdc1->lock, 646)do { ; if (!(&tdc1->lock)->excl_locked && !
(&tdc1->lock)->readers_reading) (&tdc1->lock
) -> excl_locked = 2; else Afs_Lock_Obtain(&tdc1->lock
, 2); (&tdc1->lock)->pid_writer = (get_user_struct(
)->u_procp->p_pid ); (&tdc1->lock)->src_indicator
= 646; } while (0)
;
119 else
120 code = ENOENT2;
121 tdc2 = afs_FindDCache(andp, (afs_size_t) 0);
122 if (tdc2)
9
Taking false branch
22
Taking false branch
35
Taking false branch
48
Taking false branch
123 ObtainWriteLock(&tdc2->lock, 647)do { ; if (!(&tdc2->lock)->excl_locked && !
(&tdc2->lock)->readers_reading) (&tdc2->lock
) -> excl_locked = 2; else Afs_Lock_Obtain(&tdc2->lock
, 2); (&tdc2->lock)->pid_writer = (get_user_struct(
)->u_procp->p_pid ); (&tdc2->lock)->src_indicator
= 647; } while (0)
;
124 }
125
126 osi_dnlc_remove(aodp, aname1, 0);
127 osi_dnlc_remove(andp, aname2, 0);
128
129 /*
130 * Make sure that the data in the cache is current. We may have
131 * received a callback while we were waiting for the write lock.
132 */
133 if (tdc1) {
10
Taking true branch
23
Taking true branch
36
Taking true branch
49
Taking true branch
134 if (!(aodp->f.states & CStatd0x00000001)
11
Taking true branch
24
Taking true branch
37
Taking true branch
50
Taking false branch
135 || !hsame(aodp->f.m.DataVersion, tdc1->f.versionNo)((aodp->f.m.DataVersion).low == (tdc1->f.versionNo).low
&& (aodp->f.m.DataVersion).high == (tdc1->f.versionNo
).high)
) {
136
137 ReleaseWriteLock(&aodp->lock)do { ; (&aodp->lock)->excl_locked &= ~2; if ((&
aodp->lock)->wait_states) Afs_Lock_ReleaseR(&aodp->
lock); (&aodp->lock)->pid_writer=0; } while (0)
;
138 if (!oneDir) {
12
Taking true branch
25
Taking true branch
38
Taking true branch
139 if (tdc2) {
13
Taking false branch
26
Taking false branch
39
Taking false branch
140 ReleaseWriteLock(&tdc2->lock)do { ; (&tdc2->lock)->excl_locked &= ~2; if ((&
tdc2->lock)->wait_states) Afs_Lock_ReleaseR(&tdc2->
lock); (&tdc2->lock)->pid_writer=0; } while (0)
;
141 afs_PutDCache(tdc2);
142 }
143 ReleaseWriteLock(&andp->lock)do { ; (&andp->lock)->excl_locked &= ~2; if ((&
andp->lock)->wait_states) Afs_Lock_ReleaseR(&andp->
lock); (&andp->lock)->pid_writer=0; } while (0)
;
144 }
145 ReleaseWriteLock(&tdc1->lock)do { ; (&tdc1->lock)->excl_locked &= ~2; if ((&
tdc1->lock)->wait_states) Afs_Lock_ReleaseR(&tdc1->
lock); (&tdc1->lock)->pid_writer=0; } while (0)
;
146 afs_PutDCache(tdc1);
147 goto tagain;
14
Control jumps to line 61
27
Control jumps to line 61
40
Control jumps to line 61
148 }
149 }
150
151 if (code == 0)
51
Taking true branch
152 code = afs_dir_Lookup(tdc1, aname1, &fileFid.Fid);
153 if (code) {
52
Taking false branch
154 if (tdc1) {
155 ReleaseWriteLock(&tdc1->lock)do { ; (&tdc1->lock)->excl_locked &= ~2; if ((&
tdc1->lock)->wait_states) Afs_Lock_ReleaseR(&tdc1->
lock); (&tdc1->lock)->pid_writer=0; } while (0)
;
156 afs_PutDCache(tdc1);
157 }
158 ReleaseWriteLock(&aodp->lock)do { ; (&aodp->lock)->excl_locked &= ~2; if ((&
aodp->lock)->wait_states) Afs_Lock_ReleaseR(&aodp->
lock); (&aodp->lock)->pid_writer=0; } while (0)
;
159 if (!oneDir) {
160 if (tdc2) {
161 ReleaseWriteLock(&tdc2->lock)do { ; (&tdc2->lock)->excl_locked &= ~2; if ((&
tdc2->lock)->wait_states) Afs_Lock_ReleaseR(&tdc2->
lock); (&tdc2->lock)->pid_writer=0; } while (0)
;
162 afs_PutDCache(tdc2);
163 }
164 ReleaseWriteLock(&andp->lock)do { ; (&andp->lock)->excl_locked &= ~2; if ((&
andp->lock)->wait_states) Afs_Lock_ReleaseR(&andp->
lock); (&andp->lock)->pid_writer=0; } while (0)
;
165 }
166 goto done;
167 }
168
169 if (!AFS_IS_DISCON_RW(afs_is_discon_rw)) {
53
Taking false branch
170 /* Connected. */
171 do {
172 tc = afs_Conn(&aodp->f.fidusr_fid, areq, SHARED_LOCK4, &rxconn);
173 if (tc) {
174 XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_RENAME)opP = &(afs_stats_cmfullperf.rpc.fsRPCTimes[8]); osi_GetTime
(&opStartTime);
;
175 RX_AFS_GUNLOCK()do { do { if (!(pthread_self() == afs_global_owner)) { osi_Panic
("afs global lock not held"); } } while(0); memset(&afs_global_owner
, 0, sizeof(pthread_t)); do{if (!(pthread_mutex_unlock(&afs_global_lock
) == 0)) AssertionFailed("/home/wollman/openafs/src/afs/VNOPS/afs_vnop_rename.c"
, 175);}while(0); } while(0)
;
176 code =
177 RXAFS_Rename(rxconn,
178 (struct AFSFid *)&aodp->f.fidusr_fid.Fid,
179 aname1,
180 (struct AFSFid *)&andp->f.fidusr_fid.Fid,
181 aname2,
182 &OutOldDirStatus,
183 &OutNewDirStatus,
184 &tsync);
185 RX_AFS_GLOCK()do { do{if (!(pthread_mutex_lock(&afs_global_lock) == 0))
AssertionFailed("/home/wollman/openafs/src/afs/VNOPS/afs_vnop_rename.c"
, 185);}while(0); afs_global_owner = pthread_self(); } while(
0)
;
186 XSTATS_END_TIMEosi_GetTime(&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; }; } }
;
187 } else
188 code = -1;
189
190 } while (afs_Analyze
191 (tc, rxconn, code, &andp->f.fidusr_fid, areq, AFS_STATS_FS_RPCIDX_RENAME8,
192 SHARED_LOCK4, NULL((void *)0)));
193
194 } else {
195 /* Disconnected. */
196
197 /* Seek moved file vcache. */
198 fileFid.Cell = aodp->f.fidusr_fid.Cell;
199 fileFid.Fid.Volume = aodp->f.fidusr_fid.Fid.Volume;
200 ObtainSharedLock(&afs_xvcache, 754)do { ; if (!(&afs_xvcache)->excl_locked) (&afs_xvcache
) -> excl_locked = 4; else Afs_Lock_Obtain(&afs_xvcache
, 4); (&afs_xvcache)->pid_writer = (get_user_struct()->
u_procp->p_pid ); (&afs_xvcache)->src_indicator = 754
; } while (0)
;
201 tvc = afs_FindVCache(&fileFid, 0 , 1);
202 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
)
;
203
204 if (tvc) {
54
Taking true branch
205 /* XXX - We're locking this vcache whilst holding dcaches. Ooops */
206 ObtainWriteLock(&tvc->lock, 750)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 = (get_user_struct()->
u_procp->p_pid ); (&tvc->lock)->src_indicator = 750
; } while (0)
;
207 if (!(tvc->f.ddirty_flags & (VDisconRename0x00010000|VDisconCreate0x00004000))) {
55
Taking false branch
208 /* If the vnode was created locally, then we don't care
209 * about recording the rename - we'll do it automatically
210 * on replay. If we've already renamed, we've already stored
211 * the required information about where we came from.
212 */
213
214 if (!aodp->f.shadow.vnodeusr_vnode) {
215 /* Make shadow copy of parent dir only. */
216 afs_MakeShadowDir(aodp, tdc1);
217 }
218
219 /* Save old parent dir fid so it will be searchable
220 * in the shadow dir.
221 */
222 tvc->f.oldParent.vnodeusr_vnode = aodp->f.fidusr_fid.Fid.Vnode;
223 tvc->f.oldParent.unique = aodp->f.fidusr_fid.Fid.Unique;
224
225 afs_DisconAddDirty(tvc,
226 VDisconRename0x00010000
227 | (oneDir ? VDisconRenameSameDir0x00020000:0),
228 1);
229 }
230
231 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)
;
232 afs_PutVCache(tvc);
233 } else {
234 code = ENOENT2;
235 } /* if (tvc) */
236 } /* if !(AFS_IS_DISCON_RW)*/
237 returnCode = code; /* remember for later */
238
239 /* Now we try to do things locally. This is really loathsome code. */
240 unlinkFid.Fid.Vnode = 0;
241 if (code == 0) {
56
Taking true branch
242 /* In any event, we don't really care if the data (tdc2) is not
243 * in the cache; if it isn't, we won't do the update locally. */
244 /* see if version numbers increased properly */
245 doLocally = 1;
246 if (!AFS_IS_DISCON_RW(afs_is_discon_rw)) {
57
Taking false branch
247 if (oneDir) {
248 /* number increases by 1 for whole rename operation */
249 if (!afs_LocalHero(aodp, tdc1, &OutOldDirStatus, 1)) {
250 doLocally = 0;
251 }
252 } else {
253 /* two separate dirs, each increasing by 1 */
254 if (!afs_LocalHero(aodp, tdc1, &OutOldDirStatus, 1))
255 doLocally = 0;
256 if (!afs_LocalHero(andp, tdc2, &OutNewDirStatus, 1))
257 doLocally = 0;
258 if (!doLocally) {
259 if (tdc1) {
260 ZapDCE(tdc1)do { (tdc1)->f.usr_fid.Fid.Unique = 0; afs_indexUnique[(tdc1
)->index] = 0; (tdc1)->dflags |= 0x02; } while(0)
;
261 DZap(tdc1);
262 }
263 if (tdc2) {
264 ZapDCE(tdc2)do { (tdc2)->f.usr_fid.Fid.Unique = 0; afs_indexUnique[(tdc2
)->index] = 0; (tdc2)->dflags |= 0x02; } while(0)
;
265 DZap(tdc2);
266 }
267 }
268 }
269 } /* if (!AFS_IS_DISCON_RW) */
270
271 /* now really do the work */
272 if (doLocally) {
58
Taking true branch
273 /* first lookup the fid of the dude we're moving */
274 code = afs_dir_Lookup(tdc1, aname1, &fileFid.Fid);
275 if (code == 0) {
59
Taking false branch
276 /* delete the source */
277 code = afs_dir_Delete(tdc1, aname1);
278 }
279 /* first see if target is there */
280 if (code == 0
60
Taking false branch
281 && afs_dir_Lookup(tdc2, aname2,
282 &unlinkFid.Fid) == 0) {
283 /* target already exists, and will be unlinked by server */
284 code = afs_dir_Delete(tdc2, aname2);
285 }
286 if (code == 0) {
61
Taking false branch
287 ObtainWriteLock(&afs_xdcache, 292)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 = (get_user_struct()->u_procp->p_pid )
; (&afs_xdcache)->src_indicator = 292; } while (0)
;
288 code = afs_dir_Create(tdc2, aname2, &fileFid.Fid);
289 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)
;
290 }
291 if (code != 0) {
62
Taking true branch
292 ZapDCE(tdc1)do { (tdc1)->f.usr_fid.Fid.Unique = 0; afs_indexUnique[(tdc1
)->index] = 0; (tdc1)->dflags |= 0x02; } while(0)
;
293 DZap(tdc1);
294 if (!oneDir) {
63
Taking true branch
295 ZapDCE(tdc2)do { (tdc2)->f.usr_fid.Fid.Unique = 0; afs_indexUnique[(tdc2
)->index] = 0; (tdc2)->dflags |= 0x02; } while(0)
;
64
Within the expansion of the macro 'ZapDCE':
a
Dereference of null pointer
296 DZap(tdc2);
297 }
298 }
299 }
300
301
302 /* update dir link counts */
303 if (AFS_IS_DISCON_RW(afs_is_discon_rw)) {
304 if (!oneDir) {
305 aodp->f.m.LinkCount--;
306 andp->f.m.LinkCount++;
307 }
308 /* If we're in the same directory, link count doesn't change */
309 } else {
310 aodp->f.m.LinkCount = OutOldDirStatus.LinkCount;
311 if (!oneDir)
312 andp->f.m.LinkCount = OutNewDirStatus.LinkCount;
313 }
314
315 } else { /* operation failed (code != 0) */
316 if (code < 0) {
317 /* if failed, server might have done something anyway, and
318 * assume that we know about it */
319 ObtainWriteLock(&afs_xcbhash, 498)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 = (get_user_struct()->u_procp->p_pid )
; (&afs_xcbhash)->src_indicator = 498; } while (0)
;
320 afs_DequeueCallback(aodp);
321 afs_DequeueCallback(andp);
322 andp->f.states &= ~CStatd0x00000001;
323 aodp->f.states &= ~CStatd0x00000001;
324 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)
;
325 osi_dnlc_purgedp(andp);
326 osi_dnlc_purgedp(aodp);
327 }
328 }
329
330 /* release locks */
331 if (tdc1) {
332 ReleaseWriteLock(&tdc1->lock)do { ; (&tdc1->lock)->excl_locked &= ~2; if ((&
tdc1->lock)->wait_states) Afs_Lock_ReleaseR(&tdc1->
lock); (&tdc1->lock)->pid_writer=0; } while (0)
;
333 afs_PutDCache(tdc1);
334 }
335
336 if ((!oneDir) && tdc2) {
337 ReleaseWriteLock(&tdc2->lock)do { ; (&tdc2->lock)->excl_locked &= ~2; if ((&
tdc2->lock)->wait_states) Afs_Lock_ReleaseR(&tdc2->
lock); (&tdc2->lock)->pid_writer=0; } while (0)
;
338 afs_PutDCache(tdc2);
339 }
340
341 ReleaseWriteLock(&aodp->lock)do { ; (&aodp->lock)->excl_locked &= ~2; if ((&
aodp->lock)->wait_states) Afs_Lock_ReleaseR(&aodp->
lock); (&aodp->lock)->pid_writer=0; } while (0)
;
342
343 if (!oneDir) {
344 ReleaseWriteLock(&andp->lock)do { ; (&andp->lock)->excl_locked &= ~2; if ((&
andp->lock)->wait_states) Afs_Lock_ReleaseR(&andp->
lock); (&andp->lock)->pid_writer=0; } while (0)
;
345 }
346
347 if (returnCode) {
348 code = returnCode;
349 goto done;
350 }
351
352 /* now, some more details. if unlinkFid.Fid.Vnode then we should decrement
353 * the link count on this file. Note that if fileFid is a dir, then we don't
354 * have to invalidate its ".." entry, since its DataVersion # should have
355 * changed. However, interface is not good enough to tell us the
356 * *file*'s new DataVersion, so we're stuck. Our hack: delete mark
357 * the data as having an "unknown" version (effectively discarding the ".."
358 * entry */
359 if (unlinkFid.Fid.Vnode) {
360
361 unlinkFid.Fid.Volume = aodp->f.fidusr_fid.Fid.Volume;
362 unlinkFid.Cell = aodp->f.fidusr_fid.Cell;
363 tvc = NULL((void *)0);
364 if (!unlinkFid.Fid.Unique) {
365 tvc = afs_LookupVCache(&unlinkFid, areq, NULL((void *)0), aodp, aname1);
366 }
367 if (!tvc) /* lookup failed or wasn't called */
368 tvc = afs_GetVCache(&unlinkFid, areq, NULL((void *)0), NULL((void *)0));
369
370 if (tvc) {
371#ifdef AFS_BOZONLOCK_ENV
372 afs_BozonLock(&tvc->pvnLock, tvc); /* Since afs_TryToSmush will do a pvn_vptrunc */
373#endif
374 ObtainWriteLock(&tvc->lock, 151)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 = (get_user_struct()->
u_procp->p_pid ); (&tvc->lock)->src_indicator = 151
; } while (0)
;
375 tvc->f.m.LinkCount--;
376 tvc->f.states &= ~CUnique0x00001000; /* For the dfs xlator */
377 if (tvc->f.m.LinkCount == 0 && !osi_Active(tvc)) {
378 /* if this was last guy (probably) discard from cache.
379 * We have to be careful to not get rid of the stat
380 * information, since otherwise operations will start
381 * failing even if the file was still open (or
382 * otherwise active), and the server no longer has the
383 * info. If the file still has valid links, we'll get
384 * a break-callback msg from the server, so it doesn't
385 * matter that we don't discard the status info */
386 if (!AFS_NFSXLATORREQ(acred)(((acred)->cr_rgid) == 0xaaaa))
387 afs_TryToSmush(tvc, acred, 0);
388 }
389 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)
;
390#ifdef AFS_BOZONLOCK_ENV
391 afs_BozonUnlock(&tvc->pvnLock, tvc);
392#endif
393 afs_PutVCache(tvc);
394 }
395 }
396
397 /* now handle ".." invalidation */
398 if (!oneDir) {
399 fileFid.Fid.Volume = aodp->f.fidusr_fid.Fid.Volume;
400 fileFid.Cell = aodp->f.fidusr_fid.Cell;
401 if (!fileFid.Fid.Unique)
402 tvc = afs_LookupVCache(&fileFid, areq, NULL((void *)0), andp, aname2);
403 else
404 tvc = afs_GetVCache(&fileFid, areq, NULL((void *)0), (struct vcache *)0);
405 if (tvc && (vType(tvc)(tvc)->v.v_type == VDIR0040000)) {
406 ObtainWriteLock(&tvc->lock, 152)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 = (get_user_struct()->
u_procp->p_pid ); (&tvc->lock)->src_indicator = 152
; } while (0)
;
407 tdc1 = afs_FindDCache(tvc, (afs_size_t) 0);
408 if (tdc1) {
409 if (AFS_IS_DISCON_RW(afs_is_discon_rw)) {
410 /* If disconnected, we need to fix (not discard) the "..".*/
411 afs_dir_ChangeFid(tdc1,
412 "..",
413 &aodp->f.fidusr_fid.Fid.Vnode,
414 &andp->f.fidusr_fid.Fid.Vnode);
415 } else {
416 ObtainWriteLock(&tdc1->lock, 648)do { ; if (!(&tdc1->lock)->excl_locked && !
(&tdc1->lock)->readers_reading) (&tdc1->lock
) -> excl_locked = 2; else Afs_Lock_Obtain(&tdc1->lock
, 2); (&tdc1->lock)->pid_writer = (get_user_struct(
)->u_procp->p_pid ); (&tdc1->lock)->src_indicator
= 648; } while (0)
;
417 ZapDCE(tdc1)do { (tdc1)->f.usr_fid.Fid.Unique = 0; afs_indexUnique[(tdc1
)->index] = 0; (tdc1)->dflags |= 0x02; } while(0)
; /* mark as unknown */
418 DZap(tdc1);
419 ReleaseWriteLock(&tdc1->lock)do { ; (&tdc1->lock)->excl_locked &= ~2; if ((&
tdc1->lock)->wait_states) Afs_Lock_ReleaseR(&tdc1->
lock); (&tdc1->lock)->pid_writer=0; } while (0)
;
420 afs_PutDCache(tdc1); /* put it back */
421 }
422 }
423 osi_dnlc_remove(tvc, "..", 0);
424 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)
;
425 afs_PutVCache(tvc);
426 } else if (AFS_IS_DISCON_RW(afs_is_discon_rw) && tvc && (vType(tvc)(tvc)->v.v_type == VREG0100000)) {
427 /* XXX - Should tvc not get locked here? */
428 tvc->f.parent.vnodeusr_vnode = andp->f.fidusr_fid.Fid.Vnode;
429 tvc->f.parent.unique = andp->f.fidusr_fid.Fid.Unique;
430 } else if (tvc) {
431 /* True we shouldn't come here since tvc SHOULD be a dir, but we
432 * 'syntactically' need to unless we change the 'if' above...
433 */
434 afs_PutVCache(tvc);
435 }
436 }
437 code = returnCode;
438 done:
439 return code;
440}
441
442int
443#if defined(AFS_SGI_ENV)
444afs_rename(OSI_VC_DECL(aodp)struct vcache *aodp, char *aname1, struct vcache *andp, char *aname2, struct pathname *npnp, afs_ucred_tstruct usr_ucred *acred)
445#else
446afs_rename(OSI_VC_DECL(aodp)struct vcache *aodp, char *aname1, struct vcache *andp, char *aname2, afs_ucred_tstruct usr_ucred *acred)
447#endif
448{
449 afs_int32 code;
450 struct afs_fakestat_state ofakestate;
451 struct afs_fakestat_state nfakestate;
452 struct vrequest treq;
453 OSI_VC_CONVERT(aodp);
454
455 code = afs_InitReq(&treq, acred);
456 if (code)
457 return code;
458 afs_InitFakeStat(&ofakestate);
459 afs_InitFakeStat(&nfakestate);
460
461 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
= (get_user_struct()->u_procp->p_pid ); } while (0)
;
462
463 code = afs_EvalFakeStat(&aodp, &ofakestate, &treq);
464 if (code)
465 goto done;
466 code = afs_EvalFakeStat(&andp, &nfakestate, &treq);
467 if (code)
468 goto done;
469 code = afsrename(aodp, aname1, andp, aname2, acred, &treq);
470 done:
471 afs_PutFakeStat(&ofakestate);
472 afs_PutFakeStat(&nfakestate);
473
474 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
== (get_user_struct()->u_procp->p_pid ) ) (&afs_discon_lock
)->pid_last_reader =0; } while (0)
;
475
476 code = afs_CheckCode(code, &treq, 25);
477 return code;
478}