afs_int32 last3MinCheck, last10MinCheck, last60MinCheck, lastNMinCheck;
afs_int32 last1MinCheck, last5MinCheck;
afs_uint32 lastCBSlotBump;
- char cs_warned = 0;
AFS_STATCNT(afs_Daemon);
if (last1MinCheck + 60 < now) {
/* things to do every minute */
DFlush(); /* write out dir buffers */
- afs_WriteThroughDSlots(); /* write through cacheinfo entries */
+ (void)afs_WriteThroughDSlots(); /* write through cacheinfo entries */
ObtainWriteLock(&afs_xvcache, 736);
afs_FlushReclaimedVcaches();
ReleaseWriteLock(&afs_xvcache);
afs_FlushActiveVcaches(1); /* keep flocks held & flush nfs writes */
-#if 0
- afs_StoreDirtyVcaches();
-#endif
last1MinCheck = now;
}
}
if (!afs_CheckServerDaemonStarted) {
- /* Do the check here if the correct afsd is not installed. */
- if (!cs_warned) {
- cs_warned = 1;
- afs_warn("Please install afsd with check server daemon.\n");
- }
if (lastNMinCheck + afs_probe_interval < now) {
/* only check down servers */
afs_CheckServers(1, NULL);
int
afs_CheckRootVolume(void)
{
- char rootVolName[32];
+ char rootVolName[MAXROOTVOLNAMELEN];
struct volume *tvp = NULL;
int usingDynroot = afs_GetDynrootEnable();
int localcell;
* count to zero and fs checkv is executed when the current
* directory is /afs.
*/
-#ifdef AFS_LINUX20_ENV
- {
- struct vrequest *treq = NULL;
- struct vattr vattr;
- cred_t *credp;
- struct dentry *dp;
- struct vcache *vcp;
-
- afs_rootFid.Fid.Volume = volid;
- afs_rootFid.Fid.Vnode = 1;
- afs_rootFid.Fid.Unique = 1;
-
- credp = crref();
- if (afs_CreateReq(&treq, credp))
- goto out;
- vcp = afs_GetVCache(&afs_rootFid, treq, NULL, NULL);
- if (!vcp)
- goto out;
- afs_getattr(vcp, &vattr, credp);
- afs_fill_inode(AFSTOV(vcp), &vattr);
-
- dp = d_find_alias(AFSTOV(afs_globalVp));
-
-#if defined(AFS_LINUX24_ENV)
-#if defined(HAVE_DCACHE_LOCK)
- spin_lock(&dcache_lock);
-#else
- spin_lock(&AFSTOV(vcp)->i_lock);
-#endif
-#if defined(AFS_LINUX26_ENV)
- spin_lock(&dp->d_lock);
-#endif
-#endif
-#if defined(D_ALIAS_IS_HLIST)
- hlist_del_init(&dp->d_alias);
- hlist_add_head(&dp->d_alias, &(AFSTOV(vcp)->i_dentry));
-#else
- list_del_init(&dp->d_alias);
- list_add(&dp->d_alias, &(AFSTOV(vcp)->i_dentry));
-#endif
- dp->d_inode = AFSTOV(vcp);
-#if defined(AFS_LINUX24_ENV)
-#if defined(AFS_LINUX26_ENV)
- spin_unlock(&dp->d_lock);
-#endif
-#if defined(HAVE_DCACHE_LOCK)
- spin_unlock(&dcache_lock);
-#else
- spin_unlock(&AFSTOV(vcp)->i_lock);
-#endif
-#endif
- dput(dp);
-
- AFS_FAST_RELE(afs_globalVp);
- afs_globalVp = vcp;
- out:
- crfree(credp);
- afs_DestroyReq(treq);
- }
+#ifdef AFS_LINUX22_ENV
+ osi_ResetRootVCache(volid);
#else
-#ifdef AFS_DARWIN80_ENV
+# ifdef AFS_DARWIN80_ENV
afs_PutVCache(afs_globalVp);
-#else
+# else
AFS_FAST_RELE(afs_globalVp);
-#endif
+# endif
afs_globalVp = 0;
#endif
}
afs_DestroyReq(treq);
}
+static void
+BInvalidateSegments(struct brequest *ab)
+{
+ int code;
+ struct vcache *tvc = ab->vc;
+ osi_Assert(WriteLocked(&tvc->lock));
+
+ code = afs_InvalidateAllSegments_once(tvc);
+
+ /* Set return code, and wakeup anyone waiting. */
+ if ((ab->flags & BUVALID) == 0) {
+ ab->code_raw = ab->code_checkcode = code;
+ ab->flags |= BUVALID;
+ if ((ab->flags & BUWAIT)) {
+ ab->flags &= ~BUWAIT;
+ afs_osi_Wakeup(ab);
+ }
+ }
+}
+
/* release a held request buffer */
void
afs_BRelease(struct brequest *ab)
crhold(tb->cred);
}
if (avc) {
- AFS_FAST_HOLD(avc);
+ osi_Assert(osi_vnhold(avc) == 0);
}
tb->refCount = ause + 1;
tb->size_parm[0] = asparm0;
}
#ifdef AFS_NEW_BKG
+static_inline int
+should_do_noop(int foundAny, int n_processed)
+{
+ if (!foundAny && n_processed > 0) {
+ /* If there aren't any requests right now, and we've processed
+ * at least one request, do a noop. */
+ return 1;
+ } else if (foundAny && n_processed > 100) {
+ /* If we've processed over 100 requests in a row, do a noop. */
+ return 1;
+ }
+ return 0;
+}
+#endif
+
+/**
+ * Entry point for background daemon processes.
+ *
+ * For old-style background daemons (non-AFS_NEW_BKG), a background daemon afsd
+ * process will end up in this function, and it will stay in here forever
+ * processing in-kernel bkg requests until the client shuts down.
+ *
+ * For new-style background daemons (AFS_NEW_BKG), we can pass data back to
+ * afsd to perform some background operations in userspace, by populating
+ * 'uspc' with the operation to perform and then returning. When the afsd
+ * process enters this function again, the return code for that operation is
+ * also provided in 'uspc'.
+ *
+ * @param[inout] uspc Userspace operation data. If uspc->ts is non-negative
+ * on entry, the related background request has finished,
+ * and we're providing the return code. On return,
+ * contains the userspace operation to perform.
+ * @param[inout] param1 Operation-specific pointer.
+ * @param[inout] param2 Operation-specific pointer.
+ *
+ * @return Always returns 0.
+ */
+#ifdef AFS_NEW_BKG
int
afs_BackgroundDaemon(struct afs_uspc_param *uspc, void *param1, void *param2)
#else
{
struct brequest *tb;
int i, foundAny;
+ int n_processed = 0;
AFS_STATCNT(afs_BackgroundDaemon);
/* initialize subsystem */
afs_BackgroundDaemon_once();
#ifdef AFS_NEW_BKG
- /* If it's a re-entering syscall, complete the request and release */
- if (uspc->ts > -1) {
+ if (uspc->reqtype == AFS_USPC_NOOP) {
+ /* The daemon is re-entering from a noop, not actually returning data;
+ * don't look for an existing request. */
+ /* noop */
+
+ } else if (uspc->ts > -1) {
+ /* If it's a re-entering syscall, complete the request and release */
tb = afs_brs;
for (i = 0; i < NBRS; i++, tb++) {
if (tb->ts == uspc->ts) {
/* copy the userspace status back in */
- ((struct afs_uspc_param *) tb->ptr_parm[0])->retval =
- uspc->retval;
+ tb->code_raw = tb->code_checkcode = uspc->retval;
/* mark it valid and notify our caller */
tb->flags |= BUVALID;
if (tb->flags & BUWAIT) {
ReleaseWriteLock(&afs_xbrs);
afs_osi_Wakeup(&afs_termState);
#ifdef AFS_NEW_BKG
- return -2;
+ memset(uspc, 0, sizeof(*uspc));
+ uspc->reqtype = AFS_USPC_SHUTDOWN;
+ return 0;
#else
return;
#endif
tb->flags |= BSTARTED;
ReleaseWriteLock(&afs_xbrs);
foundAny = 1;
+ n_processed++;
afs_Trace1(afs_iclSetp, CM_TRACE_BKG1, ICL_TYPE_INT32,
tb->opcode);
if (tb->opcode == BOP_FETCH)
#endif
else if (tb->opcode == BOP_PARTIAL_STORE)
BPartialStore(tb);
+ else if (tb->opcode == BOP_INVALIDATE_SEGMENTS)
+ BInvalidateSegments(tb);
else
panic("background bop");
brequest_release(tb);
ObtainWriteLock(&afs_xbrs, 305);
}
+
+#ifdef AFS_NEW_BKG
+ if (should_do_noop(foundAny, n_processed)) {
+ ReleaseWriteLock(&afs_xbrs);
+ memset(uspc, 0, sizeof(*uspc));
+ uspc->reqtype = AFS_USPC_NOOP;
+ return 0;
+ }
+#endif
+
if (!foundAny) {
/* wait for new request */
afs_brsDaemons++;