aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2004-10-19 22:01:21 +0000
committerMiklos Szeredi <miklos@szeredi.hu>2004-10-19 22:01:21 +0000
commita2c5e56bc066ba01b5f17e528b92c4d878226b25 (patch)
tree1741a3ee9a8c359755b1f265662e5ea7ef3902d7
parent127d49b0ef823cd8d7e6b83648f982566eab0016 (diff)
downloadlibfuse-a2c5e56bc066ba01b5f17e528b92c4d878226b25.tar.gz
fix
-rw-r--r--FAQ220
-rw-r--r--Filesystems2
-rw-r--r--README4
-rw-r--r--kernel/dev.c8
-rw-r--r--kernel/file.c10
5 files changed, 235 insertions, 9 deletions
diff --git a/FAQ b/FAQ
new file mode 100644
index 0000000..3b8cf5a
--- /dev/null
+++ b/FAQ
@@ -0,0 +1,220 @@
+Here are some good questions and answers in no particular order.
+
+---------------------------------------------------------------------------
+Subject: FUSE vs. LUFS
+
+
+> Can you explain me what are the differences between this two modules
+> and why did you start a new project?
+
+Well looking at the release dates on SF, the first release of FUSE is
+almost a year older than that of LUFS. But we probably weren't awere
+of each others project for quite some time.
+
+The main difference between them is that in LUFS the filesystem is a
+shared object (.so) which is loaded by lufsmount, and in FUSE the
+filesystem is a separate executable, which uses the fuse library. The
+actual API is very similar, and I've written a translator, that can
+load LUFS modules and run them using the FUSE kernel module (see the
+lufis package on the FUSE page).
+
+Another difference is that LUFS does some caching of directories and
+file attributes. FUSE does not do this, so it provides a 'thinner'
+interface.
+
+---------------------------------------------------------------------------
+Subject: close() not in struct fuse_operations
+
+
+> Is there a reason for 'close' not being one of the
+> fuse_operations? I'd need to know when files are
+> closed...
+
+It's not easy. Consider mmap(): if you have a memory file, even after
+closing it, you can read or write the file through memory.
+
+Despite this there are close()-like operations: flush and release.
+Flush gets called on each close() and release gets called when there
+are no more uses of a file, including memory mappings.
+
+---------------------------------------------------------------------------
+Subject: overlapping open/release states
+
+
+> I'm using a fairly current CVS version of Fuse, and have noticed
+> overlapping open / release calls for a file. In other words a file
+> is opened multiple times and receives multiple release calls. Is
+> this expected?
+
+It has always been like this. The open / release calls correspond to
+actual file opens / releases. The release is called when there are no
+more refernces to the file, i.e. on the last close() or munmap().
+
+> This isn't what I expected. Do I need to keep track of how many
+> open() calls were made to a file and expect that many release() calls?
+
+Yes. You can also keep track of the number of files opened for
+writing for example, and use that information for finally flushing
+dirty data of a file.
+
+> So it appears that there may even be additional file operations after
+> one or more of the release calls..
+
+That is expected also. It would be a bug if there were reads/writes
+after the last release, or if the number of releases didn't match the
+number of opens.
+
+> I've solved this in my code by counting the number of open / release
+> calls and only dropping information when the last expected release
+> is received. But I thought I'd point this out in case, as it was
+> unexpected behavior..
+
+---------------------------------------------------------------------------
+Subject: return value from release()
+
+
+> Hmm. So it doesn't matter what I return from my release function? I
+> understand there is not an exact 1:1 relationship between close() and
+> release, but I had hoped that a error return from release would be
+> carried up as an error return from close().
+
+In release() the error value is ignored, and not every close will
+cause a release. Consider this:
+
+ - process opens a file
+ - process forks
+ - parent closes the file
+ - child closes the file
+
+The file will only be released on the second close, i.e. when all
+references to the file are closed. Also memory mapping a file creates
+a reference to the file, that is released when the memory is unmapped.
+
+There is a flush() operation that is called on every close(), through
+which the filesystem can return an error.
+
+Note: there can be read/write operations even after the last flush()
+but before a release().
+
+---------------------------------------------------------------------------
+Subject: FUSE lacks ioctl support
+
+
+> I'll try to add ioctl support to FUSE, but I am quite new to it, so I
+> would apreciate any suggestions.
+
+It's not clear to me how would you use ioctls since they are
+meaningless on normal files, and on device files the filesystem
+implementation usually does not care about the ioctl operations. And
+even if you manage to hack fuse to intercept device ioctls, you
+wouldn't be able to do anything with them, because they contain
+arbitrarily structured data (not length/value as in the case of read
+or write).
+
+[...]
+
+Using getxattr() and setxattr() is much cleaner than ioctl(), and is
+actually supported in fuse-2.0.
+
+---------------------------------------------------------------------------
+Subject: Short reads
+
+
+> Now for the problem case: I cat the 256k file, the kernel issues a
+> read with length 65536 and offset 0. My program returns only 10
+> bytes. What I expected to see was the kernel to then issue a read for
+> length 65536 and offset 10. Instead what I saw in the result was the
+> 10 bytes I returned, followed by 65526 zero bytes.
+>
+> Is this the intended behavior?
+
+Yes. You can easily program around it with a for-loop in your read
+function.
+
+> Does this simplify things significantly? If it isn't much of a
+> difference, I'd like to suggest doing it the other way: many people
+> (like me) implement their fuse read function in terms of read(), and
+> read() can return early.
+
+No. Read from a pipe/socket can be short, but read from a file can't.
+
+---------------------------------------------------------------------------
+Subject: protocol error
+
+> I'm having trouble with file writing. I can
+> 'echo something > file' to a file, but
+> 'cp file something' or 'cat something > file'
+> gives a protocol error.
+
+Two possible reasons for this are:
+
+1) A mismatch between the library version and the kernel module
+version.
+
+2) The write() operation returns less than the 'size' parameter.
+Short writes are generally not allowed (as in case of read()). The
+exception is if the 'direct_io' mount option is used.
+
+---------------------------------------------------------------------------
+Subject: FUSE naming
+
+
+> There are a million other projects with the same name. Why did you
+> call it 'FUSE'?
+
+Because I'm an imbecile. The lesson is that a common term is not a
+good project name. A somewhat strange story comes to my mind: I was
+contacted by Philip Kendall shortly after releasing FUSE, blaming me
+for choosing the same name as his ZX Spectrum emulator (Fuse). We
+have known each other from earlier times, since I have also written a
+ZX Spectrum emulator (Spectemu).
+
+---------------------------------------------------------------------------
+Subject: Uid/gid/pid
+
+
+> Is there any easy way to know the uid of a reader? For example, let's
+> say I wanted to create a file that contained 'foo' for uid 1, but
+> 'bar' for uid 2.
+
+Yes:
+
+fuse_get_context()->uid
+
+
+---------------------------------------------------------------------------
+Subject: 'find' command
+
+
+> I'm having trouble getting the find command to search through fuse
+> directories. What settings do I need in 'getattr'?
+
+use the -noleaf option to find
+(find uses the following parameters to determine whether it should recurse
+into a subdirectory)
+
+nr_links must be >= 3
+size must be > 0
+and must be a directory
+
+so just return those in the getattr for your directories and you wont have
+to use -noleaf.
+
+---------------------------------------------------------------------------
+Subject: File system interactivity
+
+> I need to add interactivity to my user space file system.
+> For example, while executing create(), I need to ask a
+> question to the terminal that issued the request.
+>
+> Is there a way I can achieve this goal?
+
+It would not be possible generally speaking, since it might not be an
+interactive program but rather a daemon, or a GUI program creating the
+file. However you should be able to get the PID for the caller, and
+by looking in /proc you should be able to find the process tty or
+something similar. Perhaps it would be better to redesign your program
+not to have such interactivity anyway, try to use e.g. extended
+attributes of files to set per-file options, or a configuration file
+for your filesystem.
+
diff --git a/Filesystems b/Filesystems
index 6332cc4..3ca82dc 100644
--- a/Filesystems
+++ b/Filesystems
@@ -120,7 +120,7 @@ Name: LUFS bridge (alpha)
Author: Miklos Szeredi <mszeredi at inf bme hu>
-Homepage: http://sourceforge.net/project/showfiles.php?group_id=21636&package_id=109154
+Homepage: http://sourceforge.net/project/showfiles.php?group_id=121684&package_id=132803
Description:
diff --git a/README b/README
index f00e303..50e9f2b 100644
--- a/README
+++ b/README
@@ -8,12 +8,12 @@ create and mount their own filesystem implementations.
You can download the source code releases from
- http://sourceforge.net/projects/avf
+ http://sourceforge.net/projects/fuse
or alternatively you can use CVS to get the very latest development
version by setting the cvsroot to
- :pserver:anonymous@cvs.avf.sourceforge.net:/cvsroot/avf
+ :pserver:anonymous@cvs.sourceforge.net:/cvsroot/fuse
and checking out the 'fuse' module.
diff --git a/kernel/dev.c b/kernel/dev.c
index ac856cb..c783ead 100644
--- a/kernel/dev.c
+++ b/kernel/dev.c
@@ -121,6 +121,9 @@ static struct fuse_req *do_get_request(struct fuse_conn *fc)
list_del_init(&req->list);
spin_unlock(&fuse_lock);
fuse_reset_request(req);
+ req->in.h.uid = current->fsuid;
+ req->in.h.gid = current->fsgid;
+ req->in.h.pid = current->pid;
return req;
}
@@ -132,9 +135,6 @@ struct fuse_req *fuse_get_request(struct fuse_conn *fc)
return NULL;
req = do_get_request(fc);
- req->in.h.uid = current->fsuid;
- req->in.h.gid = current->fsgid;
- req->in.h.pid = current->pid;
return req;
}
@@ -146,8 +146,6 @@ struct fuse_req *fuse_get_request_nonblock(struct fuse_conn *fc)
return NULL;
req = do_get_request(fc);
- req->in.h.uid = current->fsuid;
- req->in.h.gid = current->fsgid;
return req;
}
diff --git a/kernel/file.c b/kernel/file.c
index ec2e40c..91fd07b 100644
--- a/kernel/file.c
+++ b/kernel/file.c
@@ -598,6 +598,11 @@ static ssize_t fuse_send_write(struct fuse_req *req, int writepage,
inarg.size = count;
req->in.h.opcode = FUSE_WRITE;
req->in.h.ino = inode->i_ino;
+ if (writepage) {
+ req->in.h.uid = 0;
+ req->in.h.gid = 0;
+ req->in.h.pid = 0;
+ }
req->in.numargs = 2;
req->in.args[0].size = sizeof(inarg);
req->in.args[0].value = &inarg;
@@ -740,7 +745,7 @@ static void send_write_nonblock(struct fuse_req *req, struct inode *inode,
struct fuse_write_in *inarg;
struct fuse_file *ff;
char *buffer;
-
+
BUG_ON(list_empty(&fi->write_files));
ff = list_entry(fi->write_files.next, struct fuse_file, ff_list);
@@ -752,6 +757,9 @@ static void send_write_nonblock(struct fuse_req *req, struct inode *inode,
inarg->size = count;
req->in.h.opcode = FUSE_WRITE;
req->in.h.ino = inode->i_ino;
+ req->in.h.uid = 0;
+ req->in.h.gid = 0;
+ req->in.h.pid = 0;
req->in.numargs = 2;
req->in.args[0].size = sizeof(struct fuse_write_in);
req->in.args[0].value = inarg;