On 4/25/15 4:28 AM, John Baldwin wrote: > On Saturday, April 25, 2015 02:36:24 AM Julian Elischer wrote: >> On 4/25/15 1:30 AM, Julian Elischer wrote: >>> On 4/24/15 10:59 PM, John Baldwin wrote: >>>> Index: head/lib/libc/gen/telldir.c >>>> =================================================================== >>>> --- head/lib/libc/gen/telldir.c (revision 281929) >>>> +++ head/lib/libc/gen/telldir.c (working copy) >>>> _at__at_ -101,8 +101,10 _at__at_ >>>> return; >>>> if (lp->loc_loc == dirp->dd_loc && lp->loc_seek == >>>> dirp->dd_seek) >>>> return; >>>> - (void) lseek(dirp->dd_fd, (off_t)lp->loc_seek, SEEK_SET); >>>> - dirp->dd_seek = lp->loc_seek; >>>> + if (lp->loc_seek != dirp->dd_seek) { >>>> + (void) lseek(dirp->dd_fd, (off_t)lp->loc_seek, >>>> SEEK_SET); >>>> + dirp->dd_seek = lp->loc_seek; >>>> + } >>> yes I did that yesterday but it still fails when you transition >>> blocks.. (badly). >>> >>> I also tried bigger blocks.. also fails (eventually) >>> >>> I did find a way to make it work... you had to seek back >>> to the first block you deleted on each set.. >>> then work forward from there again.. unfortunately since >>> I'm trying to make a microsoft program not fail (via samba) >>> I have no control over how it does things and seekdir doesn't >>> know what was deleted anyway... (so the fix is fine for the >>> test program but not for real life) >>> >>> I think I can make the BSD one act like the linux one by changing >>> the lseek being done to use the offset (loc) plus the buffer seek >>> address of the target, instead of just going for the buffer base and >>> stepping forward through the entries.. >>> >>> maybe tomorrow. >>> >> The following conditional code makes ours behave the same as the linux >> one. >> it breaks several 'rules' but works where ours is clean but fails.. >> as Rick said.. "maybe that's what we should do too." >> >> >> this is at the end of seekdir() >> >> >> The new code does what linux does.. and shouldn't work.. but does >> // at least in the limited conditions I need it to. >> // We'll probably need to do this at work...: >> >> >> The original code is what we have now, but gets mightily confused >> sometimes. >> // This is clean(er) but fails in specific situations(when >> doing commands >> // from Microft windows, via samba). >> >> >> root_at_vps1:/tmp # diff -u dir.c.orig dir.c >> --- dir.c.orig 2015-04-24 11:29:36.855317000 -0700 >> +++ dir.c 2015-04-24 11:15:49.058500000 -0700 >> _at__at_ -1105,6 +1105,13 _at__at_ >> dirp->dd_loc = lp->loc_loc; >> return; >> } >> +#ifdef GLIBC_SEEK >> + (void) lseek(dirp->dd_fd, (off_t)lp->loc_seek + lp->loc_loc, >> SEEK_SET); >> + dirp->dd_seek = lp->loc_seek + lp->loc_loc; >> + dirp->dd_loc = 0; >> + lp->loc_seek = dirp->dd_seek; >> + lp->loc_loc = 0; >> +#else >> (void) lseek(dirp->dd_fd, (off_t)lp->loc_seek, SEEK_SET); >> dirp->dd_seek = lp->loc_seek; >> dirp->dd_loc = 0; >> _at__at_ -1114,6 +1121,7 _at__at_ >> if (dp == NULL) >> break; >> } >> +#endif >> } > Yes, this isn't at all safe. There's no guarantee whatsoever that > the offset on the directory fd that isn't something returned by > getdirentries has any meaning. In particular, the size of the > directory entry in a random filesystem might be a different size > than the structure returned by getdirentries (since it converts > things into a FS-independent format). > > This might work for UFS by accident, but this is probably why ZFS > doesn't work. > > However, this might be properly fixed by the thing that ino64 is > doing where each directory entry returned by getdirentries gives > you a seek offset that you _can_ directly seek to (as opposed to > seeking to the start of the block and then walking forward N > entries until you get an inter-block entry that is the same). I just made the stunning discovery that our seekdir/readdir/telldir code in libc works with FreeBSD 8.0. so maybe the problem is that the kernel changed it's behaviour, and no-one thought to fix libc.. (at least it works on one of our 8.0 base appliances.. I'll do more testing tomorrow.. it's past midnight.) >Received on Mon Apr 27 2015 - 14:44:49 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:57 UTC