static void
update_md(gpointer data,
          gpointer user_data)
{
        pentry_t *pe = NULL;
        char *path = NULL;
        dpl_ftype_t type;
        dpl_ino_t ino;
        dpl_status_t rc;
        dpl_dict_t *metadata = NULL;
        struct list *dirent = NULL;

        (void)user_data;
        pe = data;
        path = pentry_get_path(pe);

        LOG(LOG_DEBUG, "path=%s", path);

        ino = dpl_cwd(ctx, ctx->cur_bucket);

        rc = dfs_namei_timeout(ctx, path, ctx->cur_bucket,
                               ino, NULL, NULL, &type);

        LOG(LOG_DEBUG, "path=%s, dpl_namei: %s, type=%s",
            path, dpl_status_str(rc), ftype_to_str(type));

        if (DPL_SUCCESS != rc) {
                LOG(LOG_NOTICE, "dfs_namei_timeout: %s", dpl_status_str(rc));
                goto end;
        }

        rc = dfs_getattr_timeout(ctx, path, &metadata);
        if (DPL_SUCCESS != rc && DPL_EISDIR != rc) {
                LOG(LOG_ERR, "dfs_getattr_timeout: %s", dpl_status_str(rc));
                goto end;
        }

        /* If this is a directory, update its entries' metadata */
        if (DPL_FTYPE_DIR == type) {
                dirent = pentry_get_dirents(pe);
                if (dirent)
                        list_map(dirent, cb_map_dirents, pe);
        }

        if (pentry_md_trylock(pe))
                goto end;

        if (metadata)
                pentry_set_metadata(pe, metadata);

        pentry_set_atime(pe);

        (void)pentry_md_unlock(pe);
  end:
        if (metadata)
                dpl_dict_free(metadata);
}
static void
cb_map_dirents(void *elem, void *cb_arg)
{
        char *path = NULL;
        dpl_dict_t *metadata = NULL;
        dpl_status_t rc;
        dpl_ftype_t type;
        dpl_ino_t ino, parent_ino, obj_ino;
        pentry_t *pe_dirent = NULL;
        pentry_t *pe = NULL;

        path = elem;
        pe = cb_arg;

        LOG(LOG_DEBUG, "path='%s', dirent='%s'", path, pentry_get_path(pe));

        pe_dirent = g_hash_table_lookup(hash, path);
        if (! pe_dirent) {
                LOG(LOG_ERR, "'%s' is not an entry anymore in '%s'",
                    path, pentry_get_path(pe));
                goto end;
        }

        rc = dfs_namei_timeout(ctx, path, ctx->cur_bucket,
                               ino, &parent_ino, &obj_ino, &type);

        LOG(LOG_DEBUG, "path=%s, dpl_namei: %s, type=%s, parent_ino=%s, obj_ino=%s",
            path, dpl_status_str(rc), ftype_to_str(type),
            parent_ino.key, obj_ino.key);

        if (DPL_SUCCESS != rc) {
                LOG(LOG_NOTICE, "dfs_namei_timeout: %s", dpl_status_str(rc));
                goto end;
        }

        rc = dfs_getattr_timeout(ctx, path, &metadata);
        if (DPL_SUCCESS != rc && DPL_EISDIR != rc) {
                LOG(LOG_ERR, "dfs_getattr_timeout: %s", dpl_status_str(rc));
                goto end;
        }

        if (pentry_md_trylock(pe_dirent))
                goto end;

        if (metadata)
                pentry_set_metadata(pe_dirent, metadata);

        pentry_set_atime(pe_dirent);

        (void)pentry_md_unlock(pe_dirent);
  end:
        if (metadata)
                dpl_dict_free(metadata);

}
int
dfs_readlink(const char *path,
             char *buf,
             size_t bufsiz)
{
        dpl_dict_t *dict = NULL;
        dpl_status_t rc;
        int ret;
        char *dest = NULL;
        size_t dest_size = 0;

        rc = dfs_getattr_timeout(ctx, path, &dict);
        if (DPL_SUCCESS != rc) {
                LOG(LOG_ERR, "dfs_getattr_timeout: %s", dpl_status_str(rc));
                ret = -1;
                goto err;
        }

        if (! dict) {
                LOG(LOG_ERR, "dpl_getattr: %s", dpl_status_str(rc));
                ret = -1;
                goto err;
        }

        dest = dpl_dict_get_value(dict, "symlink");
        if (! dest) {
                LOG(LOG_ERR, "empty link path");
                ret = -1;
                goto err;
        }

        dest_size = strlen(dest);
        if (dest_size > bufsiz) {
                LOG(LOG_NOTICE, "link length too big: '%s'", dest);
                dest_size = bufsiz;
        }

        if (! strncpy(buf, dest, dest_size)) {
                LOG(LOG_ERR, "path=%s: strcpy: %s", path, strerror(errno));
                ret = -1;
                goto err;
        }

        ret = 0;
  err:
        if (dict)
                dpl_dict_free(dict);

        LOG(LOG_DEBUG, "%s", path);
        return 0;
}
示例#4
0
int
dfs_rename(const char *src,
           const char *dst)
{
        dpl_status_t rc;
        dpl_ftype_t type;
        char *p = NULL;
        int ret = 0;
        tfs_ctx *ctx = fuse_get_context()->private_data;

        LOG(LOG_DEBUG, "src=%s dst=%s", src, dst);

        if (0 == strcmp(dst, ".")) {
                p = strrchr(src, '/');
                dst = p ? p + 1 : src;
        }

        rc = dfs_getattr_timeout(ctx, src, NULL, &type);
        if (! DPL_SUCCESS == rc && (DPL_ENOENT != rc)) {
                LOG(LOG_ERR, "dpl_getattr_timeout: %s", dpl_status_str(rc));
                ret = -1;
                goto err;
        }

        rc = dfs_rename_timeout(ctx, src, dst, type);
        if (DPL_SUCCESS != rc) {
                LOG(LOG_ERR, "dpl_rename_timeout: %s", dpl_status_str(rc));
                ret = rc;
                goto err;
        }

        ret = 0;
  err:
        LOG(LOG_DEBUG, "src=%s dst=%s ret=%s", src, dst, dpl_status_str(ret));
        return ret;
}