X-Git-Url: https://git.sven.stormbind.net/?p=sven%2Fexfat-utils.git;a=blobdiff_plain;f=libexfat%2Fio.c;h=514383ca4bedb64bf12ed4a28c6e4bbf3c87d6f6;hp=683461b6def445c01fba666ea67f278199a68912;hb=2fa6c5654e0a345af10df5227b77d9f468759f20;hpb=f77812e8b678b8bf620bfbf33882139997ccda34 diff --git a/libexfat/io.c b/libexfat/io.c index 683461b..514383c 100644 --- a/libexfat/io.c +++ b/libexfat/io.c @@ -3,7 +3,7 @@ exFAT file system implementation library. Free exFAT implementation. - Copyright (C) 2010-2014 Andrew Nayenko + Copyright (C) 2010-2017 Andrew Nayenko This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -37,20 +37,12 @@ #include #endif #include -#ifdef USE_UBLIO -#include -#include -#endif struct exfat_dev { int fd; enum exfat_mode mode; off_t size; /* in bytes */ -#ifdef USE_UBLIO - off_t pos; - ublio_filehandle_t ufh; -#endif }; static int open_ro(const char* spec) @@ -82,9 +74,6 @@ struct exfat_dev* exfat_open(const char* spec, enum exfat_mode mode) { struct exfat_dev* dev; struct stat stbuf; -#ifdef USE_UBLIO - struct ublio_param up; -#endif dev = malloc(sizeof(struct exfat_dev)); if (dev == NULL) @@ -222,24 +211,6 @@ struct exfat_dev* exfat_open(const char* spec, enum exfat_mode mode) } } -#ifdef USE_UBLIO - memset(&up, 0, sizeof(struct ublio_param)); - up.up_blocksize = 256 * 1024; - up.up_items = 64; - up.up_grace = 32; - up.up_priv = &dev->fd; - - dev->pos = 0; - dev->ufh = ublio_open(&up); - if (dev->ufh == NULL) - { - close(dev->fd); - free(dev); - exfat_error("failed to initialize ublio"); - return NULL; - } -#endif - return dev; } @@ -247,13 +218,6 @@ int exfat_close(struct exfat_dev* dev) { int rc = 0; -#ifdef USE_UBLIO - if (ublio_close(dev->ufh) != 0) - { - exfat_error("failed to close ublio"); - rc = -EIO; - } -#endif if (close(dev->fd) != 0) { exfat_error("failed to close device: %s", strerror(errno)); @@ -267,13 +231,6 @@ int exfat_fsync(struct exfat_dev* dev) { int rc = 0; -#ifdef USE_UBLIO - if (ublio_fsync(dev->ufh) != 0) - { - exfat_error("ublio fsync failed"); - rc = -EIO; - } -#endif if (fsync(dev->fd) != 0) { exfat_error("fsync failed: %s", strerror(errno)); @@ -294,56 +251,29 @@ off_t exfat_get_size(const struct exfat_dev* dev) off_t exfat_seek(struct exfat_dev* dev, off_t offset, int whence) { -#ifdef USE_UBLIO - /* XXX SEEK_CUR will be handled incorrectly */ - return dev->pos = lseek(dev->fd, offset, whence); -#else return lseek(dev->fd, offset, whence); -#endif } ssize_t exfat_read(struct exfat_dev* dev, void* buffer, size_t size) { -#ifdef USE_UBLIO - ssize_t result = ublio_pread(dev->ufh, buffer, size, dev->pos); - if (result >= 0) - dev->pos += size; - return result; -#else return read(dev->fd, buffer, size); -#endif } ssize_t exfat_write(struct exfat_dev* dev, const void* buffer, size_t size) { -#ifdef USE_UBLIO - ssize_t result = ublio_pwrite(dev->ufh, buffer, size, dev->pos); - if (result >= 0) - dev->pos += size; - return result; -#else return write(dev->fd, buffer, size); -#endif } ssize_t exfat_pread(struct exfat_dev* dev, void* buffer, size_t size, off_t offset) { -#ifdef USE_UBLIO - return ublio_pread(dev->ufh, buffer, size, offset); -#else return pread(dev->fd, buffer, size, offset); -#endif } ssize_t exfat_pwrite(struct exfat_dev* dev, const void* buffer, size_t size, off_t offset) { -#ifdef USE_UBLIO - return ublio_pwrite(dev->ufh, buffer, size, offset); -#else return pwrite(dev->fd, buffer, size, offset); -#endif } ssize_t exfat_generic_pread(const struct exfat* ef, struct exfat_node* node, @@ -362,7 +292,7 @@ ssize_t exfat_generic_pread(const struct exfat* ef, struct exfat_node* node, if (CLUSTER_INVALID(cluster)) { exfat_error("invalid cluster 0x%x while reading", cluster); - return -1; + return -EIO; } loffset = offset % CLUSTER_SIZE(*ef->sb); @@ -372,21 +302,21 @@ ssize_t exfat_generic_pread(const struct exfat* ef, struct exfat_node* node, if (CLUSTER_INVALID(cluster)) { exfat_error("invalid cluster 0x%x while reading", cluster); - return -1; + return -EIO; } lsize = MIN(CLUSTER_SIZE(*ef->sb) - loffset, remainder); if (exfat_pread(ef->dev, bufp, lsize, exfat_c2o(ef, cluster) + loffset) < 0) { exfat_error("failed to read cluster %#x", cluster); - return -1; + return -EIO; } bufp += lsize; loffset = 0; remainder -= lsize; cluster = exfat_next_cluster(ef, node, cluster); } - if (!ef->ro && !ef->noatime) + if (!(node->attrib & EXFAT_ATTRIB_DIR) && !ef->ro && !ef->noatime) exfat_update_atime(node); return MIN(size, node->size - offset) - remainder; } @@ -394,16 +324,23 @@ ssize_t exfat_generic_pread(const struct exfat* ef, struct exfat_node* node, ssize_t exfat_generic_pwrite(struct exfat* ef, struct exfat_node* node, const void* buffer, size_t size, off_t offset) { + int rc; cluster_t cluster; const char* bufp = buffer; off_t lsize, loffset, remainder; if (offset > node->size) - if (exfat_truncate(ef, node, offset, true) != 0) - return -1; + { + rc = exfat_truncate(ef, node, offset, true); + if (rc != 0) + return rc; + } if (offset + size > node->size) - if (exfat_truncate(ef, node, offset + size, false) != 0) - return -1; + { + rc = exfat_truncate(ef, node, offset + size, false); + if (rc != 0) + return rc; + } if (size == 0) return 0; @@ -411,7 +348,7 @@ ssize_t exfat_generic_pwrite(struct exfat* ef, struct exfat_node* node, if (CLUSTER_INVALID(cluster)) { exfat_error("invalid cluster 0x%x while writing", cluster); - return -1; + return -EIO; } loffset = offset % CLUSTER_SIZE(*ef->sb); @@ -421,20 +358,23 @@ ssize_t exfat_generic_pwrite(struct exfat* ef, struct exfat_node* node, if (CLUSTER_INVALID(cluster)) { exfat_error("invalid cluster 0x%x while writing", cluster); - return -1; + return -EIO; } lsize = MIN(CLUSTER_SIZE(*ef->sb) - loffset, remainder); if (exfat_pwrite(ef->dev, bufp, lsize, exfat_c2o(ef, cluster) + loffset) < 0) { exfat_error("failed to write cluster %#x", cluster); - return -1; + return -EIO; } bufp += lsize; loffset = 0; remainder -= lsize; cluster = exfat_next_cluster(ef, node, cluster); } - exfat_update_mtime(node); + if (!(node->attrib & EXFAT_ATTRIB_DIR)) + /* directory's mtime should be updated by the caller only when it + creates or removes something in this directory */ + exfat_update_mtime(node); return size - remainder; }