[fuse-discuss] Major problems with |fuse_get_context()| and global variables...

Sarah Jelinek Sarah.Jelinek at Sun.COM
Mon Nov 20 09:56:37 PST 2006


Roland Mainz wrote:
> Hi!
>
> ----
>
> I did a quick look at the FUSE sources at
> http://src.opensolaris.org/source/xref/fuse/ and found the following
> piece of code in the public header
> http://src.opensolaris.org/source/xref/fuse/libfuse/include/fuse.h
> -- snip --
>     473 /**
>     474  * Get the current context
>     475  *
>     476  * The context is only valid for the duration of a filesystem
>     477  * operation, and thus must not be stored and used later.
>     478  *
>     479  * @param f the FUSE handle
>     480  * @return the context
>     481  */
>     482 struct fuse_context *fuse_get_context(void);
> -- snip --
>
> I would STRONGLY suggest to avoid the usage of such global or
> thread-local variables. IMO they cause huge pain and development
> problems for multithreaded applications and usually result in the use of
> locking and other horrific stunts in more complex applications (I'm
> currently in this hell with ksh83/libshell and it's not really fun top
> cleanup a large pile of global variables... ;-( ).
>   
Agreed. This code is currently inherited as is from the linux FUSE 
implemenation. This will be one thing we can keep in mind moving forward.

Thanks,
sarah
****
> My suggestion would be that each callback function called by FUSE
> accepts a |struct fuse_context *| as first parameter (and remove
> |fuse_get_context()|&co. completely) instead - this would avoid the use
> of global data and it's side-effects entirely.
>
> The resulting |fuse_operations| would look like this:
> -- snip --
> struct fuse_operations {
>     int (*getattr) (struct fuse_context *, const char *, struct stat *);
>
>     int (*readlink) (struct fuse_context *, const char *, char *,
> size_t);
>
>     int (*getdir) (struct fuse_context *, const char *, fuse_dirh_t,
> fuse_dirfil_t);
>
>     int (*mknod) (struct fuse_context *, const char *, mode_t, dev_t);
>
>     int (*mkdir) (struct fuse_context *, const char *, mode_t);
>
>     int (*unlink) (struct fuse_context *, const char *);
>
>     int (*rmdir) (struct fuse_context *, const char *);
>
>     int (*symlink) (struct fuse_context *, const char *, const char *);
>
>     int (*rename) (struct fuse_context *, const char *, const char *);
>
>     int (*link) (struct fuse_context *, const char *, const char *);
>
>     int (*chmod) (struct fuse_context *, const char *, mode_t);
>
>     int (*chown) (struct fuse_context *, const char *, uid_t, gid_t);
>
>     int (*truncate) (struct fuse_context *, const char *, off_t);
>
>     int (*utime) (struct fuse_context *, const char *, struct utimbuf
> *);
>
>     int (*open) (struct fuse_context *, const char *, struct
> fuse_file_info *);
>
>     int (*read) (struct fuse_context *, const char *, char *, size_t,
> off_t, struct fuse_file_info *);
>
>     int (*write) (struct fuse_context *, const char *, const char *,
> size_t, off_t,
>                   struct fuse_file_info *);
>
>     int (*statfs) (struct fuse_context *, const char *, struct statvfs
> *);
>
>     int (*flush) (struct fuse_context *, const char *, struct
> fuse_file_info *);
>
>     int (*release) (struct fuse_context *, const char *, struct
> fuse_file_info *);
>
>     int (*fsync) (struct fuse_context *, const char *, int, struct
> fuse_file_info *);
>
>     int (*setxattr) (struct fuse_context *, const char *, const char *,
> const char *, size_t, int);
>
>     int (*getxattr) (struct fuse_context *, const char *, const char *,
> char *, size_t);
>
>     int (*listxattr) (struct fuse_context *, const char *, char *,
> size_t);
>
>     int (*removexattr) (struct fuse_context *, const char *, const char
> *);
>
>     int (*opendir) (struct fuse_context *, const char *, struct
> fuse_file_info *);
>
>     int (*readdir) (struct fuse_context *, const char *, void *,
> fuse_fill_dir_t, off_t,
>                     struct fuse_file_info *);
>
>     int (*releasedir) (struct fuse_context *, const char *, struct
> fuse_file_info *);
>
>     int (*fsyncdir) (struct fuse_context *, const char *, int, struct
> fuse_file_info *);
>
>     void *(*init) (struct fuse_context *);
>
>     void (*destroy) (struct fuse_context *, void *);
>
>     int (*access) (struct fuse_context *, const char *, int);
>
>     int (*create) (struct fuse_context *, const char *, mode_t, struct
> fuse_file_info *);
>
>     int (*ftruncate) (struct fuse_context *, const char *, off_t, struct
> fuse_file_info *);
>
>     int (*fgetattr) (struct fuse_context *, const char *, struct stat *,
> struct fuse_file_info *);
> };
> -- snip --
>
> ----
>
> Bye,
> Roland
>
>   




More information about the fuse-discuss mailing list