#include <roken.h>
#include <afs/stds.h>
+#include <afs/unified_afs.h>
#include <windows.h>
#include <winsock2.h>
if (scp->mountRootFid.cell != 0 && scp->mountRootGen >= cm_data.mountRootGen) {
tfid = scp->mountRootFid;
lock_ReleaseWrite(&scp->rw);
- code = cm_GetSCache(&tfid, outScpp, userp, reqp);
+ code = cm_GetSCache(&tfid, NULL, outScpp, userp, reqp);
lock_ObtainWrite(&scp->rw);
return code;
}
tfid = scp->mountRootFid;
lock_ReleaseWrite(&scp->rw);
- code = cm_GetSCache(&tfid, outScpp, userp, reqp);
+ code = cm_GetSCache(&tfid, NULL, outScpp, userp, reqp);
lock_ObtainWrite(&scp->rw);
}
if ( !tscp ) /* we did not find it in the dnlc */
{
dnlcHit = 0;
- code = cm_GetSCache(&rock.fid, &tscp, userp, reqp);
+ code = cm_GetSCache(&rock.fid, &dscp->fid, &tscp, userp, reqp);
if (code)
goto done;
}
cm_SetFid(&fid, cellp->cellID, volume, 1, 1);
- code = cm_GetSCache(&fid, outScpp, userp, reqp);
+ code = cm_GetSCache(&fid, NULL, outScpp, userp, reqp);
_exit_cleanup:
if (fnamep)
int symlinkCount; /* count of # of symlinks traversed */
int extraFlag; /* avoid chasing mt pts for dir cmd */
int phase = 1; /* 1 = tidPathp, 2 = pathp */
-#define MAX_FID_COUNT 512
cm_fid_t fids[MAX_FID_COUNT]; /* array of fids processed in this path walk */
int fid_count = 0; /* number of fids processed in this path walk */
int i;
if (tscp) {
if (lock_TryWrite(&tscp->rw)) {
/* we have an entry that we can look at */
- if (!(tscp->flags & CM_SCACHEFLAG_EACCESS) && cm_HaveCallback(tscp)) {
+ if (!cm_EAccesFindEntry(bsp->userp, &tscp->fid) && cm_HaveCallback(tscp)) {
/* we have a callback on it. Don't bother
* fetching this stat entry, since we're happy
* with the info we have.
!(tfid.vnode==0x1 && tfid.unique==0x1) )
{
osi_Log0(afsd_logp, "cm_TryBulkProc Freelance calls cm_SCache on root.afs mountpoint");
- return cm_GetSCache(&tfid, &tscp, NULL, NULL);
+ return cm_GetSCache(&tfid, NULL, &tscp, NULL, NULL);
}
#endif /* AFS_FREELANCE_CLIENT */
if (inlinebulk && (&bbp->stats[j])->errorCode) {
cm_req_t treq = *reqp;
cm_Analyze(NULL, userp, &treq, &tfid, 0, &volSync, NULL, &cbReq, (&bbp->stats[j])->errorCode);
+ switch ((&bbp->stats[j])->errorCode) {
+ case EACCES:
+ case UAEACCES:
+ case EPERM:
+ case UAEPERM:
+ cm_EAccesAddEntry(userp, &tfid, &dscp->fid);
+ }
} else {
- code = cm_GetSCache(&tfid, &scp, userp, reqp);
+ code = cm_GetSCache(&tfid, &dscp->fid, &scp, userp, reqp);
if (code != 0)
continue;
if ((scp->cbServerp == NULL &&
!(scp->flags & (CM_SCACHEFLAG_FETCHING | CM_SCACHEFLAG_STORING | CM_SCACHEFLAG_SIZESTORING))) ||
(scp->flags & CM_SCACHEFLAG_PURERO) ||
- (scp->flags & CM_SCACHEFLAG_EACCESS))
+ cm_EAccesFindEntry(userp, &scp->fid))
{
lock_ConvertRToW(&scp->rw);
lostRace = cm_EndCallbackGrantingCall(scp, &cbReq,
bbp = malloc(sizeof(cm_bulkStat_t));
memset(bbp, 0, sizeof(cm_bulkStat_t));
+ bbp->userp = userp;
bbp->bufOffset = *offsetp;
lock_ReleaseWrite(&dscp->rw);
statusp->Mask = mask;
}
+int
+cm_IsSpaceAvailable(cm_fid_t * fidp, osi_hyper_t *sizep, cm_user_t *userp, cm_req_t *reqp)
+{
+ int spaceAvail = 1;
+ afs_uint32 code;
+ cm_conn_t *connp;
+ struct rx_connection * rxconnp;
+ AFSFetchVolumeStatus volStat;
+ cm_volume_t *volp = NULL;
+ afs_uint32 volType;
+ char *Name;
+ char *OfflineMsg;
+ char *MOTD;
+ char volName[32]="(unknown)";
+ char offLineMsg[256]="server temporarily inaccessible";
+ char motd[256]="server temporarily inaccessible";
+ osi_hyper_t freespace;
+
+ if (fidp->cell==AFS_FAKE_ROOT_CELL_ID &&
+ fidp->volume==AFS_FAKE_ROOT_VOL_ID)
+ {
+ goto _done;
+ }
+
+ volp = cm_GetVolumeByFID(fidp);
+ if (!volp) {
+ spaceAvail = 0;
+ goto _done;
+ }
+ volType = cm_VolumeType(volp, fidp->volume);
+ if (volType == ROVOL || volType == BACKVOL) {
+ spaceAvail = 0;
+ goto _done;
+ }
+
+ Name = volName;
+ OfflineMsg = offLineMsg;
+ MOTD = motd;
+
+ do {
+ code = cm_ConnFromFID(fidp, userp, reqp, &connp);
+ if (code) continue;
+
+ rxconnp = cm_GetRxConn(connp);
+ code = RXAFS_GetVolumeStatus(rxconnp, fidp->volume,
+ &volStat, &Name, &OfflineMsg, &MOTD);
+ rx_PutConnection(rxconnp);
+
+ } while (cm_Analyze(connp, userp, reqp, fidp, 0, NULL, NULL, NULL, code));
+ code = cm_MapRPCError(code, reqp);
+ if (code == 0) {
+ if (volStat.MaxQuota) {
+ freespace.QuadPart = 1024 * (afs_int64)min(volStat.MaxQuota - volStat.BlocksInUse, volStat.PartBlocksAvail);
+ } else {
+ freespace.QuadPart = 1024 * (afs_int64)volStat.PartBlocksAvail;
+ }
+ spaceAvail = LargeIntegerGreaterThanOrEqualTo(freespace, *sizep);
+ }
+ /* the rpc failed, assume there is space and we can fail it later. */
+
+ _done:
+ if (volp)
+ cm_PutVolume(volp);
+
+ return spaceAvail;
+}
+
/* set the file size, and make sure that all relevant buffers have been
* truncated. Ensure that any partially truncated buffers have been zeroed
* to the end of the buffer.
}
else if (LargeIntegerGreaterThan(*sizep, scp->length)) {
/* really extending the file */
- scp->length = *sizep;
- scp->mask |= CM_SCACHEMASK_LENGTH;
+ /* Check to see if we have sufficient quota */
+ if (cm_IsSpaceAvailable(&scp->fid, sizep, userp, reqp)) {
+ scp->length = *sizep;
+ scp->mask |= CM_SCACHEMASK_LENGTH;
+ } else {
+ code = CM_ERROR_SPACE;
+ goto syncopdone;
+ }
}
/* done successfully */
code = 0;
+ syncopdone:
cm_SyncOpDone(scp, NULL,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS
| CM_SCACHESYNC_SETSTATUS | CM_SCACHESYNC_SETSIZE);
* info.
*/
if (code == 0) {
- code = cm_GetSCache(&newFid, &scp, userp, reqp);
+ code = cm_GetSCache(&newFid, &dscp->fid, &scp, userp, reqp);
if (code == 0) {
lock_ObtainWrite(&scp->rw);
scp->creator = userp; /* remember who created it */
* info.
*/
if (code == 0) {
- code = cm_GetSCache(&newFid, &scp, userp, reqp);
+ code = cm_GetSCache(&newFid, &dscp->fid, &scp, userp, reqp);
if (code == 0) {
lock_ObtainWrite(&scp->rw);
if (!cm_HaveCallback(scp)) {
* info.
*/
if (code == 0) {
- code = cm_GetSCache(&newFid, &scp, userp, reqp);
+ code = cm_GetSCache(&newFid, &dscp->fid, &scp, userp, reqp);
if (code == 0) {
lock_ObtainWrite(&scp->rw);
if (!cm_HaveCallback(scp)) {
osi_Log2(afsd_logp, "CALL SetLock scp 0x%p for lock %d", scp, lockType);
- if ((lockType != LOCKING_ANDX_SHARED_LOCK && scp->fsLockCount != 0) ||
- (lockType == LOCKING_ANDX_SHARED_LOCK && scp->fsLockCount < 0))
- {
- code = CM_ERROR_LOCK_NOT_GRANTED;
+#if 0
+ /*
+ * The file server prior to 1.6.2 does not report an accurate value
+ * and callbacks are not issued if the lock is dropped due to expiration.
+ */
+ if ((lockType != LOCKING_ANDX_SHARED_LOCK && scp->fsLockCount != 0) ||
+ (lockType == LOCKING_ANDX_SHARED_LOCK && scp->fsLockCount < 0))
+ {
+ code = CM_ERROR_LOCK_NOT_GRANTED;
osi_Log2(afsd_logp, "CALL SetLock FAILURE, fsLockCount %d code 0x%x", scp->fsLockCount, code);
- return code;
- }
+ return code;
+ }
+#endif
memset(&volSync, 0, sizeof(volSync));