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