From c5126c598585baa83340e4c2305d3b0e81539dda Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sat, 5 Mar 2005 20:45:45 +0000 Subject: [PATCH] * Write buffers should be const. * Added sys_stat_attr(). * Added sys_open_attr_dir(). Extended the directory functions to be able to deal with attribute directories. * Init the current directory, so we can use it (the support is there already). * Use our open modes instead of the platform ones. * Added O_NOTRAVERSE support to sys_open(). git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11586 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/file_systems/fs_shell/kernel.c | 371 ++++++++++++------ .../kernel/file_systems/fs_shell/kprotos.h | 13 +- 2 files changed, 254 insertions(+), 130 deletions(-) diff --git a/src/tests/add-ons/kernel/file_systems/fs_shell/kernel.c b/src/tests/add-ons/kernel/file_systems/fs_shell/kernel.c index 2e8cdba67c..9ff7995d9f 100644 --- a/src/tests/add-ons/kernel/file_systems/fs_shell/kernel.c +++ b/src/tests/add-ons/kernel/file_systems/fs_shell/kernel.c @@ -36,7 +36,7 @@ #include -#define OMODE_MASK (O_RDONLY | O_WRONLY | O_RDWR) +#define OMODE_MASK (MY_O_RDONLY | MY_O_WRONLY | MY_O_RDWR) #define SLEEP_TIME (10000.0) #define MAX_SYM_LINKS 16 @@ -48,8 +48,9 @@ #define FD_FILE 1 #define FD_DIR 2 #define FD_WD 4 +#define FD_ATTR_DIR 8 -#define FD_ALL (FD_FILE | FD_DIR | FD_WD) +#define FD_ALL (FD_FILE | FD_DIR | FD_WD | FD_ATTR_DIR) #define DEFAULT_FD_NUM (128) #define VNNUM 256 @@ -171,6 +172,7 @@ int sys_rstat(bool kernel, int fd, const char *path, struct my_stat *st, bool eatlink); static fsystem * inc_file_system(const char *name); static int dec_file_system(fsystem *fs); +static ioctx * get_cur_ioctx(void); static int get_dir_fd(bool kernel, int fd, const char *path, char *filename, vnode **dvn); @@ -474,6 +476,7 @@ init_vnode_layer(void) nspace *ns; void *data; extern vnode_ops rootfs; /* XXXdbg */ + ioctx *io; /* compute vnnum based on memsize. 256 vnodes with 8MB. @@ -565,6 +568,11 @@ init_vnode_layer(void) ns->root = lookup_vnode(ns->nsid, vnid); rootvn = ns->root; + // set cwd to "/" + io = get_cur_ioctx(); + inc_vnode(rootvn); + io->cwd = rootvn; + #ifndef USER #ifdef DEBUG @@ -880,7 +888,7 @@ error1: int sys_closedir(bool kernel, int fd) { - return remove_fd(kernel, fd, FD_DIR); + return remove_fd(kernel, fd, FD_DIR | FD_ATTR_DIR); } /* @@ -901,15 +909,20 @@ sys_readdir(bool kernel, int fd, struct my_dirent *buf, size_t bufsize, vnode_id vnid; long nm; - f = get_fd(kernel, fd, FD_DIR); + f = get_fd(kernel, fd, FD_DIR | FD_ATTR_DIR); if (!f) { err = FS_EBADF; goto error1; } vn = f->vn; nm = count; - err = (*vn->ns->fs->ops.readdir)(vn->ns->data, vn->data, f->cookie, - &nm, buf, bufsize); + if (f->type == FD_DIR) { + err = (*vn->ns->fs->ops.readdir)(vn->ns->data, vn->data, f->cookie, + &nm, buf, bufsize); + } else { + err = (*vn->ns->fs->ops.read_attrdir)(vn->ns->data, vn->data, f->cookie, + &nm, buf, bufsize); + } if (err) goto error1; @@ -922,23 +935,25 @@ sys_readdir(bool kernel, int fd, struct my_dirent *buf, size_t bufsize, patch the mount points and the root. */ - LOCK(vnlock); - nsid = vn->ns->nsid; - p = buf; - for(i=0; id_ino, &vnid)) - p->d_ino = vnid; - if (vn->ns->mount && !strcmp(p->d_name, "..")) { - UNLOCK(vnlock); - err = sys_rstat(kernel, fd, "..", &st, FALSE); - if (err) - goto error2; - LOCK(vnlock); - p->d_ino = st.ino; - } - p = (struct my_dirent *) ((char *) p + p->d_reclen); - } - UNLOCK(vnlock); + if (f->type == FD_DIR) { + LOCK(vnlock); + nsid = vn->ns->nsid; + p = buf; + for(i=0; id_ino, &vnid)) + p->d_ino = vnid; + if (vn->ns->mount && !strcmp(p->d_name, "..")) { + UNLOCK(vnlock); + err = sys_rstat(kernel, fd, "..", &st, FALSE); + if (err) + goto error2; + LOCK(vnlock); + p->d_ino = st.ino; + } + p = (struct my_dirent *) ((char *) p + p->d_reclen); + } + UNLOCK(vnlock); + } put_fd(f); return nm; @@ -961,11 +976,16 @@ sys_rewinddir(bool kernel, int fd) int err; vnode *vn; - f = get_fd(kernel, fd, FD_DIR); + f = get_fd(kernel, fd, FD_DIR | FD_ATTR_DIR); if (!f) return FS_EBADF; vn = f->vn; - err = (*vn->ns->fs->ops.rewinddir)(vn->ns->data, vn->data, f->cookie); + if (f->type == FD_DIR) { + err = (*vn->ns->fs->ops.rewinddir)(vn->ns->data, vn->data, f->cookie); + } else { + err = (*vn->ns->fs->ops.rewind_attrdir)(vn->ns->data, vn->data, + f->cookie); + } put_fd(f); return err; } @@ -990,7 +1010,7 @@ sys_open(bool kernel, int fd, const char *path, int omode, int perms, op_open *opo; op_free_cookie *opf; - if (omode & O_CREAT) { + if (omode & MY_O_CREAT) { err = get_dir_fd(kernel, fd, path, filename, &dvn); if (err) goto errorA; @@ -1009,7 +1029,7 @@ sys_open(bool kernel, int fd, const char *path, int omode, int perms, dec_vnode(dvn, FALSE); } else { - err = get_file_fd(kernel, fd, path, TRUE, &vn); + err = get_file_fd(kernel, fd, path, !(omode & MY_O_NOTRAVERSE), &vn); if (err) goto error1; opo = vn->ns->fs->ops.open; @@ -1055,7 +1075,7 @@ error3: opf = vn->ns->fs->ops.free_cookie; if (opf) (*opf)(vn->ns->data, vn->data, cookie); - if (omode & O_CREAT) + if (omode & MY_O_CREAT) goto errorC; error2: dec_vnode(vn, FALSE); @@ -1170,11 +1190,11 @@ sys_lseek(bool kernel, int fd, fs_off_t pos, int whence) goto error1; } switch(whence) { - case SEEK_SET: + case MY_SEEK_SET: f->pos = pos; break; - case SEEK_CUR: - if ((f->omode & O_APPEND) == 0) + case MY_SEEK_CUR: + if ((f->omode & MY_O_APPEND) == 0) f->pos += pos; else { /* we're in append mode so ask where the EOF is */ vn = f->vn; @@ -1191,7 +1211,7 @@ sys_lseek(bool kernel, int fd, fs_off_t pos, int whence) break; } break; - case SEEK_END: + case MY_SEEK_END: vn = f->vn; op = vn->ns->fs->ops.rstat; if (!op) { @@ -1245,7 +1265,7 @@ sys_read(bool kernel, int fd, void *buf, size_t len) err = FS_EBADF; goto error1; } - if ((f->omode & OMODE_MASK) == O_WRONLY) { + if ((f->omode & OMODE_MASK) == MY_O_WRONLY) { err = FS_EBADF; goto error2; } @@ -1279,7 +1299,7 @@ error1: */ ssize_t -sys_write(bool kernel, int fd, void *buf, size_t len) +sys_write(bool kernel, int fd, const void *buf, size_t len) { ofile *f; int err; @@ -1291,7 +1311,7 @@ sys_write(bool kernel, int fd, void *buf, size_t len) err = FS_EBADF; goto error1; } - if ((f->omode & OMODE_MASK) == O_RDONLY) { + if ((f->omode & OMODE_MASK) == MY_O_RDONLY) { err = FS_EBADF; goto error2; } @@ -1319,96 +1339,6 @@ error1: } -ssize_t -sys_read_attr(bool kernel, int fd, const char *name, int type, void *buffer, size_t len, off_t pos) -{ - ofile *f; - int err; - vnode *vn; - size_t sz; - - f = get_fd(kernel, fd, FD_FILE); - if (!f) { - err = FS_EBADF; - goto error1; - } - - vn = f->vn; - sz = len; - err = (*vn->ns->fs->ops.read_attr)(vn->ns->data, vn->data, name, type, buffer, &sz, pos); - if (err) - goto error2; - - put_fd(f); - - return sz; - -error2: - put_fd(f); -error1: - return err; -} - - -ssize_t -sys_write_attr(bool kernel, int fd, const char *name,int type,void *buffer, size_t len, off_t pos) -{ - ofile *f; - int err; - vnode *vn; - size_t sz; - - f = get_fd(kernel, fd, FD_FILE); - if (!f) { - err = FS_EBADF; - goto error1; - } - - vn = f->vn; - sz = len; - err = (*vn->ns->fs->ops.write_attr)(vn->ns->data, vn->data, name, type, buffer, &sz, pos); - if (err) - goto error2; - - put_fd(f); - return sz; - -error2: - put_fd(f); -error1: - return err; -} - - -ssize_t -sys_remove_attr(bool kernel, int fd, const char *name) -{ - ofile *f; - int err; - vnode *vn; - - f = get_fd(kernel, fd, FD_FILE); - if (!f) { - err = FS_EBADF; - goto error1; - } - - vn = f->vn; - err = (*vn->ns->fs->ops.remove_attr)(vn->ns->data, vn->data, name); - if (err) - goto error2; - - put_fd(f); - - return 0; - -error2: - put_fd(f); -error1: - return err; -} - - /* * sys_ioctl */ @@ -1781,6 +1711,188 @@ add_nspace(nspace *ns, fsystem *fs, const char *fileSystem, dev_t dev, ino_t ino } +int +sys_open_attr_dir(bool kernel, int fd, const char *path) +{ + int err; + op_open_attrdir *op; + op_free_cookie *opf; + ofile *f; + int nfd; + vnode *vn; + void *cookie; + + err = get_file_fd(kernel, fd, path, TRUE, &vn); + if (err) + goto error1; + op = vn->ns->fs->ops.open_attrdir; + if (!op) { + err = FS_EINVAL; + goto error2; + } + err = (*op)(vn->ns->data, vn->data, &cookie); + if (err) + goto error2; + + /* + find a file descriptor + */ + + f = (ofile *) calloc(sizeof(ofile), 1); + if (!f) { + err = FS_ENOMEM; + goto error3; + } + + f->type = FD_ATTR_DIR; + f->vn = vn; + f->cookie = cookie; + f->rcnt = 0; + f->ocnt = 0; + + nfd = new_fd(kernel, -1, f, -1, TRUE); + if (nfd < 0) { + err = FS_EMFILE; + goto error4; + } + + return nfd; + +error4: + free(f); +error3: + (*vn->ns->fs->ops.close_attrdir)(vn->ns->data, vn->data, cookie); + opf = vn->ns->fs->ops.free_attrdircookie; + if (opf) + (*opf)(vn->ns->data, vn->data, cookie); +error2: + dec_vnode(vn, FALSE); +error1: + return err; +} + + +ssize_t +sys_read_attr(bool kernel, int fd, const char *name, int type, void *buffer, size_t len, off_t pos) +{ + ofile *f; + int err; + vnode *vn; + size_t sz; + + f = get_fd(kernel, fd, FD_FILE); + if (!f) { + err = FS_EBADF; + goto error1; + } + + vn = f->vn; + sz = len; + err = (*vn->ns->fs->ops.read_attr)(vn->ns->data, vn->data, name, type, buffer, &sz, pos); + if (err) + goto error2; + + put_fd(f); + + return sz; + +error2: + put_fd(f); +error1: + return err; +} + + +ssize_t +sys_write_attr(bool kernel, int fd, const char *name,int type, + const void *buffer, size_t len, off_t pos) +{ + ofile *f; + int err; + vnode *vn; + size_t sz; + + f = get_fd(kernel, fd, FD_FILE); + if (!f) { + err = FS_EBADF; + goto error1; + } + + vn = f->vn; + sz = len; + err = (*vn->ns->fs->ops.write_attr)(vn->ns->data, vn->data, name, type, buffer, &sz, pos); + if (err) + goto error2; + + put_fd(f); + return sz; + +error2: + put_fd(f); +error1: + return err; +} + + +ssize_t +sys_remove_attr(bool kernel, int fd, const char *name) +{ + ofile *f; + int err; + vnode *vn; + + f = get_fd(kernel, fd, FD_FILE); + if (!f) { + err = FS_EBADF; + goto error1; + } + + vn = f->vn; + err = (*vn->ns->fs->ops.remove_attr)(vn->ns->data, vn->data, name); + if (err) + goto error2; + + put_fd(f); + + return 0; + +error2: + put_fd(f); +error1: + return err; +} + + +int +sys_stat_attr(bool kernel, int fd, const char *path, const char *name, + my_attr_info *info) +{ + int err; + vnode *vn; + op_stat_attr *op; + + err = get_file_fd(kernel, fd, path, TRUE, &vn); + if (err) + goto error1; + op = vn->ns->fs->ops.stat_attr; + if (!op) { + err = FS_EINVAL; + goto error2; + } + err = (*op)(vn->ns->data, vn->data, name, info); + if (err) + goto error2; + dec_vnode(vn, FALSE); + + return 0; + +error2: + dec_vnode(vn, FALSE); +error1: + return err; +} + + /* * sys_mount */ @@ -2986,7 +3098,7 @@ remove_fd(bool kernel, int fd, int type) LOCK(fds->lock); if ((fd >= 0) && (fd < fds->num) && fds->fds[fd]) { f = fds->fds[fd]; - if (f->type == type) { + if (f->type & type) { SETBIT(fds->alloc, fd, 0); fds->fds[fd] = NULL; } else @@ -3094,6 +3206,10 @@ invoke_close(ofile *f) case FD_DIR: err = (*vn->ns->fs->ops.closedir)(vn->ns->data, vn->data, f->cookie); break; + case FD_ATTR_DIR: + err = (*vn->ns->fs->ops.close_attrdir)(vn->ns->data, vn->data, + f->cookie); + break; case FD_WD: default: err = 0; @@ -3119,6 +3235,9 @@ invoke_free(ofile *f) case FD_WD: op = NULL; break; + case FD_ATTR_DIR: + op = vn->ns->fs->ops.free_attrdircookie; + break; } if (op) (*op)(vn->ns->data, vn->data, f->cookie); diff --git a/src/tests/add-ons/kernel/file_systems/fs_shell/kprotos.h b/src/tests/add-ons/kernel/file_systems/fs_shell/kprotos.h index 16b7c3d599..3a1a9526db 100644 --- a/src/tests/add-ons/kernel/file_systems/fs_shell/kprotos.h +++ b/src/tests/add-ons/kernel/file_systems/fs_shell/kprotos.h @@ -20,7 +20,7 @@ int sys_open_entry_ref(bool kernel, nspace_id device, vnode_id parent, int sys_close(bool kernel, int fd); fs_off_t sys_lseek(bool kernel, int fd, fs_off_t pos, int whence); ssize_t sys_read(bool kernel, int fd, void *buf, size_t len); -ssize_t sys_write(bool kernel, int fd, void *buf, size_t len); +ssize_t sys_write(bool kernel, int fd, const void *buf, size_t len); int sys_unlink(bool kernel, int fd, const char *path); int sys_link(bool kernel, int ofd, const char *oldpath, int nfd, const char *newpath); @@ -47,10 +47,15 @@ int sys_access(bool kernel, int fd, const char *path, int mode); int sys_sync(void); -ssize_t sys_read_attr(bool kernel, int fd, const char *name, int type, void *buffer, size_t len, off_t pos); -ssize_t sys_write_attr(bool kernel, int fd, const char *name, int type, void *buffer, size_t len, off_t pos); +int sys_open_attr_dir(bool kernel, int fd, const char *path); +ssize_t sys_read_attr(bool kernel, int fd, const char *name, int type, + void *buffer, size_t len, off_t pos); +ssize_t sys_write_attr(bool kernel, int fd, const char *name, int type, + const void *buffer, size_t len, off_t pos); ssize_t sys_remove_attr(bool kernel, int fd, const char *name); - +int sys_stat_attr(bool kernel, int fd, const char *path, const char *name, + my_attr_info *info); + int sys_open_query(bool kernel, int fd, const char *path, const char *query, ulong flags, port_id port, ulong token, void **cookie); int sys_close_query(bool kernel, int fd, const char *path, void *cookie); int sys_read_query(bool kernel, int fd, const char *path, void *cookie, struct my_dirent *dent,size_t bufferSize,long num);