added more fuse functions
This commit is contained in:
parent
794edb07d5
commit
3c8f2caa10
1 changed files with 226 additions and 105 deletions
|
@ -1,10 +1,3 @@
|
||||||
/*
|
|
||||||
FUSE: Filesystem in Userspace
|
|
||||||
Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
|
|
||||||
|
|
||||||
This program can be distributed under the terms of the GNU GPL.
|
|
||||||
See the file COPYING.
|
|
||||||
*/
|
|
||||||
#include <stasis/transactional.h>
|
#include <stasis/transactional.h>
|
||||||
|
|
||||||
#define FUSE_USE_VERSION 26
|
#define FUSE_USE_VERSION 26
|
||||||
|
@ -21,29 +14,137 @@ typedef struct {
|
||||||
} stasis_dir_entry;
|
} stasis_dir_entry;
|
||||||
|
|
||||||
static int stasis_lookup_helper(const char *path, stasis_dir_entry** subentry) {
|
static int stasis_lookup_helper(const char *path, stasis_dir_entry** subentry) {
|
||||||
return ThashLookup(-1, ROOT_RECORD, (byte*)path, strlen(path)+1, (byte**)subentry);
|
return ThashLookup(-1, ROOT_RECORD, (byte*)path, strlen(path)+1,
|
||||||
|
(byte**)subentry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int stasis_link_dirent(int xid, const char * path) {
|
||||||
|
char * parentbuf = strdup(path);
|
||||||
|
char * parent = dirname(parentbuf);
|
||||||
|
printf("attaching to parent %s\n", parent); fflush(stdout);
|
||||||
|
char * filebuf = strdup(path);
|
||||||
|
char * file = basename(filebuf);
|
||||||
|
stasis_dir_entry * entry;
|
||||||
|
printf("lu ->%s<- %d\n", parent, (int)strlen(parent)+1);fflush(stdout);
|
||||||
|
int entrylen = ThashLookup(xid, ROOT_RECORD,
|
||||||
|
(const byte*)parent, strlen(parent)+1,
|
||||||
|
(byte**)&entry);
|
||||||
|
printf("entrylen %d\n",entrylen); fflush(stdout);
|
||||||
|
if(entrylen == -1) {
|
||||||
|
return -ENOENT;
|
||||||
|
} else {
|
||||||
|
const char * next;
|
||||||
|
for(next = (const char*)(entry+1);
|
||||||
|
next != ((char*)entry) + entrylen;
|
||||||
|
next += (strlen(next)+1)) {
|
||||||
|
assert(next < ((char*)entry)+entrylen);
|
||||||
|
printf("next: %s\n", next); fflush(stdout);fflush(stdout);
|
||||||
|
if(0 == strcmp(next, path)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("forloop done\n"); fflush(stdout);
|
||||||
|
if(next == ((char*)entry)+entrylen) {
|
||||||
|
printf("inserting %s\n", path); fflush(stdout);
|
||||||
|
int newentrylen = entrylen+strlen(file)+1;
|
||||||
|
|
||||||
|
entry = realloc(entry, newentrylen);
|
||||||
|
strcpy(((char*)entry)+entrylen,file);
|
||||||
|
|
||||||
|
printf("parent ->%s<- %d; newlen=%d\n", parent, (int)strlen(parent)+1,
|
||||||
|
newentrylen);fflush(stdout);
|
||||||
|
|
||||||
|
ThashInsert(xid, ROOT_RECORD, (const byte*)parent, strlen(parent)+1,
|
||||||
|
(const byte*)entry, newentrylen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("returning 0\n"); fflush(stdout);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int stasis_unlink_dirent(int xid, const char * path) {
|
||||||
|
|
||||||
|
printf("in unlink\n"); fflush(stdout);
|
||||||
|
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
char * pathcpy1 = strdup(path);
|
||||||
|
char * pathcpy2 = strdup(path);
|
||||||
|
|
||||||
|
char * base = basename(pathcpy1);
|
||||||
|
char * dir = dirname(pathcpy2);
|
||||||
|
|
||||||
|
// remove from parent
|
||||||
|
stasis_dir_entry * parent;
|
||||||
|
ssize_t parentsz = ThashLookup(xid, ROOT_RECORD,
|
||||||
|
(const byte*)dir,strlen(dir)+1,
|
||||||
|
(byte**)&parent);
|
||||||
|
assert(parentsz != -1);
|
||||||
|
|
||||||
|
size_t newentsz = parentsz - (strlen(base)+1);
|
||||||
|
|
||||||
|
byte * newent = malloc(newentsz);
|
||||||
|
memcpy(newent, parent, sizeof(*parent));
|
||||||
|
byte * newnext = newent + sizeof(*parent);
|
||||||
|
int found = 0;
|
||||||
|
for(char* next = (char*)(parent+1);
|
||||||
|
next != ((char*)parent)+parentsz;
|
||||||
|
next += (1+strlen(next))) {
|
||||||
|
assert(next < ((char*)parent)+parentsz);
|
||||||
|
printf("%s %s\n", base, next);
|
||||||
|
if(strcmp(base,next)) {
|
||||||
|
assert(((char*)newnext + strlen(next)+1) <= ((char*)newent)+newentsz);
|
||||||
|
strcat((char*)newnext,next);
|
||||||
|
newnext+=(1+strlen(next));
|
||||||
|
} else {
|
||||||
|
found++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(found == 1);
|
||||||
|
ThashInsert(xid, ROOT_RECORD, (const byte*)dir, strlen(dir)+1,
|
||||||
|
newent, newentsz);
|
||||||
|
free(pathcpy1);
|
||||||
|
free(pathcpy2);
|
||||||
|
free(parent);
|
||||||
|
free(newent);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
static int stasis_mknod_helper(int xid, const char * path,
|
||||||
|
stasis_dir_entry * dir, int sz, int parent) {
|
||||||
|
int res = 0;
|
||||||
|
printf("mk ->%s<- %d\n", path, (int)strlen(path)+1);fflush(stdout);
|
||||||
|
if(ThashInsert(xid, ROOT_RECORD, (const byte*)path, strlen(path)+1, (byte*)dir, sz)) {
|
||||||
|
// value existed. set error so xactn will abort.
|
||||||
|
res = -EEXIST;
|
||||||
|
} else {
|
||||||
|
if(parent) {
|
||||||
|
res = stasis_link_dirent(xid, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** removes directory entry, without checking for data, subdirs etc... */
|
||||||
|
static int stasis_rmnod_helper(int xid, const char *path, int parent) {
|
||||||
|
printf("in rmnod\n"); fflush(stdout);
|
||||||
|
int res = 0;
|
||||||
|
if(!ThashRemove(xid, ROOT_RECORD, (const byte*)path, strlen(path)+1)) {
|
||||||
|
res = -ENOENT;
|
||||||
|
} else {
|
||||||
|
if(parent) {
|
||||||
|
res = stasis_unlink_dirent(xid, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------ Fuse operations ---------------------------------------------
|
||||||
|
|
||||||
static int stasis_getattr(const char *path, struct stat *stbuf)
|
static int stasis_getattr(const char *path, struct stat *stbuf)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
memset(stbuf, 0, sizeof(struct stat));
|
memset(stbuf, 0, sizeof(struct stat));
|
||||||
/* if(strcmp(path, "/") == 0) {
|
|
||||||
stbuf->st_mode = S_IFDIR | 0755;
|
|
||||||
stbuf->st_nlink = 2;
|
|
||||||
} else { */
|
|
||||||
/* memset(stbuf, 0, sizeof(struct stat));
|
|
||||||
|
|
||||||
|
|
||||||
else if(strcmp(path, hello_path) == 0) {
|
|
||||||
stbuf->st_mode = S_IFREG | 0444;
|
|
||||||
stbuf->st_nlink = 1;
|
|
||||||
stbuf->st_size = strlen(hello_str);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
res = -ENOENT;
|
|
||||||
} */
|
|
||||||
|
|
||||||
stasis_dir_entry * e;
|
stasis_dir_entry * e;
|
||||||
int sz = stasis_lookup_helper(path, &e);
|
int sz = stasis_lookup_helper(path, &e);
|
||||||
|
@ -65,9 +166,6 @@ static stasis_dir_entry* malloc_nod(int*sz) {
|
||||||
static int stasis_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
|
static int stasis_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
|
||||||
off_t offset, struct fuse_file_info *fi)
|
off_t offset, struct fuse_file_info *fi)
|
||||||
{
|
{
|
||||||
(void) offset;
|
|
||||||
(void) fi;
|
|
||||||
|
|
||||||
stasis_dir_entry * entry;
|
stasis_dir_entry * entry;
|
||||||
printf("lu ->%s<- %d\n", path, (int)strlen(path)+1);fflush(stdout);
|
printf("lu ->%s<- %d\n", path, (int)strlen(path)+1);fflush(stdout);
|
||||||
int entrylen = ThashLookup(-1, ROOT_RECORD, (byte*)path, strlen(path)+1,(byte**)&entry);
|
int entrylen = ThashLookup(-1, ROOT_RECORD, (byte*)path, strlen(path)+1,(byte**)&entry);
|
||||||
|
@ -118,12 +216,6 @@ static int stasis_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
|
||||||
|
|
||||||
static int stasis_open(const char *path, struct fuse_file_info *fi)
|
static int stasis_open(const char *path, struct fuse_file_info *fi)
|
||||||
{
|
{
|
||||||
/* if(strcmp(path, hello_path) != 0)
|
|
||||||
return -ENOENT;
|
|
||||||
|
|
||||||
if((fi->flags & 3) != O_RDONLY)
|
|
||||||
return -EACCES; */
|
|
||||||
|
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
stasis_dir_entry * entry;
|
stasis_dir_entry * entry;
|
||||||
|
@ -132,7 +224,6 @@ static int stasis_open(const char *path, struct fuse_file_info *fi)
|
||||||
(byte**)&entry);
|
(byte**)&entry);
|
||||||
|
|
||||||
if(entrylen != -1) {
|
if(entrylen != -1) {
|
||||||
|
|
||||||
// XXX check permissions?
|
// XXX check permissions?
|
||||||
if(entry->s.st_mode & S_IFDIR) {
|
if(entry->s.st_mode & S_IFDIR) {
|
||||||
printf("found a directory entry %s\n",path); fflush(stdout);
|
printf("found a directory entry %s\n",path); fflush(stdout);
|
||||||
|
@ -223,7 +314,7 @@ static int stasis_write(const char *path, const char *buf, const size_t sz, cons
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hello_read(const char *path, char *buf, size_t size, off_t offset,
|
static int stasis_read(const char *path, char *buf, size_t size, off_t offset,
|
||||||
struct fuse_file_info *fi)
|
struct fuse_file_info *fi)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
@ -256,72 +347,66 @@ static int hello_read(const char *path, char *buf, size_t size, off_t offset,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
/*if(strcmp(path, hello_path) != 0)
|
|
||||||
|
|
||||||
|
|
||||||
len = strlen(hello_str);
|
|
||||||
if (offset < len) {
|
|
||||||
if (offset + size > len)
|
|
||||||
size = len - offset;
|
|
||||||
memcpy(buf, hello_str + offset, size);
|
|
||||||
} else
|
|
||||||
size = 0;
|
|
||||||
|
|
||||||
return size; */
|
|
||||||
}
|
}
|
||||||
|
static int stasis_unlink(const char * path) {
|
||||||
|
int res = 0;
|
||||||
|
stasis_dir_entry *ent;
|
||||||
|
|
||||||
static int stasis_mknod_helper(int xid, const char * path,
|
int entsz = ThashLookup(-1, ROOT_RECORD, (const byte*)path, strlen(path)+1, (byte**)&ent);
|
||||||
stasis_dir_entry * dir, int sz, int parent) {
|
|
||||||
|
|
||||||
printf("mk ->%s<- %d\n", path, (int)strlen(path)+1);fflush(stdout);
|
if(entsz == -1) {
|
||||||
ThashInsert(xid, ROOT_RECORD, (const byte*)path, strlen(path)+1, (byte*)dir, sz);
|
res = -ENOENT;
|
||||||
|
|
||||||
if(parent) {
|
|
||||||
char * parentbuf = strdup(path);
|
|
||||||
char * parent = dirname(parentbuf);
|
|
||||||
printf("attaching to parent %s\n", parent); fflush(stdout);
|
|
||||||
char * filebuf = strdup(path);
|
|
||||||
char * file = basename(filebuf);
|
|
||||||
stasis_dir_entry * entry;
|
|
||||||
printf("lu ->%s<- %d\n", parent, (int)strlen(parent)+1);fflush(stdout);
|
|
||||||
int entrylen = ThashLookup(xid, ROOT_RECORD,
|
|
||||||
(const byte*)parent, strlen(parent)+1,
|
|
||||||
(byte**)&entry);
|
|
||||||
printf("entrylen %d\n",entrylen); fflush(stdout);
|
|
||||||
if(entrylen == -1) {
|
|
||||||
return -ENOENT;
|
|
||||||
} else {
|
} else {
|
||||||
const char * next;
|
assert(entsz >= sizeof(stasis_dir_entry));
|
||||||
for(next = (const char*)(entry+1);
|
if(S_ISREG(ent->s.st_mode)) {
|
||||||
next != ((char*)entry) + entrylen;
|
assert(entsz == (sizeof(stasis_dir_entry)+sizeof(recordid)));
|
||||||
next += (strlen(next)+1)) {
|
recordid * blob_rid = (recordid*)(ent+1);
|
||||||
assert(next < ((char*)entry)+entrylen);
|
int xid = Tbegin();
|
||||||
printf("next: %s\n", next); fflush(stdout);fflush(stdout);
|
if(blob_rid->page != NULLRID.page || blob_rid->slot != NULLRID.slot) {
|
||||||
if(0 == strcmp(next, path)) {
|
Tdealloc(xid, *blob_rid);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
res = stasis_rmnod_helper(xid,path,1);
|
||||||
|
if(res) {
|
||||||
|
Tabort(xid);
|
||||||
|
} else {
|
||||||
|
Tcommit(xid);
|
||||||
}
|
}
|
||||||
printf("forloop done\n"); fflush(stdout);
|
} else {
|
||||||
if(next == ((char*)entry)+entrylen) {
|
// XXX check for block devices, etc...
|
||||||
printf("inserting %s\n", path); fflush(stdout);
|
res = -EISDIR;
|
||||||
int newentrylen = entrylen+strlen(file)+1;
|
}
|
||||||
|
free(ent);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
static int stasis_rmdir(const char *path) {
|
||||||
|
int res = 0;
|
||||||
|
stasis_dir_entry *ent;
|
||||||
|
|
||||||
entry = realloc(entry, newentrylen);
|
int entsz = ThashLookup(-1, ROOT_RECORD, (const byte*)path, strlen(path)+1, (byte**)&ent);
|
||||||
strcpy(((char*)entry)+entrylen,file);
|
|
||||||
|
|
||||||
printf("parent ->%s<- %d; newlen=%d\n", parent, (int)strlen(parent)+1,
|
if(entsz == -1) {
|
||||||
newentrylen);fflush(stdout);
|
res = -ENOENT;
|
||||||
|
} else {
|
||||||
ThashInsert(xid, ROOT_RECORD, (const byte*)parent, strlen(parent)+1,
|
assert(entsz >= sizeof(stasis_dir_entry));
|
||||||
(const byte*)entry, newentrylen);
|
if(S_ISDIR(ent->s.st_mode)) {
|
||||||
|
if(entsz > sizeof(stasis_dir_entry)) {
|
||||||
|
res = -ENOTEMPTY;
|
||||||
|
} else {
|
||||||
|
int xid = Tbegin();
|
||||||
|
res = stasis_rmnod_helper(xid,path,1);
|
||||||
|
if(res) {
|
||||||
|
Tabort(xid);
|
||||||
|
} else {
|
||||||
|
Tcommit(xid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
res = -ENOTDIR;
|
||||||
}
|
}
|
||||||
printf("returning 0\n"); fflush(stdout);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
static int stasis_mknod(const char *path, mode_t mode, dev_t dev) {
|
static int stasis_mknod(const char *path, mode_t mode, dev_t dev) {
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int xid = Tbegin();
|
int xid = Tbegin();
|
||||||
|
@ -393,20 +478,8 @@ static int stasis_mkdir(const char *path, mode_t mode) {
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
static struct fuse_operations hello_oper = {
|
|
||||||
.getattr = stasis_getattr,
|
|
||||||
.readdir = stasis_readdir,
|
|
||||||
.mkdir = stasis_mkdir,
|
|
||||||
.mknod = stasis_mknod,
|
|
||||||
.open = stasis_open,
|
|
||||||
.read = hello_read,
|
|
||||||
.write = stasis_write,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
static void* stasis_init(struct fuse_conn_info *conn) {
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
Tinit();
|
Tinit();
|
||||||
|
|
||||||
int xid = Tbegin();
|
int xid = Tbegin();
|
||||||
|
@ -428,7 +501,55 @@ int main(int argc, char *argv[])
|
||||||
stasis_mknod_helper(xid, "/", dir, sz, 0);
|
stasis_mknod_helper(xid, "/", dir, sz, 0);
|
||||||
}
|
}
|
||||||
Tcommit(xid);
|
Tcommit(xid);
|
||||||
ret = fuse_main(argc, argv, &hello_oper, 0);
|
|
||||||
// Tdeinit();
|
// XXX xid caching
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static void stasis_destroy(void * parm) {
|
||||||
|
Tdeinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct fuse_operations stasis_oper = {
|
||||||
|
.getattr = stasis_getattr,
|
||||||
|
//.readlink = stasis_readlink,
|
||||||
|
.mknod = stasis_mknod,
|
||||||
|
.mkdir = stasis_mkdir,
|
||||||
|
.unlink = stasis_unlink,
|
||||||
|
.rmdir = stasis_rmdir,
|
||||||
|
//.symlink = stasis_symlink,
|
||||||
|
//.rename = stasis_rename,
|
||||||
|
//.link = stasis_link,
|
||||||
|
//.chmod = stasis_chmod,
|
||||||
|
//.chown = stasis_chown,
|
||||||
|
//.truncate = stasis_truncate,
|
||||||
|
//.utime = stasis_utime,
|
||||||
|
.open = stasis_open,
|
||||||
|
.read = stasis_read,
|
||||||
|
.write = stasis_write,
|
||||||
|
//.statfs = stasis_statfs,
|
||||||
|
//.flush = stasis_flush,
|
||||||
|
//.release = stasis_release,
|
||||||
|
//.fsync = stasis_fsync,
|
||||||
|
//.setxattr = stasis_setxattr,
|
||||||
|
//.getxattr = stasis_getxattr,
|
||||||
|
//.listxattr = stasis_listxattr,
|
||||||
|
//.removexattr= stasis_removexattr,
|
||||||
|
//.opendir = stasis_opendir,
|
||||||
|
.readdir = stasis_readdir,
|
||||||
|
//.releasedir = stasis_releasedir,
|
||||||
|
//.fsyncdir = stasis_fsyncdir,
|
||||||
|
.init = stasis_init,
|
||||||
|
.destroy = stasis_destroy,
|
||||||
|
//.access = stasis_access,
|
||||||
|
//.ftruncate = stasis_ftruncate,
|
||||||
|
//.lock = stasis_lock,
|
||||||
|
//.utimens = stasis_utimens,
|
||||||
|
//.bmap = stasis_bmap,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int ret = fuse_main(argc, argv, &stasis_oper, 0);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue