Contradicting create() behaviour

View: New views
11 Messages — Rating Filter:   Alert me  
< Prev | 1 - 2 | Next >

Re: Contradicting create() behaviour

by Miklos Szeredi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sat, 19 Jul 2008, Nikolaus Rath wrote:
> Is there a particular reason why fuse calls getattr() after the
> create()? Why doesn't it trust the return value of the create()
> request to determine if everything worked fine?
>
> Does fuse do this for all kind of requests (e.g. also for link(),
> symlink() or chmod())?

Yes, after creating any object.

It does the getattr, so it can cache the attributes (ownership,
timestamps, etc.) immediately after lookup.  So it's basically just an
optimization, but one that currently can't be turned off ;)

Miklos

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
fuse-devel mailing list
fuse-devel@...
https://lists.sourceforge.net/lists/listinfo/fuse-devel

Re: Contradicting create() behaviour

by Gilad Rom-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Fri, 2008-07-18 at 18:51 +0200, Miklos Szeredi wrote:

> On Fri, 18 Jul 2008, Nikolaus Rath wrote:
> > Miklos Szeredi <miklos@...> writes:
> > > On Thu, 17 Jul 2008, Nikolaus Rath wrote:
> > >> |
> > >> | Is this the "right" way to do things, or should I still try to implement
> > >> | create()? is there a down side to using mknod+open instead?
> > >>
> > >> That's an alternative way to do things, but using create() should work
> > >> just as well.
> > >
> > > Right.
> > >
> > > The EIO is caused by ->getattr() not returning a correct st_mode
> > > value, i.e. S_ISREG(buf.st_mode) fails.
> > >
> > > (Yeah, I know, should be better ducumented ;)
> >
> > If can explain it to me, I may provide another patch :-).
> >
> >
> > From what function is EIO returned if S_ISREG fails? I didn't quite
> > get it...
>
> Sorry, I'll try again :)
>
> Fuse will return EIO if the filesystem did something contradictory.
>
> More specifically, here libfuse will return EIO (to the original
> open(O_CREAT) or create() syscalls), if after calling the ->create()
> method, and then calling the ->getattr() method, the returned file
> type in st_mode is not a regular file.
>


That's the thing - I couldn't see a getattr() call after create().
It looked as though the create() itself has failed, even though
I returned 0...

Gilad




-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
fuse-devel mailing list
fuse-devel@...
https://lists.sourceforge.net/lists/listinfo/fuse-devel

Re: Contradicting create() behaviour

by Miklos Szeredi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sun, 20 Jul 2008, Gilad Rom wrote:

> On Fri, 2008-07-18 at 18:51 +0200, Miklos Szeredi wrote:
> > More specifically, here libfuse will return EIO (to the original
> > open(O_CREAT) or create() syscalls), if after calling the ->create()
> > method, and then calling the ->getattr() method, the returned file
> > type in st_mode is not a regular file.
> >
>
>
> That's the thing - I couldn't see a getattr() call after create().
> It looked as though the create() itself has failed, even though
> I returned 0...

getattr() *or* fgetattr().  One of them must have been called if
create() succeeded.

Miklos

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
fuse-devel mailing list
fuse-devel@...
https://lists.sourceforge.net/lists/listinfo/fuse-devel

Re: Contradicting create() behaviour

by Gilad Rom-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Ok... let me rephrase that:

Is there a reason for create() to fail, even if it returned
0 ?

Gilad

On Wed, 2008-07-23 at 11:01 +0200, Miklos Szeredi wrote:

