X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Fofork.c;h=4e0eb886901718f4a0a4f79d183714e1a1f14ea2;hb=b0bcb8f6b0571592a50ce039882c9319e012a270;hp=a69a73c56c5de3d015f07858ea6d0e9b029ad3a9;hpb=8ea9eaad323ec8ea180ffc277cd409d713a5895f;p=netatalk.git diff --git a/etc/afpd/ofork.c b/etc/afpd/ofork.c index a69a73c5..4e0eb886 100644 --- a/etc/afpd/ofork.c +++ b/etc/afpd/ofork.c @@ -21,18 +21,17 @@ #include #include #include +#include +#include -#include "globals.h" #include "volume.h" #include "directory.h" #include "fork.h" -/* we need to have a hashed list of oforks (by dev inode). just hash - * by first letter. */ +/* we need to have a hashed list of oforks (by dev inode) */ #define OFORK_HASHSIZE 64 -static struct ofork *ofork_table[OFORK_HASHSIZE]; - -static struct ofork **oforks = NULL; +static struct ofork *ofork_table[OFORK_HASHSIZE]; /* forks hashed by dev/inode */ +static struct ofork **oforks = NULL; /* point to allocated table of open forks pointers */ static int nforks = 0; static u_short lastrefnum = 0; @@ -40,12 +39,6 @@ static u_short lastrefnum = 0; /* OR some of each character for the hash*/ static unsigned long hashfn(const struct file_key *key) { -#if 0 - unsigned long i = 0; - while (*name) { - i = ((i << 4) | (8*sizeof(i) - 4)) ^ *name++; - } -#endif return key->inode & (OFORK_HASHSIZE - 1); } @@ -69,22 +62,6 @@ static void of_unhash(struct ofork *of) } } -#ifdef DEBUG1 -void of_pforkdesc( FILE *f) -{ - int ofrefnum; - - if (!oforks) - return; - - for ( ofrefnum = 0; ofrefnum < nforks; ofrefnum++ ) { - if ( oforks[ ofrefnum ] != NULL ) { - fprintf( f, "%hu <%s>\n", ofrefnum, of_name(oforks[ ofrefnum ])); - } - } -} -#endif - int of_flush(const struct vol *vol) { int refnum; @@ -223,12 +200,9 @@ of_alloc(struct vol *vol, 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->ad_refcount++; } + ad_ref(ad); of->of_ad = ad; of->of_vol = vol; of->of_did = dir->d_did; @@ -272,7 +246,7 @@ int of_stat(struct path *path) } -#ifdef HAVE_RENAMEAT +#ifdef HAVE_ATFUNCS int of_fstatat(int dirfd, struct path *path) { int ret; @@ -285,7 +259,7 @@ int of_fstatat(int dirfd, struct path *path) return ret; } -#endif /* HAVE_RENAMEAT */ +#endif /* HAVE_ATFUNCS */ /* -------------------------- stat the current directory. @@ -365,7 +339,7 @@ struct ofork *of_findname(struct path *path) * @param dirfd (r) directory fd * @param path (rw) pointer to struct path */ -#ifdef HAVE_RENAMEAT +#ifdef HAVE_ATFUNCS struct ofork *of_findnameat(int dirfd, struct path *path) { struct ofork *of; @@ -398,17 +372,6 @@ void of_dealloc( struct ofork *of) 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 ); } @@ -416,15 +379,10 @@ void of_dealloc( struct ofork *of) int of_closefork(struct ofork *ofork) { struct timeval tv; - int adflags, doflush = 0; + int 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. */ @@ -439,9 +397,20 @@ int of_closefork(struct ofork *ofork) } } } + + /* Somone has used write_fork, we assume file was changed, register it to file change event api */ + if (ofork->of_flags & AFPFORK_MODIFIED) { + fce_register_file_modification(ofork); + } + ret = 0; - if ( ad_close( ofork->of_ad, adflags ) < 0 ) { - ret = -1; + + 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; + } } of_dealloc( ofork ); @@ -485,3 +454,23 @@ void of_closevol(const struct vol *vol) return; } +/* ---------------------- + close all forks for a volume +*/ +void of_close_all_forks(void) +{ + int refnum; + + if (!oforks) + return; + + for ( refnum = 0; refnum < nforks; refnum++ ) { + if (oforks[ refnum ] != NULL) { + if (of_closefork( oforks[ refnum ]) < 0 ) { + LOG(log_error, logtype_afpd, "of_close_all_forks: %s", strerror(errno) ); + } + } + } + return; +} +