+/* Unmount a read-only or read-write mounted WIM image. */
+static int
+do_unmount(const char *dir)
+{
+ int status;
+ ssize_t len;
+
+ len = getxattr(dir, "wimfs.unmount", &status, sizeof(int));
+ if (len == sizeof(int))
+ return status;
+ else if (len < 0 && (errno == EACCES || errno == EPERM))
+ return WIMLIB_ERR_NOT_PERMITTED_TO_UNMOUNT;
+ else
+ return WIMLIB_ERR_NOT_A_MOUNTPOINT;
+}
+
+static int
+set_unmount_info(const char *dir, const struct wimfs_unmount_info *unmount_info)
+{
+ if (!setxattr(dir, "wimfs.unmount_info",
+ unmount_info, sizeof(struct wimfs_unmount_info), 0))
+ return 0;
+ else if (errno == EROFS)
+ return 0;
+ else if (errno == EACCES || errno == EPERM)
+ return WIMLIB_ERR_NOT_PERMITTED_TO_UNMOUNT;
+ else
+ return WIMLIB_ERR_NOT_A_MOUNTPOINT;
+}
+
+static int
+do_unmount_discard(const char *dir)
+{
+ int ret;
+ struct wimfs_unmount_info unmount_info;
+
+ memset(&unmount_info, 0, sizeof(unmount_info));
+
+ ret = set_unmount_info(dir, &unmount_info);
+ if (ret)
+ return ret;
+ return do_unmount(dir);
+}
+