int dbd_search(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply)
{
DBT key;
- int rc;
- static char resbuf[DBD_MAX_SRCH_RPLY_PAYLOAD];
+ int results;
+ static char resbuf[DBD_MAX_SRCH_RSLTS * sizeof(cnid_t)];
memset(&key, 0, sizeof(key));
+ rply->name = resbuf;
rply->namelen = 0;
key.data = rqst->name;
key.size = rqst->namelen;
- if ((rc = dbif_del(dbd, DBIF_IDX_DEVINO, &key, 0)) < 0) {
- LOG(log_error, logtype_cnid, "dbd_delete: Unable to delete entry for dev/ino: 0x%llx/0x%llx",
- (unsigned long long)rqst->dev, (unsigned long long)rqst->ino);
+ if ((results = dbif_search(dbd, &key, 0)) < 0) {
+ LOG(log_error, logtype_cnid, "dbd_search(\"%s\"): db error", rqst->name);
rply->result = CNID_DBD_RES_ERR_DB;
return -1;
}
- if (rc) {
- LOG(log_debug, logtype_cnid, "cnid_delete: deleted dev/ino: 0x%llx/0x%llx",
- (unsigned long long)rqst->dev, (unsigned long long)rqst->ino);
+ if (results) {
+ LOG(log_debug, logtype_cnid, "dbd_search(\"%s\"): %d matches", rqst->name, results);
+ rply->namelen = results * sizeof(cnid_t);
rply->result = CNID_DBD_RES_OK;
} else {
- LOG(log_debug, logtype_cnid, "cnid_delete: dev/ino: 0x%llx/0x%llx not in database",
- (unsigned long long)rqst->dev, (unsigned long long)rqst->ino);
+ LOG(log_debug, logtype_cnid, "dbd_search(\"%s\"): no matches", rqst->name);
rply->result = CNID_DBD_RES_NOTFOUND;
}
return 1;
}
-int dbif_search(DBD *dbd, DBT *key, int sindex, char *resbuf, ssize_t bufsize)
+/*!
+ * Search the database by name
+ *
+ * @param resbuf (w) buffer for search results CNIDs, maxsize is assumed to be
+ * DBD_MAX_SRCH_RSLTS * sizefof(cnid_t)
+ *
+ * @returns -1 on error, 0 when nothing found, else the number of matches
+ */
+int dbif_search(DBD *dbd, DBT *key, char *resbuf)
{
- int ret;
- DBC *cursorp;
+ int ret = 0;
+ int count = 0;
+ DBC *cursorp = NULL;
+ DBT pkey, data;
+ char *cnids = resbuf;
+ cnid_t cnid;
+
+ memset(&pkey, 0, sizeof(DBT));
+ memset(&data, 0, sizeof(DBT));
/* Get a cursor */
- dbd->db_table[DBIF_IDX_NAME].db->cursor(dbd->db_table[DBIF_IDX_NAME].db,
- NULL,
- &cursorp,
- 0);
+ ret = dbd->db_table[DBIF_IDX_NAME].db->cursor(dbd->db_table[DBIF_IDX_NAME].db,
+ NULL,
+ &cursorp,
+ 0);
+ if (ret != 0) {
+ LOG(log_error, logtype_cnid, "Couldn't create cursor: %s", db_strerror(ret));
+ ret = -1;
+ goto exit;
+ }
+
+ ret = cursorp->pget(cursorp, key, &pkey, &data, DB_SET_RANGE);
+ while (count < DBD_MAX_SRCH_RSLTS && ret != DB_NOTFOUND) {
+ count++;
+ memcpy(cnids, pkey.data, sizeof(cnid_t));
+ cnids += sizeof(cnid_t);
+ LOG(log_error, logtype_cnid, "match: CNID %" PRIu32, memcpy(&cnid, pkey.data, sizeof(cnid_t)), ntohl(cnid));
+ ret = cursorp->pget(cursorp, key, &pkey, &data, DB_NEXT_DUP);
+ }
- return 1;
+ ret = count;
+
+exit:
+ if (cursorp != NULL)
+ cursorp->close(cursorp);
+ return ret;
}
int dbif_txn_begin(DBD *dbd)
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_search(DBD *dbd, DBT *key, char *resbuf);
extern int dbif_copy_rootinfokey(DBD *srcdbd, DBD *destdbd);
extern int dbif_txn_begin(DBD *);
extern int dbif_txn_commit(DBD *);
#define CNID_DBD_RES_SRCH_CNT 0x05
#define CNID_DBD_RES_SRCH_DONE 0x06
-#define DBD_MAX_SRCH_RPLY_PAYLOAD 4096
+#define DBD_MAX_SRCH_RSLTS 100
struct cnid_dbd_rqst {
int op;
cnid_t cnid;
dev_t dev;
ino_t ino;
- union {
- uint32_t type;
- uint32_t reqcount; /* for dbd_search: number of results per query */
- };
- union {
- cnid_t did;
- uint32_t sindex; /* for dbd_search: continuation index */
- };
+ uint32_t type;
+ cnid_t did;
char *name;
size_t namelen;
};
struct cnid_dbd_rply {
int result;
- union {
- cnid_t cnid;
- uint32_t count; /* for dbd_search: number of returned names */
- };
+ cnid_t cnid;
cnid_t did;
char *name;
size_t namelen;