/*
Check CNID for a file/dir, both from db and from ad-file.
For detailed specs see intro.
+
+ @return Correct CNID of object or CNID_INVALID (ie 0) on error
*/
static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfile_ok, int adflags)
{
cnidcount = 0;
if (dbif_txn_checkpoint(dbd, 0, 0, 0) < 0) {
dbd_log(LOGSTD, "Error checkpointing!");
- return 0;
+ return CNID_INVALID;
}
}
if (ad_open_metadata( name, adflags, O_RDWR, &ad) != 0) {
if (dbd_flags & DBD_FLAGS_CLEANUP)
- return 0;
+ return CNID_INVALID;
dbd_log( LOGSTD, "Error opening AppleDouble file for '%s/%s': %s", cwdbuf, name, strerror(errno));
- return 0;
+ return CNID_INVALID;
}
if (dbd_flags & DBD_FLAGS_FORCE) {
/* Query the database */
ret = dbd_lookup(dbd, &rqst, &rply, (dbd_flags & DBD_FLAGS_SCAN) ? 1 : 0);
- dbif_txn_close(dbd, ret);
+ if (dbif_txn_close(dbd, ret) != 0)
+ return CNID_INVALID;
if (rply.result == CNID_DBD_RES_OK) {
db_cnid = rply.cnid;
} else if (rply.result == CNID_DBD_RES_NOTFOUND) {
if ( ! (dbd_flags & DBD_FLAGS_SCAN)) {
rqst.cnid = db_cnid;
ret = dbd_delete(dbd, &rqst, &rply, DBIF_CNID);
- dbif_txn_close(dbd, ret);
+ if (dbif_txn_close(dbd, ret) != 0)
+ return CNID_INVALID;
rqst.cnid = ad_cnid;
ret = dbd_delete(dbd, &rqst, &rply, DBIF_CNID);
- dbif_txn_close(dbd, ret);
+ if (dbif_txn_close(dbd, ret) != 0)
+ return CNID_INVALID;
ret = dbd_rebuild_add(dbd, &rqst, &rply);
- dbif_txn_close(dbd, ret);
+ if (dbif_txn_close(dbd, ret) != 0)
+ return CNID_INVALID;
}
return ad_cnid;
} else if (ad_cnid && (db_cnid == 0)) {
if (ret == CNID_DBD_RES_OK) {
/* Occupied! Choose another, update ad-file */
ret = dbd_add(dbd, &rqst, &rply, 1);
- dbif_txn_close(dbd, ret);
+ if (dbif_txn_close(dbd, ret) != 0)
+ return CNID_INVALID;
db_cnid = rply.cnid;
dbd_log(LOGSTD, "New CNID for '%s/%s': %u", cwdbuf, name, ntohl(db_cnid));
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 0;
+ return CNID_INVALID;
}
ad_setid( &ad, st->st_dev, st->st_ino, db_cnid, did, stamp);
ad_flush(&ad);
cwdbuf, name, ntohl(ad_cnid));
rqst.cnid = ad_cnid;
ret = dbd_rebuild_add(dbd, &rqst, &rply);
- dbif_txn_close(dbd, ret);
+ if (dbif_txn_close(dbd, ret) != 0)
+ return CNID_INVALID;
}
return ad_cnid;
} else if ((db_cnid == 0) && (ad_cnid == 0)) {
if ( ! (dbd_flags & DBD_FLAGS_SCAN)) {
/* add to db */
ret = dbd_add(dbd, &rqst, &rply, 1);
- dbif_txn_close(dbd, ret);
+ if (dbif_txn_close(dbd, ret) != 0)
+ return CNID_INVALID;
db_cnid = rply.cnid;
dbd_log(LOGSTD, "New CNID for '%s/%s': %u", cwdbuf, name, ntohl(db_cnid));
}
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 0;
+ return CNID_INVALID;
}
ad_setid( &ad, st->st_dev, st->st_ino, db_cnid, did, stamp);
ad_flush(&ad);
return db_cnid;
}
- return 0;
+ return CNID_INVALID;
}
/*
cnid = check_cnid(ep->d_name, did, &st, adfile_ok, adflags);
/* Now add this object to our rebuild dbd */
- if (cnid) {
+ if (cnid && dbd_rebuild) {
static uint count = 0;
rqst.cnid = rply.cnid;
ret = dbd_rebuild_add(dbd_rebuild, &rqst, &rply);
- dbif_txn_close(dbd_rebuild, ret);
+ if (dbif_txn_close(dbd_rebuild, ret) != 0)
+ return -1;
if (rply.result != CNID_DBD_RES_OK) {
- dbd_log( LOGDEBUG, "Fatal error adding CNID: %u for '%s/%s' to in-memory rebuild-db",
+ dbd_log( LOGSTD, "Fatal error adding CNID: %u for '%s/%s' to in-memory rebuild-db",
cnid, cwdbuf, ep->d_name);
- longjmp(jmp, 1); /* this jumps back to cmd_dbd_scanvol() */
+ return -1;
}
count++;
if (count == 10000) {
close(cwd);
*(strrchr(cwdbuf, '/')) = 0;
if (ret < 0)
- continue;
+ return -1;
}
}
goto cleanup;
}
- dbif_txn_close(dbd, ret);
+ if (dbif_txn_close(dbd, ret) != 0)
+ return;
deleted++;
}
/* Check if we got a termination signal */
(void)dbif_txn_abort(dbd);
goto cleanup;
}
- dbif_txn_close(dbd, ret);
+ if (dbif_txn_close(dbd, ret) != 0)
+ return;
deleted++;
}
continue;
if (dbd_cnid > rebuild_cnid) {
dbif_idwalk(dbd, NULL, 1); /* Close cursor */
dbif_idwalk(dbd_rebuild, NULL, 1); /* Close cursor */
- dbif_txn_close(dbd, 2);
- dbif_txn_close(dbd_rebuild, 2);
+ (void)dbif_txn_close(dbd, 2);
+ (void)dbif_txn_close(dbd_rebuild, 2);
dbd_log(LOGSTD, "Ghost CNID: %u. This is fatal! Dumping rebuild db:\n", rebuild_cnid);
dbif_dump(dbd_rebuild, 0);
dbd_log(LOGSTD, "Send this dump and a `dbd -d ...` dump to the Netatalk Dev team!");
return -1;
}
- if (! nocniddb) {
+ /* temporary rebuild db, used with -re rebuild to delete unused CNIDs, not used with -f */
+ if (! nocniddb && !(flags & DBD_FLAGS_FORCE)) {
/* Get volume stamp */
dbd_getstamp(dbd, &rqst, &rply);
if (rply.result != CNID_DBD_RES_OK)
if (setjmp(jmp) != 0) {
ret = 0; /* Got signal, jump from dbd_readdir */
- goto exit_cleanup;
+ goto exit;
}
/* scanvol */
goto exit;
}
-exit_cleanup:
+exit:
if (! nocniddb) {
- dbif_txn_close(dbd, 2);
- dbif_txn_close(dbd_rebuild, 2);
- if ((flags & DBD_FLAGS_EXCL) && !(flags & DBD_FLAGS_FORCE))
+ if (dbif_txn_close(dbd, 2) != 0)
+ ret = -1;
+ if (dbd_rebuild)
+ if (dbif_txn_close(dbd_rebuild, 2) != 0)
+ ret = -1;
+ if ((ret == 0) && dbd_rebuild && (flags & DBD_FLAGS_EXCL) && !(flags & DBD_FLAGS_FORCE))
/* We can only do this in exclusive mode, otherwise we might delete CNIDs added from
other clients in between our pass 1 and 2 */
delete_orphaned_cnids(dbd, dbd_rebuild, flags);
}
-exit:
if (dbd_rebuild) {
dbd_log(LOGDEBUG, "Closing tmp db");
dbif_close(dbd_rebuild);