tmore from dave swasey - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit d28cfee19e748c6a1fffa1ef2eb37ec3ea0fadd0 | |
parent 6322b295cf737c785f39efa978522b0a7da5e6fa | |
Author: rsc <devnull@localhost> | |
Date: Mon, 18 Jun 2007 15:24:25 +0000 | |
more from dave swasey | |
Diffstat: | |
M src/libdiskfs/hfs.c | 90 +++++++++++++++++++++++++++--… | |
M src/libdiskfs/hfs.h | 2 ++ | |
2 files changed, 80 insertions(+), 12 deletions(-) | |
--- | |
diff --git a/src/libdiskfs/hfs.c b/src/libdiskfs/hfs.c | |
t@@ -2,7 +2,6 @@ | |
Copyright (c) 2007 David Swasey; see COPYRIGHT. | |
Limitations: | |
Hfsreaddir skips entries whose names contain NUL. | |
- Simulated hard links are ignored. | |
Hfsbadblock is untested. | |
*/ | |
t@@ -22,6 +21,7 @@ enum { Rplen = nelem(Rprefix)-1 }; | |
static int hfssync(Fsys*); | |
static int hfswrapper(Fsys*); | |
static int hfstreesync(Hfs*, Fork*, Tree*, int); | |
+static u32int hfsmetadir(Hfs*); | |
static void hfsclose(Fsys*); | |
static Block* hfsblockread(Fsys*, u64int); | |
t@@ -29,7 +29,7 @@ static Nfs3Status hfsroot(Fsys*, Nfs3Handle*); | |
static Nfs3Status hfsgetattr(Fsys*, SunAuthUnix*, Nfs3Handle*, Nfs3Attr*); | |
static Nfs3Status hfsaccess(Fsys *fsys, SunAuthUnix*, Nfs3Handle *, u32int, u3… | |
static Nfs3Status hfslookup(Fsys*, SunAuthUnix*, Nfs3Handle*, char*, Nfs3Handl… | |
-static Nfs3Status _hfslookup(Hfs*, u32int, char*, Catalogkey*, Treeref*); | |
+static Nfs3Status _hfslookup(Hfs*, u32int, char*, Treeref*); | |
static Nfs3Status hfsreaddir(Fsys *fsys, SunAuthUnix*, Nfs3Handle *h, u32int, … | |
static Nfs3Status hfsreadfile(Fsys*, SunAuthUnix*, Nfs3Handle*, u32int, u64int… | |
static Nfs3Status hfsreadlink(Fsys*, SunAuthUnix*, Nfs3Handle*, char**); | |
t@@ -206,6 +206,7 @@ hfssync(Fsys *fsys) | |
goto error; | |
if(hfstreesync(fs, &fs->catalogfork, &fs->catalog, sensitive) < 0) | |
goto error; | |
+ fs->hlinkparent = hfsmetadir(fs); | |
fsys->blocksize = fs->blocksize; | |
fsys->nblock = fs->nblock; | |
t@@ -258,6 +259,33 @@ error: | |
return -1; | |
} | |
+static u32int | |
+hfsmetadir(Hfs *fs) | |
+{ | |
+ static Rune name[] = {0,0,0,0,'H','F','S','+',' ','P','r','i','v','a',… | |
+ Catalogkey key; | |
+ Treeref ref; | |
+ Inode ino; | |
+ | |
+ key.parent = RootId; | |
+ key.name.len = nelem(name); | |
+ memcpy(key.name.name, name, sizeof name); | |
+ if(hfscatsearch(fs, &key, &ref) < 0) | |
+ goto notfound; | |
+ if(getcatalogrecord(&ino, ref.data, ref.dlen) < 0) | |
+ goto notfound; | |
+ if((ino.mode&IFMT) != IFDIR) | |
+ goto notfound; | |
+ hfsrefput(&ref); | |
+ if(debug) fprint(2, "metadata directory %ud\n", ino.cnid); | |
+ return ino.cnid; | |
+ | |
+notfound: | |
+ if(debug) fprint(2, "metadata directory not found\n"); | |
+ hfsrefput(&ref); | |
+ return 0; | |
+} | |
+ | |
static int | |
hfsbadblock(Hfs *fs, u32int bno) | |
{ | |
t@@ -327,6 +355,42 @@ useresource(Inode *ino) | |
ino->fork = &ino->rfork; | |
} | |
+static int | |
+ref2ino(Hfs *fs, Treeref *ref, Inode *ino) | |
+{ | |
+ static uchar magic[] = {'h','l','n','k','h','f','s','+'}; | |
+ Catalogkey key; | |
+ Treeref hlink; | |
+ u32int cnid; | |
+ | |
+ if(getcatalogrecord(ino, ref->data, ref->dlen) < 0) | |
+ return -1; | |
+ | |
+ if((ino->mode&IFMT) == IFREG | |
+ && memcmp(ino->info, magic, nelem(magic)) == 0){ | |
+ if(debug) print("iNode%ud...", ino->special); | |
+ if(fs->hlinkparent == 0) | |
+ return -1; | |
+ key.parent = fs->hlinkparent; | |
+ key.name.len = runesnprint(key.name.name, sizeof key.name.name, | |
+ "iNode%ud", ino->special); | |
+ if(hfscatsearch(fs, &key, &hlink) < 0) | |
+ goto error; | |
+ cnid = ino->cnid; | |
+ if(getcatalogrecord(ino, hlink.data, hlink.dlen) < 0) | |
+ goto error; | |
+ hfsrefput(&hlink); | |
+ ino->cnid = cnid; | |
+ ino->fileid = cnid; | |
+ ino->nlink = ino->special; | |
+ } | |
+ return 0; | |
+ | |
+error: | |
+ hfsrefput(&hlink); | |
+ return -1; | |
+} | |
+ | |
static void | |
mkhandle(Nfs3Handle *h, int rsrc, u32int cnid) | |
{ | |
t@@ -377,7 +441,7 @@ handle2ino(Hfs *fs, Nfs3Handle *h, Treeref *ref, Catalogke… | |
if(hfscatsearch(fs, key, ref) < 0) | |
goto error; | |
if(ino != nil){ | |
- if(getcatalogrecord(ino, ref->data, ref->dlen) < 0) | |
+ if(ref2ino(fs, ref, ino) < 0) | |
goto error; | |
if(rsrc){ | |
if(!hasresource(ino)){ | |
t@@ -431,7 +495,7 @@ ino2attr(Hfs *fs, Inode *ino, Nfs3Attr *attr) | |
} | |
attr->mode = ino->mode&07777; | |
- attr->nlink = 1; | |
+ attr->nlink = ino->nlink; | |
attr->uid = ino->uid; | |
attr->gid = ino->gid; | |
if(attr->type==Nfs3FileReg || attr->type==Nfs3FileSymlink){ | |
t@@ -603,14 +667,14 @@ hfslookup(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, ch… | |
} | |
rsrc = 0; | |
- if((ok = _hfslookup(fs, ino.cnid, name, &key, &ref)) != Nfs3Ok){ | |
+ if((ok = _hfslookup(fs, ino.cnid, name, &ref)) != Nfs3Ok){ | |
if(memcmp(name, Rprefix, Rplen)==0 | |
- && _hfslookup(fs, ino.cnid, name+Rplen, &key, &ref)==Nfs3Ok) | |
+ && _hfslookup(fs, ino.cnid, name+Rplen, &ref)==Nfs3Ok) | |
rsrc = 1; | |
else | |
return ok; | |
} | |
- if(getcatalogrecord(&target, ref.data, ref.dlen) < 0) | |
+ if(ref2ino(fs, &ref, &target) < 0) | |
goto error; | |
hfsrefput(&ref); | |
if(rsrc && !hasresource(&target)) | |
t@@ -624,14 +688,15 @@ error: | |
} | |
static Nfs3Status | |
-_hfslookup(Hfs *fs, u32int parent, char *name, Catalogkey *key, Treeref *ref) | |
+_hfslookup(Hfs *fs, u32int parent, char *name, Treeref *ref) | |
{ | |
+ Catalogkey key; | |
Nfs3Status ok; | |
- key->parent = parent; | |
- if((ok = utf2name(&key->name, name)) != Nfs3Ok) | |
+ key.parent = parent; | |
+ if((ok = utf2name(&key.name, name)) != Nfs3Ok) | |
return ok; | |
- if(hfscatsearch(fs, key, ref) < 0) | |
+ if(hfscatsearch(fs, &key, ref) < 0) | |
return Nfs3ErrNoEnt; | |
return Nfs3Ok; | |
} | |
t@@ -730,7 +795,7 @@ hfsreaddir(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32… | |
goto error; | |
if(key.parent != ino.cnid) | |
goto badparent; | |
- if(getcatalogrecord(&child, ref.data, ref.dlen) < 0) | |
+ if(ref2ino(fs, &ref, &child) < 0) | |
goto error; | |
} | |
else if(!hasresource(&child)) | |
t@@ -1356,6 +1421,7 @@ getcatalogrecord(Inode *ino, uchar *b, int blen) | |
ino->ctime = gettime(b+20); | |
ino->atime = gettime(b+24); | |
p = b+32; | |
+ ino->nlink = 1; | |
ino->uid = get32(p+0); | |
ino->gid = get32(p+4); | |
ino->mode = get16(p+10); | |
diff --git a/src/libdiskfs/hfs.h b/src/libdiskfs/hfs.h | |
t@@ -120,6 +120,7 @@ struct Inode | |
u32int mtime; /* modification */ | |
u32int ctime; /* attribute modification */ | |
u32int atime; /* access */ | |
+ u32int nlink; /* in memory only */ | |
u32int uid; | |
u32int gid; | |
int mode; | |
t@@ -213,6 +214,7 @@ struct Hfs | |
Fork catalogfork; | |
Tree extents; /* Extentkey -> Extent[NEXTENT] */ | |
Tree catalog; /* Catalogkey -> Catalogkey + Inod… | |
+ u32int hlinkparent; /* 0 or cnid */ | |
Disk *disk; | |
Fsys *fsys; | |
}; |