ngx_chain_t * ngx_http_tfs_meta_server_create_message(ngx_http_tfs_t *t) { uint16_t msg_type; ngx_chain_t *cl; cl = NULL; msg_type = t->r_ctx.action.code; switch (msg_type) { case NGX_HTTP_TFS_ACTION_CREATE_DIR: case NGX_HTTP_TFS_ACTION_CREATE_FILE: ngx_log_error(NGX_LOG_DEBUG, t->log, 0, "will create path: last_dir_level: %i, dir_len: %i, last_file_path: %V", t->last_dir_level, t->last_file_path.len, &t->last_file_path); cl = ngx_http_tfs_create_action_message(t, &t->last_file_path, NULL); break; case NGX_HTTP_TFS_ACTION_MOVE_DIR: case NGX_HTTP_TFS_ACTION_MOVE_FILE: cl = ngx_http_tfs_create_action_message(t, &t->r_ctx.file_path_s, &t->last_file_path); break; case NGX_HTTP_TFS_ACTION_REMOVE_DIR: cl = ngx_http_tfs_create_action_message(t, &t->r_ctx.file_path_s, NULL); break; case NGX_HTTP_TFS_ACTION_READ_FILE: cl = ngx_http_tfs_create_read_meta_message(t, t->file.file_offset, t->file.left_length); break; case NGX_HTTP_TFS_ACTION_WRITE_FILE: switch (t->state) { case NGX_HTTP_TFS_STATE_WRITE_CLUSTER_ID_MS: cl = ngx_http_tfs_create_read_meta_message(t, 0, 0); break; case NGX_HTTP_TFS_STATE_WRITE_WRITE_MS: cl = ngx_http_tfs_create_write_meta_message(t); break; } break; case NGX_HTTP_TFS_ACTION_REMOVE_FILE: switch (t->state) { case NGX_HTTP_TFS_STATE_REMOVE_GET_FRAG_INFO: cl = ngx_http_tfs_create_read_meta_message(t, t->file.file_offset, t->file.left_length); break; case NGX_HTTP_TFS_STATE_REMOVE_NOTIFY_MS: cl = ngx_http_tfs_create_action_message(t, &t->r_ctx.file_path_s, NULL); break; } break; case NGX_HTTP_TFS_ACTION_LS_DIR: case NGX_HTTP_TFS_ACTION_LS_FILE: t->json_output = ngx_http_tfs_json_init(t->log, t->pool); if (t->json_output == NULL) { return NULL; } cl = ngx_http_tfs_create_ls_message(t); break; } return cl; }
ngx_int_t ngx_http_tfs_process_ms(ngx_http_tfs_t *t) { ngx_buf_t *b; ngx_int_t rc, dir_levels, parent_dir_len; ngx_chain_t *cl, **ll; ngx_http_tfs_header_t *header; ngx_http_tfs_peer_connection_t *tp; ngx_http_tfs_logical_cluster_t *logical_cluster; ngx_http_tfs_physical_cluster_t *physical_cluster; header = (ngx_http_tfs_header_t *) t->header; tp = t->tfs_peer; b = &tp->body_buffer; if (ngx_buf_size(b) < header->len) { return NGX_AGAIN; } rc = ngx_http_tfs_meta_server_parse_message(t); if (rc == NGX_ERROR) { return NGX_ERROR; } b->pos += header->len; /* need update meta table */ if (rc == NGX_HTTP_TFS_EXIT_LEASE_EXPIRED || rc == NGX_HTTP_TFS_EXIT_TABLE_VERSION_ERROR) { t->state = NGX_HTTP_TFS_STATE_ACTION_GET_META_TABLE; ngx_http_tfs_clear_buf(b); ngx_http_tfs_peer_set_addr(t->pool, &t->tfs_peer_servers[NGX_HTTP_TFS_ROOT_SERVER], (ngx_http_tfs_inet_t *)&t->loc_conf->meta_root_server); ngx_log_error(NGX_LOG_DEBUG, t->log, 0, "need update meta table, rc: %i", rc); return NGX_OK; } /* parent dir not exist, recursive create them */ if (rc == NGX_HTTP_TFS_EXIT_PARENT_EXIST_ERROR && t->r_ctx.recursive) { switch (t->r_ctx.action.code) { case NGX_HTTP_TFS_ACTION_CREATE_DIR: case NGX_HTTP_TFS_ACTION_CREATE_FILE: case NGX_HTTP_TFS_ACTION_MOVE_DIR: case NGX_HTTP_TFS_ACTION_MOVE_FILE: if (t->dir_lens == NULL) { parent_dir_len = ngx_http_tfs_get_parent_dir(&t->last_file_path, &dir_levels); t->dir_lens = ngx_pcalloc(t->pool, sizeof(ngx_int_t) * dir_levels); if (t->dir_lens == NULL) { return NGX_ERROR; } t->last_dir_level = 0; t->dir_lens[0] = t->last_file_path.len; } else { parent_dir_len = ngx_http_tfs_get_parent_dir(&t->last_file_path, NULL); } t->last_dir_level++; t->dir_lens[t->last_dir_level] = parent_dir_len; t->last_file_path.len = t->dir_lens[t->last_dir_level]; t->orig_action = t->r_ctx.action.code; /* temporarily modify */ t->r_ctx.action.code = NGX_HTTP_TFS_ACTION_CREATE_DIR; return NGX_OK; } } /* parent dir may be created by others * during the recursive creating process */ if (rc == NGX_HTTP_TFS_EXIT_TARGET_EXIST_ERROR && t->last_dir_level > 0) { rc = NGX_OK; } if (rc == NGX_OK || rc == NGX_DECLINED) { switch (t->r_ctx.action.code) { case NGX_HTTP_TFS_ACTION_CREATE_DIR: case NGX_HTTP_TFS_ACTION_CREATE_FILE: case NGX_HTTP_TFS_ACTION_MOVE_DIR: case NGX_HTTP_TFS_ACTION_MOVE_FILE: if (t->dir_lens != NULL) { if (t->last_dir_level > 0) { if (t->last_dir_level == 1) { t->r_ctx.action.code = t->orig_action; } t->last_file_path.len = t->dir_lens[--(t->last_dir_level)]; return NGX_OK; } } case NGX_HTTP_TFS_ACTION_REMOVE_DIR: t->state = NGX_HTTP_TFS_STATE_ACTION_DONE; return NGX_DONE; case NGX_HTTP_TFS_ACTION_REMOVE_FILE: switch (t->state) { case NGX_HTTP_TFS_STATE_REMOVE_GET_FRAG_INFO: if (rc == NGX_DECLINED) { t->state = NGX_HTTP_TFS_STATE_REMOVE_NOTIFY_MS; ngx_http_tfs_clear_buf(b); return NGX_OK; } t->state = NGX_HTTP_TFS_STATE_REMOVE_GET_BLK_INFO; break; case NGX_HTTP_TFS_STATE_REMOVE_NOTIFY_MS: t->state = NGX_HTTP_TFS_STATE_REMOVE_DONE; return NGX_DONE; } break; case NGX_HTTP_TFS_ACTION_LS_FILE: if (t->r_ctx.chk_exist == NGX_HTTP_TFS_NO && t->meta_info.file_count > 0) { /* need json output */ for (cl = t->out_bufs, ll = &t->out_bufs; cl; cl = cl->next) { ll = &cl->next; } cl = ngx_http_tfs_json_custom_file_info(t->json_output, &t->meta_info, t->r_ctx.file_type); if (cl == NULL) { return NGX_ERROR; } *ll = cl; } t->state = NGX_HTTP_TFS_STATE_ACTION_DONE; return NGX_DONE; case NGX_HTTP_TFS_ACTION_READ_FILE: if (rc == NGX_DECLINED || (t->r_ctx.chk_file_hole && !t->file.still_have)) { if (t->r_ctx.chk_file_hole) { /* need json output */ if (t->file_holes.nelts > 0) { t->json_output = ngx_http_tfs_json_init(t->log, t->pool); if (t->json_output == NULL) { return NGX_ERROR; } for (cl = t->out_bufs, ll = &t->out_bufs; cl; cl = cl->next) { ll = &cl->next; } cl = ngx_http_tfs_json_file_hole_info(t->json_output, &t->file_holes); if (cl == NULL) { return NGX_ERROR; } *ll = cl; } } t->state = NGX_HTTP_TFS_STATE_READ_DONE; return NGX_DONE; } if (t->r_ctx.chk_file_hole) { ngx_http_tfs_clear_buf(b); return NGX_OK; } t->state = NGX_HTTP_TFS_STATE_READ_GET_BLK_INFO; break; case NGX_HTTP_TFS_ACTION_WRITE_FILE: switch (t->state) { case NGX_HTTP_TFS_STATE_WRITE_CLUSTER_ID_MS: t->state = NGX_HTTP_TFS_STATE_WRITE_CLUSTER_ID_NS; break; case NGX_HTTP_TFS_STATE_WRITE_WRITE_MS: if (t->file.left_length == 0) { t->state = NGX_HTTP_TFS_STATE_WRITE_DONE; return NGX_DONE; } t->state = NGX_HTTP_TFS_STATE_WRITE_GET_BLK_INFO; } break; default: return NGX_ERROR; } /* NGX_OK */ /* only select once */ if (t->name_server_addr_text.len == 0) { rc = ngx_http_tfs_select_name_server(t, t->rc_info_node, &t->name_server_addr, &t->name_server_addr_text); if (rc == NGX_ERROR) { /* in order to return 404 */ return NGX_HTTP_TFS_EXIT_SERVER_OBJECT_NOT_FOUND; } ngx_http_tfs_peer_set_addr(t->pool, &t->tfs_peer_servers[NGX_HTTP_TFS_NAME_SERVER], &t->name_server_addr); /* skip get cluster id from ns */ if (t->r_ctx.action.code == NGX_HTTP_TFS_ACTION_WRITE_FILE && t->state == NGX_HTTP_TFS_STATE_WRITE_CLUSTER_ID_NS) { logical_cluster = &t->rc_info_node->logical_clusters[t->logical_cluster_index]; physical_cluster = &logical_cluster->rw_clusters[t->rw_cluster_index]; if (physical_cluster->cluster_id > 0) { if (t->file.cluster_id == 0) { t->file.cluster_id = physical_cluster->cluster_id; } else if (t->file.cluster_id != physical_cluster->cluster_id) { ngx_log_error(NGX_LOG_ERR, t->log, 0, "error, cluster id conflict: " "%uD(ns) <> %uD(ms)", physical_cluster->cluster_id, t->file.cluster_id); return NGX_ERROR; } t->state = NGX_HTTP_TFS_STATE_WRITE_GET_BLK_INFO; } } } if (t->r_ctx.action.code == NGX_HTTP_TFS_ACTION_READ_FILE) { /* lookup block cache */ t->block_cache_ctx.curr_lookup_cache = NGX_HTTP_TFS_LOCAL_BLOCK_CACHE; t->decline_handler = ngx_http_tfs_batch_lookup_block_cache; return NGX_DECLINED; } return NGX_OK; } return rc; }