Commit 9e6268db authored by Miklos Szeredi's avatar Miklos Szeredi Committed by Linus Torvalds

[PATCH] FUSE - read-write operations

This patch adds the write filesystem operations of FUSE.

The following operations are added:

 o setattr
 o symlink
 o mknod
 o mkdir
 o create
 o unlink
 o rmdir
 o rename
 o link
Signed-off-by: default avatarMiklos Szeredi <miklos@szeredi.hu>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent e5e5558e
This diff is collapsed.
...@@ -30,6 +30,9 @@ struct fuse_inode { ...@@ -30,6 +30,9 @@ struct fuse_inode {
* and kernel */ * and kernel */
u64 nodeid; u64 nodeid;
/** Number of lookups on this inode */
u64 nlookup;
/** The request used for sending the FORGET message */ /** The request used for sending the FORGET message */
struct fuse_req *forget_req; struct fuse_req *forget_req;
...@@ -252,13 +255,13 @@ extern spinlock_t fuse_lock; ...@@ -252,13 +255,13 @@ extern spinlock_t fuse_lock;
* Get a filled in inode * Get a filled in inode
*/ */
struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid, struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
int generation, struct fuse_attr *attr, int version); int generation, struct fuse_attr *attr);
/** /**
* Send FORGET command * Send FORGET command
*/ */
void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req, void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
unsigned long nodeid, int version); unsigned long nodeid, u64 nlookup);
/** /**
* Initialise inode operations on regular files and special files * Initialise inode operations on regular files and special files
......
...@@ -51,6 +51,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) ...@@ -51,6 +51,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
fi = get_fuse_inode(inode); fi = get_fuse_inode(inode);
fi->i_time = jiffies - 1; fi->i_time = jiffies - 1;
fi->nodeid = 0; fi->nodeid = 0;
fi->nlookup = 0;
fi->forget_req = fuse_request_alloc(); fi->forget_req = fuse_request_alloc();
if (!fi->forget_req) { if (!fi->forget_req) {
kmem_cache_free(fuse_inode_cachep, inode); kmem_cache_free(fuse_inode_cachep, inode);
...@@ -74,10 +75,10 @@ static void fuse_read_inode(struct inode *inode) ...@@ -74,10 +75,10 @@ static void fuse_read_inode(struct inode *inode)
} }
void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req, void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
unsigned long nodeid, int version) unsigned long nodeid, u64 nlookup)
{ {
struct fuse_forget_in *inarg = &req->misc.forget_in; struct fuse_forget_in *inarg = &req->misc.forget_in;
inarg->version = version; inarg->nlookup = nlookup;
req->in.h.opcode = FUSE_FORGET; req->in.h.opcode = FUSE_FORGET;
req->in.h.nodeid = nodeid; req->in.h.nodeid = nodeid;
req->in.numargs = 1; req->in.numargs = 1;
...@@ -91,7 +92,7 @@ static void fuse_clear_inode(struct inode *inode) ...@@ -91,7 +92,7 @@ static void fuse_clear_inode(struct inode *inode)
struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_conn *fc = get_fuse_conn(inode);
if (fc) { if (fc) {
struct fuse_inode *fi = get_fuse_inode(inode); struct fuse_inode *fi = get_fuse_inode(inode);
fuse_send_forget(fc, fi->forget_req, fi->nodeid, inode->i_version); fuse_send_forget(fc, fi->forget_req, fi->nodeid, fi->nlookup);
fi->forget_req = NULL; fi->forget_req = NULL;
} }
} }
...@@ -156,9 +157,10 @@ static int fuse_inode_set(struct inode *inode, void *_nodeidp) ...@@ -156,9 +157,10 @@ static int fuse_inode_set(struct inode *inode, void *_nodeidp)
} }
struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid, struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
int generation, struct fuse_attr *attr, int version) int generation, struct fuse_attr *attr)
{ {
struct inode *inode; struct inode *inode;
struct fuse_inode *fi;
struct fuse_conn *fc = get_fuse_conn_super(sb); struct fuse_conn *fc = get_fuse_conn_super(sb);
int retried = 0; int retried = 0;
...@@ -181,8 +183,9 @@ struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid, ...@@ -181,8 +183,9 @@ struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
goto retry; goto retry;
} }
fi = get_fuse_inode(inode);
fi->nlookup ++;
fuse_change_attributes(inode, attr); fuse_change_attributes(inode, attr);
inode->i_version = version;
return inode; return inode;
} }
...@@ -389,7 +392,7 @@ static struct inode *get_root_inode(struct super_block *sb, unsigned mode) ...@@ -389,7 +392,7 @@ static struct inode *get_root_inode(struct super_block *sb, unsigned mode)
attr.mode = mode; attr.mode = mode;
attr.ino = FUSE_ROOT_ID; attr.ino = FUSE_ROOT_ID;
return fuse_iget(sb, 1, 0, &attr, 0); return fuse_iget(sb, 1, 0, &attr);
} }
static struct super_operations fuse_super_operations = { static struct super_operations fuse_super_operations = {
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include <asm/types.h> #include <asm/types.h>
/** Version number of this interface */ /** Version number of this interface */
#define FUSE_KERNEL_VERSION 6 #define FUSE_KERNEL_VERSION 7
/** Minor version number of this interface */ /** Minor version number of this interface */
#define FUSE_KERNEL_MINOR_VERSION 1 #define FUSE_KERNEL_MINOR_VERSION 1
...@@ -52,12 +52,28 @@ struct fuse_kstatfs { ...@@ -52,12 +52,28 @@ struct fuse_kstatfs {
__u32 namelen; __u32 namelen;
}; };
#define FATTR_MODE (1 << 0)
#define FATTR_UID (1 << 1)
#define FATTR_GID (1 << 2)
#define FATTR_SIZE (1 << 3)
#define FATTR_ATIME (1 << 4)
#define FATTR_MTIME (1 << 5)
#define FATTR_CTIME (1 << 6)
enum fuse_opcode { enum fuse_opcode {
FUSE_LOOKUP = 1, FUSE_LOOKUP = 1,
FUSE_FORGET = 2, /* no reply */ FUSE_FORGET = 2, /* no reply */
FUSE_GETATTR = 3, FUSE_GETATTR = 3,
FUSE_SETATTR = 4,
FUSE_READLINK = 5, FUSE_READLINK = 5,
FUSE_SYMLINK = 6,
FUSE_GETDIR = 7, FUSE_GETDIR = 7,
FUSE_MKNOD = 8,
FUSE_MKDIR = 9,
FUSE_UNLINK = 10,
FUSE_RMDIR = 11,
FUSE_RENAME = 12,
FUSE_LINK = 13,
FUSE_STATFS = 17, FUSE_STATFS = 17,
FUSE_INIT = 26 FUSE_INIT = 26
}; };
...@@ -66,6 +82,7 @@ enum fuse_opcode { ...@@ -66,6 +82,7 @@ enum fuse_opcode {
#define FUSE_MAX_IN 8192 #define FUSE_MAX_IN 8192
#define FUSE_NAME_MAX 1024 #define FUSE_NAME_MAX 1024
#define FUSE_SYMLINK_MAX 4096
struct fuse_entry_out { struct fuse_entry_out {
__u64 nodeid; /* Inode ID */ __u64 nodeid; /* Inode ID */
...@@ -79,7 +96,7 @@ struct fuse_entry_out { ...@@ -79,7 +96,7 @@ struct fuse_entry_out {
}; };
struct fuse_forget_in { struct fuse_forget_in {
__u64 version; __u64 nlookup;
}; };
struct fuse_attr_out { struct fuse_attr_out {
...@@ -93,6 +110,28 @@ struct fuse_getdir_out { ...@@ -93,6 +110,28 @@ struct fuse_getdir_out {
__u32 fd; __u32 fd;
}; };
struct fuse_mknod_in {
__u32 mode;
__u32 rdev;
};
struct fuse_mkdir_in {
__u32 mode;
};
struct fuse_rename_in {
__u64 newdir;
};
struct fuse_link_in {
__u64 oldnodeid;
};
struct fuse_setattr_in {
__u32 valid;
struct fuse_attr attr;
};
struct fuse_statfs_out { struct fuse_statfs_out {
struct fuse_kstatfs st; struct fuse_kstatfs st;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment