]> www.infradead.org Git - users/dhowells/kafs-web.git/commitdiff
Initial import
authorDavid Howells <dhowells@casper.infradead.org>
Tue, 30 Jun 2020 16:57:15 +0000 (17:57 +0100)
committerDavid Howells <dhowells@casper.infradead.org>
Tue, 30 Jun 2020 16:57:15 +0000 (17:57 +0100)
.gitignore [new file with mode: 0644]
af_rxrpc_client.html [new file with mode: 0644]
fsinfo.html [new file with mode: 0644]
index.html [new file with mode: 0644]
kafs_client.html [new file with mode: 0644]
kafs_utils.html [new file with mode: 0644]
todo.html [new file with mode: 0644]
user_interface.html [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..09c2257
--- /dev/null
@@ -0,0 +1,5 @@
+*.rpm
+*.tar.bz2
+kafs-client.spec
+aklog-*.c
+
diff --git a/af_rxrpc_client.html b/af_rxrpc_client.html
new file mode 100644 (file)
index 0000000..09c467e
--- /dev/null
@@ -0,0 +1,271 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+   "http://www.w3.org/TR/html4/strict.dtd">
+<HTML>
+  <STYLE type="text/css">
+    CODE.example { color: blue }
+  </STYLE>
+  <HEAD>
+    <TITLE>AF_RXRPC: Client</TITLE>
+  </HEAD>
+  <BODY>
+    <HEADER>
+    </HEADER>
+    <MAIN>
+      <H1>Example userspace AF_RXRPC client usage</H1>
+      <TEXT>
+       <P>
+         AF_RXRPC is implemented as a network protocol and, as such, is
+         accessible from userspace through the Linux socket interface.  A
+         socket is opened and then multiple calls may be made over it using
+         the ancillary data provided to <CODE>sendmsg()</CODE>
+         and <CODE>recvmsg()</CODE> to determine the call.
+       </P>
+       <H2>Prologue</H2>
+       <P>
+         First of all, an AF_RXRPC socket must be opened:
+       </P>
+       <CODE class="example"><PRE>
+            client = socket(AF_RXRPC, SOCK_DGRAM, PF_INET);</PRE></CODE>
+       <P>
+         The second argument is the transport socket type (which must
+         be <CODE>DGRAM</CODE> for the moment) and the third argument
+         specified the transport protocol (<CODE>PF_INET</CODE>
+         or <CODE>PF_INET6</CODE>).  This gets you a file descriptor that can
+         be used to perform RPC message passing.  You can then set the
+         security on it:
+       </P>
+       <CODE class="example"><PRE>
+            int sec = RXRPC_SECURITY_AUTH;
+            ret = setsockopt(client, SOL_RXRPC, RXRPC_MIN_SECURITY_LEVEL, &amp;sec, sizeof(sec));
+            const char principal[] = "afs@GRAND.CENTRAL.ORG";
+            ret = setsockopt(client, SOL_RXRPC, RXRPC_SECURITY_KEY, principal, strlen(principal));</PRE></CODE>
+       <P>
+         The first statement sets the minimum security level required to one
+         of checksum only (<CODE>PLAIN</CODE>), authenticated packet only
+         (<CODE>AUTH</CODE>) or full packet encryption (<CODE>ENCRYPT</CODE>).
+         The second statement sets the name of the key to be used.
+       <P>
+         An address can then be bound to the local endpoint.  This is optional
+         for a client, but if a specific address and/or port is required for
+         the local UDP transport, then this must be used.
+       </P>
+       <CODE class="example"><PRE>
+            memset(&amp;my_addr, 0, sizeof(my_addr));
+            my_addr.my_addr_family              = AF_RXRPC;
+            my_addr.my_addr_service             = 0;
+            my_addr.transport_type              = SOCK_DGRAM;
+            my_addr.transport_len               = sizeof(my_addr.transport.sin);
+            my_addr.transport.sin.sin_family    = AF_INET;
+            my_addr.transport.sin.sin_port      = htons(7001);
+            memcpy(&amp;my_addr.transport.sin.sin_addr, &amp;local_addr, 4);
+
+            ret = bind(client, (struct sockaddr *)&amp;my_addr, sizeof(my_addr));</PRE></CODE>
+       <P>
+         For a service, <CODE>.srx_service</CODE> is where the service ID on
+         which the caller wishes to listen is specified; this should
+         be <CODE>0</CODE> for a purely client socket.
+       <P>
+         It should be noted that client sockets opened separately may share a
+         UDP port inside the kernel with each other, but sharing a UDP socket
+         between a service and a client or between a pair of services is
+         forbidden.
+       <P>
+         We then need to set up the address of the server to which we're going
+         to try to talk:
+       </P>
+       <CODE class="example"><PRE>
+            peer_addr.peer_addr_family          = AF_RXRPC;
+            peer_addr.peer_addr_service         = 52;
+            peer_addr.transport_type            = SOCK_DGRAM;
+            peer_addr.transport_len             = sizeof(peer_addr.transport.sin);
+            peer_addr.transport.sin.sin_family  = AF_INET;
+            peer_addr.transport.sin.sin_port    = htons(7003);
+            memcpy(&amp;peer_addr.transport.sin.sin_addr, &amp;remote_addr, 4);</PRE></CODE>
+       <P>
+         The <CODE>.srx_service</CODE> member holds the service ID that we
+         wish to contact on the far port. <CODE>.transport</CODE> holds the
+         transport socket parameters.  The <CODE>.transport_type</CODE>
+         and <CODE>.transport_family</CODE> must match the values given to
+         socket as <CODE>type</CODE>
+         and <CODE>protocol</CODE>.  <CODE>.transport.sin</CODE> carries the
+         target UDP address.
+       </P>
+       <H2>Call Initiation and Transmission Phase</H2>
+       <P>
+         Next we need to load up the ancillary data into the control buffer
+         for <CODE>sendmsg()</CODE> to use in call multiplexing:
+       </P>
+       <CODE class="example"><PRE>
+            ctrllen = 0;
+            RXRPC_ADD_CALLID(control, ctrllen, 0x12345);</PRE></CODE>
+       <P>
+         This includes userspace's identifier for the call we're about to
+         launch (in this case <CODE>0x12345</CODE>).  It must be included in
+         all subsequent <CODE>sendmsg()</CODE> calls and it will be included
+         in the return from all subsequent <CODE>recvmsg()</CODE> calls.  It
+         is valid until <CODE>recvmsg()</CODE> returns <CODE>MSG_EOR</CODE> in
+         conjuction with this call ID.  The call identifier is an integer of
+         size <CODE>unsigned long</CODE> and may be used to hold a pointer if
+         that is convenient.
+       <P>
+         We then marshal the request data into a buffer:
+       </P>
+       <CODE class="example"><PRE>
+            static char vlname[] = "root.cell";
+            vllen = sizeof(vlname) - 1;
+            param[0] = htonl(VLGETENTRYBYNAME);
+            param[1] = htonl(vllen);
+            padding = 0;</PRE></CODE>
+       <P>
+         And then we call sendmsg() to send the data, inserting suitable
+         padding to round strings up to four-byte alignment:
+       </P>
+       <CODE class="example"><PRE>
+            iov[0].iov_len  = sizeof(param);
+            iov[0].iov_base = param;
+            iov[1].iov_len  = vllen;
+            iov[1].iov_base = vlname;
+            iov[2].iov_len  = 4 - (vllen &amp; 3);
+            iov[2].iov_base = &amp;padding;
+            ioc = (iov[2].iov_len > 0) ? 3 : 2;
+
+            msg.msg_name            = (struct sockaddr *)&amp;peer_addr;
+            msg.msg_namelen         = sizeof(peer_addr);
+            msg.msg_iov             = iov;
+            msg.msg_iovlen          = ioc;
+            msg.msg_control         = control;
+            msg.msg_controllen      = ctrllen;
+            msg.msg_flags           = 0;
+
+            ret = sendmsg(client, &amp;msg, 0);</PRE></CODE>
+       <P>
+         Note that we pass MSG_MORE if we want to send more data.  AF_RXRPC
+         will collect the data into appropriately sized packets so that there
+         is no wastage of sequence number space (there is a limit to the
+         number of DATA packets that can be sent in each direction).
+       </P>
+       <H2>Reception Phase</H2>
+       <P>
+         We can listen for a response from the server:
+       </P>
+       <CODE class="example"><PRE>
+            iov[0].iov_base = buffer;
+            iov[0].iov_len = sizeof(buffer);
+
+            msg.msg_name            = &amp;rx_addr;
+            msg.msg_namelen         = sizeof(rx_addr);
+            msg.msg_iov             = iov;
+            msg.msg_iovlen          = 1;
+            msg.msg_control         = control;
+            msg.msg_controllen      = sizeof(control);
+            msg.msg_flags           = 0;
+
+            ret = recvmsg(client, &amp;msg, 0);</PRE></CODE>
+       <P>
+         This will return <CODE>0</CODE> or the number of bytes read into the
+         buffer if it successfully queried a call - even if that call failed -
+         and <CODE>-ENODATA</CODE> if no calls were outstanding on a client
+         socket.  If a call did fail, the control message buffer will hold
+         ancillary data indicating the reason.  The ancillary data will also
+         hold the call identifier.  It should be noted that if several calls
+         are in progress simultaneously upon a socket, consecutive calls
+         to <CODE>recvmsg()</CODE> may return information from different
+         calls.  It is possible, however, to specify <CODE>MSG_PEEK</CODE> to
+         find out what the next call will be without altering the call state.
+       <P>
+         If there is more data to be read because the call has not yet reached
+         the end of its reception phase, then <CODE>MSG_MORE</CODE> will be
+         returned.
+       <P>
+         If any terminal indication is given, then the recvmsg will have
+         indicated <CODE>MSG_EOR</CODE> to indicate that the call identifier
+         is now released and can be reused.
+       <P>
+         The contents of the control buffer then need to be parsed:
+       </P>
+       <CODE class="example"><PRE>
+            struct cmsghdr *cmsg;
+            unsigned long call_identifier;
+            int abort_code, error;
+            enum {
+                call_ongoing,
+                call_remotely_aborted,
+                service_call_finally_acked,
+                call_network_error,
+                call_error,
+                call_busy,
+            } call_state = call_ongoing;
+
+            for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
+                    void *p = CMSG_DATA(cmsg);
+                    int n = cmsg->cmsg_len - CMSG_ALIGN(sizeof(*cmsg));
+
+                    if (cmsg->cmsg_level == SOL_RXRPC) {
+                            switch (cmsg->cmsg_type) {
+                            case RXRPC_USER_CALL_ID:
+                                    memcpy(&amp;call_identifier, p, sizeof(user_id));
+                                    continue;
+                            case RXRPC_ABORT:
+                                    memcpy(&amp;abort_code, p, sizeof(abort_code));
+                                    call_state = call_remotely_aborted;
+                                    continue;
+                            case RXRPC_ACK:
+                                    call_state = service_call_finally_acked;
+                                    continue;
+                            case RXRPC_NET_ERROR:
+                                    memcpy(&amp;error, p, sizeof(error));
+                                    errno = error;
+                                    call_state = call_network_error;
+                                    continue;
+                            case RXRPC_BUSY:
+                                    call_state = call_busy;
+                                    continue;
+                            case RXRPC_LOCAL_ERROR:
+                                    memcpy(&amp;error, p, sizeof(error));
+                                    errno = error;
+                                    call_state = call_error;
+                                    continue;
+                            default:
+                                    break;
+                            }
+                    }
+            }</CODE></PRE>
+       <P>
+         The above snippet parses the control buffer, extracting the call
+         identifier along with the code of any abort received and any local or
+         network error incurred.  It also extracts the indication that the
+         call was terminated because the server kept returning a busy packet
+         and the indication that a service call received the final ACK from
+         the remote client.
+       </P>
+       <H2>Aborting a Call</H2>
+       <P>
+         An active call may be aborted as long as recvmsg() hasn't yet
+         indicated that the call has been terminated by
+         flagging <CODE>MSG_EOR</CODE>.  This is done by specifying the call
+         identifier and the abort code in the control message:
+       </P>
+       <CODE class="example"><PRE>
+            ctrllen = 0;
+            RXRPC_ADD_CALLID(control, ctrllen, 0x12345);
+            RXRPC_ADD_ABORT(control, ctrllen, 0x6789);
+
+            msg.msg_name            = NULL;
+            msg.msg_namelen         = 0;
+            msg.msg_iov             = NULL;
+            msg.msg_iovlen          = 0;
+            msg.msg_control         = control;
+            msg.msg_controllen      = ctrllen;
+            msg.msg_flags           = 0;
+
+            ret = sendmsg(client, &amp;msg, 0);</PRE></CODE>
+       <P>
+         Note that this still has to be followed with a call
+         to <CODE>recvmsg()</CODE> to find out how the call actually ended
+         (it's possible the call was aborted first from the other side, for
+         example).
+       </P>
+      </TEXT>
+    </MAIN>
+  </BODY>
+</HTML>
diff --git a/fsinfo.html b/fsinfo.html
new file mode 100644 (file)
index 0000000..28b7ad3
--- /dev/null
@@ -0,0 +1,1404 @@
+<HTML><HEAD><TITLE>Manpage of FSINFO</TITLE>
+</HEAD><BODY>
+<H1>FSINFO</H1>
+Section: Linux Programmer's Manual (2)<BR>Updated: 2018-06-06<BR><A HREF="#index">Index</A>
+<A HREF="/man/man2html">Return to Main Contents</A><HR>
+
+<A NAME="lbAB">&nbsp;</A>
+<H2>NAME</H2>
+
+fsinfo - Get filesystem information
+<A NAME="lbAC">&nbsp;</A>
+<H2>SYNOPSIS</H2>
+
+<PRE>
+<B>#include &lt;<A HREF="file:///usr/include/sys/types.h">sys/types.h</A>&gt;</B>
+<B>#include &lt;<A HREF="file:///usr/include/sys/fsinfo.h">sys/fsinfo.h</A>&gt;</B>
+<B>#include &lt;<A HREF="file:///usr/include/unistd.h">unistd.h</A>&gt;</B>
+<B>#include &lt;<A HREF="file:///usr/include/fcntl.h">fcntl.h</A>&gt;           </B>/* Definition of AT_* constants */
+
+<B>int fsinfo(int </B><I>dirfd</I><B>, const char *</B><I>pathname</I><B>,</B>
+<B>           struct fsinfo_params *</B><I>params</I><B>,</B>
+<B>           void *</B><I>buffer</I><B>, size_t </B><I>buf_size</I><B>);</B>
+</PRE>
+
+<P>
+
+<I>Note</I>:
+
+There is no glibc wrapper for
+<B>fsinfo</B>();
+
+see NOTES.
+<A NAME="lbAD">&nbsp;</A>
+<H2>DESCRIPTION</H2>
+
+<P>
+
+fsinfo() retrieves the desired filesystem attribute, as selected by the
+parameters pointed to by
+<I>params</I>,
+
+and stores its value in the buffer pointed to by
+<I>buffer</I>.
+
+<P>
+
+The parameter structure is optional, defaulting to all the parameters being 0
+if the pointer is NULL.  The structure looks like the following:
+<P>
+
+
+<PRE>
+struct fsinfo_params {
+    __u32 at_flags;     /* AT_SYMLINK_NOFOLLOW and similar flags */
+    __u32 request;      /* Requested attribute */
+    __u32 Nth;          /* Instance of attribute */
+    __u32 Mth;          /* Subinstance of Nth instance */
+    __u32 __reserved[6]; /* Reserved params; all must be 0 */
+};
+</PRE>
+
+
+<P>
+
+The filesystem to be queried is looked up using a combination of
+<I>dfd</I>, <I>pathname</I> and <I>params-&gt;at_flags.</I>
+
+This is discussed in more detail below.
+<P>
+
+The desired attribute is indicated by
+<I>params-&gt;request</I>.
+
+If
+<I>params</I>
+
+is NULL, this will default to
+<B>fsinfo_attr_statfs</B>,
+
+which retrieves some of the information returned by
+<B>statfs</B>().
+
+The available attributes are described below in the &quot;THE ATTRIBUTES&quot; section.
+<P>
+
+Some attributes can have multiple values and some can even have multiple
+instances with multiple values.  For example, a network filesystem might use
+multiple servers.  The names of each of these servers can be retrieved by
+using
+<I>params-&gt;Nth</I>
+
+to iterate through all the instances until error
+<B>ENODATA</B>
+
+occurs, indicating the end of the list.  Further, each server might have
+multiple addresses available; these can be enumerated using
+<I>params-&gt;Nth</I>
+
+to iterate the servers and
+<I>params-&gt;Mth</I>
+
+to iterate the addresses of the Nth server.
+<P>
+
+The amount of data written into the buffer depends on the attribute selected.
+Some attributes return variable-length strings and some return fixed-size
+structures.  If either
+<I>buffer</I> is  NULL  or <I>buf_size</I> is 0
+
+then the size of the attribute value will be returned and nothing will be
+written into the buffer.
+<P>
+
+The
+<I>params-&gt;__reserved</I>
+
+parameters must all be 0.
+
+<A NAME="lbAE">&nbsp;</A>
+<H3>Allowance for Future Attribute Expansion</H3>
+
+<P>
+
+To allow for the future expansion and addition of fields to any fixed-size
+structure attribute,
+<B>fsinfo</B>()
+
+makes the following guarantees:
+<OL>
+  <LI>It will always clear any excess space in the buffer.
+  <LI>It will always return the actual size of the data.
+  <LI>It will truncate the data to fit it into the buffer rather than giving an
+    error.
+  <LI>Any new version of a structure will incorporate all the fields from the old
+    version at same offsets.
+</OL>
+
+<P>
+
+So, for example, if the caller is running on an older version of the kernel
+with an older, smaller version of the structure than was asked for, the kernel
+will write the smaller version into the buffer and will clear the remainder of
+the buffer to make sure any additional fields are set to 0.  The function will
+return the actual size of the data.
+<P>
+
+On the other hand, if the caller is running on a newer version of the kernel
+with a newer version of the structure that is larger than the buffer, the write
+to the buffer will be truncated to fit as necessary and the actual size of the
+data will be returned.
+<P>
+
+Note that this doesn't apply to variable-length string attributes.
+<P>
+
+<A NAME="lbAF">&nbsp;</A>
+<H3>Invoking <B>fsinfo</B>():</H3>
+
+<P>
+
+To access a file's status, no permissions are required on the file itself, but
+in the case of
+<B>fsinfo</B>()
+
+with a path, execute (search) permission is required on all of the directories
+in
+<I>pathname</I>
+
+that lead to the file.
+<P>
+
+<B>fsinfo</B>()
+
+uses
+<I>pathname</I>, <I>dirfd</I> and <I>params-&gt;at_flags</I>
+
+to locate the target file in one of a variety of ways:
+<DL COMPACT>
+<DT>[*] By absolute path.<DD>
+<I>pathname</I>
+
+points to an absolute path and
+<I>dirfd</I>
+
+is ignored.  The file is looked up by name, starting from the root of the
+filesystem as seen by the calling process.
+<DT>[*] By cwd-relative path.<DD>
+<I>pathname</I>
+
+points to a relative path and
+<I>dirfd</I> is <I>AT_FDCWD</I>.
+
+The file is looked up by name, starting from the current working directory.
+<DT>[*] By dir-relative path.<DD>
+<I>pathname</I>
+
+points to relative path and
+<I>dirfd</I>
+
+indicates a file descriptor pointing to a directory.  The file is looked up by
+name, starting from the directory specified by
+<I>dirfd</I>.
+
+<DT>[*] By file descriptor.<DD>
+<I>pathname</I> is <I>NULL</I> and <I>dirfd</I>
+
+indicates a file descriptor.  The file attached to the file descriptor is
+queried directly.  The file descriptor may point to any type of file, not just
+a directory.
+</DL>
+<P>
+
+<I>flags</I>
+
+can be used to influence a path-based lookup.  A value for
+<I>flags</I>
+
+is constructed by OR'ing together zero or more of the following constants:
+<DL COMPACT>
+<DT><B>AT_EMPTY_PATH</B>
+
+<DD>
+
+If
+<I>pathname</I>
+
+is an empty string, operate on the file referred to by
+<I>dirfd</I>
+
+(which may have been obtained using the
+<B><A HREF="/man/man2html?2+open">open</A></B>(2)
+
+<B>O_PATH</B>
+
+flag).
+If
+<I>dirfd</I>
+
+is
+<B>AT_FDCWD</B>,
+
+the call operates on the current working directory.
+In this case,
+<I>dirfd</I>
+
+can refer to any type of file, not just a directory.
+This flag is Linux-specific; define
+<B>_GNU_SOURCE</B>
+
+
+to obtain its definition.
+<DT><B>AT_NO_AUTOMOUNT</B>
+
+<DD>
+Don't automount the terminal (&quot;basename&quot;) component of
+<I>pathname</I>
+
+if it is a directory that is an automount point.  This allows the caller to
+gather attributes of the filesystem holding an automount point (rather than
+the filesystem it would mount).  This flag can be used in tools that scan
+directories to prevent mass-automounting of a directory of automount points.
+The
+<B>AT_NO_AUTOMOUNT</B>
+
+flag has no effect if the mount point has already been mounted over.
+This flag is Linux-specific; define
+<B>_GNU_SOURCE</B>
+
+
+to obtain its definition.
+<DT><B>AT_SYMLINK_NOFOLLOW</B>
+
+<DD>
+If
+<I>pathname</I>
+
+is a symbolic link, do not dereference it:
+instead return information about the link itself, like
+<B>lstat</B>().
+
+</DL>
+<A NAME="lbAG">&nbsp;</A>
+<H2>THE ATTRIBUTES</H2>
+
+<P>
+
+There is a range of attributes that can be selected from.  These are:
+<P>
+
+<DL COMPACT>
+<DT><B>fsinfo_attr_statfs</B>
+
+<DD>
+This retrieves the &quot;dynamic&quot;
+<B>statfs</B>
+
+information, such as block and file counts, that are expected to change whilst
+a filesystem is being used.  This fills in the following structure:
+</DL>
+<P>
+
+<DL COMPACT><DT><DD>
+
+<PRE>
+struct fsinfo_statfs {
+    __u64 f_blocks;     /* Total number of blocks in fs */
+    __u64 f_bfree;      /* Total number of free blocks */
+    __u64 f_bavail;     /* Number of free blocks available to ordinary user */
+    __u64 f_files;      /* Total number of file nodes in fs */
+    __u64 f_ffree;      /* Number of free file nodes */
+    __u64 f_favail;     /* Number of free file nodes available to ordinary user */
+    __u32 f_bsize;      /* Optimal block size */
+    __u32 f_frsize;     /* Fragment size */
+};
+</PRE>
+
+
+</DL>
+
+<DL COMPACT>
+<DT><DD>
+The fields correspond to those of the same name returned by
+<B>statfs</B>().
+
+<P>
+
+<DT><B>fsinfo_attr_fsinfo</B>
+
+<DD>
+This retrieves information about the
+<B>fsinfo</B>()
+
+system call itself.  This fills in the following structure:
+</DL>
+<P>
+
+<DL COMPACT><DT><DD>
+
+<PRE>
+struct fsinfo_fsinfo {
+    __u32 max_attr;
+    __u32 max_cap;
+};
+</PRE>
+
+
+</DL>
+
+<DL COMPACT>
+<DT><DD>
+The
+<I>max_attr</I>
+
+value indicates the number of attributes supported by the
+<B>fsinfo</B>()
+
+system call, and
+<I>max_cap</I>
+
+indicates the number of capability bits supported by the
+<B>fsinfo_attr_capabilities</B>
+
+attribute.  The first corresponds to
+<I>fsinfo_attr__nr</I>
+
+and the second to
+<I>fsinfo_cap__nr</I>
+
+in the header file.
+<P>
+
+<DT><B>fsinfo_attr_ids</B>
+
+<DD>
+This retrieves a number of fixed IDs and other static information otherwise
+available through
+<B>statfs</B>().
+
+The following structure is filled in:
+</DL>
+<P>
+
+<DL COMPACT><DT><DD>
+
+<PRE>
+struct fsinfo_ids {
+    char  f_fs_name[15 + 1]; /* Filesystem name */
+    __u64 f_flags;      /* Filesystem mount flags (MS_*) */
+    __u64 f_fsid;       /* Short 64-bit Filesystem ID */
+    __u64 f_sb_id;      /* Internal superblock ID */
+    __u32 f_fstype;     /* Filesystem type from linux/magic.h */
+    __u32 f_dev_major;  /* As st_dev_* from struct statx */
+    __u32 f_dev_minor;
+};
+</PRE>
+
+
+</DL>
+
+<DL COMPACT>
+<DT><DD>
+Most of these are filled in as for
+<B>statfs</B>(),
+
+with the addition of the filesystem's symbolic name in
+<I>f_fs_name</I>
+
+and an identifier for use in notifications in
+<I>f_sb_id</I>.
+
+<P>
+
+<DT><B>fsinfo_attr_limits</B>
+
+<DD>
+This retrieves information about the limits of what a filesystem can support.
+The following structure is filled in:
+</DL>
+<P>
+
+<DL COMPACT><DT><DD>
+
+<PRE>
+struct fsinfo_limits {
+    __u64 max_file_size;
+    __u64 max_uid;
+    __u64 max_gid;
+    __u64 max_projid;
+    __u32 max_dev_major;
+    __u32 max_dev_minor;
+    __u32 max_hard_links;
+    __u32 max_xattr_body_len;
+    __u16 max_xattr_name_len;
+    __u16 max_filename_len;
+    __u16 max_symlink_len;
+    __u16 __reserved[1];
+};
+</PRE>
+
+
+</DL>
+
+<DL COMPACT>
+<DT><DD>
+These indicate the maximum supported sizes for a variety of filesystem objects,
+including the file size, the extended attribute name length and body length,
+the filename length and the symlink body length.
+<DT><DD>
+It also indicates the maximum representable values for a User ID, a Group ID,
+a Project ID, a device major number and a device minor number.
+<DT><DD>
+And finally, it indicates the maximum number of hard links that can be made to
+a file.
+<DT><DD>
+Note that some of these values may be zero if the underlying object or concept
+is not supported by the filesystem or the medium.
+<P>
+
+<DT><B>fsinfo_attr_supports</B>
+
+<DD>
+This retrieves information about what bits a filesystem supports in various
+masks.  The following structure is filled in:
+</DL>
+<P>
+
+<DL COMPACT><DT><DD>
+
+<PRE>
+struct fsinfo_supports {
+    __u64 stx_attributes;
+    __u32 stx_mask;
+    __u32 ioc_flags;
+    __u32 win_file_attrs;
+    __u32 __reserved[1];
+};
+</PRE>
+
+
+</DL>
+
+<DL COMPACT>
+<DT><DD>
+The
+<I>stx_attributes</I> and <I>stx_mask</I>
+
+fields indicate what bits in the struct statx fields of the matching names
+are supported by the filesystem.
+<DT><DD>
+The
+<I>ioc_flags</I>
+
+field indicates what FS_*_FL flag bits as used through the FS_IOC_GET/SETFLAGS
+ioctls are supported by the filesystem.
+<DT><DD>
+The
+<I>win_file_attrs</I>
+
+indicates what DOS/Windows file attributes a filesystem supports, if any.
+<P>
+
+<DT><B>fsinfo_attr_capabilities</B>
+
+<DD>
+This retrieves information about what features a filesystem supports as a
+series of single bit indicators.  The following structure is filled in:
+</DL>
+<P>
+
+<DL COMPACT><DT><DD>
+
+<PRE>
+struct fsinfo_capabilities {
+    __u8 capabilities[(fsinfo_cap__nr + 7) / 8];
+};
+</PRE>
+
+
+</DL>
+
+<DL COMPACT>
+<DT><DD>
+where the bit of interest can be found by:
+</DL>
+<P>
+
+<DL COMPACT><DT><DD>
+
+<PRE>
+        p-&gt;capabilities[bit / 8] &amp; (1 &lt;&lt; (bit % 8)))
+</PRE>
+
+
+</DL>
+
+<DL COMPACT>
+<DT><DD>
+The bits are listed by
+<I>enum fsinfo_capability</I>
+
+and
+<B>fsinfo_cap__nr</B>
+
+is one more than the last capability bit listed in the header file.
+<DT><DD>
+Note that the number of capability bits actually supported by the kernel can be
+found using the
+<B>fsinfo_attr_fsinfo</B>
+
+attribute.
+<DT><DD>
+The capability bits and their meanings are listed below in the &quot;THE
+CAPABILITIES&quot; section.
+<P>
+
+<DT><B>fsinfo_attr_timestamp_info</B>
+
+<DD>
+This retrieves information about what timestamp resolution and scope is
+supported by a filesystem for each of the file timestamps.  The following
+structure is filled in:
+</DL>
+<P>
+
+<DL COMPACT><DT><DD>
+
+<PRE>
+struct fsinfo_timestamp_info {
+        __s64 minimum_timestamp;
+        __s64 maximum_timestamp;
+        __u16 atime_gran_mantissa;
+        __u16 btime_gran_mantissa;
+        __u16 ctime_gran_mantissa;
+        __u16 mtime_gran_mantissa;
+        __s8  atime_gran_exponent;
+        __s8  btime_gran_exponent;
+        __s8  ctime_gran_exponent;
+        __s8  mtime_gran_exponent;
+        __u32 __reserved[1];
+};
+</PRE>
+
+
+</DL>
+
+<DL COMPACT>
+<DT><DD>
+where
+<I>minimum_timestamp</I> and <I>maximum_timestamp</I>
+
+are the limits on the timestamps that the filesystem supports and
+<I>*time_gran_mantissa</I> and <I>*time_gran_exponent</I>
+
+indicate the granularity of each timestamp in terms of seconds, using the
+formula:
+</DL>
+<P>
+
+<DL COMPACT><DT><DD>
+
+<PRE>
+mantissa * pow(10, exponent) Seconds
+</PRE>
+
+
+</DL>
+
+<DL COMPACT>
+<DT><DD>
+where exponent may be negative and the result may be a fraction of a second.
+<DT><DD>
+Four timestamps are detailed: <B>A</B>ccess time, <B>B</B>irth/creation time,
+<B>C</B>hange time and <B>M</B>odification time.  Capability bits are defined
+that specify whether each of these exist in the filesystem or not.
+<DT><DD>
+Note that the timestamp description may be approximated or inaccurate if the
+file is actually remote or is the union of multiple objects.
+<P>
+
+<DT><B>fsinfo_attr_volume_id</B>
+
+<DD>
+This retrieves the system's superblock volume identifier as a variable-length
+string.  This does not necessarily represent a value stored in the medium but
+might be constructed on the fly.
+<DT><DD>
+For instance, for a block device this is the block device identifier
+(eg. &quot;sdb2&quot;); for AFS this would be the numeric volume identifier.
+<P>
+
+<DT><B>fsinfo_attr_volume_uuid</B>
+
+<DD>
+This retrieves the volume UUID, if there is one, as a little-endian binary
+UUID.  This fills in the following structure:
+</DL>
+<P>
+
+<DL COMPACT><DT><DD>
+
+<PRE>
+struct fsinfo_volume_uuid {
+    __u8 uuid[16];
+};
+</PRE>
+
+
+</DL>
+
+<DL COMPACT>
+<DT><DD>
+<P>
+
+<DT><B>fsinfo_attr_volume_name</B>
+
+<DD>
+This retrieves the filesystem's volume name as a variable-length string.  This
+is expected to represent a name stored in the medium.
+<DT><DD>
+For a block device, this might be a label stored in the superblock.  For a
+network filesystem, this might be a logical volume name of some sort.
+<P>
+
+</DL>
+<P>
+
+<B>fsinfo_attr_cell_name</B>
+
+<BR>
+
+<B>fsinfo_attr_domain_name</B>
+
+<BR>
+
+<DL COMPACT>
+<DT><DD>
+These two attributes are variable-length string attributes that may be used to
+obtain information about network filesystems.  An AFS volume, for instance,
+belongs to a named cell.  CIFS shares may belong to a domain.
+<P>
+
+<DT><B>fsinfo_attr_realm_name</B>
+
+<DD>
+This attribute is variable-length string that indicates the Kerberos realm that
+a filesystem's authentication tokens should come from.
+<P>
+
+<DT><B>fsinfo_attr_server_name</B>
+
+<DD>
+This attribute is a multiple-value attribute that lists the names of the
+servers that are backing a network filesystem.  Each value is a variable-length
+string.  The values are enumerated by calling
+<B>fsinfo</B>()
+
+multiple times, incrementing
+<I>params-&gt;Nth</I>
+
+each time until an ENODATA error occurs, thereby indicating the end of the
+list.
+<P>
+
+<DT><B>fsinfo_attr_server_address</B>
+
+<DD>
+This attribute is a multiple-instance, multiple-value attribute that lists the
+addresses of the servers that are backing a network filesystem.  Each value is
+a structure of the following type:
+</DL>
+<P>
+
+<DL COMPACT><DT><DD>
+
+<PRE>
+struct fsinfo_server_address {
+    struct __kernel_sockaddr_storage address;
+};
+</PRE>
+
+
+</DL>
+
+<DL COMPACT>
+<DT><DD>
+Where the address may be AF_INET, AF_INET6, AF_RXRPC or any other type as
+appropriate to the filesystem.
+<DT><DD>
+The values are enumerated by calling
+<I>fsinfo</I>()
+
+multiple times, incrementing
+<I>params-&gt;Nth</I>
+
+to step through the servers and
+<I>params-&gt;Mth</I>
+
+to step through the addresses of the Nth server each time until ENODATA errors
+occur, thereby indicating either the end of a server's address list or the end
+of the server list.
+<DT><DD>
+Barring the server list changing whilst being accessed, it is expected that the
+<I>params-&gt;Nth</I>
+
+will correspond to
+<I>params-&gt;Nth</I>
+
+for
+<B>fsinfo_attr_server_name</B>.
+
+<P>
+
+<DT><B>fsinfo_attr_parameter</B>
+
+<DD>
+This attribute is a multiple-value attribute that lists the values of the mount
+parameters for a filesystem as variable-length strings.
+<DT><DD>
+The parameters are enumerated by calling
+<B>fsinfo</B>()
+
+multiple times, incrementing
+<I>params-&gt;Nth</I>
+
+to step through them until error ENODATA is given.
+<DT><DD>
+Parameter strings are presented in a form akin to the way they're passed to the
+context created by the
+<B>fsopen</B>()
+
+system call.  For example, straight text parameters will be rendered as
+something like:
+</DL>
+<P>
+
+<DL COMPACT><DT><DD>
+
+<PRE>
+&quot;o data=journal&quot;
+&quot;o noquota&quot;
+</PRE>
+
+
+</DL>
+
+<DL COMPACT>
+<DT><DD>
+Where the initial &quot;word&quot; indicates the option form.
+<P>
+
+<DT><B>fsinfo_attr_source</B>
+
+<DD>
+This attribute is a multiple-value attribute that lists the mount sources for a
+filesystem as variable-length strings.  Normally only one source will be
+available, but the possibility of having more than one is allowed for.
+<DT><DD>
+The sources are enumerated by calling
+<B>fsinfo</B>()
+
+multiple times, incrementing
+<I>params-&gt;Nth</I>
+
+to step through them until error ENODATA is given.
+<DT><DD>
+Source strings are presented in a form akin to the way they're passed to the
+context created by the
+<B>fsopen</B>()
+
+system call.  For example, they will be rendered as something like:
+</DL>
+<P>
+
+<DL COMPACT><DT><DD>
+
+<PRE>
+&quot;s /dev/sda1&quot;
+&quot;s example.com/pub/linux/&quot;
+</PRE>
+
+
+</DL>
+
+<DL COMPACT>
+<DT><DD>
+Where the initial &quot;word&quot; indicates the option form.
+<P>
+
+<DT><B>fsinfo_attr_name_encoding</B>
+
+<DD>
+This attribute is variable-length string that indicates the filename encoding
+used by the filesystem.  The default is &quot;utf8&quot;.  Note that this may indicate a
+non-8-bit encoding if that's what the underlying filesystem actually supports.
+<P>
+
+<DT><B>fsinfo_attr_name_codepage</B>
+
+<DD>
+This attribute is variable-length string that indicates the codepage used to
+translate filenames from the filesystem to the system if this is applicable to
+the filesystem.
+<P>
+
+<DT><B>fsinfo_attr_io_size</B>
+
+<DD>
+This retrieves information about the I/O sizes supported by the filesystem.
+The following structure is filled in:
+</DL>
+<P>
+
+<DL COMPACT><DT><DD>
+
+<PRE>
+struct fsinfo_io_size {
+    __u32 block_size;
+    __u32 max_single_read_size;
+    __u32 max_single_write_size;
+    __u32 best_read_size;
+    __u32 best_write_size;
+};
+</PRE>
+
+
+</DL>
+
+<DL COMPACT>
+<DT><DD>
+Where
+<I>block_size</I>
+
+indicates the fundamental I/O block size of the filesystem as something
+O_DIRECT read/write sizes must be a multiple of;
+<I>max_single_write_size</I> and <I>max_single_write_size</I>
+
+indicate the maximum sizes for individual unbuffered data transfer operations;
+and
+<I>best_read_size</I> and <I>best_write_size</I>
+
+indicate the recommended I/O sizes.
+<DT><DD>
+Note that any of these may be zero if inapplicable or indeterminable.
+<P>
+<P>
+<P>
+</DL>
+<A NAME="lbAH">&nbsp;</A>
+<H2>THE CAPABILITIES</H2>
+
+<P>
+
+There are number of capability bits in a bit array that can be retrieved using
+<B>fsinfo_attr_capabilities</B>.
+
+These give information about features of the filesystem driver and the specific
+filesystem.
+<P>
+
+<P>
+
+<B>fsinfo_cap_is_kernel_fs</B>
+
+<BR>
+
+<B>fsinfo_cap_is_block_fs</B>
+
+<BR>
+
+<B>fsinfo_cap_is_flash_fs</B>
+
+<BR>
+
+<B>fsinfo_cap_is_network_fs</B>
+
+<BR>
+
+<B>fsinfo_cap_is_automounter_fs</B>
+
+<DL COMPACT>
+<DT><DD>
+These indicate the primary type of the filesystem.
+<B>kernel</B>
+
+filesystems are special communication interfaces that substitute files for
+system calls; examples include procfs and sysfs.
+<B>block</B>
+
+filesystems require a block device on which to operate; examples include ext4
+and XFS.
+<B>flash</B>
+
+filesystems require an MTD device on which to operate; examples include JFFS2.
+<B>network</B>
+
+filesystems require access to the network and contact one or more servers;
+examples include NFS and AFS.
+<B>automounter</B>
+
+filesystems are kernel special filesystems that host automount points and
+triggers to dynamically create automount points.  Examples include autofs and
+AFS's dynamic root.
+<P>
+
+<DT><B>fsinfo_cap_automounts</B>
+
+<DD>
+The filesystem may have automount points that can be triggered by pathwalk.
+<P>
+
+<DT><B>fsinfo_cap_adv_locks</B>
+
+<DD>
+The filesystem supports advisory file locks.  For a network filesystem, this
+indicates that the advisory file locks are cross-client (and also between
+server and its local filesystem on something like NFS).
+<P>
+
+<DT><B>fsinfo_cap_mand_locks</B>
+
+<DD>
+The filesystem supports mandatory file locks.  For a network filesystem, this
+indicates that the mandatory file locks are cross-client (and also between
+server and its local filesystem on something like NFS).
+<P>
+
+<DT><B>fsinfo_cap_leases</B>
+
+<DD>
+The filesystem supports leases.  For a network filesystem, this means that the
+server will tell the client to clean up its state on a file before passing the
+lease to another client.
+<P>
+
+</DL>
+<P>
+
+<B>fsinfo_cap_uids</B>
+
+<BR>
+
+<B>fsinfo_cap_gids</B>
+
+<BR>
+
+<B>fsinfo_cap_projids</B>
+
+<DL COMPACT>
+<DT><DD>
+These indicate that the filesystem supports numeric user IDs, group IDs and
+project IDs respectively.
+<P>
+
+</DL>
+<P>
+
+<B>fsinfo_cap_id_names</B>
+
+<BR>
+
+<B>fsinfo_cap_id_guids</B>
+
+<DL COMPACT>
+<DT><DD>
+These indicate that the filesystem employs textual names and/or GUIDs as
+identifiers.
+<P>
+
+<DT><B>fsinfo_cap_windows_attrs</B>
+
+<DD>
+Indicates that the filesystem supports some Windows FILE_* attributes.
+<P>
+
+</DL>
+<P>
+
+<B>fsinfo_cap_user_quotas</B>
+
+<BR>
+
+<B>fsinfo_cap_group_quotas</B>
+
+<BR>
+
+<B>fsinfo_cap_project_quotas</B>
+
+<DL COMPACT>
+<DT><DD>
+These indicate that the filesystem supports quotas for users, groups and
+projects respectively.
+<P>
+
+</DL>
+<P>
+
+<B>fsinfo_cap_xattrs</B>
+
+<BR>
+
+<B>fsinfo_cap_symlinks</B>
+
+<BR>
+
+<B>fsinfo_cap_hard_links</B>
+
+<BR>
+
+<B>fsinfo_cap_hard_links_1dir</B>
+
+<BR>
+
+<B>fsinfo_cap_device_files</B>
+
+<BR>
+
+<B>fsinfo_cap_unix_specials</B>
+
+<DL COMPACT>
+<DT><DD>
+These indicate that the filesystem supports respectively extended attributes;
+symbolic links; hard links spanning direcories; hard links, but only within a
+directory; block and character device files; and UNIX special files, such as
+FIFO and socket.
+<P>
+
+</DL>
+<P>
+
+<B>fsinfo_cap_journal</B>
+
+<BR>
+
+<B>fsinfo_cap_data_is_journalled</B>
+
+<DL COMPACT>
+<DT><DD>
+The first of these indicates that the filesystem has a journal and the second
+that the file data changes are being journalled.
+<P>
+
+</DL>
+<P>
+
+<B>fsinfo_cap_o_sync</B>
+
+<BR>
+
+<B>fsinfo_cap_o_direct</B>
+
+<DL COMPACT>
+<DT><DD>
+These indicate that O_SYNC and O_DIRECT are supported respectively.
+<P>
+
+</DL>
+<P>
+
+<B>fsinfo_cap_volume_id</B>
+
+<BR>
+
+<B>fsinfo_cap_volume_uuid</B>
+
+<BR>
+
+<B>fsinfo_cap_volume_name</B>
+
+<BR>
+
+<B>fsinfo_cap_volume_fsid</B>
+
+<BR>
+
+<B>fsinfo_cap_cell_name</B>
+
+<BR>
+
+<B>fsinfo_cap_domain_name</B>
+
+<BR>
+
+<B>fsinfo_cap_realm_name</B>
+
+<DL COMPACT>
+<DT><DD>
+These indicate if various attributes are supported by the filesystem, where
+<B>fsinfo_cap_X</B>
+
+here corresponds to
+<B>fsinfo_attr_X</B>.
+
+<P>
+
+</DL>
+<P>
+
+<B>fsinfo_cap_iver_all_change</B>
+
+<BR>
+
+<B>fsinfo_cap_iver_data_change</B>
+
+<BR>
+
+<B>fsinfo_cap_iver_mono_incr</B>
+
+<DL COMPACT>
+<DT><DD>
+These indicate if
+<I>i_version</I>
+
+on an inode in the filesystem is supported and
+how it behaves.
+<B>all_change</B>
+
+indicates that i_version is incremented on metadata changes as well as data
+changes.
+<B>data_change</B>
+
+indicates that i_version is only incremented on data changes, including
+truncation.
+<B>mono_incr</B>
+
+indicates that i_version is incremented by exactly 1 for each change made.
+<P>
+
+<DT><B>fsinfo_cap_resource_forks</B>
+
+<DD>
+This indicates that the filesystem supports some sort of resource fork or
+alternate data stream on a file.  This isn't the same as an extended attribute.
+<P>
+
+</DL>
+<P>
+
+<B>fsinfo_cap_name_case_indep</B>
+
+<BR>
+
+<B>fsinfo_cap_name_non_utf8</B>
+
+<BR>
+
+<B>fsinfo_cap_name_has_codepage</B>
+
+<DL COMPACT>
+<DT><DD>
+These indicate certain facts about the filenames in a filesystem: whether
+they're case-independent; if they're not UTF-8; and if there's a codepage
+employed to map the names.
+<P>
+
+<DT><B>fsinfo_cap_sparse</B>
+
+<DD>
+This indicates that the filesystem supports sparse files.
+<P>
+
+<DT><B>fsinfo_cap_not_persistent</B>
+
+<DD>
+This indicates that the filesystem is not persistent, and that any data stored
+here will not be saved in the event that the filesystem is unmounted, the
+machine is rebooted or the machine loses power.
+<P>
+
+<DT><B>fsinfo_cap_no_unix_mode</B>
+
+<DD>
+This indicates that the filesystem doesn't support the UNIX mode permissions
+bits.
+<P>
+
+</DL>
+<P>
+
+<B>fsinfo_cap_has_atime</B>
+
+<BR>
+
+<B>fsinfo_cap_has_btime</B>
+
+<BR>
+
+<B>fsinfo_cap_has_ctime</B>
+
+<BR>
+
+<B>fsinfo_cap_has_mtime</B>
+
+<DL COMPACT>
+<DT><DD>
+These indicate as to what timestamps a filesystem supports, including: Access
+time, Birth/creation time, Change time (metadata and data) and Modification
+time (data only).
+<P>
+<P>
+
+
+
+</DL>
+<A NAME="lbAI">&nbsp;</A>
+<H2>RETURN VALUE</H2>
+
+On success, the size of the value that the kernel has available is returned,
+irrespective of whether the buffer is large enough to hold that.  The data
+written to the buffer will be truncated if it is not.  On error, -1 is
+returned, and
+<I>errno</I>
+
+is set appropriately.
+<A NAME="lbAJ">&nbsp;</A>
+<H2>ERRORS</H2>
+
+<DL COMPACT>
+<DT><B>EACCES</B>
+
+<DD>
+Search permission is denied for one of the directories
+in the path prefix of
+<I>pathname</I>.
+
+(See also
+<B><A HREF="/man/man2html?7+path_resolution">path_resolution</A></B>(7).)
+
+<DT><B>EBADF</B>
+
+<DD>
+<I>dirfd</I>
+
+is not a valid open file descriptor.
+<DT><B>EFAULT</B>
+
+<DD>
+<I>pathname</I>
+
+is NULL or
+<I>pathname</I>, <I>params</I> or <I>buffer</I>
+
+point to a location outside the process's accessible address space.
+<DT><B>EINVAL</B>
+
+<DD>
+Reserved flag specified in
+<I>params-&gt;at_flags</I> or one of <I>params-&gt;__reserved[]</I>
+
+is not 0.
+<DT><B>EOPNOTSUPP</B>
+
+<DD>
+Unsupported attribute requested in
+<I>params-&gt;request</I>.
+
+This may be beyond the limit of the supported attribute set or may just not be
+one that's supported by the filesystem.
+<DT><B>ENODATA</B>
+
+<DD>
+Unavailable attribute value requested by
+<I>params-&gt;Nth</I> and/or <I>params-&gt;Mth</I>.
+
+<DT><B>ELOOP</B>
+
+<DD>
+Too many symbolic links encountered while traversing the pathname.
+<DT><B>ENAMETOOLONG</B>
+
+<DD>
+<I>pathname</I>
+
+is too long.
+<DT><B>ENOENT</B>
+
+<DD>
+A component of
+<I>pathname</I>
+
+does not exist, or
+<I>pathname</I>
+
+is an empty string and
+<B>AT_EMPTY_PATH</B>
+
+was not specified in
+<I>params-&gt;at_flags</I>.
+
+<DT><B>ENOMEM</B>
+
+<DD>
+Out of memory (i.e., kernel memory).
+<DT><B>ENOTDIR</B>
+
+<DD>
+A component of the path prefix of
+<I>pathname</I>
+
+is not a directory or
+<I>pathname</I>
+
+is relative and
+<I>dirfd</I>
+
+is a file descriptor referring to a file other than a directory.
+</DL>
+<A NAME="lbAK">&nbsp;</A>
+<H2>VERSIONS</H2>
+
+<B>fsinfo</B>()
+
+was added to Linux in kernel 4.18.
+<A NAME="lbAL">&nbsp;</A>
+<H2>CONFORMING TO</H2>
+
+<B>fsinfo</B>()
+
+is Linux-specific.
+<A NAME="lbAM">&nbsp;</A>
+<H2>NOTES</H2>
+
+Glibc does not (yet) provide a wrapper for the
+<B>fsinfo</B>()
+
+system call; call it using
+<B><A HREF="/man/man2html?2+syscall">syscall</A></B>(2).
+
+<A NAME="lbAN">&nbsp;</A>
+<H2>SEE ALSO</H2>
+
+<B><A HREF="/man/man2html?2+ioctl_iflags">ioctl_iflags</A></B>(2),
+
+<B><A HREF="/man/man2html?2+statx">statx</A></B>(2),
+
+<B><A HREF="/man/man2html?2+statfs">statfs</A></B>(2)
+
+<P>
+
+<HR>
+<A NAME="index">&nbsp;</A><H2>Index</H2>
+<DL>
+<DT><A HREF="#lbAB">NAME</A><DD>
+<DT><A HREF="#lbAC">SYNOPSIS</A><DD>
+<DT><A HREF="#lbAD">DESCRIPTION</A><DD>
+<DL>
+<DT><A HREF="#lbAE">Allowance for Future Attribute Expansion</A><DD>
+<DT><A HREF="#lbAF">Invoking <B>fsinfo</B>():</A><DD>
+</DL>
+<DT><A HREF="#lbAG">THE ATTRIBUTES</A><DD>
+<DT><A HREF="#lbAH">THE CAPABILITIES</A><DD>
+<DT><A HREF="#lbAI">RETURN VALUE</A><DD>
+<DT><A HREF="#lbAJ">ERRORS</A><DD>
+<DT><A HREF="#lbAK">VERSIONS</A><DD>
+<DT><A HREF="#lbAL">CONFORMING TO</A><DD>
+<DT><A HREF="#lbAM">NOTES</A><DD>
+<DT><A HREF="#lbAN">SEE ALSO</A><DD>
+</DL>
+<HR>
+This document was created by
+<A HREF="/man/man2html">man2html</A>,
+using the manual pages.<BR>
+Time: 21:25:28 GMT, June 18, 2018
+</BODY>
+</HTML>
diff --git a/index.html b/index.html
new file mode 100644 (file)
index 0000000..c786a54
--- /dev/null
@@ -0,0 +1,369 @@
+<!DOCTYPE html>
+<HTML>
+  <HEAD>
+    <TITLE>kAFS and AF_RXRPC</TITLE>
+  </HEAD>
+  <BODY>
+    <MAIN>
+      <H1>kAFS and AF_RXRPC</H1>
+
+      <!--
+      <TABLE border=0>
+       <TR>
+         <TD bgcolor="black">
+           &nbsp;
+         </TD>
+         <TD bgcolor="lightgreen">
+             <H2>Linux kernel AFS (kAFS) Hackathon and BoF at USENIX Vault '20</H2>
+             <P>
+               <BIG>
+                 AFS and Linux kernel developers are invited to attend the
+                 <A href="https://www.auristor.com/events/kafsvault20">third
+                   Linux kernel AFS (kAFS) Hackathon and Birds of a Feather
+                   meeting</A>, sponsored
+                   by <A href="https://www.auristor.com/">AuriStor, Inc.</A>.
+               </BIG>
+             <P>
+               <BIG>
+                 The hackathon and BoF will be co-located with the
+                 <A href="https://www.usenix.org/conference/vault20">USENIX
+                   Vault '20</A> - Linux Storage and Filesystems Conference.
+               </BIG>
+             </P>
+         </TD>
+       </TR>
+      </TABLE>
+      -->
+
+      <H2>Introduction</H2>
+      <TEXT>
+       <P>
+         The primary goal of the <U>kAFS</U> project is to provide a
+         filesystem within the Linux kernel that can communicate with an AFS
+         server to the same extent
+         that <A href="https://www.openafs.org">OpenAFS</A> can and, as such,
+         can be a drop-in replacement for OpenAFS on the Linux platform.  With
+         the sources being in the upstream Linux kernel, kAFS can take
+         advantage of GPL-only kernel APIs and can be fixed up by people
+         wanting to make wholesale VFS interface changes.
+       <P>
+         kAFS comprises four in-kernel components:
+       </P>
+       <UL>
+         <LI>
+           <B><A href="#kafs">kAFS</A></B> itself.  This is a network
+           filesystem that's used in much the same way as any other network
+           filesystem provided by the Linux kernel, such as NFS.
+         <LI>
+           <B><A href="#af_rxrpc">AF_RXRPC</A></B>.  This is a network
+           protocol that provides the network interface for kAFS to use and
+           also offers userspace access via the socket interface.
+         <LI>
+           <B><A href="#keyrings">Kernel keyrings</A></B>.  This facility's
+           primary purpose is to retain and manage the authentication tokens
+           used by kAFS and AF_RXRPC, though it has been kept generic enough
+           that it has been adapted to a variety of roles within the kernel.
+         <LI>
+           <B><A href="#fscache">FS-Cache</A></B>.  This is an interface layer
+           acts as a broker between any network filesystem and local storage,
+           allowing retrieved data to be cached.  It can be used with NFS,
+           CIFS, Plan9 and Ceph in addition to kAFS.
+       </UL>
+       <P>
+         and three userspace components:
+       </P>
+       <UL>
+         <LI>
+           <B><A href="#kafs-client">kafs-client</A></B>.  This will be the
+           configuration and systemd integration for automatically mounting
+           the kAFS filesystem and tools for managing authentication.
+         <LI>
+           <B><A href="#kafs-utils">kafs-utils</A></B>.  This is a suite of
+           AFS management tools, written in Python3, that use AF_RXRPC from
+           userspace as a transport to communicate with a server.
+         <LI>
+           <B><A href="#keyrings">keyutils</A></B>.  This is a set of
+           utilities for manipulating the keyrings facility from userspace.
+       </UL>
+       <P>
+         A TODO list can be found <A href="todo.html">here</A>.
+       </P>
+      </TEXT>
+
+      <!-- #################################################################################### -->
+      <!-- #################################################################################### -->
+      <!-- #################################################################################### -->
+      <!-- kAFS -->
+      <H2><A name="kafs"><A name="kafs">kAFS</A></H2>
+      <TEXT>
+       <P>
+         The kAFS filesystem is a Linux filesystem for accessing AFS servers
+         over the network.  It is mounted using something like the following:
+       </P>
+       <CODE><PRE>
+           insmod /tmp/kafs.ko
+           echo grand.central.org &gt;/proc/fs/afs/rootcell
+           mount -t afs none /afs -o dyn</PRE></CODE>
+       Or to mount a specific volume:
+       <CODE><PRE>
+           mount -t afs "#grand.central.org:root.cell." /mnt</PRE></CODE>
+       <P>
+         Implemented features:
+       </P>
+       <UL>
+         <LI>Reading and writing.
+         <LI>Advisory file locking.
+         <LI>Encryption and authentication.
+         <LI>Automounting of mountpoints.
+         <LI>Failover.
+         <LI>AFSDB and SRV DNS record lookup.
+         <LI>Handle volumes being moved or being busy.
+         <LI>Path substitution (<CODE>@sys</CODE> and <CODE>@cell</CODE>).
+         <LI>IPv6 support, thus allowing access to
+           current <A href="https://www.auristor.com/">AuriStor<A> servers.
+         <LI>Kernel tracepoints.
+       </UL>
+       <P>
+         Features that need to be added:
+       </P>
+       <UL>
+         <LI>Network namespacing.
+         <LI>Notifications (inotify and friends).
+         <LI><A href="user_interface.html">Userspace tool interface</A> (substitute for pioctl).
+       </UL>
+       <P>
+         Features that could be added:
+       </P>
+       <UL>
+         <LI><CODE>RXAFSCB</CODE> RPCs for debugging.  Have to be careful of
+         this is it can be a security problem, but it could require encryption
+         to access.
+       </UL>
+       <P>
+         The kAFS filesystem sources are integrated into the upstream Linux
+         kernel
+         <A href="http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/afs">
+           here</A>
+       </P>
+      </TEXT>
+
+      <!-- #################################################################################### -->
+      <!-- #################################################################################### -->
+      <!-- #################################################################################### -->
+      <!-- AF_RXRPC -->
+      <H2><A name="af_rxrpc">AF_RXRPC</A></H2>
+      <TEXT>
+       <P>
+         The AF_RXRPC network protocol is the network transport for RX on
+         behalf of the kAFS program and the Python tools.  It opens UDP
+         sockets internally and exchanges network packets with peers over it.
+       <P>
+         An open AF_RXRPC socket can support multiple calls to different
+         peers, both service calls and client calls.
+         The <CODE>sendmsg()</CODE> and <CODE>recvmsg()</CODE> system calls
+         are used with the ancillary data being used to manage the
+         multiplexing and to pass information.
+       <P>
+         The kernel handles all the RX protocol metadata internally so that
+         the user only sees the content data.  This allows virtual
+         connections to be shared transparently between userspace processes.
+       <P>
+         Implemented features:
+       </P>
+       <UL>
+         <LI>Usable from userspace via <CODE>socket(AF_RXRPC, ...)</CODE>.
+         <LI>Supports client and server calls over the same socket.
+         <LI>Kauth, Kerberos 4 and Kerberos 5 security; plain, partial and
+           full encryption.
+         <LI>IPv6 support.
+         <LI>Kernel tracepoints.
+         <LI>Slow start congestion management.
+         <LI>Service upgrade.
+       </UL>
+       <P>
+         Features that need to be added:
+       </P>
+       <UL>
+         <LI>RXGK security.
+         <LI>YFS-RXGK security.
+       </UL>
+       <P>
+         Features that could be added:
+       </P>
+       <UL>
+         <LI>Debug and stat packet support.  These are a potential security
+         hole as there's no encryption on them.  It might be possible to limit
+         access to these using netfilter - or just provide the information
+         through /proc in userspace and let anyone who wishes to read it do
+         so, provided they can log in to the system.
+       </UL>
+       <P>
+         The AF_RXRPC sources are integrated into the upstream Linux kernel
+         <A href="http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/net/rxrpc">
+           here</A>.
+       </P>
+       <P>
+         An example client built using AF_RXRPC can be found
+         <A href="af_rxrpc_client.html">here</A>.
+       </P>
+      </TEXT>
+
+      <!-- #################################################################################### -->
+      <!-- #################################################################################### -->
+      <!-- #################################################################################### -->
+      <!-- keyrings -->
+      <H2><A name="keyrings">Kernel Keyrings and keyutils</A></H2>
+      <TEXT>
+       <P>
+         The kernel keyrings facility was created to carry tokens for kAFS
+         and AF_RXRPC to identify and authenticate a user with the various
+         servers and to provide cryptographic keys for the network transport.
+         PAGs are not available, rather the session keyring to which a
+         process subscribes is the container for these keys.
+       <P>
+         Keys and keyrings can be manipulated by users to a certain extent,
+         including adding and deleting keys, though security features exist
+         to control a user's access.
+       <P>
+         The PAM package and the keyutils package are the main keyring
+         manipulators.
+       <P>
+         Looking in <CODE>/proc/keys</CODE> something like the following
+         would appear:
+       </P>
+       <CODE><PRE>
+       396198eb I--Q---     1   1d 3b010000     0     0 rxrpc     afs@your.cell.com</PRE></CODE>
+       <P>
+         The current process's session keyring can be listed to see the
+         kAFS/AF_RXRPC keys applicable to processes run under a shell:
+       </P>
+       <CODE><PRE>
+       [root@andromeda ~]# keyctl show @s
+       Keyring
+        340802050 --alswrv      0     0  keyring: _ses
+        566823513 --alswrv      0 65534   \_ keyring: _uid.0
+        962697451 --als-rv      0     0   \_ rxrpc: afs@your-file-system.com</PRE></CODE>
+               <P>
+         kAFS and AF_RXRPC clients will pick up the appropriate rxrpc-type key
+         automatically by name and use it if it is available.
+               </P>
+               <P>
+         The kernel keyrings sources are integrated into the upstream Linux
+         kernel primarily
+         <A href="http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/security/keys">
+           here</A> and
+         <A href="http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/security/keys.txt">
+           here</A>.
+       <P>
+         The keyutils utility sources can be found
+         <A href="http://git.kernel.org/cgit/linux/kernel/git/dhowells/keyutils.git">here</A>
+       </P>
+      </TEXT>
+
+      <!-- #################################################################################### -->
+      <!-- #################################################################################### -->
+      <!-- #################################################################################### -->
+      <!-- fscache -->
+      <H2><A name="fscache">FS-Cache</A></H2>
+      <TEXT>
+       <P>
+         The FS-Cache kernel module is a thin layer between any network
+         filesystem and a cache.  There is one caching back-end available
+         (CacheFiles) that uses one disk file per network filesystem file to
+         store data.
+       <P>
+         Supported features:
+       </P>
+       <UL>
+         <LI>Persistent across reboots.
+         <LI>Usable by multiple filesystems: AFS, NFS, CIFS, Plan9, Ceph.
+         <LI>Transparent.
+       </UL>
+       <P>
+         Features that need to be added:
+       </P>
+       <UL>
+         <LI>Kernel tracepoints.
+         <LI>More tuning knobs.
+         <LI>Backends to make use of non-rotating cache media.
+       </UL>
+       <P>
+         Features that would be nice:
+       </P>
+       <UL>
+         <LI>Disconnected operation support (requires netfs integration).
+       </UL>
+       <P>
+         The FS-Cache sources are integrated into the upstream Linux kernel
+         <A href="http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/fscache">
+           here</A>
+       </P>
+      </TEXT>
+
+      <!-- #################################################################################### -->
+      <!-- #################################################################################### -->
+      <!-- #################################################################################### -->
+      <!-- kafs-client -->
+      <H2><A name="kafs-client">kafs-client</A></H2>
+      <TEXT>
+       <P>
+         The <A href="kafs_client.html">kafs-client</A>
+         package will be the tools to configure and mount the kAFS filesystem
+         and provide <I>systemd</I>integration.  It will also provide
+         authentications support through <I>aklog</I> and <I>PAM</I>
+         integration.
+       </P>
+      </TEXT>
+
+      <!-- #################################################################################### -->
+      <!-- #################################################################################### -->
+      <!-- #################################################################################### -->
+      <!-- kafs-utils -->
+      <H2><A name="kafs-utils">kafs-utils</A></H2>
+      <TEXT>
+       <P>
+         The <A href="kafs_utils.html">kafs-utils</A> suite is a replacement
+         for bos, vos, pts and co. written in v3 Python, utilising AF_RXRPC to
+         provide the transport.
+       <P>
+         Implemented features:
+       </P>
+       <UL>
+         <LI>Parameter, input and output equivalence with OpenAFS for use with
+           existing scripts.
+         <LI>Bash completion.
+         <LI>Two layers, the command suite applications and wrappers for the raw RPC
+           calls.
+         <LI>Some command/subcommands are supported, including most of bos and pts and
+           some of vos.
+       </UL>
+       <P>
+         Features that need to be added:
+       </P>
+       <UL>
+         <LI><A href="user_interface.html">Kernel interface</A> (substitute for pioctl).
+         <LI>The rest of the commands and subcommands.
+         <LI>The ability to use other transports than AF_RXRPC.
+         <LI>Two more layers within the library to abstract some of the RPCs.
+         <LI>User scripting support so that users and admins can use this to write
+           scripts directly in Python.
+         <LI>Better error processing.
+       </UL>
+       <P>
+         Features that would be nice to have.
+       </P>
+       <UL>
+         <LI>Python 2 support.
+         <LI>The ability to talk to other AFS kernel modules, such as OpenAFS and
+           Auristor.
+       </UL>
+       <P>
+         The kafs-utils sources can be found
+         <A href="http://git.infradead.org/users/dhowells/kafs-utils.git">here</A>
+       </P>
+      </TEXT>
+
+
+    </MAIN>
+  </BODY>
+</HTML>
diff --git a/kafs_client.html b/kafs_client.html
new file mode 100644 (file)
index 0000000..664ec77
--- /dev/null
@@ -0,0 +1,134 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+   "http://www.w3.org/TR/html4/strict.dtd">
+<HTML>
+  <STYLE type="text/css">
+    P.example { color: blue; margin-left: 40px }
+    CODE.example { color: blue }
+  </STYLE>
+  <HEAD>
+    <TITLE>kafs-client</TITLE>
+  </HEAD>
+  <BODY>
+    <HEADER>
+    </HEADER>
+    <MAIN>
+      <H1>kAFS Client</H1>
+      <TEXT>
+       <P>
+         The <I>kafs-client</I> package provides the following features:
+       </P>
+       <UL>
+         <LI>
+           <I>systemd</I> integration:
+           <UL>
+             <LI>
+               Automatic loading of the client configuration,
+               including <CODE>@sys</CODE> and <CODE>@cell</CODE>.
+             <LI>
+               Automatic loading of the <I>cellservdb</I> to fill out the list
+               of cells in the dynamic root.
+             <LI>
+               Automatic mounting on <CODE>/afs</CODE>.
+           </UL>
+         <LI>
+           AFS DNS upcall handling, drawing on multiple sources:
+           <UL>
+             <LI>
+               SRV records.
+             <LI>
+               AFSDB records.
+             <LI>
+               Static cellservdb configuration.
+           </UL>
+           Both IPv4 and IPv6 are supported.  This
+           requires <I>keyutils-1.6</I> or better.
+         <LI>
+           Authentication/log-on support:
+           <UL>
+             <LI>
+               <CODE>aklog-kafs</CODE>.
+             <LI>
+               In the future, it will provide <I>PAM</I> integration too.
+           </UL>
+       </UL>
+       <P>
+         The sources can be found in a
+         git repository <A href="http://git.infradead.org/users/dhowells/kafs-client.git">here</A>.
+       </P>
+      </TEXT>
+
+
+      <H2><I>systemd</I> Integration</H2>
+      <TEXT>
+       <P>
+         Two systemd unit files are provided.  The
+         first, <CODE>kafs-config.service</CODE> loads the configuration into
+         the kernel.  This is a one-shot service normally executed as a
+         dependency of the second unit.  The second
+         unit, <CODE>afs.mount</CODE> mounts a dynamic root onto
+         <CODE>/afs</CODE>.  This starts off inactive, but can be started once
+         with:
+       <P class="example">
+         <CODE>systemctl start afs.mount</CODE>
+       <P>
+         and enabled for automatic start on boot with:
+       <P class="example">
+         <CODE>systemctl enable afs.mount</CODE>
+       </P>
+      </TEXT>
+
+
+      <H2>Configuration</H2>
+      <TEXT>
+       <P>
+         Configuration files for <I>kafs-client</I> can be found in
+         the <CODE>/etc/kafs/</CODE> directory.  In there is
+         a <CODE>client.conf</CODE> file that the code actually reads and
+         a <CODE>client.d/</CODE> directory into which the administrator can
+         place configuration.  <CODE>client.conf</CODE> simply parses the
+         contents of the directory first and then the
+         standard <I>cellservdb</I> file.  The format of the files follows the
+         MIT Kerberos profile file form.
+       <P>
+         As an example, a local configuration could be supplied in a file
+         in <CODE>client.d/local.conf</CODE> looking something like the
+         following:
+       <P>
+         <CODE class="example"><PRE>
+       [defaults]
+       thiscell = my.afs.cell
+       sysname = fedora28_x86 amd64_linux
+
+       [cells]
+       my.afs.cell = {
+               use_dns = no
+               servers = {
+                       server1.afs.cell = {
+                               address = 1111:2222:3333:4444:5555:6666:7777:8888
+                               address = 1.2.3.4
+                       }
+               }
+       }</PRE>
+         </CODE>
+       <P>
+         The configuration can be checked and queried with
+         the <CODE>kafs-check-config</CODE> tool.
+       </P>
+      </TEXT>
+
+
+      <H2>Authentication</H2>
+      <TEXT>
+       <P>
+         Authentication tokens can be obtained by getting a kerberos TGT, say
+         with <I>kinit</I>, and then calling the <CODE>aklog-kafs</CODE>
+         program to obtain a ticket from that.
+       <P class="example">
+         <CODE>aklog-kafs my.afs.cell</CODE>
+       <P>
+         If the compat package is installed, this provides a synonym
+         of <CODE>aklog</CODE> for the <CODE>aklog-kafs</CODE> program.
+      </TEXT>
+    </MAIN>
+  </BODY>
+</HTML>
diff --git a/kafs_utils.html b/kafs_utils.html
new file mode 100644 (file)
index 0000000..3fe918c
--- /dev/null
@@ -0,0 +1,343 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+   "http://www.w3.org/TR/html4/strict.dtd">
+<HTML>
+  <STYLE type="text/css">
+    CODE.example { color: blue }
+    TABLE.arch {
+       border-collapse: collapse;
+       border: 0px solid #aaa;
+       margin: 1em 0;
+    }
+    TABLE.arch > tr > th, TABLE.arch > tr > td {
+       padding: 0.8em 2em;
+       vertical-align: center;
+    }
+    TD.arch_diagram_yes {
+       background-color: #d2d2f2;
+       border: 1px solid #aaa;
+       padding: 0.8em 2em;
+       text-align: center;
+    }
+    TD.arch_diagram_done {
+       background-color: #f2a2a2;
+       border: 1px solid #aaa;
+       padding: 0.8em 2em;
+       text-align: center;
+    }
+    TD.arch_diagram_no {
+       background-color: #f2f2f2;
+       border: 1px solid #aaa;
+       padding: 0.8em 2em;
+       text-align: center;
+    }
+    TABLE.arch > tbody > tr > th {
+       padding: 0.2em 0.4em;
+       font-weight: normal;
+       text-align: left;
+    }
+  </STYLE>
+  <HEAD>
+    <TITLE>kafs-utils</TITLE>
+  </HEAD>
+  <BODY>
+    <HEADER>
+    </HEADER>
+    <MAIN>
+      <H1>kAFS Utilities</H1>
+      <TEXT>
+       <P>
+         The <A href="http://git.infradead.org/users/dhowells/kafs-utils.git"><I>kafs-utils</I></A>
+         suite is a replacement
+         for <CODE>bos</CODE>, <CODE>vos</CODE>, <CODE>pts</CODE>, etc.,
+         utilising AF_RXRPC to provide the transport.  The library is written
+         in C, and language bindings will be provided on top to allow
+         languages such as Python to be used for scripting.
+       </P>
+      </TEXT>
+      <H2>Architecture</H2>
+      <TEXT>
+       <P>
+         The utilities are intended to have the following internal
+         architecture:
+       </P>
+       <TABLE class="arch">
+         <TR>
+           <TH>
+             <I>Application</I>
+           </TH>
+           <TD class="arch_diagram_yes" colspan=2>
+             AFS standard tools
+           <TD class="arch_diagram_no" colspan=2>
+             Python language bindings
+           </TD>
+         <TR>
+           <TH>
+             <I>Layer 4</I>
+           </TH>
+           <TD class="arch_diagram_no" colspan=6>
+             High-level utility library
+           </TD>
+         <TR>
+           <TH>
+             <I>Layer 3</I>
+           </TH>
+           <TD class="arch_diagram_no" colspan=3>
+             Mid-level RPC abstraction library
+           <TD class="arch_diagram_no" colspan=3 rowspan=2>
+             AFS filesystem query interface
+           </TD>
+         <TR>
+           <TH>
+             <I>Layer 2</I>
+           </TH>
+           <TD class="arch_diagram_yes" colspan=3>
+             Autogenerated RPC calls
+           </TD>
+         <TR>
+           <TH>
+             <I>Layer 1</I>
+           </TH>
+           <TD class="arch_diagram_no" colspan=3>
+             Pluggable transport interface
+           <TD class="arch_diagram_no" colspan=3>
+             Pluggable query interface
+           </TD>
+         <TR>
+           <TH>
+             <I>Protocol</I>
+           </TH>
+           <TD class="arch_diagram_yes" rowspan=2>
+             AF_RXRPC<BR>socket
+           <TD class="arch_diagram_no">
+             OpenAFS lib
+           <TD class="arch_diagram_no">
+             AuriStor lib
+           <TD class="arch_diagram_no">
+             kAFS lib
+           <TD class="arch_diagram_no">
+             OpenAFS lib
+           <TD class="arch_diagram_no">
+             AuriStor lib
+           </TD>
+         <TR>
+           <TH>
+             <I>Kernel I/F</I>
+           </TH>
+           <TD class="arch_diagram_done" colspan=2>
+             UDP socket
+           <TD class="arch_diagram_no">
+             <A href="user_interface.html"><CODE>getxattr</CODE>,<BR><CODE>procfs,</CODE> ...</A>
+           <TD class="arch_diagram_done" colspan=2>
+             <CODE>pioctl</CODE>, <CODE>afs</CODE> syscalls
+           </TD>
+         </TR>
+       </TABLE>
+      </TEXT>
+
+      <H2>Pluggable Transport Interface</H2>
+      <TEXT>
+       <P>
+         Whilst the kafs-utils library will include an interface to the
+         AF_RXRPC socket to provide <I>rx</I> services, it will also have the
+         ability to dynamically load a substitute implementation in shared
+         library form.  This allows third-party rx stacks to be used.  The
+         transport module will need to provide a table of functions the
+         framework to call.
+       <P>
+         These functions allow the framework to set up and tear down
+         connections, security descriptors and calls, and allow data to be
+         sent and received.
+       <P>
+         The code is still in a state of flux.
+       </P>
+      </TEXT>
+
+      <H2>Autogenerated RPC Calls</H2>
+      <TEXT>
+       <P>
+         As part of building the python module, the <CODE>.xg</CODE> files
+         that describe the various AFS RPC calls are processed to produce
+         method functions and constant definitions corresponding the
+         definitions in the protocol specification files.
+       <P>
+         Fundamental types, such as integers, strings and opaques, are
+         translated to/from Python objects that represent equivalent data.
+         Arrays are translated into Python sequences.
+       <P>
+         Constructed data types are translated into Python object classes and
+         these are translated to/from raw data when the code is
+         marshalled/unmarshalled.  Generated Python object classes have
+         members representing the members of the constructed type in the
+         protocol.
+       <P>
+         If a call is aborted by the peer, the Python module will raise an
+         appropriate exception that can be caught individually, for example:
+       </P>
+       <CODE class="example"><PRE>
+    try:
+        ret = rpc.BOZO_DeleteBnode(bos_conn, i)
+    <B>except rpc.AbortBZBUSY</B>:
+        error("can't delete running instance '", i, "'\n")</PRE>
+       </CODE>
+       <P>
+         All raised objects are derived from the <CODE>rpc.RemoteAbort</CODE>
+         class and so can be caught as a group through that.  There is also an
+         intermediate class defined for each package containing abort codes,
+         so, for example, there's an <CODE>rpc.BOZOAbort</CODE> class that can
+         be caught for all the bos server aborts, such
+         as <CODE>rpc.AbortBZBUSY</CODE>.  So:
+       </P>
+       <CODE class="example"><PRE>
+    except rpc.AbortBZBUSY:
+    except rpc.BOZOAbort:
+    except rpc.RemoteAbort:</PRE>
+       </CODE>
+       will all catch <CODE>rpc.AbortBZBUSY</CODE>.
+       <P>
+       <P>
+         Each function returns a Python object that contains the reply data as
+         named members, for example:
+       </P>
+       <CODE class="example"><PRE>
+    users = ""
+    try:
+        i = 0
+        while True:
+            <B>ret</B> = rpc.BOZO_ListSUsers(bos_conn, i)
+            i += 1
+            users += " " + <B>ret.name</B>
+    except rpc.RemoteAbort as msg:
+        if str(msg) == "Aborted 1":
+            pass
+        else:
+            raise</PRE>
+       </CODE>
+      </TEXT>
+
+      <H2>RPC Abstraction Wrappers</H2>
+      <TEXT>
+       <P>
+         The higher level functions don't really want to call the
+         autogenerated Python module directly for a number of reasons:
+       </P>
+       <UL>
+         <LI>
+           Many of the RPC calls in the AFS definition files have multiple
+           variants:
+           <UL>
+             <LI>
+               Some have different options available in the parameters.
+             <LI>
+               Some return extra data.
+             <LI>
+               Some return data in linked-list form rather than array form
+               (which shouldn't be a <I>protocol</I> distinction at all, but
+               rather an <I>interface</I> distinction).
+             <LI>
+               AuriStor's service-upgrade capability provides the ability to
+               have RPC calls that can pass data that can't be supported in
+               the basic AFS definitions (IPv6 addresses, for example).
+           </UL>
+         <LI>
+           The autogenerated interface is slightly tricky to use in the way it
+           returns values.
+         <LI>
+           Some RPC calls (such as <CODE>BOZO.LISTSUsers</CODE>) have to be
+           called multiple times to enumerate a set of objects, and give an
+           abort when done.
+       </UL>
+       <P>
+         The higher level stuff really want all of this hidden from it.  It
+         wants to set out what it wants from a call and let the middle layer
+         sort out how to achieve that.  So, for example,
+         the <CODE>BOZO.ListSUsers</CODE> RPC call used above might be wrapped
+         thusly:
+       </P>
+       <CODE class="example"><PRE>
+         user_list = kafs_rpc.list_bos_super_users(bos_conn)</PRE>
+       </CODE>
+       <P>
+         where <CODE>user_list</CODE> is a sequence of strings, each of which
+         is a user name.
+       </P>
+      </TEXT>
+
+      <H2>Pluggable Query Interface</H2>
+      <TEXT>
+       <P>
+         The scripting Python module will also not have a method of
+         communicating directly with a running filesystem linked in, but
+         rather will load this dynamically as well.  This will allow
+         third-party filesystems to be queried, possibly on the basis of just
+         which one is behind the targetted file if it becomes possible to run
+         different AFS filesystems side-by-side.
+       <P>
+         The method loaded will have to hide the exact method of communicating
+         with the kernel inside of itself, whether that involves
+         calling <CODE>pioctl</CODE>, opening a file in <CODE>/proc</CODE> and
+         doing an <CODE>ioctl</CODE> on it or using some combination
+         of <CODE>getxattr</CODE> and other calls.
+       </P>
+      </TEXT>
+
+      <H2>AFS Filesystem Query Interface</H2>
+      <TEXT>
+       <P>
+         The AFS filesystem running on the local machine can be asked to
+         provide information, both about specific objects and more generally,
+         and to manipulate specific object state and more generally.  This is
+         typically done using the <CODE>afs</CODE> and <CODE>pioctl</CODE>
+         system calls or some emulation thereof, using
+         the <CODE><A href="http://registrar.central.org/pioctls.txt">VIOC*</A></CODE>
+         command codes.
+       <P>
+         Some of the utilities in the suite need access to information the
+         filesystem has available, so the query interface provides a
+         high-level view on this.  For instance:
+       </P>
+       <CODE class="example"><PRE>
+         (vol, fileid, uniquifier) = kafs.get_fid_of_file(filename)</PRE>
+       </CODE>
+       <P>
+         They also need to talk to the cache manager associated with the AFS
+         filesystem in order to manipulate things.  For instance:
+       </P>
+       <CODE class="example"><PRE>
+         kafs.flush_file(filename)</PRE>
+       </CODE>
+      </TEXT>
+
+      <H2>High-Level Scripting Interface</H2>
+      <TEXT>
+       <P>
+         The high-level scripting interface will provide functions that do the
+         equivalent of standard AFS commands, but rather than
+         parsing <CODE>argv[]</CODE>, the arguments will be passed to the
+         function as predigested Python objects of the appropriate types and
+         the output will come back as Python objects rather than being printed
+         to the standard output.
+       <P>
+         So, for example, the function to examine a volume might look like:
+       </P>
+       <CODE class="example"><PRE>
+         cell_handle = kafs.get_cell_handle(cell_name, auth_handle)
+         call_handle->set_encryption(principal_name)
+         volume_info = kafs.examine_volume(cell_handle, volume_name_or_id, extended=False)</PRE>
+       </CODE>
+       <P>
+         possibly and/or:
+       </P>
+       <CODE class="example"><PRE>
+         volume_info = kafs.vos.examine(cell=cell_name, id=volume_name_or_id, extended=False, noauth=True, ...)
+         kafs.display_vol_information(volume_info)</PRE>
+       </CODE>
+       <P>
+         where <CODE>cell_handle</CODE> is a Python object that represents a
+         cell, including caches for volume and protection data, and
+         <CODE>volume_info</CODE> is the looked-up information about the
+         specified volume.
+       </P>
+      </TEXT>
+    </MAIN>
+  </BODY>
+</HTML>
diff --git a/todo.html b/todo.html
new file mode 100644 (file)
index 0000000..8f6408f
--- /dev/null
+++ b/todo.html
@@ -0,0 +1,616 @@
+<!DOCTYPE html>
+<HTML>
+  <STYLE type="text/css">
+    TABLE.todo {
+       border-collapse: collapse;
+       border: 1px solid #aaa;
+       margin: 1em 0;
+    }
+    TABLE.todo > tbody > tr > th, TABLE.todo > tbody > tr > td {
+       padding: 0.2em 0.4em;
+       border: 1px solid #aaa;
+    }
+  </STYLE>
+  <HEAD>
+    <TITLE>kAFS TODO List</TITLE>
+  </HEAD>
+  <BODY>
+    <MAIN>
+      <H1>kAFS To-Do List </H1>
+      <TABLE class="todo">
+       <TR>
+         <TH>Component</TH>
+         <TH>What</TH>
+         <TH>Where</TH>
+         <TH>Ease</TH>
+         <TH>State</TH>
+       </TR>
+
+       <!-- ################################################################################## --!>
+       <!-- ################################################################################## --!>
+       <!-- ################################################################################## --!>
+       <!-- AF_RXRPC -->
+       <TR>
+         <TD rowspan=8>AF_RXRPC protocol</TD>
+         <TD>Service upgrade</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD bgcolor="lightgreen">Done</TD>
+       </TR>
+
+       <TR>
+         <TD>Kerberos 5 support</TD>
+         <TD>Kernel C</TD>
+         <TD>Unknown</TD>
+         <TD bgcolor="lightgreen">Done</TD>
+       </TR>
+
+       <TR>
+         <TD>RxGK/GSS security class</TD>
+         <TD>Kernel C</TD>
+         <TD>Unknown</TD>
+         <TD>no</TD>
+       </TR>
+
+       <TR>
+         <TD>YFS-RxGK security class</TD>
+         <TD>Kernel C</TD>
+         <TD>Unknown</TD>
+         <TD>no</TD>
+       </TR>
+
+       <TR>
+         <TD>Pin UDP routes by rxrpc_connection</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD>no</TD>
+       </TR>
+
+       <TR>
+         <TD>Use MSG_CONFIRM on the UDP socket</TD>
+         <TD>Kernel C</TD>
+         <TD>Easy</TD>
+         <TD>no</TD>
+       </TR>
+
+       <TR>
+         <TD>Support per-call <I>sendfile</I>(), splice-in and splice-out,
+           using <I>setsockopt</I>() to select the call to use</TD>
+         <TD>Kernel C</TD>
+         <TD>Easy</TD>
+         <TD bgcolor="yellow">Written</TD>
+       </TR>
+
+       <TR>
+         <TD>Allow sockets to be bonded together to make multiple queues</TD>
+         <TD>Kernel C</TD>
+         <TD>Easy</TD>
+         <TD>no</TD>
+       </TR>
+
+       <!-- ################################################################################### --!>
+       <!-- ################################################################################### --!>
+       <!-- ################################################################################### --!>
+       <!-- kafs -->
+       <TR>
+         <TD rowspan=28 >kAFS filesystem</TD>
+         <TD>Provide <A href="user_interface.html">pioctl</A> replacement,
+           using <CODE>getxattr</CODE>, <I>sysfs</I>, <I>procfs</I>, <I>keyctl</I>
+           and other interfaces as appropriate.  This is needed for path-based services
+         </TD>
+         <TD>Kernel C</TD>
+         <TD>Easy to Hard</TD>
+         <TD bgcolor="yellow">Partial</TD>
+       </TR>
+
+       <TR>
+         <TD>Dynamic root support (mount -o dyn)</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD bgcolor="lightgreen">v4.16</TD>
+       </TR>
+
+       <TR>
+         <TD>IPv6: Upcall for IPv6 addresses as well as IPv4</TD>
+         <TD>Kernel C</TD>
+         <TD>Easy</TD>
+         <TD bgcolor="lightgreen">v4.18</TD>
+       </TR>
+
+       <TR>
+         <TD>IPv6: Support for VL server comms</TD>
+         <TD>Kernel C</TD>
+         <TD>Hard</TD>
+         <TD bgcolor="lightgreen">v4.15</TD>
+       </TR>
+
+       <TR>
+         <TD>IPv6: Support for FS server comms with YFS</TD>
+         <TD>Kernel C</TD>
+         <TD>Hard</TD>
+         <TD bgcolor="lightgreen">v4.15</TD>
+       </TR>
+
+       <TR>
+         <TD>Multipage read support</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD bgcolor="lightgreen">Done</TD>
+       </TR>
+
+       <TR>
+         <TD>Multipage write support</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD bgcolor="lightgreen">v4.15</TD>
+       </TR>
+
+       <TR>
+         <TD>Handling volumes being moved, busy or offline</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD bgcolor="lightgreen">v4.15</TD>
+       </TR>
+
+       <TR>
+         <TD>Re-evaluate server/volume state after having had difficulty
+         reaching it.</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD bgcolor="lightgreen">v4.18</TD>
+       </TR>
+
+       <TR>
+         <TD>Magic path substitution handling (@sys and @cell)</TD>
+         <TD>Kernel C</TD>
+         <TD>Easy</TD>
+         <TD bgcolor="lightgreen">v4.17</TD>
+       </TR>
+
+       <TR>
+         <TD>Use of speculative batched file status fetching from dir lookup</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD bgcolor="lightgreen">v4.17</TD>
+       </TR>
+
+       <TR>
+         <TD>Local directory blob editing to avoid reload after create/mkdir/unlink/etc.</TD>
+         <TD>Kernel C</TD>
+         <TD>Hard</TD>
+         <TD bgcolor="lightgreen">v4.17</TD>
+       </TR>
+
+       <TR>
+         <TD>Handle permissions on a per file basis instead of per directory</TD>
+         <TD>Kernel C</TD>
+         <TD>Easy</TD>
+         <TD bgcolor="lightgreen">v4.15</TD>
+       </TR>
+
+       <TR>
+         <TD>Modify unix mode bit handling</TD>
+         <TD>Kernel C</TD>
+         <TD>Easy</TD>
+         <TD bgcolor="lightgreen">v4.11</TD>
+       </TR>
+
+       <TR>
+         <TD>Network namespacing support</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD bgcolor="lightgreen">v4.18</TD>
+       </TR>
+
+       <TR>
+         <TD>Network namespace propagation over automounts</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD bgcolor="lightgreen">v5.1</TD>
+       </TR>
+
+       <TR>
+         <TD>Silly rename on unlink or rename</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD bgcolor="lightgreen">v5.2</TD>
+       </TR>
+
+       <TR>
+         <TD>Byte-range file locking emulation</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD bgcolor="lightgreen">v5.2</TD>
+       </TR>
+
+       <TR>
+         <TD>Make calls asynchronous inside the kernel, including address
+           and server rotation</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD bgcolor="lightgreen">v5.8</TD>
+       </TR>
+
+       <TR>
+         <TD>AIO read/write support</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD>no</TD>
+       </TR>
+
+       <TR>
+         <TD>O_DIRECT read/write support</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD bgcolor="yellow">Partial</TD>
+       </TR>
+
+       <TR>
+         <TD>Container keyring</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD>no</TD>
+       </TR>
+
+       <TR>
+         <TD>inotify (and similar) support</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium-Hard</TD>
+         <TD>no</TD>
+       </TR>
+
+       <TR>
+         <TD>Fix population of the vfs group id</TD>
+         <TD>Kernel C</TD>
+         <TD>Easy</TD>
+         <TD>no</TD>
+       </TR>
+
+       <TR>
+         <TD>SELinux/Smack label storage - requires xattr support on the server</TD>
+         <TD>Kernel C</TD>
+         <TD>Unknown</TD>
+         <TD>no</TD>
+       </TR>
+
+       <TR>
+         <TD>YFS FS client and CM service support</TD>
+         <TD>Kernel C</TD>
+         <TD>Unknown</TD>
+         <TD bgcolor="lightgreen">v4.20</TD>
+       </TR>
+
+       <TR>
+         <TD>File system exports for afs2nfs translation</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD>no</TD>
+       </TR>
+
+       <TR>
+         <TD>Getting kafs enabled in the Fedora kernel
+           (<A href="https://bugzilla.redhat.com/show_bug.cgi?id=1616016">Fedora
+             bz 1616016</A>)
+           .</TD>
+         <TD>Spec</TD>
+         <TD>Easy</TD>
+         <TD bgcolor="lightgreen">F29</TD>
+       </TR>
+
+       <!-- ################################################################################### -->
+       <!-- ################################################################################### -->
+       <!-- ################################################################################### -->
+       <!-- Local cache -->
+       <TR>
+         <TD rowspan=10>Local caching</TD>
+         <TD>Fscache: Rewrite of object model</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD bgcolor="yellow">Written</TD>
+       </TR>
+
+       <TR>
+         <TD>Fscache: Rewrite of I/O API</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD bgcolor="yellow">Written</TD>
+       </TR>
+
+       <TR>
+         <TD>Cachefiles: Use bitmap to track contents rather than <I>bmap</I>()</TD>
+         <TD>Kernel C</TD>
+         <TD>Easy</TD>
+         <TD bgcolor="yellow">Written</TD>
+       </TR>
+
+       <TR>
+         <TD>Cachefiles: Use kiocb asynchronous direct-I/O interface rather
+         than event interception</TD>
+         <TD>Kernel C</TD>
+         <TD>Easy</TD>
+         <TD bgcolor="yellow">Written</TD>
+       </TR>
+
+       <TR>
+         <TD>Cachefiles: Use O_TMPFILE to speed up invalidation</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD bgcolor="yellow">Written</TD>
+       </TR>
+
+       <TR>
+         <TD>Write local data changes to cache</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD bgcolor="yellow">Written</TD>
+       </TR>
+
+       <TR>
+         <TD>Write local directory changes to cache</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD bgcolor="yellow">Written</TD>
+       </TR>
+
+       <TR>
+         <TD>Disconnected mode: Operation</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD>no</TD>
+       </TR>
+
+       <TR>
+         <TD>Disconnected mode: Modification journal and change submission on
+         reconnection</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD>no</TD>
+       </TR>
+
+       <TR>
+         <TD>Disconnected mode: Conflict resolution</TD>
+         <TD>Kernel C</TD>
+         <TD>Medium</TD>
+         <TD>no</TD>
+       </TR>
+
+       <!-- ################################################################################### -->
+       <!-- ################################################################################### -->
+       <!-- ################################################################################### -->
+       <!-- afs-filesystem -->
+       <TR>
+         <TD rowspan=3>filesystem</TD>
+         <TD>Getting the /afs mountpoint in the FHS
+         (<A href="https://bugs.linuxfoundation.org/show_bug.cgi?id=1438">Linux
+         Foundation bug 1438</A>)</TD>
+         <TD>Spec</TD>
+         <TD>-</TD>
+         <TD bgcolor="yellow">Review</TD>
+       </TR>
+
+       <TR>
+         <TD>Getting the /afs mountpoint accepted by Fedora
+         (<A href="https://pagure.io/packaging-committee/issue/888">Fedora
+         packaging bug 888</A>)</TD>
+         <TD>Spec</TD>
+         <TD>-</TD>
+         <TD bgcolor="lightgreen">Accepted</TD>
+       </TR>
+
+       <TR>
+         <TD>Getting the /afs mountpoint packaged in the base <B>filesystem</B>
+           rpm as a <B>filesystem-afs</B> subpackage
+           (<A href="https://bugzilla.redhat.com/show_bug.cgi?id=1720232">Fedora
+             bz 1720232</A>)
+           .</TD>
+         <TD>Spec</TD>
+         <TD>Easy</TD>
+         <TD bgcolor="lightgreen">F31</TD>
+       </TR>
+
+       <!-- ################################################################################### -->
+       <!-- ################################################################################### -->
+       <!-- ################################################################################### -->
+       <!-- kAFS-client -->
+       <TR>
+         <TD rowspan=10>kafs-client</TD>
+         <TD>systemd files</TD>
+         <TD>Config</TD>
+         <TD>Easy</TD>
+         <TD bgcolor="lightgreen">v0.1</TD>
+       </TR>
+
+       <TR>
+         <TD>Start/stop managing and mounter</TD>
+         <TD>systemd</TD>
+         <TD>Easy</TD>
+         <TD bgcolor="lightgreen">v0.1</TD>
+       </TR>
+
+       <TR>
+         <TD>Configuration loading from systemd</TD>
+         <TD>C/Script</TD>
+         <TD>Easy</TD>
+         <TD bgcolor="lightgreen">v0.1</TD>
+       </TR>
+
+       <TR>
+         <TD>Support for Loading AuriStorFS profile cell information</TD>
+         <TD>Unknown</TD>
+         <TD>Unknown</TD>
+         <TD bgcolor="lightgreen">v0.1</TD>
+       </TR>
+       <TR>
+         <TD>SRV DNS record support for DNS upcalls
+           (<A href="https://tools.ietf.org/html/rfc5864">RFC 5864</A>)</TD>
+         <TD>User C</TD>
+         <TD>Easy</TD>
+         <TD bgcolor="lightgreen">v0.1</TD>
+       </TR>
+
+       <TR>
+         <TD>IPv6: DNS lookups</TD>
+         <TD>User C</TD>
+         <TD>Easy</TD>
+         <TD bgcolor="lightgreen">v0.1</TD>
+       </TR>
+
+       <TR>
+         <TD>Read CellServDB on demand</TD>
+         <TD>User C</TD>
+         <TD>Easy</TD>
+         <TD bgcolor="lightgreen">v0.1</TD>
+       </TR>
+
+       <TR>
+         <TD>aklog program; may need to interact with kafs-utils.
+           A cut down program is <A href="aklog-k5.c">here</A>.</TD>
+         <TD>C</TD>
+         <TD>Easy</TD>
+         <TD bgcolor="yellow">Partial</TD>
+       </TR>
+
+       <TR>
+         <TD>PAM support (libpam_kafs_session)</TD>
+         <TD>C</TD>
+         <TD>Easy</TD>
+         <TD>no</TD>
+       </TR>
+
+       <TR>
+         <TD>Getting the kafs-client package into Fedora
+           (<A href="https://bugzilla.redhat.com/show_bug.cgi?id=1724281">Fedora
+             bz 1724281</A>)
+           .</TD>
+         <TD>Spec</TD>
+         <TD>Easy</TD>
+         <TD bgcolor="lightgreen">F31</TD>
+       </TR>
+
+       <!-- ################################################################################### -->
+       <!-- ################################################################################### -->
+       <!-- ################################################################################### -->
+       <!-- keyutils -->
+       <TR>
+         <TD rowspan=3>keyutils</TD>
+         <TD>SRV DNS record support for DNS upcalls
+           (<A href="https://tools.ietf.org/html/rfc5864">RFC 5864</A>)</TD>
+         <TD>User C</TD>
+         <TD>Easy</TD>
+         <TD bgcolor="green">kafs-client</TD>
+       </TR>
+
+       <TR>
+         <TD>IPv6: DNS lookups</TD>
+         <TD>User C</TD>
+         <TD>Easy</TD>
+         <TD bgcolor="green">kafs-client</TD>
+       </TR>
+
+       <TR>
+         <TD>Allow override by kafs-client</TD>
+         <TD>User C</TD>
+         <TD>Easy</TD>
+         <TD bgcolor="lightgreen">v1.6</TD>
+       </TR>
+
+       <!-- ################################################################################### -->
+       <!-- ################################################################################### -->
+       <!-- ################################################################################### -->
+       <!-- kafs-utils -->
+       <TR>
+         <TD rowspan=9>kafs-utils</TD>
+         <TD>Provide AFS-compatible command line framework (bos, vos, pts, fs,
+         ...)</TD>
+         <TD>User C</TD>
+         <TD>Easy</TD>
+         <TD bgcolor="yellow">Written</TD>
+       </TR>
+
+       <TR>
+         <TD>Provide a mid-level library, to hide differences between RPC call
+           variants (eg. <I>ListVolumes</I>, <I>XListVolumes</I>), RPC
+           service variants (AFS vs YFS) and to handle server and address
+           rotation</TD>
+         <TD>User C</TD>
+         <TD>Medium</TD>
+         <TD bgcolor="yellow">In&nbsp;progress</TD>
+       </TR>
+
+       <TR>
+         <TD>Provide compatible AFS command line support (bos, vos, pts, fs,
+         ...)  commands</TD>
+         <TD>User C</TD>
+         <TD>Easy to Hard</TD>
+         <TD bgcolor="yellow">In&nbsp;progress</TD>
+       </TR>
+
+       <TR>
+         <TD>Make it possible to override the AF_RXRPC transport with a
+         shared library plug-in</TD>
+         <TD>User C</TD>
+         <TD>Slightly tricky</TD>
+         <TD bgcolor="yellow">Written</TD>
+       </TR>
+
+       <TR>
+         <TD>Provide other transport plug-ins for OpenAFS librx, etc..
+           <UL>
+             <LI>
+           Note that the AF_RXRPC doesn't work in quite the same way as the
+           standard Rx library interface (connections aren't accessible to
+           user; local errors separate from remote aborts).  Requires
+           transport separation.
+           </UL>
+         </TD>
+         <TD>User C</TD>
+         <TD>Medium</TD>
+         <TD>no</TD>
+       </TR>
+
+       <TR>
+         <TD>Provide AFS filesystem query interface</TD>
+         <TD>User C</TD>
+         <TD>Medium</TD>
+         <TD>no</TD>
+       </TR>
+
+       <TR>
+         <TD>Provide kAFS pluggable query module.  Requires kAFS kernel
+         module support.</TD>
+         <TD>User C</TD>
+         <TD>Medium</TD>
+         <TD>no</TD>
+       </TR>
+
+       <TR>
+         <TD>Provide Python language bindings and scripting interface</TD>
+         <TD>Python, swig</TD>
+         <TD>Medium</TD>
+         <TD>no</TD>
+       </TR>
+
+       <TR>
+         <TD>Python server support.
+           <UL>
+             <LI>
+               Maybe pass Python dict of operation ID -&gt; function mappings
+               to backend when starting server, where the server will call the
+               appropriate function to get an app call object.  The object
+               would then have methods with predefined names called upon it to
+               deliver data, aborts, acks, etc.
+           </UL>
+         </TD>
+         <TD>Python lib &amp; C backend</TD>
+         <TD>Medium</TD>
+         <TD>no</TD>
+       </TR>
+
+      </TABLE>
+      <TEXT>
+       <P>
+       </P>
+      </TEXT>
+    </MAIN>
+  </BODY>
+</HTML>
diff --git a/user_interface.html b/user_interface.html
new file mode 100644 (file)
index 0000000..be3a07c
--- /dev/null
@@ -0,0 +1,347 @@
+<!DOCTYPE html>
+<HTML>
+  <STYLE type="text/css">
+    TABLE.main {
+       border-collapse: collapse;
+       border: 1px solid #aaa;
+       margin: 1em 0;
+    }
+    TABLE.main > tr > th, TABLE.main > tr > td, TABLE.main > * > tr > th, TABLE.main > * > tr > td {
+       border: 1px solid #aaa;
+       padding: 0.2em 0.4em;
+       vertical-align: top
+    }
+    TABLE.main > tbody > tr > th {
+       background-color: #f2f2f2;
+       font-weight: bold;
+       text-align: center;
+    }
+  </STYLE>
+    <!-- TABLE.main { border-collapse: collapse; border: blue } -->
+  <HEAD>
+    <TITLE>kAFS userspace interface</TITLE>
+  </HEAD>
+  <BODY>
+    <MAIN>
+      <H1>The kAFS Kernel-Userspace Interface</H1>
+      <TEXT>
+       <H2>The pioctl Problem</H2>
+       <P>
+         There's a reserved system call for AFS (called <CODE>afs</CODE>)
+         that's a multiplexor, one of the subfunctions of which is a
+         path-based ioctl-equivalent (<CODE>pioctl()</CODE>).  Unfortunately,
+         Linus and various members of the Linux community
+         hate <CODE>pioctl()</CODE> as it is highly abused.  In OpenAFS, for
+         example, various of its commands ignore the path they're given, so
+         there's no way this will get into the Linux kernel.
+       <P>
+         This means that kAFS has to work around this lack, using a
+         combination of:
+         <UL>
+           <LI>configfs or sysctl settings
+           <LI><CODE>keyctl()</CODE> calls
+           <LI><CODE>get/setxattr</CODE> calls
+           <LI><CODE>ioctls</CODE> calls on files opened <CODE>O_NODE</CODE>
+           <LI>New syscalls, particularly if they're generic
+             <UL>
+               <LI><CODE><A href="fsinfo.html">fsinfo</A></CODE> - Retrieve filesystem attributes.
+             </UL>
+         </UL>
+       </P>
+
+       <H2>Emulation of pioctl Commands Within kAFS</H2>
+       <TABLE class="main" border="1" cellspacing="0">
+         <TBODY>
+           <TR>
+             <TH><A href="http://registrar.central.org/pioctls.txt">Command</A></TH>
+             <TH>Purpose</TH>
+             <TH>Proposed kAFS Implementation</TH>
+             <TH>Kernel done?</TH>
+             <TH>Comments</TH>
+
+           <TR>
+             <TD rowspan="2">
+               <CODE>VIOC_FILE_CELL_NAME</CODE><BR>
+               <CODE>VIOCIGETCELL</CODE><BR>
+             <TD rowspan="2">Get cell name the object is located within
+             <TD>
+               <CODE>getxattr(path, "afs.cell")</CODE>
+             <TD bgcolor="lightgreen">v4.13</TD>
+             <TD rowspan="5">
+               Actually, I *really* need to dust off my extended-stat
+               patches and also add an fsinfo syscall.  fsinfo()
+               would be able to return things like cell name, volume
+               name, server name for AFS, CIFS, NFS, ...
+             </TD>
+           <TR>
+             <TD>
+               <CODE>fsinfo()</CODE>&nbspwith&nbsp<CODE>fsinfo_attr_cell_name</CODE>
+             <TD bgcolor="yellow">Pending</TD>
+             </TD>
+           <TR>
+             <TD rowspan="2"><CODE>?</CODE>
+             <TD rowspan="2">Determine in which volume the object is located
+             <TD><CODE>getxattr(path, "afs.volume")</CODE>
+             <TD bgcolor="lightgreen">v4.13</TD>
+             </TD>
+           <TR>
+             <TD>
+               <CODE>fsinfo()</CODE>&nbspwith&nbsp<CODE>fsinfo_attr_volume_name</CODE>
+             <TD bgcolor="yellow">Pending</TD>
+             </TD>
+           <TR>
+             <TD><CODE>VIOCGETFID</CODE>
+             <TD>Get the fid
+             <TD>
+               <CODE>getxattr(path, "afs.fid")</CODE>
+             <TD bgcolor="lightgreen">v4.13</TD>
+             </TD>
+
+           <TR>
+             <TD>
+               <CODE>VIOCGETAL</CODE><BR>
+               <CODE>VIOCSETAL</CODE>
+             <TD>Get/set acls on the object
+             <TD>
+               <CODE>getxattr(path, "afs.acl")</CODE><BR>
+               <CODE>setxattr(path, "afs.acl")</CODE>
+             <TD bgcolor="lightgreen">v5.2</TD>
+             <TD>These get/set raw AFS3 ACL blobs; userspace toolage is required.
+             </TD>
+
+           <TR>
+             <TD>
+             <TD>Get/set YFS acls on the object
+             <TD>
+               <CODE>getxattr(path, "afs.yfs.acl")</CODE><BR>
+               <CODE>setxattr(path, "afs.yfs.acl")</CODE><BR>
+               <CODE>getxattr(path, "afs.yfs.vol_acl")</CODE>
+             <TD bgcolor="lightgreen">v5.2</TD>
+             <TD>These get/set raw YFS ACL blobs; userspace toolage is required.
+             </TD>
+
+           <TR>
+             <TD><CODE>VIOCWHEREIS</CODE>
+             <TD>Determine on which servers the object is replicated
+             <TD>
+               <CODE>fsinfo()</CODE>&nbspwith&nbsp<CODE>fsinfo_attr_server_name</CODE><BR>
+               <CODE>fsinfo()</CODE>&nbspwith&nbsp<CODE>fsinfo_attr_server_address</CODE>
+             <TD bgcolor="yellow">Pending
+             <TD>
+               This allows enumeration of the UUIDs and addresses of the
+               servers backing a volume.
+             </TD>
+
+           <TR>
+             <TD>
+               <CODE>VIOCGETCACHEPARMS</CODE><BR>
+               <CODE>VIOCSETCACHESIZE</CODE><BR>
+             <TD>Get/set caching attributes for the object, its volume, or
+               everything
+             <TD rowspan="3">
+               <CODE>fcachectl(int dirfd,<BR>
+                 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const char *pathname,<BR>
+                 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned flags,<BR>
+                 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const char *cmd,<BR>
+                 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char *result,<BR>
+                 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_t *result_len);
+               </CODE>
+             <TD rowspan="3">No
+             <TD rowspan="3">
+               New syscall as it can be applied to NFS and CIFS also.  The
+               <I>cmd</I> argument would be a string of the form:
+               <BR>
+               <CODE>"&lt;command&gt; &lt;scope&gt; [&lt;key&gt;=&lt;val&gt;]*"</CODE>
+               <BR>
+               e.g.
+               <BR>
+               <CODE>"flush volume"</CODE><BR>
+               <CODE>"set file cache=pin"</CODE>
+               <BR>
+               <I>flags</I> would indicate the
+               <CODE>AT_*</CODE> flags.
+             </TD>
+
+           <TR>
+             <TD>
+               <CODE>VIOCFLUSH</CODE><BR>
+               <CODE>VIOCFLUSHCB</CODE><BR>
+               <CODE>VIOC_FLUSHVOLUME</CODE><BR>
+               <CODE>VIOC_FLUSHALL</CODE>
+             <TD>Flush the cache state (for the specified object, for the entire
+               volume the object is in or for everything)
+             </TD>
+
+           <TR>
+             <TD>
+               <CODE>VIOCPREFETCH</CODE><BR>
+             <TD>Prefetch a file into the cache
+             </TD>
+
+           <TR>
+             <TD>
+               <CODE>VIOCGETVOLSTAT</CODE><BR>
+               <CODE>VIOCSETVOLSTAT</CODE><BR>
+             <TD>Get/set volume state via the cache manager
+             <TD>
+             <TD>No
+             <TD>
+             </TD>
+
+           <TR>
+             <TD>
+               <CODE>VIOC_AFS_CREATE_MT_PT</CODE><BR>
+               <CODE>VIOC_AFS_DELETE_MT_PT</CODE><BR>
+               <CODE>VIOC_AFS_STAT_MT_PT</CODE><BR>
+               <CODE>VIOC_AFS_FLUSHMOUNT</CODE><BR>
+             <TD>Create, delete, get and flush information about mount points
+             <TD>
+             <TD>No
+             <TD>
+               Mountpoint operations are the tricky ones because we have to
+               avoid triggering or crossing into an automount.  However, there
+               is a pathwalk control to help deal with that.
+             </TD>
+
+           <TR>
+             <TD>
+               <CODE>VIOC_AFS_SYSNAME</CODE>
+             <TD>Change the list of substitutions for <CODE>@sys</CODE>.
+             <TD>
+               <CODE>echo x86_64 foo bar &gt;/proc/fs/afs/sysname</CODE>
+             <TD bgcolor="lightgreen">v4.17</TD>
+             <TD>
+               An ordered list of substitutions is permitted.  Each
+               substitution is tried in turn.
+             </TD>
+
+           <TR>
+             <TD>
+               <CODE>VIOC_GET_WS_CELL</CODE>
+             <TD>Get/set the workstation cell and implement @cell substitution.
+             <TD>
+               <CODE>
+                 cat /proc/fs/afs/rootcell<BR>
+                 echo foo.bar.org \<BR>&gt;/proc/fs/afs/rootcell
+               </CODE>
+             <TD bgcolor="lightgreen">v4.17</TD>
+             <TD>
+             </TD>
+           <TR>
+             <TD>
+               <CODE>VIOCGETCELL</CODE><BR>
+               <CODE>VIOCNEWCELL</CODE><BR>
+               <CODE>VIOC_NEWALIAS</CODE><BR>
+               <CODE>VIOC_GETALIAS</CODE><BR>
+             <TD>Get/set cellservdb info
+             <TD>
+               <CODE>
+                 cat /proc/fs/afs/cells<BR>
+                 cat&nbsp;/proc/fs/afs/&lt;cell&gt;/vlservers<BR>
+                 echo add your-file-system.com \
+                 &nbsp;204.29.154.37&nbsp;&gt;/proc/fs/afs/cells
+               </CODE>
+             <TD bgcolor="lightgreen">Yes</TD>
+             <TD>
+               Possibly this should be deprecated in favour of using configfs,
+               but it needs to be network-namespace aware, so perhaps not.
+             </TD>
+
+           <TR>
+             <TD>
+               <CODE>VIOC_GETSPREFS</CODE><BR>
+               <CODE>VIOC_SETSPREFS</CODE><BR>
+             <TD>Get/set server preference rankings used to prefer one server
+               instance over another
+             <TD>
+               Go through <CODE>/proc/fs/afs/</CODE>
+             <TD>No
+             <TD>
+             </TD>
+
+           <TR>
+             <TD>
+               <CODE>afs(setpag)</CODE><BR>
+               <CODE>VIOC_GETPAG</CODE><BR>
+               <CODE>VIOCUNPAG</CODE><BR>
+             <TD>Get, set or unset process access group
+             <TD>
+               <CODE>keyctl_join_session_keyring()</CODE><BR>
+               <CODE>keyctl_session_to_parent()</CODE><BR>
+               <CODE>keyctl_clear()</CODE><BR>
+             <TD>No
+             <TD>
+             </TD>
+
+           <TR>
+             <TD>
+               <CODE>VIOCGETTOK</CODE><BR>
+               <CODE>VIOCSETTOK</CODE><BR>
+               <CODE>VIOCGETTOK2</CODE><BR>
+               <CODE>VIOCSETTOK2</CODE><BR>
+               <CODE>VIOCUNLOG</CODE><BR>
+             <TD>Get/set/delete token sets
+             <TD>
+               <CODE>add_key()</CODE><BR>
+               <CODE>keyctl_*()</CODE><BR>
+             <TD>No
+             <TD>
+               Might be worth adding an <CODE>add_keys()</CODE> syscall; this
+               would load a token set as a keyring of keys.  Would need to be
+               able to automatically name keys.
+             </TD>
+
+           <TR>
+             <TD>
+               <CODE>VIOCGETRXKCRYPT</CODE><BR>
+               <CODE>VIOCSETRXKCRYPT</CODE><BR>
+             <TD>Get/set encryption modes
+             <TD><CODE>add_key()</CODE>
+             <TD>No
+             <TD>Scope?
+             </TD>
+
+           <TR>
+             <TD><CODE>?</CODE>
+             <TD>Get the security class and mode used to obtain the status
+               info and data for the current object from the remote
+               server
+             <TD>
+               <CODE>
+                 getxattr(path, "afs.sec_class")<BR>
+                 getxattr(path, "afs.sec_mode")<BR>
+               </CODE>
+             <TD>No
+             <TD>
+             </TD>
+
+           <TR>
+             <TD><CODE>VIOCNEWUUID</CODE>
+             <TD>Get/reset the cache manager's uuid
+             <TD><CODE>/proc/fs/afs/uuid</CODE>
+             <TD>No
+             <TD>
+             </TD>
+
+           <TR>
+             <TD>
+               <CODE>VIOC_RXSTAT_PROC</CODE><BR>
+               <CODE>VIOC_RXSTAT_PEER</CODE><BR>
+             <TD>Get/reset RPC statistics for the server the object's volume
+               is on or everything
+             <TD>
+             <TD>No
+             <TD>
+               Currently no stats kept since they're somewhat
+               implementation-specific, but would make sense to go
+               through <CODE>/proc/fs/afs/</CODE>
+               or <CODE>/proc/net/rxrpc/</CODE>.
+             </TD>
+
+           </TR>
+         </TBODY>
+       </TABLE>
+      </TEXT>
+    </MAIN>
+  </BODY>
+</HTML>