*/
#include <afsconfig.h>
-#include "../afs/param.h"
+#include "afs/param.h"
-RCSID("$Header$");
-#include "../afs/sysincludes.h" /* Standard vendor system headers */
-#include "../afs/afsincludes.h" /* Afs-based standard headers */
-#include "../afs/afs_stats.h" /* statistics */
-#include "../afs/afs_cbqueue.h"
-#include "../afs/nfsclient.h"
-#include "../afs/afs_osidnlc.h"
+#include "afs/sysincludes.h" /* Standard vendor system headers */
+#include "afsincludes.h" /* Afs-based standard headers */
+#include "afs/afs_stats.h" /* statistics */
+#include "afs/afs_cbqueue.h"
+#include "afs/nfsclient.h"
+#include "afs/afs_osidnlc.h"
extern afs_rwlock_t afs_xcbhash;
/* Note that we don't set CDirty here, this is OK because the rename
* RPC is called synchronously. */
-afsrename(aodp, aname1, andp, aname2, acred)
- register struct vcache *aodp, *andp;
- char *aname1, *aname2;
- struct AFS_UCRED *acred; {
- struct vrequest treq;
- register struct conn *tc;
- register afs_int32 code;
+int
+afsrename(struct vcache *aodp, char *aname1, struct vcache *andp,
+ char *aname2, afs_ucred_t *acred, struct vrequest *areq)
+{
+ struct afs_conn *tc;
+ afs_int32 code = 0;
afs_int32 returnCode;
int oneDir, doLocally;
afs_size_t offset, len;
struct dcache *tdc1, *tdc2;
struct AFSFetchStatus OutOldDirStatus, OutNewDirStatus;
struct AFSVolSync tsync;
- XSTATS_DECLS
-
+ XSTATS_DECLS;
AFS_STATCNT(afs_rename);
- afs_Trace4(afs_iclSetp, CM_TRACE_RENAME, ICL_TYPE_POINTER, aodp,
+ afs_Trace4(afs_iclSetp, CM_TRACE_RENAME, ICL_TYPE_POINTER, aodp,
ICL_TYPE_STRING, aname1, ICL_TYPE_POINTER, andp,
ICL_TYPE_STRING, aname2);
- if (code = afs_InitReq(&treq, acred)) return code;
+ if (strlen(aname1) > AFSNAMEMAX || strlen(aname2) > AFSNAMEMAX) {
+ code = ENAMETOOLONG;
+ goto done;
+ }
/* verify the latest versions of the stat cache entries */
-tagain:
- code = afs_VerifyVCache(aodp, &treq);
- if (code) goto done;
- code = afs_VerifyVCache(andp, &treq);
- if (code) goto done;
-
+ tagain:
+ code = afs_VerifyVCache(aodp, areq);
+ if (code)
+ goto done;
+ code = afs_VerifyVCache(andp, areq);
+ if (code)
+ goto done;
+
/* lock in appropriate order, after some checks */
- if (aodp->fid.Cell != andp->fid.Cell || aodp->fid.Fid.Volume != andp->fid.Fid.Volume) {
+ if (aodp->f.fid.Cell != andp->f.fid.Cell
+ || aodp->f.fid.Fid.Volume != andp->f.fid.Fid.Volume) {
code = EXDEV;
goto done;
}
oneDir = 0;
code = 0;
- if (andp->fid.Fid.Vnode == aodp->fid.Fid.Vnode) {
+ if (andp->f.fid.Fid.Vnode == aodp->f.fid.Fid.Vnode) {
if (!strcmp(aname1, aname2)) {
/* Same directory and same name; this is a noop and just return success
* to save cycles and follow posix standards */
code = 0;
goto done;
}
- ObtainWriteLock(&andp->lock,147);
- tdc1 = afs_GetDCache(aodp, (afs_size_t) 0, &treq, &offset, &len, 0);
+
+ if (AFS_IS_DISCONNECTED && !AFS_IS_DISCON_RW) {
+ code = ENETDOWN;
+ goto done;
+ }
+
+ ObtainWriteLock(&andp->lock, 147);
+ tdc1 = afs_GetDCache(aodp, (afs_size_t) 0, areq, &offset, &len, 0);
if (!tdc1) {
code = ENOENT;
} else {
ObtainWriteLock(&tdc1->lock, 643);
}
tdc2 = tdc1;
- oneDir = 1; /* only one dude locked */
- }
- else if ((andp->states & CRO) || (aodp->states & CRO)) {
- code = EROFS;
- goto done;
- }
- else if (andp->fid.Fid.Vnode < aodp->fid.Fid.Vnode) {
- ObtainWriteLock(&andp->lock,148); /* lock smaller one first */
- ObtainWriteLock(&aodp->lock,149);
- tdc2 = afs_FindDCache(andp, 0);
- if (tdc2) ObtainWriteLock(&tdc2->lock, 644);
- tdc1 = afs_GetDCache(aodp, (afs_size_t) 0, &treq, &offset, &len, 0);
+ oneDir = 1; /* only one dude locked */
+ } else if ((andp->f.states & CRO) || (aodp->f.states & CRO)) {
+ code = EROFS;
+ goto done;
+ } else if (andp->f.fid.Fid.Vnode < aodp->f.fid.Fid.Vnode) {
+ ObtainWriteLock(&andp->lock, 148); /* lock smaller one first */
+ ObtainWriteLock(&aodp->lock, 149);
+ tdc2 = afs_FindDCache(andp, (afs_size_t) 0);
+ if (tdc2)
+ ObtainWriteLock(&tdc2->lock, 644);
+ tdc1 = afs_GetDCache(aodp, (afs_size_t) 0, areq, &offset, &len, 0);
if (tdc1)
ObtainWriteLock(&tdc1->lock, 645);
else
code = ENOENT;
- }
- else {
- ObtainWriteLock(&aodp->lock,150); /* lock smaller one first */
- ObtainWriteLock(&andp->lock,557);
- tdc1 = afs_GetDCache(aodp, (afs_size_t) 0, &treq, &offset, &len, 0);
+ } else {
+ ObtainWriteLock(&aodp->lock, 150); /* lock smaller one first */
+ ObtainWriteLock(&andp->lock, 557);
+ tdc1 = afs_GetDCache(aodp, (afs_size_t) 0, areq, &offset, &len, 0);
if (tdc1)
ObtainWriteLock(&tdc1->lock, 646);
else
code = ENOENT;
- tdc2 = afs_FindDCache(andp, 0);
- if (tdc2) ObtainWriteLock(&tdc2->lock, 647);
+ tdc2 = afs_FindDCache(andp, (afs_size_t) 0);
+ if (tdc2)
+ ObtainWriteLock(&tdc2->lock, 647);
}
- osi_dnlc_remove (aodp, aname1, 0);
- osi_dnlc_remove (andp, aname2, 0);
- afs_symhint_inval(aodp);
- afs_symhint_inval(andp);
+ osi_dnlc_remove(aodp, aname1, 0);
+ osi_dnlc_remove(andp, aname2, 0);
/*
* Make sure that the data in the cache is current. We may have
* received a callback while we were waiting for the write lock.
*/
if (tdc1) {
- if (!(aodp->states & CStatd)
- || !hsame(aodp->m.DataVersion, tdc1->f.versionNo)) {
+ if (!(aodp->f.states & CStatd)
+ || !hsame(aodp->f.m.DataVersion, tdc1->f.versionNo)) {
ReleaseWriteLock(&aodp->lock);
if (!oneDir) {
}
if (code == 0)
- code = afs_dir_Lookup(&tdc1->f.inode, aname1, &fileFid.Fid);
+ code = afs_dir_Lookup(tdc1, aname1, &fileFid.Fid);
if (code) {
if (tdc1) {
ReleaseWriteLock(&tdc1->lock);
goto done;
}
- /* locks are now set, proceed to do the real work */
- do {
- tc = afs_Conn(&aodp->fid, &treq, SHARED_LOCK);
- if (tc) {
- XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_RENAME);
-#ifdef RX_ENABLE_LOCKS
- AFS_GUNLOCK();
-#endif /* RX_ENABLE_LOCKS */
- code = RXAFS_Rename(tc->id, (struct AFSFid *) &aodp->fid.Fid, aname1,
- (struct AFSFid *) &andp->fid.Fid, aname2,
- &OutOldDirStatus, &OutNewDirStatus, &tsync);
-#ifdef RX_ENABLE_LOCKS
- AFS_GLOCK();
-#endif /* RX_ENABLE_LOCKS */
- XSTATS_END_TIME;
- } else code = -1;
-
- } while
- (afs_Analyze(tc, code, &andp->fid, &treq,
- AFS_STATS_FS_RPCIDX_RENAME, SHARED_LOCK, (struct cell *)0));
-
- returnCode = code; /* remember for later */
-
+ if (!AFS_IS_DISCON_RW) {
+ /* Connected. */
+ do {
+ tc = afs_Conn(&aodp->f.fid, areq, SHARED_LOCK);
+ if (tc) {
+ XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_RENAME);
+ RX_AFS_GUNLOCK();
+ code =
+ RXAFS_Rename(tc->id,
+ (struct AFSFid *)&aodp->f.fid.Fid,
+ aname1,
+ (struct AFSFid *)&andp->f.fid.Fid,
+ aname2,
+ &OutOldDirStatus,
+ &OutNewDirStatus,
+ &tsync);
+ RX_AFS_GLOCK();
+ XSTATS_END_TIME;
+ } else
+ code = -1;
+
+ } while (afs_Analyze
+ (tc, code, &andp->f.fid, areq, AFS_STATS_FS_RPCIDX_RENAME,
+ SHARED_LOCK, NULL));
+
+ } else {
+ /* Disconnected. */
+
+ /* Seek moved file vcache. */
+ fileFid.Cell = aodp->f.fid.Cell;
+ fileFid.Fid.Volume = aodp->f.fid.Fid.Volume;
+ ObtainSharedLock(&afs_xvcache, 754);
+ tvc = afs_FindVCache(&fileFid, 0 , 1);
+ ReleaseSharedLock(&afs_xvcache);
+
+ if (tvc) {
+ /* XXX - We're locking this vcache whilst holding dcaches. Ooops */
+ ObtainWriteLock(&tvc->lock, 750);
+ if (!(tvc->f.ddirty_flags & (VDisconRename|VDisconCreate))) {
+ /* If the vnode was created locally, then we don't care
+ * about recording the rename - we'll do it automatically
+ * on replay. If we've already renamed, we've already stored
+ * the required information about where we came from.
+ */
+
+ if (!aodp->f.shadow.vnode) {
+ /* Make shadow copy of parent dir only. */
+ afs_MakeShadowDir(aodp, tdc1);
+ }
+
+ /* Save old parent dir fid so it will be searchable
+ * in the shadow dir.
+ */
+ tvc->f.oldParent.vnode = aodp->f.fid.Fid.Vnode;
+ tvc->f.oldParent.unique = aodp->f.fid.Fid.Unique;
+
+ afs_DisconAddDirty(tvc,
+ VDisconRename
+ | (oneDir ? VDisconRenameSameDir:0),
+ 1);
+ }
+
+ ReleaseWriteLock(&tvc->lock);
+ afs_PutVCache(tvc);
+ } else {
+ code = ENOENT;
+ } /* if (tvc) */
+ } /* if !(AFS_IS_DISCON_RW)*/
+ returnCode = code; /* remember for later */
+
/* Now we try to do things locally. This is really loathsome code. */
unlinkFid.Fid.Vnode = 0;
if (code == 0) {
/* In any event, we don't really care if the data (tdc2) is not
- in the cache; if it isn't, we won't do the update locally. */
+ * in the cache; if it isn't, we won't do the update locally. */
/* see if version numbers increased properly */
doLocally = 1;
- if (oneDir) {
- /* number increases by 1 for whole rename operation */
- if (!afs_LocalHero(aodp, tdc1, &OutOldDirStatus, 1)) {
- doLocally = 0;
- }
- }
- else {
- /* two separate dirs, each increasing by 1 */
- if (!afs_LocalHero(aodp, tdc1, &OutOldDirStatus, 1))
- doLocally = 0;
- if (!afs_LocalHero(andp, tdc2, &OutNewDirStatus, 1))
- doLocally = 0;
- if (!doLocally) {
- if (tdc1) {
- ZapDCE(tdc1);
- DZap(&tdc1->f.inode);
- }
- if (tdc2) {
- ZapDCE(tdc2);
- DZap(&tdc2->f.inode);
- }
+ if (!AFS_IS_DISCON_RW) {
+ if (oneDir) {
+ /* number increases by 1 for whole rename operation */
+ if (!afs_LocalHero(aodp, tdc1, &OutOldDirStatus, 1)) {
+ doLocally = 0;
+ }
+ } else {
+ /* two separate dirs, each increasing by 1 */
+ if (!afs_LocalHero(aodp, tdc1, &OutOldDirStatus, 1))
+ doLocally = 0;
+ if (!afs_LocalHero(andp, tdc2, &OutNewDirStatus, 1))
+ doLocally = 0;
+ if (!doLocally) {
+ if (tdc1) {
+ ZapDCE(tdc1);
+ DZap(tdc1);
+ }
+ if (tdc2) {
+ ZapDCE(tdc2);
+ DZap(tdc2);
+ }
+ }
}
- }
+ } /* if (!AFS_IS_DISCON_RW) */
+
/* now really do the work */
if (doLocally) {
/* first lookup the fid of the dude we're moving */
- code = afs_dir_Lookup(&tdc1->f.inode, aname1, &fileFid.Fid);
+ code = afs_dir_Lookup(tdc1, aname1, &fileFid.Fid);
if (code == 0) {
/* delete the source */
- code = afs_dir_Delete(&tdc1->f.inode, aname1);
+ code = afs_dir_Delete(tdc1, aname1);
}
/* first see if target is there */
- if (code == 0 &&
- afs_dir_Lookup(&tdc2->f.inode, aname2, &unlinkFid.Fid) == 0) {
+ if (code == 0
+ && afs_dir_Lookup(tdc2, aname2,
+ &unlinkFid.Fid) == 0) {
/* target already exists, and will be unlinked by server */
- code = afs_dir_Delete(&tdc2->f.inode, aname2);
+ code = afs_dir_Delete(tdc2, aname2);
}
if (code == 0) {
- code = afs_dir_Create(&tdc2->f.inode, aname2, &fileFid.Fid);
+ ObtainWriteLock(&afs_xdcache, 292);
+ code = afs_dir_Create(tdc2, aname2, &fileFid.Fid);
+ ReleaseWriteLock(&afs_xdcache);
}
if (code != 0) {
ZapDCE(tdc1);
- DZap(&tdc1->f.inode);
+ DZap(tdc1);
if (!oneDir) {
ZapDCE(tdc2);
- DZap(&tdc2->f.inode);
+ DZap(tdc2);
}
}
}
+
/* update dir link counts */
- aodp->m.LinkCount = OutOldDirStatus.LinkCount;
- if (!oneDir)
- andp->m.LinkCount = OutNewDirStatus.LinkCount;
+ if (AFS_IS_DISCON_RW) {
+ if (!oneDir) {
+ aodp->f.m.LinkCount--;
+ andp->f.m.LinkCount++;
+ }
+ /* If we're in the same directory, link count doesn't change */
+ } else {
+ aodp->f.m.LinkCount = OutOldDirStatus.LinkCount;
+ if (!oneDir)
+ andp->f.m.LinkCount = OutNewDirStatus.LinkCount;
+ }
- }
- else { /* operation failed (code != 0) */
- if (code < 0) {
+ } else { /* operation failed (code != 0) */
+ if (code < 0) {
/* if failed, server might have done something anyway, and
* assume that we know about it */
- ObtainWriteLock(&afs_xcbhash, 498);
- afs_DequeueCallback(aodp);
- afs_DequeueCallback(andp);
- andp->states &= ~CStatd;
- aodp->states &= ~CStatd;
- ReleaseWriteLock(&afs_xcbhash);
- osi_dnlc_purgedp(andp);
- osi_dnlc_purgedp(aodp);
+ ObtainWriteLock(&afs_xcbhash, 498);
+ afs_DequeueCallback(aodp);
+ afs_DequeueCallback(andp);
+ andp->f.states &= ~CStatd;
+ aodp->f.states &= ~CStatd;
+ ReleaseWriteLock(&afs_xcbhash);
+ osi_dnlc_purgedp(andp);
+ osi_dnlc_purgedp(aodp);
}
}
}
ReleaseWriteLock(&aodp->lock);
- if (!oneDir) ReleaseWriteLock(&andp->lock);
-
+
+ if (!oneDir) {
+ ReleaseWriteLock(&andp->lock);
+ }
+
if (returnCode) {
code = returnCode;
goto done;
}
/* now, some more details. if unlinkFid.Fid.Vnode then we should decrement
- the link count on this file. Note that if fileFid is a dir, then we don't
- have to invalidate its ".." entry, since its DataVersion # should have
- changed. However, interface is not good enough to tell us the
- *file*'s new DataVersion, so we're stuck. Our hack: delete mark
- the data as having an "unknown" version (effectively discarding the ".."
- entry */
+ * the link count on this file. Note that if fileFid is a dir, then we don't
+ * have to invalidate its ".." entry, since its DataVersion # should have
+ * changed. However, interface is not good enough to tell us the
+ * *file*'s new DataVersion, so we're stuck. Our hack: delete mark
+ * the data as having an "unknown" version (effectively discarding the ".."
+ * entry */
if (unlinkFid.Fid.Vnode) {
- unlinkFid.Fid.Volume = aodp->fid.Fid.Volume;
- unlinkFid.Cell = aodp->fid.Cell;
- tvc = (struct vcache *)0;
+
+ unlinkFid.Fid.Volume = aodp->f.fid.Fid.Volume;
+ unlinkFid.Cell = aodp->f.fid.Cell;
+ tvc = NULL;
if (!unlinkFid.Fid.Unique) {
- tvc = afs_LookupVCache(&unlinkFid, &treq, (afs_int32 *)0, WRITE_LOCK,
- aodp, aname1);
+ tvc = afs_LookupVCache(&unlinkFid, areq, NULL, aodp, aname1);
}
- if (!tvc) /* lookup failed or wasn't called */
- tvc = afs_GetVCache(&unlinkFid, &treq, (afs_int32 *)0,
- (struct vcache*)0, WRITE_LOCK);
+ if (!tvc) /* lookup failed or wasn't called */
+ tvc = afs_GetVCache(&unlinkFid, areq, NULL, NULL);
if (tvc) {
-#if defined(AFS_SUN_ENV) || defined(AFS_ALPHA_ENV) || defined(AFS_SUN5_ENV)
+#ifdef AFS_BOZONLOCK_ENV
afs_BozonLock(&tvc->pvnLock, tvc); /* Since afs_TryToSmush will do a pvn_vptrunc */
#endif
- ObtainWriteLock(&tvc->lock,151);
- tvc->m.LinkCount--;
- tvc->states &= ~CUnique; /* For the dfs xlator */
- if (tvc->m.LinkCount == 0 && !osi_Active(tvc)) {
+ ObtainWriteLock(&tvc->lock, 151);
+ tvc->f.m.LinkCount--;
+ tvc->f.states &= ~CUnique; /* For the dfs xlator */
+ if (tvc->f.m.LinkCount == 0 && !osi_Active(tvc)) {
/* if this was last guy (probably) discard from cache.
- * We have to be careful to not get rid of the stat
- * information, since otherwise operations will start
- * failing even if the file was still open (or
- * otherwise active), and the server no longer has the
- * info. If the file still has valid links, we'll get
- * a break-callback msg from the server, so it doesn't
- * matter that we don't discard the status info */
- if (!AFS_NFSXLATORREQ(acred)) afs_TryToSmush(tvc, acred, 0);
+ * We have to be careful to not get rid of the stat
+ * information, since otherwise operations will start
+ * failing even if the file was still open (or
+ * otherwise active), and the server no longer has the
+ * info. If the file still has valid links, we'll get
+ * a break-callback msg from the server, so it doesn't
+ * matter that we don't discard the status info */
+ if (!AFS_NFSXLATORREQ(acred))
+ afs_TryToSmush(tvc, acred, 0);
}
ReleaseWriteLock(&tvc->lock);
-#if defined(AFS_SUN_ENV) || defined(AFS_ALPHA_ENV) || defined(AFS_SUN5_ENV)
+#ifdef AFS_BOZONLOCK_ENV
afs_BozonUnlock(&tvc->pvnLock, tvc);
#endif
- afs_PutVCache(tvc, WRITE_LOCK);
+ afs_PutVCache(tvc);
}
}
/* now handle ".." invalidation */
if (!oneDir) {
- fileFid.Fid.Volume = aodp->fid.Fid.Volume;
- fileFid.Cell = aodp->fid.Cell;
+ fileFid.Fid.Volume = aodp->f.fid.Fid.Volume;
+ fileFid.Cell = aodp->f.fid.Cell;
if (!fileFid.Fid.Unique)
- tvc = afs_LookupVCache(&fileFid, &treq, (afs_int32 *)0, WRITE_LOCK, andp, aname2);
+ tvc = afs_LookupVCache(&fileFid, areq, NULL, andp, aname2);
else
- tvc = afs_GetVCache(&fileFid, &treq, (afs_int32 *)0,
- (struct vcache*)0, WRITE_LOCK);
+ tvc = afs_GetVCache(&fileFid, areq, NULL, (struct vcache *)0);
if (tvc && (vType(tvc) == VDIR)) {
- ObtainWriteLock(&tvc->lock,152);
- tdc1 = afs_FindDCache(tvc, 0);
+ ObtainWriteLock(&tvc->lock, 152);
+ tdc1 = afs_FindDCache(tvc, (afs_size_t) 0);
if (tdc1) {
- ObtainWriteLock(&tdc1->lock, 648);
- ZapDCE(tdc1); /* mark as unknown */
- DZap(&tdc1->f.inode);
- ReleaseWriteLock(&tdc1->lock);
- afs_PutDCache(tdc1); /* put it back */
+ if (AFS_IS_DISCON_RW) {
+ /* If disconnected, we need to fix (not discard) the "..".*/
+ afs_dir_ChangeFid(tdc1,
+ "..",
+ &aodp->f.fid.Fid.Vnode,
+ &andp->f.fid.Fid.Vnode);
+ } else {
+ ObtainWriteLock(&tdc1->lock, 648);
+ ZapDCE(tdc1); /* mark as unknown */
+ DZap(tdc1);
+ ReleaseWriteLock(&tdc1->lock);
+ afs_PutDCache(tdc1); /* put it back */
+ }
}
osi_dnlc_remove(tvc, "..", 0);
ReleaseWriteLock(&tvc->lock);
- afs_PutVCache(tvc, WRITE_LOCK);
+ afs_PutVCache(tvc);
+ } else if (AFS_IS_DISCON_RW && tvc && (vType(tvc) == VREG)) {
+ /* XXX - Should tvc not get locked here? */
+ tvc->f.parent.vnode = andp->f.fid.Fid.Vnode;
+ tvc->f.parent.unique = andp->f.fid.Fid.Unique;
} else if (tvc) {
/* True we shouldn't come here since tvc SHOULD be a dir, but we
* 'syntactically' need to unless we change the 'if' above...
*/
- afs_PutVCache(tvc, WRITE_LOCK);
+ afs_PutVCache(tvc);
}
}
code = returnCode;
-done:
- code = afs_CheckCode(code, &treq, 25);
+ done:
return code;
}
-#ifdef AFS_OSF_ENV
-afs_rename(fndp, tndp)
- struct nameidata *fndp, *tndp; {
- register struct vcache *aodp = (struct vcache *)fndp->ni_dvp;
- char *aname1 = fndp->ni_dent.d_name;
- register struct vcache *andp = (struct vcache *)tndp->ni_dvp;
- char *aname2 = tndp->ni_dent.d_name;
- struct ucred *acred = tndp->ni_cred;
-#else /* AFS_OSF_ENV */
+int
#if defined(AFS_SGI_ENV)
-afs_rename(OSI_VC_ARG(aodp), aname1, andp, aname2, npnp, acred)
- struct pathname *npnp;
+afs_rename(OSI_VC_DECL(aodp), char *aname1, struct vcache *andp, char *aname2, struct pathname *npnp, afs_ucred_t *acred)
#else
-afs_rename(OSI_VC_ARG(aodp), aname1, andp, aname2, acred)
+afs_rename(OSI_VC_DECL(aodp), char *aname1, struct vcache *andp, char *aname2, afs_ucred_t *acred)
#endif
- OSI_VC_DECL(aodp);
- register struct vcache *andp;
- char *aname1, *aname2;
- struct AFS_UCRED *acred; {
-#endif
- register afs_int32 code;
- OSI_VC_CONVERT(aodp)
-
- code = afsrename(aodp, aname1, andp, aname2, acred);
-#ifdef AFS_OSF_ENV
- AFS_RELE(tndp->ni_dvp);
- if (tndp->ni_vp != NULL) {
- AFS_RELE(tndp->ni_vp);
- }
- AFS_RELE(fndp->ni_dvp);
- AFS_RELE(fndp->ni_vp);
-#endif /* AFS_OSF_ENV */
+{
+ afs_int32 code;
+ struct afs_fakestat_state ofakestate;
+ struct afs_fakestat_state nfakestate;
+ struct vrequest treq;
+ OSI_VC_CONVERT(aodp);
+
+ code = afs_InitReq(&treq, acred);
+ if (code)
+ return code;
+ afs_InitFakeStat(&ofakestate);
+ afs_InitFakeStat(&nfakestate);
+
+ AFS_DISCON_LOCK();
+
+ code = afs_EvalFakeStat(&aodp, &ofakestate, &treq);
+ if (code)
+ goto done;
+ code = afs_EvalFakeStat(&andp, &nfakestate, &treq);
+ if (code)
+ goto done;
+ code = afsrename(aodp, aname1, andp, aname2, acred, &treq);
+ done:
+ afs_PutFakeStat(&ofakestate);
+ afs_PutFakeStat(&nfakestate);
+
+ AFS_DISCON_UNLOCK();
+
+ code = afs_CheckCode(code, &treq, 25);
return code;
}