]> arthur.barton.de Git - netatalk.git/commitdiff
Update the CNID code again to allow for 4G CNIDs, and a little somethin'
authorjmarcus <jmarcus>
Tue, 29 Jan 2002 21:12:14 +0000 (21:12 +0000)
committerjmarcus <jmarcus>
Tue, 29 Jan 2002 21:12:14 +0000 (21:12 +0000)
somethin' to try and fix the issue when a client holding the recovery lock
on a database unexpectedly disconnects without closing the database.

etc/afpd/enumerate.c
etc/afpd/file.c
etc/afpd/fork.c
include/atalk/cnid.h
libatalk/cnid/cnid_add.c
libatalk/cnid/cnid_close.c
libatalk/cnid/cnid_open.c
libatalk/cnid/cnid_private.h

index 61e98a15403183c5ae5bbe2fbdd2a91bc52d05a9..199913fee298cc8f91f6b8c0af4dce76bea98af3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: enumerate.c,v 1.15 2002-01-24 16:32:12 jmarcus Exp $
+ * $Id: enumerate.c,v 1.16 2002-01-29 21:12:14 jmarcus Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -82,8 +82,8 @@ struct stat *st;
     cdir->d_did = cnid_add(vol->v_db, st, dir->d_did, upath,
                            upathlen, cdir->d_did);
     /* Fail out if things go bad with CNID. */
