[Patch 1/1] chunkd: split up fs_list_objs
This way we create a set of methods that can be used by self-check
to list existing objects.
Signed-off-by: Pete Zaitcev <zaitcev@xxxxxxxxxx>
---
server/be-fs.c | 361 +++++++++++++++++++++++++++++-----------------
server/chunkd.h | 16 ++
2 files changed, 244 insertions(+), 133 deletions(-)
commit cbc71b0262fa3594be940d8a758873f746c410e7
Author: Master <zaitcev@xxxxxxxxxxxxxxxxxx>
Date: Sun Dec 27 15:35:13 2009 -0700
Add methods with which a self-check can list objects later.
diff --git a/server/be-fs.c b/server/be-fs.c
index 89635f8..1f8f1a5 100644
--- a/server/be-fs.c
+++ b/server/be-fs.c
@@ -689,168 +689,263 @@ err_out:
return false;
}
-GList *fs_list_objs(uint32_t table_id, const char *user)
+int fs_list_objs_open(struct fs_obj_lister *t,
+ const char *root_path, uint32_t table_id)
{
- GList *res = NULL;
- struct dirent *de, *root_de;
- DIR *d, *root;
- char *sub, *table_path = NULL;
+ int err;
- sub = alloca(strlen(chunkd_srv.vol_path) + 1 + 16 + 4 + 1);
+ if (asprintf(&t->table_path, MDB_TPATH_FMT, root_path, table_id) < 0)
+ return -ENOMEM;
+ t->root = opendir(t->table_path);
+ if (!t->root) {
+ err = errno;
+ free(t->table_path);
+ return -err;
+ }
+ return 0;
+}
- if (asprintf(&table_path, MDB_TPATH_FMT,
- chunkd_srv.vol_path, table_id) < 0)
- return NULL;
+/*
+ * Get next filename.
+ * Return:
+ * -1 - error
+ * 0 - EOF
+ * 1 - ok
+ */
+int fs_list_objs_next(struct fs_obj_lister *t, char **fnp)
+{
+ struct dirent *de;
- root = opendir(table_path);
- if (!root) {
- syslogerr(table_path);
- free(table_path);
- return NULL;
- }
+again:
+ if (!t->sub) {
+ if ((de = readdir(t->root)) == NULL)
+ return 0;
- /* iterate through each dir */
- while ((root_de = readdir(root)) != NULL) {
+ if (de->d_name[0] == '.')
+ goto again;
+ if (strlen(de->d_name) != 4)
+ goto again;
- if (root_de->d_name[0] == '.')
- continue;
- if (strlen(root_de->d_name) != 4)
- continue;
+ if (asprintf(&t->sub, "%s/%s", t->table_path, de->d_name) < 0)
+ return -1;
+ }
- sprintf(sub, "%s/%s", table_path, root_de->d_name);
- d = opendir(sub);
- if (!d) {
- syslogerr(sub);
- break;
+ if (!t->d) {
+ t->d = opendir(t->sub);
+ if (!t->d) {
+ syslogerr(t->sub);
+ free(t->sub);
+ t->sub = NULL;
+ goto again;
}
+ }
- while ((de = readdir(d)) != NULL) {
- int fd;
- char *fn;
- ssize_t rrc;
- struct be_fs_obj_hdr hdr;
- struct stat st;
- struct volume_entry *ve;
- void *p;
- size_t alloc_len;
- void *key_in;
- uint32_t key_len_in;
-
- if (de->d_name[0] == '.')
- continue;
-
- if (asprintf(&fn, "%s/%s", sub, de->d_name) < 0)
- break;
-
- fd = open(fn, O_RDONLY);
- if (fd < 0) {
- syslogerr(fn);
- free(fn);
- break;
- }
+ if ((de = readdir(t->d)) == NULL) {
+ closedir(t->d);
+ t->d = NULL;
+ free(t->sub);
+ t->sub = NULL;
+ goto again;
+ }
- if (fstat(fd, &st) < 0) {
- syslogerr(fn);
- close(fd);
- free(fn);
- break;
- }
+ if (de->d_name[0] == '.')
+ goto again;
- rrc = read(fd, &hdr, sizeof(hdr));
- if (rrc != sizeof(hdr)) {
- if (rrc < 0)
- syslogerr(fn);
- else
- applog(LOG_ERR, "%s hdr read failed", fn);
- close(fd);
- free(fn);
- break;
- }
+ if (asprintf(fnp, "%s/%s", t->sub, de->d_name) < 0)
+ return -1;
- key_len_in = GUINT32_FROM_LE(hdr.key_len);
- if (key_len_in < 1 || key_len_in > CHD_KEY_SZ) {
- applog(LOG_ERR, "%s hdr key len invalid", fn);
- close(fd);
- free(fn);
- break;
- }
+ return 1;
+}
- key_in = malloc(key_len_in);
- if (!key_in) {
- close(fd);
- free(fn);
- break;
- }
+void fs_list_objs_close(struct fs_obj_lister *t)
+{
+ closedir(t->root);
+ free(t->table_path);
- rrc = read(fd, key_in, key_len_in);
- if (rrc != key_len_in) {
- if (rrc < 0)
- syslogerr(fn);
- else
- applog(LOG_ERR, "%s hdr read failed", fn);
- close(fd);
- free(fn);
- free(key_in);
- break;
- }
+ if (t->d)
+ closedir(t->d);
+ free(t->sub);
+}
- if (close(fd) < 0)
- syslogerr(fn);
+GList *fs_list_objs(uint32_t table_id, const char *user)
+{
+ struct fs_obj_lister lister;
+ GList *res = NULL;
+ char *fn;
+ int rc;
+
+ memset(&lister, 0, sizeof(struct fs_obj_lister));
+ rc = fs_list_objs_open(&lister, chunkd_srv.vol_path, table_id);
+ if (rc) {
+ applog(LOG_WARNING, "Cannot open table %u: %s", table_id,
+ strerror(-rc));
+ return NULL;
+ }
+ while (fs_list_objs_next(&lister, &fn) > 0) {
+ char *owner;
+ char *csum;
+ unsigned long long size;
+ time_t mtime;
+ struct volume_entry *ve;
+ void *p;
+ size_t alloc_len;
+ void *key_in;
+ size_t klen_in;
+
+ rc = fs_obj_hdr_read(fn, &owner, &csum, &key_in, &klen_in,
+ &size, &mtime);
+ if (rc < 0) {
free(fn);
+ break;
+ }
+ free(fn);
+
+ /* filter out results that do not match
+ * the authenticated user
+ */
+ if (strcmp(user, owner)) {
+ free(owner);
+ free(csum);
+ free(key_in);
+ continue;
+ }
- /* filter out results that do not match
- * the authenticated user
- */
- if (strcmp(user, hdr.owner)) {
- free(key_in);
- continue;
- }
+ /* one alloc, for fixed + var length struct */
+ alloc_len = sizeof(*ve) + strlen(csum) + 1 + strlen(owner) + 1;
- /* one alloc, for fixed + var length struct */
- alloc_len = sizeof(*ve) +
- strlen(hdr.checksum) + 1 +
- strlen(hdr.owner) + 1;
+ ve = malloc(alloc_len);
+ if (!ve) {
+ free(owner);
+ free(csum);
+ free(key_in);
+ applog(LOG_ERR, "OOM");
+ break;
+ }
- ve = malloc(alloc_len);
- if (!ve) {
- free(key_in);
- applog(LOG_ERR, "OOM");
- break;
- }
+ /* store fixed-length portion of struct */
+ ve->size = size;
+ ve->mtime = mtime;
+ ve->key = key_in;
+ ve->key_len = klen_in;
- /* store fixed-length portion of struct */
- st.st_size -= sizeof(struct be_fs_obj_hdr);
- st.st_size -= key_len_in;
+ /*
+ * store variable-length portion of struct:
+ * checksum, owner strings
+ */
- ve->size = st.st_size;
- ve->mtime = st.st_mtime;
- ve->key = key_in;
- ve->key_len = key_len_in;
+ p = (ve + 1);
+ ve->hash = p;
+ strcpy(ve->hash, csum);
- /*
- * store variable-length portion of struct:
- * checksum, owner strings
- */
+ p += strlen(ve->hash) + 1;
+ ve->owner = p;
+ strcpy(ve->owner, owner);
- p = (ve + 1);
- ve->hash = p;
- strcpy(ve->hash, hdr.checksum);
+ /* add entry to result list */
+ res = g_list_append(res, ve);
- p += strlen(ve->hash) + 1;
- ve->owner = p;
- strcpy(ve->owner, hdr.owner);
+ free(owner);
+ free(csum);
+ }
- /* add entry to result list */
- res = g_list_append(res, ve);
- }
+ fs_list_objs_close(&lister);
+ return res;
+}
+
+/*
+ * Read an object by filename.
+ * TODO - possibly factor out some code from fs_obj_open and fs_obj_delete.
+ */
+int fs_obj_hdr_read(const char *fn, char **owner, char **csum,
+ void **keyp, size_t *klenp,
+ unsigned long long *size, time_t *mtime)
+{
+ struct be_fs_obj_hdr hdr;
+ struct stat st;
+ int fd;
+ ssize_t rrc;
+ void *key_in;
+ size_t klen_in;
+ unsigned long long sz;
- closedir(d);
+ fd = open(fn, O_RDONLY);
+ if (fd < 0) {
+ syslogerr(fn);
+ goto err_open;
}
- closedir(root);
+ if (fstat(fd, &st) < 0) {
+ syslogerr(fn);
+ goto err_stat;
+ }
- free(table_path);
- return res;
+ rrc = read(fd, &hdr, sizeof(hdr));
+ if (rrc != sizeof(hdr)) {
+ if (rrc < 0)
+ syslogerr(fn);
+ else
+ applog(LOG_WARNING, "%s hdr read failed", fn);
+ goto err_fix;
+ }
+
+ klen_in = GUINT32_FROM_LE(hdr.key_len);
+ if (klen_in < 1 || klen_in > CHD_KEY_SZ) {
+ applog(LOG_WARNING, "%s hdr key len (0x%x) invalid",
+ fn, (unsigned int)klen_in);
+ goto err_fix;
+ }
+
+ key_in = malloc(klen_in);
+ if (!key_in) {
+ applog(LOG_WARNING, "NO CORE");
+ goto err_fix;
+ }
+
+ rrc = read(fd, key_in, klen_in);
+ if (rrc != klen_in) {
+ if (rrc < 0)
+ syslogerr(fn);
+ else
+ applog(LOG_ERR, "%s hdr short read (%lu)",
+ fn, (unsigned long)rrc);
+ goto err_var;
+ }
+
+ *owner = strndup(hdr.owner, sizeof(hdr.owner));
+ if (!*owner) {
+ applog(LOG_WARNING, "NO CORE");
+ goto err_owner;
+ }
+ *csum = strndup(hdr.checksum, sizeof(hdr.checksum));
+ if (!*csum) {
+ applog(LOG_WARNING, "NO CORE");
+ goto err_csum;
+ }
+
+ *keyp = key_in;
+ *klenp = klen_in;
+
+ sz = st.st_size;
+ if (sz < klen_in + sizeof(struct be_fs_obj_hdr))
+ sz = 0;
+ else
+ sz = st.st_size - (sizeof(struct be_fs_obj_hdr) + klen_in);
+ *size = sz;
+ *mtime = st.st_mtime;
+
+ close(fd);
+ return 0;
+
+ err_csum:
+ free(*owner);
+ err_owner:
+ err_var:
+ free(key_in);
+ err_fix:
+ err_stat:
+ close(fd);
+ err_open:
+ return -1;
}
diff --git a/server/chunkd.h b/server/chunkd.h
index 57726fd..a97088d 100644
--- a/server/chunkd.h
+++ b/server/chunkd.h
@@ -217,6 +217,15 @@ struct server {
extern struct hail_log cldu_hail_log;
/* be-fs.c */
+#include <dirent.h>
+struct fs_obj_lister {
+ DIR *root;
+ char *table_path;
+
+ DIR *d;
+ char *sub;
+};
+
extern int fs_open(void);
extern void fs_close(void);
extern void fs_free(void);
@@ -234,6 +243,13 @@ extern bool fs_obj_delete(uint32_t table_id, const char *user,
const void *kbuf, size_t klen,
enum chunk_errcode *err_code);
extern ssize_t fs_obj_sendfile(struct backend_obj *bo, int out_fd, size_t len);
+extern int fs_list_objs_open(struct fs_obj_lister *t,
+ const char *root_path, uint32_t table_id);
+extern int fs_list_objs_next(struct fs_obj_lister *t, char **fnp);
+extern void fs_list_objs_close(struct fs_obj_lister *t);
+extern int fs_obj_hdr_read(const char *fn, char **owner, char **checksum,
+ void **keyp, size_t *klenp,
+ unsigned long long *size, time_t *mtime);
extern GList *fs_list_objs(uint32_t table_id, const char *user);
extern bool fs_table_open(const char *user, const void *kbuf, size_t klen,
bool tbl_creat, bool excl_creat, uint32_t *table_id,
--
To unsubscribe from this list: send the line "unsubscribe hail-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
[Linux USB Devel]
[Video for Linux]
[Linux Audio Users]
[Photo]
[Yosemite News]
[Yosemite Photos]
[Free Online Dating]
[Linux Kernel]
[Linux SCSI]
[XFree86]