diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-08-05 06:27:16 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-08-05 06:27:16 -0400 |
commit | cdac8a5c4ad0cbcc3a610bbbe768dbe06936bae1 (patch) | |
tree | 536ba98f9972ca86013cd3f57c0d0be52152995b | |
parent | 7bac7f9d97e8ffab884370e8e776f072914c9eab (diff) | |
download | dbfs-cdac8a5c4ad0cbcc3a610bbbe768dbe06936bae1.tar.gz |
To reduce unnecessary RMW cycles, permit partial pointers (offset, length)
to a hash-indexed binary buffer.
-rw-r--r-- | dbfs-backend.c | 67 | ||||
-rw-r--r-- | dbfs.h | 5 |
2 files changed, 36 insertions, 36 deletions
diff --git a/dbfs-backend.c b/dbfs-backend.c index 4310a04..a75670a 100644 --- a/dbfs-backend.c +++ b/dbfs-backend.c @@ -23,12 +23,6 @@ struct dbfs_dirscan_info { void *end_ent; }; -struct dbfs_ext_list { - dbfs_blk_id_t id; /* block id */ - guint64 off; /* offset into block */ - guint64 len; /* length of fragment */ -}; - int dbmeta_del(const char *key_str) { DBT key; @@ -598,11 +592,12 @@ static void ext_list_free(GList *ext_list) g_list_free(ext_list); } -static int dbfs_ext_match(struct dbfs_inode *ino, guint64 off, guint64 rd_size, +static int dbfs_ext_match(struct dbfs_inode *ino, guint64 off, guint32 rd_size, GList **ext_list_out) { - struct dbfs_ext_list *el; - guint64 pos, size, ext_list_want, bytes = 0; + struct dbfs_extent *ext; + guint64 pos; + guint32 ext_len, ext_off, ext_list_want, bytes = 0; GList *ext_list = *ext_list_out; gboolean in_frag; unsigned int i; @@ -612,47 +607,51 @@ static int dbfs_ext_match(struct dbfs_inode *ino, guint64 off, guint64 rd_size, in_frag = FALSE; ext_list_want = rd_size; for (i = 0; i < ino->n_extents; i++) { - size = GUINT64_FROM_LE(ino->raw_inode->blocks[i].size); + ext_len = GUINT32_FROM_LE(ino->raw_inode->blocks[i].len); + ext_off = GUINT32_FROM_LE(ino->raw_inode->blocks[i].off); + + if ((!in_frag) && ((pos + ext_len) > off)) { + guint32 skip; - if ((!in_frag) && ((pos + size) > off)) { - el = g_new(struct dbfs_ext_list, 1); - if (!el) { + ext = g_new(struct dbfs_extent, 1); + if (!ext) { rc = -ENOMEM; goto err_out; } - memcpy(&el->id, &ino->raw_inode->blocks[i].id, + memcpy(&ext->id, &ino->raw_inode->blocks[i].id, sizeof(dbfs_blk_id_t)); - el->off = off - pos; - el->len = MIN(size - el->off, ext_list_want); + skip = off - pos; + ext->off = skip + ext_off; + ext->len = MIN(ext_len - skip, ext_list_want); - ext_list = g_list_append(ext_list, el); - ext_list_want -= el->len; - bytes += el->len; + ext_list = g_list_append(ext_list, ext); + ext_list_want -= ext->len; + bytes += ext->len; in_frag = TRUE; } else if (in_frag) { - el = g_new(struct dbfs_ext_list, 1); - if (!el) { + ext = g_new(struct dbfs_extent, 1); + if (!ext) { rc = -ENOMEM; goto err_out; } - memcpy(&el->id, &ino->raw_inode->blocks[i].id, + memcpy(&ext->id, &ino->raw_inode->blocks[i].id, sizeof(dbfs_blk_id_t)); - el->off = 0; - el->len = MIN(size, ext_list_want); + ext->off = ext_off; + ext->len = MIN(ext_len, ext_list_want); - ext_list = g_list_append(ext_list, el); - ext_list_want -= el->len; - bytes += el->len; + ext_list = g_list_append(ext_list, ext); + ext_list_want -= ext->len; + bytes += ext->len; if (ext_list_want == 0) break; } - pos += size; + pos += ext_len; } *ext_list_out = ext_list; @@ -714,18 +713,18 @@ int dbfs_read(guint64 ino_n, guint64 off, size_t read_req_size, tmp = ext_list; while (tmp) { - struct dbfs_ext_list *el; + struct dbfs_extent *ext; void *frag; size_t fraglen; - el = tmp->data; - rc = dbfs_ext_read(&el->id, &frag, &fraglen); + ext = tmp->data; + rc = dbfs_ext_read(&ext->id, &frag, &fraglen); if (rc) { free(buf); buf = NULL; goto out_list; } - if ((el->off + el->len) > fraglen) { + if ((ext->off + ext->len) > fraglen) { free(frag); free(buf); buf = NULL; @@ -733,10 +732,10 @@ int dbfs_read(guint64 ino_n, guint64 off, size_t read_req_size, goto out_list; } - memcpy(buf + pos, frag + el->off, el->len); + memcpy(buf + pos, frag + ext->off, ext->len); free(frag); - pos += el->len; + pos += ext->len; tmp = tmp->next; } @@ -62,8 +62,9 @@ struct dbfs_xlist { } __attribute__ ((packed)); struct dbfs_extent { - dbfs_blk_id_t id; - guint64 size; + guint32 off; /* offset into block */ + guint32 len; /* length of fragment */ + dbfs_blk_id_t id; /* block id */ } __attribute__ ((packed)); struct dbfs_raw_inode { |