mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-25 18:40:19 -04:00
Track read-only handle fallback to report accurate write permission errors instead of EBADF
This commit is contained in:
parent
05778a9a46
commit
59f3086841
2 changed files with 27 additions and 0 deletions
|
|
@ -32,6 +32,7 @@ int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, in
|
|||
|
||||
/* initial values, changed later if required */
|
||||
handle->created = 0;
|
||||
handle->readonly_errno = 0;
|
||||
|
||||
/*
|
||||
* Flags for opening
|
||||
|
|
@ -45,8 +46,12 @@ int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, in
|
|||
|
||||
/* if failed for missing write permission */
|
||||
if (handle->f == -1 && (errno == EACCES || errno == EROFS)) {
|
||||
int saved_errno = errno;
|
||||
/* open for read-only */
|
||||
handle->f = open(handle->path, flags | O_RDONLY);
|
||||
if (handle->f != -1) {
|
||||
handle->readonly_errno = saved_errno;
|
||||
}
|
||||
}
|
||||
|
||||
/* if failed for missing file */
|
||||
|
|
@ -109,6 +114,16 @@ int handle_truncate(struct snapraid_handle* handle, struct snapraid_file* file)
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (handle->readonly_errno != 0) {
|
||||
if (file->size == handle->st.st_size)
|
||||
return 0;
|
||||
/* LCOV_EXCL_START */
|
||||
errno = handle->readonly_errno;
|
||||
log_fatal(errno, "Failed to truncate file '%s' for missing write permission. %s.\n", handle->path, strerror(errno));
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
ret = ftruncate(handle->f, file->size);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
|
|
@ -145,6 +160,7 @@ int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, int
|
|||
|
||||
/* for sure not created */
|
||||
handle->created = 0;
|
||||
handle->readonly_errno = 0;
|
||||
|
||||
/*
|
||||
* Flags for opening
|
||||
|
|
@ -220,6 +236,7 @@ int handle_close(struct snapraid_handle* handle)
|
|||
handle->file = 0;
|
||||
handle->f = -1;
|
||||
handle->valid_size = 0;
|
||||
handle->readonly_errno = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -304,6 +321,14 @@ int handle_write(struct snapraid_handle* handle, block_off_t file_pos, unsigned
|
|||
ssize_t count;
|
||||
int ret;
|
||||
|
||||
if (handle->readonly_errno != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
errno = handle->readonly_errno;
|
||||
log_fatal(errno, "Failed to write file '%s' for missing write permission. %s.\n", handle->path, strerror(errno));
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
offset = file_pos * (data_off_t)block_size;
|
||||
|
||||
write_size = file_block_size(handle->file, file_pos, block_size);
|
||||
|
|
@ -390,6 +415,7 @@ struct snapraid_handle* handle_mapping(struct snapraid_state* state, unsigned* h
|
|||
handle[j].file = 0;
|
||||
handle[j].f = -1;
|
||||
handle[j].valid_size = 0;
|
||||
handle[j].readonly_errno = 0;
|
||||
handle[j].bw = 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ struct snapraid_handle {
|
|||
struct advise_struct advise; /**< Advise information. */
|
||||
data_off_t valid_size; /**< Size of the valid data. */
|
||||
int created; /**< If the file was created, otherwise it was already existing. */
|
||||
int readonly_errno; /**< Non-zero if opened read-only as fallback. */
|
||||
struct snapraid_bw* bw; /**< Context for bandwidth limiting. */
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue