Better handling of return value in handle_create().

This commit is contained in:
Andrea Mazzoleni 2013-06-01 22:49:38 +02:00
parent a84bd62ee6
commit 5c0b7d2e6c
3 changed files with 27 additions and 19 deletions

View file

@ -618,7 +618,7 @@ static int state_check_process(struct snapraid_state* state, int check, int fix,
}
/* check if the file was larger and now truncated */
if (ret == 1) {
if (handle[j].truncated != 0) {
fprintf(stdlog, "File '%s' is larger than expected.\n", handle[j].path);
fprintf(stdlog, "error:%u:%s:%s: Size error\n", i, handle[j].disk->name, block_file_get(block)->sub);
++error;

View file

@ -41,33 +41,38 @@ int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, in
return -1;
}
/* initial values, changed later if required */
handle->truncated = 0;
handle->created = 0;
/* open for read write */
/* O_SEQUENTIAL: opening in sequential mode in Windows */
/* O_NOFOLLOW: do not follow links to ensure to open the real file */
flags = O_RDWR | O_BINARY | O_NOFOLLOW;
if (!skip_sequential)
flags |= O_SEQUENTIAL;
handle->created = 0;
handle->f = open(handle->path, flags);
/* if failed for missing file */
if (handle->f == -1 && errno == ENOENT) {
/* retry creating it */
flags |= O_CREAT;
handle->created = 1;
handle->f = open(handle->path, flags, 0600);
}
/* if failed for missing permission */
if (handle->f == -1 && errno == EACCES) {
/* retry without requesting write permission */
flags = O_RDONLY | O_BINARY | O_NOFOLLOW;
if (!skip_sequential)
flags |= O_SEQUENTIAL;
handle->created = 0;
handle->f = open(handle->path, flags);
}
/* if failed for missing file */
if (handle->f == -1 && errno == ENOENT) {
/* retry creating it */
flags = O_RDWR | O_CREAT | O_BINARY | O_NOFOLLOW;
if (!skip_sequential)
flags |= O_SEQUENTIAL;
/* mark it as created */
handle->created = 1;
handle->f = open(handle->path, flags, 0600);
}
if (handle->f == -1) {
/* invalidate for error */
handle->file = 0;
@ -105,6 +110,9 @@ int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, in
return -1;
}
/* mark it as truncated */
handle->truncated = 1;
/* adjust the size to the truncated size */
handle->valid_size = file->size;
}
@ -120,11 +128,6 @@ int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, in
}
#endif
/* return if the file size was truncated */
if (handle->st.st_size > file->size) {
return 1;
}
return 0;
}
@ -140,6 +143,10 @@ int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, FILE
pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub);
/* for sure neither created and truncated */
handle->truncated = 0;
handle->created = 0;
/* open for read */
/* O_SEQUENTIAL: opening in sequential mode in Windows */
/* O_NOFOLLOW: do not follow links to ensure to open the real file */
@ -147,7 +154,6 @@ int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, FILE
flags = O_RDONLY | O_BINARY | O_NOFOLLOW;
if (!skip_sequential)
flags |= O_SEQUENTIAL;
handle->created = 0;
handle->f = open_noatime(handle->path, flags);
if (handle->f == -1) {
/* invalidate for error */

View file

@ -30,14 +30,16 @@ struct snapraid_handle {
int f; /**< Handle of the file. */
struct stat st; /**< Stat info of the opened file. */
data_off_t valid_size; /**< Size of the valid data. */
int created; /**< If the file was created, or it was already existing. */
int created; /**< If the file was created, otherwise it was already existing. */
int truncated; /**< If the file was truncated. */
};
/**
* Creates a file.
* The file is created if missing, and opened with write access.
* If the file has a different size than expected, it's enlarged or truncated to the correct size.
* If the file is truncated 1 is returned.
* If the file is created, the handle->created is set.
* If the file is truncated, the handle->truncated is set.
* The initial size of the file is stored in the file->st struct.
* If the file cannot be opened for write access, it's opened with read-only access.
* The read-only access works only if the file has already the correct size and doesn't need to be modified.