-    if (cdir->d_did > CNID_MAX) {
-        switch (cdir->d_did) {
+    if (cdir->d_did < 0) {
+        switch (errno) {
         case CNID_ERR_PARAM:
             LOG(log_error, logtype_default, "adddir: Incorrect parameters passed to cnid_add");
             return NULL;
index b21a99226d6578a4ffad724e8294b6b3446bb06a..1908170230900808d697190a22c289fe6e4ad7d1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: file.c,v 1.37 2002-01-20 01:32:45 jmarcus Exp $
+ * $Id: file.c,v 1.38 2002-01-29 21:12:14 jmarcus Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -225,8 +225,8 @@ int getfilparams(struct vol *vol,
             aint = cnid_add(vol->v_db, st, dir->d_did, upath,
                             strlen(upath), aint);
             /* Throw errors if cnid_add fails. */
-            if (aint > CNID_MAX) {
-                switch (aint) {
+            if (aint < 0) {
+                switch (errno) {
                 case CNID_ERR_PARAM:
                     LOG(log_error, logtype_default, "getfilparams: Incorrect parameters passed to cnid_add");
                     return(AFPERR_PARAM);
index 0a793d631a3b9f49c9878ec77d0df6692f292dfa..b98c304d74693d38d125740c9059edbd9718de27 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: fork.c,v 1.18 2002-01-20 01:34:40 jmarcus Exp $
+ * $Id: fork.c,v 1.19 2002-01-29 21:12:14 jmarcus Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -191,8 +191,8 @@ const u_int16_t     attrbits;
             aint = cnid_add(ofork->of_vol->v_db, &st,
                             ofork->of_dir->d_did,
                             upath, strlen(upath), aint);
-            if (aint > CNID_MAX) {
-                switch (aint) {
+            if (aint < 0) {
+                switch (errno) {
                 case CNID_ERR_PARAM:
                     LOG(log_error, logtype_default, "getforkparams: Incorrect parameters passed to cnid_add");
                     return(AFPERR_PARAM);
index 5ffba486061422f3a97539e69b24edf8e4295d82..29e428793aead488bf348a309e2aecbbd9ed83bf 100644 (file)
@@ -18,8 +18,6 @@
 #define CNID_ERR_DB    0x80000003
 #define CNID_ERR_MAX   0x80000004
 
-#define CNID_MAX       0x80000000
-
 typedef u_int32_t cnid_t;
 
 /* cnid_open.c */
index c803d9b596bded38e00cf1ec5f26ea9df26eaea0..dc61790e246f89ecc85ce54c6f6201ad92dacd7d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cnid_add.c,v 1.26 2002-01-24 15:15:48 jmarcus Exp $
+ * $Id: cnid_add.c,v 1.27 2002-01-29 21:12:18 jmarcus Exp $
  *
  * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
  * All Rights Reserved. See COPYRIGHT.
@@ -119,7 +119,8 @@ cnid_t cnid_add(void *CNID, const struct stat *st,
     int rc;
 
     if (!(db = CNID) || !st || !name) {
-        return CNID_ERR_PARAM;
+               errno = CNID_ERR_PARAM;
+        return -1;
     }
 
     /* Do a lookup. */
@@ -142,7 +143,8 @@ cnid_t cnid_add(void *CNID, const struct stat *st,
 
     if ((data.data = make_cnid_data(st, did, name, len)) == NULL) {
         LOG(log_error, logtype_default, "cnid_add: Path name is too long");
-        return CNID_ERR_PATH;
+        errno = CNID_ERR_PATH;
+               return -1;
     }
 
     data.size = CNID_HEADER_LEN + len + 1;
@@ -159,7 +161,8 @@ cnid_t cnid_add(void *CNID, const struct stat *st,
         default:
             LOG(log_error, logtype_default, "cnid_add: Unable to add CNID %u: %s",
                 ntohl(hint), db_strerror(rc));
-            return CNID_ERR_DB;
+            errno = CNID_ERR_DB;
+                       return -1;
         case 0:
 #ifdef DEBUG
             LOG(log_info, logtype_default, "cnid_add: Used hint for did %u, name %s as %u",
@@ -177,7 +180,8 @@ cnid_t cnid_add(void *CNID, const struct stat *st,
 retry:
     if ((rc = txn_begin(db->dbenv, NULL, &tid, 0)) != 0) {
         LOG(log_error, logtype_default, "cnid_add: Failed to begin transaction: %s", db_strerror(rc));
-        return CNID_ERR_DB;
+        errno = CNID_ERR_DB;
+               return -1;
     }
 
     /* Get the key. */
@@ -186,18 +190,20 @@ retry:
     case DB_LOCK_DEADLOCK:
         if ((rc = txn_abort(tid)) != 0) {
             LOG(log_error, logtype_default, "cnid_add: txn_abort: %s", db_strerror(rc));
-            return CNID_ERR_DB;
+            errno = CNID_ERR_DB;
+                       return -1;
         }
         goto retry;
     case 0:
         memcpy(&hint, rootinfo_data.data, sizeof(hint));
                id = ntohl(hint);
-       /* If we've hit the MAX CNID allowed, we return a fatal error.  CNID 
+       /* If we've hit the max CNID allowed, we return a fatal error.  CNID 
                 * needs to be recycled before proceding. */
-       if (++id == CNID_MAX) {
+       if (++id == CNID_INVALID) {
                txn_abort(tid);
                LOG(log_error, logtype_default, "cnid_add: FATAL: Cannot add CNID for %s.  CNID database has reached its limit.", name);
-               return CNID_ERR_MAX;
+                       errno = CNID_ERR_MAX;
+               return -1;
        }
                hint = htonl(id);
 #ifdef DEBUG
@@ -222,14 +228,16 @@ retry:
     case DB_LOCK_DEADLOCK:
         if ((rc = txn_abort(tid)) != 0) {
             LOG(log_error, logtype_default, "cnid_add: txn_abort: %s", db_strerror(rc));
-            return CNID_ERR_DB;
+            errno = CNID_ERR_DB;
+                       return -1;
         }
         goto retry;
     case 0:
        /* The transaction finished, commit it. */
        if ((rc = txn_commit(tid, 0)) != 0) {
                LOG(log_error, logtype_default, "cnid_add: Unable to commit transaction: %s", db_strerror(rc));
-               return CNID_ERR_DB;
+               errno = CNID_ERR_DB;
+                       return -1;
        }
                break;
     default:
@@ -241,7 +249,8 @@ retry:
     rc = add_cnid(db, &key, &data);
     if (rc) {
         LOG(log_error, logtype_default, "cnid_add: Failed to add CNID for %s to database using hint %u: %s", name, ntohl(hint), db_strerror(rc));
-        return CNID_ERR_DB;
+        errno = CNID_ERR_DB;
+               return -1;
     }
 
 #ifdef DEBUG
@@ -253,7 +262,8 @@ retry:
 cleanup_abort:
     txn_abort(tid);
 
-    return CNID_ERR_DB;
+    errno = CNID_ERR_DB;
+       return -1;
 }
 #endif /* CNID_DB */
 
index e15b285ecf4d506ef5247636d4ed64d93bb5feac..15021ee614846196f92056f837eacc784b35dd5c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cnid_close.c,v 1.20 2002-01-19 21:42:08 jmarcus Exp $
+ * $Id: cnid_close.c,v 1.21 2002-01-29 21:12:18 jmarcus Exp $
  */
 
 #ifdef HAVE_CONFIG_H
@@ -78,6 +78,7 @@ void cnid_close(void *CNID) {
                 LOG(log_error, logtype_default, "cnid_close: Failed to open database closing lock file: %s", strerror(errno));
             }
         }
+               (void)remove(db->lock_file);
     }
 
     db->db_didname->close(db->db_didname, 0);
index e2795ecda6e56faf68f805249254fbd8293c7d68..4025a9091cb99482f8cbbbe77504e35c40995ff6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cnid_open.c,v 1.36 2002-01-24 16:22:16 jmarcus Exp $
+ * $Id: cnid_open.c,v 1.37 2002-01-29 21:12:18 jmarcus Exp $
  *
  * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
  * All Rights Reserved. See COPYRIGHT.
@@ -188,7 +188,7 @@ static int compare_unicode(const DBT *a, const DBT *b)
 static int have_lock = 0;
 
 void *cnid_open(const char *dir) {
-    struct stat st, rsb, csb;
+    struct stat st, rsb, lsb, csb;
     struct flock lock;
     char path[MAXPATHLEN + 1];
     char recover_file[MAXPATHLEN + 1];
@@ -197,6 +197,7 @@ void *cnid_open(const char *dir) {
     DB_TXN *tid;
     u_int32_t DBEXTRAS = 0;
     int open_flag, len;
+       int no_recover_flag = 0;
     int rc, rfd = -1;
 
     if (!dir) {
@@ -256,6 +257,10 @@ void *cnid_open(const char *dir) {
      * NOTE: This won't work if multiple volumes for the same user refer
      * to the sahe directory. */
     strcat(path, DBLOCKFILE);
+       strcpy(db->lock_file, path);
+       if (stat(path, &lsb) == 0) {
+               no_recover_flag = 1;
+       }
     if ((db->lockfd = open(path, O_RDWR | O_CREAT, 0666)) > -1) {
         lock.l_start = 0;
         lock.l_len = 1;
@@ -275,7 +280,8 @@ void *cnid_open(const char *dir) {
     /* Create a file to represent database recovery.  While this file
      * exists, the database is being recovered, and all other clients will
      * select until recovery is complete, and this file goes away. */
-    if (!have_lock && db->lockfd > -1 && lock.l_start == 0) {
+    if (!have_lock && db->lockfd > -1 && lock.l_start == 0 &&
+               no_recover_flag == 0) {
         if (stat(recover_file, &rsb) == 0) {
             (void)remove(recover_file);
         }
index 8316259bddf61274970fb78397c1f9878fe5acb7..04713abf03fe7ea836b4ba1252bfc2d0ff41ee48 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cnid_private.h,v 1.6 2002-01-18 05:19:26 jmarcus Exp $
+ * $Id: cnid_private.h,v 1.7 2002-01-29 21:12:18 jmarcus Exp $
  */
 
 #ifndef LIBATALK_CNID_PRIVATE_H
@@ -25,6 +25,7 @@
 #define CNID_HEADER_LEN          (CNID_DEVINO_LEN + CNID_DID_LEN)
 
 #define CNID_START               17
+#define CNID_INVALID             0
 
 #define CNIDFLAG_ROOTINFO_RO     (1 << 0)
 #define CNIDFLAG_DB_RO           (1 << 1)
@@ -47,6 +48,7 @@ typedef struct CNID_private {
     DB_ENV* dbenv;
     int lockfd, flags;
     char close_file[MAXPATHLEN + 1];
+       char lock_file[MAXPATHLEN + 1];
 } CNID_private;
 
 /* on-disk data format (in network byte order where appropriate) --