From b17572488834ae47a7a28a32b08ccbbf6b2d6a7f Mon Sep 17 00:00:00 2001 From: Far Date: Wed, 27 Apr 2022 13:53:53 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dramfs=20(tmpfs)?= =?UTF-8?q?=E7=9A=84=E4=B8=80=E4=BA=9B=E9=97=AE=E9=A2=98=20=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E5=8C=85=E6=8B=AC=EF=BC=9A=201.=20=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=96=AD=E8=A8=80=E9=94=99=E8=AF=AF:mount=20=E5=85=A5=E5=8F=82?= =?UTF-8?q?=E5=88=A4=E6=96=AD=E4=BB=A5=E5=8F=8A=20=E5=A4=A7=E9=87=8F?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=AF=B9file=E7=A7=81=E6=9C=89=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E7=9A=84=E5=88=A4=E6=96=AD=EF=BC=9B=202.=20=E9=83=A8?= =?UTF-8?q?=E5=88=86=E5=8A=A0=E9=94=81=E6=93=8D=E4=BD=9C=E9=81=97=E6=BC=8F?= =?UTF-8?q?:=E5=AF=B9=E6=9C=AA=E9=94=81=E7=9A=84=E9=94=81=E8=BF=9B?= =?UTF-8?q?=E8=A1=8C=E8=A7=A3=E9=94=81=E6=93=8D=E4=BD=9C=EF=BC=9B=203.=20?= =?UTF-8?q?=E9=83=A8=E5=88=86=E5=BC=95=E7=94=A8=E8=AE=A1=E6=95=B0=E6=9C=AA?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0:=E5=B0=9D=E8=AF=95=E5=87=8F=E5=B0=91?= =?UTF-8?q?=E4=B8=BA=E9=9B=B6=E7=9A=84=E5=BC=95=E7=94=A8=E8=AE=A1=E6=95=B0?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Far --- fs/tmpfs/fs_tmpfs.c | 93 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 81 insertions(+), 12 deletions(-) diff --git a/fs/tmpfs/fs_tmpfs.c b/fs/tmpfs/fs_tmpfs.c index 548d0e7..3758edd 100644 --- a/fs/tmpfs/fs_tmpfs.c +++ b/fs/tmpfs/fs_tmpfs.c @@ -137,6 +137,7 @@ int tmpfs_unmount(struct Mount *mnt, struct Vnode **blkdriver); int tmpfs_lookup(struct Vnode *parent, const char *name, int len, struct Vnode **vpp); ssize_t tmpfs_write(struct file *filep, const char *buffer, size_t buflen); ssize_t tmpfs_read(struct file *filep, char *buffer, size_t buflen); +ssize_t tmpfs_readpage(struct Vnode *vnode, char *buffer, off_t off); int tmpfs_stat(struct Vnode *vp, struct stat *st); int tmpfs_opendir(struct Vnode *vp, struct fs_dirent_s *dir); int tmpfs_readdir(struct Vnode *vp, struct fs_dirent_s *dir); @@ -166,6 +167,8 @@ struct VnodeOps tmpfs_vops = { .Getattr = tmpfs_stat, .Opendir = tmpfs_opendir, .Readdir = tmpfs_readdir, + .ReadPage = tmpfs_readpage, + .WritePage = NULL, .Rename = tmpfs_rename, .Mkdir = tmpfs_mkdir, .Create = tmpfs_create, @@ -548,11 +551,6 @@ static int tmpfs_create_file(struct tmpfs_s *fs, { /* No subdirectories... use the root directory */ parent = (struct tmpfs_directory_s *)fs->tfs_root.tde_object; - - /* Lock the root directory to emulate the behavior of tmpfs_find_directory() */ - - tmpfs_lock_directory(parent); - parent->tdo_refs++; } else { @@ -563,6 +561,8 @@ static int tmpfs_create_file(struct tmpfs_s *fs, ret = -EEXIST; goto errout_with_copy; } + tmpfs_lock_directory(parent); + parent->tdo_refs++; /* Verify that no object of this name already exists in the directory */ tde = tmpfs_find_dirent(parent, copy); @@ -695,9 +695,6 @@ static int tmpfs_create_directory(struct tmpfs_s *fs, /* No subdirectories... use the root directory */ parent = (struct tmpfs_directory_s *)fs->tfs_root.tde_object; - - tmpfs_lock_directory(parent); - parent->tdo_refs++; } else { @@ -710,6 +707,8 @@ static int tmpfs_create_directory(struct tmpfs_s *fs, ret = -EEXIST; goto errout_with_copy; } + tmpfs_lock_directory(parent); + parent->tdo_refs++; tde = tmpfs_find_dirent(parent, copy); if (tde != NULL) { @@ -1065,7 +1064,7 @@ ssize_t tmpfs_read(struct file *filep, char *buffer, size_t buflen) loff_t startpos; loff_t endpos; - DEBUGASSERT(filep->f_priv != NULL && filep->f_vnode != NULL); + DEBUGASSERT(filep->f_vnode != NULL); /* Recover our private data from the struct file instance */ @@ -1114,6 +1113,66 @@ ssize_t tmpfs_read(struct file *filep, char *buffer, size_t buflen) return nread; } +/**************************************************************************** + * Name: tmpfs_readpage + ****************************************************************************/ + +ssize_t tmpfs_readpage(struct Vnode *vnode, char *buffer, off_t off) +{ + struct tmpfs_file_s *tfo; + ssize_t nread; + loff_t startpos; + loff_t endpos; + + DEBUGASSERT(vnode->data != NULL); + + /* Recover our private data from the vnode */ + + tfo = (struct tmpfs_file_s *)(vnode->data); + if (tfo == NULL) + { + return -EINVAL; + } + if (off >= tfo->tfo_size) + { + return 0; + } + + /* Get exclusive access to the file */ + + tmpfs_lock_file(tfo); + + /* Handle attempts to read beyond the end of the file. */ + + startpos = off; + nread = PAGE_SIZE; + endpos = startpos + PAGE_SIZE; + + if (endpos > tfo->tfo_size) + { + endpos = tfo->tfo_size; + nread = endpos - startpos; + } + + /* Copy data from the memory object to the user buffer */ + + if (LOS_CopyFromKernel(buffer, PAGE_SIZE, &tfo->tfo_data[startpos], nread) != 0) + { + tmpfs_unlock_file(tfo); + return -EINVAL; + } + + /* Update the node's access time */ + + tfo->tfo_atime = tmpfs_timestamp(); + + /* Release the lock on the file */ + + tmpfs_unlock_file(tfo); + return nread; +} + + /**************************************************************************** * Name: tmpfs_create ****************************************************************************/ @@ -1209,7 +1268,7 @@ ssize_t tmpfs_write(struct file *filep, const char *buffer, size_t buflen) int alloc; char *data; - DEBUGASSERT(filep->f_priv != NULL && filep->f_vnode != NULL); + DEBUGASSERT(filep->f_vnode != NULL); if (buflen == 0) { @@ -1300,7 +1359,7 @@ off_t tmpfs_seek(struct file *filep, off_t offset, int whence) struct tmpfs_file_s *tfo; off_t position; - DEBUGASSERT(filep->f_priv != NULL && filep->f_vnode != NULL); + DEBUGASSERT(filep->f_vnode != NULL); /* Recover our private data from the struct file instance */ @@ -1407,6 +1466,7 @@ int tmpfs_opendir(struct Vnode *vp, struct fs_dirent_s *dir) tmpfs_unlock(fs); return -EINTR; } + tmpfs_lock_directory(tdo); tmp->tf_tdo = tdo; tmp->tf_index = 0; dir->u.fs_dir = (fs_dir_s)tmp; @@ -1616,7 +1676,7 @@ int tmpfs_mount(struct Mount *mnt, struct Vnode *device, const void *data) struct Vnode *vp = NULL; int ret; - DEBUGASSERT(device == NULL && data != NULL); + DEBUGASSERT(device == NULL); if (fs->tfs_root.tde_object != NULL) { @@ -1784,6 +1844,8 @@ int tmpfs_lookup(struct Vnode *parent, const char *relPath, int len, struct Vnod ret = -ENOENT; goto errout_with_lock; } + tmpfs_lock_object(to); + to->to_refs++; (void)VfsHashGet(parent->originMount, (uint32_t)to, &vp, NULL, NULL); if (vp == NULL) @@ -1905,6 +1967,8 @@ int tmpfs_unlink(struct Vnode *parent, struct Vnode *node, const char *relpath) goto errout_with_lock; } DEBUGASSERT(tfo != NULL); + tmpfs_lock_directory(parent_dir); + tmpfs_lock_file(tfo); /* Remove the file from parent directory */ ret = tmpfs_remove_dirent(parent_dir, (struct tmpfs_object_s *)tfo); @@ -2078,6 +2142,7 @@ int tmpfs_rmdir(struct Vnode *parent, struct Vnode *target, const char *dirname) ret = -EISDIR; goto errout_with_lock; } + tmpfs_lock_directory(parent_dir); /* Is the directory empty? We cannot remove directories that still * contain references to file system objects. No can we remove the @@ -2226,6 +2291,9 @@ int tmpfs_rename(struct Vnode *oldVnode, struct Vnode *newParent, const char *ol } tmpfs_lock_directory(oldparent); + tmpfs_lock_object(old_to); + oldparent->tdo_refs++; + old_to->to_refs++; tde = tmpfs_find_dirent(newparent_tdo, copy); if (tde != NULL) { @@ -2435,6 +2503,7 @@ int tmpfs_stat(struct Vnode *vp, struct stat *st) { to = fs->tfs_root.tde_object; } + tmpfs_lock_object(to); to->to_refs++; /* We found it... Return information about the file object in the stat -- GitLab