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