Work around MacOSX Finder's behavior by returning ENOENT when the user
authorNickolai Zeldovich <kolya@mit.edu>
Tue, 23 Jul 2002 00:04:22 +0000 (00:04 +0000)
committerNickolai Zeldovich <kolya@mit.edu>
Tue, 23 Jul 2002 00:04:22 +0000 (00:04 +0000)
tries to look up Contents or .DS_Store in an uncached volume root.

NEWS
src/afs/VNOPS/afs_vnop_lookup.c

diff --git a/NEWS b/NEWS
index c42d9ef..e90d49c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,12 @@
-OpenAFS News -- history of user-visible changes. October 19, 2001
+OpenAFS News -- history of user-visible changes.  July 22, 2002.
 
 * Changes incorporated in OpenAFS 1.3
 
+** When fakestat is enabled on MacOSX, the Finder can be used to browse
+   a fully-populated /afs directory.  However, this precludes reliable
+   use of entire volumes as MacOS bundles (i.e. containing a Contents
+   directory in the root of the volume).
+
 ** Mountpoint directory information can be faked by the cache manager,
    making operations such as stat'ing all cells under /afs much faster.
    This is enabled by passing -fakestat to afsd, but might not be stable
index e71338d..91184d0 100644 (file)
@@ -1099,6 +1099,7 @@ afs_lookup(adp, aname, avcp, acred)
     struct sysname_info sysState;   /* used only for @sys checking */
     int dynrootRetry = 1;
     struct afs_fakestat_state fakestate;
+    int tryEvalOnly = 0;
 
     AFS_STATCNT(afs_lookup);
     afs_InitFakeStat(&fakestate);
@@ -1106,15 +1107,33 @@ afs_lookup(adp, aname, avcp, acred)
     if (code = afs_InitReq(&treq, acred))
        goto done;
 
-    code = afs_EvalFakeStat(&adp, &fakestate, &treq);
-    if (code)
-       goto done;
 #ifdef AFS_OSF_ENV
     ndp->ni_dvp = AFSTOV(adp);
     memcpy(aname, ndp->ni_ptr, ndp->ni_namelen);
     aname[ndp->ni_namelen] = '\0';
 #endif /* AFS_OSF_ENV */
 
+#if defined(AFS_DARWIN_ENV)
+    /* Workaround for MacOSX Finder, which tries to look for
+     * .DS_Store and Contents under every directory.
+     */
+    if (afs_fakestat_enable && adp->mvstat == 1) {
+       if (strcmp(aname, ".DS_Store") == 0)
+           tryEvalOnly = 1;
+       if (strcmp(aname, "Contents") == 0)
+           tryEvalOnly = 1;
+    }
+#endif
+
+    if (tryEvalOnly)
+       code = afs_TryEvalFakeStat(&adp, &fakestate, &treq);
+    else
+       code = afs_EvalFakeStat(&adp, &fakestate, &treq);
+    if (tryEvalOnly && adp->mvstat == 1)
+       code = ENOENT;
+    if (code)
+       goto done;
+
     *avcp = (struct vcache *) 0;   /* Since some callers don't initialize it */
 
     /* come back to here if we encounter a non-existent object in a read-only