#include <atalk/bstrlib.h>
#include <atalk/bstradd.h>
#include <atalk/errchk.h>
+#include <atalk/util.h>
#include "ad_lock.h"
char *buf, *nentp;
int len;
+ LOG(log_debug, logtype_default, "ad_rebuild_adouble_header");
+
buf = ad->ad_data;
temp = htonl( ad->ad_magic );
static int ad_flush_hf(struct adouble *ad)
{
+ EC_INIT;
int len;
+ int cwd = -1;
LOG(log_debug, logtype_default, "ad_flush_hf(%s)", adflags2logstr(ad->ad_adflags));
return -1;
}
- if ((adf->adf_flags & O_RDWR)) {
+ if ((adf->adf_flags & O_RDWR)
+ || ((ad->ad_adflags & ADFLAGS_DIR) && (ad->ad_adflags & ADFLAGS_RDWR))) {
if (ad_getentryoff(ad, ADEID_RFORK)) {
if (ad->ad_rlen > 0xffffffff)
ad_setentrylen(ad, ADEID_RFORK, 0xffffffff);
break;
case AD_VERSION_EA:
if (AD_META_OPEN(ad)) {
- 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;
+ if (ad->ad_adflags & ADFLAGS_DIR) {
+ EC_NEG1_LOG( cwd = open(".", O_RDONLY) );
+ EC_NEG1_LOG( fchdir(ad_data_fileno(ad)) );
+ EC_ZERO_LOG( sys_lsetxattr(".", AD_EA_META, ad->ad_data, AD_DATASZ_EA, 0) );
+ EC_NEG1_LOG( fchdir(cwd) );
+ EC_NEG1_LOG( close(cwd) );
+ cwd = -1;
+ } else {
+ EC_ZERO_LOG( sys_fsetxattr(ad_data_fileno(ad), AD_EA_META, ad->ad_data, AD_DATASZ_EA, 0) );
}
}
break;
}
}
- return( 0 );
+EC_CLEANUP:
+ if (cwd != -1) {
+ if (fchdir(cwd) != 0) {
+ AFP_PANIC("ad_flush: cant fchdir");
+ }
+ close(cwd);
+ }
+ EC_EXIT;
}
/* Flush resofork adouble file if any (currently adouble:ea and #ifndef HAVE_EAFD eg Linux) */
if (ad == NULL)
return err;
- LOG(log_debug, logtype_default, "ad_close(%s)", adflags2logstr(adflags));
+ LOG(log_debug, logtype_default,
+ "ad_close(%s): BEGIN [dfd: %d (ref: %d), mfd: %d (ref: %d), rfd: %d (ref: %d)]",
+ adflags2logstr(adflags),
+ ad_data_fileno(ad), ad->ad_data_fork.adf_refcount,
+ ad_meta_fileno(ad), ad->ad_mdp->adf_refcount,
+ ad_reso_fileno(ad), ad->ad_rfp->adf_refcount);
- /* cf ad_open(): we opened the datafork too for sharemode locks */
- if ((ad->ad_vers == AD_VERSION_EA) && (ad->ad_adflags & ADFLAGS_SETSHRMD))
- adflags |= ADFLAGS_DF;
+ if ((ad->ad_vers == AD_VERSION2) && (adflags & ADFLAGS_RF))
+ adflags |= ADFLAGS_HF;
if ((adflags & ADFLAGS_DF)
&& (ad_data_fileno(ad) >= 0 || ad_data_fileno(ad) == -2) /* -2 means symlink */
err = -1;
ad->ad_rlen = 0;
ad_reso_fileno(ad) = -1;
+ adf_lock_free(ad->ad_rfp);
}
}
+ LOG(log_debug, logtype_default,
+ "ad_close(%s): END: %d [dfd: %d (ref: %d), mfd: %d (ref: %d), rfd: %d (ref: %d)]",
+ adflags2logstr(adflags), err,
+ ad_data_fileno(ad), ad->ad_data_fork.adf_refcount,
+ ad_meta_fileno(ad), ad->ad_mdp->adf_refcount,
+ ad_reso_fileno(ad), ad->ad_rfp->adf_refcount);
+
return err;
}