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);
}
|