📄 vfs.c
字号:
Mutex_Lock(&s_vfsLock); Add_To_Back_Of_Mount_Point_List(&s_mountPointList, mountPoint); Mutex_Unlock(&s_vfsLock); return 0;memfail: rc = ENOMEM;fail: if (mountPoint != 0) { if (mountPoint->pathPrefix != 0) Free(mountPoint->pathPrefix); Free(mountPoint); } if (dev != 0) Close_Block_Device(dev); return rc;}/* * Open a file. * Params: * path - full path of the file * mode - open flags: combination of O_CREATE, O_READ, O_WRITE, O_EXCL * pFile - where to store pointer to File object if successful * Returns: 0 if successful, error code (< 0) if not */int Open(const char *path, int mode, struct File **pFile){ int rc = Do_Open(path, mode, pFile, &Do_Open_File); /*if (rc != 0) { Print("File open failed with code %d\n", rc); }*/ return rc;}/* * Close a file or directory. This will destroy the file object, * so it is important not to use the file again after this function * is called. * Params: * file - the File to close * Returns: 0 if successful, error code (< 0) if not */int Close(struct File *file){ int rc; KASSERT(file->ops->Close != 0); /* All filesystems must implement Close(). */ rc = file->ops->Close(file); if (rc == 0) Free(file); return rc;}/* * Get metadata for file specified by given path. * Params: * path - path of file * stat - pointer to VFS_File_Stat * Return: 0 if successful, error code (< 0) if not */int Stat(const char *path, struct VFS_File_Stat *stat){ char prefix[MAX_PREFIX_LEN + 1]; const char *suffix; struct Mount_Point *mountPoint; if (!Unpack_Path(path, prefix, &suffix)) return ENOTFOUND; /* Get mount point for path */ Debug("Stat: lookup mount point for %s\n", prefix); mountPoint = Lookup_Mount_Point(prefix); if (mountPoint == 0) return ENOTFOUND; Debug("Stat: found mount point, dispatching to filesystem\n"); if (mountPoint->ops->Stat == 0) return EUNSUPPORTED; else return mountPoint->ops->Stat(mountPoint, suffix, stat);}/* * Sync all mounted filesystems. * Returns: 0 if successful, error code (< 0) if not */int Sync(void){ int rc = 0; struct Mount_Point *mountPoint; Mutex_Lock(&s_vfsLock); for (mountPoint = Get_Front_Of_Mount_Point_List(&s_mountPointList); mountPoint != 0; mountPoint = Get_Next_In_Mount_Point_List(mountPoint)) { KASSERT(mountPoint->ops->Sync != 0);/* All filesystems must implement Sync */ rc = mountPoint->ops->Sync(mountPoint); if (rc != 0) break; } Mutex_Unlock(&s_vfsLock); return rc;}/* * Allocate a new File object. * Params: * ops - the File_Ops for the file * filePos - initial value for filePos * endPos - initial value for endPos * fsData - private data for use by filesystem implementation * mode - file mode * mountPoint - Mount_Point object of filesystem instance file belongs to * * Returns: new File object, or null if out of memory */struct File *Allocate_File(struct File_Ops *ops, int filePos, int endPos, void *fsData, int mode, struct Mount_Point *mountPoint){ struct File *file; file = (struct File *) Malloc(sizeof(struct File)); if (file != 0) { file->ops = ops; file->filePos = filePos; file->endPos = endPos; file->fsData = fsData; file->mode = mode; file->mountPoint = mountPoint; } return file;}/* * Get metadata for given file. * Params: * file - File object * stat - pointer to VFS_File_Stat * Returns: 0 if successful, error code (< 0) if not */int FStat(struct File *file, struct VFS_File_Stat *stat){ if (file->ops->FStat == 0) return EUNSUPPORTED; else return file->ops->FStat(file, stat);}/* * Read bytes from the current position in a file. * Params: * file - the File object * buf - kernel buffer where data read from file should be stored * len - number of bytes to read * Returns: number of bytes read, 0 if end-of-file is reached, * or error code (< 0) if read fails */int Read(struct File *file, void *buf, ulong_t len){ if (file->ops->Read == 0) return EUNSUPPORTED; else return file->ops->Read(file, buf, len);}/* * Write bytes to the current position of a file. * Params: * file - the File object * buf - kernel buffer containing data to be written * len - number of bytes to write * Returns: number of bytes written, or error code (< 0) if read fails */int Write(struct File *file, void *buf, ulong_t len){ if (file->ops->Write == 0) return EUNSUPPORTED; else return file->ops->Write(file, buf, len);}/* * Change current postion in file * Params: * file - the File object * len - new position * Returns: 0 if successful, * or error code (< 0) if it fails */int Seek(struct File *file, ulong_t len){ if (file->ops->Seek == 0) return EUNSUPPORTED; else return file->ops->Seek(file, len);}/* * Completely read named file into a buffer. * Params: * path - full path of file * pBuffer - reference to variable where pointer to allocated buffer * should be stored * pLen - reference to variable where length of file should * be stored * Returns: 0 if successful, error code (< 0) if not */int Read_Fully(const char *path, void **pBuffer, ulong_t *pLen){ struct File *file = 0; struct VFS_File_Stat stat; int rc; char *buf = 0; int numBytesRead; if ((rc = Stat(path, &stat)) < 0 || (rc = Open(path, O_READ, &file)) < 0) goto fail; if (stat.size < 0) { rc = ENOTFOUND; goto fail; } buf = (char*) Malloc(stat.size); if (buf == 0) goto memfail; /* Read until buffer is full */ numBytesRead = 0; while (numBytesRead < stat.size) { rc = Read(file, buf + numBytesRead, stat.size - numBytesRead); if (rc < 0) goto fail; numBytesRead += rc; } /* Success! */ Close(file); *pBuffer = (void*) buf; *pLen = stat.size; return 0;memfail: rc = ENOMEM;fail: if (file != 0) Close(file); if (buf != 0) Free(buf); return rc;}/* * Create a directory. * Params: * path - full path of directory to create * Returns: 0 if successful, error code (< 0) if not */int Create_Directory(const char *path){ char prefix[MAX_PREFIX_LEN + 1]; const char *suffix; struct Mount_Point *mountPoint; /* Split path into prefix and suffix */ if (!Unpack_Path(path, prefix, &suffix)) return ENOTFOUND; /* Get mount point for path */ mountPoint = Lookup_Mount_Point(prefix); if (mountPoint == 0) return ENOTFOUND; if (mountPoint->ops->Create_Directory == 0) return EUNSUPPORTED; else return mountPoint->ops->Create_Directory(mountPoint, suffix);}/* * Delete a file or directory * Params: * path - full path of file/directory to delete * Returns: 0 if successful, error code (< 0) if not */int Delete(const char *path){ char prefix[MAX_PREFIX_LEN + 1]; const char *suffix; struct Mount_Point *mountPoint; /* Split path into prefix and suffix */ if (!Unpack_Path(path, prefix, &suffix)) return ENOTFOUND; /* Get mount point for path */ mountPoint = Lookup_Mount_Point(prefix); if (mountPoint == 0) return ENOTFOUND; if (mountPoint->ops->Delete == 0) return EUNSUPPORTED; else return mountPoint->ops->Delete(mountPoint, suffix);}/* * Open a directory. * Params: * path - full path of directory * pDir - where File object of opened directory should be stored * Returns: 0 if successful, error code (< 0) if not */int Open_Directory(const char *path, struct File **pDir){ return Do_Open(path, 0, pDir, &Do_Open_Directory);}/* * Read next directory entry. * Params: * file - the File object representing the opened directory * entry - pointer to VFS_Dir_Entry object * Returns: 0 if successful, error code (< 0) if not */int Read_Entry(struct File *file, struct VFS_Dir_Entry *entry){ if (file->ops->Read_Entry == 0) return EUNSUPPORTED; else return file->ops->Read_Entry(file, entry);}/* * Register a paging device. */void Register_Paging_Device(struct Paging_Device *pagingDevice){ KASSERT(s_pagingDevice == 0); KASSERT(pagingDevice != 0); Print("Registering paging device: %s on %s\n", pagingDevice->fileName, pagingDevice->dev->name); s_pagingDevice = pagingDevice;}/* * Get the paging device. * Returns null if no paging device has been registered. */struct Paging_Device *Get_Paging_Device(void){ return s_pagingDevice;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -