X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=fs%2Ffuse%2Ffuse_i.h;h=b24fc9b386f826b10220f39136f4eda8def271f4;hb=6ff958edbf39c014eb06b65ad25b736be08c4e63;hp=b98b20de740562bd32dc81fcf8af415779496f97;hpb=7e23772f414cdbfb2a08aed237d6e926bb1cb728;p=linux-2.6 diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index b98b20de74..b24fc9b386 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -20,7 +20,10 @@ #define FUSE_MAX_PAGES_PER_REQ 32 /** Maximum number of outstanding background requests */ -#define FUSE_MAX_BACKGROUND 10 +#define FUSE_MAX_BACKGROUND 12 + +/** Congestion starts at 75% of maximum */ +#define FUSE_CONGESTION_THRESHOLD (FUSE_MAX_BACKGROUND * 75 / 100) /** It could be as large as PATH_MAX, but would that have any uses? */ #define FUSE_NAME_MAX 1024 @@ -60,6 +63,13 @@ struct fuse_inode { /** Time in jiffies until the file attributes are valid */ u64 i_time; + + /** The sticky bit in inode->i_mode may have been removed, so + preserve the original mode */ + mode_t orig_i_mode; + + /** Version of last attribute change */ + u64 attr_version; }; /** FUSE specific file data */ @@ -69,6 +79,9 @@ struct fuse_file { /** File handle used by userspace */ u64 fh; + + /** Refcount */ + atomic_t count; }; /** One input argument of a request */ @@ -213,7 +226,7 @@ struct fuse_req { unsigned page_offset; /** File used in the request (or NULL) */ - struct file *file; + struct fuse_file *ff; /** vfsmount used in release */ struct vfsmount *vfsmount; @@ -286,6 +299,9 @@ struct fuse_conn { /** waitq for blocked connection */ wait_queue_head_t blocked_waitq; + /** waitq for reserved requests */ + wait_queue_head_t reserved_req_waitq; + /** The next unique request id */ u64 reqctr; @@ -304,6 +320,9 @@ struct fuse_conn { /** Do readpages asynchronously? Only set in INIT */ unsigned async_read : 1; + /** Do not send separate SETATTR request before open(O_TRUNC) */ + unsigned atomic_o_trunc : 1; + /* * The following bitfields are only for optimization purposes * and hence races in setting them will not cause malfunction @@ -374,6 +393,9 @@ struct fuse_conn { /** Reserved request for the DESTROY message */ struct fuse_req *destroy_req; + + /** Version counter for attribute changes */ + u64 attr_version; }; static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb) @@ -403,7 +425,8 @@ extern const struct file_operations fuse_dev_operations; * Get a filled in inode */ struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid, - int generation, struct fuse_attr *attr); + int generation, struct fuse_attr *attr, + u64 attr_valid, u64 attr_version); /** * Send FORGET command @@ -414,7 +437,7 @@ void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req, /** * Initialize READ or READDIR request */ -void fuse_read_fill(struct fuse_req *req, struct file *file, +void fuse_read_fill(struct fuse_req *req, struct fuse_file *ff, struct inode *inode, loff_t pos, size_t count, int opcode); /** @@ -427,9 +450,9 @@ void fuse_file_free(struct fuse_file *ff); void fuse_finish_open(struct inode *inode, struct file *file, struct fuse_file *ff, struct fuse_open_out *outarg); -/** */ -struct fuse_req *fuse_release_fill(struct fuse_file *ff, u64 nodeid, int flags, - int opcode); +/** Fill in ff->reserved_req with a RELEASE request */ +void fuse_release_fill(struct fuse_file *ff, u64 nodeid, int flags, int opcode); + /** * Send RELEASE or RELEASEDIR request */ @@ -464,7 +487,8 @@ void fuse_init_symlink(struct inode *inode); /** * Change attributes of an inode */ -void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr); +void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, + u64 attr_valid, u64 attr_version); /** * Initialize the client device @@ -523,11 +547,6 @@ void request_send_background(struct fuse_conn *fc, struct fuse_req *req); /* Abort all requests */ void fuse_abort_conn(struct fuse_conn *fc); -/** - * Get the attributes of a file - */ -int fuse_do_getattr(struct inode *inode); - /** * Invalidate inode attributes */ @@ -552,3 +571,13 @@ int fuse_ctl_add_conn(struct fuse_conn *fc); * Remove connection from control filesystem */ void fuse_ctl_remove_conn(struct fuse_conn *fc); + +/** + * Is file type valid? + */ +int fuse_valid_type(int m); + +/** + * Is task allowed to perform filesystem operation? + */ +int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task);