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