> On Sun, 20 Jul 2008, Gilad Rom wrote:
> > On Fri, 2008-07-18 at 18:51 +0200, Miklos Szeredi wrote:
> > > More specifically, here libfuse will return EIO (to the original
> > > open(O_CREAT) or create() syscalls), if after calling the ->create()
> > > method, and then calling the ->getattr() method, the returned file
> > > type in st_mode is not a regular file.
> > >
> >
> >
> > That's the thing - I couldn't see a getattr() call after create().
> > It looked as though the create() itself has failed, even though
> > I returned 0...
>
> getattr() *or* fgetattr().  One of them must have been called if
> create() succeeded.
>
> Miklos


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
fuse-devel mailing list
fuse-devel@...
https://lists.sourceforge.net/lists/listinfo/fuse-devel

Re: Contradicting create() behaviour

by Miklos Szeredi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, 23 Jul 2008, Gilad Rom wrote:
> Ok... let me rephrase that:
>
> Is there a reason for create() to fail, even if it returned
> 0 ?

Yes, but only _after_ calling fgetattr() or getattr(), and only if
those either returned an error, or they returned an invalid st_mode
value.  I pretty sure that it was the latter that caused CREATE to
return EIO in your case:

| unique: 2514, opcode: CREATE (35), nodeid: 1, insize: 58
|    NODEID: 3
| release: closing file /newfile13
| delete: 3
|    unique: 2514, error: -5 (Input/output error), outsize: 16

Miklos

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
fuse-devel mailing list
fuse-devel@...
https://lists.sourceforge.net/lists/listinfo/fuse-devel

Re: Contradicting create() behaviour

by Gilad Rom-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Ok - solved. After stepping using GDB, fgetattr() is indeed called,
but is not printed as an opcode.... That was the confusing part ;)

(might want to fix that?!)

Thanks!

-- Gilad


On Wed, 2008-07-23 at 19:08 +0200, Miklos Szeredi wrote:

> On Wed, 23 Jul 2008, Gilad Rom wrote:
> > Ok... let me rephrase that:
> >
> > Is there a reason for create() to fail, even if it returned
> > 0 ?
>
> Yes, but only _after_ calling fgetattr() or getattr(), and only if
> those either returned an error, or they returned an invalid st_mode
> value.  I pretty sure that it was the latter that caused CREATE to
> return EIO in your case:
>
> | unique: 2514, opcode: CREATE (35), nodeid: 1, insize: 58
> |    NODEID: 3
> | release: closing file /newfile13
> | delete: 3
> |    unique: 2514, error: -5 (Input/output error), outsize: 16
>
> Miklos


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
fuse-devel mailing list
fuse-devel@...
https://lists.sourceforge.net/lists/listinfo/fuse-devel

Re: Contradicting create() behaviour

by Miklos Szeredi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, 24 Jul 2008, Gilad Rom wrote:
> Ok - solved. After stepping using GDB, fgetattr() is indeed called,
> but is not printed as an opcode.... That was the confusing part ;)
>
> (might want to fix that?!)

OK, that's now fixed in CVS.

Miklos

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
fuse-devel mailing list
fuse-devel@...
https://lists.sourceforge.net/lists/listinfo/fuse-devel

Re: Contradicting create() behaviour

by Goswin von Brederlow-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Miklos Szeredi <miklos@...> writes:

> On Thu, 24 Jul 2008, Gilad Rom wrote:
>> Ok - solved. After stepping using GDB, fgetattr() is indeed called,
>> but is not printed as an opcode.... That was the confusing part ;)
>>
>> (might want to fix that?!)
>
> OK, that's now fixed in CVS.
>
> Miklos

I did run into the same problem but with a different cause.
My code looked simplified like this:

int create(const char *path, mode_t, struct fuse_file_info *fi) {
  char *name = rindex(path, '/');
  *name = 0;
  ++name;
  Dir *dir = lookup(path);
  fi->fh = create_file(dir, name);
  return 0;
}


Now I see that I violate the const-ness in path but it causes the
following call sequence:

create("/foo", mode, fi);
getattr("", buf);

and that gave the wrong attributes. Took me ages to find the problem
as g++ also doesn't warn about the violation of const.



But all that aside. Why is it neccessary for libfuse to call getattr()
after mknod() or create()?

MfG
        Goswin

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
fuse-devel mailing list
fuse-devel@...
https://lists.sourceforge.net/lists/listinfo/fuse-devel

Re: Contradicting create() behaviour

by Miklos Szeredi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, 07 Aug 2008, Goswin von Brederlow wrote:
> Now I see that I violate the const-ness in path but it causes the
> following call sequence:
>
> create("/foo", mode, fi);
> getattr("", buf);
>
> and that gave the wrong attributes. Took me ages to find the problem
> as g++ also doesn't warn about the violation of const.

Mmm, lots of people run into this.  How come g++ doesn't warn on const
violation?  I thought that C++ was supposed to have _stricter_ type
checking than C.

> But all that aside. Why is it neccessary for libfuse to call getattr()
> after mknod() or create()?

Because it wants to cache the attributes the file was created with,
without having to perform a separate GETATTR request that would almost
certainly follow shortly after the creation.

It's not strictly necessary, but currently there's no way to turn off
this behavior.

Miklos

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
fuse-devel mailing list
fuse-devel@...
https://lists.sourceforge.net/lists/listinfo/fuse-devel

Re: Contradicting create() behaviour

by Mark Huijgen-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Miklos Szeredi wrote:

> On Thu, 07 Aug 2008, Goswin von Brederlow wrote:
>  
>> Now I see that I violate the const-ness in path but it causes the
>> following call sequence:
>>
>> create("/foo", mode, fi);
>> getattr("", buf);
>>
>> and that gave the wrong attributes. Took me ages to find the problem
>> as g++ also doesn't warn about the violation of const.
>>    
>
> Mmm, lots of people run into this.  How come g++ doesn't warn on const
> violation?  I thought that C++ was supposed to have _stricter_ type
> checking than C.
>  
The example from Goswin itself does not violate const directly though:
-------------------------------------

int create(const char *path, mode_t, struct fuse_file_info *fi) {
  char *name = rindex(path, '/');
-------------------------------------

In this case the rindex function internally violates it by returning a non const pointer to (a part of) a const string.


If you compile the following example with g++ it will give an error about violating const:
error: invalid conversion from ‘const char*’ to ‘char*’
-------------------------------------
char * test_f(const char* string)
{
    return string+1;
}

int main()
{
    char * a = test_f("test");
}
-------------------------------------

So, yes c++ does do stricter type checking, but rindex is compiled by gcc as part of glibc and C doesn't complain about this, although it gives a warning "return discards qualifiers from pointer target type".

Mark


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
fuse-devel mailing list
fuse-devel@...
https://lists.sourceforge.net/lists/listinfo/fuse-devel

Re: Contradicting create() behaviour

by Goswin von Brederlow-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Miklos Szeredi <miklos@...> writes:

> On Thu, 07 Aug 2008, Goswin von Brederlow wrote:
>> Now I see that I violate the const-ness in path but it causes the
>> following call sequence:
>>
>> create("/foo", mode, fi);
>> getattr("", buf);
>>
>> and that gave the wrong attributes. Took me ages to find the problem
>> as g++ also doesn't warn about the violation of const.
>
> Mmm, lots of people run into this.  How come g++ doesn't warn on const
> violation?  I thought that C++ was supposed to have _stricter_ type
> checking than C.

In my case the problem is

char *foo = index(path, '/');

and index is declared as

       char *index(const char *s, int c);

The use of index looses the const-ness of the pointer. In C there is
no other way for index to work for both const char* and char* but in
C++ there could be 2 declarations:

       const char *index(const char *s, int c);
       char *index(char *s, int c);

Unfortunately <cstring> does not contain those. I bet there are a
number of other C functions with this "bug".

MfG
        Goswin

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
fuse-devel mailing list
fuse-devel@...
https://lists.sourceforge.net/lists/listinfo/fuse-devel
< Prev | 1 - 2 | Next >
LightInTheBox - Buy quality products at wholesale price!