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