Quantcast

READDIR_PLUS: getattr still gets called for dir attributes in-spite of populating stat for each files in readdir?

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

READDIR_PLUS: getattr still gets called for dir attributes in-spite of populating stat for each files in readdir?

kingsmasher1

Hi Mikloas,

I am using the readdir_plus high level API, and upgraded our fuse library to fuse3.0 and using the RPM fuse-3.0.0_pre_61eed2-74.1.

I invoked "ls" :
{{{
    insite1@ServerIFM30:/opt/insiteone/fuse-mount/ifm/test> ls
           a.txt  b.txt  c.txt  d.txt

}}}

Now i am seeing 2 issues:-

1) getattr looks for some shared library, in addition to files on fuse-mount (this issue was there in fuse earlier releases as well):

   ifm_getattr path /ifm/test/libselinux.so.1
   ifm_getattr path /ifm/tls
   ifm_getattr path /ifm/test/x86_64
   ifm_getattr path /ifm/test/libselinux.so.1
   ifm_getattr path /ifm/test/librt.so.1

   ifm_getattr path /ifm/test/libacl.so.1
   ifm_getattr path /ifm/test/libc.so.6
   ifm_getattr path /ifm/test/libattr.so.1

2) In-spite of enabling FUSE_FILL_DIR_PLUS in filler flags, and fully populating the stat structure for each file in readdir, still getattr gets called once for each of these files:
     

Here is the function call flow observed:
         
ifm_readdir() - filePath = /ifm/test/a.txt
ifm_readdir() - filePath = /ifm/test/b.txt
ifm_readdir() - filePath = /ifm/test/c.txt
ifm_readdir() - filePath = /ifm/test/d.txt
   
ifm_getattr path /ifm/test/a.txt
ifm_getattr path /ifm/test/b.txt
ifm_getattr path /ifm/test/c.txt
ifm_getattr path /ifm/test/d.txt



Finally, here is the skeleton snippet of our readdir, please help us.

