]> arthur.barton.de Git - netatalk.git/commitdiff
Reactivate fcntl locking and fixes
authorFrank Lahm <franklahm@googlemail.com>
Fri, 23 Dec 2011 13:05:51 +0000 (14:05 +0100)
committerFrank Lahm <franklahm@googlemail.com>
Fri, 23 Dec 2011 13:05:51 +0000 (14:05 +0100)
etc/afpd/fork.c
etc/afpd/ofork.c
libatalk/adouble/ad_lock.c

index 1273e4aac8c60e7327d06d82d5a0f8bac1523176..d3c4b531bd2d4f036caef5fbc877315335f3175c 100644 (file)
@@ -267,10 +267,8 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si
         return  AFPERR_BADTYPE;
     }
 
-    LOG(log_debug, logtype_afpd,
-        "afp_openfork(\"%s\", %s)",
-        fullpathname(s_path->u_name),
-        (fork & OPENFORK_RSCS) ? "OPENFORK_RSCS" : "OPENFORK_DATA");
+    LOG(log_debug, logtype_afpd, "afp_openfork(\"%s\", %s)",
+        fullpathname(s_path->u_name), (fork & OPENFORK_RSCS) ? "RSRC" : "DATA");
 
     /* stat() data fork st is set because it's not a dir */
     switch ( s_path->st_errno ) {
@@ -325,7 +323,7 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si
     ret = AFPERR_NOOBJ;
     if (access & OPENACC_WR) {
         /* try opening in read-write mode */
-        if (ad_open(ofork->of_ad, upath, adflags, O_RDWR, O_RDWR) < 0) {
+        if (ad_open(ofork->of_ad, upath, adflags | ADFLAGS_RDWR) < 0) {
             switch ( errno ) {
             case EROFS:
                 ret = AFPERR_VLOCK;
@@ -335,14 +333,14 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si
             case ENOENT:
                 if (fork == OPENFORK_DATA) {
                     /* try to open only the data fork */
-                    if (ad_open(ofork->of_ad, upath, ADFLAGS_DF, O_RDWR) < 0) {
+                    if (ad_open(ofork->of_ad, upath, ADFLAGS_DF | ADFLAGS_RDWR) < 0) {
                         goto openfork_err;
                     }
                     adflags = ADFLAGS_DF;
                 } else {
                     /* here's the deal. we only try to create the resource
                      * fork if the user wants to open it for write acess. */
-                    if (ad_open(ofork->of_ad, upath, adflags, O_RDWR | O_CREAT, 0666, O_RDWR | O_CREAT, 0666) < 0)
+                    if (ad_open(ofork->of_ad, upath, adflags | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666) < 0)
                         goto openfork_err;
                     ofork->of_flags |= AFPFORK_OPEN;
                 }
@@ -370,7 +368,7 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si
     } else {
         /* try opening in read-only mode */
         ret = AFPERR_NOOBJ;
-        if (ad_open(ofork->of_ad, upath, adflags, O_RDONLY, O_RDONLY) < 0) {
+        if (ad_open(ofork->of_ad, upath, adflags | ADFLAGS_RDONLY) < 0) {
             switch ( errno ) {
             case EROFS:
                 ret = AFPERR_VLOCK;
@@ -380,7 +378,7 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si
             case ENOENT:
                 /* see if client asked for a read only data fork */
                 if (fork == OPENFORK_DATA) {
-                    if (ad_open(ofork->of_ad, upath, ADFLAGS_DF, O_RDONLY) < 0) {
+                    if (ad_open(ofork->of_ad, upath, ADFLAGS_DF | ADFLAGS_RDONLY) < 0) {
                         goto openfork_err;
                     }
                     adflags = ADFLAGS_DF;
index 02e250a448996d8f0b96e786b7392d03699df4a7..f535459f743d98f77dea0945d54b982027bcf89e 100644 (file)
@@ -200,9 +200,12 @@ of_alloc(struct vol *vol,
             return NULL;
         }
         strlcpy( ad->ad_m_name, path, ad->ad_m_namelen);
+    } else {
+        /* Increase the refcount on this struct adouble. This is
+           decremented again in oforc_dealloc. */
+        ad_ref(ad);
     }
 
-    ad_ref(ad);
     of->of_ad = ad;
     of->of_vol = vol;
     of->of_did = dir->d_did;
@@ -372,6 +375,17 @@ void of_dealloc( struct ofork *of)
 
     of_unhash(of);
     oforks[ of->of_refnum % nforks ] = NULL;
+
+    /* decrease refcount */
+    of->of_ad->ad_refcount--;
+
+    if ( of->of_ad->ad_refcount <= 0) {
+        free( of->of_ad->ad_m_name );
+        free( of->of_ad);
+    } else {/* someone's still using it. just free this user's locks */
+        ad_unlock(of->of_ad, of->of_refnum);
+    }
+
     free( of );
 }
 
@@ -379,10 +393,15 @@ void of_dealloc( struct ofork *of)
 int of_closefork(struct ofork *ofork)
 {
     struct timeval      tv;
-    int         doflush = 0;
+    int         adflags, doflush = 0;
     int                 ret;
 
+    adflags = 0;
+    if ((ofork->of_flags & AFPFORK_DATA) && (ad_data_fileno( ofork->of_ad ) != -1)) {
+        adflags |= ADFLAGS_DF;
+    }
     if ( (ofork->of_flags & AFPFORK_OPEN) && ad_reso_fileno( ofork->of_ad ) != -1 ) {
+        adflags |= ADFLAGS_HF;
         /*
          * Only set the rfork's length if we're closing the rfork.
          */
@@ -404,13 +423,8 @@ int of_closefork(struct ofork *ofork)
     }
 
     ret = 0;
-
-    ad_unlock(ofork->of_ad, ofork->of_refnum);
-    
-    if (ad_unref(ofork->of_ad) == 0) {
-        if ( ad_close( ofork->of_ad, 0 ) < 0 ) {
-            ret = -1;
-        }
+    if ( ad_close( ofork->of_ad, adflags ) < 0 ) {
+        ret = -1;
     }
 
     of_dealloc( ofork );
index 28d7bde82cb6b97ae97f7b1a333a838911d2feb0..3361008dc45277fa4009745b96f3bf7bde792552 100644 (file)
@@ -77,7 +77,6 @@ static int OVERLAP(off_t a, off_t alen, off_t b, off_t blen)
 /* remove a lock and compact space if necessary */
 static void adf_freelock(struct ad_fd *ad, const int i)
 {
-#if 0
     adf_lock_t *lock = ad->adf_lock + i;
 
     if (--(*lock->refcount) < 1) {
@@ -110,7 +109,6 @@ static void adf_freelock(struct ad_fd *ad, const int i)
                ad->adf_lockmax = ad->adf_lockcount + ARRAY_FREE_DELTA;
            }
     }
-#endif
 }
 
 
@@ -123,7 +121,6 @@ static void adf_freelock(struct ad_fd *ad, const int i)
  */
 static void adf_unlock(struct ad_fd *ad, const int fork)
 {
-#if 0
     adf_lock_t *lock = ad->adf_lock;
     int i;
 
@@ -138,14 +135,12 @@ static void adf_unlock(struct ad_fd *ad, const int fork)
         lock = ad->adf_lock;       
       }
     }
-#endif
 }
 
 /* relock any byte lock that overlaps off/len. unlock everything
  * else. */
 static void adf_relockrange(struct ad_fd *ad, int fd, off_t off, off_t len)
 {
-#if 0
     adf_lock_t *lock = ad->adf_lock;
     int i;
     
@@ -153,7 +148,6 @@ static void adf_relockrange(struct ad_fd *ad, int fd, off_t off, off_t len)
       if (OVERLAP(off, len, lock[i].lock.l_start, lock[i].lock.l_len)) 
        set_lock(fd, F_SETLK, &lock[i].lock);
     }
-#endif
 }
 
 
@@ -163,7 +157,6 @@ static int adf_findlock(struct ad_fd *ad,
                         const off_t off,
                         const off_t len)
 {
-#if 0
   adf_lock_t *lock = ad->adf_lock;
   int i;
   
@@ -175,7 +168,6 @@ static int adf_findlock(struct ad_fd *ad,
       return i;
     }
   }
-#endif
   return -1;
 }
 
@@ -186,7 +178,6 @@ static int adf_findxlock(struct ad_fd *ad,
                          const off_t off,
                          const off_t len)
 {
-#if 0
   adf_lock_t *lock = ad->adf_lock;
   int i;
   
@@ -197,7 +188,6 @@ static int adf_findxlock(struct ad_fd *ad,
        OVERLAP(off, len, lock[i].lock.l_start, lock[i].lock.l_len)) 
            return i;
   } 
-#endif
   return -1;
 }
 
@@ -267,10 +257,9 @@ static off_t hf2off(off_t off)
 }
 
 /* ------------------ */
-static int ad_fcntl_lock(struct adouble *ad, const uint32_t eid, const int locktype,
-                         const off_t off, const off_t len, const int fork)
+int ad_lock(struct adouble *ad, const uint32_t eid, const int locktype,
+            const off_t off, const off_t len, const int fork)
 {
-#if 0
   struct flock lock;
   struct ad_fd *adf;
   adf_lock_t *adflock;
@@ -284,7 +273,7 @@ static int ad_fcntl_lock(struct adouble *ad, const uint32_t eid, const int lockt
     adf = &ad->ad_data_fork;
     if ((type & ADLOCK_FILELOCK)) {
         if (ad_meta_fileno(ad) != -1) { /* META */
-            adf = ad->ad_md;
+            adf = ad->ad_mdp;
             lock.l_start = df2off(off);
         }
     }
@@ -298,7 +287,7 @@ static int ad_fcntl_lock(struct adouble *ad, const uint32_t eid, const int lockt
         return -1;
     }
     if (type & ADLOCK_FILELOCK) {
-      adf = ad->ad_md;                 /* either resource or meta data (set in ad_open) */
+      adf = ad->ad_mdp;                        /* either resource or meta data (set in ad_open) */
       lock.l_start = hf2off(off);
     }
     else {
@@ -408,7 +397,6 @@ fcntl_lock_err:
   lock.l_type = F_UNLCK;
   if (!adf->adf_excl) set_lock(adf->adf_fd, F_SETLK, &lock);
   return -1;
-#endif
   return 0;
 }
 
@@ -422,7 +410,6 @@ fcntl_lock_err:
 */
 static int testlock(struct ad_fd *adf, off_t off, off_t len)
 {
-#if 0
   struct flock lock;
   adf_lock_t *plock;
   int i;
@@ -451,15 +438,14 @@ static int testlock(struct ad_fd *adf, off_t off, off_t len)
       return 0;
   }
   return 1;
-#endif
   return 0;
 }
 
 
 /* -------------------------
 */
-static int ad_fcntl_tmplock(struct adouble *ad, const uint32_t eid, const int locktype,
-                            const off_t off, const off_t len, const int fork)
+int ad_tmplock(struct adouble *ad, const uint32_t eid, const int locktype,
+               const off_t off, const off_t len, const int fork)
 {
   struct flock lock;
   struct ad_fd *adf;
@@ -522,7 +508,7 @@ static int ad_fcntl_tmplock(struct adouble *ad, const uint32_t eid, const int lo
 }
 
 /* --------------------- */
-static void ad_fcntl_unlock(struct adouble *ad, const int fork)
+void ad_unlock(struct adouble *ad, const int fork)
 {
   if (ad_data_fileno(ad) != -1) {
     adf_unlock(&ad->ad_data_fork, fork);
@@ -539,8 +525,6 @@ static void ad_fcntl_unlock(struct adouble *ad, const int fork)
 /* --------------- */
 int ad_testlock(struct adouble *ad, int eid, const off_t off)
 {
-    return 0;
-#if 0
   struct ad_fd *adf;
   off_t      lock_offset;
 
@@ -548,7 +532,7 @@ int ad_testlock(struct adouble *ad, int eid, const off_t off)
   if (eid == ADEID_DFORK) {
     adf = &ad->ad_data_fork;
     if (ad_meta_fileno(ad) != -1) {
-       adf = ad->ad_md;
+       adf = ad->ad_mdp;
        lock_offset = df2off(off);
     }
   } 
@@ -557,11 +541,10 @@ int ad_testlock(struct adouble *ad, int eid, const off_t off)
         /* there's no resource fork. return no lock */
         return 0;
     }
-    adf = ad->ad_md;
+    adf = ad->ad_mdp;
     lock_offset = hf2off(off);
   }
   return testlock(adf, lock_offset, 1);
-#endif
 }
 
 /* -------------------------
@@ -572,8 +555,6 @@ int ad_testlock(struct adouble *ad, int eid, const off_t off)
 */
 uint16_t ad_openforks(struct adouble *ad, uint16_t attrbits)
 {
-    return 0;
-#if 0
   u_int16_t ret = 0;
   struct ad_fd *adf;
   off_t off;
@@ -588,7 +569,7 @@ uint16_t ad_openforks(struct adouble *ad, uint16_t attrbits)
           /* there's a resource fork test the four bytes for
            * data RW/RD and fork RW/RD locks in one request
           */
-         adf = ad->ad_md;
+         adf = ad->ad_mdp;
          off = LOCK_DATA_WR;
          len = 4;
       }
@@ -606,7 +587,7 @@ uint16_t ad_openforks(struct adouble *ad, uint16_t attrbits)
   */
   if (!(attrbits & ATTRBIT_DOPEN)) {
       if (ad_meta_fileno(ad) != -1) {
-         adf = ad->ad_md;
+         adf = ad->ad_mdp;
          off = LOCK_DATA_WR;
       }
       else {
@@ -618,14 +599,13 @@ uint16_t ad_openforks(struct adouble *ad, uint16_t attrbits)
 
   if (!(attrbits & ATTRBIT_ROPEN)) {
       if (ad_meta_fileno(ad) != -1) {
-         adf = ad->ad_md;
+         adf = ad->ad_mdp;
           off = LOCK_RSRC_WR;
           ret |= testlock(adf, off, 2) > 0? ATTRBIT_ROPEN : 0;
       }
   }
 
   return ret;
-#endif
 }
 
 /* -------------------------
@@ -634,8 +614,6 @@ uint16_t ad_openforks(struct adouble *ad, uint16_t attrbits)
 */
 int ad_excl_lock(struct adouble *ad, const uint32_t eid)
 {
-    return 0;
-#if 0
   struct ad_fd *adf;
   struct flock lock;
   int    err;
@@ -656,20 +634,4 @@ int ad_excl_lock(struct adouble *ad, const uint32_t eid)
   if (!err)
       adf->adf_excl = 1;
   return err;
-#endif
-}
-
-int ad_lock(struct adouble *ad, uint32_t eid, int type, off_t off, off_t len, int user)
-{
-    return 0;
-}
-
-void ad_unlock(struct adouble *ad, int user)
-{
-    return;
-}
-
-int ad_tmplock(struct adouble *ad, uint32_t eid, int type, off_t off, off_t len, int user)
-{
-    return 0;
 }