]> arthur.barton.de Git - netatalk.git/commitdiff
Redesign ad_open API to only use one arg for all flags, fix locking for adouble:v2
authorFrank Lahm <franklahm@googlemail.com>
Thu, 22 Dec 2011 16:07:32 +0000 (17:07 +0100)
committerFrank Lahm <franklahm@googlemail.com>
Thu, 22 Dec 2011 16:07:32 +0000 (17:07 +0100)
21 files changed:
bin/ad/ad_cp.c
bin/ad/ad_ls.c
bin/ad/ad_mv.c
etc/afpd/catsearch.c
etc/afpd/desktop.c
etc/afpd/directory.c
etc/afpd/extattrs.c
etc/afpd/file.c
etc/afpd/filedir.c
etc/afpd/fork.c
etc/afpd/volume.c
etc/cnid_dbd/cmd_dbd_scanvol.c
include/atalk/adouble.h
libatalk/adouble/ad_attr.c
libatalk/adouble/ad_flush.c
libatalk/adouble/ad_lock.c
libatalk/adouble/ad_lock.h
libatalk/adouble/ad_open.c
libatalk/adouble/ad_write.c
libatalk/vfs/ea_ad.c
libatalk/vfs/vfs.c

index 1020d7d6c022fcb998baab55edbcc05d0dbda6fe..49984637dc9e5cdb640445c545ac33f70765dbce 100644 (file)
@@ -544,7 +544,7 @@ static int copy(const char *path,
                 break;
             }
             ad_init(&ad, dvolume.volinfo.v_adouble, dvolume.volinfo.v_ad_options);
-            if (ad_open(&ad, to.p_path, ADFLAGS_HF | ADFLAGS_DIR, O_RDWR | O_CREAT, 0666) != 0) {
+            if (ad_open(&ad, to.p_path, ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666) != 0) {
                 ERROR("Error opening adouble for: %s", to.p_path);
             }
             ad_setid( &ad, st.st_dev, st.st_ino, did, pdid, dvolume.db_stamp);
@@ -554,7 +554,7 @@ static int copy(const char *path,
             ad_setdate(&ad, AD_DATE_ACCESS | AD_DATE_UNIX, st.st_mtime);
             ad_setdate(&ad, AD_DATE_BACKUP, AD_DATE_START);
             ad_flush(&ad);
-            ad_close_metadata(&ad);
+            ad_close(&ad, ADFLAGS_HF);
 
             umask(omask);
         }
@@ -611,7 +611,7 @@ static int copy(const char *path,
                 break;
             }
             ad_init(&ad, dvolume.volinfo.v_adouble, dvolume.volinfo.v_ad_options);
-            if (ad_open(&ad, to.p_path, ADFLAGS_HF, O_RDWR | O_CREAT) != 0) {
+            if (ad_open(&ad, to.p_path, ADFLAGS_HF | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666) != 0) {
                 ERROR("Error opening adouble for: %s", to.p_path);
             }
             ad_setid( &ad, st.st_dev, st.st_ino, cnid, did, dvolume.db_stamp);
@@ -621,7 +621,7 @@ static int copy(const char *path,
             ad_setdate(&ad, AD_DATE_ACCESS | AD_DATE_UNIX, st.st_mtime);
             ad_setdate(&ad, AD_DATE_BACKUP, AD_DATE_START);
             ad_flush(&ad);
-            ad_close_metadata(&ad);
+            ad_close(&ad, ADFLAGS_HF);
             umask(omask);
         }
         break;
index 63226a37cd77ccc5a174ad285151546481a88268..f7ca00e98979df1e723346d85f405a37af458915 100644 (file)
@@ -381,7 +381,7 @@ static void print_flags(char *path, afpvol_t *vol, const struct stat *st)
     else
         printf(" !ADVOL_CACHE ");
 
-    ad_close_metadata(&ad);
+    ad_close(&ad, ADFLAGS_HF);
 }
 
 #define TYPE(b) ((st->st_mode & (S_IFMT)) == (b))
index 156d648b004a5d2fe0f26a6a30ef1b95b4378651..9d5f5c227034bb0324cd374c7cf69835f5cf75c8 100644 (file)
@@ -374,13 +374,13 @@ static int do_move(const char *from, const char *to)
 
         struct adouble ad;
         ad_init(&ad, dvolume.volinfo.v_adouble, dvolume.volinfo.v_ad_options);
-        if (ad_open(&ad, to, S_ISDIR(sb.st_mode) ? (ADFLAGS_DIR | ADFLAGS_HF) : ADFLAGS_HF, O_RDWR) != 0) {
+        if (ad_open(&ad, to, S_ISDIR(sb.st_mode) ? (ADFLAGS_DIR | ADFLAGS_HF | ADFLAGS_RDWR) : ADFLAGS_HF | ADFLAGS_RDWR) != 0) {
             SLOG("Error opening adouble for: %s", to);
             return 1;
         }
         ad_setid(&ad, sb.st_dev, sb.st_ino, cnid, newdid, dvolume.db_stamp);
         ad_flush(&ad);
-        ad_close_metadata(&ad);
+        ad_close(&ad, ADFLAGS_HF);
 
         if (vflg)
             printf("%s -> %s\n", from, to);
index 1c913a0aab9de1fc008ea21b52cc789c724673e4..68d28664f822c374868020af23fcf56d13c00c88 100644 (file)
@@ -418,7 +418,7 @@ static int crit_check(struct vol *vol, struct path *path) {
        result |= 1;
 crit_check_ret:
        if (adp != NULL)
-               ad_close_metadata(adp);
+               ad_close(adp, ADFLAGS_HF);
        return result;
 }  
 
index 96e2fccf2f04b0e24634a8ddf314cd2af4079a87..a8e71a81dd0e1c228d325a07da9aeb2571792b6c 100644 (file)
@@ -650,8 +650,7 @@ static int ad_addcomment(struct vol *vol, struct path *path, char *ibuf)
         adp = of->of_ad;
 
     if (ad_open(adp, upath,
-                ADFLAGS_HF | ( (isadir) ? ADFLAGS_DIR : 0),
-                O_CREAT | O_RDWR,
+                ADFLAGS_HF | ( (isadir) ? ADFLAGS_DIR : 0) | ADFLAGS_CREATE | ADFLAGS_RDWR,
                 0666) < 0 ) {
         return( AFPERR_ACCESS );
     }
@@ -669,7 +668,7 @@ static int ad_addcomment(struct vol *vol, struct path *path, char *ibuf)
         memcpy( ad_entry( adp, ADEID_COMMENT ), ibuf, clen );
         ad_flush( adp );
     }
-    ad_close_metadata( adp);
+    ad_close(adp, ADFLAGS_HF);
     return( AFP_OK );
 }
 
@@ -730,7 +729,7 @@ static int ad_getcomment(struct vol *vol, struct path *path, char *rbuf, size_t
     }
 
     if (!ad_getentryoff(adp, ADEID_COMMENT)) {
-        ad_close_metadata( adp );
+        ad_close(adp, ADFLAGS_HF);
         return AFPERR_NOITEM;
     }
     /*
@@ -738,7 +737,7 @@ static int ad_getcomment(struct vol *vol, struct path *path, char *rbuf, size_t
      */
     if ( ad_getentrylen( adp, ADEID_COMMENT ) <= 0 ||
             ad_getentrylen( adp, ADEID_COMMENT ) > 199 ) {
-        ad_close_metadata( adp );
+        ad_close(adp, ADFLAGS_HF);
         return( AFPERR_NOITEM );
     }
 
@@ -746,7 +745,7 @@ static int ad_getcomment(struct vol *vol, struct path *path, char *rbuf, size_t
     *rbuf++ = clen;
     memcpy( rbuf, ad_entry( adp, ADEID_COMMENT ), clen);
     *rbuflen = clen + 1;
-    ad_close_metadata( adp);
+    ad_close(adp, ADFLAGS_HF);
 
     return( AFP_OK );
 }
@@ -802,7 +801,7 @@ static int ad_rmvcomment(struct vol *vol, struct path *path)
     } else
         adp = of->of_ad;
 
