mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 10:51:54 -04:00
Uses Windows API for reading/writing to improve error detection and reporting.
This commit is contained in:
parent
aeb167bb16
commit
e2c269fcdf
4 changed files with 227 additions and 20 deletions
1
HISTORY
1
HISTORY
|
|
@ -3,6 +3,7 @@ SnapRAID HISTORY
|
|||
|
||||
3.1 2013/4
|
||||
==========
|
||||
* Diret use of Windows API for disk access to improve error reporting.
|
||||
|
||||
3.0 2013/3
|
||||
==========
|
||||
|
|
|
|||
209
mingw.c
209
mingw.c
|
|
@ -333,15 +333,6 @@ static void windows_info2stat(const BY_HANDLE_FILE_INFORMATION* info, const FILE
|
|||
st->st_desc = "regular-dedup";
|
||||
}
|
||||
break;
|
||||
/* All the other are skipped as reparse-point */
|
||||
case IO_REPARSE_TAG_MOUNT_POINT :
|
||||
st->st_mode = S_IFCHR;
|
||||
st->st_desc = "reparse-point-mount";
|
||||
break;
|
||||
case IO_REPARSE_TAG_NFS :
|
||||
st->st_mode = S_IFCHR;
|
||||
st->st_desc = "reparse-point-nfs";
|
||||
break;
|
||||
case IO_REPARSE_TAG_SYMLINK :
|
||||
if ((info->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
|
||||
st->st_mode = S_IFLNKDIR;
|
||||
|
|
@ -351,6 +342,15 @@ static void windows_info2stat(const BY_HANDLE_FILE_INFORMATION* info, const FILE
|
|||
st->st_desc = "reparse-point-symlink-file";
|
||||
}
|
||||
break;
|
||||
/* All the other are skipped as reparse-point */
|
||||
case IO_REPARSE_TAG_MOUNT_POINT :
|
||||
st->st_mode = S_IFCHR;
|
||||
st->st_desc = "reparse-point-mount";
|
||||
break;
|
||||
case IO_REPARSE_TAG_NFS :
|
||||
st->st_mode = S_IFCHR;
|
||||
st->st_desc = "reparse-point-nfs";
|
||||
break;
|
||||
default:
|
||||
st->st_mode = S_IFCHR;
|
||||
st->st_desc = "reparse-point";
|
||||
|
|
@ -426,15 +426,6 @@ static void windows_finddata2stat(const WIN32_FIND_DATAW* info, struct windows_s
|
|||
st->st_desc = "regular-dedup";
|
||||
}
|
||||
break;
|
||||
/* All the other are skipped as reparse-point */
|
||||
case IO_REPARSE_TAG_MOUNT_POINT :
|
||||
st->st_mode = S_IFCHR;
|
||||
st->st_desc = "reparse-point-mount";
|
||||
break;
|
||||
case IO_REPARSE_TAG_NFS :
|
||||
st->st_mode = S_IFCHR;
|
||||
st->st_desc = "reparse-point-nfs";
|
||||
break;
|
||||
case IO_REPARSE_TAG_SYMLINK :
|
||||
if ((info->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
|
||||
st->st_mode = S_IFLNKDIR;
|
||||
|
|
@ -444,6 +435,15 @@ static void windows_finddata2stat(const WIN32_FIND_DATAW* info, struct windows_s
|
|||
st->st_desc = "reparse-point-symlink-file";
|
||||
}
|
||||
break;
|
||||
/* All the other are skipped as reparse-point */
|
||||
case IO_REPARSE_TAG_MOUNT_POINT :
|
||||
st->st_mode = S_IFCHR;
|
||||
st->st_desc = "reparse-point-mount";
|
||||
break;
|
||||
case IO_REPARSE_TAG_NFS :
|
||||
st->st_mode = S_IFCHR;
|
||||
st->st_desc = "reparse-point-nfs";
|
||||
break;
|
||||
default:
|
||||
st->st_mode = S_IFCHR;
|
||||
st->st_desc = "reparse-point";
|
||||
|
|
@ -1069,5 +1069,178 @@ const char* windows_strerror(int err)
|
|||
return last_error;
|
||||
}
|
||||
|
||||
ssize_t windows_read(int fd, void* buffer, size_t size)
|
||||
{
|
||||
HANDLE h;
|
||||
DWORD count;
|
||||
|
||||
if (fd == -1) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
h = (HANDLE)_get_osfhandle(fd);
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!ReadFile(h, buffer, size, &count, 0)) {
|
||||
windows_errno(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
ssize_t windows_write(int fd, const void* buffer, size_t size)
|
||||
{
|
||||
HANDLE h;
|
||||
DWORD count;
|
||||
|
||||
if (fd == -1) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
h = (HANDLE)_get_osfhandle(fd);
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!WriteFile(h, buffer, size, &count, 0)) {
|
||||
windows_errno(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
off_t windows_lseek(int fd, off_t offset, int whence)
|
||||
{
|
||||
HANDLE h;
|
||||
LARGE_INTEGER pos;
|
||||
LARGE_INTEGER ret;
|
||||
|
||||
if (fd == -1) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* we support only SEEK_SET */
|
||||
if (whence != SEEK_SET) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
h = (HANDLE)_get_osfhandle(fd);
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pos.QuadPart = offset;
|
||||
if (!SetFilePointerEx(h, pos, &ret, FILE_BEGIN)) {
|
||||
windows_errno(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret.QuadPart;
|
||||
}
|
||||
|
||||
ssize_t windows_pread(int fd, void* buffer, size_t size, off_t offset)
|
||||
{
|
||||
HANDLE h;
|
||||
LARGE_INTEGER pos;
|
||||
DWORD count;
|
||||
|
||||
if (fd == -1) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
h = (HANDLE)_get_osfhandle(fd);
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
retry:
|
||||
pos.QuadPart = offset;
|
||||
if (!SetFilePointerEx(h, pos, 0, FILE_BEGIN)) {
|
||||
windows_errno(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!ReadFile(h, buffer, size, &count, 0)) {
|
||||
DWORD err = GetLastError();
|
||||
/*
|
||||
* If Windows is not able to allocate memory pages for the disk cache
|
||||
* it could return the ERROR_NO_SYSTEM_RESOURCES error.
|
||||
* In this case, the only possibility is to retry after a wait of few milliseconds.
|
||||
*
|
||||
* See:
|
||||
* SQL Server reports operating system error 1450 or 1452 or 665 (retries)
|
||||
* http://blogs.msdn.com/b/psssql/archive/2008/07/10/sql-server-reports-operating-system-error-1450-or-1452-or-665-retries.aspx
|
||||
*
|
||||
* 03-12-09 - ERROR_NO_SYSTEM_RESOURCES
|
||||
* http://cbloomrants.blogspot.it/2009/03/03-12-09-errornosystemresources.html
|
||||
*
|
||||
* SnapRAID Help Forum: Error reading file
|
||||
* https://sourceforge.net/projects/snapraid/forums/forum/1677233/topic/7273746
|
||||
*/
|
||||
if (err == ERROR_NO_SYSTEM_RESOURCES) {
|
||||
fprintf(stderr, "Unexpected Windows ERROR_NO_SYSTEM_RESOURCES in pread(), retrying...\n");
|
||||
Sleep(50);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
windows_errno(err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
ssize_t windows_pwrite(int fd, const void* buffer, size_t size, off_t offset)
|
||||
{
|
||||
HANDLE h;
|
||||
LARGE_INTEGER pos;
|
||||
DWORD count;
|
||||
|
||||
if (fd == -1) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
h = (HANDLE)_get_osfhandle(fd);
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
retry:
|
||||
pos.QuadPart = offset;
|
||||
if (!SetFilePointerEx(h, pos, 0, FILE_BEGIN)) {
|
||||
windows_errno(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!WriteFile(h, buffer, size, &count, 0)) {
|
||||
DWORD err = GetLastError();
|
||||
if (err == ERROR_NO_SYSTEM_RESOURCES) {
|
||||
fprintf(stderr, "Unexpected Windows ERROR_NO_SYSTEM_RESOURCES in pwrite(), retrying...\n");
|
||||
Sleep(50);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
windows_errno(err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
35
mingw.h
35
mingw.h
|
|
@ -35,7 +35,6 @@
|
|||
#define stat windows_stat
|
||||
#define lstat windows_lstat
|
||||
#define off_t off64_t
|
||||
#define lseek lseek64
|
||||
#define fstat windows_fstat
|
||||
#define HAVE_FTRUNCATE 1
|
||||
#define ftruncate windows_ftruncate
|
||||
|
|
@ -63,12 +62,19 @@
|
|||
#define S_ISLNK(m) (((m) & _S_IFMT) == S_IFLNK)
|
||||
#define S_IFLNKDIR 0x6000 /* Symbolic link to directory */
|
||||
#define S_ISLNKDIR(m) (((m) & _S_IFMT) == S_IFLNKDIR)
|
||||
#define S_IFJUN 0x6000 /* Junction */
|
||||
#define S_IFJUN 0x7000 /* Junction */
|
||||
#define S_ISJUN(m) (((m) & _S_IFMT) == S_IFJUN)
|
||||
#define readlink windows_readlink
|
||||
#define symlink windows_symlink
|
||||
#define link windows_link
|
||||
#define strerror windows_strerror
|
||||
#define read windows_read
|
||||
#define write windows_write
|
||||
#define lseek windows_lseek
|
||||
#define HAVE_PREAD 1
|
||||
#define HAVE_PWRITE 1
|
||||
#define pread windows_pread
|
||||
#define pwrite windows_pwrite
|
||||
|
||||
/* We have nano second support */
|
||||
#define STAT_NSEC(st) (st)->st_mtimensec
|
||||
|
|
@ -256,6 +262,31 @@ int windows_link(const char* existing, const char* file);
|
|||
*/
|
||||
const char* windows_strerror(int err);
|
||||
|
||||
/**
|
||||
* Like read().
|
||||
*/
|
||||
ssize_t windows_read(int f, void* buffer, size_t size);
|
||||
|
||||
/**
|
||||
* Like write().
|
||||
*/
|
||||
ssize_t windows_write(int f, const void* buffer, size_t size);
|
||||
|
||||
/**
|
||||
* Like lseek().
|
||||
*/
|
||||
off_t windows_lseek(int f, off_t offset, int whence);
|
||||
|
||||
/**
|
||||
* Like pread().
|
||||
*/
|
||||
ssize_t windows_pread(int f, void* buffer, size_t size, off_t offset);
|
||||
|
||||
/**
|
||||
* Like pwrite().
|
||||
*/
|
||||
ssize_t windows_pwrite(int f, const void* buffer, size_t size, off_t offset);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
|||
2
util.c
2
util.c
|
|
@ -49,7 +49,9 @@ static unsigned strdecset[256] =
|
|||
|
||||
STREAM* sopen_read(const char* file)
|
||||
{
|
||||
#if HAVE_POSIX_FADVISE
|
||||
int ret;
|
||||
#endif
|
||||
STREAM* s = malloc_nofail(sizeof(STREAM));
|
||||
|
||||
s->handle_size = 1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue