about summary refs log tree commit homepage
path: root/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'file.c')
-rw-r--r--file.c108
1 files changed, 89 insertions, 19 deletions
diff --git a/file.c b/file.c
index bd47537..62efa27 100644
--- a/file.c
+++ b/file.c
@@ -19,27 +19,53 @@ bool mog_open_expire_retry(struct mog_svc *svc)
 
 /* path must be a free()-able pointer */
 struct mog_fd *
-mog_file_open_read(struct mog_svc *svc, char *path)
+mog_file_open_read(struct mog_svc *svc, uint32_t mog_devid, char *path)
 {
         struct mog_fd *mfd;
         struct mog_file *mfile;
-        int fd = mog_open_read(svc, path);
-
-        if (fd < 0 && mog_open_expire_retry(svc))
-                fd = mog_open_read(svc, path);
-
-        if (fd < 0) return NULL;
+        int fd;
+        struct mog_dev *dev = mog_dev_for(svc, mog_devid, false);
+
+        mog_dev_wait(dev);
+        fd = mog_open_read(svc, path);
+
+        if (fd < 0) {
+                mog_dev_post(dev);
+                if (mog_open_expire_retry(svc)) {
+                        mog_dev_wait(dev);
+                        fd = mog_open_read(svc, path);
+                        if (fd < 0)
+                                mog_dev_post(dev);
+                }
+                if (fd < 0)
+                        return NULL;
+        }
 
         mfd = mog_fd_init(fd, MOG_FD_TYPE_FILE);
 
         mfile = &mfd->as.file;
         memset(mfile, 0, sizeof(struct mog_file));
         mfile->fsize = -1;
+        mfile->dev = dev;
+        mfile->dev_held = true;
         mfile->svc = svc;
 
         return mfd;
 }
 
+int mog_stat_req(struct mog_svc *svc, uint32_t mog_devid,
+                const char *path, struct stat *sb)
+{
+        struct mog_dev *dev = mog_dev_for(svc, mog_devid, false);
+        int rc;
+
+        mog_dev_wait(dev);
+        rc = mog_stat(svc, path, sb);
+        mog_dev_post(dev);
+
+        return rc;
+}
+
 static int mkpath_open_put(struct mog_svc *svc, char *path, int flags)
 {
         int fd = mog_open_put(svc, path, flags);
@@ -59,36 +85,80 @@ static int mkpath_open_put(struct mog_svc *svc, char *path, int flags)
 
 /* path must be a free()-able pointer */
 struct mog_fd *
-mog_file_open_put(struct mog_svc *svc, char *path, int flags)
+mog_file_open_put(struct mog_svc *svc, uint32_t mog_devid, char *path,
+                int flags)
 {
         struct mog_fd *mfd;
         struct mog_file *mfile;
-        int fd = mkpath_open_put(svc, path, flags);
-
-        if (fd < 0 && mog_open_expire_retry(svc))
-                fd = mkpath_open_put(svc, path, flags);
-
-        if (fd < 0) return NULL;
-
+        int fd;
+        struct mog_dev *dev = mog_dev_for(svc, mog_devid, false);
+
+        mog_dev_wait(dev);
+        fd = mkpath_open_put(svc, path, flags);
+
+        if (fd < 0) {
+                mog_dev_post(dev);
+                if (mog_open_expire_retry(svc)) {
+                        mog_dev_wait(dev);
+                        fd = mkpath_open_put(svc, path, flags);
+                        if (fd < 0)
+                                mog_dev_post(dev);
+                }
+                if (fd < 0)
+                        return NULL;
+        }
         mfd = mog_fd_init(fd, MOG_FD_TYPE_FILE);
 
         mfile = &mfd->as.file;
         memset(mfile, 0, sizeof(struct mog_file));
         mfile->svc = svc;
+        mfile->dev = dev;
+        mfile->dev_held = true;
 
         return mfd;
 }
 
+void mog_file_post(struct mog_fd *mfd)
+{
+        struct mog_file *file = &mfd->as.file;
+
+        assert(file->dev_held);
+        file->dev_held = false;
+        mog_dev_post(file->dev);
+}
+
+void mog_file_wait(struct mog_fd *mfd)
+{
+        struct mog_file *file = &mfd->as.file;
+
+        assert(!file->dev_held);
+        file->dev_held = true;
+        mog_dev_wait(file->dev);
+}
+
+void mog_file_ensure_wait(struct mog_fd *mfd)
+{
+        struct mog_file *file = &mfd->as.file;
+
+        if (!file->dev_held) {
+                file->dev_held = true;
+                mog_dev_wait(file->dev);
+        }
+}
+
 void mog_file_close(struct mog_fd *mfd)
 {
-        struct mog_file *mfile = &mfd->as.file;
+        struct mog_file *file = &mfd->as.file;
 
         assert(mfd->fd_type == MOG_FD_TYPE_FILE && "mog_fd is not a file");
 
+        if (file->dev_held)
+                mog_dev_post(file->dev);
+
         /* all of these may already be NULL */
-        free(mfile->path);
-        free(mfile->tmppath);
-        mog_digest_destroy(&mfile->digest);
+        free(file->path);
+        free(file->tmppath);
+        mog_digest_destroy(&file->digest);
 
         mog_fd_put(mfd);
 }