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 ) {
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;
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;
}
} 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;
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;
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;
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 );
}
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.
*/
}
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 );
/* 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) {
ad->adf_lockmax = ad->adf_lockcount + ARRAY_FREE_DELTA;
}
}
-#endif
}
*/
static void adf_unlock(struct ad_fd *ad, const int fork)
{
-#if 0
adf_lock_t *lock = ad->adf_lock;
int i;
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;
if (OVERLAP(off, len, lock[i].lock.l_start, lock[i].lock.l_len))
set_lock(fd, F_SETLK, &lock[i].lock);
}
-#endif
}
const off_t off,
const off_t len)
{
-#if 0
adf_lock_t *lock = ad->adf_lock;
int i;
return i;
}
}
-#endif
return -1;
}
const off_t off,
const off_t len)
{
-#if 0
adf_lock_t *lock = ad->adf_lock;
int i;
OVERLAP(off, len, lock[i].lock.l_start, lock[i].lock.l_len))
return i;
}
-#endif
return -1;
}
}
/* ------------------ */
-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;
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);
}
}
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 {
lock.l_type = F_UNLCK;
if (!adf->adf_excl) set_lock(adf->adf_fd, F_SETLK, &lock);
return -1;
-#endif
return 0;
}
*/
static int testlock(struct ad_fd *adf, off_t off, off_t len)
{
-#if 0
struct flock lock;
adf_lock_t *plock;
int i;
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;
}
/* --------------------- */
-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);
/* --------------- */
int ad_testlock(struct adouble *ad, int eid, const off_t off)
{
- return 0;
-#if 0
struct ad_fd *adf;
off_t lock_offset;
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);
}
}
/* 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
}
/* -------------------------
*/
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;
/* 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;
}
*/
if (!(attrbits & ATTRBIT_DOPEN)) {
if (ad_meta_fileno(ad) != -1) {
- adf = ad->ad_md;
+ adf = ad->ad_mdp;
off = LOCK_DATA_WR;
}
else {
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
}
/* -------------------------
*/
int ad_excl_lock(struct adouble *ad, const uint32_t eid)
{
- return 0;
-#if 0
struct ad_fd *adf;
struct flock lock;
int err;
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;
}