소스 검색

[dfsv2] add dfs pwrite pread

geniusgogo 1 년 전
부모
커밋
651f23a604
3개의 변경된 파일125개의 추가작업 그리고 11개의 파일을 삭제
  1. 2 0
      components/dfs/dfs_v2/include/dfs_file.h
  2. 121 5
      components/dfs/dfs_v2/src/dfs_file.c
  3. 2 6
      components/dfs/dfs_v2/src/dfs_posix.c

+ 2 - 0
components/dfs/dfs_v2/include/dfs_file.h

@@ -151,7 +151,9 @@ int dfs_file_close(struct dfs_file *file);
 
 off_t dfs_file_get_fpos(struct dfs_file *file);
 void dfs_file_set_fpos(struct dfs_file *file, off_t fpos);
+ssize_t dfs_file_pread(struct dfs_file *file, void *buf, size_t len, off_t offset);
 ssize_t dfs_file_read(struct dfs_file *file, void *buf, size_t len);
+ssize_t dfs_file_pwrite(struct dfs_file *file, const void *buf, size_t len, off_t offset);
 ssize_t dfs_file_write(struct dfs_file *file, const void *buf, size_t len);
 off_t generic_dfs_lseek(struct dfs_file *file, off_t offset, int whence);
 off_t dfs_file_lseek(struct dfs_file *file, off_t offset, int wherece);

+ 121 - 5
components/dfs/dfs_v2/src/dfs_file.c

@@ -626,6 +626,54 @@ int dfs_file_close(struct dfs_file *file)
     return ret;
 }
 
+ssize_t dfs_file_pread(struct dfs_file *file, void *buf, size_t len, off_t offset)
+{
+    ssize_t ret = -EBADF;
+
+    if (file)
+    {
+        /* check whether read */
+        if (!(dfs_fflags(file->flags) & DFS_F_FREAD))
+        {
+            ret = -EPERM;
+        }
+        else if (!file->fops || !file->fops->read)
+        {
+            ret = -ENOSYS;
+        }
+        else if (file->vnode && file->vnode->type != FT_DIRECTORY)
+        {
+            off_t pos = offset;
+
+            ret = rw_verify_area(file, &pos, len);
+            if (ret > 0)
+            {
+                len = ret;
+
+                if (dfs_is_mounted(file->vnode->mnt) == 0)
+                {
+#ifdef RT_USING_PAGECACHE
+                    if (file->vnode->aspace && !(file->flags & O_DIRECT))
+                    {
+                        ret = dfs_aspace_read(file, buf, len, &pos);
+                    }
+                    else
+#endif
+                    {
+                        ret = file->fops->read(file, buf, len, &pos);
+                    }
+                }
+                else
+                {
+                    ret = -EINVAL;
+                }
+            }
+        }
+    }
+
+    return ret;
+}
+
 ssize_t dfs_file_read(struct dfs_file *file, void *buf, size_t len)
 {
     ssize_t ret = -EBADF;
@@ -677,9 +725,65 @@ ssize_t dfs_file_read(struct dfs_file *file, void *buf, size_t len)
     return ret;
 }
 
+ssize_t dfs_file_pwrite(struct dfs_file *file, const void *buf, size_t len, off_t offset)
+{
+    ssize_t ret = -EBADF;
+
+    if (file)
+    {
+        if (!(dfs_fflags(file->flags) & DFS_F_FWRITE))
+        {
+            LOG_W("bad write flags.");
+            ret = -EBADF;
+        }
+        else if (!file->fops || !file->fops->write)
+        {
+            LOG_W("no fops write.");
+            ret = -ENOSYS;
+        }
+        else if (file->vnode && file->vnode->type != FT_DIRECTORY)
+        {
+            off_t pos = offset;
+
+            ret = rw_verify_area(file, &pos, len);
+            if (ret > 0)
+            {
+                len = ret;
+                DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG,
+                    "dfs_file_write(fd, buf, %d)", len);
+
+                if (dfs_is_mounted(file->vnode->mnt) == 0)
+                {
+#ifdef RT_USING_PAGECACHE
+                    if (file->vnode->aspace && !(file->flags & O_DIRECT))
+                    {
+                        ret = dfs_aspace_write(file, buf, len, &pos);
+                    }
+                    else
+#endif
+                    {
+                        ret = file->fops->write(file, buf, len, &pos);
+                    }
+
+                    if (file->flags & O_SYNC)
+                    {
+                        file->fops->flush(file);
+                    }
+                }
+                else
+                {
+                    ret = -EINVAL;
+                }
+            }
+        }
+    }
+
+    return ret;
+}
+
 ssize_t dfs_file_write(struct dfs_file *file, const void *buf, size_t len)
 {
-    size_t ret = -EBADF;
+    ssize_t ret = -EBADF;
 
     if (file)
     {
@@ -695,8 +799,17 @@ ssize_t dfs_file_write(struct dfs_file *file, const void *buf, size_t len)
         }
         else if (file->vnode && file->vnode->type != FT_DIRECTORY)
         {
-            /* fpos lock */
-            off_t pos = dfs_file_get_fpos(file);
+            off_t pos;
+
+            if (!(file->flags & O_APPEND))
+            {
+                /* fpos lock */
+                pos = dfs_file_get_fpos(file);
+            }
+            else
+            {
+                pos = file->vnode->size;
+            }
 
             ret = rw_verify_area(file, &pos, len);
             if (ret > 0)
@@ -728,8 +841,11 @@ ssize_t dfs_file_write(struct dfs_file *file, const void *buf, size_t len)
                     ret = -EINVAL;
                 }
             }
-            /* fpos unlock */
-            dfs_file_set_fpos(file, pos);
+            if (!(file->flags & O_APPEND))
+            {
+                /* fpos unlock */
+                dfs_file_set_fpos(file, pos);
+            }
         }
     }
 

+ 2 - 6
components/dfs/dfs_v2/src/dfs_posix.c

@@ -1363,9 +1363,7 @@ ssize_t pread(int fd, void *buf, size_t len, off_t offset)
 
     /* fpos lock */
     fpos = dfs_file_get_fpos(file);
-    dfs_file_lseek(file, offset, SEEK_SET);
-    result = dfs_file_read(file, buf, len);
-    dfs_file_lseek(file, fpos, SEEK_SET);
+    result = dfs_file_pread(file, buf, len, offset);
     /* fpos unlock */
     dfs_file_set_fpos(file, fpos);
     if (result < 0)
@@ -1411,9 +1409,7 @@ ssize_t pwrite(int fd, const void *buf, size_t len, off_t offset)
     }
     /* fpos lock */
     fpos = dfs_file_get_fpos(file);
-    dfs_file_lseek(file, offset, SEEK_SET);
-    result = dfs_file_write(file, buf, len);
-    dfs_file_lseek(file, fpos, SEEK_SET);
+    result = dfs_file_pwrite(file, buf, len, offset);
     /* fpos unlock */
     dfs_file_set_fpos(file, fpos);
     if (result < 0)