Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 May 2015 11:43:56 -0400
From:      Benjamin Kaduk <bjkfbsd@gmail.com>
To:        Julian Elischer <julian@freebsd.org>
Cc:        "src-committers@freebsd.org" <src-committers@freebsd.org>,  "svn-src-all@freebsd.org" <svn-src-all@freebsd.org>,  "svn-src-head@freebsd.org" <svn-src-head@freebsd.org>
Subject:   Re: svn commit: r282485 - head/lib/libc/gen
Message-ID:  <CAJ5_RoBPe0ZnLYbNSyOTpXgChhqU3UuORv9uZj50iUC7nV%2BTZw@mail.gmail.com>
In-Reply-To: <201505051452.t45EqXXv027613@svn.freebsd.org>
References:  <201505051452.t45EqXXv027613@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, May 5, 2015 at 10:52 AM, Julian Elischer <julian@freebsd.org> wrote:

> Author: julian
> Date: Tue May  5 14:52:33 2015
> New Revision: 282485
> URL: https://svnweb.freebsd.org/changeset/base/282485
>
> Log:
>   Tweak seekdir, telldir and readdir so that when htere are deletes going
> on,
>   as seek to teh last location saved will still work. This is needed for
> Samba
>   to be able to correctly handle delete requests from windows. This does
> not
>   completely fix seekdir when deletes are present but fixes the worst of
> the
>   problems. The real solution must involve some changes to the API for eh
> VFS
>   and getdirentries(2).
>
>
Would it be so hard to run a spell-checker over commit messages?  "teh" is
not a word, nor is "htere", and "eh" only is if you're in Canada or
Minnesota (not that it's the right word there anyway).


>   Obtained from:        Panzura inc
>   MFC after:    1 week
>
> Modified:
>   head/lib/libc/gen/directory.3
>   head/lib/libc/gen/readdir.c
>   head/lib/libc/gen/rewinddir.c
>   head/lib/libc/gen/telldir.c
>   head/lib/libc/gen/telldir.h
>
> Modified: head/lib/libc/gen/directory.3
>
> ==============================================================================
> --- head/lib/libc/gen/directory.3       Tue May  5 14:19:22 2015
> (r282484)
> +++ head/lib/libc/gen/directory.3       Tue May  5 14:52:33 2015
> (r282485)
> @@ -267,4 +267,27 @@ The invalidation of
>  .Fn telldir
>  tokens when calling
>  .Fn seekdir
> -is non-standard.
> +is non-standard. This is a compile time option.
>

Man page style puts the start of new sentences on a new line.


> +.Pp
> +The behaviour of
> +.Fn telldir
> +and
> +.Fn seekdir
> +is likely to be wrong if there are parallel unlinks happening
> +and the directory is larger than one page.
> +There is code to ensure that a
> +.Fn seekdir
> +to the location given by a
> +.Fn telldir
> +immediately before the last
> +.Fn readdir
> +will always set the correct location to return the same value as that last
> +.Fn readdir
> +performed.
> +This is enough for some applications which want to "push back the last
> entry read" E.g. Samba.
>

"e.g." should be offset by commas on both sides, and the capital 'E' is
only appropriate at the start of a sentence.


> +Seeks back to any other location,
> +other than the beginning of the directory,
> +may result in unexpected behaviour if deletes are present.
>

"behaviour" is the British English; we use American unless an entire file
is already in British.


> +It is hoped that this situation will be resolved with changes to
> +.Fn getdirentries
> +and the VFS.
>
>
This sort of thing is more appropriate for BUGS or CAVEATS, in my opinion.


> Modified: head/lib/libc/gen/readdir.c
>
> ==============================================================================
> --- head/lib/libc/gen/readdir.c Tue May  5 14:19:22 2015        (r282484)
> +++ head/lib/libc/gen/readdir.c Tue May  5 14:52:33 2015        (r282485)
> @@ -54,19 +54,25 @@ _readdir_unlocked(dirp, skip)
>         int skip;
>  {
>         struct dirent *dp;
> +       long initial_seek;
> +       long initial_loc = 0;
>
>         for (;;) {
>                 if (dirp->dd_loc >= dirp->dd_size) {
>                         if (dirp->dd_flags & __DTF_READALL)
>                                 return (NULL);
> +                       initial_loc = dirp->dd_loc;
> +                       dirp->dd_flags &= ~__DTF_SKIPREAD;
>                         dirp->dd_loc = 0;
>                 }
>                 if (dirp->dd_loc == 0 &&
>                     !(dirp->dd_flags & (__DTF_READALL | __DTF_SKIPREAD))) {
> +                       initial_seek = dirp->dd_seek;
>                         dirp->dd_size = _getdirentries(dirp->dd_fd,
>                             dirp->dd_buf, dirp->dd_len, &dirp->dd_seek);
>                         if (dirp->dd_size <= 0)
>                                 return (NULL);
> +                       _fixtelldir(dirp, initial_seek, initial_loc);
>                 }
>                 dirp->dd_flags &= ~__DTF_SKIPREAD;
>                 dp = (struct dirent *)(dirp->dd_buf + dirp->dd_loc);
>
> Modified: head/lib/libc/gen/rewinddir.c
>
> ==============================================================================
> --- head/lib/libc/gen/rewinddir.c       Tue May  5 14:19:22 2015
> (r282484)
> +++ head/lib/libc/gen/rewinddir.c       Tue May  5 14:52:33 2015
> (r282485)
> @@ -51,6 +51,7 @@ rewinddir(dirp)
>
>         if (__isthreaded)
>                 _pthread_mutex_lock(&dirp->dd_lock);
> +       dirp->dd_flags &= ~__DTF_SKIPREAD; /* current contents are invalid
> */
>         if (dirp->dd_flags & __DTF_READALL)
>                 _filldir(dirp, false);
>         else {
>
> Modified: head/lib/libc/gen/telldir.c
>
> ==============================================================================
> --- head/lib/libc/gen/telldir.c Tue May  5 14:19:22 2015        (r282484)
> +++ head/lib/libc/gen/telldir.c Tue May  5 14:52:33 2015        (r282485)
> @@ -101,9 +101,21 @@ _seekdir(dirp, loc)
>                 return;
>         if (lp->loc_loc == dirp->dd_loc && lp->loc_seek == dirp->dd_seek)
>                 return;
> +       /* If it's within the same chunk of data, don't bother reloading */
>

No stop at the end of the sentence in the comment?


> +       if (lp->loc_seek == dirp->dd_seek) {
> +               /*
> +                * If we go back to 0 don't make the next readdir
> +                * trigger a call to getdirentries()
>

nor here


> +                */
> +               if (lp->loc_loc == 0)
> +                       dirp->dd_flags |= __DTF_SKIPREAD;
> +               dirp->dd_loc = lp->loc_loc;
> +               return;
> +       }
>         (void) lseek(dirp->dd_fd, (off_t)lp->loc_seek, SEEK_SET);
>         dirp->dd_seek = lp->loc_seek;
>         dirp->dd_loc = 0;
> +       dirp->dd_flags &= ~__DTF_SKIPREAD; /* current contents are invalid
> */
>         while (dirp->dd_loc < lp->loc_loc) {
>                 dp = _readdir_unlocked(dirp, 0);
>                 if (dp == NULL)
> @@ -112,6 +124,27 @@ _seekdir(dirp, loc)
>  }
>
>  /*
> + * when we do a read and cross a boundary, any telldir we
> + * just did will have wrong information in it.
>

No capital letter at start of sentence.  Strange line wrapping (in lieu of
proper paragraph break with empty line?).

-Ben


> + * We need to move it from "beyond the end of the previous chunk"
> + * to "the beginning of the new chunk"
> + */
> +void
> +_fixtelldir(DIR *dirp, long oldseek, long oldloc)
> +{
> +       struct ddloc *lp;
> +
> +       lp = LIST_FIRST(&dirp->dd_td->td_locq);
> +       if (lp != NULL) {
> +               if (lp->loc_loc == oldloc &&
> +                   lp->loc_seek == oldseek) {
> +                       lp->loc_seek = dirp->dd_seek;
> +                       lp->loc_loc = dirp->dd_loc;
> +               }
> +       }
> +}
> +
> +/*
>   * Reclaim memory for telldir cookies which weren't used.
>   */
>  void
>
> Modified: head/lib/libc/gen/telldir.h
>
> ==============================================================================
> --- head/lib/libc/gen/telldir.h Tue May  5 14:19:22 2015        (r282484)
> +++ head/lib/libc/gen/telldir.h Tue May  5 14:52:33 2015        (r282485)
> @@ -64,5 +64,6 @@ bool          _filldir(DIR *, bool);
>  struct dirent  *_readdir_unlocked(DIR *, int);
>  void           _reclaim_telldir(DIR *);
>  void           _seekdir(DIR *, long);
> +void           _fixtelldir(DIR *dirp, long oldseek, long oldloc);
>
>  #endif
> _______________________________________________
> svn-src-all@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/svn-src-all
> To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAJ5_RoBPe0ZnLYbNSyOTpXgChhqU3UuORv9uZj50iUC7nV%2BTZw>