X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libatalk%2Fadouble%2Fad_lock.c;h=8222500b0c46135cda15a7eacd22b7aa4ad78340;hb=22ce5ab8206909a9972ee1b95cdd65c3ae403ae6;hp=0331bb3c3d239aab3347075c14ea2ebba59d5736;hpb=60a8d986667706e525a746815917575f732db075;p=netatalk.git diff --git a/libatalk/adouble/ad_lock.c b/libatalk/adouble/ad_lock.c index 0331bb3c..8222500b 100644 --- a/libatalk/adouble/ad_lock.c +++ b/libatalk/adouble/ad_lock.c @@ -1,5 +1,5 @@ /* - * $Id: ad_lock.c,v 1.7 2003-01-16 20:06:33 didg Exp $ + * $Id: ad_lock.c,v 1.11 2003-02-16 12:35:05 didg Exp $ * * Copyright (c) 1998,1999 Adrian Sun (asun@zoology.washington.edu) * All Rights Reserved. See COPYRIGHT for more information. @@ -55,7 +55,6 @@ static int XLATE_FCNTL_LOCK(int type) } /* ----------------------- */ - static int OVERLAP(off_t a, off_t alen, off_t b, off_t blen) { return (!alen && a <= b) || @@ -63,7 +62,6 @@ static int OVERLAP(off_t a, off_t alen, off_t b, off_t blen) ( (a + alen > b) && (b + blen > a) ); } - /* allocation for lock regions. we allocate aggressively and shrink * only in large chunks. */ #define ARRAY_BLOCK_SIZE 10 @@ -76,8 +74,10 @@ static __inline__ void adf_freelock(struct ad_fd *ad, const int i) if (--(*lock->refcount) < 1) { free(lock->refcount); - lock->lock.l_type = F_UNLCK; - fcntl(ad->adf_fd, F_SETLK, &lock->lock); /* unlock */ + if (!ad->adf_excl) { + lock->lock.l_type = F_UNLCK; + fcntl(ad->adf_fd, F_SETLK, &lock->lock); /* unlock */ + } } ad->adf_lockcount--; @@ -135,7 +135,7 @@ static __inline__ void adf_relockrange(struct ad_fd *ad, int fd, adf_lock_t *lock = ad->adf_lock; int i; - for (i = 0; i < ad->adf_lockcount; i++) { + if (!ad->adf_excl) for (i = 0; i < ad->adf_lockcount; i++) { if (OVERLAP(off, len, lock[i].lock.l_start, lock[i].lock.l_len)) fcntl(fd, F_SETLK, &lock[i].lock); } @@ -212,7 +212,7 @@ static __inline__ int adf_findxlock(struct ad_fd *ad, translate a data fork lock to an offset */ -static int df2off(int off) +static off_t df2off(int off) { int start = off; if (off == AD_FILELOCK_OPEN_WR) @@ -232,7 +232,7 @@ int start = off; translate a resource fork lock to an offset */ -static int hf2off(int off) +static off_t hf2off(int off) { int start = off; if (off == AD_FILELOCK_OPEN_WR) @@ -254,7 +254,8 @@ int ad_fcntl_lock(struct adouble *ad, const u_int32_t eid, const int locktype, { struct flock lock; struct ad_fd *adf; - adf_lock_t *adflock, *oldlock; + adf_lock_t *adflock; + int oldlock; int i; int type; @@ -328,7 +329,7 @@ int ad_fcntl_lock(struct adouble *ad, const u_int32_t eid, const int locktype, } /* attempt to lock the file. */ - if (fcntl(adf->adf_fd, F_SETLK, &lock) < 0) + if (!adf->adf_excl && fcntl(adf->adf_fd, F_SETLK, &lock) < 0) return -1; /* we upgraded this lock. */ @@ -338,10 +339,9 @@ int ad_fcntl_lock(struct adouble *ad, const u_int32_t eid, const int locktype, } /* it wasn't an upgrade */ - oldlock = NULL; - if ((lock.l_type == F_RDLCK) && - ((i = adf_findxlock(adf, user, ADLOCK_RD, lock.l_start, lock.l_len)) > -1)) { - oldlock = adf->adf_lock + i; + oldlock = -1; + if (lock.l_type == F_RDLCK) { + oldlock = adf_findxlock(adf, user, ADLOCK_RD, lock.l_start, lock.l_len); } /* no more space. this will also happen if lockmax == lockcount == 0 */ @@ -359,9 +359,9 @@ int ad_fcntl_lock(struct adouble *ad, const u_int32_t eid, const int locktype, /* fill in fields */ memcpy(&adflock->lock, &lock, sizeof(lock)); adflock->user = user; - if (oldlock) - adflock->refcount = oldlock->refcount; - else if ((adflock->refcount = calloc(1, sizeof(int))) == NULL) { + if (oldlock > -1) { + adflock->refcount = (adf->adf_lock + oldlock)->refcount; + } else if ((adflock->refcount = calloc(1, sizeof(int))) == NULL) { goto fcntl_lock_err; } @@ -371,7 +371,7 @@ int ad_fcntl_lock(struct adouble *ad, const u_int32_t eid, const int locktype, fcntl_lock_err: lock.l_type = F_UNLCK; - fcntl(adf->adf_fd, F_SETLK, &lock); + if (!adf->adf_excl) fcntl(adf->adf_fd, F_SETLK, &lock); return -1; } @@ -425,14 +425,16 @@ int ad_testlock(struct adouble *ad, int eid, const off_t off) /* ------------------------- */ -int ad_fcntl_tmplock(struct adouble *ad, const u_int32_t eid, const int type, +int ad_fcntl_tmplock(struct adouble *ad, const u_int32_t eid, const int locktype, const off_t off, const off_t len, const int user) { struct flock lock; struct ad_fd *adf; int err; + int type; lock.l_start = off; + type = locktype; if (eid == ADEID_DFORK) { adf = &ad->ad_df; } else { @@ -446,6 +448,11 @@ int ad_fcntl_tmplock(struct adouble *ad, const u_int32_t eid, const int type, if (!(type & ADLOCK_FILELOCK)) lock.l_start += ad_getentryoff(ad, eid); } + + if (!(adf->adf_flags & O_RDWR) && (type & ADLOCK_WR)) { + type = (type & ~ADLOCK_WR) | ADLOCK_RD; + } + lock.l_type = XLATE_FCNTL_LOCK(type & ADLOCK_MASK); lock.l_whence = SEEK_SET; lock.l_len = len; @@ -464,14 +471,45 @@ int ad_fcntl_tmplock(struct adouble *ad, const u_int32_t eid, const int type, * XXX: in the future, all the byte locks will be sorted and contiguous. * we just want to upgrade all the locks and then downgrade them * here. */ - err = fcntl(adf->adf_fd, F_SETLK, &lock); + if (!adf->adf_excl) { + err = fcntl(adf->adf_fd, F_SETLK, &lock); + } + else { + err = 0; + } if (!err && (lock.l_type == F_UNLCK)) adf_relockrange(adf, adf->adf_fd, lock.l_start, len); return err; } +/* ------------------------- + the fork is opened in Read Write, Deny Read, Deny Write mode + lock the whole file once +*/ +int ad_excl_lock(struct adouble *ad, const u_int32_t eid) +{ + struct ad_fd *adf; + struct flock lock; + int err; + + if (eid == ADEID_DFORK) { + adf = &ad->ad_df; + } else { + adf = &ad->ad_hf; + } + lock.l_start = 0; + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_len = 0; + + err = fcntl(adf->adf_fd, F_SETLK, &lock); + if (!err) + adf->adf_excl = 1; + return err; +} +/* --------------------- */ void ad_fcntl_unlock(struct adouble *ad, const int user) { if (ad->ad_df.adf_fd != -1) {