提交 792664a5 编写于 作者: O openharmony_ci 提交者: Gitee

!70 pagecache从filep改为使用vnode

Merge pull request !70 from LeonChan/pg
......@@ -150,7 +150,6 @@ errout:
int do_opendir(const char *path, int oflags)
{
int ret;
int fd;
struct Vnode *vp = NULL;
struct file *filep = NULL;
......@@ -197,30 +196,19 @@ int do_opendir(const char *path, int oflags)
vp->useCount++;
VnodeDrop();
/* Associate the vnode with a file structure */
fd = files_allocate(vp, oflags, 0, NULL, 3); /* 3: file start fd */
if (fd < 0)
filep = files_allocate(vp, oflags, 0, NULL, FILE_START_FD);
if (filep == NULL)
{
ret = -EMFILE;
goto errout_with_vnode;
}
/* Get the file structure corresponding to the file descriptor. */
ret = fs_getfilep(fd, &filep);
if (ret < 0)
{
ret = -EPERM;
goto errout_with_fd;
}
filep->f_path = (char *)fullpath; /* The mem will free in close(fd); */
/* Allocate a type DIR -- which is little more than an vnode container. */
dir = (struct fs_dirent_s *)zalloc(sizeof(struct fs_dirent_s));
if (dir == NULL)
{
ret = -ENOMEM;
goto errout_with_fd;
goto errout_with_file;
}
dir->fd_position = 0; /* This is the position in the read stream */
......@@ -237,17 +225,21 @@ int do_opendir(const char *path, int oflags)
if (ret < 0)
{
free(dir);
goto errout_with_fd;
goto errout_with_file;
}
dir->fd_root = vp;
dir->fd_status = DIRENT_MAGIC;
filep->f_dir = dir;
if (fullpath)
{
free(fullpath);
}
return fd;
return filep->fd;
errout_with_fd:
files_release(fd);
errout_with_file:
files_release(filep->fd);
errout_with_vnode:
VnodeHold();
vp->useCount--;
......
......@@ -223,11 +223,6 @@ int block_proxy(const char *blkdev, int oflags)
vnode->type = VNODE_TYPE_BCHR;
VnodeDrop();
/* Block char device is no need for file mapping */
#ifdef LOSCFG_KERNEL_VM
(void)remove_mapping(chardev);
#endif
/* Free the allocate character driver name and return the open file
* descriptor.
*/
......
......@@ -111,7 +111,6 @@ bool get_bit(int i)
return false;
}
/****************************************************************************
* Private Functions
****************************************************************************/
......@@ -140,6 +139,40 @@ static void _files_semtake(struct filelist *list)
#define _files_semgive(list) (void)sem_post(&list->fl_sem)
void file_hold(struct file *filep)
{
struct filelist *list = sched_getfiles();
if (!list)
{
return;
}
_files_semtake(list);
if (filep != NULL)
{
assert(filep->f_refcount > 0);
filep->f_refcount++;
}
_files_semgive(list);
}
void file_release(struct file *filep)
{
struct filelist *list = sched_getfiles();
if (!list)
{
return;
}
_files_semtake(list);
if (filep != NULL)
{
assert(filep->f_refcount > 0);
filep->f_refcount--;
}
_files_semgive(list);
}
/****************************************************************************
* Name: _files_close
*
......@@ -192,21 +225,10 @@ static int _files_close(struct file *filep)
VnodeDrop();
}
/* Release the path of file */
free(filep->f_path);
/* Release the file descriptor */
filep->f_magicnum = 0;
filep->f_oflags = 0;
filep->f_pos = 0;
filep->f_path = NULL;
filep->f_priv = NULL;
filep->f_vnode = NULL;
filep->f_refcount = 0;
filep->f_mapping = NULL;
filep->f_dir = NULL;
memset(filep, 0, sizeof(struct file));
filep->fd = -1;
return ret;
}
......@@ -293,10 +315,7 @@ int file_dup2(struct file *filep1, struct file *filep2)
{
struct filelist *list = NULL;
struct Vnode *vnode_ptr = NULL;
char *fullpath = NULL;
const char *relpath = NULL;
int err;
int len;
int ret;
if (!filep1 || !filep1->f_vnode || !filep2)
......@@ -331,20 +350,6 @@ int file_dup2(struct file *filep1, struct file *filep2)
goto errout_with_ret;
}
len = strlen(filep1->f_path);
if ((len == 0) || (len >= PATH_MAX))
{
ret = -EINVAL;
goto errout_with_ret;
}
fullpath = (char *)zalloc(len + 1);
if (fullpath == NULL)
{
ret = -ENOMEM;
goto errout_with_ret;
}
/* Increment the reference count on the contained vnode */
vnode_ptr = filep1->f_vnode;
......@@ -353,12 +358,11 @@ int file_dup2(struct file *filep1, struct file *filep2)
filep2->f_oflags = filep1->f_oflags;
filep2->f_pos = filep1->f_pos;
filep2->f_vnode = vnode_ptr;
filep2->f_vnode = filep1->f_vnode;
filep2->f_priv = filep1->f_priv;
(void)strncpy_s(fullpath, len + 1, filep1->f_path, len);
filep2->f_path = fullpath;
filep2->f_relpath = relpath;
filep2->f_path = filep1->f_path;
filep2->ops = filep1->ops;
filep2->f_refcount = filep1->f_refcount;
/* Call the open method on the file, driver, mountpoint so that it
* can maintain the correct open counts.
......@@ -400,14 +404,8 @@ int file_dup2(struct file *filep1, struct file *filep2)
/* Handle various error conditions */
errout_with_vnode:
free(filep2->f_path);
filep2->f_oflags = 0;
filep2->f_pos = 0;
filep2->f_vnode = NULL;
filep2->f_priv = NULL;
filep2->f_path = NULL;
filep2->f_relpath = NULL;
memset(filep2, 0, sizeof(struct file));
filep2->fd = -1;
errout_with_ret:
err = -ret;
......@@ -418,32 +416,13 @@ errout:
return VFS_ERROR;
}
#define FILE_START_FD 3
static inline unsigned int files_magic_generate(void)
{
static unsigned int files_magic = 0;
return files_magic++;
}
/****************************************************************************
* Name: files_allocate
*
* Description:
* Allocate a struct files instance and associate it with an inode instance.
* Returns the file descriptor == index into the files array.
*
****************************************************************************/
int files_allocate(struct Vnode *vnode_ptr, int oflags, off_t pos, void *priv, int minfd)
struct file *files_allocate(const struct Vnode *vnode_ptr, int oflags, off_t pos, const void *priv, int minfd)
{
struct filelist *list = NULL;
unsigned int *p = NULL;
unsigned int mask;
unsigned int i;
struct files_struct *process_files = NULL;
/* minfd should be a positive number,and 0,1,2 had be distributed to stdin,stdout,stderr */
struct file *filep = NULL;
if (minfd < FILE_START_FD)
{
......@@ -463,29 +442,25 @@ int files_allocate(struct Vnode *vnode_ptr, int oflags, off_t pos, void *priv, i
if ((~(*p) & mask))
{
set_bit(i, bitmap);
list->fl_files[i].f_oflags = oflags;
list->fl_files[i].f_pos = pos;
list->fl_files[i].f_vnode = vnode_ptr;
list->fl_files[i].f_priv = priv;
list->fl_files[i].f_refcount = 1;
list->fl_files[i].f_mapping = NULL;
list->fl_files[i].f_dir = NULL;
list->fl_files[i].f_magicnum = files_magic_generate();
process_files = OsCurrProcessGet()->files;
if (process_files == NULL)
{
PRINT_ERR("process files is NULL, %s %d\n", __FUNCTION__ ,__LINE__);
_files_semgive(list);
return VFS_ERROR;
}
filep = &list->fl_files[i];
filep->f_oflags = oflags;
filep->f_pos = pos;
filep->f_vnode = (struct Vnode *)vnode_ptr;
filep->f_priv = (void *)priv;
filep->f_refcount = 1;
filep->f_mapping = (struct page_mapping *)&vnode_ptr->mapping;
filep->f_dir = NULL;
filep->f_path = vnode_ptr->filePath;
filep->fd = i;
filep->ops = vnode_ptr->fop;
_files_semgive(list);
return (int)i;
return filep;
}
i++;
}
_files_semgive(list);
return VFS_ERROR;
return NULL;
}
int files_close_internal(int fd, LosProcessCB *processCB)
......@@ -525,20 +500,9 @@ int files_close_internal(int fd, LosProcessCB *processCB)
return -EINVAL;
}
/* The filep->f_refcount may not be zero here, when the filep is shared in parent-child processes.
so, upon closing the filep in current process, relevant region must be released immediately */
#ifdef LOSCFG_KERNEL_VM
struct file *filep = &list->fl_files[fd];
OsVmmFileRegionFree(filep, processCB);
#endif
list->fl_files[fd].f_refcount--;
if (list->fl_files[fd].f_refcount == 0)
{
#ifdef LOSCFG_KERNEL_VM
dec_mapping_nolock(filep->f_mapping);
#endif
ret = _files_close(&list->fl_files[fd]);
if (ret == OK)
{
......@@ -585,17 +549,10 @@ void files_release(int fd)
if (fd >=0 && fd < CONFIG_NFILE_DESCRIPTORS)
{
_files_semtake(list);
struct file *filep = &list->fl_files[fd];
list->fl_files[fd].f_magicnum = 0;
list->fl_files[fd].f_oflags = 0;
list->fl_files[fd].f_vnode = NULL;
list->fl_files[fd].f_pos = 0;
list->fl_files[fd].f_refcount = 0;
list->fl_files[fd].f_path = NULL;
list->fl_files[fd].f_relpath = NULL;
list->fl_files[fd].f_priv = NULL;
list->fl_files[fd].f_mapping = NULL;
list->fl_files[fd].f_dir = NULL;
memset(filep, 0, sizeof(struct file));
filep->fd = -1;
clear_bit(fd, bitmap);
_files_semgive(list);
}
......
......@@ -296,6 +296,7 @@ int mount(const char *source, const char *target,
}
mnt->vnodeBeCovered->flag |= VNODE_FLAG_MOUNT_ORIGIN;
mnt->vnodeCovered->flag |= VNODE_FLAG_MOUNT_NEW;
mnt->vnodeCovered->filePath = strdup(target);
mnt->vnodeDev = device;
mnt->ops = mops;
if (target && (strlen(target) != 0))
......
......@@ -1764,6 +1764,210 @@ errout_with_mutex:
return -error;
}
ssize_t vfs_nfs_writepage(struct Vnode *node, char *buffer, off_t pos, size_t buflen)
{
struct nfsmount *nmp;
struct nfsnode *np;
loff_t f_pos = pos;
size_t writesize;
size_t bufsize;
size_t byteswritten;
size_t reqlen;
uint32_t *ptr = NULL;
uint32_t tmp;
int committed = NFSV3WRITE_UNSTABLE;
int error;
char *temp_buffer = NULL;
struct file_handle parent_fhandle;
nmp = (struct nfsmount *)(node->originMount->data);
DEBUGASSERT(nmp != NULL);
/* Make sure that the mount is still healthy */
nfs_mux_take(nmp);
np = (struct nfsnode *)node->data;
error = nfs_checkmount(nmp);
if (error != OK)
{
nfs_debug_error("nfs_checkmount failed: %d\n", error);
goto errout_with_mutex;
}
parent_fhandle.length = ((struct nfsnode *)node->parent->data)->n_fhsize;
memcpy_s(&(parent_fhandle.handle), parent_fhandle.length,
&(((struct nfsnode *)node->parent->data)->n_fhandle),
((struct nfsnode *)node->parent->data)->n_fhsize);
/* Check if the file size would exceed the range of off_t */
if (np->n_size + buflen < np->n_size)
{
error = EFBIG;
goto errout_with_mutex;
}
/* writepage cannot exceed the file range */
if (f_pos >= np->n_size)
{
error = ERANGE;
goto errout_with_mutex;
}
buflen = min(buflen, np->n_size - f_pos);
/* Allocate memory for data */
bufsize = (buflen < nmp->nm_wsize) ? buflen : nmp->nm_wsize;
temp_buffer = malloc(bufsize);
if (temp_buffer == NULL)
{
error = ENOMEM;
goto errout_with_mutex;
}
/* Now loop until we send the entire user buffer */
writesize = 0;
for (byteswritten = 0; byteswritten < buflen; )
{
/* Make sure that the attempted write size does not exceed the RPC
* maximum.
*/
writesize = buflen - byteswritten;
if (writesize > nmp->nm_wsize)
{
writesize = nmp->nm_wsize;
}
/* Make sure that the attempted read size does not exceed the IO
* buffer size.
*/
bufsize = SIZEOF_rpc_call_write(writesize);
if (bufsize > nmp->nm_buflen)
{
writesize -= (bufsize - nmp->nm_buflen);
}
/* Copy a chunk of the user data into the temporary buffer */
if (LOS_CopyToKernel(temp_buffer, writesize, buffer, writesize) != 0)
{
error = EINVAL;
goto errout_with_memfree;
}
/* Initialize the request. Here we need an offset pointer to the write
* arguments, skipping over the RPC header. Write is unique among the
* RPC calls in that the entry RPC calls messasge lies in the I/O buffer
*/
ptr = (uint32_t *)&((struct rpc_call_write *)
nmp->nm_iobuffer)->write;
reqlen = 0;
/* Copy the variable length, file handle */
*ptr++ = txdr_unsigned((uint32_t)np->n_fhsize);
reqlen += sizeof(uint32_t);
(void)memcpy_s(ptr, np->n_fhsize, &np->n_fhandle, np->n_fhsize);
reqlen += (int)np->n_fhsize;
ptr += uint32_increment((int)np->n_fhsize);
/* Copy the file offset */
txdr_hyper((uint64_t)f_pos, ptr);
ptr += 2;
reqlen += 2*sizeof(uint32_t);
/* Copy the count and stable values */
*ptr++ = txdr_unsigned(writesize);
*ptr++ = txdr_unsigned((uint32_t)committed);
reqlen += 2*sizeof(uint32_t);
/* Copy a chunk of the user data into the I/O buffer from temporary buffer */
*ptr++ = txdr_unsigned(writesize);
reqlen += sizeof(uint32_t);
error = memcpy_s(ptr, writesize, temp_buffer, writesize);
if (error != EOK)
{
error = ENOBUFS;
goto errout_with_memfree;
}
reqlen += uint32_alignup(writesize);
/* Perform the write */
nfs_statistics(NFSPROC_WRITE);
error = nfs_request(nmp, NFSPROC_WRITE,
(void *)nmp->nm_iobuffer, reqlen,
(void *)&nmp->nm_msgbuffer.write,
sizeof(struct rpc_reply_write));
if (error)
{
goto errout_with_memfree;
}
/* Get a pointer to the WRITE reply data */
ptr = (uint32_t *)&nmp->nm_msgbuffer.write.write;
/* Parse file_wcc. First, check if WCC attributes follow. */
tmp = *ptr++;
if (tmp != 0)
{
/* Yes.. WCC attributes follow. But we just skip over them. */
ptr += uint32_increment(sizeof(struct wcc_attr));
}
/* Check if normal file attributes follow */
tmp = *ptr++;
if (tmp != 0)
{
/* Yes.. Update the cached file status in the file structure. */
nfs_attrupdate(np, (struct nfs_fattr *)ptr);
ptr += uint32_increment(sizeof(struct nfs_fattr));
}
/* Get the count of bytes actually written */
tmp = fxdr_unsigned(uint32_t, *ptr);
ptr++;
if (tmp < 1 || tmp > writesize)
{
error = EIO;
goto errout_with_memfree;
}
writesize = tmp;
f_pos += writesize;
np->n_fpos = f_pos;
byteswritten += writesize;
buffer += writesize;
}
free(temp_buffer);
nfs_mux_release(nmp);
return byteswritten;
errout_with_memfree:
free(temp_buffer);
errout_with_mutex:
nfs_mux_release(nmp);
return -error;
}
off_t vfs_nfs_seek(struct file *filep, off_t offset, int whence)
{
struct Vnode *node = filep->f_vnode;
......@@ -1834,6 +2038,156 @@ errout_with_mutex:
return -error;
}
ssize_t vfs_nfs_readpage(struct Vnode *node, char *buffer, off_t pos)
{
struct nfsnode *np;
struct rpc_reply_read *read_response = NULL;
size_t readsize;
size_t tmp;
size_t bytesread;
size_t reqlen;
uint32_t *ptr = NULL;
int error = 0;
struct file_handle parent_fhandle;
int buflen = PAGE_SIZE;
struct nfsmount *nmp = (struct nfsmount *)(node->originMount->data);
DEBUGASSERT(nmp != NULL);
/* Make sure that the mount is still healthy */
nfs_mux_take(nmp);
np = (struct nfsnode *)node->data;
error = nfs_checkmount(nmp);
if (error != OK)
{
nfs_debug_error("nfs_checkmount failed: %d\n", error);
goto errout_with_mutex;
}
parent_fhandle.length = ((struct nfsnode *)node->parent->data)->n_fhsize;
memcpy_s(&(parent_fhandle.handle), parent_fhandle.length,
&(((struct nfsnode *)node->parent->data)->n_fhandle),
((struct nfsnode *)node->parent->data)->n_fhsize);
error = nfs_fileupdate(nmp, np->n_name, &parent_fhandle, np);
if (error != OK)
{
nfs_debug_info("nfs_fileupdate failed: %d\n", error);
goto errout_with_mutex;
}
/* Get the number of bytes left in the file and truncate read count so that
* it does not exceed the number of bytes left in the file.
*/
if (pos >= np->n_size) {
error = EFAULT;
nfs_debug_info("readpage out of file range: %d\n", error);
goto errout_with_mutex;
}
tmp = np->n_size - pos;
if (buflen > tmp)
{
buflen = tmp;
}
/* Now loop until we fill the user buffer (or hit the end of the file) */
for (bytesread = 0; bytesread < buflen; )
{
/* Make sure that the attempted read size does not exceed the RPC maximum */
readsize = buflen - bytesread;
if (readsize > nmp->nm_rsize)
{
readsize = nmp->nm_rsize;
}
/* Make sure that the attempted read size does not exceed the IO buffer size */
tmp = SIZEOF_rpc_reply_read(readsize);
if (tmp > nmp->nm_buflen)
{
readsize -= (tmp - nmp->nm_buflen);
}
/* Initialize the request */
ptr = (uint32_t *)&nmp->nm_msgbuffer.read.read;
reqlen = 0;
/* Copy the variable length, file handle */
*ptr++ = txdr_unsigned((uint32_t)np->n_fhsize);
reqlen += sizeof(uint32_t);
memcpy_s(ptr, np->n_fhsize, &np->n_fhandle, np->n_fhsize);
reqlen += (int)np->n_fhsize;
ptr += uint32_increment((int)np->n_fhsize);
/* Copy the file offset */
txdr_hyper((uint64_t)pos, ptr);
ptr += 2;
reqlen += 2*sizeof(uint32_t);
/* Set the readsize */
*ptr = txdr_unsigned(readsize);
reqlen += sizeof(uint32_t);
/* Perform the read */
nfs_statistics(NFSPROC_READ);
error = nfs_request(nmp, NFSPROC_READ,
(void *)&nmp->nm_msgbuffer.read, reqlen,
(void *)nmp->nm_iobuffer, nmp->nm_buflen);
if (error)
{
nfs_debug_error("nfs_request failed: %d\n", error);
goto errout_with_mutex;
}
/* The read was successful. Get a pointer to the beginning of the NFS
* response data.
*/
read_response = (struct rpc_reply_read *)nmp->nm_iobuffer;
readsize = fxdr_unsigned(uint32_t, read_response->read.hdr.count);
/* Copy the read data into the user buffer */
if (LOS_CopyFromKernel(buffer, buflen, (const void *)read_response->read.data, readsize) != 0)
{
error = EINVAL;
goto errout_with_mutex;
}
/* Update the read state data */
pos += readsize;
np->n_fpos += readsize;
bytesread += readsize;
buffer += readsize;
/* Check if we hit the end of file */
if (read_response->read.hdr.eof != 0)
{
break;
}
}
nfs_mux_release(nmp);
return bytesread;
errout_with_mutex:
nfs_mux_release(nmp);
return -error;
}
ssize_t vfs_nfs_read(struct file *filep, char *buffer, size_t buflen)
{
struct nfsnode *np;
......@@ -2725,6 +3079,8 @@ struct VnodeOps nfs_vops =
.Rename = vfs_nfs_rename,
.Mkdir = vfs_nfs_mkdir,
.Create = vfs_nfs_create,
.ReadPage = vfs_nfs_readpage,
.WritePage = vfs_nfs_writepage,
.Unlink = vfs_nfs_unlink,
.Rmdir = vfs_nfs_rmdir,
.Reclaim = vfs_nfs_reclaim,
......
......@@ -303,6 +303,63 @@ errout_with_semaphore:
return ret;
}
/****************************************************************************
* Name: romfs_readpage
****************************************************************************/
static ssize_t romfs_readpage(struct Vnode *vnode, char *buffer, off_t off)
{
size_t bytesleft;
int ret = 0;
int buflen = PAGE_SIZE;
struct romfs_mountpt_s *rm = NULL;
struct romfs_file_s *rf = NULL;
/* Recover our private data from the struct file instance */
rf = (struct romfs_file_s *)vnode->data;
rm = (struct romfs_mountpt_s *)vnode->originMount->data;
/* Make sure that the mount is still healthy */
romfs_semtake(rm);
ret = romfs_checkmount(rm);
if (ret != OK)
{
PRINTK("ERROR: romfs_checkmount failed: %d\n", ret);
goto errout_with_semaphore;
}
if (off >= rf->rf_size)
{
ret = -ERANGE;
PRINTK("ERROR: readpage out of range, ret: %d.\n", ret);
goto errout_with_semaphore;
}
/* Get the number of bytes left in the file */
bytesleft = rf->rf_size - off;
/* Truncate read count so that it does not exceed the number
* of bytes left in the file.
*/
if (buflen > bytesleft)
{
buflen = bytesleft;
}
LOS_CopyFromKernel(buffer, buflen, &rm->rm_buffer[off], buflen);
romfs_semgive(rm);
return buflen;
errout_with_semaphore:
romfs_semgive(rm);
return ret;
}
/****************************************************************************
* Name: romfs_seek
****************************************************************************/
......@@ -830,6 +887,8 @@ struct VnodeOps g_romfsVops =
{
.Lookup = romfs_lookup,
.Create = NULL,
.ReadPage = romfs_readpage,
.WritePage = NULL,
.Rename = NULL,
.Mkdir = NULL,
.Getattr = romfs_stat,
......
......@@ -75,12 +75,7 @@
int file_dup(struct file *filep, int minfd)
{
int fd2;
int ret;
int err,len,rellen;
struct file *filep2 = NULL;
char *fullpath = NULL;
char *relpath = NULL;
/* Verify that fd is a valid, open file descriptor */
......@@ -90,57 +85,17 @@ int file_dup(struct file *filep, int minfd)
return VFS_ERROR;
}
len = strlen(filep->f_path);
fullpath = (char *)zalloc(len + 1);
if (fullpath == NULL)
{
set_errno(ENOMEM);
return VFS_ERROR;
}
/* Then allocate a new file descriptor for the vnode */
fd2 = files_allocate(filep->f_vnode, filep->f_oflags, filep->f_pos, filep->f_priv, minfd);
if (fd2 < 0)
filep2 = files_allocate(filep->f_vnode, filep->f_oflags, filep->f_pos, filep->f_priv, minfd);
if (filep2 == NULL)
{
free(fullpath);
set_errno(EMFILE);
return VFS_ERROR;
}
filep2->f_refcount = filep->f_refcount;
ret = fs_getfilep(fd2, &filep2);
(void)strncpy_s(fullpath, len + 1, filep->f_path, len);
if (filep->f_relpath != NULL)
{
rellen = strlen(filep->f_relpath);
relpath = (char *)zalloc(rellen + 1);
(void)strncpy_s(relpath, rellen + 1, filep->f_relpath, rellen);
}
filep2->f_path = fullpath;
filep2->f_relpath = relpath;
filep2->f_priv = filep->f_priv;
if (ret < 0)
{
goto errout_with_vnode;
}
return fd2;
errout_with_vnode:
clear_fd(fd2);
free(fullpath);
filep2->f_oflags = 0;
filep2->f_pos = 0;
filep2->f_vnode = NULL;
filep2->f_priv = NULL;
filep2->f_path = NULL;
filep2->f_relpath = NULL;
filep2->f_mapping = NULL;
err = -ret;
set_errno(err);
return VFS_ERROR;
return filep2->fd;
}
/****************************************************************************
......
......@@ -144,6 +144,7 @@ int do_mkdir(int dirfd, const char *pathname, mode_t mode)
// alloc name cache failed is not a critical problem, let it go.
PRINT_ERR("alloc path cache %s failed\n", dirname);
}
vnode->filePath = strdup(fullpath);
parentVnode->useCount--;
VnodeDrop();
out:
......
......@@ -158,7 +158,6 @@ static int do_creat(struct Vnode *parentNode, char *fullpath, mode_t mode, struc
int fp_open(int dirfd, const char *path, int oflags, mode_t mode)
{
int ret;
int fd;
int accmode;
struct file *filep = NULL;
struct Vnode *vnode = NULL;
......@@ -180,7 +179,7 @@ int fp_open(int dirfd, const char *path, int oflags, mode_t mode)
if (vnode->type == VNODE_TYPE_BLK)
{
VnodeDrop();
fd = block_proxy(fullpath, oflags);
int fd = block_proxy(fullpath, oflags);
if (fd < 0)
{
ret = fd;
......@@ -239,6 +238,7 @@ int fp_open(int dirfd, const char *path, int oflags, mode_t mode)
VnodeDrop();
goto errout;
}
vnode->filePath = strdup(fullpath);
}
if (ret != OK)
......@@ -273,26 +273,13 @@ int fp_open(int dirfd, const char *path, int oflags, mode_t mode)
}
}
fd = files_allocate(vnode, oflags, 0, NULL, 3); /* 3: file start fd */
if (fd < 0)
filep = files_allocate(vnode, oflags, 0, NULL, FILE_START_FD);
if (filep == NULL)
{
ret = -EMFILE;
goto errout_with_count;
}
/* Get the file structure corresponding to the file descriptor. */
ret = fs_getfilep(fd, &filep);
if (ret < 0)
{
files_release(fd);
ret = -get_errno();
goto errout_with_count;
}
filep->f_vnode = vnode;
filep->ops = vnode->fop;
filep->f_path = fullpath;
if (filep->ops && filep->ops->open)
{
ret = filep->ops->open(filep);
......@@ -300,17 +287,15 @@ int fp_open(int dirfd, const char *path, int oflags, mode_t mode)
if (ret < 0)
{
files_release(fd);
files_release(filep->fd);
goto errout_with_count;
}
/* we do not bother to handle the NULL scenario, if so, page-cache feature will not be used
* when we do the file fault */
#ifdef LOSCFG_KERNEL_VM
add_mapping(filep, fullpath);
#endif
return fd;
if (fullpath)
{
free(fullpath);
}
return filep->fd;
errout_with_count:
VnodeHold();
......
......@@ -208,16 +208,9 @@ int do_rename(int oldfd, const char *oldpath, int newfd, const char *newpath)
}
VnodeFree(new_vnode);
VnodePathCacheFree(old_vnode);
old_vnode->filePath = strdup(fullnewpath);
PathCacheAlloc(new_parent_vnode, old_vnode, newname, strlen(newname));
VnodeDrop();
ret = update_file_path(fulloldpath, fullnewpath);
if (ret != OK)
{
PRINT_ERR("rename change file path failed, something bad might happped.\n");
}
/* Successfully renamed */
rename_mapping(fulloldpath, fullnewpath);
free(fulloldpath);
free(fullnewpath);
......
......@@ -149,9 +149,7 @@ int do_unlink(int dirfd, const char *pathname)
done:
VnodeDrop();
#ifdef LOSCFG_KERNEL_VM
(void)remove_mapping(fullpath);
#endif
/* Successfully unlinked */
free(fullpath);
......
......@@ -64,23 +64,37 @@ extern "C" {
#define OK 0
#endif
/* minimal fd allocated for file */
#define FILE_START_FD 3
struct Vnode;
/* file mapped in VMM pages */
struct page_mapping {
LOS_DL_LIST page_list; /* all pages */
SPIN_LOCK_S list_lock; /* lock protecting it */
LosMux mux_lock; /* mutex lock */
unsigned long nrpages; /* number of total pages */
unsigned long flags;
Atomic ref; /* reference counting */
struct Vnode *host; /* owner of this mapping */
};
/* This is the underlying representation of an open file. A file
* descriptor is an index into an array of such types. The type associates
* the file descriptor to the file state and to a set of vnode operations.
*/
struct Vnode;
struct file
{
unsigned int f_magicnum; /* file magic number */
unsigned int f_magicnum; /* file magic number. -- to be deleted */
int f_oflags; /* Open mode flags */
struct Vnode *f_vnode; /* Driver interface */
loff_t f_pos; /* File position */
unsigned long f_refcount; /* reference count */
char *f_path; /* File fullpath */
void *f_priv; /* Per file driver private data */
const char *f_relpath; /* realpath */
const char *f_relpath; /* realpath. -- to be deleted */
struct page_mapping *f_mapping; /* mapping file to memory */
void *f_dir; /* DIR struct for iterate the directory if open a directory */
const struct file_operations_vfs *ops;
......@@ -131,26 +145,8 @@ struct file_operations_vfs
int (*unlink)(struct Vnode *vnode);
};
/* file mapped in VMM pages */
struct page_mapping {
LOS_DL_LIST page_list; /* all pages */
SPIN_LOCK_S list_lock; /* lock protecting it */
LosMux mux_lock; /* mutex lock */
unsigned long nrpages; /* number of total pages */
unsigned long flags;
Atomic ref; /* reference counting */
struct file *host; /* owner of this mapping */
};
/* map: full_path(owner) <-> mapping */
struct file_map {
LOS_DL_LIST head;
LosMux lock; /* lock to protect this mapping */
struct page_mapping mapping;
int name_len;
char *rename;
char owner[0]; /* owner: full path of file */
};
void file_hold(struct file *filep);
void file_release(struct file *filep);
/****************************************************************************
* Name: files_initlist
......@@ -467,11 +463,11 @@ off64_t file_seek64(struct file *filep, off64_t offset, int whence);
*
* Description:
* Allocate a struct files instance and associate it with an vnode instance.
* Returns the file descriptor == index into the files array.
* Returns the file descriptor pointer.
*
****************************************************************************/
int files_allocate(struct Vnode *vnode, int oflags, off_t pos, void *priv, int minfd);
struct file *files_allocate(const struct Vnode *vnode_ptr, int oflags, off_t pos, const void *priv, int minfd);
/****************************************************************************
* Name: files_close
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册