[Libsysio-commit] HEAD: libsysio/src inode.c link.c
Brought to you by:
lward
From: Lee W. <lw...@us...> - 2007-11-20 17:49:29
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv31929/src Modified Files: inode.c link.c Log Message: Added _sysio_p_link and modified library entry-point to use it. Also, added IS_RDONLY checks to many pnode manipulation routines in inode.c Index: inode.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v retrieving revision 1.32 retrieving revision 1.33 diff -u -w -b -B -p -r1.32 -r1.33 --- inode.c 24 Sep 2007 18:00:39 -0000 1.32 +++ inode.c 20 Nov 2007 17:49:26 -0000 1.33 @@ -974,7 +974,7 @@ _sysio_p_setattr(struct pnode *pno, struct intnl_stat *stbuf) { - if (pno && IS_RDONLY(pno)) + if (IS_RDONLY(pno)) return -EROFS; /* @@ -985,6 +985,38 @@ _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; + new->p_base->pb_ino = old->p_base->pb_ino; + I_REF(new->p_base->pb_ino); + return 0; +} + +/* * Perform unlink operation on some pnode. */ int @@ -992,6 +1024,8 @@ _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)) @@ -1010,13 +1044,15 @@ _sysio_p_unlink(struct pnode *pno) } /* - * Perform unlink operation on some pnode. + * 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)) @@ -1039,6 +1075,9 @@ _sysio_p_rmdir(struct pnode *pno) return 0; } +/* + * Perform rename operation on some pnode. + */ int _sysio_p_rename(struct pnode *old, struct pnode *new) { @@ -1058,6 +1097,14 @@ _sysio_p_rename(struct pnode *old, struc 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 || Index: link.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/link.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -w -b -B -p -r1.14 -r1.15 --- link.c 2 Jul 2007 18:58:16 -0000 1.14 +++ link.c 20 Nov 2007 17:49:26 -0000 1.15 @@ -63,47 +63,25 @@ SYSIO_INTERFACE_NAME(link)(const char *o SYSIO_INTERFACE_DISPLAY_BLOCK; SYSIO_INTERFACE_ENTER(link, "%s%s", oldpath, newpath); + old = new = NULL; + err = 0; + do { INTENT_INIT(&intent, 0, NULL, NULL); - err = _sysio_namei(_sysio_cwd, oldpath, 0, &intent, &old); + err = + _sysio_namei(_sysio_cwd, oldpath, 0, &intent, &old); if (err) - goto out; - if (S_ISDIR(old->p_base->pb_ino->i_stbuf.st_mode)) { - err = -EPERM; - goto error1; - } + break; INTENT_INIT(&intent, INT_UPDPARENT, NULL, NULL); - new = NULL; - err = _sysio_namei(_sysio_cwd, newpath, ND_NEGOK, &intent, &new); + err = + _sysio_namei(_sysio_cwd, newpath, ND_NEGOK, &intent, &new); if (err) - goto error1; - if (new->p_base->pb_ino) { - err = -EEXIST; - goto error2; - } - if (old->p_mount->mnt_root != new->p_mount->mnt_root) { - err = -EXDEV; - goto error2; - } - /* - * Use the parent node operations to request the task in case the - * driver is implemented using differentiated inode operations based - * on file type, such as incore does. - */ - err = PNOP_LINK(old, new); - if (err) - goto error2; - /* - * The new p-node must be pointed at the inode referenced by the old. - */ - assert(!new->p_base->pb_ino && old->p_base->pb_ino); - new->p_base->pb_ino = old->p_base->pb_ino; - I_REF(new->p_base->pb_ino); - -error2: + break; + err = _sysio_p_link(old, new); + } while (0); + if (new) P_RELE(new); -error1: + if (old) P_RELE(old); -out: SYSIO_INTERFACE_RETURN(err ? -1 : 0, err, link, "%d", 0); } |