more from dave swasey
This commit is contained in:
parent
6322b295cf
commit
d28cfee19e
2 changed files with 80 additions and 12 deletions
|
|
@ -2,7 +2,6 @@
|
||||||
Copyright (c) 2007 David Swasey; see COPYRIGHT.
|
Copyright (c) 2007 David Swasey; see COPYRIGHT.
|
||||||
Limitations:
|
Limitations:
|
||||||
Hfsreaddir skips entries whose names contain NUL.
|
Hfsreaddir skips entries whose names contain NUL.
|
||||||
Simulated hard links are ignored.
|
|
||||||
Hfsbadblock is untested.
|
Hfsbadblock is untested.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -22,6 +21,7 @@ enum { Rplen = nelem(Rprefix)-1 };
|
||||||
static int hfssync(Fsys*);
|
static int hfssync(Fsys*);
|
||||||
static int hfswrapper(Fsys*);
|
static int hfswrapper(Fsys*);
|
||||||
static int hfstreesync(Hfs*, Fork*, Tree*, int);
|
static int hfstreesync(Hfs*, Fork*, Tree*, int);
|
||||||
|
static u32int hfsmetadir(Hfs*);
|
||||||
static void hfsclose(Fsys*);
|
static void hfsclose(Fsys*);
|
||||||
static Block* hfsblockread(Fsys*, u64int);
|
static Block* hfsblockread(Fsys*, u64int);
|
||||||
|
|
||||||
|
|
@ -29,7 +29,7 @@ static Nfs3Status hfsroot(Fsys*, Nfs3Handle*);
|
||||||
static Nfs3Status hfsgetattr(Fsys*, SunAuthUnix*, Nfs3Handle*, Nfs3Attr*);
|
static Nfs3Status hfsgetattr(Fsys*, SunAuthUnix*, Nfs3Handle*, Nfs3Attr*);
|
||||||
static Nfs3Status hfsaccess(Fsys *fsys, SunAuthUnix*, Nfs3Handle *, u32int, u32int*, Nfs3Attr *attr);
|
static Nfs3Status hfsaccess(Fsys *fsys, SunAuthUnix*, Nfs3Handle *, u32int, u32int*, Nfs3Attr *attr);
|
||||||
static Nfs3Status hfslookup(Fsys*, SunAuthUnix*, Nfs3Handle*, char*, Nfs3Handle*);
|
static Nfs3Status hfslookup(Fsys*, SunAuthUnix*, Nfs3Handle*, char*, Nfs3Handle*);
|
||||||
static Nfs3Status _hfslookup(Hfs*, u32int, char*, Catalogkey*, Treeref*);
|
static Nfs3Status _hfslookup(Hfs*, u32int, char*, Treeref*);
|
||||||
static Nfs3Status hfsreaddir(Fsys *fsys, SunAuthUnix*, Nfs3Handle *h, u32int, u64int, uchar**, u32int*, u1int*);
|
static Nfs3Status hfsreaddir(Fsys *fsys, SunAuthUnix*, Nfs3Handle *h, u32int, u64int, uchar**, u32int*, u1int*);
|
||||||
static Nfs3Status hfsreadfile(Fsys*, SunAuthUnix*, Nfs3Handle*, u32int, u64int, uchar**, u32int*, u1int*);
|
static Nfs3Status hfsreadfile(Fsys*, SunAuthUnix*, Nfs3Handle*, u32int, u64int, uchar**, u32int*, u1int*);
|
||||||
static Nfs3Status hfsreadlink(Fsys*, SunAuthUnix*, Nfs3Handle*, char**);
|
static Nfs3Status hfsreadlink(Fsys*, SunAuthUnix*, Nfs3Handle*, char**);
|
||||||
|
|
@ -206,6 +206,7 @@ hfssync(Fsys *fsys)
|
||||||
goto error;
|
goto error;
|
||||||
if(hfstreesync(fs, &fs->catalogfork, &fs->catalog, sensitive) < 0)
|
if(hfstreesync(fs, &fs->catalogfork, &fs->catalog, sensitive) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
fs->hlinkparent = hfsmetadir(fs);
|
||||||
|
|
||||||
fsys->blocksize = fs->blocksize;
|
fsys->blocksize = fs->blocksize;
|
||||||
fsys->nblock = fs->nblock;
|
fsys->nblock = fs->nblock;
|
||||||
|
|
@ -258,6 +259,33 @@ error:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32int
|
||||||
|
hfsmetadir(Hfs *fs)
|
||||||
|
{
|
||||||
|
static Rune name[] = {0,0,0,0,'H','F','S','+',' ','P','r','i','v','a','t','e',' ','D','a','t','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
|
static int
|
||||||
hfsbadblock(Hfs *fs, u32int bno)
|
hfsbadblock(Hfs *fs, u32int bno)
|
||||||
{
|
{
|
||||||
|
|
@ -327,6 +355,42 @@ useresource(Inode *ino)
|
||||||
ino->fork = &ino->rfork;
|
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
|
static void
|
||||||
mkhandle(Nfs3Handle *h, int rsrc, u32int cnid)
|
mkhandle(Nfs3Handle *h, int rsrc, u32int cnid)
|
||||||
{
|
{
|
||||||
|
|
@ -377,7 +441,7 @@ handle2ino(Hfs *fs, Nfs3Handle *h, Treeref *ref, Catalogkey *key, Inode *ino)
|
||||||
if(hfscatsearch(fs, key, ref) < 0)
|
if(hfscatsearch(fs, key, ref) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
if(ino != nil){
|
if(ino != nil){
|
||||||
if(getcatalogrecord(ino, ref->data, ref->dlen) < 0)
|
if(ref2ino(fs, ref, ino) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
if(rsrc){
|
if(rsrc){
|
||||||
if(!hasresource(ino)){
|
if(!hasresource(ino)){
|
||||||
|
|
@ -431,7 +495,7 @@ ino2attr(Hfs *fs, Inode *ino, Nfs3Attr *attr)
|
||||||
}
|
}
|
||||||
|
|
||||||
attr->mode = ino->mode&07777;
|
attr->mode = ino->mode&07777;
|
||||||
attr->nlink = 1;
|
attr->nlink = ino->nlink;
|
||||||
attr->uid = ino->uid;
|
attr->uid = ino->uid;
|
||||||
attr->gid = ino->gid;
|
attr->gid = ino->gid;
|
||||||
if(attr->type==Nfs3FileReg || attr->type==Nfs3FileSymlink){
|
if(attr->type==Nfs3FileReg || attr->type==Nfs3FileSymlink){
|
||||||
|
|
@ -603,14 +667,14 @@ hfslookup(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, char *name, Nfs3Handle *nh
|
||||||
}
|
}
|
||||||
|
|
||||||
rsrc = 0;
|
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
|
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;
|
rsrc = 1;
|
||||||
else
|
else
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
if(getcatalogrecord(&target, ref.data, ref.dlen) < 0)
|
if(ref2ino(fs, &ref, &target) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
hfsrefput(&ref);
|
hfsrefput(&ref);
|
||||||
if(rsrc && !hasresource(&target))
|
if(rsrc && !hasresource(&target))
|
||||||
|
|
@ -624,14 +688,15 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
static Nfs3Status
|
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;
|
Nfs3Status ok;
|
||||||
|
|
||||||
key->parent = parent;
|
key.parent = parent;
|
||||||
if((ok = utf2name(&key->name, name)) != Nfs3Ok)
|
if((ok = utf2name(&key.name, name)) != Nfs3Ok)
|
||||||
return ok;
|
return ok;
|
||||||
if(hfscatsearch(fs, key, ref) < 0)
|
if(hfscatsearch(fs, &key, ref) < 0)
|
||||||
return Nfs3ErrNoEnt;
|
return Nfs3ErrNoEnt;
|
||||||
return Nfs3Ok;
|
return Nfs3Ok;
|
||||||
}
|
}
|
||||||
|
|
@ -730,7 +795,7 @@ hfsreaddir(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int count,
|
||||||
goto error;
|
goto error;
|
||||||
if(key.parent != ino.cnid)
|
if(key.parent != ino.cnid)
|
||||||
goto badparent;
|
goto badparent;
|
||||||
if(getcatalogrecord(&child, ref.data, ref.dlen) < 0)
|
if(ref2ino(fs, &ref, &child) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
else if(!hasresource(&child))
|
else if(!hasresource(&child))
|
||||||
|
|
@ -1356,6 +1421,7 @@ getcatalogrecord(Inode *ino, uchar *b, int blen)
|
||||||
ino->ctime = gettime(b+20);
|
ino->ctime = gettime(b+20);
|
||||||
ino->atime = gettime(b+24);
|
ino->atime = gettime(b+24);
|
||||||
p = b+32;
|
p = b+32;
|
||||||
|
ino->nlink = 1;
|
||||||
ino->uid = get32(p+0);
|
ino->uid = get32(p+0);
|
||||||
ino->gid = get32(p+4);
|
ino->gid = get32(p+4);
|
||||||
ino->mode = get16(p+10);
|
ino->mode = get16(p+10);
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,7 @@ struct Inode
|
||||||
u32int mtime; /* modification */
|
u32int mtime; /* modification */
|
||||||
u32int ctime; /* attribute modification */
|
u32int ctime; /* attribute modification */
|
||||||
u32int atime; /* access */
|
u32int atime; /* access */
|
||||||
|
u32int nlink; /* in memory only */
|
||||||
u32int uid;
|
u32int uid;
|
||||||
u32int gid;
|
u32int gid;
|
||||||
int mode;
|
int mode;
|
||||||
|
|
@ -213,6 +214,7 @@ struct Hfs
|
||||||
Fork catalogfork;
|
Fork catalogfork;
|
||||||
Tree extents; /* Extentkey -> Extent[NEXTENT] */
|
Tree extents; /* Extentkey -> Extent[NEXTENT] */
|
||||||
Tree catalog; /* Catalogkey -> Catalogkey + Inode */
|
Tree catalog; /* Catalogkey -> Catalogkey + Inode */
|
||||||
|
u32int hlinkparent; /* 0 or cnid */
|
||||||
Disk *disk;
|
Disk *disk;
|
||||||
Fsys *fsys;
|
Fsys *fsys;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue