[Libsysio-commit] HEAD: libsysio/src getdirentries.c inode.c link.c readlink.c rename.c rmdir.c rw.
Brought to you by:
lward
From: Lee W. <lw...@us...> - 2009-01-28 16:13:26
|
Update of /cvsroot/libsysio/libsysio/src In directory ddv4jf1.ch3.sourceforge.com:/tmp/cvs-serv31818/src Modified Files: getdirentries.c inode.c link.c readlink.c rename.c rmdir.c rw.c symlink.c unlink.c Log Message: Big code refactor to pave the way folr the handles-based API. No, real, functional change. Index: getdirentries.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/getdirentries.c,v retrieving revision 1.27 retrieving revision 1.28 diff -u -w -b -B -p -r1.27 -r1.28 --- getdirentries.c 17 Jun 2008 17:18:57 -0000 1.27 +++ getdirentries.c 28 Jan 2009 16:13:19 -0000 1.28 @@ -63,25 +63,40 @@ #define __restrict #endif -static ssize_t -filldirents(struct file *fil, - char *buf, size_t nbytes, +ssize_t +_sysio_p_filldirentries(struct pnode *pno, + char *buf, + size_t nbytes, _SYSIO_OFF_T *__restrict basep) { - _SYSIO_OFF_T opos; + _SYSIO_OFF_T pos; ssize_t cc; - if (!(fil && fil->f_pno->p_base->pb_ino)) + if (!pno->p_base->pb_ino) return -EBADF; - if (!S_ISDIR(fil->f_pno->p_base->pb_ino->i_stbuf.st_mode)) + if (!S_ISDIR(pno->p_base->pb_ino->i_stbuf.st_mode)) return -ENOTDIR; - opos = fil->f_pos; + pos = *basep; cc = - PNOP_FILLDIRENTRIES(fil->f_pno, &fil->f_pos, buf, nbytes); - if (cc < 0) + PNOP_FILLDIRENTRIES(pno, &pos, buf, nbytes); + if (cc >= 0) + *basep = pos; return cc; - *basep = opos; +} + +static ssize_t +filldirents(struct file *fil, + char *buf, size_t nbytes, + _SYSIO_OFF_T *__restrict basep) +{ + ssize_t cc; + + if (!fil) + return -EBADF; + cc = _sysio_p_filldirentries(fil->f_pno, buf, nbytes, basep); + if (cc >= 0) + fil->f_pos = *basep; return cc; } @@ -175,7 +190,10 @@ SYSIO_INTERFACE_NAME(getdirentries)(int cc = -EBADF; /* assume failure */ fil = _sysio_fd_find(fd); - if (FIL_FILEOK(fil)) { + if (*basep < 0) + cc = 0; + else if (FIL_FILEOK(fil)) { + b = *basep; cc = filldirents(fil, buf, nbytes, &b); FIL_PUT(fil); } Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.54 retrieving revision 1.55 diff -u -w -b -B -p -r1.54 -r1.55 --- inode.c 22 Jan 2009 19:12:19 -0000 1.54 +++ inode.c 28 Jan 2009 16:13:19 -0000 1.55 @@ -608,7 +608,7 @@ _sysio_pb_gone(struct pnode_base *pb) /* * Clean up the namespace graph after an unlink. */ -static void +void _sysio_pb_disconnect(struct pnode_base *pb) { @@ -1263,194 +1263,6 @@ _sysio_p_setattr(struct pnode *pno, } /* - * Perform link operation; old to new. - */ -int -_sysio_p_link(struct pnode *old, struct pnode *new) -{ - int err; - - if (S_ISDIR(old->p_base->pb_ino->i_stbuf.st_mode)) - return -EPERM; - if (new->p_base->pb_ino) - return -EEXIST; - /* - * Make sure they aren't trying to link across a mount-point. - * - * NB: Arguably, should check that the root pnodes are the same. - * However, that would allow linking across bound mounts. I'm thinking - * we don't want to allow that. Though, I don't really know why not. - * I'm a pedant? - */ - if (old->p_mount != new->p_mount) - return -EXDEV; - if (IS_RDONLY(new->p_parent)) - return -EROFS; - err = PNOP_LINK(old, new); - if (err) - return err; - PB_SET_ASSOC(new->p_base, old->p_base->pb_ino); - I_REF(new->p_base->pb_ino); - return 0; -} - -/* - * Perform unlink operation on some pnode. - */ -int -_sysio_p_unlink(struct pnode *pno) -{ - int err; - - if (IS_RDONLY(pno)) - return -EROFS; - if (!pno->p_base->pb_ino) - return -ENOENT; /* huh? */ - if (S_ISDIR(pno->p_base->pb_ino->i_stbuf.st_mode)) - return -EISDIR; - /* - * Call the FS implementation. - */ - err = PNOP_UNLINK(pno); - if (err) - return err; - /* - * Clean the namespace graphs to reflect the unlink. - */ - _sysio_i_undead(pno->p_base->pb_ino); - _sysio_pb_disconnect(pno->p_base); - return 0; -} - -/* - * Perform symlink operation; oldpath to new. - */ -int -_sysio_p_symlink(const char *oldpath, struct pnode *new) -{ - - if (new->p_base->pb_ino) - return -EEXIST; - if (IS_RDONLY(new->p_parent)) - return -EROFS; - return PNOP_SYMLINK(new, oldpath); -} - -/* - * Perform remove directory operation on some pnode. - */ -int -_sysio_p_rmdir(struct pnode *pno) -{ - int err; - - if (IS_RDONLY(pno)) - return -EROFS; - if (!pno->p_base->pb_ino) - return -ENOENT; /* huh? */ - if (!S_ISDIR(pno->p_base->pb_ino->i_stbuf.st_mode)) - return -ENOTDIR; - /* - * Don't allow unlink of a root or a mount point. - */ - if (pno->p_cover || pno->p_mount->mnt_root == pno) - return -EBUSY; - /* - * Call the FS implementation. - */ - err = PNOP_RMDIR(pno); - if (err) - return err; - /* - * Clean the namespace graphs to reflect the unlink. - */ - _sysio_i_undead(pno->p_base->pb_ino); - _sysio_pb_disconnect(pno->p_base); - return 0; -} - -/* - * Perform rename operation on some pnode. - */ -int -_sysio_p_rename(struct pnode *old, struct pnode *new) -{ - struct pnode_base *nxtpb, *pb; - int err; - - /* - * Check for rename to self. - */ - if (old == new) - return 0; - - /* - * No xdev renames please. - */ - if (old->p_mount->mnt_fs != new->p_mount->mnt_fs) - return -EXDEV; - - /* - * Must not be a read-only mount. - * - * NB: Invariant old->p_mount->mnt_fs == new->p_mount->mnt_fs. - */ - if (IS_RDONLY(new)) - return -EROFS; - - /* - * Don't allow mount points to move. - */ - if (old->p_mount->mnt_root == old || - old->p_cover || - new->p_mount->mnt_root == new) - return -EBUSY; - - /* - * Make sure the old pnode can't be found in the ancestor chain - * for the new. If it can, they are trying to move into a subdirectory - * of the old. - */ - nxtpb = new->p_base; - do { - pb = nxtpb; - nxtpb = pb->pb_key.pbk_parent; - if (pb == old->p_base) - return -EINVAL; - } while (nxtpb); - - if (new->p_base->pb_ino) { - /* - * Existing entry. We're replacing the new. Make sure that's - * ok. - */ - if (S_ISDIR(new->p_base->pb_ino->i_stbuf.st_mode)) { - if (!S_ISDIR(old->p_base->pb_ino->i_stbuf.st_mode)) - return -EISDIR; - } else if (S_ISDIR(old->p_base->pb_ino->i_stbuf.st_mode)) - return -ENOTDIR; - } - - /* - * Give the op a try. - */ - err = PNOP_RENAME(old, new); - if (err) - return err; - /* - * Disconnect the old. - */ - _sysio_pb_disconnect(old->p_base); - /* - * Disconnect the new if positive. We want new lookups - * to find the just renamed entity. - */ - if (new->p_base->pb_ino) - _sysio_pb_disconnect(new->p_base); - return 0; -} - -/* * Do nothing. */ void Index: link.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/link.c,v retrieving revision 1.16 retrieving revision 1.17 diff -u -w -b -B -p -r1.16 -r1.17 --- link.c 17 Jun 2008 17:18:57 -0000 1.16 +++ link.c 28 Jan 2009 16:13:19 -0000 1.17 @@ -54,6 +54,193 @@ #include "inode.h" #include "sysio-symbols.h" +/* + * Perform link operation; old to new. + */ +int +_sysio_p_link(struct pnode *old, struct pnode *new) +{ + int err; + + if (S_ISDIR(old->p_base->pb_ino->i_stbuf.st_mode)) + return -EPERM; + if (new->p_base->pb_ino) + return -EEXIST; + /* + * Make sure they aren't trying to link across a mount-point. + * + * NB: Arguably, should check that the root pnodes are the same. + * However, that would allow linking across bound mounts. I'm thinking + * we don't want to allow that. Though, I don't really know why not. + * I'm a pedant? + */ + if (old->p_mount != new->p_mount) + return -EXDEV; + if (IS_RDONLY(new->p_parent)) + return -EROFS; + err = PNOP_LINK(old, new); + if (err) + return err; + PB_SET_ASSOC(new->p_base, old->p_base->pb_ino); + I_REF(new->p_base->pb_ino); + return 0; +} + +/* + * Perform unlink operation on some pnode. + */ +int +_sysio_p_unlink(struct pnode *pno) +{ + int err; + + if (IS_RDONLY(pno)) + return -EROFS; + if (!pno->p_base->pb_ino) + return -ENOENT; /* huh? */ + if (S_ISDIR(pno->p_base->pb_ino->i_stbuf.st_mode)) + return -EISDIR; + /* + * Call the FS implementation. + */ + err = PNOP_UNLINK(pno); + if (err) + return err; + /* + * Clean the namespace graphs to reflect the unlink. + */ + _sysio_i_undead(pno->p_base->pb_ino); + _sysio_pb_disconnect(pno->p_base); + return 0; +} + +/* + * Perform symlink operation; oldpath to new. + */ +int +_sysio_p_symlink(const char *oldpath, struct pnode *new) +{ + + if (new->p_base->pb_ino) + return -EEXIST; + if (IS_RDONLY(new->p_parent)) + return -EROFS; + return PNOP_SYMLINK(new, oldpath); +} + +/* + * Perform remove directory operation on some pnode. + */ +int +_sysio_p_rmdir(struct pnode *pno) +{ + int err; + + if (IS_RDONLY(pno)) + return -EROFS; + if (!pno->p_base->pb_ino) + return -ENOENT; /* huh? */ + if (!S_ISDIR(pno->p_base->pb_ino->i_stbuf.st_mode)) + return -ENOTDIR; + /* + * Don't allow unlink of a root or a mount point. + */ + if (pno->p_cover || pno->p_mount->mnt_root == pno) + return -EBUSY; + /* + * Call the FS implementation. + */ + err = PNOP_RMDIR(pno); + if (err) + return err; + /* + * Clean the namespace graphs to reflect the unlink. + */ + _sysio_i_undead(pno->p_base->pb_ino); + _sysio_pb_disconnect(pno->p_base); + return 0; +} + +/* + * Perform rename operation on some pnode. + */ +int +_sysio_p_rename(struct pnode *old, struct pnode *new) +{ + struct pnode_base *nxtpb, *pb; + int err; + + /* + * Check for rename to self. + */ + if (old == new) + return 0; + + /* + * No xdev renames please. + */ + if (old->p_mount->mnt_fs != new->p_mount->mnt_fs) + return -EXDEV; + + /* + * Must not be a read-only mount. + * + * NB: Invariant old->p_mount->mnt_fs == new->p_mount->mnt_fs. + */ + if (IS_RDONLY(new)) + return -EROFS; + + /* + * Don't allow mount points to move. + */ + if (old->p_mount->mnt_root == old || + old->p_cover || + new->p_mount->mnt_root == new) + return -EBUSY; + + /* + * Make sure the old pnode can't be found in the ancestor chain + * for the new. If it can, they are trying to move into a subdirectory + * of the old. + */ + nxtpb = new->p_base; + do { + pb = nxtpb; + nxtpb = pb->pb_key.pbk_parent; + if (pb == old->p_base) + return -EINVAL; + } while (nxtpb); + + if (new->p_base->pb_ino) { + /* + * Existing entry. We're replacing the new. Make sure that's + * ok. + */ + if (S_ISDIR(new->p_base->pb_ino->i_stbuf.st_mode)) { + if (!S_ISDIR(old->p_base->pb_ino->i_stbuf.st_mode)) + return -EISDIR; + } else if (S_ISDIR(old->p_base->pb_ino->i_stbuf.st_mode)) + return -ENOTDIR; + } + + /* + * Give the op a try. + */ + err = PNOP_RENAME(old, new); + if (err) + return err; + /* + * Disconnect the old. + */ + _sysio_pb_disconnect(old->p_base); + /* + * Disconnect the new if positive. We want new lookups + * to find the just renamed entity. + */ + if (new->p_base->pb_ino) + _sysio_pb_disconnect(new->p_base); + return 0; +} int SYSIO_INTERFACE_NAME(link)(const char *oldpath, const char *newpath) { Index: readlink.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/readlink.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -w -b -B -p -r1.11 -r1.12 --- readlink.c 17 Jun 2008 17:18:57 -0000 1.11 +++ readlink.c 28 Jan 2009 16:13:19 -0000 1.12 @@ -52,6 +52,20 @@ #include "inode.h" #include "sysio-symbols.h" +/* + * Read symbolic link content from passed path-node. + */ +ssize_t +_sysio_p_readlink(struct pnode *pno, char *buf, size_t bufsiz) +{ + + if (!pno->p_base->pb_ino) + return -ESTALE; + if (!S_ISLNK(pno->p_base->pb_ino->i_stbuf.st_mode)) + return -EINVAL; + return (ssize_t )PNOP_READLINK(pno, buf, bufsiz); +} + #ifdef HAVE_POSIX_1003_READLINK ssize_t #else @@ -61,30 +75,32 @@ SYSIO_INTERFACE_NAME(readlink)(const cha { struct intent intent; int err; + ssize_t cc; struct pnode *pno; SYSIO_INTERFACE_DISPLAY_BLOCK; SYSIO_INTERFACE_ENTER(readlink, "%s%zd", path, bufsiz); - INTENT_INIT(&intent, INT_GETATTR, NULL, NULL); + INTENT_INIT(&intent, 0, NULL, NULL); err = _sysio_namei(_sysio_cwd, path, ND_NOFOLLOW, &intent, &pno); - if (err) + if (err) { + cc = err; goto out; - if (!S_ISLNK(pno->p_base->pb_ino->i_stbuf.st_mode)) { - err = -EINVAL; - goto error; } - err = PNOP_READLINK(pno, buf, bufsiz); -error: + cc = _sysio_p_readlink(pno, buf, bufsiz); P_PUT(pno); out: #ifdef HAVE_POSIX_1003_READLINK +#define _ty ssize_t #define _rtnfmt "%zd" #else +#define _ty int #define _rtnfmt "%d" #endif - SYSIO_INTERFACE_RETURN(err < 0 ? -1 : err, err >= 0 ? 0 : err, - readlink, _rtnfmt "%*s", err, buf); + SYSIO_INTERFACE_RETURN((_ty )(cc < 0 ? -1 : cc), + cc >= 0 ? 0 : (int )cc, + readlink, _rtnfmt "%*s", cc, buf); #undef _rtnfmt +#undef _ty } #ifdef REDSTORM Index: rename.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/rename.c,v retrieving revision 1.15 retrieving revision 1.16 diff -u -w -b -B -p -r1.15 -r1.16 --- rename.c 17 Jun 2008 17:18:57 -0000 1.15 +++ rename.c 28 Jan 2009 16:13:19 -0000 1.16 @@ -54,6 +54,87 @@ #include "mount.h" #include "inode.h" +/* + * Perform rename operation on some pnode. + */ +int +_sysio_p_rename(struct pnode *old, struct pnode *new) +{ + struct pnode_base *nxtpb, *pb; + int err; + + /* + * Check for rename to self. + */ + if (old == new) + return 0; + + /* + * No xdev renames please. + */ + if (old->p_mount->mnt_fs != new->p_mount->mnt_fs) + return -EXDEV; + + /* + * Must not be a read-only mount. + * + * NB: Invariant old->p_mount->mnt_fs == new->p_mount->mnt_fs. + */ + if (IS_RDONLY(new)) + return -EROFS; + + /* + * Don't allow mount points to move. + */ + if (old->p_mount->mnt_root == old || + old->p_cover || + new->p_mount->mnt_root == new) + return -EBUSY; + + /* + * Make sure the old pnode can't be found in the ancestor chain + * for the new. If it can, they are trying to move into a subdirectory + * of the old. + */ + nxtpb = new->p_base; + do { + pb = nxtpb; + nxtpb = pb->pb_key.pbk_parent; + if (pb == old->p_base) + return -EINVAL; + } while (nxtpb); + + if (new->p_base->pb_ino) { + /* + * Existing entry. We're replacing the new. Make sure that's + * ok. + */ + if (S_ISDIR(new->p_base->pb_ino->i_stbuf.st_mode)) { + if (!S_ISDIR(old->p_base->pb_ino->i_stbuf.st_mode)) + return -EISDIR; + } else if (S_ISDIR(old->p_base->pb_ino->i_stbuf.st_mode)) + return -ENOTDIR; + } + + /* + * Give the op a try. + */ + err = PNOP_RENAME(old, new); + if (err) + return err; + /* + * Disconnect the old. + */ + _sysio_pb_disconnect(old->p_base); + /* + * Disconnect the new if positive. We want new lookups + * to find the just renamed entity. + */ + if (new->p_base->pb_ino) + _sysio_pb_disconnect(new->p_base); + return 0; +} + int SYSIO_INTERFACE_NAME(rename)(const char *oldpath, const char *newpath) { Index: rmdir.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/rmdir.c,v retrieving revision 1.23 retrieving revision 1.24 diff -u -w -b -B -p -r1.23 -r1.24 --- rmdir.c 17 Jun 2008 17:18:57 -0000 1.23 +++ rmdir.c 28 Jan 2009 16:13:19 -0000 1.24 @@ -54,6 +54,39 @@ #include "mount.h" #include "sysio-symbols.h" +/* + * Perform remove directory operation on some pnode. + */ +int +_sysio_p_rmdir(struct pnode *pno) +{ + int err; + + if (IS_RDONLY(pno)) + return -EROFS; + if (!pno->p_base->pb_ino) + return -ENOENT; /* huh? */ + if (!S_ISDIR(pno->p_base->pb_ino->i_stbuf.st_mode)) + return -ENOTDIR; + /* + * Don't allow unlink of a root or a mount point. + */ + if (pno->p_cover || pno->p_mount->mnt_root == pno) + return -EBUSY; + /* + * Call the FS implementation. + */ + err = PNOP_RMDIR(pno); + if (err) + return err; + /* + * Clean the namespace graphs to reflect the unlink. + */ + _sysio_i_undead(pno->p_base->pb_ino); + _sysio_pb_disconnect(pno->p_base); + return 0; +} + int SYSIO_INTERFACE_NAME(rmdir)(const char *path) { Index: rw.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/rw.c,v retrieving revision 1.30 retrieving revision 1.31 diff -u -w -b -B -p -r1.30 -r1.31 --- rw.c 11 Jul 2008 18:23:57 -0000 1.30 +++ rw.c 28 Jan 2009 16:13:19 -0000 1.31 @@ -201,36 +201,34 @@ _sysio_p_awrite(struct pnode *pno, } /* - * Post asynch IO operation using file handle. + * Post asynch IO operation using path-node. */ -static int -_sysio_iiox(int writing, - struct file *fil, +int +_sysio_p_iiox(int (*f)(struct ioctx *), + struct pnode *pno, + _SYSIO_OFF_T limit, const struct iovec *iov, size_t iov_count, void (*release_iov)(struct ioctx *, void *), const struct intnl_xtvec *xtv, size_t xtv_count, void (*release_xtv)(struct ioctx *, void *), void (*completio)(struct ioctx *, void *), + void *data, struct ioctx **ioctxp) { int err; ssize_t cc; - int (*f)(struct ioctx *); err = 0; do { - /* - * Opened for proper access? - */ - if (!FIL_CHKRW(fil, writing ? 'w' : 'r')) { - err = -EBADF; + if (f == NULL) { + err = -ENOTSUP; break; } /* * Is it live? */ - if (!fil->f_pno->p_base->pb_ino) { + if (!pno->p_base->pb_ino) { err = -EBADF; break; } @@ -239,37 +237,61 @@ _sysio_iiox(int writing, * Valid maps? */ cc = - _sysio_validx(xtv, xtv_count, iov, iov_count, -#if defined(_LARGEFILE64_SOURCE) && defined(O_LARGEFILE) - (fil->f_flags & O_LARGEFILE) - ? LONG_MAX - : -#endif - _SYSIO_OFF_T_MAX); + _sysio_validx(xtv, xtv_count, iov, iov_count, limit); if (cc < 0) { err = cc; break; } - f = - writing - ? PNOP_FUNC(fil->f_pno, write) - : PNOP_FUNC(fil->f_pno, read); - if (f == NULL) { - err = -ENOTSUP; - break; - } - /* * Post the operation. */ err = _sysio_post_io(f, + pno, + iov, iov_count, release_iov, + xtv, xtv_count, release_xtv, + completio, data, + ioctxp); + } while (0); + return err; +} + +/* + * Post asynch IO operation using file handle. + */ +static int +_sysio_iiox(direction writing, + struct file *fil, + const struct iovec *iov, size_t iov_count, + void (*release_iov)(struct ioctx *, void *), + const struct intnl_xtvec *xtv, size_t xtv_count, + void (*release_xtv)(struct ioctx *, void *), + void (*completio)(struct ioctx *, void *), + struct ioctx **ioctxp) +{ + int err; + + /* + * Opened for proper access? + */ + if (!FIL_CHKRW(fil, writing ? 'w' : 'r')) + return -EBADF; + err = + _sysio_p_iiox((writing + ? PNOP_FUNC(fil->f_pno, write) + : PNOP_FUNC(fil->f_pno, read)), fil->f_pno, + ( +#if defined(_LARGEFILE64_SOURCE) && defined(O_LARGEFILE) + (fil->f_flags & O_LARGEFILE) + ? LONG_MAX + : +#endif + _SYSIO_OFF_T_MAX), iov, iov_count, release_iov, xtv, xtv_count, release_xtv, completio, fil, ioctxp); - } while (0); return err; } @@ -317,10 +339,6 @@ _do_ireadx(int fd, err = -EBADF; break; } - if (fil->f_pno->p_base->pb_ino == NULL) { - err = -ESTALE; - break; - } err = _sysio_iiox(READ, fil, @@ -375,10 +393,6 @@ _do_iwritex(int fd, err = -EBADF; break; } - if (fil->f_pno->p_base->pb_ino == NULL) { - err = -ESTALE; - break; - } err = _sysio_iiox(WRITE, fil, @@ -916,10 +930,6 @@ _do_iiov(direction dir, } xtv->xtv_off = fil->f_pos; xtv->xtv_len = cc; - if (fil->f_pno->p_base->pb_ino == NULL) { - err = -ESTALE; - break; - } err = _sysio_iiox(dir, fil, Index: symlink.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/symlink.c,v retrieving revision 1.20 retrieving revision 1.21 diff -u -w -b -B -p -r1.20 -r1.21 --- symlink.c 17 Jun 2008 17:18:57 -0000 1.20 +++ symlink.c 28 Jan 2009 16:13:19 -0000 1.21 @@ -50,8 +50,24 @@ #include "sysio.h" #include "inode.h" +#include "mount.h" + #include "sysio-symbols.h" +/* + * Perform symlink operation; oldpath to new. + */ +int +_sysio_p_symlink(const char *oldpath, struct pnode *new) +{ + + if (new->p_base->pb_ino) + return -EEXIST; + if (IS_RDONLY(new->p_parent)) + return -EROFS; + return PNOP_SYMLINK(new, oldpath); +} + int SYSIO_INTERFACE_NAME(symlink)(const char *oldpath, const char *newpath) { Index: unlink.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/unlink.c,v retrieving revision 1.21 retrieving revision 1.22 diff -u -w -b -B -p -r1.21 -r1.22 --- unlink.c 17 Jun 2008 17:18:57 -0000 1.21 +++ unlink.c 28 Jan 2009 16:13:19 -0000 1.22 @@ -54,6 +54,34 @@ #include "mount.h" #include "sysio-symbols.h" +/* + * Perform unlink operation on some pnode. + */ +int +_sysio_p_unlink(struct pnode *pno) +{ + int err; + + if (IS_RDONLY(pno)) + return -EROFS; + if (!pno->p_base->pb_ino) + return -ENOENT; /* huh? */ + if (S_ISDIR(pno->p_base->pb_ino->i_stbuf.st_mode)) + return -EISDIR; + /* + * Call the FS implementation. + */ + err = PNOP_UNLINK(pno); + if (err) + return err; + /* + * Clean the namespace graphs to reflect the unlink. + */ + _sysio_i_undead(pno->p_base->pb_ino); + _sysio_pb_disconnect(pno->p_base); + return 0; +} + int SYSIO_INTERFACE_NAME(unlink)(const char *path) { |