From 667eec91942bbfa71da6b62de905cafdb295796d Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Mon, 27 Sep 2010 11:54:31 +0200 Subject: [PATCH] Adjust dircache for renamed files and minor fixes --- etc/afpd/afp_avahi.c | 4 +--- etc/afpd/dircache.c | 2 +- etc/afpd/directory.c | 12 ++++-------- etc/afpd/directory.h | 2 +- etc/afpd/file.c | 35 +++++++++++++++++++++++++++-------- etc/afpd/file.h | 8 ++++++-- etc/afpd/filedir.c | 12 ++++++++++++ include/atalk/cnid.h | 2 +- libatalk/cnid/cnid.c | 4 +--- 9 files changed, 54 insertions(+), 27 deletions(-) diff --git a/etc/afpd/afp_avahi.c b/etc/afpd/afp_avahi.c index fc362711..28c72e22 100644 --- a/etc/afpd/afp_avahi.c +++ b/etc/afpd/afp_avahi.c @@ -250,7 +250,7 @@ static void client_callback(AvahiClient *client, * neccessary config setting. */ void av_zeroconf_setup(const AFPConfig *configs) { - int error, ret; + int error; /* initialize the struct that holds our config settings. */ if (ctx) { @@ -291,8 +291,6 @@ fail: * This function finally runs the loop impl. */ int av_zeroconf_run(void) { - int ret; - /* Finally, start the event loop thread */ if (avahi_threaded_poll_start(ctx->threaded_poll) < 0) { LOG(log_error, logtype_afpd, "Failed to create thread: %s", diff --git a/etc/afpd/dircache.c b/etc/afpd/dircache.c index f6f19f71..c641f249 100644 --- a/etc/afpd/dircache.c +++ b/etc/afpd/dircache.c @@ -527,7 +527,7 @@ void dircache_dump(void) cfrombstring(dir->d_u_name)); } - fprintf(dump, "\Secondary DID/name index:\n"); + fprintf(dump, "\nSecondary DID/name index:\n"); fprintf(dump, " VID DID CNID STAT PATH\n"); fprintf(dump, "====================================================================\n"); hash_scan_begin(&hs, index_didname); diff --git a/etc/afpd/directory.c b/etc/afpd/directory.c index a6f75643..ad76bd09 100644 --- a/etc/afpd/directory.c +++ b/etc/afpd/directory.c @@ -757,7 +757,7 @@ void dir_free(struct dir *dir) * 3. Build fullpath and create struct dir. * 4. Add it to the cache. * - * @param vol (r) pointer to struct vol + * @param vol (r) pointer to struct vol, possibly modified in callee * @param dir (r) pointer to parrent directory * @param path (rw) pointer to struct path with valid path->u_name * @param len (r) strlen of path->u_name @@ -766,7 +766,7 @@ void dir_free(struct dir *dir) * * @note Function also assigns path->m_name from path->u_name. */ -struct dir *dir_add(const struct vol *vol, const struct dir *dir, struct path *path, int len) +struct dir *dir_add(struct vol *vol, const struct dir *dir, struct path *path, int len) { int err = 0; struct dir *cdir = NULL; @@ -907,6 +907,7 @@ int dir_remove(const struct vol *vol, struct dir *dir) * @param did (r) new DID * @param new_mname (r) new mac-name * @param new_uname (r) new unix-name + * @param pdir_fullpath (r) new fullpath of parent dir */ int dir_modify(const struct vol *vol, struct dir *dir, @@ -944,7 +945,7 @@ int dir_modify(const struct vol *vol, dir->d_u_name = dir->d_m_name; } else { if ((dir->d_u_name = bfromcstr(new_uname)) == NULL) { - LOG(log_error, logtype_afpd, "renamedir: bassigncstr: %s", strerror(errno) ); + LOG(log_error, logtype_afpd, "dir_modify: bassigncstr: %s", strerror(errno) ); return -1; } } @@ -2201,11 +2202,6 @@ int renamedir(const struct vol *vol, ad_close_metadata( &ad); } - if (dir_modify(vol, dir, curdir->d_did, 0, newname, dst, curdir->d_fullpath) != 0) { - LOG(log_error, logtype_afpd, "renamedir: fatal error from dir_modify: %s -> %s", src, dst); - return AFPERR_MISC; - } - return( AFP_OK ); } diff --git a/etc/afpd/directory.h b/etc/afpd/directory.h index 0fe65e70..c9e193d9 100644 --- a/etc/afpd/directory.h +++ b/etc/afpd/directory.h @@ -111,7 +111,7 @@ typedef int (*dir_loop)(struct dirent *, char *, void *); extern struct dir *dir_new(const char *mname, const char *uname, const struct vol *, cnid_t pdid, cnid_t did, bstring fullpath); /* volume.c needs it once */ extern void dir_free (struct dir *); -extern struct dir *dir_add(const struct vol *, const struct dir *, struct path *, int); +extern struct dir *dir_add(struct vol *, const struct dir *, struct path *, int); extern int dir_modify(const struct vol *vol, struct dir *dir, cnid_t pdid, cnid_t did, const char *new_mname, const char *new_uname, bstring pdir_fullpath); extern int dir_remove(const struct vol *vol, struct dir *dir); diff --git a/etc/afpd/file.c b/etc/afpd/file.c index a1674601..8aef42de 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -202,9 +202,27 @@ char *set_name(const struct vol *vol, char *data, cnid_t pid, char *name, cnid_t (1 << FILPBIT_FNUM) |\ (1 << FILPBIT_UNIXPR))) -/* -------------------------- */ -uint32_t get_id(struct vol *vol, struct adouble *adp, const struct stat *st, - const cnid_t did, char *upath, const int len) +/*! + * @brief Get CNID for did/upath args both from database and adouble file + * + * 1. Get the objects CNID as stored in its adouble file + * 2. Get the objects CNID from the database + * 3. If there's a problem with a "dbd" database, fallback to "tdb" in memory + * 4. In case 2 and 3 differ, store 3 in the adouble file + * + * @param vol (rw) volume + * @param adp (rw) adouble struct of object upath, might be NULL + * @param st (r) stat of upath, must NOT be NULL + * @param did (r) parent CNID of upath + * @param upath (r) name of object + * @param len (r) strlen of upath + */ +uint32_t get_id(struct vol *vol, + struct adouble *adp, + const struct stat *st, + const cnid_t did, + const char *upath, + const int len) { static int first = 1; /* mark if this func is called the first time */ u_int32_t adcnid; @@ -214,9 +232,9 @@ restart: if (vol->v_cdb != NULL) { /* prime aint with what we think is the cnid, set did to zero for catching moved files */ - adcnid = ad_getid(adp, st->st_dev, st->st_ino, 0, vol->v_stamp); + adcnid = ad_getid(adp, st->st_dev, st->st_ino, 0, vol->v_stamp); /* (1) */ - dbcnid = cnid_add(vol->v_cdb, st, did, upath, len, adcnid); + dbcnid = cnid_add(vol->v_cdb, st, did, upath, len, adcnid); /* (2) */ /* Throw errors if cnid_add fails. */ if (dbcnid == CNID_INVALID) { switch (errno) { @@ -234,7 +252,7 @@ restart: /* we have to do it here for "dbd" because it uses "lazy opening" */ /* In order to not end in a loop somehow with goto restart below */ /* */ - if (first && (strcmp(vol->v_cnidscheme, "dbd") == 0)) { + if (first && (strcmp(vol->v_cnidscheme, "dbd") == 0)) { /* (3) */ cnid_close(vol->v_cdb); free(vol->v_cnidscheme); vol->v_cnidscheme = strdup("tdb"); @@ -268,9 +286,10 @@ restart: goto exit; } } - else if (adp && (adcnid != dbcnid)) { + else if (adp && (adcnid != dbcnid)) { /* 4 */ /* Update the ressource fork. For a folder adp is always null */ - LOG(log_debug, logtype_afpd, "get_id: calling ad_setid. adcnid: %u, dbcnid: %u", htonl(adcnid), htonl(dbcnid)); + LOG(log_note, logtype_afpd, "get_id: calling ad_setid(old: %u, new: %u)", + htonl(adcnid), htonl(dbcnid)); if (ad_setid(adp, st->st_dev, st->st_ino, dbcnid, did, vol->v_stamp)) { ad_flush(adp); } diff --git a/etc/afpd/file.h b/etc/afpd/file.h index 3c64e7dd..483f6be6 100644 --- a/etc/afpd/file.h +++ b/etc/afpd/file.h @@ -127,8 +127,12 @@ extern void *get_finderinfo (const struct vol *, const char *, struct adouble *, extern size_t mtoUTF8 (const struct vol *, const char *, size_t , char *, size_t ); extern int copy_path_name (const struct vol *, char *, char *i); -extern uint32_t get_id (struct vol *, struct adouble *, const struct stat *, - const cnid_t , char *, const int ); +extern uint32_t get_id (struct vol *, + struct adouble *, + const struct stat *, + cnid_t , + const char *, + int ); /* FP functions */ int afp_exchangefiles (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen); diff --git a/etc/afpd/filedir.c b/etc/afpd/filedir.c index 74bbd2e8..095189ce 100644 --- a/etc/afpd/filedir.c +++ b/etc/afpd/filedir.c @@ -449,6 +449,18 @@ static int moveandrename(const struct vol *vol, if (stat(upath, st) < 0) return AFPERR_MISC; + if (dir_modify(vol, + sdir, + curdir->d_did, + 0, + newname, + upath, + S_ISDIR(st->st_mode) ? curdir->d_fullpath : NULL) != 0) { + LOG(log_error, logtype_afpd, "moveandrename: dir_modify error: %s -> %s", + p, upath); + return AFPERR_MISC; + } + /* fix up the catalog entry */ cnid_update(vol->v_cdb, id, st, curdir->d_did, upath, strlen(upath)); } diff --git a/include/atalk/cnid.h b/include/atalk/cnid.h index 8dcb33fb..5cd5ff70 100644 --- a/include/atalk/cnid.h +++ b/include/atalk/cnid.h @@ -111,7 +111,7 @@ struct _cnid_db *cnid_open(const char *volpath, const char *cnidport); /* Only for dbd */ cnid_t cnid_add(struct _cnid_db *cdb, const struct stat *st, const cnid_t did, - char *name, const size_t len, cnid_t hint); + const char *name, const size_t len, cnid_t hint); int cnid_delete(struct _cnid_db *cdb, cnid_t id); diff --git a/libatalk/cnid/cnid.c b/libatalk/cnid/cnid.c index 263f2414..ca2190e5 100644 --- a/libatalk/cnid/cnid.c +++ b/libatalk/cnid/cnid.c @@ -1,6 +1,4 @@ /* - * $Id: cnid.c,v 1.13 2010-03-31 09:47:32 franklahm Exp $ - * * Copyright (c) 2003 the Netatalk Team * Copyright (c) 2003 Rafal Lewczuk * @@ -216,7 +214,7 @@ u_int32_t flags; /* --------------- */ cnid_t cnid_add(struct _cnid_db *cdb, const struct stat *st, const cnid_t did, - char *name, const size_t len, cnid_t hint) + const char *name, const size_t len, cnid_t hint) { cnid_t ret; -- 2.39.2