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_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; }