OSDN Git Service

Refactored device access mode handling.
authorresver <resver@60bc1c72-a15a-11de-b98f-4500b42dc123>
Tue, 4 Dec 2012 18:34:01 +0000 (18:34 +0000)
committerresver <resver@60bc1c72-a15a-11de-b98f-4500b42dc123>
Tue, 4 Dec 2012 18:34:01 +0000 (18:34 +0000)
git-svn-id: http://exfat.googlecode.com/svn/trunk@299 60bc1c72-a15a-11de-b98f-4500b42dc123

dump/main.c
fuse/main.c
libexfat/exfat.h
libexfat/io.c
libexfat/mount.c
mkfs/main.c

index 1536f81..07c8b05 100644 (file)
@@ -76,7 +76,7 @@ static int dump_sb(const char* spec)
        struct exfat_dev* dev;
        struct exfat_super_block sb;
 
-       dev = exfat_open(spec, 1);
+       dev = exfat_open(spec, EXFAT_MODE_RO);
        if (dev == NULL)
                return 1;
 
index 84db40d..19f1816 100644 (file)
@@ -439,7 +439,7 @@ int main(int argc, char* argv[])
                return 1;
        }
 
-       if (ef.ro_fallback)
+       if (ef.ro == -1) /* read-only fallback was used */
        {
                mount_options = add_option(mount_options, "ro", NULL);
                if (mount_options == NULL)
index 9373c41..119798d 100644 (file)
@@ -72,6 +72,13 @@ struct exfat_node
        le16_t name[EXFAT_NAME_MAX + 1];
 };
 
+enum exfat_mode
+{
+       EXFAT_MODE_RO,
+       EXFAT_MODE_RW,
+       EXFAT_MODE_ANY,
+};
+
 struct exfat_dev;
 
 struct exfat
@@ -97,7 +104,6 @@ struct exfat
        uid_t uid;
        gid_t gid;
        int ro;
-       int ro_fallback;
        int noatime;
 };
 
@@ -125,9 +131,10 @@ void exfat_warn(const char* format, ...)
 void exfat_debug(const char* format, ...)
        __attribute__((format(printf, 1, 2)));
 
-struct exfat_dev* exfat_open(const char* spec, int ro);
+struct exfat_dev* exfat_open(const char* spec, enum exfat_mode mode);
 int exfat_close(struct exfat_dev* dev);
 int exfat_fsync(struct exfat_dev* dev);
+enum exfat_mode exfat_mode(const struct exfat_dev* dev);
 off_t exfat_seek(struct exfat_dev* dev, off_t offset, int whence);
 ssize_t exfat_read(struct exfat_dev* dev, void* buffer, size_t size);
 ssize_t exfat_write(struct exfat_dev* dev, const void* buffer, size_t size);
index 7d416ed..755d0d6 100644 (file)
 struct exfat_dev
 {
        int fd;
+       enum exfat_mode mode;
 #ifdef USE_UBLIO
        off_t pos;
        ublio_filehandle_t ufh;
 #endif
 };
 
-struct exfat_dev* exfat_open(const char* spec, int ro)
+struct exfat_dev* exfat_open(const char* spec, enum exfat_mode mode)
 {
        struct exfat_dev* dev;
        struct stat stbuf;
@@ -59,14 +60,47 @@ struct exfat_dev* exfat_open(const char* spec, int ro)
                return NULL;
        }
 
-       dev->fd = open(spec, ro ? O_RDONLY : O_RDWR);
-       if (dev->fd < 0)
+       switch (mode)
        {
+       case EXFAT_MODE_RO:
+               dev->fd = open(spec, O_RDONLY);
+               if (dev->fd == -1)
+               {
+                       free(dev);
+                       exfat_error("failed to open `%s' in read-only mode", spec);
+                       return NULL;
+               }
+               dev->mode = EXFAT_MODE_RO;
+               break;
+       case EXFAT_MODE_RW:
+               dev->fd = open(spec, O_RDWR);
+               if (dev->fd == -1)
+               {
+                       free(dev);
+                       exfat_error("failed to open `%s' in read-write mode", spec);
+                       return NULL;
+               }
+               dev->mode = EXFAT_MODE_RW;
+               break;
+       case EXFAT_MODE_ANY:
+               dev->fd = open(spec, O_RDWR);
+               if (dev->fd != -1)
+               {
+                       dev->mode = EXFAT_MODE_RW;
+                       break;
+               }
+               dev->fd = open(spec, O_RDONLY);
+               if (dev->fd != -1)
+               {
+                       dev->mode = EXFAT_MODE_RO;
+                       exfat_warn("`%s' is write-protected, mounting read-only", spec);
+                       break;
+               }
                free(dev);
-               exfat_error("failed to open `%s' in read-%s mode", spec,
-                               ro ? "only" : "write");
+               exfat_error("failed to open `%s'", spec);
                return NULL;
        }
+
        if (fstat(dev->fd, &stbuf) != 0)
        {
                close(dev->fd);
@@ -135,6 +169,11 @@ int exfat_fsync(struct exfat_dev* dev)
        return 0;
 }
 
+enum exfat_mode exfat_mode(const struct exfat_dev* dev)
+{
+       return dev->mode;
+}
+
 off_t exfat_seek(struct exfat_dev* dev, off_t offset, int whence)
 {
 #ifdef USE_UBLIO
index a62466b..925ec85 100644 (file)
@@ -86,7 +86,6 @@ static void parse_options(struct exfat* ef, const char* options)
        ef->uid = get_int_option(options, "uid", 10, geteuid());
        ef->gid = get_int_option(options, "gid", 10, getegid());
 
-       ef->ro = match_option(options, "ro");
        ef->noatime = match_option(options, "noatime");
 }
 
@@ -137,22 +136,28 @@ static int prepare_super_block(const struct exfat* ef)
 int exfat_mount(struct exfat* ef, const char* spec, const char* options)
 {
        int rc;
+       enum exfat_mode mode;
 
        exfat_tzset();
        memset(ef, 0, sizeof(struct exfat));
 
        parse_options(ef, options);
 
-       ef->dev = exfat_open(spec, ef->ro);
+       if (match_option(options, "ro"))
+               mode = EXFAT_MODE_RO;
+       else if (match_option(options, "ro_fallback"))
+               mode = EXFAT_MODE_ANY;
+       else
+               mode = EXFAT_MODE_RW;
+       ef->dev = exfat_open(spec, mode);
        if (ef->dev == NULL)
+               return -EIO;
+       if (exfat_mode(ef->dev) == EXFAT_MODE_RO)
        {
-               if (ef->ro || !match_option(options, "ro_fallback"))
-                       return -EIO;
-               ef->dev = exfat_open(spec, 1);
-               if (ef->dev == NULL)
-                       return -EIO;
-               exfat_warn("device is write-protected, mounting read-only");
-               ef->ro_fallback = ef->ro = 1;
+               if (mode == EXFAT_MODE_ANY)
+                       ef->ro = -1;
+               else
+                       ef->ro = 1;
        }
 
        ef->sb = malloc(sizeof(struct exfat_super_block));
index 4d44fa1..b8ce63d 100644 (file)
@@ -264,7 +264,7 @@ int main(int argc, char* argv[])
        if (spec == NULL)
                usage(argv[0]);
 
-       dev = exfat_open(spec, 0);
+       dev = exfat_open(spec, EXFAT_MODE_RW);
        if (dev == NULL)
                return 1;
        if (setup(dev, 9, spc_bits, volume_label, volume_serial,