2. `readdir(2)`
2. `readlink(2)`
2. `readlinkat(2)`
+2. `rmdir(2)`
+2. `unlink(2)`
+2. `unlinkat(2)`
### LunaixOS自有
__LXSYSCALL1(int, close, int, fd);
__LXSYSCALL1(int, mkdir, const char*, path);
+__LXSYSCALL1(int, rmdir, const char*, pathname);
+__LXSYSCALL1(int, unlink, const char*, pathname);
+__LXSYSCALL2(int, unlinkat, int, fd, const char*, pathname);
__LXSYSCALL2(int, readdir, int, fd, struct dirent*, dent);
#define VFS_INODE_TYPE_DIR 0x1
#define VFS_INODE_TYPE_FILE 0x2
-#define VFS_INODE_TYPE_DEVICE 0x4
+#define VFS_INODE_TYPE_DEVICE 0x3
#define VFS_ENOFS -2
#define VFS_EBADMNT -3
uint32_t ctime;
uint32_t mtime;
uint64_t lb_addr;
- uint32_t ref_count;
+ uint32_t open_count;
uint32_t lb_usage;
uint32_t fsize;
void* data; // 允许底层FS绑定他的一些专有数据
int (*open)(struct v_inode* inode, struct v_file* file);
int (*sync)(struct v_inode* inode);
int (*mkdir)(struct v_inode* inode, struct v_dnode* dnode);
+ int (*rmdir)(struct v_inode* inode);
+ int (*unlink)(struct v_inode* inode);
int (*dir_lookup)(struct v_inode* inode, struct v_dnode* dnode);
} ops;
};
struct twifs_node*
twifs_toplevel_node(const char* name, int name_len);
-void
+int
twifs_rm_node(struct twifs_node* node);
#endif /* __LUNAIX_TWIFS_H */
#define ENOTSUP -14
#define ENXIO -15
#define ELOOP -16
+#define ENOTEMPTY -17
+#define EROFS -18
+#define EISDIR -19
+#define EBUSY -20
#endif /* __LUNAIX_CODE_H */
#define __SYSCALL_geterrno 26
#define __SYSCALL_readlink 27
#define __SYSCALL_readlinkat 28
+#define __SYSCALL_rmdir 29
+#define __SYSCALL_unlink 30
+#define __SYSCALL_unlinkat 31
#define __SYSCALL_MAX 0x100
.long __lxsys_write
.long __lxsys_readdir
.long __lxsys_mkdir
- .long __lxsys_lseek /* 25 */
+ .long __lxsys_lseek /* 25 */
.long __lxsys_geterrno
.long __lxsys_readlink
.long __lxsys_readlinkat
+ .long __lxsys_rmdir
+ .long __lxsys_unlink /* 30 */
+ .long __lxsys_unlinkat
2:
.rept __SYSCALL_MAX - (2b - 1b)/4
.long 0
struct filesystem* twifs = vzalloc(sizeof(struct filesystem));
twifs->fs_name = HSTR("twifs", 5);
twifs->mount = __twifs_mount;
+ twifs->types = FSTYPE_ROFS;
fsm_register(twifs);
return node;
}
-void
+int
twifs_rm_node(struct twifs_node* node)
{
- if ((node->itype & VFS_INODE_TYPE_DIR)) {
- // TODO recursivly delete any sub-directories.
+ if ((node->itype & VFS_INODE_TYPE_DIR) && !llist_empty(&node->children)) {
+ return ENOTEMPTY;
}
llist_delete(&node->siblings);
vfs_i_free(node->inode);
cake_release(twi_pile, node);
+ return 0;
}
struct twifs_node*
.lb_usage = 0,
.data = twi_node,
.mtime = 0,
- .ref_count = 0 };
+ .open_count = 0 };
inode->ops.dir_lookup = __twifs_dirlookup;
inode->ops.mkdir = __twifs_mkdir;
+ inode->ops.unlink = __twifs_rmstuff;
+ inode->ops.rmdir = __twifs_rmstuff;
inode->ops.open = __twifs_openfile;
return inode;
return NULL;
}
+int
+__twifs_rmstuff(struct v_inode* inode)
+{
+ struct twifs_node* twi_node = (struct twifs_node*)inode->data;
+ return twifs_rm_node(twi_node);
+}
+
int
__twifs_dirlookup(struct v_inode* inode, struct v_dnode* dnode)
{
vfile->dnode = dnode;
vfile->inode = dnode->inode;
+ dnode->inode->open_count++;
int errno = dnode->inode->ops.open(dnode->inode, vfile);
if (errno) {
int errno = file->ops.close(file);
if (!errno) {
+ if (file->inode->open_count) {
+ file->inode->open_count--;
+ }
cake_release(file_pile, file);
}
return errno;
cake_release(inode_pile, inode);
}
+/* ---- System call definition and support ---- */
+
int
__vfs_do_open(struct v_file** file_out, const char* path, int options)
{
return errno;
}
+ __current->k_status = errno;
+ return SYSCALL_ESTATUS(errno);
+}
+
+__DEFINE_LXSYSCALL1(int, rmdir, const char*, pathname)
+{
+ int errno;
+ struct v_dnode* dnode;
+ if ((errno = vfs_walk(NULL, pathname, &dnode, NULL, 0))) {
+ goto done;
+ }
+ if ((dnode->super_block->fs->types & FSTYPE_ROFS)) {
+ errno = EROFS;
+ goto done;
+ }
+
+ if (dnode->inode->open_count) {
+ errno = EBUSY;
+ goto done;
+ }
+
+ if (dnode->inode->itype == VFS_INODE_TYPE_DIR) {
+ errno = dnode->inode->ops.rmdir(dnode->inode);
+ } else {
+ errno = ENOTDIR;
+ }
+
+done:
+ __current->k_status = errno;
+ return SYSCALL_ESTATUS(errno);
+}
+
+int
+__vfs_do_unlink(struct v_inode* inode)
+{
+ int errno;
+ if (inode->open_count) {
+ errno = EBUSY;
+ } else if (inode->itype != VFS_INODE_TYPE_DIR) {
+ // TODO handle symbolic link and type other than regular file
+ errno = inode->ops.unlink(inode);
+ } else {
+ errno = EISDIR;
+ }
+
+ return errno;
+}
+
+__DEFINE_LXSYSCALL1(int, unlink, const char*, pathname)
+{
+ int errno;
+ struct v_dnode* dnode;
+ if ((errno = vfs_walk(NULL, pathname, &dnode, NULL, 0))) {
+ goto done;
+ }
+ if ((dnode->super_block->fs->types & FSTYPE_ROFS)) {
+ errno = EROFS;
+ goto done;
+ }
+
+ errno = __vfs_do_unlink(dnode->inode);
+
+done:
+ __current->k_status = errno;
+ return SYSCALL_ESTATUS(errno);
+}
+
+__DEFINE_LXSYSCALL2(int, unlinkat, int, fd, const char*, pathname)
+{
+ int errno;
+ struct v_fd* fd_s;
+ if (!GET_FD(fd, fd_s)) {
+ errno = EBADF;
+ } else {
+ struct v_dnode* dnode;
+ if (!(errno = vfs_walk(fd_s->file->dnode, pathname, &dnode, NULL, 0))) {
+ errno = __vfs_do_unlink(dnode->inode);
+ }
+ }
+
+done:
__current->k_status = errno;
return SYSCALL_ESTATUS(errno);
}
\ No newline at end of file