James Carlson wrote:
> Rich.Brown at Sun.COM writes:
>   
>> The code snippet would now look like this:
>>
>>         struct stat     statPre;
>>         struct stat     statFile;
>>         DIR             *pdir;
>>
>>         stat(szPath, &statPre);
>>         pdir = opendir(szPath);
>>
>>         if (S_ISTRIGGER(statPre.st_mode)) {
>>                 stat(szPath, &statPre);
>>         }
>>
>>         fstat(pdir->dd_fd, &statFile);
>>
>>         if (statPre.st_ino != statFile.st_ino ||
>>             statPre.st_dev != statFile.st_dev) {
>>                 return(EAGAIN);
>>         }
>>     
>
> If doing the stat() call after opendir() works correctly for trigger
> points, why would it not work for all other object types?
>
> I don't quite see what the stat-after-opendir tells you that the
> fstat() does not.
>
>   

James,

The intent of the stat-after-opendir is to refresh the statPre buffer 
with the
inode and device that were loaded as a result of the opendir() causing a
trigger mount to fire.

For all other object types, the stat-before-opendir will match the 
stat-after-opendir.
For trigger mounts, they will not.

I'd also suggest that perhaps my code snippet abstracts the problem too 
much.
If you look at the webrev, 
http://anthrax.central/net/boora/brmnas/th199096/merger/webrev/,
then you can see the context inside *nftw.c. BTW: The webrev has a 
different symbol
for the bits, it used *S_ISTRMP() instead of S_ISTRIGGER().

Thanks,
Tom

PS: If we look at a test run (with code much like the snippet):

#
# Do a normal mount
#
[th199096 at burr ~]> sudo mount integrable:/ /mnt

#
# We see that stat information matches
# fprintf(stdout, "Stat flags: (%x, %x, %x)\n", statPre.st_mode, 
statPre.st_mode & S_IFMT, statPre.st_mode & 0xF0000);
#
[th199096 at burr ~]> a.out /mnt
(st_mode, st_ino, st_dev, st_fstype)
Pre stat: (41ed, 2, 78643209, nfs)
File stat: (41ed, 2, 78643209, nfs)
Stat flags: (41ed, 4000, 0)

#
# And all we have mounted is what we explicitly asked for
#
[th199096 at burr ~]> df -h -F nfs | grep mnt
integrable:/ 14G 4.6G 8.9G 35% /mnt

#
# Now we try the program and cause a mirror mount to occur
#
[th199096 at burr ~]> a.out /mnt/tank
(st_mode, st_ino, st_dev, st_fstype)
Pre stat: (241ed, 308804, 78643209, nfs)
File stat: (41ed, 3, 78643210, nfs)
Stat flags: (241ed, 4000, 20000)

#
# Note that the st_ino and st_dev do not match. This would
# trigger a false positive. We need to refresh.
#

#
# We can see the mirror mount took place
#
[th199096 at burr ~]> df -h -F nfs | grep mnt
integrable:/ 14G 4.6G 8.9G 35% /mnt
integrable:/tank 49G 19K 49G 1% /mnt/tank

#
# And now, until the mirror mount times out, the statPre and statFile
# will match. I.e., the trigger mount is hidden
#
[th199096 at burr ~]> a.out /mnt/tank
(st_mode, st_ino, st_dev, st_fstype)
Pre stat: (41ed, 3, 78643210, nfs)
File stat: (41ed, 3, 78643210, nfs)
Stat flags: (41ed, 4000, 0)



Reply via email to