| File: | afs/VNOPS/afs_vnop_link.c |
| Location: | line 139, column 6 |
| Description: | Dereference of null pointer |
| 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 | |||||
| 27 | extern 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 | |||||
| 32 | int | ||||
| 33 | #if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) | ||||
| 34 | afs_link(OSI_VC_DECL(adp)struct vcache *adp, struct vcache *avc, char *aname, | ||||
| 35 | afs_ucred_tstruct usr_ucred *acred) | ||||
| 36 | #else | ||||
| 37 | afs_link(struct vcache *avc, OSI_VC_DECL(adp)struct vcache *adp, char *aname, | ||||
| 38 | afs_ucred_tstruct usr_ucred *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))) | ||||
| |||||
| 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 = (get_user_struct()->u_procp->p_pid ); } while (0); | ||||
| 64 | |||||
| 65 | code = afs_EvalFakeStat(&avc, &vfakestate, &treq); | ||||
| 66 | if (code) | ||||
| |||||
| 67 | goto done; | ||||
| 68 | code = afs_EvalFakeStat(&adp, &dfakestate, &treq); | ||||
| 69 | if (code) | ||||
| |||||
| 70 | goto done; | ||||
| 71 | |||||
| 72 | if (avc->f.fidusr_fid.Cell != adp->f.fidusr_fid.Cell | ||||
| |||||
| 73 | || avc->f.fidusr_fid.Fid.Volume != adp->f.fidusr_fid.Fid.Volume) { | ||||
| 74 | code = EXDEV18; | ||||
| 75 | goto done; | ||||
| 76 | } | ||||
| 77 | if (strlen(aname) > AFSNAMEMAX256) { | ||||
| |||||
| 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) | ||||
| |||||
| 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) { | ||||
| |||||
| 89 | code = EROFS30; | ||||
| 90 | goto done; | ||||
| 91 | } | ||||
| 92 | |||||
| 93 | if (AFS_IS_DISCONNECTED(afs_is_disconnected)) { | ||||
| |||||
| 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 = (get_user_struct()-> u_procp->p_pid ); (&adp->lock)->src_indicator = 145 ; } while (0); | ||||
| 100 | do { | ||||
| |||||
| |||||
| 101 | tc = afs_Conn(&adp->f.fidusr_fid, &treq, SHARED_LOCK4, &rxconn); | ||||
| 102 | if (tc) { | ||||
| |||||
| |||||
| 103 | XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_LINK)opP = &(afs_stats_cmfullperf.rpc.fsRPCTimes[10]); osi_GetTime (&opStartTime);; | ||||
| 104 | 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_link.c" , 104);}while(0); } while(0); | ||||
| 105 | code = | ||||
| 106 | RXAFS_Link(rxconn, (struct AFSFid *)&adp->f.fidusr_fid.Fid, aname, | ||||
| 107 | (struct AFSFid *)&avc->f.fidusr_fid.Fid, &OutFidStatus, | ||||
| 108 | &OutDirStatus, &tsync); | ||||
| 109 | RX_AFS_GLOCK()do { do{if (!(pthread_mutex_lock(&afs_global_lock) == 0)) AssertionFailed("/home/wollman/openafs/src/afs/VNOPS/afs_vnop_link.c" , 109);}while(0); afs_global_owner = pthread_self(); } while( 0); | ||||
| 110 | 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; }; } }; | ||||
| 111 | |||||
| 112 | } else | ||||
| 113 | code = -1; | ||||
| 114 | } while (afs_Analyze | ||||
| 115 | (tc, rxconn, code, &adp->f.fidusr_fid, &treq, AFS_STATS_FS_RPCIDX_LINK10, | ||||
| 116 | SHARED_LOCK4, NULL((void *)0))); | ||||
| 117 | |||||
| 118 | if (code) { | ||||
| |||||
| 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 = (get_user_struct()->u_procp->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) | ||||
| |||||
| 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 = (get_user_struct()-> u_procp->p_pid ); (&tdc->lock)->src_indicator = 635 ; } while (0); | ||||
| 133 | if (afs_LocalHero(adp, tdc, &OutDirStatus, 1)) { | ||||
| |||||
| 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 = (get_user_struct()->u_procp->p_pid ) ; (&afs_xdcache)->src_indicator = 290; } while (0); | ||||
| 136 | code = afs_dir_Create(tdc, aname, &avc->f.fidusr_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) { | ||||
| |||||
| 139 | ZapDCE(tdc)do { (tdc)->f.usr_fid.Fid.Unique = 0; afs_indexUnique[(tdc )->index] = 0; (tdc)->dflags |= 0x02; } while(0); /* surprise error -- invalid value */ | ||||
| |||||
| 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 = (get_user_struct()-> u_procp->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 = (get_user_struct()->u_procp->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.fidusr_fid.Fid.Vnode & 1 || (vType(avc)(avc)->v.v_type == VDIR0040000)) | ||||
| 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 == (get_user_struct()->u_procp->p_pid ) ) (&afs_discon_lock )->pid_last_reader =0; } while (0); | ||||
| 170 | done2: | ||||
| 171 | return code; | ||||
| 172 | } |