]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/adouble/ad_flush.c
Merge master
[netatalk.git] / libatalk / adouble / ad_flush.c
index b60fde6b0cab1a08e85512839ae7eee69bd96dc1..f41b10826d730e2e2bffe775d5fba53848c3508c 100644 (file)
@@ -147,8 +147,21 @@ int ad_copy_header(struct adouble *add, struct adouble *ads)
 int ad_flush(struct adouble *ad)
 {
     int len;
+    struct ad_fd *adf;
 
-    if (( ad->ad_mdp->adf_flags & O_RDWR )) {
+    switch (ad->ad_flags) {
+    case AD_VERSION2:
+        adf = ad->ad_mdp;
+        break;
+    case AD_VERSION_EA:
+        adf = &ad->ad_data_fork;
+        break;
+    default:
+        LOG(log_error, logtype_afpd, "ad_flush: unexpected adouble version");
+        return -1;
+    }
+
+    if ((adf->adf_flags & O_RDWR)) {
         if (ad_getentryoff(ad, ADEID_RFORK)) {
             if (ad->ad_rlen > 0xffffffff)
                 ad_setentrylen(ad, ADEID_RFORK, 0xffffffff);
@@ -207,12 +220,32 @@ int ad_close(struct adouble *ad, int adflags)
         adf_lock_free(&ad->ad_data_fork);
     }
 
-    if ((adflags & ADFLAGS_HF)
-        && (ad_meta_fileno(ad) != -1 && !(--ad->ad_mdp->adf_refcount))) {
-        if (close( ad_meta_fileno(ad) ) < 0)
-            err = -1;
-        ad_meta_fileno(ad) = -1;
-        adf_lock_free(ad->ad_mdp);
+    if ((adflags & ADFLAGS_HF)) {
+        switch (ad->ad_flags) {
+        case AD_VERSION2:
+            if ((ad_meta_fileno(ad) != -1) && !(--ad->ad_mdp->adf_refcount)) {
+                if (close( ad_meta_fileno(ad) ) < 0)
+                    err = -1;
+                ad_meta_fileno(ad) = -1;
+                adf_lock_free(ad->ad_mdp);
+            }
+            break;
+
+        case AD_VERSION_EA:
+            if ((ad_data_fileno(ad) >= 0 || ad_data_fileno(ad) == -2) /* -2 means symlink */ 
+                && !(--ad->ad_data_fork.adf_refcount)) {
+                if (close( ad_data_fileno(ad) ) < 0)
+                    err = -1;
+                ad_data_fileno(ad) = -1;
+                adf_lock_free(&ad->ad_data_fork);
+            }
+            break;
+
+        default:
+            LOG(log_error, logtype_default, "ad_close: unknown AD version");
+            errno = EIO;
+            return -1;
+        }
     }
 
     return err;