static int ifm_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
     off_t offset, struct fuse_file_info *fi, enum fuse_readdir_flags flags)
{

    enum fuse_fill_dir_flags fill_flags = static_cast<fuse_fill_dir_flags>(0);
    fill_flags = static_cast<fuse_fill_dir_flags>(fill_flags | FUSE_FILL_DIR_PLUS);

    std::vector<ifmFileNode*>* vec = service->listDirectory(path);
    if (vec == NULL) {
         ErrLog("%s() - ERROR: Readdir %s failed\n", __FUNCTION__,path);
         return -ENOENT;
    }
    else {
              for (unsigned int indx = 0; indx < vec->size(); indx++) {
              {
                   struct stat st;
                   // Populate the stat structure for all the files in vector 1 by 1
       
                   if (filler(buf, node->getVirtualName().c_str(), &st, 0, fill_flags)) {
                         delete node;
                         break;
                   }
             }
    }
    delete vec;
    return 0;
}




Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: READDIR_PLUS: getattr still gets called for dir attributes in-spite of populating stat for each files in readdir?

Miklos Szeredi
On Wed, Apr 23, 2014 at 12:09 PM, kingsmasher1
<[hidden email]> wrote:

>
> Hi Mikloas,
>
> I am using the readdir_plus high level API, and upgraded our fuse library to
> fuse3.0 and using the RPM fuse-3.0.0_pre_61eed2-74.1.
>
> I invoked "ls" :
> {{{
>     insite1@ServerIFM30:/opt/insiteone/fuse-mount/ifm/test> ls
>            a.txt  b.txt  c.txt  d.txt
>
> }}}
>
> Now i am seeing 2 issues:-
>
> *1) getattr looks for some shared library, in addition to files on
> fuse-mount (this issue was there in fuse earlier releases as well):
> *
>    ifm_getattr path /ifm/test/libselinux.so.1
>    ifm_getattr path /ifm/tls
>    ifm_getattr path /ifm/test/x86_64
>    ifm_getattr path /ifm/test/libselinux.so.1
>    ifm_getattr path /ifm/test/librt.so.1
>
>    ifm_getattr path /ifm/test/libacl.so.1
>    ifm_getattr path /ifm/test/libc.so.6
>    ifm_getattr path /ifm/test/libattr.so.1
>
> *2) In-spite of enabling FUSE_FILL_DIR_PLUS in filler flags, and fully
> populating the stat structure for each file in readdir, still getattr gets
> called once for each of these files:*
>
>
> Here is the function call flow observed:
>
> ifm_readdir() - filePath = /ifm/test/a.txt
> ifm_readdir() - filePath = /ifm/test/b.txt
> ifm_readdir() - filePath = /ifm/test/c.txt
> ifm_readdir() - filePath = /ifm/test/d.txt
>
> ifm_getattr path /ifm/test/a.txt
> ifm_getattr path /ifm/test/b.txt
> ifm_getattr path /ifm/test/c.txt
> ifm_getattr path /ifm/test/d.txt
>
>
>
> *Finally, here is the skeleton snippet of our readdir, please help us.
> *
> static int ifm_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
>      off_t offset, struct fuse_file_info *fi, enum fuse_readdir_flags flags)
> {
>
>     enum fuse_fill_dir_flags fill_flags =
> static_cast<fuse_fill_dir_flags>(0);
>     fill_flags = static_cast<fuse_fill_dir_flags>(fill_flags |
> FUSE_FILL_DIR_PLUS);
>
>     std::vector<ifmFileNode*>* vec = service->listDirectory(path);
>     if (vec == NULL) {
>          ErrLog("%s() - ERROR: Readdir %s failed\n", __FUNCTION__,path);
>          return -ENOENT;
>     }
>     else {
>               for (unsigned int indx = 0; indx < vec->size(); indx++) {
>               {
>                    struct stat st;
>                    // Populate the stat structure for all the files in
> vector 1 by 1
>
>                    if (filler(buf, node->getVirtualName().c_str(), &st, 0,
> fill_flags)) {

You need use offsets (4th argument of filler) for readdirplus to work.
 See point 2) in the header comment for the readdir method in fuse.h.

Thanks,
Miklos

------------------------------------------------------------------------------
Start Your Social Network Today - Download eXo Platform
Build your Enterprise Intranet with eXo Platform Software
Java Based Open Source Intranet - Social, Extensible, Cloud Ready
Get Started Now And Turn Your Intranet Into A Collaboration Platform
http://p.sf.net/sfu/ExoPlatform
_______________________________________________
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: READDIR_PLUS: getattr still gets called for dir attributes in-spite of populating stat for each files in readdir?

Goswin von Brederlow-2
In reply to this post by kingsmasher1
On Wed, Apr 23, 2014 at 03:09:20AM -0700, kingsmasher1 wrote:

>
> Hi Mikloas,
>
> I am using the readdir_plus high level API, and upgraded our fuse library to
> fuse3.0 and using the RPM fuse-3.0.0_pre_61eed2-74.1.
>
> I invoked "ls" :
> {{{
>     insite1@ServerIFM30:/opt/insiteone/fuse-mount/ifm/test> ls
>            a.txt  b.txt  c.txt  d.txt
>
> }}}
>
> Now i am seeing 2 issues:-
>
> *1) getattr looks for some shared library, in addition to files on
> fuse-mount (this issue was there in fuse earlier releases as well):
> *
>    ifm_getattr path /ifm/test/libselinux.so.1
>    ifm_getattr path /ifm/tls
>    ifm_getattr path /ifm/test/x86_64
>    ifm_getattr path /ifm/test/libselinux.so.1
>    ifm_getattr path /ifm/test/librt.so.1
>
>    ifm_getattr path /ifm/test/libacl.so.1
>    ifm_getattr path /ifm/test/libc.so.6
>    ifm_getattr path /ifm/test/libattr.so.1

Do you have . in your LD_LIBRARY_PATH?

MfG
        Goswin

------------------------------------------------------------------------------
"Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE
Instantly run your Selenium tests across 300+ browser/OS combos.  Get
unparalleled scalability from the best Selenium testing platform available.
Simple to use. Nothing to install. Get started now for free."
http://p.sf.net/sfu/SauceLabs
_______________________________________________
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: READDIR_PLUS: getattr still gets called for dir attributes in-spite of populating stat for each files in readdir?

kingsmasher1
In reply to this post by Miklos Szeredi

Hi Miklos,

Currently our filesystem database stores the following metadata:

inode_number, parent_inode_number, size, filename, access related (access time, mod time, uid, gid)

And hence the reason, we were passing 0 to the filler function offset.
Please guide, how do i calculate the offset? Do i put it equal to file_size in incremental of their inode number?

If yes, what happens if there is a directory inside a directory? Should it be equal to the sum of the files inside?


Thanks.
 
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: READDIR_PLUS: getattr still gets called for dir attributes in-spite of populating stat for each files in readdir?

Goswin von Brederlow-2
On Fri, May 09, 2014 at 05:26:09AM -0700, kingsmasher1 wrote:

>
> Hi Miklos,
>
> Currently our filesystem database stores the following metadata:
>
> inode_number, parent_inode_number, size, filename, access related (access
> time, mod time, uid, gid)
>
> And hence the reason, we were passing 0 to the filler function offset.
> Please guide, how do i calculate the offset? Do i put it equal to file_size
> in incremental of their inode number?
>
> If yes, what happens if there is a directory inside a directory? Should it
> be equal to the sum of the files inside?
>
>
> Thanks.

The offset has got nothing to do with file size. It is an index for
where in the directory listing you are.

The tricky bit is that entries can be added or removed while someone
else is reading a directory. So it will not work to simply return the
index in your database table. Removing an entry at the top will shift
all later entries and then readdir() would skip one. Similar inserting
at the top would result in a duplicate entry. Both are not allowed.
Luckily it is indetermined wether deleted and added entries are still
be reported. So any behaviour is right there. Note: An offset of 0
must reset everything.

I can think of 3 ways to use the offset:

1) Use the placement in the table

As mentioned above thise causes problems when you insert/remove
entries at the top. So don't do that. Mark entries as invalid to
remove them and append or use an invalid entry for insertion. Never
shift existing entries. I believe that is what ext2 did before dir
hashes.

2) Sort table by inode and use inode as offset

If you store / process entries in order of the inode then you can
simply use that as offset. From your DB you would then "select * from
inode where inode_numer >= offset sorted by inode_numer".

3) Hash the filename and use that as offset

If you place entries into a tree, sorted by their hash then you can
use the hash as offset. Not sure what to do on hash collision though.

MfG
        Goswin

------------------------------------------------------------------------------
"Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE
Instantly run your Selenium tests across 300+ browser/OS combos.
Get unparalleled scalability from the best Selenium testing platform available
Simple to use. Nothing to install. Get started now for free."
http://p.sf.net/sfu/SauceLabs
_______________________________________________
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: READDIR_PLUS: getattr still gets called for dir attributes in-spite of populating stat for each files in readdir?

kingsmasher1

Hi Miklos/Goswin,

I got this example code, without much explanation, though it works fine.
Can you please let me know if this is the proper way to populate the offset?

Also, what is the reason for: "lenentry = ((24+strlen(namebuf)+7)&~7);"

int my_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi)
{
   (a bunch of prep work has been omitted)
   struct stat st;
   int off, nextoff=0, lenentry, i;
   char namebuf[(long enough for any one name)];

   for (i=0; i<NumDirectoryEntries; i++)
   {
      (fill st with the stat information, including inode, etc.)
      (fill namebuf with the name of the directory entry)
      lenentry = ((24+strlen(namebuf)+7)&~7);
      off = nextoff; /* offset of this entry */
      nextoff += lenentry;
      /* Skip this entry if we weren't asked for it */
      if (off<offset)
         continue;
      /* Add this to our response until we are asked to stop */
      if (filler(buf, namebuf, &st, nextoff))
         break;
   }
   /* All done because we were asked to stop or because we finished */
   return 0;
}
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: READDIR_PLUS: getattr still gets called for dir attributes in-spite of populating stat for each files in readdir?

Miklos Szeredi
On Mon, May 12, 2014 at 11:50 AM, kingsmasher1
<[hidden email]> wrote:

