From ddec37115558d3b0b9c8da7b98bb1be55e1048b9 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Wed, 7 Sep 2011 12:24:21 +0200 Subject: [PATCH] Better checking for duplicated or bogus CNIDs from AppleDouble files --- NEWS | 4 ++++ etc/cnid_dbd/cmd_dbd_scanvol.c | 28 +++++++++++++--------------- etc/cnid_dbd/dbd_rebuild_add.c | 5 +++++ etc/cnid_dbd/dbd_resolve.c | 4 ++-- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/NEWS b/NEWS index 3d244199..29be671d 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Changes in 2.2.2 +================ +* FIX: dbd: Better checking for duplicated or bogus CNIDs from AppleDouble files + Changes in 2.2.1 ================ diff --git a/etc/cnid_dbd/cmd_dbd_scanvol.c b/etc/cnid_dbd/cmd_dbd_scanvol.c index ece70dd4..50433c66 100644 --- a/etc/cnid_dbd/cmd_dbd_scanvol.c +++ b/etc/cnid_dbd/cmd_dbd_scanvol.c @@ -755,24 +755,22 @@ static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfi /* Everything is fine */ return db_cnid; } else if (ad_cnid && db_cnid && (ad_cnid != db_cnid)) { - /* Mismatch ? Delete both from db and re-add data from file */ + /* Mismatch, overwrite ad file with value from db */ dbd_log( LOGSTD, "CNID mismatch for '%s/%s', db: %u, ad-file: %u", cwdbuf, name, ntohl(db_cnid), ntohl(ad_cnid)); if ( ! (dbd_flags & DBD_FLAGS_SCAN)) { - rqst.cnid = db_cnid; - ret = dbd_delete(dbd, &rqst, &rply, DBIF_CNID); - if (dbif_txn_close(dbd, ret) != 0) - return CNID_INVALID; - - rqst.cnid = ad_cnid; - ret = dbd_delete(dbd, &rqst, &rply, DBIF_CNID); - if (dbif_txn_close(dbd, ret) != 0) - return CNID_INVALID; - - ret = dbd_rebuild_add(dbd, &rqst, &rply); - if (dbif_txn_close(dbd, ret) != 0) + dbd_log(LOGSTD, "Updating AppleDouble file for '%s/%s' with CNID: %u from database", + cwdbuf, name, ntohl(db_cnid)); + ad_init(&ad, myvolinfo->v_adouble, myvolinfo->v_ad_options); + if (ad_open_metadata( name, adflags, O_RDWR, &ad) != 0) { + dbd_log(LOGSTD, "Error opening AppleDouble file for '%s/%s': %s", + cwdbuf, name, strerror(errno)); return CNID_INVALID; + } + ad_setid( &ad, st->st_dev, st->st_ino, db_cnid, did, stamp); + ad_flush(&ad); + ad_close_metadata(&ad); } - return ad_cnid; + return db_cnid; } else if (ad_cnid && (db_cnid == 0)) { /* in ad-file but not in db */ if ( ! (dbd_flags & DBD_FLAGS_SCAN)) { @@ -782,7 +780,7 @@ static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfi rqst.cnid = ad_cnid; ret = dbd_resolve(dbd, &rqst, &rply); - if (ret == CNID_DBD_RES_OK) { + if (rply.result == CNID_DBD_RES_OK) { /* Occupied! Choose another, update ad-file */ ret = dbd_add(dbd, &rqst, &rply, 1); if (dbif_txn_close(dbd, ret) != 0) diff --git a/etc/cnid_dbd/dbd_rebuild_add.c b/etc/cnid_dbd/dbd_rebuild_add.c index 90b2ffd3..f3a93e4c 100644 --- a/etc/cnid_dbd/dbd_rebuild_add.c +++ b/etc/cnid_dbd/dbd_rebuild_add.c @@ -48,6 +48,11 @@ int dbd_rebuild_add(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply * return -1; } + LOG(log_debug, logtype_cnid, + "dbd_rebuild_add(CNID: %u, did: %u, name: \"%s\", dev/ino:0x%llx/0x%llx): success", + ntohl(rqst->cnid), ntohl(rqst->did), rqst->name, + (unsigned long long)rqst->dev, (unsigned long long)rqst->ino); + key.data = ROOTINFO_KEY; key.size = ROOTINFO_KEYLEN; diff --git a/etc/cnid_dbd/dbd_resolve.c b/etc/cnid_dbd/dbd_resolve.c index 17a42de0..1c2e2da9 100644 --- a/etc/cnid_dbd/dbd_resolve.c +++ b/etc/cnid_dbd/dbd_resolve.c @@ -53,8 +53,8 @@ int dbd_resolve(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply rply->namelen = data.size; rply->name = (char *)data.data; - LOG(log_debug, logtype_cnid, "dbd_resolve: Resolving CNID %u to did %u name %s", - ntohl(rqst->cnid), ntohl(rply->did), rply->name); + LOG(log_debug, logtype_cnid, "dbd_resolve(CNID: %u): did: %u, name: \"%s\"", + ntohl(rqst->cnid), ntohl(rply->did), rply->name + CNID_NAME_OFS); rply->result = CNID_DBD_RES_OK; return 1; -- 2.39.2