Quantcast

Allow read/write/flush/fsync of unlinked files when FUSE_HARD_REMOVE is set.

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Allow read/write/flush/fsync of unlinked files when FUSE_HARD_REMOVE is set.

John Muir-3
Hi,

I ran into trouble trying to read/write in an unlinked file with the
fuse library. The attached patch to fuse 2.3.0 modifies read, write,
flush, and fsync so that they will function even if the path cannot be
found when FUSE_HARD_REMOVE is set.

In addition, the following libc functions do not work on unlinked files:
- ftruncate
- fstat
- fchmod
- fchown
- f*xattr

Of course, you can argue as to the validity of doing some of those on an
unlinked file. However, I think we should allow ftruncate and fstat at
least.

In order to make the list above work however, one would need to change
the fuse_operations to either add new interfaces or change the existing
interfaces. Comments?

John.

--
John Muir
NORTEL
[hidden email]



diff -Nur fuse-2.3.0/lib/fuse.c.orig fuse-2.3.0/lib/fuse.c
--- fuse-2.3.0/lib/fuse.c.orig 2005-06-06 12:54:35.458614115 -0400
+++ fuse-2.3.0/lib/fuse.c 2005-06-06 12:57:29.513458487 -0400
@@ -1140,15 +1140,16 @@
     res = -ENOENT;
     pthread_rwlock_rdlock(&f->tree_lock);
     path = get_path(f, in->nodeid);
-    if (path != NULL) {
+    if (path != NULL || f->flags & FUSE_HARD_REMOVE) {
         if (f->flags & FUSE_DEBUG) {
             printf("FLUSH[%lu]\n", (unsigned long) arg->fh);
             fflush(stdout);
         }
         res = -ENOSYS;
         if (f->op.flush)
-            res = f->op.flush(path, &fi);
-        free(path);
+            res = f->op.flush(path ? path : "-", &fi);
+        if (path)
+            free(path);
     }
     pthread_rwlock_unlock(&f->tree_lock);
     send_reply(f, in, res, NULL, 0);
@@ -1217,7 +1218,7 @@
     res = -ENOENT;
     pthread_rwlock_rdlock(&f->tree_lock);
     path = get_path(f, in->nodeid);
-    if (path != NULL) {
+    if (path != NULL || f->flags & FUSE_HARD_REMOVE) {
         if (f->flags & FUSE_DEBUG) {
             printf("READ[%lu] %u bytes from %llu\n",
                    (unsigned long) arg->fh, arg->size, arg->offset);
@@ -1226,8 +1227,9 @@
 
         res = -ENOSYS;
         if (f->op.read)
-            res = f->op.read(path, buf, arg->size, arg->offset, &fi);
-        free(path);
+            res = f->op.read(path ? path : "-", buf, arg->size, arg->offset, &fi);
+        if (path)
+            free(path);
     }
     pthread_rwlock_unlock(&f->tree_lock);
 
@@ -1261,7 +1263,7 @@
     res = -ENOENT;
     pthread_rwlock_rdlock(&f->tree_lock);
     path = get_path(f, in->nodeid);
-    if (path != NULL) {
+    if (path != NULL || f->flags & FUSE_HARD_REMOVE) {
         if (f->flags & FUSE_DEBUG) {
             printf("WRITE%s[%lu] %u bytes to %llu\n",
                    (arg->write_flags & 1) ? "PAGE" : "",
@@ -1271,8 +1273,9 @@
 
         res = -ENOSYS;
         if (f->op.write)
-            res = f->op.write(path, PARAM(arg), arg->size, arg->offset, &fi);
-        free(path);
+            res = f->op.write(path ? path : "-", PARAM(arg), arg->size, arg->offset, &fi);
+        if (path)
+            free(path);
     }
     pthread_rwlock_unlock(&f->tree_lock);
 
@@ -1355,15 +1358,16 @@
     res = -ENOENT;
     pthread_rwlock_rdlock(&f->tree_lock);
     path = get_path(f, in->nodeid);
-    if (path != NULL) {
+    if (path != NULL || f->flags & FUSE_HARD_REMOVE) {
         if (f->flags & FUSE_DEBUG) {
             printf("FSYNC[%lu]\n", (unsigned long) inarg->fh);
             fflush(stdout);
         }
         res = -ENOSYS;
         if (f->op.fsync)
-            res = f->op.fsync(path, inarg->fsync_flags & 1, &fi);
-        free(path);
+            res = f->op.fsync(path ? path : "-", inarg->fsync_flags & 1, &fi);
+        if (path)
+            free(path);
     }
     pthread_rwlock_unlock(&f->tree_lock);
     send_reply(f, in, res, NULL, 0);
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Allow read/write/flush/fsync of unlinked files when FUSE_HARD_REMOVE is set.

Miklos Szeredi
> I ran into trouble trying to read/write in an unlinked file with the
> fuse library. The attached patch to fuse 2.3.0 modifies read, write,
> flush, and fsync so that they will function even if the path cannot be
> found when FUSE_HARD_REMOVE is set.

Why do you need "hard_remove"?

I think the solution to those problems you mention is just not to use
this option.  Perhaps this is not well enough documented, that this
option _will_ break expected semantics, and it's not recommended.

Miklos


-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games.  How far can you shotput
a projector? How fast can you ride your desk chair down the office luge track?
If you want to score the big prize, get to know the little guy.  
Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20
_______________________________________________
fuse-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/fuse-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Allow read/write/flush/fsync of unlinked files when FUSE_HARD_REMOVE is set.

John Muir-3
Miklos Szeredi wrote:

>>I ran into trouble trying to read/write in an unlinked file with the
>>fuse library. The attached patch to fuse 2.3.0 modifies read, write,
>>flush, and fsync so that they will function even if the path cannot be
>>found when FUSE_HARD_REMOVE is set.
>>    
>>
>
>Why do you need "hard_remove"?
>  
>
For each file, I open a duplicate. Sometimes the duplicate doesn't get
opened immediately. If all of a sudden the duplicate can be opened, and
the original file was deleted, I can ignore it instead of re-opening the
duplicate. If I was to not use hard_remove, I could look for
".fuse_hidden" in the file-name instead of "-".

Second, because I have duplicates of everything, when I receive an
unlink finally for the .fuse_hidden file, I will have to check the
file-name for every failed unlink operation. I guess that's not too bad.

Third should the file-system (or the entire system) crash, I didn't want
to have to go and search the entire file-system for .fuse_hidden* and
remove them at start-up. This will simply add startup-time cost when the
system wasn't shut-down cleanly (I can 'mark' the file-system for a
clean shut-down and avoid it then.)

>I think the solution to those problems you mention is just not to use
>this option.  Perhaps this is not well enough documented, that this
>option _will_ break expected semantics, and it's not recommended.
>  
>
OK. Maybe the hard_remove option shouldn't be available?

So, in addition to the problems out-lined in my previous e-mail, without
my patch, the following are true when hard_remove is set:

On unlinked files:
- read() doesn't work,
- write() doesn't work,
- fsync() doesn't work,
- close() returns -1 and sets errno to ENOENT when there wasn't really a
problem.

John.

--
John Muir
NORTEL
[hidden email]




-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games.  How far can you shotput
a projector? How fast can you ride your desk chair down the office luge track?
If you want to score the big prize, get to know the little guy.  
Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20
_______________________________________________
fuse-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/fuse-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Allow read/write/flush/fsync of unlinked files when FUSE_HARD_REMOVE is set.

Miklos Szeredi
> For each file, I open a duplicate. Sometimes the duplicate doesn't get
> opened immediately. If all of a sudden the duplicate can be opened, and
> the original file was deleted, I can ignore it instead of re-opening the
> duplicate. If I was to not use hard_remove, I could look for
> ".fuse_hidden" in the file-name instead of "-".

I'm not sure I understand.  Is it the case that you perform every
operation on two files instead of just one?  

> OK. Maybe the hard_remove option shouldn't be available?

Yes, that sounds like a good solution.  Or just make a very strong
warning in the README against it's use.

> So, in addition to the problems out-lined in my previous e-mail, without
> my patch, the following are true when hard_remove is set:
>
> On unlinked files:
> - read() doesn't work,
> - write() doesn't work,
> - fsync() doesn't work,
> - close() returns -1 and sets errno to ENOENT when there wasn't really a
> problem.

Yes, this is how it's supposed to work.  This option basically means,
that after removing an open file, everything will stop working.  The
release() method is the only exception, because I felt, that always
guaranteeing an open()/release() pair is important enough.

Miklos


-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games.  How far can you shotput
a projector? How fast can you ride your desk chair down the office luge track?
If you want to score the big prize, get to know the little guy.  
Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20
_______________________________________________
fuse-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/fuse-devel
Loading...