int TfsFile::tfs_open(const char *file_name, const char *suffix, const int32_tmode) { mode_ = mode; //利用文件名计算得到block_id和file_id conv_name(file_name, suffix); int32_t iret = tfs_open(block_id_, file_id_, mode_); if (iret != TFS_SUCCESS) { return iret; }
FSName fsname; fsname.set_cluster_id(session_->get_cluster_id()); fsname.set_block_id(block_id_); fsname.set_file_id(file_id_); //这个有什么用 fsname.set_prefix(suffix); file_id_ = fsname.get_file_id(); strcpy(file_name_, fsname.get_name()); return TFS_SUCCESS; }
int TfsFile::tfs_open(const uint32_t block_id, const uint64_t file_id, constint32_t mode) { if (session_ == NULL) { snprintf(error_message_, ERR_MSG_SIZE, "not set session, session is null"); return TFS_ERROR; } //读模式的话,必须指明block_id if ((block_id == 0) && (mode == READ_MODE || mode == UNLINK_MODE)) { snprintf(error_message_, ERR_MSG_SIZE, "%s no block, block_id(%u) file_id(%" PRI64_PREFIX "u)", file_name_, block_id, file_id); return TFS_ERROR; }
mode_ = mode; block_id_ = block_id; file_id_ = file_id; ds_list_.clear();
if (mode == READ_MODE) { //跟NameServer通信,主要是获取ds_list信息,主要是调用 //TfsSession::get_block_info_ex()函数,加上查询cache的信息 if (session_->get_block_info(block_id_, ds_list_) != TFS_SUCCESS) { //没有可读的DS,返回错误 if (ds_list_.size() == 0) { snprintf(error_message_, ERR_MSG_SIZE, "tfs open fail, block(%u) no exist in nameserver", block_id_); return TFS_ERROR; } } } else if (mode == UNLINK_MODE) { if (session_->get_unlink_block_info(block_id_, ds_list_) != TFS_SUCCESS) { snprintf(error_message_, ERR_MSG_SIZE, "tfs open fail, block(%u) no exist in nameserver", block_id_); return TFS_ERROR; } } //写模式 else { uint32_t current_block_id = block_id_; int32_t flag = BLOCK_WRITE | BLOCK_CREATE; if ((mode_ & NEWBLK_MODE)) { flag |= BLOCK_NEWBLK; } if ((mode_ & NOLEASE_MODE)) { flag |= BLOCK_NOLEASE; } //这里也调用TfsSession::get_block_info_ex,如果对应的文件不存在,则 //NameServer会找到一个可用的block_id返回 if (session_->create_block_info(current_block_id, ds_list_, flag,fail_servers_) != TFS_SUCCESS) { if (ds_list_.size() == 0 || current_block_id == 0) { snprintf(error_message_, ERR_MSG_SIZE, "create block(%u) fail in nameserver", block_id_); return TFS_ERROR; } } //这里的APPED_MODE是如何来判断的,跟block_id==0有什么关系 if (block_id_ == 0) { block_id_ = current_block_id; mode_ |= APPEND_MODE; } } if (block_id_ == 0 || ds_list_.size() == 0) { snprintf(error_message_, ERR_MSG_SIZE, "block(%u),is invalid, dataserver size(%u)", block_id_, static_cast<uint32_t> (ds_list_.size())); return TFS_ERROR; }
if ((mode_ & READ_MODE)) { if (file_id_ == 0) { //TBSYS_LOG(WARN, "blockId(%u) read fileid is 0.", block_id_); } //读模式通过这个方法来选择DS pri_ds_index_ = static_cast<int32_t> (file_id_ % ds_list_.size()); } else { pri_ds_index_ = 0; }
//尝试连接ds_list中的DS,并且选出第一个可连接的DS作为primary DS if (connect_ds() != TFS_SUCCESS) { snprintf(error_message_, ERR_MSG_SIZE, "connect to dataserver fail."); if ((mode_ & APPEND_MODE)) { fail_servers_.push_back(ds_list_[0]); } return TFS_ERROR; }
fail_servers_.clear();
if ((mode_ & WRITE_MODE)) { //这个函数调用client_->call(CreateFileMessage),经过上面connect_ds()的调用, //client_是连到primary DS的客户端,所以这个消息不是发送给NS的 //通过此消息,去primary DS上获取file_number int32_t ret = create_filename(); if (ret != TFS_SUCCESS) { CLIENT_POOL.release_client(client_); TBSYS_LOG(ERROR, "create file name faile(%d)", ret); return ret; } if (file_id_ == 0) { snprintf(error_message_, ERR_MSG_SIZE, "create file name fail,fileid == 0"); CLIENT_POOL.release_client(client_); return TFS_ERROR; } } offset_ = 0; eof_ = TFS_FILE_EOF_FLAG_NO; crc_ = 0; is_open_flag_ = TFS_FILE_OPEN_FLAG_YES; return TFS_SUCCESS; } |