Subject: RE: Caching issue (SHORT, really, I swear)

From: "Noveck, Dave" <[email-masked]>
Date: Thu, 12 Aug 1999 07:27:36 -0700

> > > 2. What would happen if Dave's proposal were modified so 
> that instead
> > > of the server expressing a limit in terms of file size, the server
> > > expresses the limit in terms of how much unwritten 
> (dirty) data the
> > > client can accumulate before writing back to the server?
> > 
> > My answer is it that it would cease to work.  The problem is that
> > the mapping from amount of dirty data to amount of disk depends 
> > (in a large way) on where specifically, the data is to be written.
> > If I am allowed to write 1000 bytes, if I were to write one thousand
> > very dispersed one-byte areas, the amount of space required might be
> > enormous and it would depend on lots of things, depending on the
> 
> So why can't the server report the number of bytes the client is
> allowed to cache and also what the block size is?

That might work.  I've thought about it a little.  I think I
need to convince myself that the client can properly keep track
of the amount of dirty data (as the server would interpret it
given his blocksize), even though the client's blocksize might
be different.

> 
> > type of server.  Things like indirect block structures and 
> how holes are
> > handled would all come into play.

> 
> Issues of indirect blocks apply whether one is using a limit 
> in terms of file
> size or block count. 

True, although the effect is greater when the client may
really scatter data widely.  Even if you are talking full
blocks, the client could write in such a scattered fashion
that each block required three (or four?) blocks with all
the indirect blocks which means that the server would
have to divide the space by the appropriate factor so
that the limit was suitably worst-case.

> As for holes maybe it means that we don't support
> write delegation on file systems that don't efficiently deal 
> with holes, or
> the limit is a discriminated union that's either byte count 
> or file length.
 
We could still support write delegation on such file systems
but would just have to always flush on close.

One idea I've been toying with is that the limit data consists
of a file length and a byte/block count.  The file would have
to fit within both limits for the client to avoid a flush
but a server could choose to set one of the limits very 
high.  This might allow a typical UNIX server to avoid 
very widely scattered writes by setting some (still fairly
high) limit on the file length while using the block
count as the primary limiter.  Hole-challenged systems
would use the file length limit and set the block count
limit so high it didn't matter.

I'm beginning to be fairly confident that this issue will
have a resolution but doubtful that all the kinks can be
worked out (and consensus arrived at) before the August spec 
train leaves the station.

How about this?  What is now the filesize limit become a 
structure space_limitation whose current realization is
just a filesize limit but will be flagged as intended 
for extension.  The spec will make it clear that
the architecture is one in which the server passes a 
small set of data which the client can use to determine,
given the data it has, whether the flush needs to occur.
The filesize-limit-only implementation would be a 
placeholder which would become the real implementaion
only if all of the (seemingly) better alternatives
don't pan out.

---

From: Mike Eisler <[email-masked]>
Date: Thu, 12 Aug 1999 07:51:11 -0700 (PDT)

> only if all of the (seemingly) better alternatives

I'd like people to think about alternatives now, to increase the chances that
a viable alternative will pan out.

I propose a slight change to above and that is that the discriminated union
space_limitation include both a file size limit and block reservation limit,
now. The block reservation limit is flagged as subject to change pending
implementation experience.

enum limit_by4 {
        NFS4_SIZE = 1,
        NFS4_DIRTY_BLOCKS = 2 /* experimental. subject to change */
        /* others as needed */
};

struct nfs4_dirty_limit {
        unsigned hyper bytes;
        unsigned int blocksize;
} ;

union nfs4_space_limit switch (enum limit_by4 limitby) {
                case NFS4_SIZE:
                        unsigned hyper filesize;
                case NFS4_DIRTY_BLOCKS:
                        nfs4_dirty_limit dirtyblocks;
} ;