Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
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;
}
Beispiel #4
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;
}