int trunk_file_delete(const char *trunk_filename, \ const FDFSTrunkFullInfo *pTrunkInfo) { char pack_buff[FDFS_TRUNK_FILE_HEADER_SIZE]; char buff[64 * 1024]; int fd; int write_bytes; int result; int remain_bytes; FDFSTrunkHeader trunkHeader; fd = open(trunk_filename, O_WRONLY); if (fd < 0) { return errno != 0 ? errno : EIO; } if (lseek(fd, pTrunkInfo->file.offset, SEEK_SET) < 0) { result = errno != 0 ? errno : EIO; close(fd); return result; } memset(&trunkHeader, 0, sizeof(trunkHeader)); trunkHeader.alloc_size = pTrunkInfo->file.size; trunkHeader.file_type = FDFS_TRUNK_FILE_TYPE_NONE; trunk_pack_header(&trunkHeader, pack_buff); write_bytes = write(fd, pack_buff, FDFS_TRUNK_FILE_HEADER_SIZE); if (write_bytes != FDFS_TRUNK_FILE_HEADER_SIZE) { result = errno != 0 ? errno : EIO; close(fd); return result; } memset(buff, 0, sizeof(buff)); result = 0; remain_bytes = pTrunkInfo->file.size - FDFS_TRUNK_FILE_HEADER_SIZE; while (remain_bytes > 0) { write_bytes = remain_bytes > sizeof(buff) ? \ sizeof(buff) : remain_bytes; if (write(fd, buff, write_bytes) != write_bytes) { result = errno != 0 ? errno : EIO; break; } remain_bytes -= write_bytes; } close(fd); return result; }
int dio_check_trunk_file_ex(int fd, const char *filename, const int64_t offset) { int result; char old_header[FDFS_TRUNK_FILE_HEADER_SIZE]; char expect_header[FDFS_TRUNK_FILE_HEADER_SIZE]; if (fc_safe_read(fd, old_header, FDFS_TRUNK_FILE_HEADER_SIZE) != FDFS_TRUNK_FILE_HEADER_SIZE) { result = errno != 0 ? errno : EIO; logError("file: "__FILE__", line: %d, " \ "read trunk header of file: %s fail, " \ "errno: %d, error info: %s", \ __LINE__, filename, \ result, STRERROR(result)); return result; } memset(expect_header, 0, sizeof(expect_header)); if (memcmp(old_header, expect_header, \ FDFS_TRUNK_FILE_HEADER_SIZE) != 0) { FDFSTrunkHeader srcOldTrunkHeader; FDFSTrunkHeader newOldTrunkHeader; trunk_unpack_header(old_header, &srcOldTrunkHeader); memcpy(&newOldTrunkHeader, &srcOldTrunkHeader, \ sizeof(FDFSTrunkHeader)); newOldTrunkHeader.alloc_size = 0; newOldTrunkHeader.file_size = 0; newOldTrunkHeader.file_type = 0; trunk_pack_header(&newOldTrunkHeader, old_header); if (memcmp(old_header, expect_header, \ FDFS_TRUNK_FILE_HEADER_SIZE) != 0) { char buff[256]; trunk_header_dump(&srcOldTrunkHeader, \ buff, sizeof(buff)); logError("file: "__FILE__", line: %d, " \ "trunk file: %s, offset: " \ "%"PRId64" already occupied" \ " by other file, trunk header info: %s"\ , __LINE__, filename, offset, buff); return EEXIST; } } return 0; }
int trunk_file_do_lstat_func_ex(const FDFSStorePaths *pStorePaths, \ const int store_path_index, const char *true_filename, \ const int filename_len, const int stat_func, \ struct stat *pStat, FDFSTrunkFullInfo *pTrunkInfo, \ FDFSTrunkHeader *pTrunkHeader, int *pfd) { char full_filename[MAX_PATH_SIZE]; char buff[128]; char pack_buff[FDFS_TRUNK_FILE_HEADER_SIZE]; int64_t file_size; int buff_len; int fd; int read_bytes; int result; pTrunkInfo->file.id = 0; if (filename_len != FDFS_TRUNK_FILENAME_LENGTH) //not trunk file { snprintf(full_filename, sizeof(full_filename), "%s/data/%s", \ pStorePaths->paths[store_path_index], true_filename); if (stat_func == FDFS_STAT_FUNC_STAT) { result = stat(full_filename, pStat); } else { result = lstat(full_filename, pStat); } if (result == 0) { return 0; } else { return errno != 0 ? errno : ENOENT; } } memset(buff, 0, sizeof(buff)); base64_decode_auto(&g_fdfs_base64_context, (char *)true_filename + \ FDFS_TRUE_FILE_PATH_LEN, FDFS_FILENAME_BASE64_LENGTH, \ buff, &buff_len); file_size = buff2long(buff + sizeof(int) * 2); if (!IS_TRUNK_FILE(file_size)) //slave file { snprintf(full_filename, sizeof(full_filename), "%s/data/%s", \ pStorePaths->paths[store_path_index], true_filename); if (stat_func == FDFS_STAT_FUNC_STAT) { result = stat(full_filename, pStat); } else { result = lstat(full_filename, pStat); } if (result == 0) { return 0; } else { return errno != 0 ? errno : ENOENT; } } trunk_file_info_decode(true_filename + FDFS_TRUE_FILE_PATH_LEN + \ FDFS_FILENAME_BASE64_LENGTH, &pTrunkInfo->file); pTrunkHeader->file_size = FDFS_TRUNK_FILE_TRUE_SIZE(file_size); pTrunkHeader->mtime = buff2int(buff + sizeof(int)); pTrunkHeader->crc32 = buff2int(buff + sizeof(int) * 4); memcpy(pTrunkHeader->formatted_ext_name, true_filename + \ (filename_len - (FDFS_FILE_EXT_NAME_MAX_LEN + 1)), \ FDFS_FILE_EXT_NAME_MAX_LEN + 2); //include tailing '\0' pTrunkHeader->alloc_size = pTrunkInfo->file.size; pTrunkInfo->path.store_path_index = store_path_index; pTrunkInfo->path.sub_path_high = strtol(true_filename, NULL, 16); pTrunkInfo->path.sub_path_low = strtol(true_filename + 3, NULL, 16); trunk_get_full_filename_ex(pStorePaths, pTrunkInfo, full_filename, \ sizeof(full_filename)); fd = open(full_filename, O_RDONLY); if (fd < 0) { return errno != 0 ? errno : EIO; } if (lseek(fd, pTrunkInfo->file.offset, SEEK_SET) < 0) { result = errno != 0 ? errno : EIO; close(fd); return result; } read_bytes = read(fd, buff, FDFS_TRUNK_FILE_HEADER_SIZE); if (read_bytes == FDFS_TRUNK_FILE_HEADER_SIZE) { result = 0; } else { result = errno; close(fd); return result != 0 ? result : EINVAL; } memset(pStat, 0, sizeof(struct stat)); pTrunkHeader->file_type = *(buff + FDFS_TRUNK_FILE_FILE_TYPE_OFFSET); if (pTrunkHeader->file_type == FDFS_TRUNK_FILE_TYPE_REGULAR) { pStat->st_mode = S_IFREG; } else if (pTrunkHeader->file_type == FDFS_TRUNK_FILE_TYPE_LINK) { pStat->st_mode = S_IFLNK; } else if (pTrunkHeader->file_type == FDFS_TRUNK_FILE_TYPE_NONE) { close(fd); return ENOENT; } else { close(fd); logError("file: "__FILE__", line: %d, " \ "Invalid file type: %d", __LINE__, \ pTrunkHeader->file_type); return ENOENT; } trunk_pack_header(pTrunkHeader, pack_buff); /* { char temp[265]; char szHexBuff[2 * FDFS_TRUNK_FILE_HEADER_SIZE + 1]; FDFSTrunkHeader trueTrunkHeader; fprintf(stderr, "file: "__FILE__", line: %d, true buff=%s\n", __LINE__, \ bin2hex(buff+1, FDFS_TRUNK_FILE_HEADER_SIZE - 1, szHexBuff)); trunk_unpack_header(buff, &trueTrunkHeader); fprintf(stderr, "file: "__FILE__", line: %d, true fields=%s\n", __LINE__, \ trunk_header_dump(&trueTrunkHeader, full_filename, sizeof(full_filename))); fprintf(stderr, "file: "__FILE__", line: %d, my buff=%s\n", __LINE__, \ bin2hex(pack_buff+1, FDFS_TRUNK_FILE_HEADER_SIZE - 1, szHexBuff)); fprintf(stderr, "file: "__FILE__", line: %d, my trunk=%s, my fields=%s\n", __LINE__, \ trunk_info_dump(pTrunkInfo, temp, sizeof(temp)), \ trunk_header_dump(pTrunkHeader, full_filename, sizeof(full_filename))); } */ if (memcmp(pack_buff, buff, FDFS_TRUNK_FILE_HEADER_SIZE) != 0) { close(fd); return ENOENT; } pStat->st_size = pTrunkHeader->file_size; pStat->st_mtime = pTrunkHeader->mtime; if (pfd != NULL) { *pfd = fd; } else { close(fd); } return 0; }
int dio_write_chunk_header(struct fast_task_info *pTask) { StorageFileContext *pFileContext; char header[FDFS_TRUNK_FILE_HEADER_SIZE]; FDFSTrunkHeader trunkHeader; int result; pFileContext = &(((StorageClientInfo *)pTask->arg)->file_context); if (pFileContext->extra_info.upload.file_type & _FILE_TYPE_LINK) { trunkHeader.file_type = FDFS_TRUNK_FILE_TYPE_LINK; } else { trunkHeader.file_type = FDFS_TRUNK_FILE_TYPE_REGULAR; } trunkHeader.alloc_size = pFileContext->extra_info.upload.trunk_info.file.size; trunkHeader.file_size = pFileContext->end - pFileContext->start; trunkHeader.crc32 = pFileContext->crc32; trunkHeader.mtime = pFileContext->extra_info.upload.start_time; snprintf(trunkHeader.formatted_ext_name, \ sizeof(trunkHeader.formatted_ext_name), "%s", \ pFileContext->extra_info.upload.formatted_ext_name); if (lseek(pFileContext->fd, pFileContext->start - \ FDFS_TRUNK_FILE_HEADER_SIZE, SEEK_SET) < 0) { result = errno != 0 ? errno : EIO; logError("file: "__FILE__", line: %d, " \ "lseek file: %s fail, " \ "errno: %d, error info: %s", \ __LINE__, pFileContext->filename, \ result, STRERROR(result)); return result; } trunk_pack_header(&trunkHeader, header); /* { char buff1[256]; char buff2[256]; char buff3[1024]; trunk_header_dump(&trunkHeader, buff3, sizeof(buff3)); logInfo("file: "__FILE__", line: %d, my trunk=%s, my fields=%s", __LINE__, \ trunk_info_dump(&pFileContext->extra_info.upload.trunk_info, buff1, sizeof(buff1)), \ trunk_header_dump(&trunkHeader, buff2, sizeof(buff2))); } */ if (fc_safe_write(pFileContext->fd, header, FDFS_TRUNK_FILE_HEADER_SIZE) != \ FDFS_TRUNK_FILE_HEADER_SIZE) { result = errno != 0 ? errno : EIO; logError("file: "__FILE__", line: %d, " \ "write to file: %s fail, " \ "errno: %d, error info: %s", \ __LINE__, pFileContext->filename, \ result, STRERROR(result)); return result; } return 0; }