From a5388cc58647a6506e62acddc648ed6ca7b76fa5 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Mon, 26 May 2014 15:42:50 -0500 Subject: [PATCH] Fix file locking - Lock in_fd only - Unlock WIM immediately after commiting mounted image (before fuse_main() returns) - Don't lock WIM for read-only mount --- include/wimlib/write.h | 9 ++++----- src/mount_image.c | 14 +++++++++----- src/write.c | 20 +++++++++++--------- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/include/wimlib/write.h b/include/wimlib/write.h index c15e6ced..273a6a71 100644 --- a/include/wimlib/write.h +++ b/include/wimlib/write.h @@ -32,19 +32,18 @@ #if defined(HAVE_SYS_FILE_H) && defined(HAVE_FLOCK) extern int -lock_wim_for_append(WIMStruct *wim, int fd); +lock_wim_for_append(WIMStruct *wim); extern void -unlock_wim_for_append(WIMStruct *wim, int fd); +unlock_wim_for_append(WIMStruct *wim); #else static inline int -lock_wim_for_append(WIMStruct *wim, int fd) +lock_wim_for_append(WIMStruct *wim) { return 0; } static inline void -unlock_wim_for_append(WIMStruct *wim, int fd) +unlock_wim_for_append(WIMStruct *wim) { - return 0; } #endif diff --git a/src/mount_image.c b/src/mount_image.c index 1c31cae2..3aac49d1 100644 --- a/src/mount_image.c +++ b/src/mount_image.c @@ -1189,8 +1189,10 @@ out: /* Leave the image mounted if commit failed, unless this is a * forced unmount. The user can retry without commit if they * want. */ - if (!ret || (unmount_flags & WIMLIB_UNMOUNT_FLAG_FORCE)) + if (!ret || (unmount_flags & WIMLIB_UNMOUNT_FLAG_FORCE)) { + unlock_wim_for_append(wimfs_ctx->wim); fuse_exit(fuse_ctx->fuse); + } if (mq != (mqd_t)-1) mq_close(mq); return ret; @@ -2098,9 +2100,11 @@ wimlib_mount_image(WIMStruct *wim, int image, const char *dir, return WIMLIB_ERR_INVALID_PARAM; } - ret = lock_wim_for_append(wim, wim->in_fd.fd); - if (ret) - return ret; + if (mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) { + ret = lock_wim_for_append(wim); + if (ret) + return ret; + } /* If the user did not specify an interface for accessing named * data streams, use the default (extended attributes). */ @@ -2255,7 +2259,7 @@ wimlib_mount_image(WIMStruct *wim, int image, const char *dir, if (mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) delete_staging_dir(&ctx); out_unlock: - unlock_wim_for_append(wim, wim->in_fd.fd); + unlock_wim_for_append(wim); return ret; } diff --git a/src/write.c b/src/write.c index 0114618f..52178381 100644 --- a/src/write.c +++ b/src/write.c @@ -2400,12 +2400,14 @@ finish_write(WIMStruct *wim, int image, int write_flags, } #if defined(HAVE_SYS_FILE_H) && defined(HAVE_FLOCK) + +/* Set advisory lock on WIM file (if not already done so) */ int -lock_wim_for_append(WIMStruct *wim, int fd) +lock_wim_for_append(WIMStruct *wim) { if (wim->locked_for_append) return 0; - if (!flock(fd, LOCK_EX | LOCK_NB)) { + if (!flock(wim->in_fd.fd, LOCK_EX | LOCK_NB)) { wim->locked_for_append = 1; return 0; } @@ -2413,11 +2415,13 @@ lock_wim_for_append(WIMStruct *wim, int fd) return 0; return WIMLIB_ERR_ALREADY_LOCKED; } + +/* Remove advisory lock on WIM file (if present) */ void -unlock_wim_for_append(WIMStruct *wim, int fd) +unlock_wim_for_append(WIMStruct *wim) { if (wim->locked_for_append) { - flock(fd, LOCK_UN); + flock(wim->in_fd.fd, LOCK_UN); wim->locked_for_append = 0; } } @@ -3060,7 +3064,7 @@ overwrite_wim_inplace(WIMStruct *wim, int write_flags, unsigned num_threads) if (ret) goto out_restore_memory_hdr; - ret = lock_wim_for_append(wim, wim->out_fd.fd); + ret = lock_wim_for_append(wim); if (ret) goto out_close_wim; @@ -3096,8 +3100,7 @@ overwrite_wim_inplace(WIMStruct *wim, int write_flags, unsigned num_threads) if (ret) goto out_truncate; - /* lock was dropped when file descriptor was closed */ - wim->locked_for_append = 0; + unlock_wim_for_append(wim); return 0; out_truncate: @@ -3111,8 +3114,7 @@ out_truncate: out_restore_physical_hdr: (void)write_wim_header_flags(hdr_save.flags, &wim->out_fd); out_unlock_wim: - /* lock is dropped when close_wim_writable() closes the file */ - wim->locked_for_append = 0; + unlock_wim_for_append(wim); out_close_wim: (void)close_wim_writable(wim, write_flags); out_restore_memory_hdr: -- 2.43.0