fix: 修复proc静态问题
1.proc存在静态问题 2.删除proc节点后,vnode未同步删除,导致系统崩溃 Close #I6BT1F Signed-off-by: zhushengle <zhushengle@huawei.com> Change-Id: I91deecfe1d055a4ad1c2d2cda65acf04e4c53d4c
This commit is contained in:
parent
1f05c6a24d
commit
c8dbdaeb12
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue