Difference between revisions of "LinuxCIFS Multisession Mount"

(Design Details)
Line 35: Line 35:
 
* server struct: holds info on the socket and results of a NEGOTIATE_PROTOCOL op
 
* server struct: holds info on the socket and results of a NEGOTIATE_PROTOCOL op
 
** session: tracked on a per-fsid basis and holds info pertaining to SESSION_SETUP
 
** session: tracked on a per-fsid basis and holds info pertaining to SESSION_SETUP
*** tcon: holds info pertaining to tree_connect
+
*** tcon: holds info pertaining to TREE_CONNECT operation
 
**** filehandles: info on an open filehandle. Generally a new one will be spawned on an open and destroyed on close.
 
**** filehandles: info on an open filehandle. Generally a new one will be spawned on an open and destroyed on close.
  

Revision as of 17:05, 22 March 2010

Introduction

This page is a design document for adding multisession capability to the Linux CIFS client.

Current State

Currently each mount with the Linux CIFS client is a single-user affair. That is, each mount uses a single set of credentials. Any user does operations within that mount uses the same set of credentials.

The exception to this rule is the "MultiuserMount" switch. When that is enabled, the client will try to match the uid of the current process with an existing mount to the same server and then will use that session's credentials instead. The upshot here is that if you mount the same share multiple times with different uid= and different credentials then you can allow different users to use different credentials.

There are problems with this approach though:

  • it's extremely cumbersome to implement
  • when a matching session isn't found, it uses the "default" session for the mount anyway
  • multiple mounts means that caches aren't properly shared

...as well as other issues. We'd like to see this fixed

Overview of the Goal

Allow a single mountpoint to spawn SMB sessions on the fly. When a "new" user walks into a mount, CIFS will establish a new SMB session on the fly. It will get credentials out of the keyring and then spawn a new SMB session and perform a tree connect for that user. The operations will then be done using the correct smb session and tcon for that uid.

Eventually, the list of sessions will be pruned (probably by cifsd closing out unused sessions after a timeout).

Design Details

CIFS already has a hierarchy of structures to track server state:

  • TCP_Server_Info: contains info pertaining to the connection to the server. Holds info on the socket, for instance.
    • cifsSesInfo: authentication generally happens here (unless share-level auth is used). Identified on server by VUID.
      • cifsTconInfo: info on a particular connection to the server's tree. Identified on the server by the TID.
        • filehandles: open file descriptors. Identified on server by netfid.

Currently, things are not organized quite so cleanly. For instance, when multiuser mounts are used, the TID used is not necessarily one that was established using the same VUID. This is fine in CIFS, but apparently SMB2 ties the TID to the VUID used to establish it. Also filehandles are currently somewhat "free-floating", and aren't cleanly tied to a cifsTconInfo. This info is also too closely mashed together with the superblock currently.

To do multisession mounts properly, we'll need a much more rigid heirarchy. I propose something like this:

  • server struct: holds info on the socket and results of a NEGOTIATE_PROTOCOL op
    • session: tracked on a per-fsid basis and holds info pertaining to SESSION_SETUP
      • tcon: holds info pertaining to TREE_CONNECT operation
        • filehandles: info on an open filehandle. Generally a new one will be spawned on an open and destroyed on close.

Now, all of this has nothing so far to do with the filesystem on linux. These structs just track information about the state on the server. For this to be useful, we need a way for new on the wire calls to pick out a tcon/ses combo to use.

For this, I propose using a radix tree with the fsuid of the user as the key and pointers to tcon structs as the value. We may need to consider using bumping the refcount of the tcon to ensure that they don't vanish.