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);

}
Exemple #3
0
int
dfs_create(const char *path,
           mode_t mode,
           struct fuse_file_info *info)
{
        tfs_ctx *ctx = fuse_get_context()->private_data;
        int ret = -1;
        dpl_status_t rc = DPL_FAILURE;
        tpath_entry *pe = NULL;
        struct stat st;
        dpl_dict_t *usermd = NULL;
        int exclude;

        LOG(LOG_DEBUG, "%s, mode=0x%x, %s",
            path, (unsigned)mode, flags_to_str(info->flags));

        if (! S_ISREG(mode)) {
                LOG(LOG_ERR, "%s: not a regular file", path);
                ret = -1;
                goto err;
        }

        exclude = re_matcher(&ctx->conf->regex, path);

        if (-1 == dfs_open(path, info)) {
                ret = -1;
                goto err;
        }

        pe = (tpath_entry *) info->fh;
        if (! pe) {
                ret = -1;
                goto err;
        }

        pe->exclude = exclude;

        if (-1 == pe->fd) {
                ret = -1;
                goto err;
        }

        if (-1 == fchmod(pe->fd, mode)) {
                LOG(LOG_ERR, "fchmod(fd=%d): %s", pe->fd, strerror(errno));
                ret = -errno;
                goto err;
        }

        if (-1 == fstat(pe->fd, &st)) {
                LOG(LOG_ERR, "fstat(fd=%d): %s", pe->fd, strerror(errno));
                ret = -errno;
                goto err;
        }

        usermd = pe->usermd;
        if (! usermd) {
                usermd = dpl_dict_new(13);
                if (! usermd) {
                        LOG(LOG_ERR, "allocation failure");
                        ret = -1;
                        goto err;
                }
        }

        fill_metadata_from_stat(usermd, &st);

        assign_meta_to_dict(usermd, "scal_mode", (unsigned long) mode);

        pentry_md_lock(pe);
        pentry_set_usermd(pe, usermd);
        pentry_md_unlock(pe);

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

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

        LOG(LOG_DEBUG, "path=%s ret=%s", path, dpl_status_str(ret));
        return ret;

}