>
> Hi Miklos/Goswin,
>
> I got this example code, without much explanation, though it works fine.
> Can you please let me know if this is the proper way to populate the offset?
>
> Also, what is the reason for: "lenentry = ((24+strlen(namebuf)+7)&~7);"
>
> int my_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t
> offset, struct fuse_file_info *fi)
> {
>    (a bunch of prep work has been omitted)
>    struct stat st;
>    int off, nextoff=0, lenentry, i;
>    char namebuf[(long enough for any one name)];
>
>    for (i=0; i<NumDirectoryEntries; i++)
>    {
>       (fill st with the stat information, including inode, etc.)
>       (fill namebuf with the name of the directory entry)
>       lenentry = ((24+strlen(namebuf)+7)&~7);
>       off = nextoff; /* offset of this entry */
>       nextoff += lenentry;
>       /* Skip this entry if we weren't asked for it */
>       if (off<offset)
>          continue;
>       /* Add this to our response until we are asked to stop */
>       if (filler(buf, namebuf, &st, nextoff))
>          break;
>    }
>    /* All done because we were asked to stop or because we finished */
>    return 0;
> }
>

It will work (but so will nextoff=off+1, calculating the actual lengh
of the readdir entry is not necessary).

The issue, as Goswin said, is if entries are added or removed while we
have a reader of the directory.  The most trivial way to deal with it
is to save a snapshot of the directory when supplied offset is zero.
This is essentially what the old getdir() interface did, but with
readdirplus now you have to do it by hand.

E.g.

    snap = (void *) fi->fh;
    if (offset == 0) {
        free_snapshot(snap);
        /* save a snapshot of the directory contents */
        snap = snapshot_dir(path);
        fi->fh = (unsigned long) (void *) snap;
    }
    for (i = offset; i < snap->numdirent; i++) {
        if (filler(buf, snap->entries[i].name, &snap->entries[i].stat, i + 1))
            break;
    }

Thanks,
Miklos

------------------------------------------------------------------------------
"Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE
Instantly run your Selenium tests across 300+ browser/OS combos.
Get unparalleled scalability from the best Selenium testing platform available
Simple to use. Nothing to install. Get started now for free."
http://p.sf.net/sfu/SauceLabs
_______________________________________________
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: READDIR_PLUS: getattr still gets called for dir attributes in-spite of populating stat for each files in readdir?

kingsmasher1
In reply to this post by Miklos Szeredi
> You need use offsets (4th argument of filler) for readdirplus to work.
> See point 2) in the header comment for the readdir method in fuse.h.
>
> Thanks,
> Miklos


Hi Miklos,

Unfortunately, even after using the offset and populating the flags like shown below, the "getattr" are still getting called for each files after the call to readdir in-spite of fully populating the stat structure and passing the offset in filler.

Sorry, but am i missing something? Please help.

Below is our same function but after using offset (i am working on the dir snapshot optimization parallely, but below is the present code which still calls getattrs):

static int ifm_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
     off_t offset, struct fuse_file_info *fi, enum fuse_readdir_flags flags)
{

    enum fuse_fill_dir_flags fill_flags = static_cast<fuse_fill_dir_flags>(0);
    fill_flags = static_cast<fuse_fill_dir_flags>(fill_flags | FUSE_FILL_DIR_PLUS);

    std::vector<ifmFileNode*>* vec = service->listDirectory(path);
    if (vec == NULL) {
         ErrLog("%s() - ERROR: Readdir %s failed\n", __FUNCTION__,path);
         return -ENOENT;
    }
    else {
              int off, nextoff=0, lenentry=0;
              for (unsigned int indx = 0; indx < vec->size(); indx++) {
              {
                   struct stat st;
                   // Populate the stat structure for all the files in vector 1 by 1
                 
                  // calculate offset
                  lenentry = ((24+strlen(node->getVirtualName().c_str())+7)&~7);
                  off=nextoff;  nextoff += lenentry;

                   if(off < offset)
                         continue;
       
                   if (filler(buf, node->getVirtualName().c_str(), &st, nextoff, fill_flags)) {
                         delete node;
                         break;
                   }
             }
    }
    delete vec;
    return 0;
}
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: READDIR_PLUS: getattr still gets called for dir attributes in-spite of populating stat for each files in readdir?

kingsmasher1
In reply to this post by Miklos Szeredi
>The issue, as Goswin said, is if entries are added or removed while we
>have a reader of the directory.  The most trivial way to deal with it
>is to save a snapshot of the directory when supplied offset is zero.
>This is essentially what the old getdir() interface did, but with
>readdirplus now you have to do it by hand.


Good point Miklos, thanks, but i feel as per our implementation, of readdir is, we are already dealing with it, as we are reading the entire dir contents in an array (a vector), and then looping through each of the array entries, filling up the filler function. So, even if there are entries added afterwards, the present snapshot in the vector is unaltered, and integrity is maintained.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: READDIR_PLUS: getattr still gets called for dir attributes in-spite of populating stat for each files in readdir?

Miklos Szeredi
In reply to this post by kingsmasher1
On Mon, May 12, 2014 at 1:46 PM, kingsmasher1
<[hidden email]> wrote:

>> You need use offsets (4th argument of filler) for readdirplus to work.
>> See point 2) in the header comment for the readdir method in fuse.h.
>>
>> Thanks,
>> Miklos
>
>
> Hi Miklos,
>
> Unfortunately, even after using the offset and populating the flags like
> shown below, the "getattr" are still getting called for each files after the
> call to readdir in-spite of fully populating the stat structure and passing
> the offset in filler.
>
> Sorry, but am i missing something? Please help.
>
> Below is our same function but after using offset (i am working on the dir
> snapshot optimization parallely, but below is the present code which still
> calls getattrs):
>
> static int ifm_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
>      off_t offset, struct fuse_file_info *fi, enum fuse_readdir_flags flags)
> {
>
>     enum fuse_fill_dir_flags fill_flags =
> static_cast<fuse_fill_dir_flags>(0);
>     fill_flags = static_cast<fuse_fill_dir_flags>(fill_flags |
> FUSE_FILL_DIR_PLUS);
>
>     std::vector<ifmFileNode*>* vec = service->listDirectory(path);
>     if (vec == NULL) {
>          ErrLog("%s() - ERROR: Readdir %s failed\n", __FUNCTION__,path);
>          return -ENOENT;
>     }
>     else {
>               int off, nextoff=0, lenentry=0;
>               for (unsigned int indx = 0; indx < vec->size(); indx++) {
>               {
>                    struct stat st;
>                    // Populate the stat structure for all the files in
> vector 1 by 1
>
>                   // calculate offset
>                   lenentry =
> ((24+strlen(node->getVirtualName().c_str())+7)&~7);
>                   off=nextoff;  nextoff += lenentry;
>
>                    if(off < offset)
>                          continue;
>
>                    if (filler(buf, node->getVirtualName().c_str(), &st,
> nextoff, fill_flags)) {
>                          delete node;
>                          break;
>                    }
>              }
>     }
>     delete vec;
>     return 0;
> }
>

Code looks fine.   One possibility is that you have "attr_timeout=0" option.

Thanks,
Miklos

------------------------------------------------------------------------------
"Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE
Instantly run your Selenium tests across 300+ browser/OS combos.
Get unparalleled scalability from the best Selenium testing platform available
Simple to use. Nothing to install. Get started now for free."
http://p.sf.net/sfu/SauceLabs
_______________________________________________
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: READDIR_PLUS: getattr still gets called for dir attributes in-spite of populating stat for each files in readdir?

Goswin von Brederlow-2
In reply to this post by Miklos Szeredi
On Mon, May 12, 2014 at 12:16:11PM +0200, Miklos Szeredi wrote:

> On Mon, May 12, 2014 at 11:50 AM, kingsmasher1
> <[hidden email]> wrote:
> >
> > Hi Miklos/Goswin,
> >
> > I got this example code, without much explanation, though it works fine.
> > Can you please let me know if this is the proper way to populate the offset?
> >
> > Also, what is the reason for: "lenentry = ((24+strlen(namebuf)+7)&~7);"
> >
> > int my_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t
> > offset, struct fuse_file_info *fi)
> > {
> >    (a bunch of prep work has been omitted)
> >    struct stat st;
> >    int off, nextoff=0, lenentry, i;
> >    char namebuf[(long enough for any one name)];
> >
> >    for (i=0; i<NumDirectoryEntries; i++)
> >    {
> >       (fill st with the stat information, including inode, etc.)
> >       (fill namebuf with the name of the directory entry)
> >       lenentry = ((24+strlen(namebuf)+7)&~7);
> >       off = nextoff; /* offset of this entry */
> >       nextoff += lenentry;
> >       /* Skip this entry if we weren't asked for it */
> >       if (off<offset)
> >          continue;
> >       /* Add this to our response until we are asked to stop */
> >       if (filler(buf, namebuf, &st, nextoff))
> >          break;
> >    }
> >    /* All done because we were asked to stop or because we finished */
> >    return 0;
> > }
> >
>
> It will work (but so will nextoff=off+1, calculating the actual lengh
> of the readdir entry is not necessary).

