/*
- $Id: cmd_dbd.c,v 1.2 2009-05-18 09:25:25 franklahm Exp $
+ $Id: cmd_dbd.c,v 1.3 2009-05-22 20:48:44 franklahm Exp $
Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
GNU General Public License for more details.
*/
+/*
+ dbd specs and implementation progress
+ =====================================
+
+ St := Status
+
+ Force option
+ ------------
+
+ St Spec
+ -- ----
+ OK If -f is requested, ensure -e is too.
+ Check if volumes is using AFPVOL_CACHE, then wipe db from disk. Rebuild from ad-files.
+
+ 1st pass: Scan volume
+ --------------------
+
+ St Type Check
+ -- ---- -----
+ OK F/D Make sure ad file exists
+ OK D Make sure .AppleDouble dir exist, create if missing. Error creating
+ it is fatal as that shouldn't happen as root.
+ OK F/D Delete orphaned ad-files, log dirs in ad-dir
+ OK F/D Check name encoding by roundtripping, log on error
+ OK F/D try: read CNID from ad file (if cnid caching is on)
+ try: fetch CNID from database
+ -> on mismatch: use CNID from file, update database (deleting both found CNIDs first)
+ -> if no CNID in ad file: write CNID from database to ad file
+ -> if no CNID in database: add CNID from ad file to database
+ -> on no CNID at all: create one and store in both places
+ OK F/D Add found CNID, DID, filename, dev/inode, stamp to rebuild database
+ OK F/D Check/update stamp (implicitly done while checking CNIDs)
+
+
+ 2nd pass: Delete unused CNIDs
+ -----------------------------
+
+ St Spec
+ -- ----
+ OK Step through dbd (the one on disk) and rebuild-db from pass 1 and delete any CNID from
+ dbd not in rebuild db. This in only done in exclusive mode.
+*/
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include <atalk/cnid_dbd_private.h>
#include <atalk/volinfo.h>
#include "cmd_dbd.h"
+#include "dbd.h"
#include "dbif.h"
#include "db_param.h"
" 5. Check for directories inside AppleDouble directories\n"
" 6. Check name encoding by roundtripping, log on error\n"
" Option: -f wipe database and rebuild from IDs stored in AppleDouble files,\n"
- " only available for volumes with 'cachecnid' option\n\n"
+ " only available for volumes with 'cachecnid' option.\n"
+ " Implies -e."
"General options:\n"
" -e only work on inactive volumes and lock them (exclusive)\n"
- " -x rebuild indexes\n"
+ " -x rebuild indexes (just for completeness, mostly useless!)\n"
" -v verbose\n"
);
}
break;
case 's':
scan = 1;
- flags = DBD_FLAGS_SCAN;
+ flags |= DBD_FLAGS_SCAN;
break;
case 'r':
rebuild = 1;
break;
case 'e':
exclusive = 1;
+ flags |= DBD_FLAGS_EXCL;
break;
case 'x':
rebuildindexes = 1;
break;
case 'f':
force = 1;
- flags = DBD_FLAGS_FORCE;
+ flags |= DBD_FLAGS_FORCE | DBD_FLAGS_EXCL;
break;
case ':':
case '?':
exit(EXIT_FAILURE);
}
+ /* Check if -f is requested and wipe db if yes */
+ if ((flags & DBD_FLAGS_FORCE) && (volinfo.v_flags & AFPVOL_CACHE)) {
+ char cmd[8 + MAXPATHLEN];
+ snprintf(cmd, 8 + MAXPATHLEN, "rm -f %s/cnid2.db", dbpath);
+ dbd_log( LOGSTD, "Removing old database of volume: '%s'", volpath);
+ system(cmd);
+ dbd_log( LOGSTD, "Removed old database.");
+ }
+
/*
Lets start with the BerkeleyDB stuff
*/
exit(EXIT_FAILURE);
}
+ if (dbd_stamp(dbd) < 0) {
+ dbif_close(dbd);
+ exit(EXIT_FAILURE);
+ }
+
if (dump) {
if (dbif_dump(dbd, dumpindexes) < 0) {
dbd_log( LOGSTD, "Error dumping database");
typedef unsigned int dbd_flags_t;
#define DBD_FLAGS_SCAN (1 << 0)
-#define DBD_FLAGS_FORCE (1 << 0)
+#define DBD_FLAGS_FORCE (1 << 1)
+#define DBD_FLAGS_EXCL (1 << 2)
#define ADv2_DIRNAME ".AppleDouble"
/*
- $Id: cmd_dbd_scanvol.c,v 1.3 2009-05-20 10:56:02 franklahm Exp $
+ $Id: cmd_dbd_scanvol.c,v 1.4 2009-05-22 20:48:44 franklahm Exp $
Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
GNU General Public License for more details.
*/
-/*
- dbd specs and implementation progress
- =====================================
-
- St := Status
-
- Force option
- ------------
-
- St Spec
- -- ----
- -- If -f is requested, ensure -e is too.
- Check if volumes is using AFPVOL_CACHE, then wipe db from disk.
-
- 1st pass: Scan volume
- --------------------
-
- St Type Check
- -- ---- -----
- OK F/D Make sure ad file exists
- OK D Make sure .AppleDouble dir exist, create if missing. Error creating
- it is fatal as that shouldn't happen as root.
- OK F/D Delete orphaned ad-files, log dirs in ad-dir
- OK F/D Check name encoding by roundtripping, log on error
- OK F/D try: read CNID from ad file (if cnid caching is on)
- try: fetch CNID from database
- -> on mismatch: use CNID from file, update database (deleting both found CNIDs first)
- -> if no CNID in ad file: write CNID from database to ad file
- -> if no CNID in database: add CNID from ad file to database
- -> on no CNID at all: create one and store in both places
- OK F/D Add found CNID, DID, filename, dev/inode, stamp to rebuild database
- OK F/D Check/update stamp (implicitly done while checking CNIDs)
-
- 2nd pass: Delete unused CNIDs
- -----------------------------
-
- St Spec
- -- ----
- -- Step through dbd (the one on disk) and rebuild-db from pass 1 and delete any CNID from
- dbd not in rebuild db.
-*/
-
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
dbd_log( LOGSTD, "Error opening AppleDouble file for '%s/%s': %s", cwdbuf, name, strerror(errno));
return 0;
}
- ad_cnid = ad_getid(&ad, st->st_dev, st->st_ino, did, stamp);
+
+ if (dbd_flags & DBD_FLAGS_FORCE)
+ ad_cnid = ad_forcegetid(&ad);
+ else
+ ad_cnid = ad_getid(&ad, st->st_dev, st->st_ino, did, stamp);
if (ad_cnid == 0)
dbd_log( LOGSTD, "Incorrect CNID data in .AppleDouble data for '%s/%s' (bad stamp?)", cwdbuf, name);
+
ad_close_metadata(&ad);
}
return 0;
}
+/*
+ Remove all CNIDs from dbd that are not in dbd_rebuild
+*/
+void delete_orphaned_cnids(DBD *dbd, DBD *dbd_rebuild, dbd_flags_t flags)
+{
+ int ret, deleted = 0;
+ cnid_t dbd_cnid = 0, rebuild_cnid = 0;
+ struct cnid_dbd_rqst rqst;
+ struct cnid_dbd_rply rply;
+
+ /* jump over rootinfo key */
+ if ( dbif_idwalk(dbd, &dbd_cnid, 0) != 1)
+ return;
+ if ( dbif_idwalk(dbd_rebuild, &rebuild_cnid, 0) != 1)
+ return;
+
+ /* Get first id from dbd_rebuild */
+ if ((dbif_idwalk(dbd_rebuild, &rebuild_cnid, 0)) == -1)
+ return;
+
+ /* Start main loop through dbd: get CNID from dbd */
+ while ((dbif_idwalk(dbd, &dbd_cnid, 0)) == 1) {
+
+ if (deleted > 50) {
+ deleted = 0;
+ if (dbif_txn_checkpoint(dbd, 0, 0, 0) < 0) {
+ dbd_log(LOGSTD, "Error checkpointing!");
+ goto cleanup;
+ }
+ }
+
+ /* This should be the normal case: CNID is in both dbs */
+ if (dbd_cnid == rebuild_cnid) {
+ /* Get next CNID from rebuild db */
+ if ((ret = dbif_idwalk(dbd_rebuild, &rebuild_cnid, 0)) == -1) {
+ /* Some error */
+ goto cleanup;
+ } else if (ret == 0) {
+ /* end of rebuild_cnid, delete all remaining CNIDs from dbd */
+ while ((dbif_idwalk(dbd, &dbd_cnid, 0)) == 1) {
+ dbd_log(LOGSTD, "Orphaned CNID in database: %u", dbd_cnid);
+ if ( ! (dbd_flags & DBD_FLAGS_SCAN)) {
+ rqst.cnid = htonl(dbd_cnid);
+ ret = dbd_delete(dbd, &rqst, &rply);
+ dbif_txn_close(dbd, ret);
+ deleted++;
+ }
+ }
+ return;
+ } else
+ /* Normal case (ret=1): continue while loop */
+ continue;
+ }
+
+ if (dbd_cnid < rebuild_cnid) {
+ /* CNID is orphaned -> delete */
+ dbd_log(LOGSTD, "Orphaned CNID in database: %u.", dbd_cnid);
+ if ( ! (dbd_flags & DBD_FLAGS_SCAN)) {
+ rqst.cnid = htonl(dbd_cnid);
+ ret = dbd_delete(dbd, &rqst, &rply);
+ dbif_txn_close(dbd, ret);
+ deleted++;
+ }
+ continue;
+ }
+
+ if (dbd_cnid > rebuild_cnid) {
+ 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!");
+ dbif_txn_close(dbd, ret);
+ dbif_idwalk(dbd, NULL, 1); /* Close cursor */
+ dbif_idwalk(dbd_rebuild, NULL, 1); /* Close cursor */
+ goto cleanup;
+ }
+ }
+
+cleanup:
+ dbif_idwalk(dbd, NULL, 1); /* Close cursor */
+ dbif_idwalk(dbd_rebuild, NULL, 1); /* Close cursor */
+ return;
+}
+
+/*
+ Main func called from cmd_dbd.c
+*/
int cmd_dbd_scanvol(DBD *dbd_ref, struct volinfo *volinfo, dbd_flags_t flags)
{
int ret = 0;
if (0 != (dbif_copy_rootinfokey(dbd, dbd_rebuild)))
goto exit_cleanup;
-// dbif_dump(dbd_rebuild, 0);
-
if (setjmp(jmp) != 0)
goto exit_cleanup; /* Got signal, jump from dbd_readdir */
if ( (scanvol(volinfo, flags)) != 0)
return -1;
-// dbif_dump(dbd_rebuild, 0);
+ /* We can only do this in excluse mode, otherwise we might delete CNIDs added from
+ other clients in between our pass 1 and 2 */
+ if (flags & DBD_FLAGS_EXCL)
+ delete_orphaned_cnids(dbd, dbd_rebuild, flags);
exit_cleanup:
dbif_close(dbd_rebuild);
/*
- * $Id: dbif.c,v 1.11 2009-05-18 09:54:14 franklahm Exp $
+ * $Id: dbif.c,v 1.12 2009-05-22 20:48:44 franklahm Exp $
*
* Copyright (C) Joerg Lenneis 2003
* Copyright (C) Frank Lahm 2009
int dbif_stamp(DBD *dbd, void *buffer, int size)
{
struct stat st;
- int rc;
+ int rc,cwd;
if (size < 8)
return -1;
+ /* Remember cwd */
+ if ((cwd = open(".", O_RDONLY)) < 0) {
+ LOG(log_error, logtype_cnid, "error opening cwd: %s", strerror(errno));
+ return -1;
+ }
+
+ /* chdir to db_envhome */
+ if ((chdir(dbd->db_envhome)) != 0) {
+ LOG(log_error, logtype_cnid, "error chdiring to db_env '%s': %s", dbd->db_envhome, strerror(errno));
+ return -1;
+ }
+
if ((rc = stat(dbd->db_table[DBIF_CNID].name, &st)) < 0) {
LOG(log_error, logtype_cnid, "error stating database %s: %s", dbd->db_table[DBIF_CNID].name, db_strerror(rc));
return -1;
memset(buffer, 0, size);
memcpy(buffer, &st.st_ctime, sizeof(st.st_ctime));
+ if ((fchdir(cwd)) != 0) {
+ LOG(log_error, logtype_cnid, "error chdiring back: %s", strerror(errno));
+ return -1;
+ }
+
return 0;
}
}
/* --------------- */
-int dbif_open(DBD *dbd, struct db_param *dbp _U_, int do_truncate)
+int dbif_open(DBD *dbd, struct db_param *dbp _U_, int reindex)
{
int ret;
int i;
if (dbd->db_errlog != NULL)
dbd->db_table[i].db->set_errfile(dbd->db_table[i].db, dbd->db_errlog);
- if (do_truncate && i > 0) {
+ if (reindex && i > 0) {
LOG(log_info, logtype_cnid, "Truncating CNID index.");
if ((ret = dbd->db_table[i].db->truncate(dbd->db_table[i].db, NULL, &count, 0))) {
LOG(log_error, logtype_cnid, "error truncating database %s: %s",
/* TODO: Implement CNID DB versioning info on new databases. */
/* Associate the secondary with the primary. */
- if (do_truncate)
+ if (reindex)
LOG(log_info, logtype_cnid, "Reindexing did/name index...");
if ((ret = dbd->db_table[0].db->associate(dbd->db_table[DBIF_CNID].db,
dbd->db_txn,
dbd->db_table[DBIF_IDX_DIDNAME].db,
didname,
- (do_truncate) ? DB_CREATE : 0))
+ (reindex) ? DB_CREATE : 0))
!= 0) {
LOG(log_error, logtype_cnid, "Failed to associate didname database: %s",db_strerror(ret));
return -1;
}
- if (do_truncate)
+ if (reindex)
LOG(log_info, logtype_cnid, "... done.");
- if (do_truncate)
+ if (reindex)
LOG(log_info, logtype_cnid, "Reindexing dev/ino index...");
if ((ret = dbd->db_table[0].db->associate(dbd->db_table[0].db,
dbd->db_txn,
dbd->db_table[DBIF_IDX_DEVINO].db,
devino,
- (do_truncate) ? DB_CREATE : 0))
+ (reindex) ? DB_CREATE : 0))
!= 0) {
LOG(log_error, logtype_cnid, "Failed to associate devino database: %s",db_strerror(ret));
return -1;
}
- if (do_truncate)
+ if (reindex)
LOG(log_info, logtype_cnid, "... done.");
return 0;
{
int ret;
+ /* For cooperation with the dbd utility and its usage of a cursor */
+ if (dbd->db_cur) {
+ dbd->db_cur->close(dbd->db_cur);
+ dbd->db_cur = NULL;
+ }
+
if (dbif_txn_begin(dbd) < 0) {
LOG(log_error, logtype_cnid, "error deleting key/value from %s: %s",
dbd->db_table[dbi].name, db_strerror(errno));
return 0;
}
+/*
+ Iterates over dbd, returning cnids.
+ Uses in-value of cnid to seek to that cnid, then gets next and return that in cnid.
+ If close=1, close cursor.
+ Return -1 on error, 0 on EOD (end-of-database), 1 if returning cnid.
+*/
+int dbif_idwalk(DBD *dbd, cnid_t *cnid, int close)
+{
+ int rc;
+ int flag;
+ cnid_t id;
+
+ static DBT key = { 0 }, data = { 0 };
+ DB *db = dbd->db_table[DBIF_CNID].db;
+
+ if (close && dbd->db_cur) {
+ dbd->db_cur->close(dbd->db_cur);
+ dbd->db_cur = NULL;
+ return 0;
+ }
+
+ /* An dbif_del will have closed our cursor too */
+ if ( ! dbd->db_cur ) {
+ if (db->cursor(db, NULL, &dbd->db_cur, 0) != 0) {
+ LOG(log_error, logtype_cnid, "Couldn't create cursor: %s", db_strerror(errno));
+ return -1;
+ }
+ flag = DB_SET_RANGE; /* This will seek to next cnid after the one just deleted */
+ id = htonl(*cnid);
+ key.data = &id;
+ key.size = sizeof(cnid_t);
+ } else
+ flag = DB_NEXT;
+
+ if ((rc = dbd->db_cur->get(dbd->db_cur, &key, &data, flag)) == 0) {
+ memcpy(cnid, key.data, sizeof(cnid_t));
+ *cnid = ntohl(*cnid);
+ return 1;
+ }
+
+ if (rc != DB_NOTFOUND) {
+ LOG(log_error, logtype_cnid, "Error iterating over btree: %s", db_strerror(errno));
+ dbd->db_cur->close(dbd->db_cur);
+ dbd->db_cur = NULL;
+ return -1;
+ }
+
+ if (dbd->db_cur) {
+ dbd->db_cur->close(dbd->db_cur);
+ dbd->db_cur = NULL;
+ }
+
+ return 0;
+}
/*
- $Id: dbif.h,v 1.6 2009-05-14 13:46:08 franklahm Exp $
+ $Id: dbif.h,v 1.7 2009-05-22 20:48:44 franklahm Exp $
Copyright (C) Joerg Lenneis 2003
Copyright (C) Frank Lahm 2009
#include <sys/cdefs.h>
#include <db.h>
+#include <atalk/adouble.h>
#include "db_param.h"
#define DBIF_DB_CNT 3
typedef struct {
DB_ENV *db_env;
DB_TXN *db_txn;
+ DBC *db_cur; /* for dbif_walk */
char *db_envhome;
char *db_filename;
FILE *db_errlog;
/* Functions */
extern DBD *dbif_init(const char *envhome, const char *dbname);
extern int dbif_env_open(DBD *dbd, struct db_param *dbp, uint32_t dbenv_oflags);
-extern int dbif_open(DBD *dbd, struct db_param *dbp, int do_truncate);
+extern int dbif_open(DBD *dbd, struct db_param *dbp, int reindex);
extern int dbif_close(DBD *dbd);
extern int dbif_get(DBD *, const int, DBT *, DBT *, u_int32_t);
extern int dbif_pget(DBD *, const int, DBT *, DBT *, DBT *, u_int32_t);
extern int dbif_put(DBD *, const int, DBT *, DBT *, u_int32_t);
extern int dbif_del(DBD *, const int, DBT *, u_int32_t);
-
extern int dbif_count(DBD *, const int, u_int32_t *);
extern int dbif_stamp(DBD *, void *, int);
extern int dbif_copy_rootinfokey(DBD *srcdbd, DBD *destdbd);
extern void dbif_txn_close(DBD *dbd, int ret); /* Switch between commit+abort */
extern int dbif_txn_checkpoint(DBD *, u_int32_t, u_int32_t, u_int32_t);
-extern int dbif_dump(DBD *, int dumpindexes);
-
+extern int dbif_dump(DBD *dbd, int dumpindexes);
+extern int dbif_idwalk(DBD *dbd, cnid_t *cnid, int close);
#endif
/*
- * $Id: adouble.h,v 1.33 2008-12-03 18:35:44 didg Exp $
+ * $Id: adouble.h,v 1.34 2009-05-22 20:48:44 franklahm Exp $
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
*
#if AD_VERSION == AD_VERSION2
extern int ad_setid __P((struct adouble *, const dev_t dev,const ino_t ino, const u_int32_t, const u_int32_t, const void *));
extern u_int32_t ad_getid __P((struct adouble *, const dev_t, const ino_t, const cnid_t, const void *));
+extern u_int32_t ad_forcegetid __P((struct adouble *adp));
#else
#define ad_setid(a, b, c)
#endif
/*
- * $Id: ad_attr.c,v 1.6 2006-09-29 09:39:16 didg Exp $
+ * $Id: ad_attr.c,v 1.7 2009-05-22 20:48:44 franklahm Exp $
*/
#ifdef HAVE_CONFIG_H
int ad_getattr(const struct adouble *ad, u_int16_t *attr)
{
- *attr = 0;
-
- if (ad->ad_version == AD_VERSION1) {
- if (ad_getentryoff(ad, ADEID_FILEI)) {
- memcpy(attr, ad_entry(ad, ADEID_FILEI) + FILEIOFF_ATTR,
- sizeof(u_int16_t));
- }
- }
+ *attr = 0;
+
+ if (ad->ad_version == AD_VERSION1) {
+ if (ad_getentryoff(ad, ADEID_FILEI)) {
+ memcpy(attr, ad_entry(ad, ADEID_FILEI) + FILEIOFF_ATTR,
+ sizeof(u_int16_t));
+ }
+ }
#if AD_VERSION == AD_VERSION2
- else if (ad->ad_version == AD_VERSION2) {
- if (ad_getentryoff(ad, ADEID_AFPFILEI)) {
- memcpy(attr, ad_entry(ad, ADEID_AFPFILEI) + AFPFILEIOFF_ATTR,
- sizeof(u_int16_t));
- }
- }
+ else if (ad->ad_version == AD_VERSION2) {
+ if (ad_getentryoff(ad, ADEID_AFPFILEI)) {
+ memcpy(attr, ad_entry(ad, ADEID_AFPFILEI) + AFPFILEIOFF_ATTR,
+ sizeof(u_int16_t));
+ }
+ }
#endif
- else
- return -1;
+ else
+ return -1;
- *attr |= htons(ad->ad_open_forks);
+ *attr |= htons(ad->ad_open_forks);
- return 0;
+ return 0;
}
/* ----------------- */
int ad_setattr(const struct adouble *ad, const u_int16_t attribute)
{
- /* we don't save open forks indicator */
- u_int16_t attr = attribute & ~htons(ATTRBIT_DOPEN | ATTRBIT_ROPEN);
-
- if (ad->ad_version == AD_VERSION1) {
- if (ad_getentryoff(ad, ADEID_FILEI)) {
- memcpy(ad_entry(ad, ADEID_FILEI) + FILEIOFF_ATTR, &attr,
- sizeof(attr));
- }
- }
+ /* we don't save open forks indicator */
+ u_int16_t attr = attribute & ~htons(ATTRBIT_DOPEN | ATTRBIT_ROPEN);
+
+ if (ad->ad_version == AD_VERSION1) {
+ if (ad_getentryoff(ad, ADEID_FILEI)) {
+ memcpy(ad_entry(ad, ADEID_FILEI) + FILEIOFF_ATTR, &attr,
+ sizeof(attr));
+ }
+ }
#if AD_VERSION == AD_VERSION2
- else if (ad->ad_version == AD_VERSION2) {
- if (ad_getentryoff(ad, ADEID_AFPFILEI)) {
+ else if (ad->ad_version == AD_VERSION2) {
+ if (ad_getentryoff(ad, ADEID_AFPFILEI)) {
memcpy(ad_entry(ad, ADEID_AFPFILEI) + AFPFILEIOFF_ATTR, &attr,
- sizeof(attr));
- }
- }
+ sizeof(attr));
+ }
+ }
#endif
- else
- return -1;
+ else
+ return -1;
- return 0;
+ return 0;
}
-/* --------------
+/* --------------
* save file/folder ID in AppleDoubleV2 netatalk private parameters
* return 1 if resource fork has been modified
-*/
+ */
#if AD_VERSION == AD_VERSION2
int ad_setid (struct adouble *adp, const dev_t dev, const ino_t ino , const u_int32_t id, const cnid_t did, const void *stamp)
{
if (adp->ad_flags == AD_VERSION2 && ( adp->ad_options & ADVOL_CACHE) &&
- ad_getentryoff(adp, ADEID_PRIVDEV) &&
- sizeof(dev_t) == ADEDLEN_PRIVDEV && sizeof(ino_t) == ADEDLEN_PRIVINO)
+ ad_getentryoff(adp, ADEID_PRIVDEV) &&
+ sizeof(dev_t) == ADEDLEN_PRIVDEV && sizeof(ino_t) == ADEDLEN_PRIVINO)
{
ad_setentrylen( adp, ADEID_PRIVDEV, sizeof(dev_t));
- if ((adp->ad_options & ADVOL_NODEV)) {
+ if ((adp->ad_options & ADVOL_NODEV)) {
memset(ad_entry( adp, ADEID_PRIVDEV ), 0, sizeof(dev_t));
}
- else {
+ else {
memcpy(ad_entry( adp, ADEID_PRIVDEV ), &dev, sizeof(dev_t));
}
ad_setentrylen( adp, ADEID_PRIVINO, sizeof(ino_t));
memcpy(ad_entry( adp, ADEID_PRIVINO ), &ino, sizeof(ino_t));
- ad_setentrylen( adp, ADEID_PRIVID, sizeof(id));
+ ad_setentrylen( adp, ADEID_PRIVID, sizeof(id));
memcpy(ad_entry( adp, ADEID_PRIVID ), &id, sizeof(id));
ad_setentrylen( adp, ADEID_DID, sizeof(did));
/* ----------------------------- */
u_int32_t ad_getid (struct adouble *adp, const dev_t st_dev, const ino_t st_ino , const cnid_t did, const void *stamp)
{
-u_int32_t aint = 0;
-dev_t dev;
-ino_t ino;
-cnid_t a_did;
-char temp[ADEDLEN_PRIVSYN];
+ u_int32_t aint = 0;
+ dev_t dev;
+ ino_t ino;
+ cnid_t a_did;
+ char temp[ADEDLEN_PRIVSYN];
- /* look in AD v2 header
+ /* look in AD v2 header
* note inode and device are opaques and not in network order
* only use the ID if adouble is writable for us.
- */
+ */
if (adp && ( adp->ad_options & ADVOL_CACHE) && ( adp->ad_md->adf_flags & O_RDWR )
- && sizeof(dev_t) == ad_getentrylen(adp, ADEID_PRIVDEV)
- && sizeof(ino_t) == ad_getentrylen(adp,ADEID_PRIVINO)
- && sizeof(temp) == ad_getentrylen(adp,ADEID_PRIVSYN)
- && sizeof(cnid_t) == ad_getentrylen(adp, ADEID_DID)
- && sizeof(cnid_t) == ad_getentrylen(adp, ADEID_PRIVID)
- ) {
+ && sizeof(dev_t) == ad_getentrylen(adp, ADEID_PRIVDEV)
+ && sizeof(ino_t) == ad_getentrylen(adp,ADEID_PRIVINO)
+ && sizeof(temp) == ad_getentrylen(adp,ADEID_PRIVSYN)
+ && sizeof(cnid_t) == ad_getentrylen(adp, ADEID_DID)
+ && sizeof(cnid_t) == ad_getentrylen(adp, ADEID_PRIVID)
+ ) {
memcpy(&dev, ad_entry(adp, ADEID_PRIVDEV), sizeof(dev_t));
memcpy(&ino, ad_entry(adp, ADEID_PRIVINO), sizeof(ino_t));
memcpy(temp, ad_entry(adp, ADEID_PRIVSYN), sizeof(temp));
memcpy(&a_did, ad_entry(adp, ADEID_DID), sizeof(cnid_t));
if ( ((adp->ad_options & ADVOL_NODEV) || dev == st_dev)
- && ino == st_ino && a_did == did
- && !memcmp(stamp, temp, sizeof(temp))) {
+ && ino == st_ino && a_did == did
+ && !memcmp(stamp, temp, sizeof(temp))) {
memcpy(&aint, ad_entry(adp, ADEID_PRIVID), sizeof(aint));
return aint;
}
}
- return 0;
+ return 0;
}
+/* ----------------------------- */
+u_int32_t ad_forcegetid (struct adouble *adp)
+{
+ u_int32_t aint = 0;
+
+ if (adp && ( adp->ad_options & ADVOL_CACHE)
+ && sizeof(dev_t) == ad_getentrylen(adp, ADEID_PRIVDEV)
+ && sizeof(ino_t) == ad_getentrylen(adp,ADEID_PRIVINO)
+ && sizeof(cnid_t) == ad_getentrylen(adp, ADEID_DID)
+ && sizeof(cnid_t) == ad_getentrylen(adp, ADEID_PRIVID)
+ ) {
+ memcpy(&aint, ad_entry(adp, ADEID_PRIVID), sizeof(aint));
+ return aint;
+ }
+ return 0;
+}
#endif
-/* -----------------
+/* -----------------
* set resource fork filename attribute.
-*/
+ */
int ad_setname(struct adouble *ad, const char *path)
{
if (ad_getentryoff(ad, ADEID_NAME)) {