コード例 #1
0
ファイル: tdb.c プロジェクト: atlant2011/samba
enum TDB_ERROR tdb_parse_record_(struct tdb_context *tdb,
				 TDB_DATA key,
				 enum TDB_ERROR (*parse)(TDB_DATA k,
							 TDB_DATA d,
							 void *data),
				 void *data)
{
	tdb_off_t off;
	struct tdb_used_record rec;
	struct hash_info h;
	enum TDB_ERROR ecode;

	if (tdb->flags & TDB_VERSION1) {
		return tdb->last_error = tdb1_parse_record(tdb, key, parse,
							   data);
	}

	off = find_and_lock(tdb, key, F_RDLCK, &h, &rec, NULL);
	if (TDB_OFF_IS_ERR(off)) {
		return tdb->last_error = TDB_OFF_TO_ERR(off);
	}

	if (!off) {
		ecode = TDB_ERR_NOEXIST;
	} else {
		const void *dptr;
		dptr = tdb_access_read(tdb, off + sizeof(rec) + key.dsize,
				       rec_data_length(&rec), false);
		if (TDB_PTR_IS_ERR(dptr)) {
			ecode = TDB_PTR_ERR(dptr);
		} else {
			TDB_DATA d = tdb_mkdata(dptr, rec_data_length(&rec));

			ecode = parse(key, d, data);
			tdb_access_release(tdb, dptr);
		}
	}

	tdb_unlock_hashes(tdb, h.hlock_start, h.hlock_range, F_RDLCK);
	return tdb->last_error = ecode;
}
コード例 #2
0
ファイル: tdb1_tdb.c プロジェクト: ekohl/samba
/* update an entry in place - this only works if the new data size
   is <= the old data size and the key exists.
   on failure return -1.
*/
static int tdb1_update_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, TDB_DATA dbuf)
{
	struct tdb1_record rec;
	tdb1_off_t rec_ptr;

	/* find entry */
	if (!(rec_ptr = tdb1_find(tdb, key, hash, &rec)))
		return -1;

	/* it could be an exact duplicate of what is there - this is
	 * surprisingly common (eg. with a ldb re-index). */
	if (rec.key_len == key.dsize &&
	    rec.data_len == dbuf.dsize &&
	    rec.full_hash == hash &&
	    tdb1_parse_record(tdb, key, tdb_update_hash_cmp, &dbuf) == 0) {
			return 0;
	}

	/* must be long enough key, data and tailer */
	if (rec.rec_len < key.dsize + dbuf.dsize + sizeof(tdb1_off_t)) {
		tdb->last_error = TDB_SUCCESS; /* Not really an error */
		return -1;
	}

	if (tdb->tdb1.io->tdb1_write(tdb, rec_ptr + sizeof(rec) + rec.key_len,
		      dbuf.dptr, dbuf.dsize) == -1)
		return -1;

	if (dbuf.dsize != rec.data_len) {
		/* update size */
		rec.data_len = dbuf.dsize;
		return tdb1_rec_write(tdb, rec_ptr, &rec);
	}

	return 0;
}