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)