]> arthur.barton.de Git - netatalk.git/commitdiff
CNID fallback for dbd backend, from branch-2-1
authorFrank Lahm <franklahm@googlemail.com>
Thu, 20 May 2010 08:49:11 +0000 (10:49 +0200)
committerFrank Lahm <franklahm@googlemail.com>
Thu, 20 May 2010 08:49:11 +0000 (10:49 +0200)
1  2 
etc/afpd/file.c

diff --combined etc/afpd/file.c
index 93b1a169612ab5c4f25e6fd69fc4fb01c0e8baa2,b10330c8aebaeef678a449f46e432988c43b841a..64b7b6068c78f808bd409bf052851cb722d45e76
@@@ -1,5 -1,5 +1,5 @@@
  /*
 - * $Id: file.c,v 1.141 2010-03-12 15:16:49 franklahm Exp $
 + * $Id: file.c,v 1.141 2010/03/12 15:16:49 franklahm Exp $
   *
   * Copyright (c) 1990,1993 Regents of The University of Michigan.
   * All Rights Reserved.  See COPYRIGHT.
@@@ -202,12 -202,14 +202,14 @@@ char *set_name(const struct vol *vol, c
                                  (1 << FILPBIT_UNIXPR)))
  
  /* -------------------------- */
 -u_int32_t get_id(struct vol *vol, struct adouble *adp,  const struct stat *st,
 +u_int32_t get_id(const struct vol *vol, struct adouble *adp,  const struct stat *st,
                   const cnid_t did, char *upath, const int len) 
  {
+     static int first = 1;       /* mark if this func is called the first time */
      u_int32_t adcnid;
      u_int32_t dbcnid = CNID_INVALID;
  
+ restart:
      if (vol->v_cdb != NULL) {
          /* prime aint with what we think is the cnid, set did to zero for
             catching moved files */
              case CNID_ERR_PARAM:
                  LOG(log_error, logtype_afpd, "get_id: Incorrect parameters passed to cnid_add");
                  afp_errno = AFPERR_PARAM;
-                 return CNID_INVALID;
+                 goto exit;
              case CNID_ERR_PATH:
                  afp_errno = AFPERR_PARAM;
-                 return CNID_INVALID;
+                 goto exit;
              default:
+                 /* Close CNID backend if "dbd" and switch to temp in-memory "tdb" */
+                 /* we have to do it here for "dbd" because it uses "lazy opening" */
+                 /* In order to not end in a loop somehow with goto restart below  */
+                 /*  */
+                 if (first && (strcmp(vol->v_cnidscheme, "dbd") == 0)) {
+                     cnid_close(vol->v_cdb);
+                     free(vol->v_cnidscheme);
+                     vol->v_cnidscheme = strdup("tdb");
+                     int flags = CNID_FLAG_MEMORY;
+                     if ((vol->v_flags & AFPVOL_NODEV)) {
+                         flags |= CNID_FLAG_NODEV;
+                     }
+                     LOG(log_error, logtype_afpd, "Reopen volume %s using in memory temporary CNID DB.",
+                         vol->v_path);
+                     vol->v_cdb = cnid_open(vol->v_path, vol->v_umask, "tdb", flags, NULL, NULL);
+                     if (vol->v_cdb) {
+                         /* deactivate cnid caching/storing in AppleDouble files and set ro mode*/
+                         vol->v_flags &= ~AFPVOL_CACHE;
+                         vol->v_flags |= AFPVOL_RO;
+ #ifdef SERVERTEXT
+                         /* kill ourself with SIGUSR2 aka msg pending */
+                         setmessage("Something wrong with the volume's CNID DB, using temporary CNID DB instead."
+                                    "Check server messages for details. Switching to read-only mode.");
+                         kill(getpid(), SIGUSR2);
+ #endif
+                         goto restart; /* not try again with the temp CNID db */
+                     } else {
+ #ifdef SERVERTEXT
+                         setmessage("Something wrong with the volume's CNID DB, using temporary CNID DB failed too!"
+                                    "Check server messages for details, can't recover from this state!");
+ #endif
+                     }
+                 }
                  afp_errno = AFPERR_MISC;
-                 return CNID_INVALID;
+                 goto exit;
              }
          }
          else if (adp && (adcnid != dbcnid)) {
              }
          }
      }
+ exit:
+     first = 0;
      return dbcnid;
  }
               
@@@ -259,6 -298,9 +298,6 @@@ int getmetadata(struct vol *vol
      struct stat         *st;
      struct maccess    ma;
  
 -#ifdef DEBUG
 -    LOG(log_debug9, logtype_afpd, "begin getmetadata:");
 -#endif /* DEBUG */
  
      upath = path->u_name;
      st = &path->st;
  #endif
              memcpy(data, &ashort, sizeof( ashort ));
              data += sizeof( ashort );
 +            LOG(log_debug, logtype_afpd, "metadata('%s'): AFP Attributes: %04x",
 +                path->u_name, ntohs(ashort));
              break;
  
          case FILPBIT_PDID :
              memcpy(data, &dir->d_did, sizeof( u_int32_t ));
              data += sizeof( u_int32_t );
 +            LOG(log_debug, logtype_afpd, "metadata('%s'):     Parent DID: %u",
 +                path->u_name, ntohl(dir->d_did));
              break;
  
          case FILPBIT_CDATE :
          case FILPBIT_FNUM :
              memcpy(data, &id, sizeof( id ));
              data += sizeof( id );
 +            LOG(log_debug, logtype_afpd, "metadata('%s'):           CNID: %u",
 +                path->u_name, ntohl(id));
              break;
  
          case FILPBIT_DFLEN :
@@@ -527,6 -563,10 +566,6 @@@ int getfilparams(struct vol *vol
      int                 opened = 0;
      int rc;    
  
 -#ifdef DEBUG
 -    LOG(log_debug9, logtype_default, "begin getfilparams:");
 -#endif /* DEBUG */
 -
      opened = PARAM_NEED_ADP(bitmap);
      adp = NULL;
  
      if ( adp ) {
          ad_close_metadata( adp);
      }
 -#ifdef DEBUG
 -    LOG(log_debug9, logtype_afpd, "end getfilparams:");
 -#endif /* DEBUG */
  
      return( rc );
  }
@@@ -1902,10 -1945,6 +1941,10 @@@ int afp_deleteid(AFPObj *obj _U_, char 
      }
  
      if (NULL == ( dir = dirlookup( vol, id )) ) {
 +        if (afp_errno == AFPERR_NOOBJ) {
 +            err = AFPERR_NOOBJ;
 +            goto delete;
 +        }
          return( AFPERR_PARAM );
      }
  
      else if (S_ISDIR(st.st_mode)) /* directories are bad */
          return AFPERR_BADTYPE;
  
 +delete:
      if (cnid_delete(vol->v_cdb, fileid)) {
          switch (errno) {
          case EROFS: