Browse Source

UFS Keep vnode from open to close

Beginnings of code to read inode file data

Signed-off-by: Graham MacDonald <grahamamacdonald@gmail.com>
Graham MacDonald 6 years ago
parent
commit
a961f77242
4 changed files with 105 additions and 64 deletions
  1. 76 42
      sys/src/9/port/devufs.c
  2. 5 3
      sys/src/9/ufs/ufs_ext.h
  3. 11 1
      sys/src/9/ufs/ufs_harvey.c
  4. 13 18
      sys/src/9/ufs/ufs_mountpoint.c

+ 76 - 42
sys/src/9/port/devufs.c

@@ -233,16 +233,73 @@ ufsstat(Chan* c, uint8_t* dp, int32_t n)
 static Chan*
 ufsopen(Chan* c, int omode)
 {
-	return devopen(c, omode, nil, 0, ufsgen);
+	int qid = c->qid.path & ((1 << Qidshift)-1);
+
+	c = devopen(c, omode, nil, 0, ufsgen);
+
+	switch (qid) {
+	case Qinode:
+	case Qinodedata:
+	{
+		// We need to get the inode from the last element of the path
+		// We couldn't encode it anywhere, because it'll eventually
+		// be a 64-bit value.
+		char *str = malloc(strlen(c->path->s) + 1);
+		strcpy(str, c->path->s);
+
+		char *inoend = strrchr(str, '/');
+		if (!inoend) {
+			free(str);
+			error("invalid inode");
+		}
+		*inoend = '\0';
+
+		char *inostart = strrchr(str, '/');
+		if (!inostart) {
+			free(str);
+			error("invalid inode");
+		}
+		inostart++;
+
+		ino_t ino = strtoll(inostart, nil, 10);
+		free(str);
+		if (ino == 0) {
+			error("invalid inode");
+		}
+
+		vnode *vn = ufs_open_ino(mountpoint, ino);
+		c->aux = vn;
+		break;
+	}
+	default:
+		break;
+	}
+
+	return c;
 }
 
 static void
-ufsclose(Chan* unused)
+ufsclose(Chan* c)
 {
+	int qid = c->qid.path & ((1 << Qidshift)-1);
+	switch (qid) {
+	case Qinode:
+	case Qinodedata:
+	{
+		vnode *vn = (vnode*)c->aux;
+		if (!vn) {
+			error("no vnode to close");
+		}
+		releaseufsvnode(vn);		
+		break;
+	}
+	default:
+		break;
+	}
 }
 
 static int
-dumpstats(MountPoint *mp, void *a, int32_t n, int64_t offset)
+dumpstats(void *a, int32_t n, int64_t offset, MountPoint *mp)
 {
 	int i = 0;
 	char *buf = malloc(READSTR);
@@ -263,11 +320,11 @@ dumpstats(MountPoint *mp, void *a, int32_t n, int64_t offset)
 }
 
 static int
-dumpsuperblock(MountPoint *mp, void *a, int32_t n, int64_t offset)
+dumpsuperblock(void *a, int32_t n, int64_t offset, MountPoint *mp)
 {
 	char *buf = malloc(READSTR);
 
-	writesuperblock(mp, buf, READSTR);
+	writesuperblock(buf, READSTR, mp);
 	n = readstr(offset, a, n, buf);
 
 	free(buf);
@@ -276,11 +333,11 @@ dumpsuperblock(MountPoint *mp, void *a, int32_t n, int64_t offset)
 }
 
 static int
-dumpinode(MountPoint *mp, void *a, int32_t n, int64_t offset, ino_t ino)
+dumpinode(void *a, int32_t n, int64_t offset, vnode *vn)
 {
 	char *buf = malloc(READSTR);
 
-	writeinode(mp, buf, READSTR, ino);
+	writeinode(buf, READSTR, vn);
 	n = readstr(offset, a, n, buf);
 
 	free(buf);
@@ -289,11 +346,11 @@ dumpinode(MountPoint *mp, void *a, int32_t n, int64_t offset, ino_t ino)
 }
 
 static int
-dumpinodedata(MountPoint *mp, void *a, int32_t n, int64_t offset, ino_t ino)
+dumpinodedata(void *a, int32_t n, int64_t offset, vnode *vn)
 {
 	char *buf = malloc(READSTR);
 
-	writeinodedata(mp, buf, READSTR, ino);
+	writeinodedata(buf, READSTR, vn);
 	n = readstr(offset, a, n, buf);
 
 	free(buf);
@@ -312,45 +369,22 @@ ufsread(Chan *c, void *a, int32_t n, int64_t offset)
 
 	switch (qid) {
 	case Qmountstats:
-		n = dumpstats(mountpoint, a, n, offset);
+		n = dumpstats(a, n, offset, mountpoint);
 		break;
 	case Qsuperblock:
-		n = dumpsuperblock(mountpoint, a, n, offset);
+		n = dumpsuperblock(a, n, offset, mountpoint);
 		break;
 	case Qinode:
-	case Qinodedata:
 	{
-		// We need to get the inode from the last element of the path
-		// We couldn't encode it anywhere, because it'll eventually
-		// be a 64-bit value.
-		char *str = malloc(strlen(c->path->s) + 1);
-		strcpy(str, c->path->s);
-
-		char *inoend = strrchr(str, '/');
-		if (!inoend) {
-			free(str);
-			error("invalid inode");
-		}
-		*inoend = '\0';
-
-		char *inostart = strrchr(str, '/');
-		if (!inostart) {
-			free(str);
-			error("invalid inode");
-		}
-		inostart++;
-
-		ino_t ino = strtoll(inostart, nil, 10);
-		free(str);
-		if (ino == 0) {
-			error("invalid inode");
-		}
+		vnode *vn = (vnode*)c->aux;
+		n = dumpinode(a, n, offset, vn);
+		break;
+	}
 
-		if (qid == Qinode) {
-			n = dumpinode(mountpoint, a, n, offset, ino);
-		} else if (qid == Qinodedata) {
-			n = dumpinodedata(mountpoint, a, n, offset, ino);
-		}
+	case Qinodedata:
+	{
+		vnode *vn = (vnode*)c->aux;
+		n = dumpinodedata(a, n, offset, vn);
 		break;
 	}
 

+ 5 - 3
sys/src/9/ufs/ufs_ext.h

@@ -47,9 +47,9 @@ typedef struct MountPoint {
 MountPoint *newufsmount(Chan *c, int id);
 void releaseufsmount(MountPoint *mp);
 int countvnodes(vnode *vn);
-int writesuperblock(MountPoint *mp, char *buf, int buflen);
-int writeinode(MountPoint *mp, char *buf, int buflen, ino_t ino);
-int writeinodedata(MountPoint *mp, char *buf, int buflen, ino_t ino);
+int writesuperblock(char *buf, int buflen, MountPoint *mp);
+int writeinode(char *buf, int buflen, vnode *vn);
+int writeinodedata(char *buf, int buflen, vnode *vn);
 
 int ffs_init();
 int ffs_uninit();
@@ -61,3 +61,5 @@ int ufs_root(MountPoint *mp, int flags, vnode **vpp);
 int ufs_lookup(MountPoint *mp);
 
 int lookuppath(MountPoint *mp, char *path, vnode **vn);
+vnode *ufs_open_ino(MountPoint *mp, ino_t ino);
+void releaseufsvnode(vnode *vn);

+ 11 - 1
sys/src/9/ufs/ufs_harvey.c

@@ -24,7 +24,7 @@
 #include "ufs/quota.h"
 #include "ufs/inode.h"
 #include "ufs_extern.h"
-
+#include "ffs_extern.h"
 
 int
 findexistingvnode(MountPoint *mp, ino_t ino, vnode **vpp)
@@ -123,6 +123,16 @@ releaseufsvnode(vnode *vn)
 	releasevnode(vn);
 }
 
+vnode *
+ufs_open_ino(MountPoint *mp, ino_t ino) {
+	vnode *vn;
+	int rcode = ffs_vget(mp, ino, LK_SHARED, &vn);
+	if (rcode) {
+		error("cannot get file to open");
+	}
+	return vn;
+}
+
 int
 lookuppath(MountPoint *mp, char *path, vnode **vn)
 {

+ 13 - 18
sys/src/9/ufs/ufs_mountpoint.c

@@ -193,7 +193,7 @@ countvnodes(vnode* vn)
 }
 
 int
-writesuperblock(MountPoint *mp, char *buf, int buflen)
+writesuperblock(char *buf, int buflen, MountPoint *mp)
 {
 	qlock(&mp->mnt_lock);
 
@@ -272,18 +272,9 @@ writesuperblock(MountPoint *mp, char *buf, int buflen)
 }
 
 int
-writeinode(MountPoint *mp, char *buf, int buflen, ino_t ino)
+writeinode(char *buf, int buflen, vnode *vn)
 {
-	qlock(&mp->mnt_lock);
-
-	vnode *vp = nil;
-	int rcode = ffs_vget(mp, ino, LK_SHARED, &vp);
-	if (rcode != 0) {
-		qunlock(&mp->mnt_lock);
-		error("cannot dump inode");
-	}
-
-	inode *ip = vp->data;
+	inode *ip = vn->data;
 
 	int i = 0;
 	i += snprint(buf + i, buflen - i, "i_number\t%llu\n", (uint64_t)ip->i_number);
@@ -328,17 +319,21 @@ writeinode(MountPoint *mp, char *buf, int buflen, ino_t ino)
 	i += snprint(buf + i, buflen - i, "di_modrev\t%llu\n", din->di_modrev);
 	i += snprint(buf + i, buflen - i, "di_freelink\t%u\n", din->di_freelink);
 
-	releasevnode(vp);
-
-	qunlock(&mp->mnt_lock);
-
 	return i;
 }
 
 int
-writeinodedata(MountPoint *mp, char *buf, int buflen, ino_t ino)
+writeinodedata(char *buf, int buflen, vnode *vn)
 {
 	int i = 0;
-	i += snprint(buf + i, buflen - i, "inode file data goes here\n");
+
+	if (vn->type == VREG) {
+		i += snprint(buf + i, buflen - i, "regular file\n");
+	} else if (vn->type == VDIR) {
+		i += snprint(buf + i, buflen - i, "directory\n");
+	} else {
+		i += snprint(buf + i, buflen - i, "unsupported inode type (%d)\n", vn->type);
+	}
+
 	return i;
 }