Fix file locking
authorEric Biggers <ebiggers3@gmail.com>
Mon, 26 May 2014 20:42:50 +0000 (15:42 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Mon, 26 May 2014 20:42:50 +0000 (15:42 -0500)
- 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
src/mount_image.c
src/write.c

index c15e6ce..273a6a7 100644 (file)
 
 #if defined(HAVE_SYS_FILE_H) && defined(HAVE_FLOCK)
 extern int
 
 #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
 extern void
-unlock_wim_for_append(WIMStruct *wim, int fd);
+unlock_wim_for_append(WIMStruct *wim);
 #else
 static inline int
 #else
 static inline int
-lock_wim_for_append(WIMStruct *wim, int fd)
+lock_wim_for_append(WIMStruct *wim)
 {
        return 0;
 }
 static inline void
 {
        return 0;
 }
 static inline void
-unlock_wim_for_append(WIMStruct *wim, int fd)
+unlock_wim_for_append(WIMStruct *wim)
 {
 {
-       return 0;
 }
 #endif
 
 }
 #endif
 
index 1c31cae..3aac49d 100644 (file)
@@ -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.  */
        /* 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);
                fuse_exit(fuse_ctx->fuse);
+       }
        if (mq != (mqd_t)-1)
                mq_close(mq);
        return ret;
        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;
        }
 
                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).  */
 
        /* 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:
        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;
 }
 
        return ret;
 }
 
index 0114618..5217838 100644 (file)
@@ -2400,12 +2400,14 @@ finish_write(WIMStruct *wim, int image, int write_flags,
 }
 
 #if defined(HAVE_SYS_FILE_H) && defined(HAVE_FLOCK)
 }
 
 #if defined(HAVE_SYS_FILE_H) && defined(HAVE_FLOCK)
+
+/* Set advisory lock on WIM file (if not already done so)  */
 int
 int
-lock_wim_for_append(WIMStruct *wim, int fd)
+lock_wim_for_append(WIMStruct *wim)
 {
        if (wim->locked_for_append)
                return 0;
 {
        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;
        }
                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;
 }
                return 0;
        return WIMLIB_ERR_ALREADY_LOCKED;
 }
+
+/* Remove advisory lock on WIM file (if present)  */
 void
 void
-unlock_wim_for_append(WIMStruct *wim, int fd)
+unlock_wim_for_append(WIMStruct *wim)
 {
        if (wim->locked_for_append) {
 {
        if (wim->locked_for_append) {
-               flock(fd, LOCK_UN);
+               flock(wim->in_fd.fd, LOCK_UN);
                wim->locked_for_append = 0;
        }
 }
                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;
 
        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;
 
        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;
 
        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:
        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:
 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:
 out_close_wim:
        (void)close_wim_writable(wim, write_flags);
 out_restore_memory_hdr: