[Sheepdog] [RFC] [PATCH] journaling support for atomic operations
MORITA Kazutaka
morita.kazutaka at lab.ntt.co.jp
Tue Nov 23 19:12:34 CET 2010
At Mon, 22 Nov 2010 22:55:11 +0530,
Narendra Prasad Madanapalli wrote:
>
> Hi,
>
> This patch adds journalling support for sheepdog that can aid in
> performing atomic operations.
Great!
> +#define JRNL_PATH "/journal/"
> +
> +static int jrnl_init_path(const char *base_path)
> +{
> + int new, ret;
> +
> + /* Create journal directory */
> + jrnl_path = zalloc(strlen(base_path) + strlen(JRNL_PATH) + 1);
> + sprintf(jrnl_path, "%s" JRNL_PATH, base_path);
> +
> + ret = init_path(jrnl_path, &new);
> + /* Error during directory creation */
> + if (ret)
> + return ret;
> + /* If journal is newly created */
> + if (new)
> + return 0;
> +
> + return 0;
> +}
Other functions to initialize directories are named
init_[target]_path(), so this function name should be
init_jrnl_path()?
> +
> +int jrnl_write_end_mark(jrnl_desc_t *jd)
> +{
> + ssize_t ret;
> + end_mark_t end_mark = 1;
The value of end_mark should be defined as a macro, and it should be
more complex value.
> +
> + ret = pwrite64(jd->jdf_fd, &end_mark, sizeof(end_mark),
> + sizeof(jd->jd_head) + jd->jdh_size);
> +
> + if (ret != sizeof(end_mark)) {
> + if (errno == ENOSPC)
> + ret = SD_RES_NO_SPACE;
> + else
> + ret = SD_RES_EIO;
> + } else
> + ret = SD_RES_SUCCESS;
> +
> + return ret;
> +}
> +
> +
> +int jrnl_apply_to_targe_vdi_object(jrnl_file_desc_t *jfd)
> +{
> + char path[1024], *buf;
> + int buf_len, res = 0, ret;
> + ssize_t retsize;
> + jrnl_head_t jh;
> +
> + /* FIXME: handle larger size */
> + buf_len = (1 << 22);
> + buf = zalloc(buf_len);
> + if (!buf) {
> + eprintf("failed to allocate memory\n");
> + res = SD_RES_NO_MEM;
> + goto out;
> + }
> +
> + /* Open journal */
> + snprintf(path, sizeof(path), "%s%08u/%016" PRIx64, jrnl_path,
> jfd->jf_epoch, jfd->jf_oid);
> + ret = jrnl_open(jfd, O_RDONLY);
> + if (ret) {
> + res = SD_RES_EIO;
> + goto freemem;
> + }
> +
> + /* Flush out journal to disk (vdi object) */
> + retsize = pread64(jfd->jf_fd, &jh, sizeof(jh), 0);
> + retsize = pread64(jfd->jf_fd, buf, jh.jh_size, sizeof(jh));
We should check that the journal has an end mark here.
> + retsize = pwrite64(jfd->jf_vdi_fd, buf, jh.jh_size, jh.jh_offset);
> +
> + /* Clean up */
> + close(jfd->jf_fd);
> + jfd->jf_fd = 0;
> +freemem:
> + free(buf);
> +out:
> + return res;
> +}
> +
> +int jrnl_writte_data_to_targe_vdi_object(jrnl_file_desc_t *jfd, void *data)
> +{
> + //
> + // FIXME: Need to implement this function
> + //
> +
> + return 0;
> +}
What's the difference between jrnl_apply_to_targe_vdi_object() and
jrnl_write_data_to_target_vdi_object()? When do we use
jrnl_write_data_to_target_vdi_object()?
> +
> +int jrnl_recover_vdis()
> +{
> + DIR *dir;
> + struct dirent *d;
> + char jrnl_dir[1024], jrnl_file_path[1024];
> + int epoch;
> +
> + epoch = get_latest_epoch();
> + if (epoch < 0) {
> + return 1;
> + }
> + snprintf(jrnl_dir, sizeof(jrnl_dir), "%s%08u", jrnl_path, epoch);
> +
> + dir = opendir(jrnl_dir);
> + if (!dir)
> + return -1;
> +
> + /* TODO: Not complete as error handling to be added */
> + while ((d = readdir(dir))) {
> + jrnl_file_desc_t jfd;
> + jfd.jf_oid = atoi(d->d_name);
> + snprintf(jrnl_file_path, sizeof(jrnl_file_path), "%s%016" PRIx64,
> jrnl_dir, jfd.jf_oid);
> + jrnl_open(&jfd, O_RDONLY);
> + jrnl_apply_to_targe_vdi_object(&jfd);
> + }
> + closedir(dir);
> +
> + return 0;
> +}
> +
I think the followings are not implemented yet, yes?
- remove a journal file when it becomes unnecessary
- apply journal data before accessing a vdi object if the journal file
exists
Thanks,
Kazutaka
More information about the sheepdog
mailing list