#endif
}
+ inode->i_ino = attr->ino;
inode->i_mode = (inode->i_mode & S_IFMT) + (attr->mode & 07777);
inode->i_nlink = attr->nlink;
inode->i_uid = attr->uid;
printk("fuse_init_inode: bad file type: %o\n", inode->i_mode);
}
-struct inode *fuse_iget(struct super_block *sb, ino_t ino, int generation,
- struct fuse_attr *attr, int version)
+#ifdef KERNEL_2_6
+static int fuse_inode_eq(struct inode *inode, void *_nodeidp)
+{
+ unsigned long nodeid = *(unsigned long *) _nodeidp;
+ struct fuse_inode *fi = INO_FI(inode);
+ if (fi->nodeid == nodeid)
+ return 1;
+ else
+ return 0;
+}
+
+static int fuse_inode_set(struct inode *inode, void *_nodeidp)
+{
+ unsigned long nodeid = *(unsigned long *) _nodeidp;
+ struct fuse_inode *fi = INO_FI(inode);
+ fi->nodeid = nodeid;
+ return 0;
+}
+
+struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
+ int generation, struct fuse_attr *attr, int version)
{
struct inode *inode;
- inode = iget(sb, ino);
- if (inode) {
- if (!INO_FI(inode)) {
- struct fuse_inode *fi = fuse_inode_alloc();
- if (!fi) {
- iput(inode);
- inode = NULL;
- goto out;
- }
- INO_FI(inode) = fi;
- inode->i_generation = generation;
- fuse_init_inode(inode, attr);
- } else if (inode->i_generation != generation)
- printk("fuse_iget: bad generation for ino %lu\n", ino);
-
- change_attributes(inode, attr);
- inode->i_version = version;
- }
- out:
+ inode = iget5_locked(sb, nodeid, fuse_inode_eq, fuse_inode_set, &nodeid);
+ if (!inode)
+ return NULL;
+
+ if ((inode->i_state & I_NEW)) {
+ inode->i_generation = generation;
+ fuse_init_inode(inode, attr);
+ unlock_new_inode(inode);
+ } else if (inode->i_generation != generation)
+ printk("fuse_iget: bad generation for node %lu\n", nodeid);
+
+ change_attributes(inode, attr);
+ inode->i_version = version;
+ return inode;
+}
+
+struct inode *fuse_ilookup(struct fuse_conn *fc, ino_t ino, unsigned long nodeid)
+{
+ return ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid);
+}
+#else
+static int fuse_inode_eq(struct inode *inode, unsigned long ino, void *_nodeidp){
+ unsigned long nodeid = *(unsigned long *) _nodeidp;
+ struct fuse_inode *fi = INO_FI(inode);
+ if (inode->u.generic_ip && fi->nodeid == nodeid)
+ return 1;
+ else
+ return 0;
+}
+
+struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
+ int generation, struct fuse_attr *attr, int version)
+{
+ struct inode *inode;
+
+ inode = iget4(sb, attr->ino, fuse_inode_eq, &nodeid);
+ if (!inode)
+ return NULL;
+
+ if (!inode->u.generic_ip) {
+ struct fuse_inode *fi = INO_FI(inode);
+ fi->nodeid = nodeid;
+ inode->u.generic_ip = inode;
+ inode->i_generation = generation;
+ fuse_init_inode(inode, attr);
+ } else if (inode->i_generation != generation)
+ printk("fuse_iget: bad generation for node %lu\n", nodeid);
+
+ change_attributes(inode, attr);
+ inode->i_version = version;
+ return inode;
+}
+struct inode *fuse_ilookup(struct fuse_conn *fc, ino_t ino, unsigned long nodeid)
+{
+ struct inode *inode = iget4(fc->sb, ino, fuse_inode_eq, &nodeid);
+ if (inode && !inode->u.generic_ip) {
+ iput(inode);
+ inode = NULL;
+ }
return inode;
}
+#endif
+
static int fuse_send_lookup(struct fuse_conn *fc, struct fuse_req *req,
struct inode *dir, struct dentry *entry,
struct fuse_entry_out *outarg, int *version)
{
+ struct fuse_inode *fi = INO_FI(dir);
req->in.h.opcode = FUSE_LOOKUP;
- req->in.h.ino = dir->i_ino;
+ req->in.h.nodeid = fi->nodeid;
req->in.numargs = 1;
req->in.args[0].size = entry->d_name.len + 1;
req->in.args[0].value = entry->d_name.name;
err = fuse_send_lookup(fc, req, dir, entry, &outarg, &version);
if (!err) {
- inode = fuse_iget(dir->i_sb, outarg.ino, outarg.generation,
+ inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
&outarg.attr, version);
if (!inode) {
- fuse_send_forget(fc, req, outarg.ino, version);
+ fuse_send_forget(fc, req, outarg.nodeid, version);
return -ENOMEM;
}
}
{
struct inode *inode;
struct fuse_inode *fi;
- inode = fuse_iget(dir->i_sb, outarg->ino, outarg->generation,
+ inode = fuse_iget(dir->i_sb, outarg->nodeid, outarg->generation,
&outarg->attr, version);
if (!inode) {
- fuse_send_forget(fc, req, outarg->ino, version);
+ fuse_send_forget(fc, req, outarg->nodeid, version);
return -ENOMEM;
}
fuse_put_request(fc, req);
dev_t rdev)
{
struct fuse_conn *fc = INO_FC(dir);
+ struct fuse_inode *fi = INO_FI(dir);
struct fuse_req *req = fuse_get_request(fc);
struct fuse_mknod_in inarg;
struct fuse_entry_out outarg;
inarg.mode = mode;
inarg.rdev = new_encode_dev(rdev);
req->in.h.opcode = FUSE_MKNOD;
- req->in.h.ino = dir->i_ino;
+ req->in.h.nodeid = fi->nodeid;
req->in.numargs = 2;
req->in.args[0].size = sizeof(inarg);
req->in.args[0].value = &inarg;
static int fuse_mkdir(struct inode *dir, struct dentry *entry, int mode)
{
struct fuse_conn *fc = INO_FC(dir);
+ struct fuse_inode *fi = INO_FI(dir);
struct fuse_req *req = fuse_get_request(fc);
struct fuse_mkdir_in inarg;
struct fuse_entry_out outarg;
memset(&inarg, 0, sizeof(inarg));
inarg.mode = mode;
req->in.h.opcode = FUSE_MKDIR;
- req->in.h.ino = dir->i_ino;
+ req->in.h.nodeid = fi->nodeid;
req->in.numargs = 2;
req->in.args[0].size = sizeof(inarg);
req->in.args[0].value = &inarg;
const char *link)
{
struct fuse_conn *fc = INO_FC(dir);
+ struct fuse_inode *fi = INO_FI(dir);
struct fuse_req *req;
struct fuse_entry_out outarg;
unsigned int len = strlen(link) + 1;
return -ERESTARTSYS;
req->in.h.opcode = FUSE_SYMLINK;
- req->in.h.ino = dir->i_ino;
+ req->in.h.nodeid = fi->nodeid;
req->in.numargs = 2;
req->in.args[0].size = entry->d_name.len + 1;
req->in.args[0].value = entry->d_name.name;
static int fuse_unlink(struct inode *dir, struct dentry *entry)
{
struct fuse_conn *fc = INO_FC(dir);
+ struct fuse_inode *fi = INO_FI(dir);
struct fuse_req *req = fuse_get_request(fc);
int err;
return -ERESTARTSYS;
req->in.h.opcode = FUSE_UNLINK;
- req->in.h.ino = dir->i_ino;
+ req->in.h.nodeid = fi->nodeid;
req->in.numargs = 1;
req->in.args[0].size = entry->d_name.len + 1;
req->in.args[0].value = entry->d_name.name;
static int fuse_rmdir(struct inode *dir, struct dentry *entry)
{
struct fuse_conn *fc = INO_FC(dir);
+ struct fuse_inode *fi = INO_FI(dir);
struct fuse_req *req = fuse_get_request(fc);
int err;
return -ERESTARTSYS;
req->in.h.opcode = FUSE_RMDIR;
- req->in.h.ino = dir->i_ino;
+ req->in.h.nodeid = fi->nodeid;
req->in.numargs = 1;
req->in.args[0].size = entry->d_name.len + 1;
req->in.args[0].value = entry->d_name.name;
struct inode *newdir, struct dentry *newent)
{
struct fuse_conn *fc = INO_FC(olddir);
+ struct fuse_inode *oldfi = INO_FI(olddir);
+ struct fuse_inode *newfi = INO_FI(newdir);
struct fuse_req *req = fuse_get_request(fc);
struct fuse_rename_in inarg;
int err;
return -ERESTARTSYS;
memset(&inarg, 0, sizeof(inarg));
- inarg.newdir = newdir->i_ino;
+ inarg.newdir = newfi->nodeid;
req->in.h.opcode = FUSE_RENAME;
- req->in.h.ino = olddir->i_ino;
+ req->in.h.nodeid = oldfi->nodeid;
req->in.numargs = 3;
req->in.args[0].size = sizeof(inarg);
req->in.args[0].value = &inarg;
{
struct inode *inode = entry->d_inode;
struct fuse_conn *fc = INO_FC(inode);
+ struct fuse_inode *fi = INO_FI(inode);
+ struct fuse_inode *newfi = INO_FI(newdir);
struct fuse_req *req = fuse_get_request(fc);
struct fuse_link_in inarg;
struct fuse_entry_out outarg;
return -ERESTARTSYS;
memset(&inarg, 0, sizeof(inarg));
- inarg.newdir = newdir->i_ino;
+ inarg.newdir = newfi->nodeid;
req->in.h.opcode = FUSE_LINK;
- req->in.h.ino = inode->i_ino;
+ req->in.h.nodeid = fi->nodeid;
req->in.numargs = 2;
req->in.args[0].size = sizeof(inarg);
req->in.args[0].value = &inarg;
return -ERESTARTSYS;
req->in.h.opcode = FUSE_GETATTR;
- req->in.h.ino = inode->i_ino;
+ req->in.h.nodeid = fi->nodeid;
req->out.numargs = 1;
req->out.args[0].size = sizeof(arg);
req->out.args[0].value = &arg;
struct fuse_inode *fi = INO_FI(inode);
struct fuse_conn *fc = INO_FC(inode);
- if (inode->i_ino == FUSE_ROOT_INO) {
+ if (fi->nodeid == FUSE_ROOT_ID) {
if (!(fc->flags & FUSE_ALLOW_OTHER) &&
current->fsuid != fc->uid &&
(!(fc->flags & FUSE_ALLOW_ROOT) ||
{
struct inode *inode = file->f_dentry->d_inode;
struct fuse_conn *fc = INO_FC(inode);
+ struct fuse_inode *fi = INO_FI(inode);
struct fuse_req *req = fuse_get_request(fc);
struct fuse_getdir_out_i outarg;
int err;
return -ERESTARTSYS;
req->in.h.opcode = FUSE_GETDIR;
- req->in.h.ino = inode->i_ino;
+ req->in.h.nodeid = fi->nodeid;
req->out.numargs = 1;
req->out.args[0].size = sizeof(struct fuse_getdir_out);
req->out.args[0].value = &outarg;
{
struct inode *inode = dentry->d_inode;
struct fuse_conn *fc = INO_FC(inode);
+ struct fuse_inode *fi = INO_FI(inode);
struct fuse_req *req = fuse_get_request(fc);
char *link;
goto out;
}
req->in.h.opcode = FUSE_READLINK;
- req->in.h.ino = inode->i_ino;
+ req->in.h.nodeid = fi->nodeid;
req->out.argvar = 1;
req->out.numargs = 1;
req->out.args[0].size = PAGE_SIZE - 1;
memset(&inarg, 0, sizeof(inarg));
inarg.valid = iattr_to_fattr(attr, &inarg.attr);
req->in.h.opcode = FUSE_SETATTR;
- req->in.h.ino = inode->i_ino;
+ req->in.h.nodeid = fi->nodeid;
req->in.numargs = 1;
req->in.args[0].size = sizeof(inarg);
req->in.args[0].value = &inarg;
if (ret)
return 0;
- if (outarg.ino != inode->i_ino)
+ if (outarg.nodeid != fi->nodeid)
return 0;
change_attributes(inode, &outarg.attr);
{
struct inode *inode = entry->d_inode;
struct fuse_conn *fc = INO_FC(inode);
+ struct fuse_inode *fi = INO_FI(inode);
struct fuse_req *req;
struct fuse_setxattr_in inarg;
int err;
inarg.size = size;
inarg.flags = flags;
req->in.h.opcode = FUSE_SETXATTR;
- req->in.h.ino = inode->i_ino;
+ req->in.h.nodeid = fi->nodeid;
req->in.numargs = 3;
req->in.args[0].size = sizeof(inarg);
req->in.args[0].value = &inarg;
{
struct inode *inode = entry->d_inode;
struct fuse_conn *fc = INO_FC(inode);
+ struct fuse_inode *fi = INO_FI(inode);
struct fuse_req *req;
struct fuse_getxattr_in inarg;
struct fuse_getxattr_out outarg;
memset(&inarg, 0, sizeof(inarg));
inarg.size = size;
req->in.h.opcode = FUSE_GETXATTR;
- req->in.h.ino = inode->i_ino;
+ req->in.h.nodeid = fi->nodeid;
req->in.numargs = 2;
req->in.args[0].size = sizeof(inarg);
req->in.args[0].value = &inarg;
{
struct inode *inode = entry->d_inode;
struct fuse_conn *fc = INO_FC(inode);
+ struct fuse_inode *fi = INO_FI(inode);
struct fuse_req *req;
struct fuse_getxattr_in inarg;
struct fuse_getxattr_out outarg;
memset(&inarg, 0, sizeof(inarg));
inarg.size = size;
req->in.h.opcode = FUSE_LISTXATTR;
- req->in.h.ino = inode->i_ino;
+ req->in.h.nodeid = fi->nodeid;
req->in.numargs = 1;
req->in.args[0].size = sizeof(inarg);
req->in.args[0].value = &inarg;
{
struct inode *inode = entry->d_inode;
struct fuse_conn *fc = INO_FC(inode);
+ struct fuse_inode *fi = INO_FI(inode);
struct fuse_req *req;
int err;
return -ERESTARTSYS;
req->in.h.opcode = FUSE_REMOVEXATTR;
- req->in.h.ino = inode->i_ino;
+ req->in.h.nodeid = fi->nodeid;
req->in.numargs = 1;
req->in.args[0].size = strlen(name) + 1;
req->in.args[0].value = name;
pthread_mutex_unlock(&f->lock);
}
-static struct node *__get_node(struct fuse *f, fino_t ino)
+static struct node *__get_node(struct fuse *f, nodeid_t nodeid)
{
- size_t hash = ino % f->ino_table_size;
+ size_t hash = nodeid % f->id_table_size;
struct node *node;
- for (node = f->ino_table[hash]; node != NULL; node = node->ino_next)
- if (node->ino == ino)
+ for (node = f->id_table[hash]; node != NULL; node = node->id_next)
+ if (node->nodeid == nodeid)
return node;
return NULL;
}
-static struct node *get_node(struct fuse *f, fino_t ino)
+static struct node *get_node(struct fuse *f, nodeid_t nodeid)
{
- struct node *node = __get_node(f, ino);
+ struct node *node = __get_node(f, nodeid);
if (node != NULL)
return node;
- fprintf(stderr, "fuse internal error: inode %lu not found\n", ino);
+ fprintf(stderr, "fuse internal error: inode %lu not found\n", nodeid);
abort();
}
-static void hash_ino(struct fuse *f, struct node *node)
+static void hash_id(struct fuse *f, struct node *node)
{
- size_t hash = node->ino % f->ino_table_size;
- node->ino_next = f->ino_table[hash];
- f->ino_table[hash] = node;
+ size_t hash = node->nodeid % f->id_table_size;
+ node->id_next = f->id_table[hash];
+ f->id_table[hash] = node;
}
-static void unhash_ino(struct fuse *f, struct node *node)
+static void unhash_id(struct fuse *f, struct node *node)
{
- size_t hash = node->ino % f->ino_table_size;
- struct node **nodep = &f->ino_table[hash];
+ size_t hash = node->nodeid % f->id_table_size;
+ struct node **nodep = &f->id_table[hash];
- for (; *nodep != NULL; nodep = &(*nodep)->ino_next)
+ for (; *nodep != NULL; nodep = &(*nodep)->id_next)
if (*nodep == node) {
- *nodep = node->ino_next;
+ *nodep = node->id_next;
return;
}
}
-static fino_t next_ino(struct fuse *f)
+static nodeid_t next_id(struct fuse *f)
{
do {
f->ctr++;
free(node);
}
-static unsigned int name_hash(struct fuse *f, fino_t parent, const char *name)
+static unsigned int name_hash(struct fuse *f, nodeid_t parent, const char *name)
{
unsigned int hash = *name;
return (hash + parent) % f->name_table_size;
}
-static struct node *__lookup_node(struct fuse *f, fino_t parent,
+static struct node *__lookup_node(struct fuse *f, nodeid_t parent,
const char *name)
{
size_t hash = name_hash(f, parent, name);
return NULL;
}
-static struct node *lookup_node(struct fuse *f, fino_t parent,
+static struct node *lookup_node(struct fuse *f, nodeid_t parent,
const char *name)
{
struct node *node;
abort();
}
-static int hash_name(struct fuse *f, struct node *node, fino_t parent,
+static int hash_name(struct fuse *f, struct node *node, nodeid_t parent,
const char *name)
{
size_t hash = name_hash(f, parent, name);
return;
}
fprintf(stderr, "fuse internal error: unable to unhash node: %lu\n",
- node->ino);
+ node->nodeid);
abort();
}
}
-static struct node *find_node(struct fuse *f, fino_t parent, char *name,
+static struct node *find_node(struct fuse *f, nodeid_t parent, char *name,
struct fuse_attr *attr, int version)
{
struct node *node;
pthread_mutex_lock(&f->lock);
node = __lookup_node(f, parent, name);
if (node != NULL) {
- if (node->mode == mode && node->rdev == rdev)
+ if (node->mode == mode && node->rdev == rdev &&
+ (!(f->flags & FUSE_USE_INO) || node->ino == attr->ino)) {
+ if (!(f->flags & FUSE_USE_INO))
+ attr->ino = node->nodeid;
+
goto out;
+ }
unhash_name(f, node);
}
if (node == NULL)
goto out_err;
+ node->nodeid = next_id(f);
+ if (!(f->flags & FUSE_USE_INO))
+ attr->ino = node->nodeid;
node->mode = mode;
node->rdev = rdev;
+ node->ino = attr->ino;
node->open_count = 0;
node->is_hidden = 0;
- node->ino = next_ino(f);
node->generation = f->generation;
if (hash_name(f, node, parent, name) == -1) {
free(node);
node = NULL;
goto out_err;
}
- hash_ino(f, node);
+ hash_id(f, node);
out:
node->version = version;
return node;
}
-static int path_lookup(struct fuse *f, const char *path, fino_t *inop)
+static int path_lookup(struct fuse *f, const char *path, nodeid_t *nodeidp,
+ unsigned long *inop)
{
- fino_t ino;
+ nodeid_t nodeid;
+ unsigned long ino;
int err;
char *s;
char *name;
return -ENOMEM;
pthread_mutex_lock(&f->lock);
- ino = FUSE_ROOT_INO;
+ nodeid = FUSE_ROOT_ID;
+ ino = nodeid;
err = 0;
for (s = tmp; (name = strsep(&s, "/")) != NULL; ) {
if (name[0]) {
- struct node *node = __lookup_node(f, ino, name);
+ struct node *node = __lookup_node(f, nodeid, name);
if (node == NULL) {
err = -ENOENT;
break;
}
+ nodeid = node->nodeid;
ino = node->ino;
}
}
pthread_mutex_unlock(&f->lock);
free(tmp);
- if (!err)
+ if (!err) {
+ *nodeidp = nodeid;
*inop = ino;
+ }
return err;
}
return s;
}
-static char *get_path_name(struct fuse *f, fino_t ino, const char *name)
+static char *get_path_name(struct fuse *f, nodeid_t nodeid, const char *name)
{
char buf[FUSE_MAX_PATH];
char *s = buf + FUSE_MAX_PATH - 1;
}
pthread_mutex_lock(&f->lock);
- for (node = get_node(f, ino); node->ino != FUSE_ROOT_INO;
+ for (node = get_node(f, nodeid); node->nodeid != FUSE_ROOT_ID;
node = get_node(f, node->parent)) {
if (node->name == NULL) {
s = NULL;
return strdup(s);
}
-static char *get_path(struct fuse *f, fino_t ino)
+static char *get_path(struct fuse *f, nodeid_t nodeid)
{
- return get_path_name(f, ino, NULL);
+ return get_path_name(f, nodeid, NULL);
}
-static void destroy_node(struct fuse *f, fino_t ino, int version)
+static void destroy_node(struct fuse *f, nodeid_t nodeid, int version)
{
struct node *node;
pthread_mutex_lock(&f->lock);
- node = __get_node(f, ino);
- if (node && node->version == version && ino != FUSE_ROOT_INO) {
+ node = __get_node(f, nodeid);
+ if (node && node->version == version && nodeid != FUSE_ROOT_ID) {
unhash_name(f, node);
- unhash_ino(f, node);
+ unhash_id(f, node);
free_node(node);
}
pthread_mutex_unlock(&f->lock);
}
-static void remove_node(struct fuse *f, fino_t dir, const char *name)
+static void remove_node(struct fuse *f, nodeid_t dir, const char *name)
{
struct node *node;
pthread_mutex_unlock(&f->lock);
}
-static int rename_node(struct fuse *f, fino_t olddir, const char *oldname,
- fino_t newdir, const char *newname, int hide)
+static int rename_node(struct fuse *f, nodeid_t olddir, const char *oldname,
+ nodeid_t newdir, const char *newname, int hide)
{
struct node *node;
struct node *newnode;
static void convert_stat(struct stat *stbuf, struct fuse_attr *attr)
{
+ attr->ino = stbuf->st_ino;
attr->mode = stbuf->st_mode;
attr->nlink = stbuf->st_nlink;
attr->uid = stbuf->st_uid;
return __send_reply(f, in, error, arg, argsize, 0);
}
-static int is_open(struct fuse *f, fino_t dir, const char *name)
+static int is_open(struct fuse *f, nodeid_t dir, const char *name)
{
struct node *node;
int isopen = 0;
return isopen;
}
-static char *hidden_name(struct fuse *f, fino_t dir, const char *oldname,
+static char *hidden_name(struct fuse *f, nodeid_t dir, const char *oldname,
char *newname, size_t bufsize)
{
struct stat buf;
do {
f->hidectr ++;
snprintf(newname, bufsize, ".fuse_hidden%08x%08x",
- (unsigned int) node->ino, f->hidectr);
+ (unsigned int) node->nodeid, f->hidectr);
newnode = __lookup_node(f, dir, newname);
} while(newnode);
pthread_mutex_unlock(&f->lock);
return newpath;
}
-static int hide_node(struct fuse *f, const char *oldpath, fino_t dir,
+static int hide_node(struct fuse *f, const char *oldpath, nodeid_t dir,
const char *oldname)
{
char newname[64];
return err;
}
-static int lookup_path(struct fuse *f, fino_t ino, int version, char *name,
+static int lookup_path(struct fuse *f, nodeid_t nodeid, int version, char *name,
const char *path, struct fuse_entry_out *arg)
{
int res;
memset(arg, 0, sizeof(struct fuse_entry_out));
convert_stat(&buf, &arg->attr);
- node = find_node(f, ino, name, &arg->attr, version);
+ node = find_node(f, nodeid, name, &arg->attr, version);
if (node == NULL)
res = -ENOMEM;
else {
- arg->ino = node->ino;
+ arg->nodeid = node->nodeid;
arg->generation = node->generation;
arg->entry_valid = ENTRY_REVALIDATE_TIME;
arg->entry_valid_nsec = 0;
arg->attr_valid = ATTR_REVALIDATE_TIME;
arg->attr_valid_nsec = 0;
if (f->flags & FUSE_DEBUG) {
- printf(" INO: %li\n", arg->ino);
+ printf(" NODEID: %li\n", arg->nodeid);
fflush(stdout);
}
}
struct fuse_entry_out arg;
res = -ENOENT;
- path = get_path_name(f, in->ino, name);
+ path = get_path_name(f, in->nodeid, name);
if (path != NULL) {
if (f->flags & FUSE_DEBUG) {
printf("LOOKUP %s\n", path);
}
res = -ENOSYS;
if (f->op.getattr)
- res = lookup_path(f, in->ino, in->unique, name, path, &arg);
+ res = lookup_path(f, in->nodeid, in->unique, name, path, &arg);
free(path);
}
res2 = send_reply(f, in, res, &arg, sizeof(arg));
if (res == 0 && res2 == -ENOENT)
- destroy_node(f, arg.ino, in->unique);
+ destroy_node(f, arg.nodeid, in->unique);
}
static void do_forget(struct fuse *f, struct fuse_in_header *in,
struct fuse_forget_in *arg)
{
if (f->flags & FUSE_DEBUG) {
- printf("FORGET %li/%i\n", in->ino, arg->version);
+ printf("FORGET %li/%i\n", in->nodeid, arg->version);
fflush(stdout);
}
- destroy_node(f, in->ino, arg->version);
+ destroy_node(f, in->nodeid, arg->version);
}
static void do_getattr(struct fuse *f, struct fuse_in_header *in)
struct fuse_attr_out arg;
res = -ENOENT;
- path = get_path(f, in->ino);
+ path = get_path(f, in->nodeid);
if (path != NULL) {
res = -ENOSYS;
if (f->op.getattr)
arg.attr_valid = ATTR_REVALIDATE_TIME;
arg.attr_valid_nsec = 0;
convert_stat(&buf, &arg.attr);
+ if (!(f->flags & FUSE_USE_INO))
+ arg.attr.ino = in->nodeid;
+ else {
+ struct node *node = get_node(f, in->nodeid);
+ node->ino = arg.attr.ino;
+ }
}
send_reply(f, in, res, &arg, sizeof(arg));
struct fuse_attr_out outarg;
res = -ENOENT;
- path = get_path(f, in->ino);
+ path = get_path(f, in->nodeid);
if (path != NULL) {
res = -ENOSYS;
if (f->op.getattr) {
outarg.attr_valid = ATTR_REVALIDATE_TIME;
outarg.attr_valid_nsec = 0;
convert_stat(&buf, &outarg.attr);
+ if (!(f->flags & FUSE_USE_INO))
+ outarg.attr.ino = in->nodeid;
+ else {
+ struct node *node = get_node(f, in->nodeid);
+ node->ino = outarg.attr.ino;
+ }
}
}
}
char *path;
res = -ENOENT;
- path = get_path(f, in->ino);
+ path = get_path(f, in->nodeid);
if (path != NULL) {
res = -ENOSYS;
if (f->op.readlink)
dh.fuse = f;
dh.fp = tmpfile();
- dh.dir = in->ino;
+ dh.dir = in->nodeid;
res = -EIO;
if (dh.fp == NULL)
perror("fuse: failed to create temporary file");
else {
res = -ENOENT;
- path = get_path(f, in->ino);
+ path = get_path(f, in->nodeid);
if (path != NULL) {
res = -ENOSYS;
if (f->op.getdir)
struct fuse_entry_out outarg;
res = -ENOENT;
- path = get_path_name(f, in->ino, name);
+ path = get_path_name(f, in->nodeid, name);
if (path != NULL) {
if (f->flags & FUSE_DEBUG) {
printf("MKNOD %s\n", path);
if (f->op.mknod && f->op.getattr) {
res = f->op.mknod(path, inarg->mode, inarg->rdev);
if (res == 0)
- res = lookup_path(f, in->ino, in->unique, name, path, &outarg);
+ res = lookup_path(f, in->nodeid, in->unique, name, path, &outarg);
}
free(path);
}
res2 = send_reply(f, in, res, &outarg, sizeof(outarg));
if (res == 0 && res2 == -ENOENT)
- destroy_node(f, outarg.ino, in->unique);
+ destroy_node(f, outarg.nodeid, in->unique);
}
static void do_mkdir(struct fuse *f, struct fuse_in_header *in,
struct fuse_entry_out outarg;
res = -ENOENT;
- path = get_path_name(f, in->ino, name);
+ path = get_path_name(f, in->nodeid, name);
if (path != NULL) {
if (f->flags & FUSE_DEBUG) {
printf("MKDIR %s\n", path);
if (f->op.mkdir && f->op.getattr) {
res = f->op.mkdir(path, inarg->mode);
if (res == 0)
- res = lookup_path(f, in->ino, in->unique, name, path, &outarg);
+ res = lookup_path(f, in->nodeid, in->unique, name, path, &outarg);
}
free(path);
}
res2 = send_reply(f, in, res, &outarg, sizeof(outarg));
if (res == 0 && res2 == -ENOENT)
- destroy_node(f, outarg.ino, in->unique);
+ destroy_node(f, outarg.nodeid, in->unique);
}
static void do_unlink(struct fuse *f, struct fuse_in_header *in, char *name)
char *path;
res = -ENOENT;
- path = get_path_name(f, in->ino, name);
+ path = get_path_name(f, in->nodeid, name);
if (path != NULL) {
if (f->flags & FUSE_DEBUG) {
printf("UNLINK %s\n", path);
}
res = -ENOSYS;
if (f->op.unlink) {
- if (!(f->flags & FUSE_HARD_REMOVE) && is_open(f, in->ino, name))
- res = hide_node(f, path, in->ino, name);
+ if (!(f->flags & FUSE_HARD_REMOVE) && is_open(f, in->nodeid, name))
+ res = hide_node(f, path, in->nodeid, name);
else {
res = f->op.unlink(path);
if (res == 0)
- remove_node(f, in->ino, name);
+ remove_node(f, in->nodeid, name);
}
}
free(path);
char *path;
res = -ENOENT;
- path = get_path_name(f, in->ino, name);
+ path = get_path_name(f, in->nodeid, name);
if (path != NULL) {
if (f->flags & FUSE_DEBUG) {
printf("RMDIR %s\n", path);
if (f->op.rmdir) {
res = f->op.rmdir(path);
if (res == 0)
- remove_node(f, in->ino, name);
+ remove_node(f, in->nodeid, name);
}
free(path);
}
struct fuse_entry_out outarg;
res = -ENOENT;
- path = get_path_name(f, in->ino, name);
+ path = get_path_name(f, in->nodeid, name);
if (path != NULL) {
if (f->flags & FUSE_DEBUG) {
printf("SYMLINK %s\n", path);
if (f->op.symlink && f->op.getattr) {
res = f->op.symlink(link, path);
if (res == 0)
- res = lookup_path(f, in->ino, in->unique, name, path, &outarg);
+ res = lookup_path(f, in->nodeid, in->unique, name, path, &outarg);
}
free(path);
}
res2 = send_reply(f, in, res, &outarg, sizeof(outarg));
if (res == 0 && res2 == -ENOENT)
- destroy_node(f, outarg.ino, in->unique);
+ destroy_node(f, outarg.nodeid, in->unique);
}
struct fuse_rename_in *inarg)
{
int res;
- fino_t olddir = in->ino;
- fino_t newdir = inarg->newdir;
+ nodeid_t olddir = in->nodeid;
+ nodeid_t newdir = inarg->newdir;
char *oldname = PARAM(inarg);
char *newname = oldname + strlen(oldname) + 1;
char *oldpath;
struct fuse_entry_out outarg;
res = -ENOENT;
- oldpath = get_path(f, in->ino);
+ oldpath = get_path(f, in->nodeid);
if (oldpath != NULL) {
newpath = get_path_name(f, arg->newdir, name);
if (newpath != NULL) {
}
res2 = send_reply(f, in, res, &outarg, sizeof(outarg));
if (res == 0 && res2 == -ENOENT)
- destroy_node(f, outarg.ino, in->unique);
+ destroy_node(f, outarg.nodeid, in->unique);
}
static void do_open(struct fuse *f, struct fuse_in_header *in,
struct fuse_open_out outarg;
res = -ENOENT;
- path = get_path(f, in->ino);
+ path = get_path(f, in->nodeid);
if (path != NULL) {
res = -ENOSYS;
if (f->op.open)
if(f->op.release)
f->op.release(path, arg->flags);
} else
- get_node(f, in->ino)->open_count ++;
+ get_node(f, in->nodeid)->open_count ++;
pthread_mutex_unlock(&f->lock);
} else
int res;
res = -ENOENT;
- path = get_path(f, in->ino);
+ path = get_path(f, in->nodeid);
if (path != NULL) {
if (f->flags & FUSE_DEBUG) {
printf("FLUSH[%lu]\n", arg->fh);
char *path;
pthread_mutex_lock(&f->lock);
- node = get_node(f, in->ino);
+ node = get_node(f, in->nodeid);
--node->open_count;
pthread_mutex_unlock(&f->lock);
- path = get_path(f, in->ino);
+ path = get_path(f, in->nodeid);
if (path != NULL) {
if (f->flags & FUSE_DEBUG) {
printf("RELEASE[%lu]\n", arg->fh);
size_t outsize;
res = -ENOENT;
- path = get_path(f, in->ino);
+ path = get_path(f, in->nodeid);
if (path != NULL) {
if (f->flags & FUSE_DEBUG) {
printf("READ[%lu] %u bytes from %llu\n", arg->fh, arg->size,
struct fuse_write_out outarg;
res = -ENOENT;
- path = get_path(f, in->ino);
+ path = get_path(f, in->nodeid);
if (path != NULL) {
if (f->flags & FUSE_DEBUG) {
printf("WRITE%s[%lu] %u bytes to %llu\n",
char *path;
res = -ENOENT;
- path = get_path(f, in->ino);
+ path = get_path(f, in->nodeid);
if (path != NULL) {
if (f->flags & FUSE_DEBUG) {
printf("FSYNC[%lu]\n", inarg->fh);
unsigned char *value = name + strlen(name) + 1;
res = -ENOENT;
- path = get_path(f, in->ino);
+ path = get_path(f, in->nodeid);
if (path != NULL) {
res = -ENOSYS;
if (f->op.setxattr)
char *path;
res = -ENOENT;
- path = get_path(f, in->ino);
+ path = get_path(f, in->nodeid);
if (path != NULL) {
res = -ENOSYS;
if (f->op.getxattr)
char *path;
res = -ENOENT;
- path = get_path(f, in->ino);
+ path = get_path(f, in->nodeid);
if (path != NULL) {
res = -ENOSYS;
if (f->op.listxattr)
char *path;
res = -ENOENT;
- path = get_path(f, in->ino);
+ path = get_path(f, in->nodeid);
if (path != NULL) {
res = -ENOSYS;
if (f->op.removexattr)
dec_avail(f);
if ((f->flags & FUSE_DEBUG)) {
- printf("unique: %i, opcode: %s (%i), ino: %li, insize: %i\n",
- in->unique, opname(in->opcode), in->opcode, in->ino,
+ printf("unique: %i, opcode: %s (%i), nodeid: %li, insize: %i\n",
+ in->unique, opname(in->opcode), in->opcode, in->nodeid,
cmd->buflen);
fflush(stdout);
}
{
int res;
int err;
- fino_t ino;
+ nodeid_t nodeid;
+ unsigned long ino;
struct fuse_user_header h;
- err = path_lookup(f, path, &ino);
+ err = path_lookup(f, path, &nodeid, &ino);
if (err) {
if (err == -ENOENT)
return 0;
memset(&h, 0, sizeof(struct fuse_user_header));
h.opcode = FUSE_INVALIDATE;
+ h.nodeid = nodeid;
h.ino = ino;
if ((f->flags & FUSE_DEBUG)) {
- printf("INVALIDATE ino: %li\n", ino);
+ printf("INVALIDATE nodeid: %li\n", nodeid);
fflush(stdout);
}
int fuse_is_lib_option(const char *opt)
{
if (strcmp(opt, "debug") == 0 ||
- strcmp(opt, "hard_remove") == 0)
+ strcmp(opt, "hard_remove") == 0 ||
+ strcmp(opt, "use_ino") == 0)
return 1;
else
return 0;
f->flags |= FUSE_DEBUG;
else if (strcmp(opt, "hard_remove") == 0)
f->flags |= FUSE_HARD_REMOVE;
+ else if (strcmp(opt, "use_ino") == 0)
+ f->flags |= FUSE_USE_INO;
else
fprintf(stderr, "fuse: warning: unknown option `%s'\n", opt);
}
if (f->name_table == NULL)
goto out_free;
- f->ino_table_size = 14057;
- f->ino_table = (struct node **)
- calloc(1, sizeof(struct node *) * f->ino_table_size);
- if (f->ino_table == NULL)
+ f->id_table_size = 14057;
+ f->id_table = (struct node **)
+ calloc(1, sizeof(struct node *) * f->id_table_size);
+ if (f->id_table == NULL)
goto out_free_name_table;
pthread_mutex_init(&f->lock, NULL);
root = (struct node *) calloc(1, sizeof(struct node));
if (root == NULL)
- goto out_free_ino_table;
+ goto out_free_id_table;
root->mode = 0;
root->rdev = 0;
goto out_free_root;
root->parent = 0;
- root->ino = FUSE_ROOT_INO;
+ root->nodeid = FUSE_ROOT_ID;
root->generation = 0;
- hash_ino(f, root);
+ hash_id(f, root);
return f;
out_free_root:
free(root);
- out_free_ino_table:
- free(f->ino_table);
+ out_free_id_table:
+ free(f->id_table);
out_free_name_table:
free(f->name_table);
out_free:
void fuse_destroy(struct fuse *f)
{
size_t i;
- for (i = 0; i < f->ino_table_size; i++) {
+ for (i = 0; i < f->id_table_size; i++) {
struct node *node;
- for (node = f->ino_table[i]; node != NULL; node = node->ino_next) {
+ for (node = f->id_table[i]; node != NULL; node = node->id_next) {
if (node->is_hidden) {
- char *path = get_path(f, node->ino);
+ char *path = get_path(f, node->nodeid);
if (path)
f->op.unlink(path);
}
}
}
- for (i = 0; i < f->ino_table_size; i++) {
+ for (i = 0; i < f->id_table_size; i++) {
struct node *node;
struct node *next;
- for (node = f->ino_table[i]; node != NULL; node = next) {
- next = node->ino_next;
+ for (node = f->id_table[i]; node != NULL; node = next) {
+ next = node->id_next;
free_node(node);
}
}
- free(f->ino_table);
+ free(f->id_table);
free(f->name_table);
pthread_mutex_destroy(&f->lock);
free(f);