Bug Summary

File:afs/VNOPS/afs_vnop_link.c
Location:line 139, 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 * Implements:
12 * afs_link
13 *
14 */
15
16#include <afsconfig.h>
17#include "afs/param.h"
18
19
20#include "afs/sysincludes.h" /* Standard vendor system headers */
21#include "afsincludes.h" /* Afs-based standard headers */
22#include "afs/afs_stats.h" /* statistics */
23#include "afs/afs_cbqueue.h"
24#include "afs/nfsclient.h"
25#include "afs/afs_osidnlc.h"
26
27extern afs_rwlock_t afs_xcbhash;
28
29/* Note that we don't set CDirty here, this is OK because the link
30 * RPC is called synchronously. */
31
32int
33#if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV)
34afs_link(OSI_VC_DECL(adp)struct vcache *adp, struct vcache *avc, char *aname,
35 afs_ucred_t *acred)
36#else
37afs_link(struct vcache *avc, OSI_VC_DECL(adp)struct vcache *adp, char *aname,
38 afs_ucred_t *acred)
39#endif
40{
41 struct vrequest treq;
42 struct dcache *tdc;
43 afs_int32 code;
44 struct afs_conn *tc;
45 afs_size_t offset, len;
46 struct AFSFetchStatus OutFidStatus, OutDirStatus;
47 struct AFSVolSync tsync;
48 struct afs_fakestat_state vfakestate, dfakestate;
49 struct rx_connection *rxconn;
50 XSTATS_DECLSstruct afs_stats_opTimingData *opP = ((void *)0); osi_timeval_t
opStartTime = { 0, 0}, opStopTime, elapsedTime
;
51 OSI_VC_CONVERT(adp);
52
53 AFS_STATCNT(afs_link)((afs_cmstats.callInfo.C_afs_link)++);
54 afs_Trace3(afs_iclSetp, CM_TRACE_LINK, ICL_TYPE_POINTER, adp,(((afs_iclSetp) && (afs_iclSetp->states & 2)) ?
afs_icl_Event3(afs_iclSetp, (701087827L), (1<<24)+((2)
<<18)+((2)<<12)+((4)<<6), (long)(adp), (long
)(avc), (long)(aname)) : 0)
55 ICL_TYPE_POINTER, avc, ICL_TYPE_STRING, aname)(((afs_iclSetp) && (afs_iclSetp->states & 2)) ?
afs_icl_Event3(afs_iclSetp, (701087827L), (1<<24)+((2)
<<18)+((2)<<12)+((4)<<6), (long)(adp), (long
)(avc), (long)(aname)) : 0)
;
56 /* create a hard link; new entry is aname in dir adp */
57 if ((code = afs_InitReq(&treq, acred)))
1
Taking false branch
58 goto done2;
59
60 afs_InitFakeStat(&vfakestate);
61 afs_InitFakeStat(&dfakestate);
62
63 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)
;
64
65 code = afs_EvalFakeStat(&avc, &vfakestate, &treq);
66 if (code)
2
Taking false branch
67 goto done;
68 code = afs_EvalFakeStat(&adp, &dfakestate, &treq);
69 if (code)
3
Taking false branch
70 goto done;
71
72 if (avc->f.fid.Cell != adp->f.fid.Cell
4
Taking false branch
73 || avc->f.fid.Fid.Volume != adp->f.fid.Fid.Volume) {
74 code = EXDEV18;
75 goto done;
76 }
77 if (strlen(aname) > AFSNAMEMAX256) {
5
Taking false branch
78 code = ENAMETOOLONG63;
79 goto done;
80 }
81 code = afs_VerifyVCache(adp, &treq)(((adp)->f.states & 0x00000001) ? 0 : afs_VerifyVCache2
((adp),&treq))
;
82 if (code)
6
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) {
7
Taking false branch
89 code = EROFS30;
90 goto done;
91 }
92
93 if (AFS_IS_DISCONNECTED(afs_is_disconnected)) {
8
Taking false branch
94 code = ENETDOWN50;
95 goto done;
96 }
97
98 tdc = afs_GetDCache(adp, (afs_size_t) 0, &treq, &offset, &len, 1); /* test for error below */
99 ObtainWriteLock(&adp->lock, 145)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 = 145; }
while (0)
;
100 do {
10
Loop condition is true. Execution continues on line 101
12
Loop condition is false. Exiting loop
101 tc = afs_Conn(&adp->f.fid, &treq, SHARED_LOCK4, &rxconn);
102 if (tc) {
9
Taking false branch
11
Taking true branch
103 XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_LINK)opP = &(afs_stats_cmfullperf.rpc.fsRPCTimes[10]); microtime
(&opStartTime);
;
104 RX_AFS_GUNLOCK()do { (void)0; _mtx_unlock_flags(((&afs_global_mtx)), (0),
"/home/wollman/openafs/src/afs/VNOPS/afs_vnop_link.c", 104);
} while (0)
;
105 code =
106 RXAFS_Link(rxconn, (struct AFSFid *)&adp->f.fid.Fid, aname,
107 (struct AFSFid *)&avc->f.fid.Fid, &OutFidStatus,
108 &OutDirStatus, &tsync);
109 RX_AFS_GLOCK()do { (void)0; _mtx_lock_flags(((&afs_global_mtx)), (0), "/home/wollman/openafs/src/afs/VNOPS/afs_vnop_link.c"
, 109); (void)0; } while (0)
;
110 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; }; } }
;
111
112 } else
113 code = -1;
114 } while (afs_Analyze
115 (tc, rxconn, code, &adp->f.fid, &treq, AFS_STATS_FS_RPCIDX_LINK10,
116 SHARED_LOCK4, NULL((void *)0)));
117
118 if (code) {
13
Taking false branch
119 if (tdc)
120 afs_PutDCache(tdc);
121 if (code < 0) {
122 ObtainWriteLock(&afs_xcbhash, 492)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 = 492; } while (0)
;
123 afs_DequeueCallback(adp);
124 adp->f.states &= ~CStatd0x00000001;
125 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)
;
126 osi_dnlc_purgedp(adp);
127 }
128 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)
;
129 goto done;
130 }
131 if (tdc)
14
Taking false branch
132 ObtainWriteLock(&tdc->lock, 635)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 = 635; }
while (0)
;
133 if (afs_LocalHero(adp, tdc, &OutDirStatus, 1)) {
15
Taking true branch
134 /* we can do it locally */
135 ObtainWriteLock(&afs_xdcache, 290)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 = 290; } while (0)
;
136 code = afs_dir_Create(tdc, aname, &avc->f.fid.Fid);
137 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)
;
138 if (code) {
16
Taking true branch
139 ZapDCE(tdc)do { (tdc)->f.fid.Fid.Unique = 0; afs_indexUnique[(tdc)->
index] = 0; (tdc)->dflags |= 0x02; } while(0)
; /* surprise error -- invalid value */
17
Within the expansion of the macro 'ZapDCE':
a
Dereference of null pointer
140 DZap(tdc);
141 }
142 }
143 if (tdc) {
144 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)
;
145 afs_PutDCache(tdc); /* drop ref count */
146 }
147 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)
;
148 ObtainWriteLock(&avc->lock, 146)do { ; if (!(&avc->lock)->excl_locked && !(
&avc->lock)->readers_reading) (&avc->lock) ->
excl_locked = 2; else Afs_Lock_Obtain(&avc->lock, 2);
(&avc->lock)->pid_writer = (((__curthread())->td_proc
)->p_pid ); (&avc->lock)->src_indicator = 146; }
while (0)
; /* correct link count */
149
150 /* we could lock both dir and file; since we get the new fid
151 * status back, you'd think we could put it in the cache status
152 * entry at that point. Note that if we don't lock the file over
153 * the rpc call, we have no guarantee that the status info
154 * returned in ustat is the most recent to store in the file's
155 * cache entry */
156
157 ObtainWriteLock(&afs_xcbhash, 493)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 = 493; } while (0)
;
158 afs_DequeueCallback(avc);
159 avc->f.states &= ~CStatd0x00000001; /* don't really know new link count */
160 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)
;
161 if (avc->f.fid.Fid.Vnode & 1 || (vType(avc)((avc)->v)->v_type == VDIR))
162 osi_dnlc_purgedp(avc);
163 ReleaseWriteLock(&avc->lock)do { ; (&avc->lock)->excl_locked &= ~2; if ((&
avc->lock)->wait_states) Afs_Lock_ReleaseR(&avc->
lock); (&avc->lock)->pid_writer=0; } while (0)
;
164 code = 0;
165 done:
166 code = afs_CheckCode(code, &treq, 24);
167 afs_PutFakeStat(&vfakestate);
168 afs_PutFakeStat(&dfakestate);
169 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)
;
170 done2:
171 return code;
172}