-    if ( ad_open(adp, upath, ADFLAGS_HF | (isadir) ? ADFLAGS_DIR : 0, 0) < 0 ) {
+    if ( ad_open(adp, upath, ADFLAGS_HF | ADFLAGS_RDWR | (isadir) ? ADFLAGS_DIR : 0) < 0 ) {
         switch ( errno ) {
         case ENOENT :
             return( AFPERR_NOITEM );
@@ -817,7 +816,7 @@ static int ad_rmvcomment(struct vol *vol, struct path *path)
         ad_setentrylen( adp, ADEID_COMMENT, 0 );
         ad_flush( adp );
     }
-    ad_close_metadata( adp);
+    ad_close(adp, ADFLAGS_HF);
     return( AFP_OK );
 }
 
index dd9221034dbb5daf3e1cce0747ea2f92a4052516..5c8f6e9f9c68c2d052e82ee3ae366e1e1f6679db 100644 (file)
@@ -913,7 +913,7 @@ struct dir *dir_add(struct vol *vol, const struct dir *dir, struct path *path, i
 
     /* get_id needs adp for reading CNID from adouble file */
     ad_init(&ad, vol->v_adouble, vol->v_ad_options);
-    if ((ad_open(&ad, path->u_name, ADFLAGS_HF | ADFLAGS_DIR)) == 0) /* 1 */
+    if ((ad_open(&ad, path->u_name, ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_RDONLY)) == 0) /* 1 */
         adp = &ad;
 
     /* Get CNID */
@@ -923,7 +923,7 @@ struct dir *dir_add(struct vol *vol, const struct dir *dir, struct path *path, i
     }
 
     if (adp)
-        ad_close_metadata(adp);
+        ad_close(adp, ADFLAGS_HF);
 
     /* Get macname from unixname */
     if (path->m_name == NULL) {
@@ -966,7 +966,7 @@ exit:
             cfrombstr(dir->d_u_name), path->u_name, err);
 
         if (adp)
-            ad_close_metadata(adp);
+            ad_close(adp, ADFLAGS_HF);
         if (!cdir && fullpath)
             bdestroy(fullpath);
         if (cdir)
@@ -1503,7 +1503,7 @@ int getdirparams(const struct vol *vol,
         ad_init(&ad, vol->v_adouble, vol->v_ad_options);
         if ( !ad_metadata( upath, ADFLAGS_DIR, &ad) ) {
             isad = 1;
-            if (ad.ad_md->adf_flags & O_CREAT) {
+            if (ad.ad_mdp->adf_flags & O_CREAT) {
                 /* We just created it */
                 if (s_path->m_name == NULL) {
                     if ((s_path->m_name = utompath(vol,
@@ -1700,7 +1700,7 @@ int getdirparams(const struct vol *vol,
 
         default :
             if ( isad ) {
-                ad_close_metadata( &ad );
+                ad_close(&ad, ADFLAGS_HF);
             }
             return( AFPERR_BITMAP );
         }
@@ -1718,7 +1718,7 @@ int getdirparams(const struct vol *vol,
         data = set_name(vol, data, pdid, cfrombstr(dir->d_m_name), dir->d_did, utf8);
     }
     if ( isad ) {
-        ad_close_metadata( &ad );
+        ad_close(&ad, ADFLAGS_HF);
     }
     *buflen = data - buf;
     return( AFP_OK );
@@ -1929,7 +1929,7 @@ int setdirparams(struct vol *vol, struct path *path, uint16_t d_bitmap, char *bu
     }
     ad_init(&ad, vol->v_adouble, vol->v_ad_options);
 
-    if (ad_open(&ad, upath, ADFLAGS_HF | ADFLAGS_DIR, O_CREAT, 0777) != 0) {
+    if (ad_open(&ad, upath, ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_CREATE | ADFLAGS_RDWR, 0777) != 0) {
         /*
          * Check to see what we're trying to set.  If it's anything
          * but ACCESS, UID, or GID, give an error.  If it's any of those
@@ -2113,8 +2113,8 @@ setdirparam_done:
                 ad_setid(&ad, st->st_dev, st->st_ino,  dir->d_did, dir->d_pdid, vol->v_stamp);
             }
         }
-        ad_flush( &ad);
-        ad_close_metadata( &ad);
+        ad_flush(&ad);
+        ad_close(&ad, ADFLAGS_HF);
     }
 
     if (change_parent_mdate && dir->d_did != DIRDID_ROOT
@@ -2282,7 +2282,7 @@ int afp_createdir(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_
     }
 
     ad_init(&ad, vol->v_adouble, vol->v_ad_options);
-    if (ad_open(&ad, ".", ADFLAGS_HF | ADFLAGS_DIR, O_CREAT, 0777) < 0)  {
+    if (ad_open(&ad, ".", ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_CREATE | ADFLAGS_RDWR, 0777) < 0)  {
         if (vol_noadouble(vol))
             goto createdir_done;
         return( AFPERR_ACCESS );
@@ -2292,8 +2292,8 @@ int afp_createdir(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_
 
     fce_register_new_dir(s_path);
 
-    ad_flush( &ad);
-    ad_close_metadata( &ad);
+    ad_flush(&ad);
+    ad_close(&ad, ADFLAGS_HF);
 
 createdir_done:
     memcpy( rbuf, &dir->d_did, sizeof( uint32_t ));
@@ -2350,10 +2350,10 @@ int renamedir(const struct vol *vol,
 
     ad_init(&ad, vol->v_adouble, vol->v_ad_options);
 
-    if (ad_open(&ad, dst, ADFLAGS_HF | ADFLAGS_DIR) == 0) {
+    if (ad_open(&ad, dst, ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_RDWR) == 0) {
         ad_setname(&ad, newname);
-        ad_flush( &ad);
-        ad_close_metadata( &ad);
+        ad_flush(&ad);
+        ad_close(&ad, ADFLAGS_HF);
     }
 
     return( AFP_OK );
@@ -2381,7 +2381,7 @@ int deletecurdir(struct vol *vol)
     if ( ad_metadata( ".", ADFLAGS_DIR, &ad) == 0 ) {
 
         ad_getattr(&ad, &ashort);
-        ad_close_metadata(&ad);
+        ad_close(&ad, ADFLAGS_HF);
         if ((ashort & htons(ATTRBIT_NODELETE))) {
             return  AFPERR_OLOCK;
         }
index 3be452ed962c4c0eb1d9b34433ccc2510a5116cd..2a5214e5ab968ec96ae1ea633a633cf9078dcc71 100644 (file)
@@ -234,7 +234,7 @@ exit:
         buf_valid = 0;
 
     if (adp)
-        ad_close_metadata(adp);
+        ad_close(adp, ADFLAGS_HF);
 
     return ret;
 }
index 4c954e4e80f8daccb64bac9731b975749d035a5a..41462d1987d41c4e37f5568a7d66dd16570e1e25 100644 (file)
@@ -639,7 +639,7 @@ int getfilparams(struct vol *vol,
         }
     }
     rc = getmetadata(vol, bitmap, path, dir, buf, buflen, adp);
-    ad_close_metadata( adp);
+    ad_close(adp, ADFLAGS_HF);
 
     return( rc );
 }
@@ -692,15 +692,14 @@ int afp_createfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_,
             return AFPERR_EXIST;
     }
 
-    if ( creatf)
-        openf = O_RDWR|O_CREAT|O_TRUNC;
+    if (creatf)
+        openf = ADFLAGS_RDWR | ADFLAGS_CREATE | ADFLAGS_TRUNC;
     else
        /* on a soft create, if the file is open then ad_open won't fail
           because open syscall is not called */
-        openf = O_RDWR|O_CREAT|O_EXCL;
+        openf = ADFLAGS_RDWR | ADFLAGS_CREATE | ADFLAGS_EXCL;
 
-    if ( ad_open(&ad, upath, ADFLAGS_DF | ADFLAGS_HF | ADFLAGS_NOHF,
-                 openf, 0666, openf, 0666) < 0 ) {
+    if (ad_open(&ad, upath, ADFLAGS_DF | ADFLAGS_HF | ADFLAGS_NOHF | openf, 0666) < 0) {
         switch ( errno ) {
         case EROFS:
             return AFPERR_VLOCK;
@@ -965,7 +964,7 @@ int setfilparams(struct vol *vol,
 
     /* second try with adouble open 
     */
-    if ( ad_open(adp, upath, ADFLAGS_HF, O_RDWR | O_CREAT, 0666) < 0) {
+    if (ad_open(adp, upath, ADFLAGS_HF | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666) < 0) {
         LOG(log_debug, logtype_afpd, "setfilparams: ad_open_metadata error");
         /*
          * For some things, we don't need an adouble header:
@@ -1057,8 +1056,8 @@ setfilparam_done:
     }
 
     if (isad) {
-        ad_flush( adp);
-        ad_close_metadata( adp);
+        ad_flush(adp);
+        ad_close(adp, ADFLAGS_HF);
     }
 
     if (change_parent_mdate && gettimeofday(&tv, NULL) == 0) {
@@ -1145,7 +1144,7 @@ int renamefile(const struct vol *vol, int sdir_fd, char *src, char *dst, char *n
     }
 
     /* don't care if we can't open the newly renamed ressource fork */
-    if (ad_open(adp, dst, ADFLAGS_HF, O_RDWR) == 0) {
+    if (ad_open(adp, dst, ADFLAGS_HF | ADFLAGS_RDWR) == 0) {
         ad_setname(adp, newname);
         ad_flush( adp );
         ad_close( adp, ADFLAGS_HF );
@@ -1273,7 +1272,7 @@ int afp_copyfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, si
 
     adp = of_ad(s_vol, s_path, &ad);
 
-    if (ad_open(adp, s_path->u_name, ADFLAGS_DF | ADFLAGS_HF | ADFLAGS_NOHF, O_RDONLY, O_RDONLY) < 0) {
+    if (ad_open(adp, s_path->u_name, ADFLAGS_DF | ADFLAGS_HF | ADFLAGS_NOHF | ADFLAGS_RDONLY) < 0) {
         return AFPERR_DENYCONF;
     }
     denyreadset = (ad_testlock(adp, ADEID_DFORK, AD_FILELOCK_DENY_RD) != 0 || 
@@ -1475,7 +1474,7 @@ int copyfile(const struct vol *s_vol,
         adflags |= ADFLAGS_HF;
     }
 
-    if (ad_openat(adp, sfd, src, adflags | ADFLAGS_NOHF, O_RDONLY, O_RDONLY) < 0) {
+    if (ad_openat(adp, sfd, src, adflags | ADFLAGS_NOHF | ADFLAGS_RDONLY) < 0) {
         ret_err = errno;
         goto done;
     }
@@ -1493,7 +1492,7 @@ int copyfile(const struct vol *s_vol,
     }
 
     ad_init(&add, d_vol->v_adouble, d_vol->v_ad_options);
-    if (ad_open(&add, dst, adflags, O_RDWR|O_CREAT|O_EXCL, st.st_mode, O_RDWR|O_CREAT|O_EXCL, st.st_mode) < 0) {
+    if (ad_open(&add, dst, adflags | ADFLAGS_RDWR | ADFLAGS_CREATE | ADFLAGS_EXCL, st.st_mode) < 0) {
         ret_err = errno;
         ad_close( adp, adflags );
         if (EEXIST != ret_err) {
@@ -1611,7 +1610,7 @@ int deletefile(const struct vol *vol, int dirfd, char *file, int checkAttrib)
         */
         if ( ad_metadataat(dirfd, file, ADFLAGS_CHECK_OF, &ad) == 0 ) {
             if ((err = check_attrib(&ad))) {
-               ad_close_metadata(&ad);
+                ad_close(&ad, ADFLAGS_HF);
                return err;
             }
             meta = 1;
@@ -1620,7 +1619,7 @@ int deletefile(const struct vol *vol, int dirfd, char *file, int checkAttrib)
  
     /* try to open both forks at once */
     adflags = ADFLAGS_DF;
-    if ( ad_openat(&ad, dirfd, file, adflags |ADFLAGS_HF|ADFLAGS_NOHF, O_RDONLY, O_RDONLY) < 0 ) {
+    if (ad_openat(&ad, dirfd, file, adflags | ADFLAGS_HF | ADFLAGS_NOHF | ADFLAGS_RDONLY) < 0 ) {
         switch (errno) {
         case ENOENT:
             err = AFPERR_NOOBJ;
@@ -1667,7 +1666,7 @@ int deletefile(const struct vol *vol, int dirfd, char *file, int checkAttrib)
 
 end:
     if (meta)
-        ad_close_metadata(&ad);
+        ad_close(&ad, ADFLAGS_HF);
 
     if (adp)
         ad_close( &ad, adflags );  /* ad_close removes locks if any */
@@ -2030,7 +2029,7 @@ static struct adouble *find_adouble(struct path *path, struct ofork **of, struct
         adp = (*of)->of_ad;
     }
     else {
-        ret = ad_open(adp, path->u_name, ADFLAGS_HF, O_RDONLY);
+        ret = ad_open(adp, path->u_name, ADFLAGS_HF | ADFLAGS_RDONLY);
         /* META and HF */
         if ( !ret && ad_reso_fileno(adp) != -1 && !(adp->ad_resource_fork.adf_flags & ( O_RDWR | O_WRONLY))) {
             /* from AFP spec.
index 61386d66f4e09064aae40668223458ecff6ed691..f98f79c79c45375b25bd254f0fb808dff8e63c7f 100644 (file)
@@ -305,7 +305,7 @@ static int moveandrename(const struct vol *vol,
 
         ad_getattr(adp, &bshort);
         
-        ad_close_metadata( adp);
+        ad_close(adp, ADFLAGS_HF);
         if ((bshort & htons(ATTRBIT_NORENAME))) {
             rc = AFPERR_OLOCK;
             goto exit;
@@ -380,7 +380,7 @@ static int moveandrename(const struct vol *vol,
         if (!ad_metadata(upath, adflags, adp)) {
             ad_setid(adp, st->st_dev, st->st_ino, id, curdir->d_did, vol->v_stamp);
             ad_flush(adp);
-            ad_close_metadata(adp);
+            ad_close(adp, ADFLAGS_HF);
         }
 
         /* fix up the catalog entry */
index ad92ff4a431a413517d49c7109214f4070d92dc4..1273e4aac8c60e7327d06d82d5a0f8bac1523176 100644 (file)
@@ -834,9 +834,8 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si
     reqcount = get_off_t(&ibuf, is64);
 
     LOG(log_debug, logtype_afpd,
-         "afp_read(\"%s\", off: %" PRIu64 ", size: %" PRIu64 ", fork: %s)",
-         cfrombstr(ofork->of_ad->ad_fullpath), offset, reqcount,
-         (ofork->of_flags & AFPFORK_DATA) ? "d" : "r");
+        "afp_read(off: %" PRIu64 ", size: %" PRIu64 ", fork: %s)", offset, reqcount,
+        (ofork->of_flags & AFPFORK_DATA) ? "d" : "r");
 
     if (is64) {
         nlmask = nlchar = 0;
@@ -1013,9 +1012,7 @@ int afp_flushfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U
         return( AFPERR_PARAM );
     }
 
-    LOG(log_debug, logtype_afpd,
-        "afp_flushfork(\"%s\", fork: %s)",
-        cfrombstr(ofork->of_ad->ad_fullpath),
+    LOG(log_debug, logtype_afpd, "afp_flushfork(fork: %s)",
         (ofork->of_flags & AFPFORK_DATA) ? "d" : "r");
 
     if ( flushfork( ofork ) < 0 ) {
@@ -1047,9 +1044,7 @@ int afp_syncfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_
         return( AFPERR_PARAM );
     }
 
-    LOG(log_debug, logtype_afpd,
-        "afp_syncfork(\"%s\", fork: %s)",
-        cfrombstr(ofork->of_ad->ad_fullpath),
+    LOG(log_debug, logtype_afpd, "afp_syncfork(fork: %s)",
         (ofork->of_flags & AFPFORK_DATA) ? "d" : "r");
 
     if ( flushfork( ofork ) < 0 ) {
@@ -1116,9 +1111,7 @@ int afp_closefork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U
         return( AFPERR_PARAM );
     }
 
-    LOG(log_debug, logtype_afpd,
-        "afp_closefork(\"%s\", fork: %s)",
-        cfrombstr(ofork->of_ad->ad_fullpath),
+    LOG(log_debug, logtype_afpd, "afp_closefork(fork: %s)",
         (ofork->of_flags & AFPFORK_DATA) ? "d" : "r");
 
     if ( of_closefork( ofork ) < 0 ) {
@@ -1196,10 +1189,8 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s
         goto afp_write_err;
     }
 
-    LOG(log_debug, logtype_afpd,
-        "afp_write(\"%s\", off: %" PRIu64 ", size: %" PRIu64 ", fork: %s)",
-        cfrombstr(ofork->of_ad->ad_fullpath), offset, reqcount,
-        (ofork->of_flags & AFPFORK_DATA) ? "d" : "r");
+    LOG(log_debug, logtype_afpd, "afp_write(off: %" PRIu64 ", size: %" PRIu64 ", fork: %s)",
+        offset, reqcount, (ofork->of_flags & AFPFORK_DATA) ? "d" : "r");
 
     if ((ofork->of_flags & AFPFORK_ACCWR) == 0) {
         err = AFPERR_ACCESS;
index 7437f58b6a6fad9a86b7d13bf4dd1cac89cb7446..0d2bf0614560ca78e2d5955adf1730fea9d3c68b 100644 (file)
@@ -1620,7 +1620,7 @@ static int getvolparams( uint16_t bitmap, struct vol *vol, struct stat *st, char
      * .Parent file here if it doesn't exist. */
 
     ad_init(&ad, vol->v_adouble, vol->v_ad_options);
-    if (ad_open(&ad, vol->v_path, ADFLAGS_HF | ADFLAGS_DIR, O_RDWR | O_CREAT, 0666) != 0 ) {
+    if (ad_open(&ad, vol->v_path, ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666) != 0 ) {
         isad = 0;
         vol->v_ctime = AD_DATE_FROM_UNIX(st->st_mtime);
 
@@ -1797,7 +1797,7 @@ static int getvolparams( uint16_t bitmap, struct vol *vol, struct stat *st, char
         data += aint;
     }
     if ( isad ) {
-        ad_close_metadata( &ad);
+        ad_close(&ad, ADFLAGS_HF);
     }
     *buflen = data - buf;
     return( AFP_OK );
@@ -2605,7 +2605,7 @@ int afp_setvolparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf
         return AFPERR_BITMAP;
 
     ad_init(&ad, vol->v_adouble, vol->v_ad_options);
-    if ( ad_open(&ad,  vol->v_path, ADFLAGS_HF|ADFLAGS_DIR, O_RDWR) < 0 ) {
+    if ( ad_open(&ad,  vol->v_path, ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_RDWR) < 0 ) {
         if (errno == EROFS)
             return AFPERR_VLOCK;
 
@@ -2700,7 +2700,7 @@ static int create_special_folder (const struct vol *vol, const struct _special_f
     if ( !ret && folder->hide) {
         /* Hide it */
         ad_init(&ad, vol->v_adouble, vol->v_ad_options);
-        if (ad_open(&ad, p, ADFLAGS_HF | ADFLAGS_DIR, O_RDWR | O_CREAT, 0666) != 0) {
+        if (ad_open(&ad, p, ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666) != 0) {
             free(p);
             free(q);
             return (-1);
@@ -2719,8 +2719,8 @@ static int create_special_folder (const struct vol *vol, const struct _special_f
             memcpy(ad_entry(&ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF,&attr, sizeof(attr));
         }
 
-        ad_flush( &ad );
-        ad_close_metadata( &ad);
+        ad_flush(&ad);
+        ad_close(&ad, ADFLAGS_HF);
     }
     free(p);
     free(q);
index 75f51fa6463d78757f520954fee0324833555c25..3061c2fb16cb1db93a0c7f0bbbb7f889bf6f4e60 100644 (file)
@@ -322,7 +322,7 @@ static int check_adfile(const char *fname, const struct stat *st)
         /* Create ad file */
         ad_init(&ad, myvolinfo->v_adouble, myvolinfo->v_ad_options);
 
-        if ((ret = ad_open(&ad,  fname, adflags, O_CREAT | O_RDWR, 0666)) != 0) {
+        if ((ret = ad_open(&ad, fname, adflags | ADFLAGS_CREATE | ADFLAGS_RDWR, 0666)) != 0) {
             dbd_log( LOGSTD, "Error creating AppleDouble file '%s/%s': %s",
                      cwdbuf, adname, strerror(errno));
 
@@ -332,7 +332,7 @@ static int check_adfile(const char *fname, const struct stat *st)
         /* Set name in ad-file */
         ad_setname(&ad, utompath((char *)fname));
         ad_flush(&ad);
-        ad_close_metadata(&ad);
+        ad_close(&ad, ADFLAGS_HF);
 
         chown(adname, st->st_uid, st->st_gid);
         /* FIXME: should we inherit mode too here ? */
@@ -341,11 +341,11 @@ static int check_adfile(const char *fname, const struct stat *st)
 #endif
     } else {
         ad_init(&ad, myvolinfo->v_adouble, myvolinfo->v_ad_options);
-        if (ad_open(&ad, fname, adflags, O_RDONLY) != 0) {
+        if (ad_open(&ad, fname, adflags | ADFLAGS_RDONLY) != 0) {
             dbd_log( LOGSTD, "Error opening AppleDouble file for '%s/%s'", cwdbuf, fname);
             return -1;
         }
-        ad_close_metadata(&ad);
+        ad_close(&ad, ADFLAGS_HF);
     }
     return 0;
 }
@@ -499,7 +499,7 @@ static int check_addir(int volroot)
         /* Create ad dir and set name */
         ad_init(&ad, myvolinfo->v_adouble, myvolinfo->v_ad_options);
 
-        if (ad_open(&ad, ".", ADFLAGS_HF | ADFLAGS_DIR, O_CREAT | O_RDWR, 0777) != 0) {
+        if (ad_open(&ad, ".", ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_CREATE | ADFLAGS_RDWR, 0777) != 0) {
             dbd_log( LOGSTD, "Error creating AppleDouble dir in %s: %s", cwdbuf, strerror(errno));
             return -1;
         }
@@ -510,7 +510,7 @@ static int check_addir(int volroot)
         /* Update name in ad file */
         ad_setname(&ad, mname);
         ad_flush(&ad);
-        ad_close_metadata(&ad);
+        ad_close(&ad, ADFLAGS_HF);
 
         /* Inherit owner/group from "." to ".AppleDouble" and ".Parent" */
         if ((lstat(".", &st)) != 0) {
@@ -695,7 +695,7 @@ static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfi
     ad_cnid = 0;
     if ( (myvolinfo->v_flags & AFPVOL_CACHE) && ADFILE_OK) {
         ad_init(&ad, myvolinfo->v_adouble, myvolinfo->v_ad_options);
-        if (ad_open(&ad, name, adflags, O_RDWR) != 0) {
+        if (ad_open(&ad, name, adflags | ADFLAGS_RDWR) != 0) {
             
             if (dbd_flags & DBD_FLAGS_CLEANUP)
                 return CNID_INVALID;
@@ -718,7 +718,7 @@ static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfi
         else
             dbd_log( LOGDEBUG, "CNID from .AppleDouble file for '%s/%s': %u", cwdbuf, name, ntohl(ad_cnid));
 
-        ad_close_metadata(&ad);
+        ad_close(&ad, ADFLAGS_HF);
     }
 
     /* Get CNID from database */
@@ -761,14 +761,14 @@ static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfi
             dbd_log(LOGSTD, "Updating AppleDouble file for '%s/%s' with CNID: %u from database",
                             cwdbuf, name, ntohl(db_cnid));
             ad_init(&ad, myvolinfo->v_adouble, myvolinfo->v_ad_options);
-            if (ad_open(&ad, name, adflags | ADFLAGS_HF, O_RDWR, 0666, &ad) != 0) {
+            if (ad_open(&ad, name, adflags | ADFLAGS_HF | ADFLAGS_RDWR) != 0) {
                 dbd_log(LOGSTD, "Error opening AppleDouble file for '%s/%s': %s",
                         cwdbuf, name, strerror(errno));
                 return CNID_INVALID;
             }
             ad_setid( &ad, st->st_dev, st->st_ino, db_cnid, did, stamp);
             ad_flush(&ad);
-            ad_close_metadata(&ad);
+            ad_close(&ad, ADFLAGS_HF);
         }
         return db_cnid;
     } else if (ad_cnid && (db_cnid == 0)) {
@@ -794,14 +794,14 @@ static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfi
                     dbd_log(LOGSTD, "Writing CNID data for '%s/%s' to AppleDouble file",
                             cwdbuf, name, ntohl(db_cnid));
                     ad_init(&ad, myvolinfo->v_adouble, myvolinfo->v_ad_options);
-                    if (ad_open(&ad, name, adflags, O_RDWR) != 0) {
+                    if (ad_open(&ad, name, adflags | ADFLAGS_RDWR) != 0) {
                         dbd_log(LOGSTD, "Error opening AppleDouble file for '%s/%s': %s",
                                 cwdbuf, name, strerror(errno));
                         return CNID_INVALID;
                     }
                     ad_setid( &ad, st->st_dev, st->st_ino, db_cnid, did, stamp);
                     ad_flush(&ad);
-                    ad_close_metadata(&ad);
+                    ad_close(&ad, ADFLAGS_HF);
                 }
                 return db_cnid;
             }
@@ -834,14 +834,14 @@ static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfi
                 dbd_log(LOGSTD, "Writing CNID data for '%s/%s' to AppleDouble file",
                         cwdbuf, name, ntohl(db_cnid));
                 ad_init(&ad, myvolinfo->v_adouble, myvolinfo->v_ad_options);
-                if (ad_open(&ad, name, adflags, O_RDWR) != 0) {
+                if (ad_open(&ad, name, adflags | ADFLAGS_RDWR) != 0) {
                     dbd_log(LOGSTD, "Error opening AppleDouble file for '%s/%s': %s",
                             cwdbuf, name, strerror(errno));
                     return CNID_INVALID;
                 }
                 ad_setid( &ad, st->st_dev, st->st_ino, db_cnid, did, stamp);
                 ad_flush(&ad);
-                ad_close_metadata(&ad);
+                ad_close(&ad, ADFLAGS_HF);
             }
         }
         return db_cnid;
index fd466b2fb6e4d6500d27ada409bf456657576ea3..bf8152fbdfdfa8a556a104031a9ecf4e9451e007 100644 (file)
@@ -159,16 +159,11 @@ typedef struct adf_lock_t {
 
 struct ad_fd {
     int          adf_fd;        /* -1: invalid, -2: symlink */
-#ifndef HAVE_PREAD
-    off_t        adf_off;
-#endif
     char         *adf_syml;
     int          adf_flags;
     int          adf_excl;
-#if 0
     adf_lock_t   *adf_lock;
     int          adf_refcount, adf_lockcount, adf_lockmax;
-#endif
 };
 
 /* some header protection */
@@ -192,10 +187,11 @@ struct adouble {
     struct ad_entry     ad_eid[ADEID_MAX];
     struct ad_fd        ad_data_fork;     /* the data fork                            */
     struct ad_fd        ad_resource_fork; /* adouble:v2 -> the adouble file           *
-                                           * adouble:ea -> the rfork EA               */
-    struct ad_fd        ad_metadata_fork; /* adouble:v2 -> unused                     *
-                                           * adouble:ea -> the metadata EA            */
-    struct ad_fd        *ad_md;           /* either ad_resource or ad_metadata        */
+                                           * adouble:ea -> unused                     */
+    struct ad_fd        *ad_rfp;          /* adouble:v2 -> ad_resource_fork           *
+                                           * adouble:ea -> ad_data_fork               */
+    struct ad_fd        *ad_mdp;          /* adouble:v2 -> ad_resource_fork           *
+                                           * adouble:ea -> ad_data_fork               */
     int                 ad_flags;         /* Our adouble version info (AD_VERSION*)   */
     int                 ad_adflags;       /* ad_open flags adflags like ADFLAGS_DIR   */
     uint32_t            ad_inited;
@@ -207,7 +203,6 @@ struct adouble {
                                             * the header parameter size is too small. */
     char                *ad_m_name;        /* mac name for open fork                  */
     int                 ad_m_namelen;
-    bstring             ad_fullpath;       /* fullpath of file, adouble:ea need this  */
     struct adouble_fops *ad_ops;
     uint16_t            ad_open_forks;     /* open forks (by others)                  */
     char                ad_data[AD_DATASZ_MAX];
@@ -220,6 +215,12 @@ struct adouble {
 #define ADFLAGS_NOHF      (1<<4)  /* not an error if no ressource fork */
 #define ADFLAGS_CHECK_OF  (1<<6)  /* check for open forks from us and other afpd's */
 
+#define ADFLAGS_RDWR      (1<<7)  /* open read/write */
+#define ADFLAGS_RDONLY    (1<<7)  /* open read only */
+#define ADFLAGS_CREATE    (1<<8)  /* create file, open called with O_CREAT */
+#define ADFLAGS_EXCL      (1<<9)  /* exclusive open, open called with O_EXCL */
+#define ADFLAGS_TRUNC     (1<<10) /* truncate, open called with O_TRUNC */
+
 #define ADVOL_NODEV      (1 << 0)
 #define ADVOL_CACHE      (1 << 1)
 #define ADVOL_UNIXPRIV   (1 << 2) /* adouble unix priv */
@@ -235,33 +236,14 @@ struct adouble {
 #define ADLOCK_FILELOCK (1<<3)
 
 /* we use this so that we can use the same mechanism for both byte
- * locks and file synchronization locks. i do this by co-opting either
- * first bits on 32-bit machines or shifting above the last bit on
- * 64-bit machines. this only matters for the data fork. */
-#if defined(TRY_64BITOFF_T) && (~0UL > 0xFFFFFFFFU)
-/* synchronization locks */
-#define AD_FILELOCK_BASE (0x80000000)
-#else
+ * locks and file synchronization locks. */
 #if _FILE_OFFSET_BITS == 64
-#define AD_FILELOCK_BASE (0x7FFFFFFFFFFFFFFFULL - 9)
+#define AD_FILELOCK_BASE (UINT64_C(0x7FFFFFFFFFFFFFFF) - 9)
 #else
-#define AD_FILELOCK_BASE (0x7FFFFFFF -9)
-#endif
+#define AD_FILELOCK_BASE (UINT32_C(0x7FFFFFFF) - 9)
 #endif
 
-/* FIXME:
- * AD_FILELOCK_BASE case
- */
-#if _FILE_OFFSET_BITS == 64
-#define BYTELOCK_MAX (0x7FFFFFFFFFFFFFFFULL)
-#else
-/* Tru64 is an always-64-bit OS; version 4.0 does not set _FILE_OFFSET_BITS */
-#if defined(TRU64)
-#define BYTELOCK_MAX (0x7FFFFFFFFFFFFFFFULL)
-#else
-#define BYTELOCK_MAX (0x7FFFFFFFU)
-#endif
-#endif
+#define BYTELOCK_MAX (AD_FILELOCK_BASE - 1)
 
 #define AD_FILELOCK_OPEN_WR        (AD_FILELOCK_BASE + 0)
 #define AD_FILELOCK_OPEN_RD        (AD_FILELOCK_BASE + 1)
@@ -336,8 +318,8 @@ struct adouble {
 #define AD_AFPFILEI_BLANKACCESS (1 << 2) /* blank access permissions */
 
 #define ad_data_fileno(ad)  ((ad)->ad_data_fork.adf_fd)
-#define ad_reso_fileno(ad)  ((ad)->ad_resource_fork.adf_fd)
-#define ad_meta_fileno(ad)  ((ad)->ad_md->adf_fd)
+#define ad_reso_fileno(ad)  ((ad)->ad_rfp->adf_fd)
+#define ad_meta_fileno(ad)  ((ad)->ad_mdp->adf_fd)
 
 #define ad_getversion(ad)   ((ad)->ad_version)
 
@@ -346,8 +328,8 @@ struct adouble {
 #define ad_getentryoff(ad,eid)     ((ad)->ad_eid[(eid)].ade_off)
 #define ad_entry(ad,eid)           ((caddr_t)(ad)->ad_data + (ad)->ad_eid[(eid)].ade_off)
 
-#define ad_get_RF_flags(ad) ((ad)->ad_resource_fork.adf_flags)
-#define ad_get_MD_flags(ad) ((ad)->ad_md->adf_flags)
+#define ad_get_RF_flags(ad) ((ad)->ad_rfp->adf_flags)
+#define ad_get_MD_flags(ad) ((ad)->ad_mdp->adf_flags)
 
 /* Refcounting open forks using one struct adouble */
 #define ad_ref(ad)   (ad)->ad_refcount++
@@ -370,7 +352,6 @@ extern void ad_unlock(struct adouble *, int user);
 extern int ad_tmplock(struct adouble *, uint32_t eid, int type, off_t off, off_t len, int user);
 
 /* ad_open.c */
-extern const char *oflags2logstr(int oflags);
 extern const char *adflags2logstr(int adflags);
 extern int ad_setfuid     (const uid_t );
 extern uid_t ad_getfuid   (void );
@@ -387,13 +368,6 @@ extern int ad_stat        (const char *, struct stat *);
 extern int ad_metadata    (const char *, int, struct adouble *);
 extern int ad_metadataat  (int, const char *, int, struct adouble *);
 
-#if 0
-#define ad_open_metadata(name, flags, mode, adp)\
-   ad_open(name, ADFLAGS_HF | (flags), O_RDWR |(mode), 0666, (adp))
-#endif
-
-#define ad_close_metadata(adp) ad_close( (adp), ADFLAGS_HF)
-
 /* build a resource fork mode from the data fork mode:
  * remove X mode and extend header to RW if R or W (W if R for locking),
  */
@@ -453,10 +427,4 @@ extern uint32_t  ad_forcegetid(struct adouble *adp);
 extern int ad_readfile_init(const struct adouble *ad, int eid, off_t *off, int end);
 #endif
 
-#if 0
-#ifdef HAVE_SENDFILE_WRITE
-extern ssize_t ad_writefile(struct adouble *, int, int, off_t, int, size_t);
-#endif /* HAVE_SENDFILE_WRITE */
-#endif /* 0 */
-
 #endif /* _ATALK_ADOUBLE_H */
index 6579f0def001973d5e7742c3c382f2a1432812b4..e005577f026dd1fc661ef0ded2ef1aedc49bfdbf 100644 (file)
@@ -133,7 +133,7 @@ uint32_t ad_getid (struct adouble *adp, const dev_t st_dev, const ino_t st_ino ,
      */
     if (adp
         && (adp->ad_options & ADVOL_CACHE)
-        && (adp->ad_md->adf_flags & O_RDWR )
+        && (adp->ad_mdp->adf_flags & O_RDWR )
         && (sizeof(dev_t) == ad_getentrylen(adp, ADEID_PRIVDEV)) /* One check to ensure ALL values are there */
         ) {
         memcpy(&dev, ad_entry(adp, ADEID_PRIVDEV), sizeof(dev_t));
index ed9aa95deeb41675f4d66a9ff825668ea52f45cc..e1fd54ed54f256167bda6d167c331cf98c27a362 100644 (file)
@@ -148,7 +148,7 @@ int ad_flush(struct adouble *ad)
 {
     int len;
 
-    if (( ad->ad_md->adf_flags & O_RDWR )) {
+    if (( ad->ad_mdp->adf_flags & O_RDWR )) {
         if (ad_getentryoff(ad, ADEID_RFORK)) {
             if (ad->ad_rlen > 0xffffffff)
                 ad_setentrylen(ad, ADEID_RFORK, 0xffffffff);
@@ -159,14 +159,14 @@ int ad_flush(struct adouble *ad)
 
         switch (ad->ad_flags) {
         case AD_VERSION2:
-            if (adf_pwrite(ad->ad_md, ad->ad_data, len, 0) != len) {
+            if (adf_pwrite(ad->ad_mdp, ad->ad_data, len, 0) != len) {
                 if (errno == 0)
                     errno = EIO;
                 return( -1 );
             }
             break;
         case AD_VERSION_EA:
-            if (sys_lsetxattr(cfrombstr(ad->ad_fullpath), AD_EA_META, ad->ad_data, AD_DATASZ_EA, 0) != 0) {
+            if (sys_fsetxattr(ad_data_fileno(ad), AD_EA_META, ad->ad_data, AD_DATASZ_EA, 0) != 0) {
                 LOG(log_error, logtype_afpd, "ad_flush: sys_fsetxattr error: %s",
                     strerror(errno));
                 return -1;
@@ -183,27 +183,15 @@ int ad_flush(struct adouble *ad)
 
 /*!
  * Close a struct adouble freeing all resources
- *
- * This close the whole thing, regardless of what you pass in adflags!
- * When open forks are using this struct adouble (ad_refcount>0) the close
- * request is ignored.
  */
-int ad_close( struct adouble *ad, int adflags)
+int ad_close(struct adouble *ad, int adflags)
 {
     int err = 0;
 
     if (ad == NULL)
         return 0;
 
-    LOG(log_debug, logtype_default, "ad_close(\"%s\", %s)",
-        cfrombstr(ad->ad_fullpath),
-        adflags2logstr(adflags));
-
-    if (ad->ad_refcount) {
-        LOG(log_debug, logtype_default, "ad_close(\"%s\"): adouble in use by fork, not closing",
-            cfrombstr(ad->ad_fullpath));
-        return 0;
-    }
+    LOG(log_debug, logtype_default, "ad_close(%s)", adflags2logstr(adflags));
 
     if (ad_data_fileno(ad) != -1) {
         if ((ad_data_fileno(ad) == -2) && (ad->ad_data_fork.adf_syml != NULL)) {
@@ -222,7 +210,7 @@ int ad_close( struct adouble *ad, int adflags)
         if ( close( ad_meta_fileno(ad) ) < 0 )
             err = -1;
         ad_meta_fileno(ad) = -1;
-        adf_lock_free(ad->ad_md);
+        adf_lock_free(ad->ad_mdp);
         ad->ad_adflags &= ~ADFLAGS_HF;
     }
 
@@ -232,10 +220,5 @@ int ad_close( struct adouble *ad, int adflags)
         ad->ad_adflags &= ~ADFLAGS_RF;
     }
 
-    if (ad->ad_fullpath) {
-        bdestroy(ad->ad_fullpath);
-        ad->ad_fullpath = NULL;
-    }
-
     return err;
 }
index 38d2226eec845cb8b0f48d3dbfb6e787c489da9f..28d7bde82cb6b97ae97f7b1a333a838911d2feb0 100644 (file)
@@ -530,13 +530,6 @@ static void ad_fcntl_unlock(struct adouble *ad, const int fork)
   if (ad_reso_fileno(ad) != -1) {
     adf_unlock(&ad->ad_resource_fork, fork);
   }
-
-  if (ad->ad_flags != AD_VERSION_EA) {
-    return;
-  }
-  if (ad_meta_fileno(ad) != -1) {
-    adf_unlock(&ad->ad_metadata_fork, fork);
-  }
 }
 
 /******************************************************************************
index 8e7860d2a2c3c3e372ef2c305ba50f04064f352b..7552f241ada095cf71ed327aeb24bb1bc06173d0 100644 (file)
@@ -3,13 +3,25 @@
 
 #include <atalk/adouble.h>
 
-/* this is so that we can keep lists of fds referencing the same file
- * around. that way, we can honor locks created by the same process
+/* this is so that we can keep lists of fds referencing the same file                                                                                                                                                                                                         
+ * around. that way, we can honor locks created by the same process                                                                                                                                                                                                           
  * with the same file. */
 
-#define adf_lock_free(a)                                      \
-    do {                                                      \
-        ;                                                     \
+#define adf_lock_init(a) do { \
+        (a)->adf_lockmax = (a)->adf_lockcount = 0; \
+        (a)->adf_excl = 0;(a)->adf_lock = NULL; \
+    } while (0)
+
+#define adf_lock_free(a) do { \
+        int i;\
+        if (!(a)->adf_lock) \
+            break; \
+        for (i = 0; i < (a)->adf_lockcount; i++) {\
+            adf_lock_t *lock = (a)->adf_lock + i;\
+            if (--(*lock->refcount) < 1)free(lock->refcount); \
+        }\
+        free((a)->adf_lock); \
+        adf_lock_init(a); \
     } while (0)
 
 #endif /* libatalk/adouble/ad_private.h */
index ffb188eadf551cbdb574d9bc41ebe5535cf9aa8f..8a67960ab5963af49cd389ba916ad1d89e5fc2e4 100644 (file)
@@ -28,8 +28,6 @@
 /*!
  * @file
  * Part of Netatalk's AppleDouble implementatation
- * @note We don't use inlines because a good compiler should be
- *       able to optimize all the static funcs below.
  * @sa include/atalk/adouble.h
  */
 
@@ -51,6 +49,7 @@
 #include <atalk/bstrlib.h>
 #include <atalk/bstradd.h>
 #include <atalk/compat.h>
+#include <atalk/errchk.h>
 
 #include "ad_lock.h"
 
 #define MAX(a, b)  ((a) < (b) ? (b) : (a))
 #endif /* ! MAX */
 
-#ifdef  HAVE_PREAD
-# define AD_SET(a)
-#else
-# define AD_SET(a) a = 0
-#endif
-
 #define ADEDOFF_MAGIC        (0)
 #define ADEDOFF_VERSION      (ADEDOFF_MAGIC + ADEDLEN_MAGIC)
 #define ADEDOFF_FILLER       (ADEDOFF_VERSION + ADEDLEN_VERSION)
@@ -159,6 +152,50 @@ static const struct entry entry_order_ea[ADEID_NUM_EA + 1] = {
     {0, 0, 0}
 };
 
+const char *adflags2logstr(int adflags)
+{
+    int first = 1;
+    static char buf[64];
+
+    buf[0] = 0;
+
+    if (adflags & ADFLAGS_DF) {
+        strlcat(buf, "DF", 64);
+        first = 0;
+    }
+    if (adflags & ADFLAGS_RF) {
+        if (!first)
+            strlcat(buf, "|", 64);
+        strlcat(buf, "RF", 64);
+        first = 0;
+    }
+    if (adflags & ADFLAGS_HF) {
+        if (!first)
+            strlcat(buf, "|", 64);
+        strlcat(buf, "HF", 64);
+        first = 0;
+    }
+    if (adflags & ADFLAGS_NOHF) {
+        if (!first)
+            strlcat(buf, "|", 64);
+        strlcat(buf, "NOHF", 64);
+        first = 0;
+    }
+    if (adflags & ADFLAGS_DIR) {
+        if (!first)
+            strlcat(buf, "|", 64);
+        strlcat(buf, "DIR", 64);
+        first = 0;
+    }
+    if (adflags & ADFLAGS_CHECK_OF) {
+        if (!first)
+            strlcat(buf, "|", 64);
+        strlcat(buf, "OF", 64);
+        first = 0;
+    }
+    return buf;
+}
+
 static uint32_t get_eid(uint32_t eid)
 {
     if (eid <= 15)
@@ -282,7 +319,7 @@ static int ad_header_read(struct adouble *ad, struct stat *hst)
     struct stat         st;
 
     /* read the header */
-    if ((header_len = adf_pread( ad->ad_md, buf, sizeof(ad->ad_data), 0)) < 0) {
+    if ((header_len = adf_pread( ad->ad_mdp, buf, sizeof(ad->ad_data), 0)) < 0) {
         return -1;
     }
     if (header_len < AD_HEADER_LEN) {
@@ -338,7 +375,7 @@ static int ad_header_read(struct adouble *ad, struct stat *hst)
 
     if (hst == NULL) {
         hst = &st;
-        if (fstat(ad->ad_md->adf_fd, &st) < 0) {
+        if (fstat(ad->ad_mdp->adf_fd, &st) < 0) {
             return 1; /* fail silently */
         }
     }
@@ -356,7 +393,7 @@ static int ad_header_read_ea(struct adouble *ad, struct stat *hst _U_)
     char     *buf = ad->ad_data;
 
     /* read the header */
-    if ((header_len = sys_lgetxattr(cfrombstr(ad->ad_fullpath), AD_EA_META, ad->ad_data, AD_DATASZ_EA)) < 1) {
+    if ((header_len = sys_fgetxattr(ad_data_fileno(ad), AD_EA_META, ad->ad_data, AD_DATASZ_EA)) < 1) {
         LOG(log_debug, logtype_default, "ad_header_read_ea: %s (%u)", strerror(errno), errno);
         return -1;
     }
@@ -499,148 +536,170 @@ static int ad_error(struct adouble *ad, int adflags)
     return -1 ;
 }
 
-static int ad_open_df(const char *path, int adflags, int oflags, int mode, struct adouble *ad)
+/* Map ADFLAGS to open() flags */
+static int ad2openflags(int adflags)
+{
+    int oflags = 0;
+
+    if (adflags & ADFLAGS_RDWR)
+        oflags |= O_RDWR;
+    if (adflags & ADFLAGS_RDONLY)
+        oflags |= O_RDONLY;
+    if (adflags & ADFLAGS_CREATE)
+        oflags |= O_CREAT;
+    if (adflags & ADFLAGS_EXCL)
+        oflags |= O_EXCL;
+    if (adflags & ADFLAGS_TRUNC)
+        oflags |= O_TRUNC;
+
+    return oflags;
+}
+
+static int ad_open_df(const char *path, int adflags, mode_t mode, struct adouble *ad)
 {
     struct stat st_dir;
-    int         hoflags, admode;
+    int         oflags;
+    mode_t      admode;
     int         st_invalid = -1;
+    ssize_t     lsz;
 
     LOG(log_debug, logtype_default, "ad_open_df(\"%s\", %s, %04o)",
-        fullpathname(path), oflags2logstr(oflags), mode);
+        fullpathname(path), mode);
 
-    if (ad_data_fileno(ad) == -1) {
-        hoflags = (oflags & ~(O_RDONLY | O_WRONLY)) | O_RDWR;
-        admode = mode;
-        if ((oflags & O_CREAT)) {
-            st_invalid = ad_mode_st(path, &admode, &st_dir);
-            if ((ad->ad_options & ADVOL_UNIXPRIV)) {
-                admode = mode;
+
+    if (ad_data_fileno(ad) != -1) {
+        /* the file is already open, but we want write access: */
+        if ((adflags & ADFLAGS_RDWR)
+            /* and it was denied the first time: */
+            && (ad->ad_data_fork.adf_flags & O_RDONLY)) {
+                errno = EACCES;
+                return -1;
             }
-        }
+        /* it's not new anymore */
+        ad->ad_mdp->adf_flags &= ~( O_TRUNC | O_CREAT );
+        ad->ad_data_fork.adf_refcount++;
+        return 0;
+    }
 
-        ad->ad_data_fork.adf_fd = open(path, hoflags | O_NOFOLLOW, admode);
+    oflags = O_NOFOLLOW | ad2openflags(adflags);
 
-        if (ad->ad_data_fork.adf_fd == -1) {
-            if ((errno == EACCES || errno == EROFS) && !(oflags & O_RDWR)) {
-                hoflags = oflags;
-                ad->ad_data_fork.adf_fd = open( path, hoflags | O_NOFOLLOW, admode );
-            }
-            if (ad->ad_data_fork.adf_fd == -1 && errno == OPEN_NOFOLLOW_ERRNO) {
-                int lsz;
-
-                ad->ad_data_fork.adf_syml = malloc(MAXPATHLEN+1);
-                lsz = readlink(path, ad->ad_data_fork.adf_syml, MAXPATHLEN);
-                if (lsz <= 0) {
-                    free(ad->ad_data_fork.adf_syml);
-                    return -1;
-                }
-                ad->ad_data_fork.adf_syml[lsz] = 0;
-                ad->ad_data_fork.adf_fd = -2; /* -2 means its a symlink */
-            }
-        }
+    admode = mode;
+    if ((adflags & ADFLAGS_CREATE)) {
+        st_invalid = ad_mode_st(path, &admode, &st_dir);
+        if ((ad->ad_options & ADVOL_UNIXPRIV))
+            admode = mode;
+    }
 
-        if ( ad->ad_data_fork.adf_fd == -1 )
+    ad->ad_data_fork.adf_fd = open(path, oflags, admode);
+
+    if (ad->ad_data_fork.adf_fd == -1) {
+        if (errno != OPEN_NOFOLLOW_ERRNO)
             return -1;
 
-        AD_SET(ad->ad_data_fork.adf_off);
-        ad->ad_data_fork.adf_flags = hoflags;
-        if (!st_invalid) {
-            /* just created, set owner if admin (root) */
-            ad_chown(path, &st_dir);
-        }
-    } else {
-        /* the file is already open... but */
-        if ((oflags & ( O_RDWR | O_WRONLY))
-            /* we want write access */
-            && !(ad->ad_data_fork.adf_flags & ( O_RDWR | O_WRONLY))) {
-            /* and it was denied the first time */
-            errno = EACCES;
+        ad->ad_data_fork.adf_syml = malloc(MAXPATHLEN+1);
+        if ((lsz = readlink(path, ad->ad_data_fork.adf_syml, MAXPATHLEN)) <= 0) {
+            free(ad->ad_data_fork.adf_syml);
             return -1;
         }
-        /* FIXME
-         * for now ad_open is never called with O_TRUNC or O_EXCL if the file is
-         * already open. Should we check for it? ie
-         * O_EXCL --> error
-         * O_TRUNC --> truncate the fork.
-         * idem for ressource fork.
-         */
+        ad->ad_data_fork.adf_syml[lsz] = 0;
+        ad->ad_data_fork.adf_fd = -2; /* -2 means its a symlink */
     }
 
+    if (!st_invalid)
+        ad_chown(path, &st_dir); /* just created, set owner if admin (root) */
+
+    ad->ad_data_fork.adf_flags = oflags;
+    adf_lock_init(&ad->ad_data_fork);
+    ad->ad_data_fork.adf_refcount++;
+
     return 0;
 }
 
-static int ad_open_hf_v2(const char *path, int adflags, int oflags, int mode, struct adouble *ad)
+static int ad_open_hf_v2(const char *path, int adflags, mode_t mode, struct adouble *ad)
 {
     struct stat st_dir;
     struct stat st_meta;
     struct stat *pst = NULL;
     const char  *ad_p;
-    int         hoflags, admode;
+    int         oflags, nocreatflags;
+    mode_t      admode;
     int         st_invalid = -1;
 
-    ad_p = ad->ad_ops->ad_path( path, adflags );
-
-    hoflags = (oflags & ~(O_CREAT | O_EXCL)) | O_NOFOLLOW;
+    if (ad_meta_fileno(ad) != -1) {
+        /* the file is already open, but we want write access: */
+        if (!(adflags & ADFLAGS_RDONLY) &&
+            /* and it was already denied: */
+            !(ad->ad_mdp->adf_flags & O_RDWR)) {
+            errno = EACCES;
+            return -1;
+        }
+        ad_refresh(ad);
+        /* it's not new anymore */
+        ad->ad_mdp->adf_flags &= ~( O_TRUNC | O_CREAT );
+        ad->ad_mdp->adf_refcount++;
+        return 0;
+    }
 
-    ad->ad_md->adf_fd = open(ad_p, hoflags, 0);
+    ad_p = ad->ad_ops->ad_path(path, adflags);
+    oflags = O_NOFOLLOW | ad2openflags(adflags);
+    nocreatflags = oflags & ~(O_CREAT | O_EXCL);
+    ad->ad_mdp->adf_fd = open(ad_p, nocreatflags);
 
-    if ( ad->ad_md->adf_fd < 0 ) {
-        if (errno == ENOENT && (oflags & O_CREAT) ) {
-            /*
-             * We're expecting to create a new adouble header file here
-             * if ((oflags & O_CREAT) ==> (oflags & O_RDWR)
-             */
-            LOG(log_debug, logtype_default, "ad_open(\"%s\"): creating adouble file",
-                fullpathname(path));
+    if ( ad->ad_mdp->adf_fd < 0 ) {
+        if (!(errno == ENOENT && (oflags & O_CREAT)))
+            return ad_error(ad, adflags);
+        /*
+         * We're expecting to create a new adouble header file here
+         * if ((oflags & O_CREAT) ==> (oflags & O_RDWR)
+         */
+        LOG(log_debug, logtype_default, "ad_open(\"%s\"): creating adouble file",
+            fullpathname(path));
+        admode = mode;
+        errno = 0;
+        st_invalid = ad_mode_st(ad_p, &admode, &st_dir);
+        if ((ad->ad_options & ADVOL_UNIXPRIV))
+            admode = mode;
+        admode = ad_hf_mode(admode);
+        if (errno == ENOENT) {
+            if (ad->ad_ops->ad_mkrf( ad_p) < 0) {
+                return ad_error(ad, adflags);
+            }
             admode = mode;
-            errno = 0;
             st_invalid = ad_mode_st(ad_p, &admode, &st_dir);
-            if ((ad->ad_options & ADVOL_UNIXPRIV)) {
+            if ((ad->ad_options & ADVOL_UNIXPRIV))
                 admode = mode;
-            }
             admode = ad_hf_mode(admode);
-            if ((errno == ENOENT)) {
-                if (ad->ad_ops->ad_mkrf( ad_p) < 0) {
-                    return ad_error(ad, adflags);
-                }
-                admode = mode;
-                st_invalid = ad_mode_st(ad_p, &admode, &st_dir);
-                if ((ad->ad_options & ADVOL_UNIXPRIV)) {
-                    admode = mode;
-                }
-                admode = ad_hf_mode(admode);
-            }
-            /* retry with O_CREAT */
-            ad->ad_md->adf_fd = open(ad_p, oflags, admode);
-            if ( ad->ad_md->adf_fd < 0 ) {
-                return ad_error(ad, adflags);
-            }
-            ad->ad_md->adf_flags = oflags;
-            /* just created, set owner if admin owner (root) */
-            if (!st_invalid) {
-                ad_chown(ad_p, &st_dir);
-            }
-        } else {
-            return ad_error(ad, adflags);
         }
+
+        /* retry with O_CREAT */
+        ad->ad_mdp->adf_fd = open(ad_p, oflags, admode);
+        if ( ad->ad_mdp->adf_fd < 0 )
+            return ad_error(ad, adflags);
+
+        ad->ad_mdp->adf_flags = oflags;
+        /* just created, set owner if admin owner (root) */
+        if (!st_invalid)
+            ad_chown(ad_p, &st_dir);
     } else {
-        ad->ad_md->adf_flags = hoflags;
-        if (fstat(ad->ad_md->adf_fd, &st_meta) == 0 && st_meta.st_size == 0) {
+        ad->ad_mdp->adf_flags = nocreatflags;
+        if (fstat(ad->ad_mdp->adf_fd, &st_meta) == 0 && st_meta.st_size == 0) {
             /* for 0 length files, treat them as new. */
-            ad->ad_md->adf_flags |= O_TRUNC;
+            ad->ad_mdp->adf_flags |= O_TRUNC;
         } else {
             /* we have valid data in st_meta stat structure, reused it in ad_header_read */
             pst = &st_meta;
         }
     }
 
-    AD_SET(ad->ad_md->adf_off);
+    ad->ad_mdp->adf_refcount = 1;
+    adf_lock_init(ad->ad_mdp);
 
-    if ((ad->ad_md->adf_flags & ( O_TRUNC | O_CREAT ))) {
+    if ((ad->ad_mdp->adf_flags & ( O_TRUNC | O_CREAT ))) {
         /* This is a new adouble header file, create it */
         if (new_ad_header(path, ad, adflags) < 0) {
             int err = errno;
             /* the file is already deleted, perm, whatever, so return an error */
+            ad_close(ad, adflags);
             errno = err;
             return -1;
         }
@@ -650,6 +709,7 @@ static int ad_open_hf_v2(const char *path, int adflags, int oflags, int mode, st
         if (ad->ad_ops->ad_header_read( ad , pst) < 0
             || ad->ad_ops->ad_header_upgrade(ad, ad_p) < 0) {
             int err = errno;
+            ad_close(ad, adflags);
             errno = err;
             return -1;
         }
@@ -658,21 +718,28 @@ static int ad_open_hf_v2(const char *path, int adflags, int oflags, int mode, st
     return 0;
 }
 
-static int ad_open_hf_ea(const char *path, int adflags, int oflags, int mode, struct adouble *ad)
+static int ad_open_hf_ea(const char *path, int adflags, int mode, struct adouble *ad)
 {
     ssize_t rforklen;
+    int oflags = O_NOFOLLOW;
+
+    oflags = ad2openflags(adflags) & ~(O_CREAT | O_TRUNC);
 
-    /* we dont use this fd, but open it anyway, maybe we need it sometimes */
-    if ((ad->ad_md->adf_fd = open(path, O_RDONLY | O_NOFOLLOW)) == -1)
-        goto error;
+    if (ad_meta_fileno(ad) == -1) {
+        if ((ad_meta_fileno(ad) = open(path, oflags)) == -1)
+            goto error;
+        ad->ad_mdp->adf_flags = oflags;
+        ad->ad_mdp->adf_refcount = 1;
+        adf_lock_init(ad->ad_mdp);
+    }
 
     /* Read the adouble header in and parse it.*/
     if (ad->ad_ops->ad_header_read(ad, NULL) != 0) {
-        if (!(oflags & O_CREAT))
+        if (!(adflags & ADFLAGS_CREATE))
             goto error;
 
         /* It doesnt exist, EPERM or another error */
-        if (errno != ENOATTR && errno != ENOENT) {
+        if (!(errno == ENOATTR || errno == ENOENT)) {
             LOG(log_error, logtype_default, "ad_open_hf_ea: unexpected: %s", strerror(errno));
             goto error;
         }
@@ -683,43 +750,41 @@ static int ad_open_hf_ea(const char *path, int adflags, int oflags, int mode, st
                 fullpathname(path));
             goto error;
         }
-        ad->ad_md->adf_flags |= O_CREAT; /* mark as just created */
+        ad->ad_mdp->adf_flags |= O_CREAT; /* mark as just created */
         ad_flush(ad);
-        LOG(log_debug, logtype_default, "ad_open_hf_ea(\"%s\"): created metadata EA",
-            cfrombstr(ad->ad_fullpath));
+        LOG(log_debug, logtype_default, "ad_open_hf_ea(\"%s\"): created metadata EA", path);
     }
 
-    ad->ad_md->adf_flags |= oflags & (O_RDONLY|O_WRONLY|O_RDWR); /* store current flags */
+    ad->ad_mdp->adf_refcount++;
 
-    if ((rforklen = sys_lgetxattr(cfrombstr(ad->ad_fullpath), AD_EA_RESO, NULL, 0)) > 0)
+    if ((rforklen = sys_fgetxattr(ad_meta_fileno(ad), AD_EA_RESO, NULL, 0)) > 0)
         ad->ad_rlen = rforklen;
 
     return 0;
 
 error:
-    if (ad->ad_md->adf_fd != -1) {
-        close(ad->ad_md->adf_fd);
-        ad->ad_md->adf_fd = -1;
+    if (ad_meta_fileno(ad) != -1) {
+        close(ad_meta_fileno(ad));
+        ad_meta_fileno(ad) = -1;
     }
     return ad_error(ad, adflags);
 }
 
-static int ad_open_hf(const char *path, int adflags, int oflags, int mode, struct adouble *ad)
+static int ad_open_hf(const char *path, int adflags, int mode, struct adouble *ad)
 {
     int ret = 0;
 
-    LOG(log_debug, logtype_default, "ad_open_hf(\"%s\", %s, %04o)",
-        cfrombstr(ad->ad_fullpath), oflags2logstr(oflags), mode);
+    LOG(log_debug, logtype_default, "ad_open_hf(\"%s\", %04o)", path, mode);
 
     memset(ad->ad_eid, 0, sizeof( ad->ad_eid ));
     ad->ad_rlen = 0;
 
     switch (ad->ad_flags) {
     case AD_VERSION2:
-        ret = ad_open_hf_v2(path, adflags, oflags, mode, ad);
+        ret = ad_open_hf_v2(path, adflags, mode, ad);
         break;
     case AD_VERSION_EA:
-        ret = ad_open_hf_ea(path, adflags, oflags, mode, ad);
+        ret = ad_open_hf_ea(path, adflags, mode, ad);
         break;
     default:
         ret = -1;
@@ -735,17 +800,17 @@ static int ad_open_hf(const char *path, int adflags, int oflags, int mode, struc
  * Only for adouble:ea, a nullop otherwise because adouble:v2 has the ressource fork as part
  * of the adouble file which is openend by ADFLAGS_HF.
  */
-static int ad_open_rf(const char *path, int adflags, int oflags, int mode, struct adouble *ad)
+static int ad_open_rf(const char *path, int adflags, int mode, struct adouble *ad)
 {
     int ret = 0;
 
     if (ad->ad_flags != AD_VERSION_EA)
         return 0;
 
-    LOG(log_debug, logtype_default, "ad_open_rf(\"%s\", %s, %04o)",
-        cfrombstr(ad->ad_fullpath), oflags2logstr(oflags), mode);
+    LOG(log_debug, logtype_default, "ad_open_rf(\"%s\", %04o)",
+        path, mode);
 
-    if ((ad->ad_rlen = sys_lgetxattr(cfrombstr(ad->ad_fullpath), AD_EA_RESO, NULL, 0)) <= 0) {
+    if ((ad->ad_rlen = sys_fgetxattr(ad_meta_fileno(ad), AD_EA_RESO, NULL, 0)) <= 0) {
         switch (errno) {
         case ENOATTR:
             ad->ad_rlen = 0;
@@ -769,7 +834,7 @@ static int ad_open_rf(const char *path, int adflags, int oflags, int mode, struc
 
     /* Read the EA into the buffer */
     if (ad->ad_rlen > 0) {
-        if (sys_lgetxattr(cfrombstr(ad->ad_fullpath), AD_EA_RESO, ad->ad_resforkbuf, ad->ad_rlen) == -1) {
+        if (sys_fgetxattr(ad_meta_fileno(ad), AD_EA_RESO, ad->ad_resforkbuf, ad->ad_rlen) == -1) {
             ret = -1;
             goto exit;
         }       
@@ -946,16 +1011,18 @@ int ad_mkdir( const char *path, int mode)
 
 void ad_init(struct adouble *ad, int flags, int options)
 {
-    memset(ad, 0, sizeof(struct adouble));
-
-    if (flags == AD_VERSION2) {
+    switch (flags) {
+    case AD_VERSION2:
         ad->ad_ops = &ad_adouble;
-        ad->ad_md = &ad->ad_resource_fork;
-    }
-    else if (flags == AD_VERSION_EA) {
+        ad->ad_rfp = &ad->ad_resource_fork;
+        ad->ad_mdp = &ad->ad_resource_fork;
+        break;
+    case AD_VERSION_EA:
         ad->ad_ops = &ad_adouble_ea;
-        ad->ad_md = &ad->ad_metadata_fork;
-    } else {
+        ad->ad_rfp = &ad->ad_data_fork;
+        ad->ad_mdp = &ad->ad_data_fork;
+        break;
+    default:
         LOG(log_error, logtype_default, "ad_init: unknown AD version");
         errno = EIO;
         return;
@@ -966,88 +1033,22 @@ void ad_init(struct adouble *ad, int flags, int options)
     ad_data_fileno(ad) = -1;
     ad_reso_fileno(ad) = -1;
     ad_meta_fileno(ad) = -1;
-    ad->ad_inited = AD_INITED;
-}
-
-const char *adflags2logstr(int adflags)
-{
-    int first = 1;
-    static char buf[64];
-
-    buf[0] = 0;
-
-    if (adflags & ADFLAGS_DF) {
-        strlcat(buf, "DF", 64);
-        first = 0;
-    }
-    if (adflags & ADFLAGS_RF) {
-        if (!first)
-            strlcat(buf, "|", 64);
-        strlcat(buf, "RF", 64);
-        first = 0;
-    }
-    if (adflags & ADFLAGS_HF) {
-        if (!first)
-            strlcat(buf, "|", 64);
-        strlcat(buf, "HF", 64);
-        first = 0;
-    }
-    if (adflags & ADFLAGS_NOHF) {
-        if (!first)
-            strlcat(buf, "|", 64);
-        strlcat(buf, "NOHF", 64);
-        first = 0;
-    }
-    if (adflags & ADFLAGS_DIR) {
-        if (!first)
-            strlcat(buf, "|", 64);
-        strlcat(buf, "DIR", 64);
-        first = 0;
-    }
-    if (adflags & ADFLAGS_CHECK_OF) {
-        if (!first)
-            strlcat(buf, "|", 64);
-        strlcat(buf, "OF", 64);
-        first = 0;
-    }
-    return buf;
-}
-
-const char *oflags2logstr(int oflags)
-{
-    int first = 1;
-    static char buf[64];
-
-    buf[0] = 0;
-
-    if (oflags == O_RDONLY) {
-        strlcat(buf, "O_RDONLY", 64);
-        first = 0;
-    }
-    if (oflags & O_RDWR) {
-        if (!first)
-            strlcat(buf, "|", 64);
-        strlcat(buf, "O_RDWR", 64);
-        first = 0;
-    }
-    if (oflags & O_CREAT) {
-        if (!first)
-            strlcat(buf, "|", 64);
-        strlcat(buf, "O_CREAT", 64);
-        first = 0;
-    }
-    if (oflags & O_EXCL) {
-        if (!first)
-            strlcat(buf, "|", 64);
-        strlcat(buf, "O_EXCL", 64);
-        first = 0;
-    }
-    return buf;
+    memset(ad->ad_eid, 0, sizeof( ad->ad_eid ));
+    ad->ad_rlen = 0;
+    ad->ad_refcount = 1;
+    ad->ad_open_forks = 0;
+    ad->ad_resource_fork.adf_refcount = 0;
+    ad->ad_data_fork.adf_refcount = 0;
+    ad->ad_data_fork.adf_syml=0;
+    ad->ad_inited = 0;
 }
 
 /*!
  * Open data-, metadata(header)- or ressource fork
  *
+ * ad_open(struct adouble *ad, const char *path, int adflags, int flags)
+ * ad_open(struct adouble *ad, const char *path, int adflags, int flags, mode_t mode)
+ *
  * You must call ad_init() before ad_open, usually you'll just call it like this: \n
  * @code
  *      struct adoube ad;
@@ -1056,22 +1057,6 @@ const char *oflags2logstr(int oflags)
  *
  * Open a files data fork, metadata fork or ressource fork.
  *
- * For each fork to be opened specify the open flags and mode in case you want to create it
- * (O_CREAT in open flags). The order in which forks are opened is:
- * 1) ADFLAGS_DF, 2) ADFLAGS_HF, 3) ADFLAGS_RF.
- * It is possible to call ad_open subsequently opening ADFLAGS_DF first and ADFLAGS_HF in
- * another ad_open call. Already openend forks are uneffected in subsequent calls (3).
- * The variable arguments must be passed according to this order. Then:
- * 1. Ensure the adouble struct has been initialized.
- * 2. Store the full path to the object the first time ad_open is called for it.
- * 3. Check if the fork has already been opened.
- *
- * ad_close accompanies ad_open and closes a struct adouble. In order to tigh together the
- * semantics of struct adouble/ad_open/ad_close and versus forks, which use and keep a ref to
- * the according struct adouble for the fork, open forks refcount their struct adouble
- * in struct adouble.ad_refcount. An ad_close is ignored when ad_refcount != 0, because
- * ad_refcount != 0 means an open fork is using this very struct adouble.
- *
  * @param ad        (rw) pointer to struct adouble
  * @param path      (r)  Path to file or directory
  * @param adflags   (r)  ADFLAGS_DF:        open data fork \n
@@ -1079,85 +1064,53 @@ const char *oflags2logstr(int oflags)
  *                       ADFLAGS_HF:        open header (metadata) file \n
  *                       ADFLAGS_NOHF:      it's not an error if header file couldn't be created \n
  *                       ADFLAGS_DIR:       if path is a directory you MUST or ADFLAGS_DIR to adflags \n
- *                       ADFLAGS_RDONLY:    dont upgrade mode from r to rw with adouble:v2 headerfile \n
+ * The open mode flags (rw vs ro) have to take into account all the following requirements:
+ * - we remember open fds for files because me must avoid a single close releasing fcntl locks for other
+ *   fds of the same file
+ * - a file may be opened first ro, then rw and theres no way to upgrade this -> fork.c always opens rw
  *                       ADFLAGS_CHECK_OF:  check for open forks from us and other afpd's
+ * @param mode      (r)  mode used with O_CREATE
  *
  * @returns 0 on success, any other value indicates an error
  */
-static int vad_open(struct adouble *ad, const char *path, int adflags, va_list args)
+int ad_open(struct adouble *ad, const char *path, int adflags, ...)
 {
-    int ret = 0;
-    int oflags;
-    int mode = 0;
-    
-    LOG(log_debug, logtype_default, "ad_open(\"%s\", %s)",
-        fullpathname(path), adflags2logstr(adflags));
+    EC_INIT;
+    va_list args;
+    mode_t mode = 0;
 
-    if (ad->ad_inited != AD_INITED) /* 1 */
-        AFP_PANIC("ad_open: not initialized");
+    LOG(log_debug, logtype_default, "ad_open(\"%s\", %s, %s)",
+        fullpathname(path), adflags2logstr(adflags));
 
-    if (ad->ad_fullpath == NULL) { /* 2 */
-        if ((ad->ad_fullpath = bfromcstr(fullpathname(path))) == NULL) {
-            ret = -1;
-            goto exit;
-        }
+    if (ad->ad_inited != AD_INITED) {
+        ad->ad_adflags = adflags;
+    } else {
+        ad->ad_open_forks = ((ad->ad_data_fork.adf_refcount > 0) ? ATTRBIT_DOPEN : 0);
+        if (ad->ad_resource_fork.adf_refcount > 0)
+            ad->ad_open_forks |= ATTRBIT_ROPEN;
     }
 
+    va_start(args, adflags);
+    if (adflags & ADFLAGS_CREATE)
+        mode = va_arg(args, mode_t);
+    va_end(args);
+
     if ((adflags & ADFLAGS_DF) && !(ad->ad_adflags & ADFLAGS_DF)) { /* 3 */
-        oflags = va_arg(args, int);
-        if (oflags & O_CREAT)
-            mode = va_arg(args, int);
-        if (ad_open_df(path, adflags, oflags, mode, ad) != 0) {
-            ret = -1;
-            goto exit;
-        }
+        EC_ZERO( ad_open_df(path, adflags, mode, ad) );
         ad->ad_adflags |= ADFLAGS_DF;
     }
 
     if ((adflags & ADFLAGS_HF) && !(ad->ad_adflags & ADFLAGS_HF)) { /* 3 */
-        oflags = va_arg(args, int);
-        if (oflags & O_CREAT)
-            mode = va_arg(args, int);
-        if (ad_open_hf(path, adflags, oflags, mode, ad) != 0) {
-            ret = -1;
-            goto exit;
-        }
+        EC_ZERO( ad_open_hf(path, adflags, mode, ad) );
         ad->ad_adflags |= ADFLAGS_HF;
     }
 
     if ((adflags & ADFLAGS_RF) && !(ad->ad_adflags & ADFLAGS_RF)) { /* 3 */
-        oflags = va_arg(args, int);
-        if (oflags & O_CREAT)
-            mode = va_arg(args, int);
-        if (ad_open_rf(path, adflags, oflags, mode, ad) != 0) {
-            ret = -1;
-            goto exit;
-        }
+        EC_ZERO( ad_open_rf(path, adflags, mode, ad) );
         ad->ad_adflags |= ADFLAGS_RF;
     }
 
-exit:
-    if (ret != 0) {
-        /* FIXME: ad_close stuff we opened before hitting an error */
-        /* Dont forget ADFLAGS_NOHF !!! */
-
-        if (ad->ad_fullpath) {
-            bdestroy(ad->ad_fullpath);
-            ad->ad_fullpath = NULL;
-        }
-    }
-
-    return ret;
-}
-
-int ad_open(struct adouble *ad, const char *path, int adflags, ...)
-{
-    int ret;
-    va_list args;
-
-    va_start(args, adflags);
-    ret = vad_open(ad, path, adflags, args);
-    va_end(args);
+EC_CLEANUP:
     return ret;
 }
 
@@ -1175,11 +1128,12 @@ int ad_open(struct adouble *ad, const char *path, int adflags, ...)
 int ad_metadata(const char *name, int flags, struct adouble *adp)
 {
     uid_t uid;
-    int   ret, err, dir;
+    int   ret, err, oflags;
 
-    dir = flags & ADFLAGS_DIR;
+    oflags = (flags & ADFLAGS_DIR) | ADFLAGS_HF | ADFLAGS_RDONLY;
 
-    if ((ret = ad_open(adp, name, ADFLAGS_HF | dir, O_RDONLY)) < 0 && errno == EACCES) {
+//    if ((ret = ad_open(adp, name, oflags)) < 0 && errno == EACCES) {
+    if ((ret = ad_open(adp, name, oflags, 0)) < 0 && errno == EACCES) {
         uid = geteuid();
         if (seteuid(0)) {
             LOG(log_error, logtype_default, "ad_metadata(%s): seteuid failed %s", name, strerror(errno));
@@ -1187,7 +1141,8 @@ int ad_metadata(const char *name, int flags, struct adouble *adp)
             return -1;
         }
         /* we are root open read only */
-        ret = ad_open(adp, name, ADFLAGS_HF | dir, O_RDONLY);
+//        ret = ad_open(adp, name, oflags);
+        ret = ad_open(adp, name, oflags, 0);
         err = errno;
         if ( seteuid(uid) < 0) {
             LOG(log_error, logtype_default, "ad_metadata: can't seteuid back");
@@ -1196,7 +1151,7 @@ int ad_metadata(const char *name, int flags, struct adouble *adp)
         errno = err;
     }
 
-    if (!ret && (ADFLAGS_CHECK_OF & flags)) {
+    if ((ret == 0) && (ADFLAGS_CHECK_OF & flags)) {
         /*
           we need to check if the file is open by another process.
           it's slow so we only do it if we have to:
@@ -1257,33 +1212,30 @@ int ad_openat(struct adouble  *ad,
               const char *path,
               int adflags, ...)
 {
-    int ret = 0;
+    EC_INIT;
     int cwdfd = -1;
     va_list args;
+    mode_t mode;
 
     if (dirfd != -1) {
-        if ((cwdfd = open(".", O_RDONLY) == -1) || (fchdir(dirfd) != 0)) {
-            ret = -1;
-            goto exit;
-        }
+        if ((cwdfd = open(".", O_RDONLY) == -1) || (fchdir(dirfd) != 0))
+            EC_FAIL;
     }
 
     va_start(args, adflags);
-
-    if (vad_open(ad, path, adflags, args) < 0) {
-        ret = -1;
-        goto exit;
-    }
-
+    if (adflags & ADFLAGS_CREATE)
+        mode = va_arg(args, mode_t);
     va_end(args);
 
+    EC_NEG1( ad_open(ad, path, adflags, mode) );
+
     if (dirfd != -1) {
         if (fchdir(cwdfd) != 0) {
             AFP_PANIC("ad_openat: cant chdir back");
         }
     }
 
-exit:
+EC_CLEANUP:
     if (cwdfd != -1)
         close(cwdfd);
 
index 65e3ca2d76005d4e3d6fbc5f91bb2c7427504ab2..b316fa89dc84b5d970250c58a278d4c23e4e73c3 100644 (file)
@@ -94,7 +94,7 @@ ssize_t ad_write(struct adouble *ad, uint32_t eid, off_t off, int end, const cha
             if ((off + buflen) > ad->ad_rlen)
                 ad->ad_rlen = off + buflen;
             
-            if (sys_lsetxattr(cfrombstr(ad->ad_fullpath), AD_EA_RESO, ad->ad_resforkbuf, ad->ad_rlen, 0) == -1)
+            if (sys_fsetxattr(ad_meta_fileno(ad), AD_EA_RESO, ad->ad_resforkbuf, ad->ad_rlen, 0) == -1)
                 return -1;
             cc = buflen;
         }
index 9f369ea4fb3506036ba204d10080a5d26a016474..7394e84c9de6abe18af824ed6ccf374a3809bf81 100644 (file)
@@ -1398,7 +1398,7 @@ int ea_renamefile(VFS_FUNC_ARGS_RENAMEFILE)
         if (errno == ENOENT) {
             /* Possibly the .AppleDouble folder didn't exist, we create it and try again */
             ad_init(&ad, vol->v_adouble, vol->v_ad_options); 
-            if ((ad_open(&ad, dst, ADFLAGS_HF, O_RDWR | O_CREAT, 0666)) != 0) {
+            if ((ad_open(&ad, dst, ADFLAGS_HF | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666)) != 0) {
                 LOG(log_error, logtype_afpd, "ea_renamefile('%s/%s'): ad_open error: '%s'", src, dst, dst);
                 ret = AFPERR_MISC;
                 goto exit;
@@ -1495,7 +1495,7 @@ int ea_copyfile(VFS_FUNC_ARGS_COPYFILE)
         if (errno == ENOENT) {
             /* Possibly the .AppleDouble folder didn't exist, we create it and try again */
             ad_init(&ad, vol->v_adouble, vol->v_ad_options); 
-            if ((ad_open(&ad, dst, ADFLAGS_HF, O_RDWR | O_CREAT, 0666)) != 0) {
+            if ((ad_open(&ad, dst, ADFLAGS_HF | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666)) != 0) {
                 LOG(log_error, logtype_afpd, "ea_copyfile('%s/%s'): ad_open error: '%s'", src, dst, dst);
                 ret = AFPERR_MISC;
                 goto exit;
index 0eaacfaee8af8fc5f6babb34709d2e7f7c8022f9..ca37885d01ec51145b2daa59d124470f532522ae 100644 (file)
@@ -309,7 +309,7 @@ static int RF_renamefile_adouble(VFS_FUNC_ARGS_RENAMEFILE)
              * use a diff one, it's not a pb,ie it's not the same file, yet.
              */
             ad_init(&ad, vol->v_adouble, vol->v_ad_options); 
-            if (ad_open(&ad, dst, ADFLAGS_HF, O_RDWR | O_CREAT, 0666) == 0) {
+            if (ad_open(&ad, dst, ADFLAGS_HF | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666) == 0) {
                ad_close(&ad, ADFLAGS_HF);
                if (!unix_rename(dirfd, adsrc, -1, vol->ad_path(dst, 0 )) ) 
                    err = 0;