Beispiel #1
0
static void sfree_pool(struct pool *pool, void *ptr)
{
	struct block_hdr *hdr;
	unsigned int i, idx;
	unsigned long offset;

	if (!ptr)
		return;

	ptr -= sizeof(*hdr);
	hdr = ptr;

	assert(ptr_valid(pool, ptr));

	sfree_check_redzone(hdr);

	offset = ptr - pool->map;
	i = offset / SMALLOC_BPL;
	idx = (offset % SMALLOC_BPL) / SMALLOC_BPB;

	fio_mutex_down(pool->lock);
	clear_blocks(pool, i, idx, size_to_blocks(hdr->size));
	if (i < pool->next_non_full)
		pool->next_non_full = i;
	pool->free_blocks += size_to_blocks(hdr->size);
	fio_mutex_up(pool->lock);
}
Beispiel #2
0
int mingw_fstat(int fd, struct mingw_stat *buf)
{
	HANDLE fh = (HANDLE)_get_osfhandle(fd);
	BY_HANDLE_FILE_INFORMATION fdata;

	if (fh == INVALID_HANDLE_VALUE) {
		errno = EBADF;
		return -1;
	}
	/* direct non-file handles to MS's fstat() */
	if (GetFileType(fh) != FILE_TYPE_DISK) {
		struct stat st;
		if (fstat(fd, &st))
			return -1;
		buf->st_ino = st.st_ino;
		buf->st_gid = st.st_gid;
		buf->st_uid = st.st_uid;
		buf->st_mode = st.st_mode;
		buf->st_size = st.st_size;
		buf->st_blocks = size_to_blocks(buf->st_size);
		buf->st_dev = st.st_dev;
		buf->st_atime = st.st_atime;
		buf->st_mtime = st.st_mtime;
		buf->st_ctime = st.st_ctime;
		return 0;
	}

	if (GetFileInformationByHandle(fh, &fdata)) {
		int fMode = S_IREAD;
		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			fMode |= S_IFDIR;
		else
			fMode |= S_IFREG;
		if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
			fMode |= S_IWRITE;

		buf->st_ino = 0;
		buf->st_gid = 0;
		buf->st_uid = 0;
		buf->st_mode = fMode;
		buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not a stat64 */
		buf->st_blocks = size_to_blocks(buf->st_size);
		buf->st_dev = _getdrive() - 1;
		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
		return 0;
	}
	errno = EBADF;
	return -1;
}
Beispiel #3
0
static void *__smalloc_pool(struct pool *pool, size_t size)
{
	size_t nr_blocks;
	unsigned int i;
	unsigned int offset;
	unsigned int last_idx;
	void *ret = NULL;

	fio_mutex_down(pool->lock);

	nr_blocks = size_to_blocks(size);
	if (nr_blocks > pool->free_blocks)
		goto fail;

	i = pool->next_non_full;
	last_idx = 0;
	offset = -1U;
	while (i < pool->nr_blocks) {
		unsigned int idx;

		if (pool->bitmap[i] == -1U) {
			i++;
			pool->next_non_full = i;
			last_idx = 0;
			continue;
		}

		idx = find_next_zero(pool->bitmap[i], last_idx);
		if (!blocks_free(pool, i, idx, nr_blocks)) {
			idx += nr_blocks;
			if (idx < SMALLOC_BPI)
				last_idx = idx;
			else {
				last_idx = 0;
				while (idx >= SMALLOC_BPI) {
					i++;
					idx -= SMALLOC_BPI;
				}
			}
			continue;
		}
		set_blocks(pool, i, idx, nr_blocks);
		offset = i * SMALLOC_BPL + idx * SMALLOC_BPB;
		break;
	}

	if (i < pool->nr_blocks) {
		pool->free_blocks -= nr_blocks;
		ret = pool->map + offset;
	}
fail:
	fio_mutex_up(pool->lock);
	return ret;
}
Beispiel #4
0
/* do_stat is a common implementation for cygwin_lstat and cygwin_stat.
 *
 * To simplify its logic, in the case of cygwin symlinks, this implementation
 * falls back to the cygwin version of stat/lstat, which is provided as the
 * last argument.
 */
static int do_stat(const char *file_name, struct stat *buf, stat_fn_t cygstat)
{
	WIN32_FILE_ATTRIBUTE_DATA fdata;

	if (file_name[0] == '/')
		return cygstat (file_name, buf);

	if (!(errno = get_file_attr(file_name, &fdata))) {
		/*
		 * If the system attribute is set and it is not a directory then
		 * it could be a symbol link created in the nowinsymlinks mode.
		 * Normally, Cygwin works in the winsymlinks mode, so this situation
		 * is very unlikely. For the sake of simplicity of our code, let's
		 * Cygwin to handle it.
		 */
		if ((fdata.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) &&
		    !(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
			return cygstat(file_name, buf);

		/* fill out the stat structure */
		buf->st_dev = buf->st_rdev = 0; /* not used by Git */
		buf->st_ino = 0;
		buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
		buf->st_nlink = 1;
		buf->st_uid = buf->st_gid = 0;
#ifdef __CYGWIN_USE_BIG_TYPES__
		buf->st_size = ((_off64_t)fdata.nFileSizeHigh << 32) +
			fdata.nFileSizeLow;
#else
		buf->st_size = (off_t)fdata.nFileSizeLow;
#endif
		buf->st_blocks = size_to_blocks(buf->st_size);
		filetime_to_timespec(&fdata.ftLastAccessTime, &buf->st_atim);
		filetime_to_timespec(&fdata.ftLastWriteTime, &buf->st_mtim);
		filetime_to_timespec(&fdata.ftCreationTime, &buf->st_ctim);
		return 0;
	} else if (errno == ENOENT) {
		/*
		 * In the winsymlinks mode (which is the default), Cygwin
		 * emulates symbol links using Windows shortcut files. These
		 * files are formed by adding .lnk extension. So, if we have
		 * not found the specified file name, it could be that it is
		 * a symbol link. Let's Cygwin to deal with that.
		 */
		return cygstat(file_name, buf);
	}
	return -1;
}
Beispiel #5
0
/* We keep the do_lstat code in a separate function to avoid recursion.
 * When a path ends with a slash, the stat will fail with ENOENT. In
 * this case, we strip the trailing slashes and stat again.
 */
static int do_lstat(const char *file_name, struct stat *buf)
{
	WIN32_FILE_ATTRIBUTE_DATA fdata;

	if (GetFileAttributesExA(file_name, GetFileExInfoStandard, &fdata)) {
		int fMode = S_IREAD;
		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			fMode |= S_IFDIR;
		else
			fMode |= S_IFREG;
		if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
			fMode |= S_IWRITE;

		buf->st_ino = 0;
		buf->st_gid = 0;
		buf->st_uid = 0;
		buf->st_mode = fMode;
		buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not a stat64 */
		buf->st_blocks = size_to_blocks(buf->st_size);
		buf->st_dev = _getdrive() - 1;
		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
		errno = 0;
		return 0;
	}

	switch (GetLastError()) {
	case ERROR_ACCESS_DENIED:
	case ERROR_SHARING_VIOLATION:
	case ERROR_LOCK_VIOLATION:
	case ERROR_SHARING_BUFFER_EXCEEDED:
		errno = EACCES;
		break;
	case ERROR_BUFFER_OVERFLOW:
		errno = ENAMETOOLONG;
		break;
	case ERROR_NOT_ENOUGH_MEMORY:
		errno = ENOMEM;
		break;
	default:
		errno = ENOENT;
		break;
	}
	return -1;
}