提交 c8dbdaeb 编写于 作者: Z zhushengle

fix: 修复proc静态问题

1.proc存在静态问题
2.删除proc节点后,vnode未同步删除,导致系统崩溃

Close #I6BT1F
Signed-off-by: Nzhushengle <zhushengle@huawei.com>
Change-Id: I91deecfe1d055a4ad1c2d2cda65acf04e4c53d4c
上级 1f05c6a2
......@@ -125,10 +125,18 @@ int VfsProcfsRead(struct file *filep, char *buffer, size_t buflen)
return -EINVAL;
}
VnodeHold();
entry = VnodeToEntry(filep->f_vnode);
if (entry == NULL) {
VnodeDrop();
return -EPERM;
}
spin_lock(&entry->pdeUnloadLock);
size = (ssize_t)ReadProcFile(entry, (void *)buffer, buflen);
filep->f_pos = entry->pf->fPos;
spin_unlock(&entry->pdeUnloadLock);
VnodeDrop();
return size;
}
......@@ -140,10 +148,18 @@ int VfsProcfsWrite(struct file *filep, const char *buffer, size_t buflen)
return -EINVAL;
}
VnodeHold();
entry = VnodeToEntry(filep->f_vnode);
if (entry == NULL) {
VnodeDrop();
return -EPERM;
}
spin_lock(&entry->pdeUnloadLock);
size = (ssize_t)WriteProcFile(entry, (void *)buffer, buflen);
filep->f_pos = entry->pf->fPos;
spin_unlock(&entry->pdeUnloadLock);
VnodeDrop();
return size;
}
......@@ -156,9 +172,12 @@ int VfsProcfsLookup(struct Vnode *parent, const char *name, int len, struct Vnod
if (entry == NULL) {
return -ENODATA;
}
spin_lock(&procfsLock);
entry = entry->subdir;
while (1) {
if (entry == NULL) {
spin_unlock(&procfsLock);
return -ENOENT;
}
if (EntryMatch(name, len, entry)) {
......@@ -166,6 +185,7 @@ int VfsProcfsLookup(struct Vnode *parent, const char *name, int len, struct Vnod
}
entry = entry->next;
}
spin_unlock(&procfsLock);
*vpp = EntryToVnode(entry);
if ((*vpp) == NULL) {
......@@ -214,11 +234,17 @@ int VfsProcfsUnmount(void *handle, struct Vnode **blkdriver)
int VfsProcfsStat(struct Vnode *node, struct stat *buf)
{
VnodeHold();
struct ProcDirEntry *entry = VnodeToEntry(node);
if (entry == NULL) {
VnodeDrop();
return -EPERM;
}
(void)memset_s(buf, sizeof(struct stat), 0, sizeof(struct stat));
spin_lock(&entry->pdeUnloadLock);
buf->st_mode = entry->mode;
spin_unlock(&entry->pdeUnloadLock);
VnodeDrop();
return LOS_OK;
}
......@@ -226,9 +252,7 @@ int VfsProcfsReaddir(struct Vnode *node, struct fs_dirent_s *dir)
{
int result;
char *buffer = NULL;
int buflen = NAME_MAX;
unsigned int min_size;
unsigned int dst_name_size;
unsigned int minSize, dstNameSize;
struct ProcDirEntry *pde = NULL;
int i = 0;
......@@ -238,28 +262,38 @@ int VfsProcfsReaddir(struct Vnode *node, struct fs_dirent_s *dir)
if (node->type != VNODE_TYPE_DIR) {
return -ENOTDIR;
}
VnodeHold();
pde = VnodeToEntry(node);
if (pde == NULL) {
VnodeDrop();
return -EPERM;
}
spin_lock(&pde->pdeUnloadLock);
while (i < dir->read_cnt) {
buffer = (char *)zalloc(sizeof(char) * NAME_MAX);
if (buffer == NULL) {
spin_unlock(&pde->pdeUnloadLock);
VnodeDrop();
PRINT_ERR("malloc failed\n");
return -ENOMEM;
}
result = ReadProcFile(pde, (void *)buffer, buflen);
result = ReadProcFile(pde, (void *)buffer, NAME_MAX);
if (result != ENOERR) {
free(buffer);
break;
}
dst_name_size = sizeof(dir->fd_dir[i].d_name);
min_size = (dst_name_size < NAME_MAX) ? dst_name_size : NAME_MAX;
result = strncpy_s(dir->fd_dir[i].d_name, dst_name_size, buffer, min_size);
dstNameSize = sizeof(dir->fd_dir[i].d_name);
minSize = (dstNameSize < NAME_MAX) ? dstNameSize : NAME_MAX;
result = strncpy_s(dir->fd_dir[i].d_name, dstNameSize, buffer, minSize);
if (result != EOK) {
spin_unlock(&pde->pdeUnloadLock);
VnodeDrop();
free(buffer);
return -ENAMETOOLONG;
}
dir->fd_dir[i].d_name[dst_name_size - 1] = '\0';
dir->fd_dir[i].d_name[dstNameSize - 1] = '\0';
dir->fd_position++;
dir->fd_dir[i].d_off = dir->fd_position;
dir->fd_dir[i].d_reclen = (uint16_t)sizeof(struct dirent);
......@@ -267,21 +301,30 @@ int VfsProcfsReaddir(struct Vnode *node, struct fs_dirent_s *dir)
i++;
free(buffer);
}
spin_unlock(&pde->pdeUnloadLock);
VnodeDrop();
return i;
}
int VfsProcfsOpendir(struct Vnode *node, struct fs_dirent_s *dir)
{
VnodeHold();
struct ProcDirEntry *pde = VnodeToEntry(node);
if (pde == NULL) {
VnodeDrop();
return -EINVAL;
}
spin_lock(&pde->pdeUnloadLock);
pde->pdirCurrent = pde->subdir;
if (pde->pf == NULL) {
spin_unlock(&pde->pdeUnloadLock);
VnodeDrop();
return -EINVAL;
}
pde->pf->fPos = 0;
spin_unlock(&pde->pdeUnloadLock);
VnodeDrop();
return LOS_OK;
}
......@@ -290,9 +333,17 @@ int VfsProcfsOpen(struct file *filep)
if (filep == NULL) {
return -EINVAL;
}
VnodeHold();
struct Vnode *node = filep->f_vnode;
struct ProcDirEntry *pde = VnodeToEntry(node);
if (pde == NULL) {
VnodeDrop();
return -EPERM;
}
spin_lock(&pde->pdeUnloadLock);
if (ProcOpen(pde->pf) != OK) {
spin_unlock(&pde->pdeUnloadLock);
return -ENOMEM;
}
if (S_ISREG(pde->mode) && (pde->procFileOps != NULL) && (pde->procFileOps->open != NULL)) {
......@@ -303,6 +354,8 @@ int VfsProcfsOpen(struct file *filep)
pde->pf->fPos = 0;
}
filep->f_priv = (void *)pde;
spin_unlock(&pde->pdeUnloadLock);
VnodeDrop();
return LOS_OK;
}
......@@ -312,15 +365,24 @@ int VfsProcfsClose(struct file *filep)
if (filep == NULL) {
return -EINVAL;
}
VnodeHold();
struct Vnode *node = filep->f_vnode;
struct ProcDirEntry *pde = VnodeToEntry(node);
if (pde == NULL) {
VnodeDrop();
return -EPERM;
}
spin_lock(&pde->pdeUnloadLock);
pde->pf->fPos = 0;
if ((pde->procFileOps != NULL) && (pde->procFileOps->release != NULL)) {
result = pde->procFileOps->release((struct Vnode *)pde, pde->pf);
}
LosBufRelease(pde->pf->sbuf);
pde->pf->sbuf = NULL;
spin_unlock(&pde->pdeUnloadLock);
VnodeDrop();
return result;
}
......@@ -345,9 +407,15 @@ ssize_t VfsProcfsReadlink(struct Vnode *vnode, char *buffer, size_t bufLen)
}
struct ProcDirEntry *pde = VnodeToEntry(vnode);
if (pde == NULL) {
return -EPERM;
}
spin_lock(&pde->pdeUnloadLock);
if ((pde->procFileOps != NULL) && (pde->procFileOps->readLink != NULL)) {
result = pde->procFileOps->readLink(pde, buffer, bufLen);
}
spin_unlock(&pde->pdeUnloadLock);
return result;
}
......
......@@ -378,11 +378,34 @@ struct ProcDirEntry *CreateProcEntry(const char *name, mode_t mode, struct ProcD
return pde;
}
static void ProcEntryClearVnode(struct ProcDirEntry *entry)
{
struct Vnode *item = NULL;
struct Vnode *nextItem = NULL;
VnodeHold();
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, GetVnodeActiveList(), struct Vnode, actFreeEntry) {
if ((struct ProcDirEntry *)item->data != entry) {
continue;
}
if (VnodeFree(item) != LOS_OK) {
PRINT_ERR("ProcEntryClearVnode free failed, entry: %s : 0x%x \n", entry->name, item);
}
}
VnodeDrop();
return;
}
static void FreeProcEntry(struct ProcDirEntry *entry)
{
if (entry == NULL) {
return;
}
ProcEntryClearVnode(entry);
spin_lock(&entry->pdeUnloadLock);
if (entry->pf != NULL) {
free(entry->pf);
entry->pf = NULL;
......@@ -391,6 +414,7 @@ static void FreeProcEntry(struct ProcDirEntry *entry)
free(entry->data);
entry->data = NULL;
}
spin_unlock(&entry->pdeUnloadLock);
free(entry);
}
......@@ -562,22 +586,21 @@ static int ProcRead(struct ProcDirEntry *pde, char *buf, size_t len)
struct ProcDirEntry *OpenProcFile(const char *fileName, int flags, ...)
{
unsigned int intSave;
struct ProcDirEntry *pn = ProcFindEntry(fileName);
if (pn == NULL) {
return NULL;
}
SCHEDULER_LOCK(intSave);
spin_lock(&pn->pdeUnloadLock);
if (S_ISREG(pn->mode) && (pn->count != 1)) {
SCHEDULER_UNLOCK(intSave);
spin_unlock(&pn->pdeUnloadLock);
return NULL;
}
pn->flags = (unsigned int)(pn->flags) | (unsigned int)flags;
atomic_set(&pn->count, PROC_INUSE);
SCHEDULER_UNLOCK(intSave);
if (ProcOpen(pn->pf) != OK) {
spin_unlock(&pn->pdeUnloadLock);
return NULL;
}
if (S_ISREG(pn->mode) && (pn->procFileOps != NULL) && (pn->procFileOps->open != NULL)) {
......@@ -587,6 +610,7 @@ struct ProcDirEntry *OpenProcFile(const char *fileName, int flags, ...)
pn->pdirCurrent = pn->subdir;
pn->pf->fPos = 0;
}
spin_unlock(&pn->pdeUnloadLock);
return pn;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册