X-Git-Url: http://dolda2000.com/gitweb/?p=vcfs.git;a=blobdiff_plain;f=vcfs.c;h=8529eb36e4df1ff294f192b019d7784fef24ac41;hp=0a49f491d7d6acfd923e82bad613713e2fc73cb6;hb=HEAD;hpb=d5cf535197d5090554453b6357867d782f0d1484 diff --git a/vcfs.c b/vcfs.c index 0a49f49..8529eb3 100644 --- a/vcfs.c +++ b/vcfs.c @@ -226,7 +226,7 @@ static struct vcfsdata *initvcfs(char *dir) } fsd->inocser = 1; cacheinode(fsd, 0, nilnode); - if((fsd->nextino = btcount(fsd->st, &fsd->inotab)) < 0) { + if((fsd->nextino = btcount(fsd->st, &fsd->inotab, INOBLSIZE)) < 0) { flog(LOG_ERR, "could not count inodes: %s"); close(fsd->revfd); releasestore(fsd->st); @@ -243,7 +243,7 @@ static vc_ino_t dirlookup(struct vcfsdata *fsd, struct btnode *dirdata, const ch ssize_t sz; for(i = 0; ; i++) { - if((sz = btget(fsd->st, dirdata, i, &dent, sizeof(dent))) < 0) { + if((sz = btget(fsd->st, dirdata, i, &dent, sizeof(dent), DIRBLSIZE)) < 0) { if(errno == ERANGE) errno = ENOENT; return(-1); @@ -279,7 +279,7 @@ static int getinode(struct vcfsdata *fsd, struct btnode inotab, vc_ino_t ino, st if(inotab.d == 0) inotab = fsd->inotab; - if((sz = btget(fsd->st, &inotab, ino, buf, sizeof(*buf))) < 0) + if((sz = btget(fsd->st, &inotab, ino, buf, sizeof(*buf), INOBLSIZE)) < 0) return(-1); if(sz != sizeof(*buf)) { flog(LOG_ERR, "illegal size for inode %i", ino); @@ -307,6 +307,7 @@ static void fusegetattr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *f return; } fillstat(&sb, &file); + sb.st_ino = ino; fuse_reply_attr(req, &sb, 0); } @@ -338,6 +339,7 @@ static void fuselookup(fuse_req_t req, fuse_ino_t parent, const char *name) memset(&e, 0, sizeof(e)); e.ino = cacheinode(fsd, target, inoc->inotab); fillstat(&e.attr, &file); + e.attr.st_ino = e.ino; fuse_reply_entry(req, &e); } @@ -364,7 +366,7 @@ static void fusereaddir(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, buf = NULL; while(bsz < size) { memset(&dent, 0, sizeof(dent)); - if((sz = btget(fsd->st, &file.data, off++, &dent, sizeof(dent))) < 0) { + if((sz = btget(fsd->st, &file.data, off++, &dent, sizeof(dent), DIRBLSIZE)) < 0) { if(errno == ERANGE) { if(buf != NULL) break; @@ -408,11 +410,27 @@ static vc_rev_t commit(struct vcfsdata *fsd, struct btnode inotab) static int deldentry(struct vcfsdata *fsd, struct inode *ino, int di) { + struct btop ops[2]; + struct dentry dent; + ssize_t sz; + if((di < 0) || (di >= ino->size)) { errno = ERANGE; return(-1); } - + if(di == ino->size - 1) { + if(btput(fsd->st, &ino->data, ino->size - 1, NULL, 0, DIRBLSIZE)) + return(-1); + } else { + if((sz = btget(fsd->st, &ino->data, ino->size - 1, &dent, sizeof(dent), DIRBLSIZE)) < 0) + return(-1); + btmkop(ops + 0, di, &dent, sz); + btmkop(ops + 1, ino->size - 1, NULL, 0); + if(btputmany(fsd->st, &ino->data, ops, 2, DIRBLSIZE)) + return(-1); + } + ino->size--; + return(0); } static int setdentry(struct vcfsdata *fsd, struct inode *ino, int di, const char *name, vc_ino_t target) @@ -429,12 +447,12 @@ static int setdentry(struct vcfsdata *fsd, struct inode *ino, int di, const char dent.inode = target; sz = sizeof(dent) - sizeof(dent.name) + strlen(name) + 1; if((di == -1) || (di == ino->size)) { - if(btput(fsd->st, &ino->data, ino->size, &dent, sz)) + if(btput(fsd->st, &ino->data, ino->size, &dent, sz, DIRBLSIZE)) return(-1); ino->size++; return(0); } - return(btput(fsd->st, &ino->data, di, &dent, sz)); + return(btput(fsd->st, &ino->data, di, &dent, sz, DIRBLSIZE)); } static void fusemkdir(fuse_req_t req, fuse_ino_t parent, const char *name, mode_t mode) @@ -490,7 +508,7 @@ static void fusemkdir(fuse_req_t req, fuse_ino_t parent, const char *name, mode_ file.links++; btmkop(ops + 0, inoc->inode, &file, sizeof(file)); btmkop(ops + 1, fsd->nextino, &new, sizeof(new)); - if(btputmany(fsd->st, &inotab, ops, 2)) { + if(btputmany(fsd->st, &inotab, ops, 2, INOBLSIZE)) { fuse_reply_err(req, errno); return; } @@ -509,15 +527,17 @@ static void fusemkdir(fuse_req_t req, fuse_ino_t parent, const char *name, mode_ memset(&e, 0, sizeof(e)); e.ino = cacheinode(fsd, fsd->nextino++, nilnode); fillstat(&e.attr, &new); + e.attr.st_ino = e.ino; fuse_reply_entry(req, &e); } -static void fusermdir(fuse_req_t req, fuse_ino_t parent, const char *name) +static void fuseunlink(fuse_req_t req, fuse_ino_t parent, const char *name) { struct vcfsdata *fsd; struct inoc *inoc; struct inode file; int di; + struct btnode inotab; fsd = fuse_req_userdata(req); if((inoc = getinocbf(fsd, parent)) == NULL) { @@ -540,6 +560,17 @@ static void fusermdir(fuse_req_t req, fuse_ino_t parent, const char *name) fuse_reply_err(req, ENOENT); return; } + inotab = fsd->inotab; + if(deldentry(fsd, &file, di)) { + fuse_reply_err(req, errno); + return; + } + if(btput(fsd->st, &inotab, inoc->inode, &file, sizeof(file), INOBLSIZE)) { + fuse_reply_err(req, errno); + return; + } + commit(fsd, inotab); + fuse_reply_err(req, 0); } static struct fuse_lowlevel_ops fuseops = { @@ -548,7 +579,8 @@ static struct fuse_lowlevel_ops fuseops = { .getattr = fusegetattr, .readdir = fusereaddir, .mkdir = fusemkdir, - .rmdir = fusermdir, + .rmdir = fuseunlink, + .unlink = fuseunlink, }; int main(int argc, char **argv)