Subject: Updated READDIR

From: Spencer Shepler <[email-masked]>
Date: Thu, 04 Nov 1999 15:12:06 -0600

Here is an update READDIR based on recent discussion:

-----
12.2.22.  Operation 23: READDIR - Read Directory

   SYNOPSIS
      (cfh), cookie, cookieverf, dircount, maxcount, attrbits ->
      cookieverf { cookie, filename, attrbits, attributes }

   ARGUMENT

     struct READDIR4args {
             /* CURRENT_FH: directory */
             nfs_cookie4     cookie;
             cookieverf4     cookieverf;
             count4          dircount;
             count4          maxcount;
             bitmap4         attr_request;

     };

   RESULT

     struct entry4 {
             nfs_cookie4     cookie;
             component4      name;
             fattr4          attrs;
             entry4          *nextentry;
     };

     struct dirlist4 {
             entry4          *entries;
             bool            eof;
     };

     struct READDIR4resok {
             cookieverf4     cookieverf;
             dirlist4        reply;
     };

     union READDIR4res switch (nfsstat4 status) {
      case NFS4_OK:
              READDIR4resok  resok4;
      default:
              void;
     };

   DESCRIPTION

     The READDIR procedure retrieves a variable number of entries from a
     file system directory and returns client requested attributes for
     each entry along with information to allow the client to request
     additional directory entries in a subsequent READDIR.

     The arguments contain a cookie value that represents where the
     READDIR should start within the directory.  A value of 0 (zero) for
     the cookie is used to start reading at the beginning of the
     directory.  For subsequent READDIR requests, the client specifies a
     cookie value that is provided by the server on a previous READDIR
     request.

     The cookieverf value should be set to 0 (zero) when the cookie
     value is 0 (zero) (first directory read).  On subsequent requests,
     it should be a cookieverf as returned by the server.  The
     cookieverf must match that returned by the READDIR in which the
     cookie was acquired.

     The dircount portion of the argument is a hint of the maximum
     number of bytes of directory information that should be returned.
     This value is the XDR encoded length of the name of the directory
     entry and the cookie value for the entry.  The server may return
     less data.

     The maxcount value of the argument specifies a maximum number of
     bytes for the result.  This maximum size represents all of the data
     being returned and includes the XDR overhead.  The server may
     return less data.

     Finally, attrbits represents the list of attributes to be returned
     for each directory entry supplied by the server.

     On successful return, the server's response will provide a list of
     directory entries.  Each of these entries contains the name of the
     directory entry, a cookie value for that entry, and the associated
     attributes as requested.

     The cookie value is only meaningful to the server and is used as a
     "bookmark" for the directory entry.  As mentioned, this cookie is
     used by the client for subsequent READDIR operations so that it may
     continue reading a directory.  The cookie is similar in concept to
     a READ offset but should not be interpreted as such by the client.
     Ideally, the cookie value should not change if the directory is
     modified.

     In some cases, the server may encounter an error while obtaining
     the attributes for a directory entry.  Instead of returning an
     error for the entire READDIR operation, the server can instead
     return the attribute 'fattr4_rdattr_error'.  With this the server
     is able to communicate the failure to the client and not fail the
     entire operation in the instance of what might be a transient
     failure.  Obviously, the client must request the
     fattr4_rdattr_error attribute for this method to work properly.  If
     the client does not request the attribute, the server has no choice
     but to return failure for the entire READDIR operation.

     For some file system environments, the directory entries "." and
     ".."  have special meaning and in other environments, they may not.
     If the server supports these special entries within a directory,
     they should not be returned to the client as part of the READDIR
     response.  To enable some client environments, the cookie values of
     0, 1, and 2 are to be considered reserved and not used in READDIR
     responses.

   IMPLEMENTATION

     The server's file system directory representations can differ
     greatly.  A client's APIs may also be bound to the local operating
     environment in a way that does not translate well into the NFS
     protocol.  Therefore the use of the dircount and maxcount fields
     are provided to allow the client the ability to provide guidelines
     to the server.  If the client is aggressive about attribute
     collection during a READDIR, the server has an idea of how to limit
     the encoded response.  The dircount field provides a hint on the
     number of entries based solely on the names of the directory
     entries.

     The cookieverf may be used by the server to help manage cookie
     values that may become stale.  It should be a rare occurance that a
     server is unable to continue properly reading a directory with the
     provided cookie/cookieverf pair.  The server should make every
     effort to avoid this condition since the application at the client
     may not be able to properly handle this type of failure.

   ERRORS

     NFS4ERR_IO

     NFS4ERR_ACCES

     NFS4ERR_NOTDIR

     NFS4ERR_INVAL

     NFS4ERR_STALE

     NFS4ERR_BADHANDLE

     NFS4ERR_BAD_COOKIE

     NFS4ERR_TOOSMALL

     NFS4ERR_NOTSUPP

     NFS4ERR_SERVERFAULT

     NFS4ERR_JUKEBOX

     NFS4ERR_FHEXPIRED

     NFS4ERR_WRONGSEC

     NFS4ERR_MOVED

     NFS4ERR_RESOURCE

---

From: Mike Eisler <[email-masked]>
Date: Thu, 4 Nov 1999 14:24:47 -0800 (PST)

>      The dircount portion of the argument is a hint of the maximum
						^^^^^^^
>      entry and the cookie value for the entry.  The server may return
	^^^^^^^
>      being returned and includes the XDR overhead.  The server may
		^^^^^^

Either they should be hints, or both not. Based on my understanding of Peter's
explanation, if only one is a hint it should be maxcount.

If they are hints, then the server should be able to return more data. It's
kind of tricky to xdr encode a bunch of entires, still be under the dircount
and maxcount, and then encode one more entry and find yourself over the limit.
This is especially so with V4 attributes, because the routine that processes
the attribute will encode them before the server's readdir routine gets the
attributes back.

Suggestion:

	dircount and maxcount are both hints. The server SHOULD 
	return no more than one additional directory entry beyond the counts.

>      0, 1, and 2 are to be considered reserved and not used in READDIR

What do  1 and 2 correspond to. Can I use them READDIRargs?

>    IMPLEMENTATION
...
>      may not be able to properly handle this type of failure.

The implementation description I gave of how a client can use the cookie
verifier to avoid the scenario fo cookies matching when the shouldn't should
be mentioned.

>  ERRORS

need error code for bad cookie verifier.

---

From: Spencer Shepler <[email-masked]>
Date: Thu, 04 Nov 1999 17:14:21 -0600

>         return no more than one additional directory entry beyond the counts.

This is what I was leaning towards but had not made the change.  I will
use your suggestion.

> What do  1 and 2 correspond to. Can I use them READDIRargs?

Can not be used for the cookie value in READDIRargs (reserved in both directions).

> verifier to avoid the scenario fo cookies matching when the shouldn't should

Okay

> need error code for bad cookie verifier.

I assumed that NFS4ERR_BAD_COOKIE would signify that a cookie/cookieverf
mismatch had occurred.  Not sufficient information?

Spencer

---

From: Eric Werme USG <[email-masked]>
Date: Thu, 04 Nov 1999 21:34:41 -0500

^^^^^^^
   	^^^^^^^
   		^^^^^^
   
   Either they should be hints, or both not. Based on my understanding of Peter
  's
   explanation, if only one is a hint it should be maxcount.
   
   If they are hints, then the server should be able to return more data. It's
   kind of tricky to xdr encode a bunch of entires, still be under the dircount
   and maxcount, and then encode one more entry and find yourself over the limi
  t.

I think both should be maxima.  While it may be convenient for the server
to squeeze in just one more entry, it may be difficult for the client
to discard that entry if it has allocated exactly dircount or maxcount
bytes for buffers.  (Well, okay, dircount is such a fuzzy number it's
unclear how well client or server can avoid discarding data sometimes.)

I rewrote our readdirplus code last year in response to discovering it
wa a major bottleneck in SpecSFS V2.  SFS sends dircount == 8192,
maxcount == 8192.  We were reading 8 KB of directory data, buffering
24 KB of attributes and 32K of file handles, and then discarded nearly
all of it.  I changed the code to directly generate XDR'd
data.  I now limit dircount to 20% (I think) of maxcount, and successfully
resisted the temptation to identify SFS and return a single entry.

I generate XDR data directly and found it pretty easy to stop before
exceeding maxcount:

		if (xdr_resid < NFS3XDR_RDPSIZE + xdp->kd_namlen) {
			iseof = FALSE;
			break;
		}

xdr_resid starts out as maxcount minus overhead.  NFS3XDR_RDPSIZE assumes
that fh and attributes are avaiable (a rather safe bet).

The V4 attribute stuff will be a bit more of a hassle, but you can assume
a max for that too.

	-Ric Werme

---

From: Mike Eisler <[email-masked]>
Date: Fri, 5 Nov 1999 07:17:52 -0800 (PST)

> I think both [dircont and maxcount] should be maxima

If dircount counts only bytes of native directory representation on the
clienmt, how can dircount be a maxima? What if dircount is small and on my
server, that is too small to represent one directory entry?

	-mre