]> arthur.barton.de Git - netatalk.git/commitdiff
stat in dircache_search_by_name and remove if missing, fixes PR#10100
authorFrank Lahm <franklahm@googlemail.com>
Tue, 3 May 2011 09:27:46 +0000 (11:27 +0200)
committerFrank Lahm <franklahm@googlemail.com>
Tue, 3 May 2011 09:27:46 +0000 (11:27 +0200)
etc/afpd/catsearch.c
etc/afpd/dircache.c
etc/afpd/dircache.h
etc/afpd/directory.c
etc/afpd/enumerate.c
etc/afpd/file.c
etc/afpd/filedir.c

index 6a9161e2e8720743ca3cbbf4100b0980de9d34b0..d0e89f39fdad3527dddd1a4862e8e5ca042610ad 100644 (file)
@@ -613,8 +613,7 @@ static int catsearch(struct vol *vol,
                 path.d_dir = dircache_search_by_name(vol,
                                                      curdir,
                                                      path.u_name,
-                                                     unlen,
-                                                     path.st.st_ctime);
+                                                     unlen);
                if (path.d_dir == NULL) {
                        /* path.m_name is set by adddir */
                    if ((path.d_dir = dir_add(vol,
index 9907c5dd35bddabc02bbcef02d94dc07503d2975..638db7eed49360cd7cd2354f1a0cd4f7c15f42f4 100644 (file)
@@ -358,18 +358,17 @@ struct dir *dircache_search_by_did(const struct vol *vol, cnid_t cnid)
  * @param dir      (r) directory
  * @param name     (r) name (server side encoding)
  * @parma len      (r) strlen of name
- * @param ctime    (r) current st_ctime from stat
  *
  * @returns pointer to struct dir if found in cache, else NULL
  */
 struct dir *dircache_search_by_name(const struct vol *vol,
                                     const struct dir *dir,
                                     char *name,
-                                    int len,
-                                    time_t ctime)
+                                    int len)
 {
     struct dir *cdir = NULL;
     struct dir key;
+    struct stat st;
 
     hnode_t *hn;
     static_bstring uname = {-1, len, (unsigned char *)name};
@@ -394,7 +393,15 @@ struct dir *dircache_search_by_name(const struct vol *vol,
     }
 
     if (cdir) {
-        if (cdir->ctime_dircache != ctime) {
+        if (lstat(cfrombstr(cdir->d_fullpath), &st) != 0) {
+            LOG(log_debug, logtype_afpd, "dircache(did:%u,\"%s\"): {missing:\"%s\"}",
+                ntohl(dir->d_did), name, cfrombstr(cdir->d_fullpath));
+            (void)dir_remove(vol, cdir);
+            dircache_stat.expunged++;
+            return NULL;
+        }
+
+        if (cdir->ctime_dircache != st.st_ctime) {
             LOG(log_debug, logtype_afpd, "dircache(did:%u,\"%s\"): {modified}",
                 ntohl(dir->d_did), name);
             (void)dir_remove(vol, cdir);
index 16c2df1dbde26ab5d3d994d429172a98fa9bcc7a..42466d2dc67f004ba10c6b35779a6170f28699c2 100644 (file)
@@ -35,7 +35,7 @@ extern int        dircache_init(int reqsize);
 extern int        dircache_add(const struct vol *, struct dir *);
 extern void       dircache_remove(const struct vol *, struct dir *, int flag);
 extern struct dir *dircache_search_by_did(const struct vol *vol, cnid_t did);
-extern struct dir *dircache_search_by_name(const struct vol *, const struct dir *dir, char *name, int len, time_t ctime);
+extern struct dir *dircache_search_by_name(const struct vol *, const struct dir *dir, char *name, int len);
 extern void       dircache_dump(void);
 extern void       log_dircache_stat(void);
 #endif /* DIRCACHE_H */
index 9d5cf44065cefeffb6d5ba82394f3563a9bcdf50..b784f71ddede55067741baa9c0dfe1d64b60f556 100644 (file)
@@ -481,8 +481,7 @@ struct dir *dirlookup_bypath(const struct vol *vol, const char *path)
         if ((dir = dircache_search_by_name(vol,          /* 5. */
                                            dir,
                                            cfrombstr(l->entry[i]),
-                                           blength(l->entry[i]),
-                                           st.st_ctime)) == NULL) {
+                                           blength(l->entry[i]))) == NULL) {
             if ((cnid = cnid_add(vol->v_cdb,             /* 6. */
                                  &st,
                                  did,
@@ -878,7 +877,7 @@ struct dir *dir_add(struct vol *vol, const struct dir *dir, struct path *path, i
     AFP_ASSERT(path);
     AFP_ASSERT(len > 0);
 
-    if ((cdir = dircache_search_by_name(vol, dir, path->u_name, strlen(path->u_name), path->st.st_ctime)) != NULL) {
+    if ((cdir = dircache_search_by_name(vol, dir, path->u_name, strlen(path->u_name))) != NULL) {
         /* there's a stray entry in the dircache */
         LOG(log_debug, logtype_afpd, "dir_add(did:%u,'%s/%s'): {stray cache entry: did:%u,'%s', removing}",
             ntohl(dir->d_did), cfrombstr(dir->d_fullpath), path->u_name,
@@ -1280,7 +1279,7 @@ struct path *cname(struct vol *vol, struct dir *dir, char **cpath)
 
             /* Search the cache */
             int unamelen = strlen(ret.u_name);
-            cdir = dircache_search_by_name(vol, dir, ret.u_name, unamelen, ret.st.st_ctime); /* 14 */
+            cdir = dircache_search_by_name(vol, dir, ret.u_name, unamelen); /* 14 */
             if (cdir == NULL) {
                 /* Not in cache, create one */
                 if ((cdir = dir_add(vol, dir, &ret, unamelen)) == NULL) { /* 15 */
index 1659fb77ff89cc5fbff15513fe5915600b718ae4..c136472d644adcf5863f3109dea1a5fe3835c7d3 100644 (file)
@@ -375,7 +375,7 @@ static int enumerate(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_,
                 continue;
             }
             int len = strlen(s_path.u_name);
-            if ((dir = dircache_search_by_name(vol, curdir, s_path.u_name, len, s_path.st.st_ctime)) == NULL) {
+            if ((dir = dircache_search_by_name(vol, curdir, s_path.u_name, len)) == NULL) {
                 if ((dir = dir_add(vol, curdir, &s_path, len)) == NULL) {
                     LOG(log_error, logtype_afpd, "enumerate(vid:%u, did:%u, name:'%s'): error adding dir: '%s'",
                         ntohs(vid), ntohl(did), o_path->u_name, s_path.u_name);
index f7df604982f3b966f102d96125479c358f5952a4..1708b946396002e6b6b5e34bfe7c91a22e4524e0 100644 (file)
@@ -328,7 +328,7 @@ int getmetadata(struct vol *vol,
         if (!path->id) {
             struct dir *cachedfile;
             int len = strlen(upath);
-            if ((cachedfile = dircache_search_by_name(vol, dir, upath, len, st->st_ctime)) != NULL)
+            if ((cachedfile = dircache_search_by_name(vol, dir, upath, len)) != NULL)
                 id = cachedfile->d_did;
             else {
                 id = get_id(vol, adp, st, dir->d_did, upath, len);
index 8eb8bb4d8d12ede44f8550bf43207d4656b3416c..1a0bd550b8f954bb9de0719a9afd66f4661366e7 100644 (file)
@@ -619,7 +619,7 @@ int afp_delete(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size
             rc = deletefile(vol, -1, upath, 1);
 
             struct dir *cachedfile;
-            if ((cachedfile = dircache_search_by_name(vol, dir, upath, strlen(upath), s_path->st.st_ctime))) {
+            if ((cachedfile = dircache_search_by_name(vol, dir, upath, strlen(upath)))) {
                 dircache_remove(vol, cachedfile, DIRCACHE | DIDNAME_INDEX | QUEUE_INDEX);
                 dir_free(cachedfile);
             }