Subject: link and rename update

From: Mike Eisler <[email-masked]>
Date: Tue, 16 Nov 1999 05:47:29 -0800 (PST)

The arguments to the LINK and RENAME operations both contain a pair of
fields like:

	   nfs_fh4         dir;
           component4      newname;

The field 'dir' is the file handle of the target directory. The file
handle of the source directory, or if the case of LINK, the source
file, is passed to LINK and RENAME via a previous PUT*, RESTOREFH,
LOOKUP, LOOKUPP, or OPEN (and any other operation I've overlooked at
places a file handle into the compound operation stream).

This makes target directories second class citizens.

Consider that a client can do:

	COMPOUND { putrootfh  ; lookup "a" "b" "c" ; link dir "d" },

but in order to get 'dir', the client must incur a previous round trip of:

	COMPOUND { putrootfh ; lookup "a1" "b2" "c3" ; getfh }

Considering the WG's charter, to improve performance over the internet,
this shouldn't stand.

At the D.C. IETF WG meeting, there were two questions raised.

One, given the relative "infrequency" of LINK and RENAME, should we
make the protocol more complex. I responded that I think it makes the
protocol less complex ... fewer round trips, and simpler arguments to
LINK and RENAME. After the meeting I recalled that LINK and RENAME
figure prominently in the SPEC SFS workload, and LINK has been a topic
of some interesting performance problems between Solaris and NetApp
systems recently. So improving LINK and RENAME performance is a good
thing.

Two, Neil brown's question about stateids being second class citizens
was raised. My response was that it's a bit late to consider making a
protocol specification change that injects the notion of a current
stateid similar to the current file handle. I also noted that a stateid
of all ones gives one the ability to avoid a round trip, and thus is a
partial, if not 80% solution. After the meeting, I realized that the
comparison between LINK/RENAME and LOCK, READ|WRITE, UNLOCK isn't quite
apt, because there are lots of known APIs that do atomic rename and
link, but aside from mandatory locking, zero to few APIs that do
compound lock, I/O, unlock.

Two weeks ago I made my original LINK/RENAME proposal. Since then we've
had discussion on the WG alias about it, and also some discussion on an
internal Sun alias.

The WG appears to have reached consensus on using the saved file handle
as the target's file handle in RENAME and LINK. However, as noted
within Sun, that approach requires that the client construct a COMPOUND
such that it does a LOOKUP of the target's path name before that of the
source, and yet LINK and RENAME's arguments are source followed by
target.  This is counter intuitive.

So I propose flipping the saved fh and current fh in the LINK/RENAME
arguments.

The target file handle comes from the current file handle, and the
source file handle comes from the saved file handle.

			Operation 26: RENAME 

	SYNOPSIS

			(sfh), oldname, (cfh), newname ->
				source_change_info, target_change_info

			ARGUMENT

			struct RENAME4args {
			     /* SAVED_FH: source directory */
			     component4       oldname;
			     /* CURRENT_FH: target directory */
			     component4       newname;
			};

		LINK's changes are an exercise for the editor. :-)
		E.g.

	example:

	COMPOUND {
		putrootfh ;  lookup "afrom" "bfrom" "cfrom" ; savefh ;

		putrootfh  ; lookup "atarg" "btarg" "ctarg" ;

		rename "dfrom" "dtarg" ;

		getattr fh mtime ;# gets fh and attributes of targ. dir.

		restorefh ;	 # injects fh of src directory again 
		getattr fh mtime ;# gets fh and attributes of src dir.
	}