[prev in list] [next in list] [prev in thread] [next in thread] 

List:       fuse-devel
Subject:    Re: [fuse-devel] error while trying to create mkdir through FUSE
From:       Sven Utcke <sven.utcke () gmx ! de>
Date:       2011-04-14 10:38:47
Message-ID: 20110414103847.GA7735 () acer ! fritz ! box
[Download RAW message or body]

Hello Ravi,

> The problem I am facing is when I do mkdir filename, it goes and
> checks in getattr and returns an error saying "FILE DOES NOT EXIST"
> and if I give mkdir ravi(which is already a directory) it gives me
> the error "FILE ALREADY EXISTS".

Even worse, on running your code I now see:

acer>/tmp% ls -li /tmp/mnt/
total 0
5 drwxr-xr-x 2 utcke utcke 0 2011-04-14 12:04 ravi
5 drwxr-xr-x 2 utcke utcke 0 2011-04-14 12:04 ravi
5 drwxr-xr-x 2 utcke utcke 0 2011-04-14 12:04 ravi

That's not good.  I wouln't expect to see "total 0", and I certainly
wouldn't expect to see three files with the same name  and  inode...

(ok, the inode is actually created by FUSE based on the name, but
still, you do get my point).

Then I do see:

acer>/tmp% mkdir mnt/xxx
mkdir: cannot create directory `mnt/xxx': File exists

also this clearly isn't the case, and 

acer>/tmp% mkdir mnt/ravi/xxx
mkdir: cannot create directory `mnt/ravi/xxx': File exists

so I can, in fact, not duplicate  your  error.

So let's see what happens here...

> int main(int argc, char *argv[])
> {
>   int j;
> 
>   for(j=0; j < 3; j++)
>   {
>    de[j].fname = "ravi";
>    de[j].dbit = 1;
>   }
> 
>    return fuse_main(argc,argv, &mySFS_oper, NULL);
> }

Hmm.  But "de" is:

> typedef struct direntry{
> char *fname;
> int dbit;
> } dentr;
> 
> dentr de[50];

so I wouldn't really expect to see 

>    de[j].fname = "ravi";

here...

Ok, probably not a good idea, I'll simply change this to:

int main(int argc, char *argv[])
{
  char *dirs[] = {"dir1", "dir2", "dir3"};
  int j;

  for(j=0; j < 3; j++)
  {
   de[j].fname = dirs[j];
   de[j].dbit = 1;
  }

   return fuse_main(argc,argv, &mySFS_oper, NULL);
}

Ok, this looks (slightly) better:

acer>/tmp% ls -li mnt
total 0
5 drwxr-xr-x 2 utcke utcke 0 2011-04-14 12:17 dir1
6 drwxr-xr-x 2 utcke utcke 0 2011-04-14 12:17 dir2
7 drwxr-xr-x 2 utcke utcke 0 2011-04-14 12:17 dir3

but:

acer>/tmp% mkdir mnt/xxx
mkdir: cannot create directory `mnt/xxx': File exists

results in

unique: 20, opcode: LOOKUP (1), nodeid: 1, insize: 44
LOOKUP /xxx
   NODEID: 8
   unique: 20, error: 0 (Success), outsize: 136

So what happens there?

> static int mySFS_getattr(const char *path, struct stat *stbuf)
> {
>   stbuf->st_uid = getuid();
>   stbuf->st_gid = getgid();
>   stbuf->st_atime = stbuf->st_mtime=time(NULL);
> 
> 
>    switch(mySFS_file_type(path)){
>    case mySFS_DIR:
> 
>         printf("SDIR.....................");
>       stbuf->st_mode = S_IFDIR | 0755;
>         stbuf->st_nlink = 2;
>         break;
>    case mySFS_FILE:
>         printf("SFILE.....................");
>         stbuf->st_mode = S_IFREG| 0755;
>         stbuf->st_nlink = 2;
>         break;
>   default:
>         printf("DEFAULTTTTT....................");
>         return -ENOENT;
>    }
>    return 0;
> }

Ok, so this essentially calls mySFS_file_type(path), which we expect
to return mySFS_DIR for existing dirs, mySFS_FILE for existing files,
and something else otherwise.  But does it (I've re-indented the code
somewhat to make it more readable)?

>  static int mySFS_file_type(const char *path)
> {
>   int k,set=0;
>   for(k=0;k<3;k++)

Hmm, a hardcoded "3" --- I'll assume this was done for testing
purposes only..

>   {
>     char tmp[] = "/";
>     char name[]="name";
>     strcat(tmp, de[k].fname);

Let me quote from the man-page:

  [...] and the dest string must have enough space for the result.

You are in for trouble here!  But if you are lucky, you just might end
up with

tmp = "/dir1" (and so on)

>     strcpy(name, tmp);

  [...] and the destination string dest must be large enough to
  receive the copy. 

Did I mention you are in trouble?  Well, you just might be lucky
enough to end up with:

name = "/dir1"

>     if(strcmp(path,name)==0)
>     {
>       set=k;
>       break;
>     }
>   }

Ok, we never go in there, so we end up with set=0 from above...

>   if(de[set].dbit == 1)

This is, of course, the case (you did set it in main())

>   {
>     return mySFS_DIR;
>   }

So this function will always return mySFS_DIR for any name not already
known.

If this is a commercial project, you might want to consider hiring
someone who knows C (hint: I'm for hire :-)

I hope this did help a bit

Sven
-- 
    _  ___  ___  ___                              The dCache File System
 __| |/ __|| __|/ __|              An archive file-system for PB of data
/ _` | (__ | _| \__ \                    http://www.desy.de/~utcke/Data/
\__,_|\___||_|  |___/                            http://www.dr-utcke.de/

------------------------------------------------------------------------------
Benefiting from Server Virtualization: Beyond Initial Workload 
Consolidation -- Increasing the use of server virtualization is a top
priority.Virtualization can reduce costs, simplify management, and improve 
application availability and disaster protection. Learn more about boosting 
the value of server virtualization. http://p.sf.net/sfu/vmware-sfdev2dev
_______________________________________________
fuse-devel mailing list
fuse-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/fuse-devel

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic