From 2d6528fe90e6876f6d06abc7bdebc64a5f3ba0cc Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Sun, 4 Nov 2012 00:26:30 +0100 Subject: [PATCH] If O_NOATIME use fails with EPERM, retry without it. --- check.c | 2 +- handle.c | 16 +++++++++------- parity.c | 6 ++++-- portable.h | 15 +++++++++++---- 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/check.c b/check.c index 37967b91..06531c4c 100644 --- a/check.c +++ b/check.c @@ -1002,7 +1002,7 @@ static int state_check_process(struct snapraid_state* state, int check, int fix, } /* create it */ - /* do not follow links to ensure to open the real file */ + /* O_NOFOLLOW: do not follow links to ensure to open the real file */ f = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_NOFOLLOW, 0600); if (f == -1) { fprintf(stderr, "Error creating empty file '%s'. %s.\n", path, strerror(errno)); diff --git a/handle.c b/handle.c index aaa5d07f..46bbf9ee 100644 --- a/handle.c +++ b/handle.c @@ -80,14 +80,15 @@ int handle_create(struct snapraid_handle* handle, struct snapraid_file* file) return -1; } - /* opening in sequential mode in Windows */ - /* do not follow links to ensure to open the real file */ + /* 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 */ handle->f = open(handle->path, O_RDWR | O_CREAT | O_BINARY | O_SEQUENTIAL | O_NOFOLLOW, 0600); /* if failed for missing permission */ if (handle->f == -1 && errno == EACCES) { /* retry without requesting write permission */ - handle->f = open(handle->path, O_RDONLY | O_BINARY | O_SEQUENTIAL | O_NOFOLLOW | O_NOATIME); + handle->f = open(handle->path, O_RDONLY | O_BINARY | O_SEQUENTIAL | O_NOFOLLOW); } if (handle->f == -1) { @@ -158,11 +159,12 @@ int handle_open(struct snapraid_handle* handle, struct snapraid_file* file) } pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub); - - /* opening in sequential mode in Windows */ - /* do not follow links to ensure to open the real file */ - handle->f = open(handle->path, O_RDONLY | O_BINARY | O_SEQUENTIAL | O_NOFOLLOW | O_NOATIME); + /* open for read */ + /* O_SEQUENTIAL: opening in sequential mode in Windows */ + /* O_NOFOLLOW: do not follow links to ensure to open the real file */ + /* O_NOATIME: do not change access time */ + handle->f = open_noatime(handle->path, O_RDONLY | O_BINARY | O_SEQUENTIAL | O_NOFOLLOW); if (handle->f == -1) { /* invalidate for error */ handle->file = 0; diff --git a/parity.c b/parity.c index a0e3e89f..2c84aad7 100644 --- a/parity.c +++ b/parity.c @@ -221,8 +221,10 @@ int parity_open(struct snapraid_parity* parity, const char* path) pathcpy(parity->path, sizeof(parity->path), path); - /* opening in sequential mode in Windows */ - parity->f = open(parity->path, O_RDONLY | O_BINARY | O_SEQUENTIAL | O_NOATIME); + /* open for read */ + /* O_SEQUENTIAL: opening in sequential mode in Windows */ + /* O_NOATIME: do not change access time */ + parity->f = open_noatime(parity->path, O_RDONLY | O_BINARY | O_SEQUENTIAL); if (parity->f == -1) { fprintf(stderr, "Error opening parity file '%s'. %s.\n", parity->path, strerror(errno)); return -1; diff --git a/portable.h b/portable.h index 31927634..b6fdded2 100644 --- a/portable.h +++ b/portable.h @@ -137,12 +137,19 @@ #define STAT_NSEC(st) -1 #endif +#ifdef O_NOATIME /** - * Defines O_NOATIME if absent. - * O_NOATIME is used to open files in RDONLY mode avoding to update their access time. + * Open a file with the O_NOATIME flag to avoid to update the acces time. */ -#ifndef O_NOATIME -#define O_NOATIME 0 +static int open_noatime(const char* file, int flags) +{ + int f = open(file, flags | O_NOATIME); + if (f == -1 && errno == EPERM) + f = open(file, flags); + return f; +} +#else +#define open_noatime open #endif /**