Actually nextoff=off+1 will work better because using the length of
the name makes it vulnerable to renames. If there is a verry long name
at the start and that is changed to something short between readdir()
calls then entries are skipped.

> The issue, as Goswin said, is if entries are added or removed while we
> have a reader of the directory.  The most trivial way to deal with it
> is to save a snapshot of the directory when supplied offset is zero.
> This is essentially what the old getdir() interface did, but with
> readdirplus now you have to do it by hand.
>
> E.g.
>
>     snap = (void *) fi->fh;
>     if (offset == 0) {
     if (offset == 0 || fi->fh == NULL) {

Just in case someone opens the dir and uses seekdir() with an offset !=
0 before the first readdir().

>         free_snapshot(snap);
>         /* save a snapshot of the directory contents */
>         snap = snapshot_dir(path);
>         fi->fh = (unsigned long) (void *) snap;
>     }
>     for (i = offset; i < snap->numdirent; i++) {
>         if (filler(buf, snap->entries[i].name, &snap->entries[i].stat, i + 1))
>             break;
>     }
>
> Thanks,
> Miklos

And don't forget to implement opendir() and releasedir(). opendir()
must set fi->fh to NULL and releasedir must call free_snapshot().

Note: I assume free_snapshot(NULL) is valid. Otherwise test for NULL
first.

MfG
        Goswin

------------------------------------------------------------------------------
"Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE
Instantly run your Selenium tests across 300+ browser/OS combos.
Get unparalleled scalability from the best Selenium testing platform available
Simple to use. Nothing to install. Get started now for free."
http://p.sf.net/sfu/SauceLabs
_______________________________________________
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: READDIR_PLUS: getattr still gets called for dir attributes in-spite of populating stat for each files in readdir?

kingsmasher1
In reply to this post by Miklos Szeredi
Hi Miklos,

We did a thorough benchmarking, and found that using the PLUS version of
the API consumes more time for file listing than normal one on a ration of
5:1.

We commented out 2 lines:
1)  fill_flags = static_cast<fuse_fill_dir_flags>(fill_flags |
FUSE_FILL_DIR_PLUS);
2) offset setting and reverted it to 0

And again the performance became fine.

File listing time for 10k files (with old version of readdir)

real    1m20.640s
user    0m0.308s
sys     0m0.592s

File listing time for 10k files (with readdir_plus version)
real    4m6.943s
user    0m0.244s
sys     0m0.392s

Also we don't have attr_timeout=0 but on your recommendation, we used
attr_timeout=3600

Please suggest.

Regards
kingsmasher1



On Thu, May 15, 2014 at 4:23 PM, Miklos Szeredi <[hidden email]> wrote:

> On Mon, May 12, 2014 at 1:46 PM, kingsmasher1
> <[hidden email]> wrote:
> >> You need use offsets (4th argument of filler) for readdirplus to work.
> >> See point 2) in the header comment for the readdir method in fuse.h.
> >>
> >> Thanks,
> >> Miklos
> >
> >
> > Hi Miklos,
> >
> > Unfortunately, even after using the offset and populating the flags like
> > shown below, the "getattr" are still getting called for each files after
> the
> > call to readdir in-spite of fully populating the stat structure and
> passing
> > the offset in filler.
> >
> > Sorry, but am i missing something? Please help.
> >
> > Below is our same function but after using offset (i am working on the
> dir
> > snapshot optimization parallely, but below is the present code which
> still
> > calls getattrs):
> >
> > static int ifm_readdir(const char *path, void *buf, fuse_fill_dir_t
> filler,
> >      off_t offset, struct fuse_file_info *fi, enum fuse_readdir_flags
> flags)
> > {
> >
> >     enum fuse_fill_dir_flags fill_flags =
> > static_cast<fuse_fill_dir_flags>(0);
> >     fill_flags = static_cast<fuse_fill_dir_flags>(fill_flags |
> > FUSE_FILL_DIR_PLUS);
> >
> >     std::vector<ifmFileNode*>* vec = service->listDirectory(path);
> >     if (vec == NULL) {
> >          ErrLog("%s() - ERROR: Readdir %s failed\n", __FUNCTION__,path);
> >          return -ENOENT;
> >     }
> >     else {
> >               int off, nextoff=0, lenentry=0;
> >               for (unsigned int indx = 0; indx < vec->size(); indx++) {
> >               {
> >                    struct stat st;
> >                    // Populate the stat structure for all the files in
> > vector 1 by 1
> >
> >                   // calculate offset
> >                   lenentry =
> > ((24+strlen(node->getVirtualName().c_str())+7)&~7);
> >                   off=nextoff;  nextoff += lenentry;
> >
> >                    if(off < offset)
> >                          continue;
> >
> >                    if (filler(buf, node->getVirtualName().c_str(), &st,
> > nextoff, fill_flags)) {
> >                          delete node;
> >                          break;
> >                    }
> >              }
> >     }
> >     delete vec;
> >     return 0;
> > }
> >
>
> Code looks fine.   One possibility is that you have "attr_timeout=0"
> option.
>
> Thanks,
> Miklos
>
------------------------------------------------------------------------------
"Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE
Instantly run your Selenium tests across 300+ browser/OS combos.
Get unparalleled scalability from the best Selenium testing platform available
Simple to use. Nothing to install. Get started now for free."
http://p.sf.net/sfu/SauceLabs
_______________________________________________
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: READDIR_PLUS: getattr still gets called for dir attributes in-spite of populating stat for each files in readdir?

Miklos Szeredi
On Mon, May 19, 2014 at 4:57 PM, Raj Kumar Sanpui
<[hidden email]> wrote:
> Hi Miklos,
>
> We did a thorough benchmarking, and found that using the PLUS version of the
> API consumes more time for file listing than normal one on a ration of 5:1.

Did you try "-o readdirplus=auto"?

Thanks,
Miklos

------------------------------------------------------------------------------
"Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE
Instantly run your Selenium tests across 300+ browser/OS combos.
Get unparalleled scalability from the best Selenium testing platform available
Simple to use. Nothing to install. Get started now for free."
http://p.sf.net/sfu/SauceLabs
_______________________________________________
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: READDIR_PLUS: getattr still gets called for dir attributes in-spite of populating stat for each files in readdir?

kingsmasher1
Sorry, i see only a mild 1 sec improvement:

With old readdir (10 k files):

real    1m37.739s
user    0m0.180s
sys     0m0.672s

readdir_plus with -o readirplus=auto

real    3m28.274s
user    0m0.076s
sys     0m0.420s

readdir_plus with -o attr_timeout=3600 and -o readirplus=auto
real    3m53.703s
user    0m0.184s
sys     0m0.460s

And occassionally with same configuration (-o attr_timeout=3600 and -o readirplus=auto) :
real    4m2.606s
user    0m0.196s
sys     0m0.372s

Am i missing something? Please help.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: READDIR_PLUS: getattr still gets called for dir attributes in-spite of populating stat for each files in readdir?

Miklos Szeredi
On Tue, May 20, 2014 at 12:03 PM, kingsmasher1
<[hidden email]> wrote:

> Sorry, i see only a mild 1 sec improvement:
>
> With old readdir (10 k files):
>
> real    1m37.739s
> user    0m0.180s
> sys     0m0.672s
>
> readdir_plus with -o readirplus=auto
>
> real    3m28.274s
> user    0m0.076s
> sys     0m0.420s
>
> readdir_plus with -o attr_timeout=3600 and -o readirplus=auto
> real    3m53.703s
> user    0m0.184s
> sys     0m0.460s
>
> And occassionally with same configuration (-o attr_timeout=3600 and -o
> readirplus=auto) :
> real    4m2.606s
> user    0m0.196s
> sys     0m0.372s
>
> Am i missing something? Please help.

No more ideas.

The above user/sys times don't actually account for all the time spent
doing the readdir.  Try profiling your filesystem to see where the
time is actually spent:

perf record -a ls -l large-fuse-dir > /dev/null
prof report

Thanks,
Miklos

------------------------------------------------------------------------------
"Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE
Instantly run your Selenium tests across 300+ browser/OS combos.
Get unparalleled scalability from the best Selenium testing platform available
Simple to use. Nothing to install. Get started now for free."
http://p.sf.net/sfu/SauceLabs
_______________________________________________
fuse-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/fuse-devel
Loading...