Commit ee443996 authored by Eric Van Hensbergen's avatar Eric Van Hensbergen Committed by Eric Van Hensbergen

9p: Documentation updates

The kernel-doc comments of much of the 9p system have been in disarray since
reorganization.  This patch fixes those problems, adds additional documentation
and a template book which collects the 9p information.
Signed-off-by: default avatarEric Van Hensbergen <ericvh@gmail.com>
parent b32a09db
...@@ -22,6 +22,21 @@ ...@@ -22,6 +22,21 @@
#include <linux/list.h> #include <linux/list.h>
/**
* struct v9fs_dentry - 9p private data stored in dentry d_fsdata
* @lock: protects the fidlist
* @fidlist: list of FIDs currently associated with this dentry
*
* This structure defines the 9p private data associated with
* a particular dentry. In particular, this private data is used
* to lookup which 9P FID handle should be used for a particular VFS
* operation. FID handles are associated with dentries instead of
* inodes in order to more closely map functionality to the Plan 9
* expected behavior for FID reclaimation and tracking.
*
* See Also: Mapping FIDs to Linux VFS model in
* Design and Implementation of the Linux 9P File System documentation
*/
struct v9fs_dentry { struct v9fs_dentry {
spinlock_t lock; /* protect fidlist */ spinlock_t lock; /* protect fidlist */
struct list_head fidlist; struct list_head fidlist;
......
...@@ -71,7 +71,6 @@ static match_table_t tokens = { ...@@ -71,7 +71,6 @@ static match_table_t tokens = {
/** /**
* v9fs_parse_options - parse mount options into session structure * v9fs_parse_options - parse mount options into session structure
* @options: options string passed from mount
* @v9ses: existing v9fs session information * @v9ses: existing v9fs session information
* *
*/ */
...@@ -256,9 +255,12 @@ void v9fs_session_close(struct v9fs_session_info *v9ses) ...@@ -256,9 +255,12 @@ void v9fs_session_close(struct v9fs_session_info *v9ses)
} }
/** /**
* v9fs_session_cancel - mark transport as disconnected * v9fs_session_cancel - terminate a session
* and cancel all pending requests. * @v9ses: session to terminate
*
* mark transport as disconnected and cancel all pending requests.
*/ */
void v9fs_session_cancel(struct v9fs_session_info *v9ses) { void v9fs_session_cancel(struct v9fs_session_info *v9ses) {
P9_DPRINTK(P9_DEBUG_ERROR, "cancel session %p\n", v9ses); P9_DPRINTK(P9_DEBUG_ERROR, "cancel session %p\n", v9ses);
p9_client_disconnect(v9ses->clnt); p9_client_disconnect(v9ses->clnt);
......
...@@ -21,18 +21,69 @@ ...@@ -21,18 +21,69 @@
* *
*/ */
/* /**
* Session structure provides information for an opened session * enum p9_session_flags - option flags for each 9P session
* * @V9FS_EXTENDED: whether or not to use 9P2000.u extensions
*/ * @V9FS_ACCESS_SINGLE: only the mounting user can access the hierarchy
* @V9FS_ACCESS_USER: a new attach will be issued for every user (default)
* @V9FS_ACCESS_ANY: use a single attach for all users
* @V9FS_ACCESS_MASK: bit mask of different ACCESS options
*
* Session flags reflect options selected by users at mount time
*/
enum p9_session_flags {
V9FS_EXTENDED = 0x01,
V9FS_ACCESS_SINGLE = 0x02,
V9FS_ACCESS_USER = 0x04,
V9FS_ACCESS_ANY = 0x06,
V9FS_ACCESS_MASK = 0x06,
};
/* possible values of ->cache */
/**
* enum p9_cache_modes - user specified cache preferences
* @CACHE_NONE: do not cache data, dentries, or directory contents (default)
* @CACHE_LOOSE: cache data, dentries, and directory contents w/no consistency
*
* eventually support loose, tight, time, session, default always none
*/
enum p9_cache_modes {
CACHE_NONE,
CACHE_LOOSE,
};
/**
* struct v9fs_session_info - per-instance session information
* @flags: session options of type &p9_session_flags
* @nodev: set to 1 to disable device mapping
* @debug: debug level
* @afid: authentication handle
* @cache: cache mode of type &p9_cache_modes
* @options: copy of options string given by user
* @uname: string user name to mount hierarchy as
* @aname: mount specifier for remote hierarchy
* @maxdata: maximum data to be sent/recvd per protocol message
* @dfltuid: default numeric userid to mount hierarchy as
* @dfltgid: default numeric groupid to mount hierarchy as
* @uid: if %V9FS_ACCESS_SINGLE, the numeric uid which mounted the hierarchy
* @clnt: reference to 9P network client instantiated for this session
* @debugfs_dir: reference to debugfs_dir which can be used for add'l debug
*
* This structure holds state for each session instance established during
* a sys_mount() .
*
* Bugs: there seems to be a lot of state which could be condensed and/or
* removed.
*/
struct v9fs_session_info { struct v9fs_session_info {
/* options */ /* options */
unsigned char flags; /* session flags */ unsigned char flags;
unsigned char nodev; /* set to 1 if no disable device mapping */ unsigned char nodev;
unsigned short debug; /* debug level */ unsigned short debug;
unsigned int afid; /* authentication fid */ unsigned int afid;
unsigned int cache; /* cache mode */ unsigned int cache;
char *options; /* copy of mount options */ char *options; /* copy of mount options */
char *uname; /* user name to mount as */ char *uname; /* user name to mount as */
...@@ -45,22 +96,6 @@ struct v9fs_session_info { ...@@ -45,22 +96,6 @@ struct v9fs_session_info {
struct dentry *debugfs_dir; struct dentry *debugfs_dir;
}; };
/* session flags */
enum {
V9FS_EXTENDED = 0x01, /* 9P2000.u */
V9FS_ACCESS_MASK = 0x06, /* access mask */
V9FS_ACCESS_SINGLE = 0x02, /* only one user can access the files */
V9FS_ACCESS_USER = 0x04, /* attache per user */
V9FS_ACCESS_ANY = 0x06, /* use the same attach for all users */
};
/* possible values of ->cache */
/* eventually support loose, tight, time, session, default always none */
enum {
CACHE_NONE, /* default */
CACHE_LOOSE, /* no consistency */
};
extern struct dentry *v9fs_debugfs_root; extern struct dentry *v9fs_debugfs_root;
struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *,
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
/** /**
* v9fs_vfs_readpage - read an entire page in from 9P * v9fs_vfs_readpage - read an entire page in from 9P
* *
* @file: file being read * @filp: file being read
* @page: structure to page * @page: structure to page
* *
*/ */
......
...@@ -60,7 +60,7 @@ static inline int dt_type(struct p9_stat *mistat) ...@@ -60,7 +60,7 @@ static inline int dt_type(struct p9_stat *mistat)
/** /**
* v9fs_dir_readdir - read a directory * v9fs_dir_readdir - read a directory
* @filep: opened file structure * @filp: opened file structure
* @dirent: directory structure ??? * @dirent: directory structure ???
* @filldir: function to populate directory structure ??? * @filldir: function to populate directory structure ???
* *
......
...@@ -90,10 +90,11 @@ int v9fs_file_open(struct inode *inode, struct file *file) ...@@ -90,10 +90,11 @@ int v9fs_file_open(struct inode *inode, struct file *file)
/** /**
* v9fs_file_lock - lock a file (or directory) * v9fs_file_lock - lock a file (or directory)
* @inode: inode to be opened * @filp: file to be locked
* @file: file being opened * @cmd: lock command
* @fl: file lock structure
* *
* XXX - this looks like a local only lock, we should extend into 9P * Bugs: this looks like a local only lock, we should extend into 9P
* by using open exclusive * by using open exclusive
*/ */
...@@ -118,7 +119,7 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl) ...@@ -118,7 +119,7 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)
/** /**
* v9fs_file_read - read from a file * v9fs_file_read - read from a file
* @filep: file pointer to read * @filp: file pointer to read
* @data: data buffer to read data into * @data: data buffer to read data into
* @count: size of buffer * @count: size of buffer
* @offset: offset at which to read data * @offset: offset at which to read data
...@@ -142,7 +143,7 @@ v9fs_file_read(struct file *filp, char __user * data, size_t count, ...@@ -142,7 +143,7 @@ v9fs_file_read(struct file *filp, char __user * data, size_t count,
/** /**
* v9fs_file_write - write to a file * v9fs_file_write - write to a file
* @filep: file pointer to write * @filp: file pointer to write
* @data: data buffer to write data from * @data: data buffer to write data from
* @count: size of buffer * @count: size of buffer
* @offset: offset at which to write data * @offset: offset at which to write data
......
...@@ -129,6 +129,12 @@ static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode) ...@@ -129,6 +129,12 @@ static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode)
return res; return res;
} }
/**
* v9fs_uflags2omode- convert posix open flags to plan 9 mode bits
* @uflags: flags to convert
*
*/
int v9fs_uflags2omode(int uflags) int v9fs_uflags2omode(int uflags)
{ {
int ret; int ret;
...@@ -312,6 +318,14 @@ v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry) ...@@ -312,6 +318,14 @@ v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry)
} }
*/ */
/**
* v9fs_inode_from_fid - populate an inode by issuing a attribute request
* @v9ses: session information
* @fid: fid to issue attribute request for
* @sb: superblock on which to create inode
*
*/
static struct inode * static struct inode *
v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
struct super_block *sb) struct super_block *sb)
...@@ -384,9 +398,12 @@ v9fs_open_created(struct inode *inode, struct file *file) ...@@ -384,9 +398,12 @@ v9fs_open_created(struct inode *inode, struct file *file)
/** /**
* v9fs_create - Create a file * v9fs_create - Create a file
* @v9ses: session information
* @dir: directory that dentry is being created in
* @dentry: dentry that is being created * @dentry: dentry that is being created
* @perm: create permissions * @perm: create permissions
* @mode: open mode * @mode: open mode
* @extension: 9p2000.u extension string to support devices, etc.
* *
*/ */
static struct p9_fid * static struct p9_fid *
...@@ -461,7 +478,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, ...@@ -461,7 +478,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
/** /**
* v9fs_vfs_create - VFS hook to create files * v9fs_vfs_create - VFS hook to create files
* @inode: directory inode that is being created * @dir: directory inode that is being created
* @dentry: dentry that is being deleted * @dentry: dentry that is being deleted
* @mode: create permissions * @mode: create permissions
* @nd: path information * @nd: path information
...@@ -519,7 +536,7 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, ...@@ -519,7 +536,7 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode,
/** /**
* v9fs_vfs_mkdir - VFS mkdir hook to create a directory * v9fs_vfs_mkdir - VFS mkdir hook to create a directory
* @inode: inode that is being unlinked * @dir: inode that is being unlinked
* @dentry: dentry that is being unlinked * @dentry: dentry that is being unlinked
* @mode: mode for new directory * @mode: mode for new directory
* *
...@@ -703,9 +720,9 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -703,9 +720,9 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
/** /**
* v9fs_vfs_getattr - retrieve file metadata * v9fs_vfs_getattr - retrieve file metadata
* @mnt - mount information * @mnt: mount information
* @dentry - file to get attributes on * @dentry: file to get attributes on
* @stat - metadata structure to populate * @stat: metadata structure to populate
* *
*/ */
...@@ -928,7 +945,7 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) ...@@ -928,7 +945,7 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
/** /**
* v9fs_vfs_readlink - read a symlink's location * v9fs_vfs_readlink - read a symlink's location
* @dentry: dentry for symlink * @dentry: dentry for symlink
* @buf: buffer to load symlink location into * @buffer: buffer to load symlink location into
* @buflen: length of buffer * @buflen: length of buffer
* *
*/ */
...@@ -996,10 +1013,12 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd) ...@@ -996,10 +1013,12 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd)
* v9fs_vfs_put_link - release a symlink path * v9fs_vfs_put_link - release a symlink path
* @dentry: dentry for symlink * @dentry: dentry for symlink
* @nd: nameidata * @nd: nameidata
* @p: unused
* *
*/ */
static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p) static void
v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
{ {
char *s = nd_get_link(nd); char *s = nd_get_link(nd);
...@@ -1008,6 +1027,15 @@ static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void ...@@ -1008,6 +1027,15 @@ static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void
__putname(s); __putname(s);
} }
/**
* v9fs_vfs_mkspecial - create a special file
* @dir: inode to create special file in
* @dentry: dentry to create
* @mode: mode to create special file
* @extension: 9p2000.u format extension string representing special file
*
*/
static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
int mode, const char *extension) int mode, const char *extension)
{ {
...@@ -1037,7 +1065,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, ...@@ -1037,7 +1065,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
* @dentry: dentry for symlink * @dentry: dentry for symlink
* @symname: symlink data * @symname: symlink data
* *
* See 9P2000.u RFC for more information * See Also: 9P2000.u RFC for more information
* *
*/ */
...@@ -1058,10 +1086,6 @@ v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) ...@@ -1058,10 +1086,6 @@ v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
* *
*/ */
/* XXX - lots of code dup'd from symlink and creates,
* figure out a better reuse strategy
*/
static int static int
v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
struct dentry *dentry) struct dentry *dentry)
...@@ -1098,7 +1122,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, ...@@ -1098,7 +1122,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
* @dir: inode destination for new link * @dir: inode destination for new link
* @dentry: dentry for file * @dentry: dentry for file
* @mode: mode for creation * @mode: mode for creation
* @dev_t: device associated with special file * @rdev: device associated with special file
* *
*/ */
......
...@@ -75,6 +75,7 @@ static int v9fs_set_super(struct super_block *s, void *data) ...@@ -75,6 +75,7 @@ static int v9fs_set_super(struct super_block *s, void *data)
* v9fs_fill_super - populate superblock with info * v9fs_fill_super - populate superblock with info
* @sb: superblock * @sb: superblock
* @v9ses: session information * @v9ses: session information
* @flags: flags propagated from v9fs_get_sb()
* *
*/ */
......
...@@ -29,14 +29,31 @@ ...@@ -29,14 +29,31 @@
#ifdef CONFIG_NET_9P_DEBUG #ifdef CONFIG_NET_9P_DEBUG
#define P9_DEBUG_ERROR (1<<0) /**
#define P9_DEBUG_9P (1<<2) * enum p9_debug_flags - bits for mount time debug parameter
#define P9_DEBUG_VFS (1<<3) * @P9_DEBUG_ERROR: more verbose error messages including original error string
#define P9_DEBUG_CONV (1<<4) * @P9_DEBUG_9P: 9P protocol tracing
#define P9_DEBUG_MUX (1<<5) * @P9_DEBUG_VFS: VFS API tracing
#define P9_DEBUG_TRANS (1<<6) * @P9_DEBUG_CONV: protocol conversion tracing
#define P9_DEBUG_SLABS (1<<7) * @P9_DEBUG_MUX: trace management of concurrent transactions
#define P9_DEBUG_FCALL (1<<8) * @P9_DEBUG_TRANS: transport tracing
* @P9_DEBUG_SLABS: memory management tracing
* @P9_DEBUG_FCALL: verbose dump of protocol messages
*
* These flags are passed at mount time to turn on various levels of
* verbosity and tracing which will be output to the system logs.
*/
enum p9_debug_flags {
P9_DEBUG_ERROR = (1<<0),
P9_DEBUG_9P = (1<<2),
P9_DEBUG_VFS = (1<<3),
P9_DEBUG_CONV = (1<<4),
P9_DEBUG_MUX = (1<<5),
P9_DEBUG_TRANS = (1<<6),
P9_DEBUG_SLABS = (1<<7),
P9_DEBUG_FCALL = (1<<8),
};
extern unsigned int p9_debug_level; extern unsigned int p9_debug_level;
...@@ -62,9 +79,47 @@ do { \ ...@@ -62,9 +79,47 @@ do { \
format , __FUNCTION__, task_pid_nr(current), ## arg); \ format , __FUNCTION__, task_pid_nr(current), ## arg); \
} while (0) } while (0)
/**
* enum p9_msg_t - 9P message types
* @P9_TVERSION: version handshake request
* @P9_RVERSION: version handshake response
* @P9_TAUTH: request to establish authentication channel
* @P9_RAUTH: response with authentication information
* @P9_TATTACH: establish user access to file service
* @P9_RATTACH: response with top level handle to file hierarchy
* @P9_TERROR: not used
* @P9_RERROR: response for any failed request
* @P9_TFLUSH: request to abort a previous request
* @P9_RFLUSH: response when previous request has been cancelled
* @P9_TWALK: descend a directory hierarchy
* @P9_RWALK: response with new handle for position within hierarchy
* @P9_TOPEN: prepare a handle for I/O on an existing file
* @P9_ROPEN: response with file access information
* @P9_TCREATE: prepare a handle for I/O on a new file
* @P9_RCREATE: response with file access information
* @P9_TREAD: request to transfer data from a file or directory
* @P9_RREAD: response with data requested
* @P9_TWRITE: reuqest to transfer data to a file
* @P9_RWRITE: response with out much data was transfered to file
* @P9_TCLUNK: forget about a handle to an entity within the file system
* @P9_RCLUNK: response when server has forgotten about the handle
* @P9_TREMOVE: request to remove an entity from the hierarchy
* @P9_RREMOVE: response when server has removed the entity
* @P9_TSTAT: request file entity attributes
* @P9_RSTAT: response with file entity attributes
* @P9_TWSTAT: request to update file entity attributes
* @P9_RWSTAT: response when file entity attributes are updated
*
* There are 14 basic operations in 9P2000, paired as
* requests and responses. The one special case is ERROR
* as there is no @P9_TERROR request for clients to transmit to
* the server, but the server may respond to any other request
* with an @P9_RERROR.
*
* See Also: http://plan9.bell-labs.com/sys/man/5/INDEX.html
*/
/* Message Types */ enum p9_msg_t {
enum {
P9_TVERSION = 100, P9_TVERSION = 100,
P9_RVERSION, P9_RVERSION,
P9_TAUTH = 102, P9_TAUTH = 102,
...@@ -95,30 +150,71 @@ enum { ...@@ -95,30 +150,71 @@ enum {
P9_RWSTAT, P9_RWSTAT,
}; };
/* open modes */ /**
enum { * enum p9_open_mode_t - 9P open modes
* @P9_OREAD: open file for reading only
* @P9_OWRITE: open file for writing only
* @P9_ORDWR: open file for reading or writing
* @P9_OEXEC: open file for execution
* @P9_OTRUNC: truncate file to zero-length before opening it
* @P9_OREXEC: close the file when an exec(2) system call is made
* @P9_ORCLOSE: remove the file when the file is closed
* @P9_OAPPEND: open the file and seek to the end
* @P9_OEXCL: only create a file, do not open it
*
* 9P open modes differ slightly from Posix standard modes.
* In particular, there are extra modes which specify different
* semantic behaviors than may be available on standard Posix
* systems. For example, @P9_OREXEC and @P9_ORCLOSE are modes that
* most likely will not be issued from the Linux VFS client, but may
* be supported by servers.
*
* See Also: http://plan9.bell-labs.com/magic/man2html/2/open
*/
enum p9_open_mode_t {
P9_OREAD = 0x00, P9_OREAD = 0x00,
P9_OWRITE = 0x01, P9_OWRITE = 0x01,
P9_ORDWR = 0x02, P9_ORDWR = 0x02,
P9_OEXEC = 0x03, P9_OEXEC = 0x03,
P9_OEXCL = 0x04,
P9_OTRUNC = 0x10, P9_OTRUNC = 0x10,
P9_OREXEC = 0x20, P9_OREXEC = 0x20,
P9_ORCLOSE = 0x40, P9_ORCLOSE = 0x40,
P9_OAPPEND = 0x80, P9_OAPPEND = 0x80,
}; P9_OEXCL = 0x1000,
};
/* permissions */
enum { /**
* enum p9_perm_t - 9P permissions
* @P9_DMDIR: mode bite for directories
* @P9_DMAPPEND: mode bit for is append-only
* @P9_DMEXCL: mode bit for excluse use (only one open handle allowed)
* @P9_DMMOUNT: mode bite for mount points
* @P9_DMAUTH: mode bit for authentication file
* @P9_DMTMP: mode bit for non-backed-up files
* @P9_DMSYMLINK: mode bit for symbolic links (9P2000.u)
* @P9_DMLINK: mode bit for hard-link (9P2000.u)
* @P9_DMDEVICE: mode bit for device files (9P2000.u)
* @P9_DMNAMEDPIPE: mode bit for named pipe (9P2000.u)
* @P9_DMSOCKET: mode bit for socket (9P2000.u)
* @P9_DMSETUID: mode bit for setuid (9P2000.u)
* @P9_DMSETGID: mode bit for setgid (9P2000.u)
* @P9_DMSETVTX: mode bit for sticky bit (9P2000.u)
*
* 9P permissions differ slightly from Posix standard modes.
*
* See Also: http://plan9.bell-labs.com/magic/man2html/2/stat
*/
enum p9_perm_t {
P9_DMDIR = 0x80000000, P9_DMDIR = 0x80000000,
P9_DMAPPEND = 0x40000000, P9_DMAPPEND = 0x40000000,
P9_DMEXCL = 0x20000000, P9_DMEXCL = 0x20000000,
P9_DMMOUNT = 0x10000000, P9_DMMOUNT = 0x10000000,
P9_DMAUTH = 0x08000000, P9_DMAUTH = 0x08000000,
P9_DMTMP = 0x04000000, P9_DMTMP = 0x04000000,
/* 9P2000.u extensions */
P9_DMSYMLINK = 0x02000000, P9_DMSYMLINK = 0x02000000,
P9_DMLINK = 0x01000000, P9_DMLINK = 0x01000000,
/* 9P2000.u extensions */
P9_DMDEVICE = 0x00800000, P9_DMDEVICE = 0x00800000,
P9_DMNAMEDPIPE = 0x00200000, P9_DMNAMEDPIPE = 0x00200000,
P9_DMSOCKET = 0x00100000, P9_DMSOCKET = 0x00100000,
...@@ -127,8 +223,26 @@ enum { ...@@ -127,8 +223,26 @@ enum {
P9_DMSETVTX = 0x00010000, P9_DMSETVTX = 0x00010000,
}; };
/* qid.types */ /**
enum { * enum p9_qid_t - QID types
* @P9_QTDIR: directory
* @P9_QTAPPEND: append-only
* @P9_QTEXCL: excluse use (only one open handle allowed)
* @P9_QTMOUNT: mount points
* @P9_QTAUTH: authentication file
* @P9_QTTMP: non-backed-up files
* @P9_QTSYMLINK: symbolic links (9P2000.u)
* @P9_QTLINK: hard-link (9P2000.u)
* @P9_QTFILE: normal files
*
* QID types are a subset of permissions - they are primarily
* used to differentiate semantics for a file system entity via
* a jump-table. Their value is also the most signifigant 16 bits
* of the permission_t
*
* See Also: http://plan9.bell-labs.com/magic/man2html/2/stat
*/
enum p9_qid_t {
P9_QTDIR = 0x80, P9_QTDIR = 0x80,
P9_QTAPPEND = 0x40, P9_QTAPPEND = 0x40,
P9_QTEXCL = 0x20, P9_QTEXCL = 0x20,
...@@ -140,6 +254,7 @@ enum { ...@@ -140,6 +254,7 @@ enum {
P9_QTFILE = 0x00, P9_QTFILE = 0x00,
}; };
/* 9P Magic Numbers */
#define P9_NOTAG (u16)(~0) #define P9_NOTAG (u16)(~0)
#define P9_NOFID (u32)(~0) #define P9_NOFID (u32)(~0)
#define P9_MAXWELEM 16 #define P9_MAXWELEM 16
...@@ -147,19 +262,69 @@ enum { ...@@ -147,19 +262,69 @@ enum {
/* ample room for Twrite/Rread header */ /* ample room for Twrite/Rread header */
#define P9_IOHDRSZ 24 #define P9_IOHDRSZ 24
/**
* struct p9_str - length prefixed string type
* @len: length of the string
* @str: the string
*
* The protocol uses length prefixed strings for all
* string data, so we replicate that for our internal
* string members.
*/
struct p9_str { struct p9_str {
u16 len; u16 len;
char *str; char *str;
}; };
/* qids are the unique ID for a file (like an inode */ /**
* struct p9_qid - file system entity information
* @type: 8-bit type &p9_qid_t
* @version: 16-bit monotonically incrementing version number
* @path: 64-bit per-server-unique ID for a file system element
*
* qids are identifiers used by 9P servers to track file system
* entities. The type is used to differentiate semantics for operations
* on the entity (ie. read means something different on a directory than
* on a file). The path provides a server unique index for an entity
* (roughly analogous to an inode number), while the version is updated
* every time a file is modified and can be used to maintain cache
* coherency between clients and serves.
* Servers will often differentiate purely synthetic entities by setting
* their version to 0, signaling that they should never be cached and
* should be accessed synchronously.
*
* See Also://plan9.bell-labs.com/magic/man2html/2/stat
*/
struct p9_qid { struct p9_qid {
u8 type; u8 type;
u32 version; u32 version;
u64 path; u64 path;
}; };
/* Plan 9 file metadata (stat) structure */ /**
* struct p9_stat - file system metadata information
* @size: length prefix for this stat structure instance
* @type: the type of the server (equivilent to a major number)
* @dev: the sub-type of the server (equivilent to a minor number)
* @qid: unique id from the server of type &p9_qid
* @mode: Plan 9 format permissions of type &p9_perm_t
* @atime: Last access/read time
* @mtime: Last modify/write time
* @length: file length
* @name: last element of path (aka filename) in type &p9_str
* @uid: owner name in type &p9_str
* @gid: group owner in type &p9_str
* @muid: last modifier in type &p9_str
* @extension: area used to encode extended UNIX support in type &p9_str
* @n_uid: numeric user id of owner (part of 9p2000.u extension)
* @n_gid: numeric group id (part of 9p2000.u extension)
* @n_muid: numeric user id of laster modifier (part of 9p2000.u extension)
*
* See Also: http://plan9.bell-labs.com/magic/man2html/2/stat
*/
struct p9_stat { struct p9_stat {
u16 size; u16 size;
u16 type; u16 type;
...@@ -179,10 +344,14 @@ struct p9_stat { ...@@ -179,10 +344,14 @@ struct p9_stat {
u32 n_muid; /* 9p2000.u extensions */ u32 n_muid; /* 9p2000.u extensions */
}; };
/* file metadata (stat) structure used to create Twstat message /*
The is similar to p9_stat, but the strings don't point to * file metadata (stat) structure used to create Twstat message
the same memory block and should be freed separately * The is identical to &p9_stat, but the strings don't point to
*/ * the same memory block and should be freed separately
*
* See Also: http://plan9.bell-labs.com/magic/man2html/2/stat
*/
struct p9_wstat { struct p9_wstat {
u16 size; u16 size;
u16 type; u16 type;
...@@ -335,10 +504,20 @@ struct p9_twstat { ...@@ -335,10 +504,20 @@ struct p9_twstat {
struct p9_rwstat { struct p9_rwstat {
}; };
/* /**
* fcall is the primary packet structure * struct p9_fcall - primary packet structure
* * @size: prefixed length of the structure
*/ * @id: protocol operating identifier of type &p9_msg_t
* @tag: transaction id of the request
* @sdata: payload
* @params: per-operation parameters
*
* &p9_fcall represents the structure for all 9P RPC
* transactions. Requests are packaged into fcalls, and reponses
* must be extracted from them.
*
* See Also: http://plan9.bell-labs.com/magic/man2html/2/fcall
*/
struct p9_fcall { struct p9_fcall {
u32 size; u32 size;
......
...@@ -26,6 +26,23 @@ ...@@ -26,6 +26,23 @@
#ifndef NET_9P_CLIENT_H #ifndef NET_9P_CLIENT_H
#define NET_9P_CLIENT_H #define NET_9P_CLIENT_H
/**
* struct p9_client - per client instance state
* @lock: protect @fidlist
* @msize: maximum data size negotiated by protocol
* @dotu: extension flags negotiated by protocol
* @trans_mod: module API instantiated with this client
* @trans: tranport instance state and API
* @conn: connection state information used by trans_fd
* @fidpool: fid handle accounting for session
* @fidlist: List of active fid handles
*
* The client structure is used to keep track of various per-client
* state that has been instantiated.
*
* Bugs: duplicated data and potentially unnecessary elements.
*/
struct p9_client { struct p9_client {
spinlock_t lock; /* protect client structure */ spinlock_t lock; /* protect client structure */
int msize; int msize;
...@@ -38,6 +55,24 @@ struct p9_client { ...@@ -38,6 +55,24 @@ struct p9_client {
struct list_head fidlist; struct list_head fidlist;
}; };
/**
* struct p9_fid - file system entity handle
* @clnt: back pointer to instantiating &p9_client
* @fid: numeric identifier for this handle
* @mode: current mode of this fid (enum?)
* @qid: the &p9_qid server identifier this handle points to
* @iounit: the server reported maximum transaction size for this file
* @uid: the numeric uid of the local user who owns this handle
* @aux: transport specific information (unused?)
* @rdir_fpos: tracks offset of file position when reading directory contents
* @rdir_pos: (unused?)
* @rdir_fcall: holds response of last directory read request
* @flist: per-client-instance fid tracking
* @dlist: per-dentry fid tracking
*
* TODO: This needs lots of explanation.
*/
struct p9_fid { struct p9_fid {
struct p9_client *clnt; struct p9_client *clnt;
u32 fid; u32 fid;
......
...@@ -26,12 +26,40 @@ ...@@ -26,12 +26,40 @@
#ifndef NET_9P_TRANSPORT_H #ifndef NET_9P_TRANSPORT_H
#define NET_9P_TRANSPORT_H #define NET_9P_TRANSPORT_H
/**
* enum p9_trans_status - different states of underlying transports
* @Connected: transport is connected and healthy
* @Disconnected: transport has been disconnected
* @Hung: transport is connected by wedged
*
* This enumeration details the various states a transport
* instatiation can be in.
*/
enum p9_trans_status { enum p9_trans_status {
Connected, Connected,
Disconnected, Disconnected,
Hung, Hung,
}; };
/**
* struct p9_trans - per-transport state and API
* @status: transport &p9_trans_status
* @msize: negotiated maximum packet size (duplicate from client)
* @extended: negotiated protocol extensions (duplicate from client)
* @priv: transport private data
* @close: member function to disconnect and close the transport
* @rpc: member function to issue a request to the transport
*
* This is the basic API for a transport instance. It is used as
* a handle by the client to issue requests. This interface is currently
* in flux during reorganization.
*
* Bugs: there is lots of duplicated data here and its not clear that
* the member functions need to be per-instance versus per transport
* module.
*/
struct p9_trans { struct p9_trans {
enum p9_trans_status status; enum p9_trans_status status;
int msize; int msize;
...@@ -42,6 +70,21 @@ struct p9_trans { ...@@ -42,6 +70,21 @@ struct p9_trans {
struct p9_fcall **rc); struct p9_fcall **rc);
}; };
/**
* struct p9_trans_module - transport module interface
* @list: used to maintain a list of currently available transports
* @name: the human-readable name of the transport
* @maxsize: transport provided maximum packet size
* @def: set if this transport should be considered the default
* @create: member function to create a new connection on this transport
*
* This is the basic API for a transport module which is registered by the
* transport module with the 9P core network module and used by the client
* to instantiate a new connection on a transport.
*
* Bugs: the transport module list isn't protected.
*/
struct p9_trans_module { struct p9_trans_module {
struct list_head list; struct list_head list;
char *name; /* name of transport */ char *name; /* name of transport */
......
...@@ -197,7 +197,7 @@ static void buf_get_qid(struct cbuf *bufp, struct p9_qid *qid) ...@@ -197,7 +197,7 @@ static void buf_get_qid(struct cbuf *bufp, struct p9_qid *qid)
/** /**
* p9_size_wstat - calculate the size of a variable length stat struct * p9_size_wstat - calculate the size of a variable length stat struct
* @stat: metadata (stat) structure * @wstat: metadata (stat) structure
* @dotu: non-zero if 9P2000.u * @dotu: non-zero if 9P2000.u
* *
*/ */
...@@ -511,6 +511,12 @@ p9_create_common(struct cbuf *bufp, u32 size, u8 id) ...@@ -511,6 +511,12 @@ p9_create_common(struct cbuf *bufp, u32 size, u8 id)
return fc; return fc;
} }
/**
* p9_set_tag - set the tag field of an &p9_fcall structure
* @fc: fcall structure to set tag within
* @tag: tag id to set
*/
void p9_set_tag(struct p9_fcall *fc, u16 tag) void p9_set_tag(struct p9_fcall *fc, u16 tag)
{ {
fc->tag = tag; fc->tag = tag;
...@@ -518,6 +524,12 @@ void p9_set_tag(struct p9_fcall *fc, u16 tag) ...@@ -518,6 +524,12 @@ void p9_set_tag(struct p9_fcall *fc, u16 tag)
} }
EXPORT_SYMBOL(p9_set_tag); EXPORT_SYMBOL(p9_set_tag);
/**
* p9_create_tversion - allocates and creates a T_VERSION request
* @msize: requested maximum data size
* @version: version string to negotiate
*
*/
struct p9_fcall *p9_create_tversion(u32 msize, char *version) struct p9_fcall *p9_create_tversion(u32 msize, char *version)
{ {
int size; int size;
...@@ -542,6 +554,16 @@ struct p9_fcall *p9_create_tversion(u32 msize, char *version) ...@@ -542,6 +554,16 @@ struct p9_fcall *p9_create_tversion(u32 msize, char *version)
} }
EXPORT_SYMBOL(p9_create_tversion); EXPORT_SYMBOL(p9_create_tversion);
/**
* p9_create_tauth - allocates and creates a T_AUTH request
* @afid: handle to use for authentication protocol
* @uname: user name attempting to authenticate
* @aname: mount specifier for remote server
* @n_uname: numeric id for user attempting to authneticate
* @dotu: 9P2000.u extension flag
*
*/
struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname, struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname,
u32 n_uname, int dotu) u32 n_uname, int dotu)
{ {
...@@ -580,6 +602,18 @@ struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname, ...@@ -580,6 +602,18 @@ struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname,
} }
EXPORT_SYMBOL(p9_create_tauth); EXPORT_SYMBOL(p9_create_tauth);
/**
* p9_create_tattach - allocates and creates a T_ATTACH request
* @fid: handle to use for the new mount point
* @afid: handle to use for authentication protocol
* @uname: user name attempting to attach
* @aname: mount specifier for remote server
* @n_uname: numeric id for user attempting to attach
* @n_uname: numeric id for user attempting to attach
* @dotu: 9P2000.u extension flag
*
*/
struct p9_fcall * struct p9_fcall *
p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname, p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname,
u32 n_uname, int dotu) u32 n_uname, int dotu)
...@@ -616,6 +650,12 @@ p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname, ...@@ -616,6 +650,12 @@ p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname,
} }
EXPORT_SYMBOL(p9_create_tattach); EXPORT_SYMBOL(p9_create_tattach);
/**
* p9_create_tflush - allocates and creates a T_FLUSH request
* @oldtag: tag id for the transaction we are attempting to cancel
*
*/
struct p9_fcall *p9_create_tflush(u16 oldtag) struct p9_fcall *p9_create_tflush(u16 oldtag)
{ {
int size; int size;
...@@ -639,6 +679,15 @@ struct p9_fcall *p9_create_tflush(u16 oldtag) ...@@ -639,6 +679,15 @@ struct p9_fcall *p9_create_tflush(u16 oldtag)
} }
EXPORT_SYMBOL(p9_create_tflush); EXPORT_SYMBOL(p9_create_tflush);
/**
* p9_create_twalk - allocates and creates a T_FLUSH request
* @fid: handle we are traversing from
* @newfid: a new handle for this transaction
* @nwname: number of path elements to traverse
* @wnames: array of path elements
*
*/
struct p9_fcall *p9_create_twalk(u32 fid, u32 newfid, u16 nwname, struct p9_fcall *p9_create_twalk(u32 fid, u32 newfid, u16 nwname,
char **wnames) char **wnames)
{ {
...@@ -677,6 +726,13 @@ struct p9_fcall *p9_create_twalk(u32 fid, u32 newfid, u16 nwname, ...@@ -677,6 +726,13 @@ struct p9_fcall *p9_create_twalk(u32 fid, u32 newfid, u16 nwname,
} }
EXPORT_SYMBOL(p9_create_twalk); EXPORT_SYMBOL(p9_create_twalk);
/**
* p9_create_topen - allocates and creates a T_OPEN request
* @fid: handle we are trying to open
* @mode: what mode we are trying to open the file in
*
*/
struct p9_fcall *p9_create_topen(u32 fid, u8 mode) struct p9_fcall *p9_create_topen(u32 fid, u8 mode)
{ {
int size; int size;
...@@ -701,6 +757,19 @@ struct p9_fcall *p9_create_topen(u32 fid, u8 mode) ...@@ -701,6 +757,19 @@ struct p9_fcall *p9_create_topen(u32 fid, u8 mode)
} }
EXPORT_SYMBOL(p9_create_topen); EXPORT_SYMBOL(p9_create_topen);
/**
* p9_create_tcreate - allocates and creates a T_CREATE request
* @fid: handle of directory we are trying to create in
* @name: name of the file we are trying to create
* @perm: permissions for the file we are trying to create
* @mode: what mode we are trying to open the file in
* @extension: 9p2000.u extension string (for special files)
* @dotu: 9p2000.u enabled flag
*
* Note: Plan 9 create semantics include opening the resulting file
* which is why mode is included.
*/
struct p9_fcall *p9_create_tcreate(u32 fid, char *name, u32 perm, u8 mode, struct p9_fcall *p9_create_tcreate(u32 fid, char *name, u32 perm, u8 mode,
char *extension, int dotu) char *extension, int dotu)
{ {
...@@ -736,6 +805,13 @@ struct p9_fcall *p9_create_tcreate(u32 fid, char *name, u32 perm, u8 mode, ...@@ -736,6 +805,13 @@ struct p9_fcall *p9_create_tcreate(u32 fid, char *name, u32 perm, u8 mode,
} }
EXPORT_SYMBOL(p9_create_tcreate); EXPORT_SYMBOL(p9_create_tcreate);
/**
* p9_create_tread - allocates and creates a T_READ request
* @fid: handle of the file we are trying to read
* @offset: offset to start reading from
* @count: how many bytes to read
*/
struct p9_fcall *p9_create_tread(u32 fid, u64 offset, u32 count) struct p9_fcall *p9_create_tread(u32 fid, u64 offset, u32 count)
{ {
int size; int size;
...@@ -761,6 +837,17 @@ struct p9_fcall *p9_create_tread(u32 fid, u64 offset, u32 count) ...@@ -761,6 +837,17 @@ struct p9_fcall *p9_create_tread(u32 fid, u64 offset, u32 count)
} }
EXPORT_SYMBOL(p9_create_tread); EXPORT_SYMBOL(p9_create_tread);
/**
* p9_create_twrite - allocates and creates a T_WRITE request from the kernel
* @fid: handle of the file we are trying to write
* @offset: offset to start writing at
* @count: how many bytes to write
* @data: data to write
*
* This function will create a requst with data buffers from the kernel
* such as the page cache.
*/
struct p9_fcall *p9_create_twrite(u32 fid, u64 offset, u32 count, struct p9_fcall *p9_create_twrite(u32 fid, u64 offset, u32 count,
const char *data) const char *data)
{ {
...@@ -794,6 +881,16 @@ struct p9_fcall *p9_create_twrite(u32 fid, u64 offset, u32 count, ...@@ -794,6 +881,16 @@ struct p9_fcall *p9_create_twrite(u32 fid, u64 offset, u32 count,
} }
EXPORT_SYMBOL(p9_create_twrite); EXPORT_SYMBOL(p9_create_twrite);
/**
* p9_create_twrite_u - allocates and creates a T_WRITE request from userspace
* @fid: handle of the file we are trying to write
* @offset: offset to start writing at
* @count: how many bytes to write
* @data: data to write
*
* This function will create a request with data buffers from userspace
*/
struct p9_fcall *p9_create_twrite_u(u32 fid, u64 offset, u32 count, struct p9_fcall *p9_create_twrite_u(u32 fid, u64 offset, u32 count,
const char __user *data) const char __user *data)
{ {
...@@ -827,6 +924,14 @@ struct p9_fcall *p9_create_twrite_u(u32 fid, u64 offset, u32 count, ...@@ -827,6 +924,14 @@ struct p9_fcall *p9_create_twrite_u(u32 fid, u64 offset, u32 count,
} }
EXPORT_SYMBOL(p9_create_twrite_u); EXPORT_SYMBOL(p9_create_twrite_u);
/**
* p9_create_tclunk - allocate a request to forget about a file handle
* @fid: handle of the file we closing or forgetting about
*
* clunk is used both to close open files and to discard transient handles
* which may be created during meta-data operations and hierarchy traversal.
*/
struct p9_fcall *p9_create_tclunk(u32 fid) struct p9_fcall *p9_create_tclunk(u32 fid)
{ {
int size; int size;
...@@ -850,6 +955,12 @@ struct p9_fcall *p9_create_tclunk(u32 fid) ...@@ -850,6 +955,12 @@ struct p9_fcall *p9_create_tclunk(u32 fid)
} }
EXPORT_SYMBOL(p9_create_tclunk); EXPORT_SYMBOL(p9_create_tclunk);
/**
* p9_create_tremove - allocate and create a request to remove a file
* @fid: handle of the file or directory we are removing
*
*/
struct p9_fcall *p9_create_tremove(u32 fid) struct p9_fcall *p9_create_tremove(u32 fid)
{ {
int size; int size;
...@@ -873,6 +984,12 @@ struct p9_fcall *p9_create_tremove(u32 fid) ...@@ -873,6 +984,12 @@ struct p9_fcall *p9_create_tremove(u32 fid)
} }
EXPORT_SYMBOL(p9_create_tremove); EXPORT_SYMBOL(p9_create_tremove);
/**
* p9_create_tstat - allocate and populate a request for attributes
* @fid: handle of the file or directory we are trying to get the attributes of
*
*/
struct p9_fcall *p9_create_tstat(u32 fid) struct p9_fcall *p9_create_tstat(u32 fid)
{ {
int size; int size;
...@@ -896,6 +1013,14 @@ struct p9_fcall *p9_create_tstat(u32 fid) ...@@ -896,6 +1013,14 @@ struct p9_fcall *p9_create_tstat(u32 fid)
} }
EXPORT_SYMBOL(p9_create_tstat); EXPORT_SYMBOL(p9_create_tstat);
/**
* p9_create_tstat - allocate and populate a request to change attributes
* @fid: handle of the file or directory we are trying to change
* @wstat: &p9_stat structure with attributes we wish to set
* @dotu: 9p2000.u enabled flag
*
*/
struct p9_fcall *p9_create_twstat(u32 fid, struct p9_wstat *wstat, struct p9_fcall *p9_create_twstat(u32 fid, struct p9_wstat *wstat,
int dotu) int dotu)
{ {
...@@ -922,3 +1047,4 @@ struct p9_fcall *p9_create_twstat(u32 fid, struct p9_wstat *wstat, ...@@ -922,3 +1047,4 @@ struct p9_fcall *p9_create_twstat(u32 fid, struct p9_wstat *wstat,
return fc; return fc;
} }
EXPORT_SYMBOL(p9_create_twstat); EXPORT_SYMBOL(p9_create_twstat);
...@@ -33,6 +33,13 @@ ...@@ -33,6 +33,13 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <net/9p/9p.h> #include <net/9p/9p.h>
/**
* struct errormap - map string errors from Plan 9 to Linux numeric ids
* @name: string sent over 9P
* @val: numeric id most closely representing @name
* @namelen: length of string
* @list: hash-table list for string lookup
*/
struct errormap { struct errormap {
char *name; char *name;
int val; int val;
...@@ -177,8 +184,7 @@ static struct errormap errmap[] = { ...@@ -177,8 +184,7 @@ static struct errormap errmap[] = {
}; };
/** /**
* p9_error_init - preload * p9_error_init - preload mappings into hash list
* @errstr: error string
* *
*/ */
...@@ -206,6 +212,7 @@ EXPORT_SYMBOL(p9_error_init); ...@@ -206,6 +212,7 @@ EXPORT_SYMBOL(p9_error_init);
/** /**
* errstr2errno - convert error string to error number * errstr2errno - convert error string to error number
* @errstr: error string * @errstr: error string
* @len: length of error string
* *
*/ */
......
...@@ -142,6 +142,14 @@ p9_printdata(char *buf, int buflen, u8 *data, int datalen) ...@@ -142,6 +142,14 @@ p9_printdata(char *buf, int buflen, u8 *data, int datalen)
return p9_dumpdata(buf, buflen, data, datalen < 16?datalen:16); return p9_dumpdata(buf, buflen, data, datalen < 16?datalen:16);
} }
/**
* p9_printfcall - decode and print a protocol structure into a buffer
* @buf: buffer to deposit decoded structure into
* @buflen: available space in buffer
* @fc: protocol rpc structure of type &p9_fcall
* @extended: whether or not session is operating with extended protocol
*/
int int
p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int extended) p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int extended)
{ {
......
...@@ -39,9 +39,6 @@ module_param_named(debug, p9_debug_level, uint, 0); ...@@ -39,9 +39,6 @@ module_param_named(debug, p9_debug_level, uint, 0);
MODULE_PARM_DESC(debug, "9P debugging level"); MODULE_PARM_DESC(debug, "9P debugging level");
#endif #endif
extern int p9_mux_global_init(void);
extern void p9_mux_global_exit(void);
/* /*
* Dynamic Transport Registration Routines * Dynamic Transport Registration Routines
* *
...@@ -52,7 +49,7 @@ static struct p9_trans_module *v9fs_default_transport; ...@@ -52,7 +49,7 @@ static struct p9_trans_module *v9fs_default_transport;
/** /**
* v9fs_register_trans - register a new transport with 9p * v9fs_register_trans - register a new transport with 9p
* @m - structure describing the transport module and entry points * @m: structure describing the transport module and entry points
* *
*/ */
void v9fs_register_trans(struct p9_trans_module *m) void v9fs_register_trans(struct p9_trans_module *m)
...@@ -65,7 +62,7 @@ EXPORT_SYMBOL(v9fs_register_trans); ...@@ -65,7 +62,7 @@ EXPORT_SYMBOL(v9fs_register_trans);
/** /**
* v9fs_match_trans - match transport versus registered transports * v9fs_match_trans - match transport versus registered transports
* @arg: string identifying transport * @name: string identifying transport
* *
*/ */
struct p9_trans_module *v9fs_match_trans(const substring_t *name) struct p9_trans_module *v9fs_match_trans(const substring_t *name)
......
...@@ -47,12 +47,29 @@ ...@@ -47,12 +47,29 @@
#define SCHED_TIMEOUT 10 #define SCHED_TIMEOUT 10
#define MAXPOLLWADDR 2 #define MAXPOLLWADDR 2
/**
* struct p9_fd_opts - per-transport options
* @rfd: file descriptor for reading (trans=fd)
* @wfd: file descriptor for writing (trans=fd)
* @port: port to connect to (trans=tcp)
*
*/
struct p9_fd_opts { struct p9_fd_opts {
int rfd; int rfd;
int wfd; int wfd;
u16 port; u16 port;
}; };
/**
* struct p9_trans_fd - transport state
* @rd: reference to file to read from
* @wr: reference of file to write to
* @conn: connection state reference
*
*/
struct p9_trans_fd { struct p9_trans_fd {
struct file *rd; struct file *rd;
struct file *wr; struct file *wr;
...@@ -90,10 +107,24 @@ enum { ...@@ -90,10 +107,24 @@ enum {
}; };
struct p9_req; struct p9_req;
typedef void (*p9_conn_req_callback)(struct p9_req *req, void *a); typedef void (*p9_conn_req_callback)(struct p9_req *req, void *a);
/**
* struct p9_req - fd mux encoding of an rpc transaction
* @lock: protects req_list
* @tag: numeric tag for rpc transaction
* @tcall: request &p9_fcall structure
* @rcall: response &p9_fcall structure
* @err: error state
* @cb: callback for when response is received
* @cba: argument to pass to callback
* @flush: flag to indicate RPC has been flushed
* @req_list: list link for higher level objects to chain requests
*
*/
struct p9_req { struct p9_req {
spinlock_t lock; /* protect request structure */ spinlock_t lock;
int tag; int tag;
struct p9_fcall *tcall; struct p9_fcall *tcall;
struct p9_fcall *rcall; struct p9_fcall *rcall;
...@@ -104,7 +135,39 @@ struct p9_req { ...@@ -104,7 +135,39 @@ struct p9_req {
struct list_head req_list; struct list_head req_list;
}; };
struct p9_mux_poll_task; struct p9_mux_poll_task {
struct task_struct *task;
struct list_head mux_list;
int muxnum;
};
/**
* struct p9_conn - fd mux connection state information
* @lock: protects mux_list (?)
* @mux_list: list link for mux to manage multiple connections (?)
* @poll_task: task polling on this connection
* @msize: maximum size for connection (dup)
* @extended: 9p2000.u flag (dup)
* @trans: reference to transport instance for this connection
* @tagpool: id accounting for transactions
* @err: error state
* @equeue: event wait_q (?)
* @req_list: accounting for requests which have been sent
* @unsent_req_list: accounting for requests that haven't been sent
* @rcall: current response &p9_fcall structure
* @rpos: read position in current frame
* @rbuf: current read buffer
* @wpos: write position for current frame
* @wsize: amount of data to write for current frame
* @wbuf: current write buffer
* @poll_wait: array of wait_q's for various worker threads
* @poll_waddr: ????
* @pt: poll state
* @rq: current read work
* @wq: current write work
* @wsched: ????
*
*/
struct p9_conn { struct p9_conn {
spinlock_t lock; /* protect lock structure */ spinlock_t lock; /* protect lock structure */
...@@ -132,11 +195,16 @@ struct p9_conn { ...@@ -132,11 +195,16 @@ struct p9_conn {
unsigned long wsched; unsigned long wsched;
}; };
struct p9_mux_poll_task { /**
struct task_struct *task; * struct p9_mux_rpc - fd mux rpc accounting structure
struct list_head mux_list; * @m: connection this request was issued on
int muxnum; * @err: error state
}; * @tcall: request &p9_fcall
* @rcall: response &p9_fcall
* @wqueue: wait queue that client is blocked on for this rpc
*
* Bug: isn't this information duplicated elsewhere like &p9_req
*/
struct p9_mux_rpc { struct p9_mux_rpc {
struct p9_conn *m; struct p9_conn *m;
...@@ -207,10 +275,12 @@ static void p9_mux_put_tag(struct p9_conn *m, u16 tag) ...@@ -207,10 +275,12 @@ static void p9_mux_put_tag(struct p9_conn *m, u16 tag)
/** /**
* p9_mux_calc_poll_procs - calculates the number of polling procs * p9_mux_calc_poll_procs - calculates the number of polling procs
* based on the number of mounted v9fs filesystems. * @muxnum: number of mounts
* *
* Calculation is based on the number of mounted v9fs filesystems.
* The current implementation returns sqrt of the number of mounts. * The current implementation returns sqrt of the number of mounts.
*/ */
static int p9_mux_calc_poll_procs(int muxnum) static int p9_mux_calc_poll_procs(int muxnum)
{ {
int n; int n;
...@@ -331,12 +401,11 @@ static void p9_mux_poll_stop(struct p9_conn *m) ...@@ -331,12 +401,11 @@ static void p9_mux_poll_stop(struct p9_conn *m)
/** /**
* p9_conn_create - allocate and initialize the per-session mux data * p9_conn_create - allocate and initialize the per-session mux data
* Creates the polling task if this is the first session. * @trans: transport structure
* *
* @trans - transport structure * Note: Creates the polling task if this is the first session.
* @msize - maximum message size
* @extended - extended flag
*/ */
static struct p9_conn *p9_conn_create(struct p9_trans *trans) static struct p9_conn *p9_conn_create(struct p9_trans *trans)
{ {
int i, n; int i, n;
...@@ -406,7 +475,10 @@ static struct p9_conn *p9_conn_create(struct p9_trans *trans) ...@@ -406,7 +475,10 @@ static struct p9_conn *p9_conn_create(struct p9_trans *trans)
/** /**
* p9_mux_destroy - cancels all pending requests and frees mux resources * p9_mux_destroy - cancels all pending requests and frees mux resources
* @m: mux to destroy
*
*/ */
static void p9_conn_destroy(struct p9_conn *m) static void p9_conn_destroy(struct p9_conn *m)
{ {
P9_DPRINTK(P9_DEBUG_MUX, "mux %p prev %p next %p\n", m, P9_DPRINTK(P9_DEBUG_MUX, "mux %p prev %p next %p\n", m,
...@@ -429,9 +501,14 @@ static void p9_conn_destroy(struct p9_conn *m) ...@@ -429,9 +501,14 @@ static void p9_conn_destroy(struct p9_conn *m)
} }
/** /**
* p9_pollwait - called by files poll operation to add v9fs-poll task * p9_pollwait - add poll task to the wait queue
* to files wait queue * @filp: file pointer being polled
* @wait_address: wait_q to block on
* @p: poll state
*
* called by files poll operation to add v9fs-poll task to files wait queue
*/ */
static void static void
p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p) p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)
{ {
...@@ -462,7 +539,10 @@ p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p) ...@@ -462,7 +539,10 @@ p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)
/** /**
* p9_poll_mux - polls a mux and schedules read or write works if necessary * p9_poll_mux - polls a mux and schedules read or write works if necessary
* @m: connection to poll
*
*/ */
static void p9_poll_mux(struct p9_conn *m) static void p9_poll_mux(struct p9_conn *m)
{ {
int n; int n;
...@@ -499,9 +579,14 @@ static void p9_poll_mux(struct p9_conn *m) ...@@ -499,9 +579,14 @@ static void p9_poll_mux(struct p9_conn *m)
} }
/** /**
* p9_poll_proc - polls all v9fs transports for new events and queues * p9_poll_proc - poll worker thread
* the appropriate work to the work queue * @a: thread state and arguments
*
* polls all v9fs transports for new events and queues the appropriate
* work to the work queue
*
*/ */
static int p9_poll_proc(void *a) static int p9_poll_proc(void *a)
{ {
struct p9_conn *m, *mtmp; struct p9_conn *m, *mtmp;
...@@ -527,7 +612,10 @@ static int p9_poll_proc(void *a) ...@@ -527,7 +612,10 @@ static int p9_poll_proc(void *a)
/** /**
* p9_write_work - called when a transport can send some data * p9_write_work - called when a transport can send some data
* @work: container for work to be done
*
*/ */
static void p9_write_work(struct work_struct *work) static void p9_write_work(struct work_struct *work)
{ {
int n, err; int n, err;
...@@ -638,7 +726,10 @@ static void process_request(struct p9_conn *m, struct p9_req *req) ...@@ -638,7 +726,10 @@ static void process_request(struct p9_conn *m, struct p9_req *req)
/** /**
* p9_read_work - called when there is some data to be read from a transport * p9_read_work - called when there is some data to be read from a transport
* @work: container of work to be done
*
*/ */
static void p9_read_work(struct work_struct *work) static void p9_read_work(struct work_struct *work)
{ {
int n, err; int n, err;
...@@ -793,7 +884,9 @@ static void p9_read_work(struct work_struct *work) ...@@ -793,7 +884,9 @@ static void p9_read_work(struct work_struct *work)
* @tc: request to be sent * @tc: request to be sent
* @cb: callback function to call when response is received * @cb: callback function to call when response is received
* @cba: parameter to pass to the callback function * @cba: parameter to pass to the callback function
*
*/ */
static struct p9_req *p9_send_request(struct p9_conn *m, static struct p9_req *p9_send_request(struct p9_conn *m,
struct p9_fcall *tc, struct p9_fcall *tc,
p9_conn_req_callback cb, void *cba) p9_conn_req_callback cb, void *cba)
...@@ -961,10 +1054,12 @@ p9_conn_rpc_cb(struct p9_req *req, void *a) ...@@ -961,10 +1054,12 @@ p9_conn_rpc_cb(struct p9_req *req, void *a)
/** /**
* p9_fd_rpc- sends 9P request and waits until a response is available. * p9_fd_rpc- sends 9P request and waits until a response is available.
* The function can be interrupted. * The function can be interrupted.
* @m: mux data * @t: transport data
* @tc: request to be sent * @tc: request to be sent
* @rc: pointer where a pointer to the response is stored * @rc: pointer where a pointer to the response is stored
*
*/ */
int int
p9_fd_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc) p9_fd_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
{ {
...@@ -1041,8 +1136,10 @@ p9_fd_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc) ...@@ -1041,8 +1136,10 @@ p9_fd_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
* @m: mux data * @m: mux data
* @tc: request to be sent * @tc: request to be sent
* @cb: callback function to be called when response arrives * @cb: callback function to be called when response arrives
* @cba: value to pass to the callback function * @a: value to pass to the callback function
*
*/ */
int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc, int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc,
p9_conn_req_callback cb, void *a) p9_conn_req_callback cb, void *a)
{ {
...@@ -1065,7 +1162,9 @@ int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc, ...@@ -1065,7 +1162,9 @@ int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc,
* p9_conn_cancel - cancel all pending requests with error * p9_conn_cancel - cancel all pending requests with error
* @m: mux data * @m: mux data
* @err: error code * @err: error code
*
*/ */
void p9_conn_cancel(struct p9_conn *m, int err) void p9_conn_cancel(struct p9_conn *m, int err)
{ {
struct p9_req *req, *rtmp; struct p9_req *req, *rtmp;
...@@ -1099,7 +1198,7 @@ void p9_conn_cancel(struct p9_conn *m, int err) ...@@ -1099,7 +1198,7 @@ void p9_conn_cancel(struct p9_conn *m, int err)
/** /**
* v9fs_parse_options - parse mount options into session structure * v9fs_parse_options - parse mount options into session structure
* @options: options string passed from mount * @options: options string passed from mount
* @v9ses: existing v9fs session information * @opts: transport-specific structure to parse options into
* *
*/ */
...@@ -1193,11 +1292,12 @@ static int p9_socket_open(struct p9_trans *trans, struct socket *csocket) ...@@ -1193,11 +1292,12 @@ static int p9_socket_open(struct p9_trans *trans, struct socket *csocket)
/** /**
* p9_fd_read- read from a fd * p9_fd_read- read from a fd
* @v9ses: session information * @trans: transport instance state
* @v: buffer to receive data into * @v: buffer to receive data into
* @len: size of receive buffer * @len: size of receive buffer
* *
*/ */
static int p9_fd_read(struct p9_trans *trans, void *v, int len) static int p9_fd_read(struct p9_trans *trans, void *v, int len)
{ {
int ret; int ret;
...@@ -1220,11 +1320,12 @@ static int p9_fd_read(struct p9_trans *trans, void *v, int len) ...@@ -1220,11 +1320,12 @@ static int p9_fd_read(struct p9_trans *trans, void *v, int len)
/** /**
* p9_fd_write - write to a socket * p9_fd_write - write to a socket
* @v9ses: session information * @trans: transport instance state
* @v: buffer to send data from * @v: buffer to send data from
* @len: size of send buffer * @len: size of send buffer
* *
*/ */
static int p9_fd_write(struct p9_trans *trans, void *v, int len) static int p9_fd_write(struct p9_trans *trans, void *v, int len)
{ {
int ret; int ret;
...@@ -1296,6 +1397,7 @@ p9_fd_poll(struct p9_trans *trans, struct poll_table_struct *pt) ...@@ -1296,6 +1397,7 @@ p9_fd_poll(struct p9_trans *trans, struct poll_table_struct *pt)
* @trans: private socket structure * @trans: private socket structure
* *
*/ */
static void p9_fd_close(struct p9_trans *trans) static void p9_fd_close(struct p9_trans *trans)
{ {
struct p9_trans_fd *ts; struct p9_trans_fd *ts;
......
...@@ -55,23 +55,69 @@ static int chan_index; ...@@ -55,23 +55,69 @@ static int chan_index;
#define P9_INIT_MAXTAG 16 #define P9_INIT_MAXTAG 16
#define REQ_STATUS_IDLE 0
#define REQ_STATUS_SENT 1 /**
#define REQ_STATUS_RCVD 2 * enum p9_req_status_t - virtio request status
#define REQ_STATUS_FLSH 3 * @REQ_STATUS_IDLE: request slot unused
* @REQ_STATUS_SENT: request sent to server
* @REQ_STATUS_RCVD: response received from server
* @REQ_STATUS_FLSH: request has been flushed
*
* The @REQ_STATUS_IDLE state is used to mark a request slot as unused
* but use is actually tracked by the idpool structure which handles tag
* id allocation.
*
*/
enum p9_req_status_t {
REQ_STATUS_IDLE,
REQ_STATUS_SENT,
REQ_STATUS_RCVD,
REQ_STATUS_FLSH,
};
/**
* struct p9_req_t - virtio request slots
* @status: status of this request slot
* @wq: wait_queue for the client to block on for this request
*
* The virtio transport uses an array to track outstanding requests
* instead of a list. While this may incurr overhead during initial
* allocation or expansion, it makes request lookup much easier as the
* tag id is a index into an array. (We use tag+1 so that we can accomodate
* the -1 tag for the T_VERSION request).
* This also has the nice effect of only having to allocate wait_queues
* once, instead of constantly allocating and freeing them. Its possible
* other resources could benefit from this scheme as well.
*
*/
struct p9_req_t { struct p9_req_t {
int status; int status;
wait_queue_head_t *wq; wait_queue_head_t *wq;
}; };
/* We keep all per-channel information in a structure. /**
* struct virtio_chan - per-instance transport information
* @initialized: whether the channel is initialized
* @inuse: whether the channel is in use
* @lock: protects multiple elements within this structure
* @vdev: virtio dev associated with this channel
* @vq: virtio queue associated with this channel
* @tagpool: accounting for tag ids (and request slots)
* @reqs: array of request slots
* @max_tag: current number of request_slots allocated
* @sg: scatter gather list which is used to pack a request (protected?)
*
* We keep all per-channel information in a structure.
* This structure is allocated within the devices dev->mem space. * This structure is allocated within the devices dev->mem space.
* A pointer to the structure will get put in the transport private. * A pointer to the structure will get put in the transport private.
*
*/ */
static struct virtio_chan { static struct virtio_chan {
bool initialized; /* channel is initialized */ bool initialized;
bool inuse; /* channel is in use */ bool inuse;
spinlock_t lock; spinlock_t lock;
...@@ -86,7 +132,19 @@ static struct virtio_chan { ...@@ -86,7 +132,19 @@ static struct virtio_chan {
struct scatterlist sg[VIRTQUEUE_NUM]; struct scatterlist sg[VIRTQUEUE_NUM];
} channels[MAX_9P_CHAN]; } channels[MAX_9P_CHAN];
/* Lookup requests by tag */ /**
* p9_lookup_tag - Lookup requests by tag
* @c: virtio channel to lookup tag within
* @tag: numeric id for transaction
*
* this is a simple array lookup, but will grow the
* request_slots as necessary to accomodate transaction
* ids which did not previously have a slot.
*
* Bugs: there is currently no upper limit on request slots set
* here, but that should be constrained by the id accounting.
*/
static struct p9_req_t *p9_lookup_tag(struct virtio_chan *c, u16 tag) static struct p9_req_t *p9_lookup_tag(struct virtio_chan *c, u16 tag)
{ {
/* This looks up the original request by tag so we know which /* This looks up the original request by tag so we know which
...@@ -130,6 +188,15 @@ static unsigned int rest_of_page(void *data) ...@@ -130,6 +188,15 @@ static unsigned int rest_of_page(void *data)
return PAGE_SIZE - ((unsigned long)data % PAGE_SIZE); return PAGE_SIZE - ((unsigned long)data % PAGE_SIZE);
} }
/**
* p9_virtio_close - reclaim resources of a channel
* @trans: transport state
*
* This reclaims a channel by freeing its resources and
* reseting its inuse flag.
*
*/
static void p9_virtio_close(struct p9_trans *trans) static void p9_virtio_close(struct p9_trans *trans)
{ {
struct virtio_chan *chan = trans->priv; struct virtio_chan *chan = trans->priv;
...@@ -151,6 +218,19 @@ static void p9_virtio_close(struct p9_trans *trans) ...@@ -151,6 +218,19 @@ static void p9_virtio_close(struct p9_trans *trans)
kfree(trans); kfree(trans);
} }
/**
* req_done - callback which signals activity from the server
* @vq: virtio queue activity was received on
*
* This notifies us that the server has triggered some activity
* on the virtio channel - most likely a response to request we
* sent. Figure out which requests now have responses and wake up
* those threads.
*
* Bugs: could do with some additional sanity checking, but appears to work.
*
*/
static void req_done(struct virtqueue *vq) static void req_done(struct virtqueue *vq)
{ {
struct virtio_chan *chan = vq->vdev->priv; struct virtio_chan *chan = vq->vdev->priv;
...@@ -169,6 +249,20 @@ static void req_done(struct virtqueue *vq) ...@@ -169,6 +249,20 @@ static void req_done(struct virtqueue *vq)
spin_unlock_irqrestore(&chan->lock, flags); spin_unlock_irqrestore(&chan->lock, flags);
} }
/**
* pack_sg_list - pack a scatter gather list from a linear buffer
* @sg: scatter/gather list to pack into
* @start: which segment of the sg_list to start at
* @limit: maximum segment to pack data to
* @data: data to pack into scatter/gather list
* @count: amount of data to pack into the scatter/gather list
*
* sg_lists have multiple segments of various sizes. This will pack
* arbitrary data into an existing scatter gather list, segmenting the
* data as necessary within constraints.
*
*/
static int static int
pack_sg_list(struct scatterlist *sg, int start, int limit, char *data, pack_sg_list(struct scatterlist *sg, int start, int limit, char *data,
int count) int count)
...@@ -189,6 +283,14 @@ pack_sg_list(struct scatterlist *sg, int start, int limit, char *data, ...@@ -189,6 +283,14 @@ pack_sg_list(struct scatterlist *sg, int start, int limit, char *data,
return index-start; return index-start;
} }
/**
* p9_virtio_rpc - issue a request and wait for a response
* @t: transport state
* @tc: &p9_fcall request to transmit
* @rc: &p9_fcall to put reponse into
*
*/
static int static int
p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc) p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
{ {
...@@ -263,6 +365,16 @@ p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc) ...@@ -263,6 +365,16 @@ p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
return 0; return 0;
} }
/**
* p9_virtio_probe - probe for existence of 9P virtio channels
* @vdev: virtio device to probe
*
* This probes for existing virtio channels. At present only
* a single channel is in use, so in the future more work may need
* to be done here.
*
*/
static int p9_virtio_probe(struct virtio_device *vdev) static int p9_virtio_probe(struct virtio_device *vdev)
{ {
int err; int err;
...@@ -307,11 +419,28 @@ static int p9_virtio_probe(struct virtio_device *vdev) ...@@ -307,11 +419,28 @@ static int p9_virtio_probe(struct virtio_device *vdev)
return err; return err;
} }
/* This sets up a transport channel for 9p communication. Right now
/**
* p9_virtio_create - allocate a new virtio channel
* @devname: string identifying the channel to connect to (unused)
* @args: args passed from sys_mount() for per-transport options (unused)
* @msize: requested maximum packet size
* @extended: 9p2000.u enabled flag
*
* This sets up a transport channel for 9p communication. Right now
* we only match the first available channel, but eventually we couldlook up * we only match the first available channel, but eventually we couldlook up
* alternate channels by matching devname versus a virtio_config entry. * alternate channels by matching devname versus a virtio_config entry.
* We use a simple reference count mechanism to ensure that only a single * We use a simple reference count mechanism to ensure that only a single
* mount has a channel open at a time. */ * mount has a channel open at a time.
*
* Bugs: doesn't allow identification of a specific channel
* to allocate, channels are allocated sequentially. This was
* a pragmatic decision to get things rolling, but ideally some
* way of identifying the channel to attach to would be nice
* if we are going to support multiple channels.
*
*/
static struct p9_trans * static struct p9_trans *
p9_virtio_create(const char *devname, char *args, int msize, p9_virtio_create(const char *devname, char *args, int msize,
unsigned char extended) unsigned char extended)
...@@ -360,6 +489,12 @@ p9_virtio_create(const char *devname, char *args, int msize, ...@@ -360,6 +489,12 @@ p9_virtio_create(const char *devname, char *args, int msize,
return trans; return trans;
} }
/**
* p9_virtio_remove - clean up resources associated with a virtio device
* @vdev: virtio device to remove
*
*/
static void p9_virtio_remove(struct virtio_device *vdev) static void p9_virtio_remove(struct virtio_device *vdev)
{ {
struct virtio_chan *chan = vdev->priv; struct virtio_chan *chan = vdev->priv;
......
...@@ -32,11 +32,23 @@ ...@@ -32,11 +32,23 @@
#include <linux/idr.h> #include <linux/idr.h>
#include <net/9p/9p.h> #include <net/9p/9p.h>
/**
* struct p9_idpool - per-connection accounting for tag idpool
* @lock: protects the pool
* @pool: idr to allocate tag id from
*
*/
struct p9_idpool { struct p9_idpool {
spinlock_t lock; spinlock_t lock;
struct idr pool; struct idr pool;
}; };
/**
* p9_idpool_create - create a new per-connection id pool
*
*/
struct p9_idpool *p9_idpool_create(void) struct p9_idpool *p9_idpool_create(void)
{ {
struct p9_idpool *p; struct p9_idpool *p;
...@@ -52,6 +64,11 @@ struct p9_idpool *p9_idpool_create(void) ...@@ -52,6 +64,11 @@ struct p9_idpool *p9_idpool_create(void)
} }
EXPORT_SYMBOL(p9_idpool_create); EXPORT_SYMBOL(p9_idpool_create);
/**
* p9_idpool_destroy - create a new per-connection id pool
* @p: idpool to destory
*/
void p9_idpool_destroy(struct p9_idpool *p) void p9_idpool_destroy(struct p9_idpool *p)
{ {
idr_destroy(&p->pool); idr_destroy(&p->pool);
...@@ -61,9 +78,9 @@ EXPORT_SYMBOL(p9_idpool_destroy); ...@@ -61,9 +78,9 @@ EXPORT_SYMBOL(p9_idpool_destroy);
/** /**
* p9_idpool_get - allocate numeric id from pool * p9_idpool_get - allocate numeric id from pool
* @p - pool to allocate from * @p: pool to allocate from
* *
* XXX - This seems to be an awful generic function, should it be in idr.c with * Bugs: This seems to be an awful generic function, should it be in idr.c with
* the lock included in struct idr? * the lock included in struct idr?
*/ */
...@@ -94,9 +111,10 @@ EXPORT_SYMBOL(p9_idpool_get); ...@@ -94,9 +111,10 @@ EXPORT_SYMBOL(p9_idpool_get);
/** /**
* p9_idpool_put - release numeric id from pool * p9_idpool_put - release numeric id from pool
* @p - pool to allocate from * @id: numeric id which is being released
* @p: pool to release id into
* *
* XXX - This seems to be an awful generic function, should it be in idr.c with * Bugs: This seems to be an awful generic function, should it be in idr.c with
* the lock included in struct idr? * the lock included in struct idr?
*/ */
...@@ -111,11 +129,13 @@ EXPORT_SYMBOL(p9_idpool_put); ...@@ -111,11 +129,13 @@ EXPORT_SYMBOL(p9_idpool_put);
/** /**
* p9_idpool_check - check if the specified id is available * p9_idpool_check - check if the specified id is available
* @id - id to check * @id: id to check
* @p - pool * @p: pool to check
*/ */
int p9_idpool_check(int id, struct p9_idpool *p) int p9_idpool_check(int id, struct p9_idpool *p)
{ {
return idr_find(&p->pool, id) != NULL; return idr_find(&p->pool, id) != NULL;
} }
EXPORT_SYMBOL(p9_idpool_check); EXPORT_SYMBOL(p9_idpool_check);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment