Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8f40f672 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of ssh://master.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs:
  9p: fix error path during early mount
  9p: make cryptic unknown error from server less scary
  9p: fix flags length in net
  9p: Correct fidpool creation failure in p9_client_create
  9p: use struct mutex instead of struct semaphore
  9p: propagate parse_option changes to client and transports
  fs/9p/v9fs.c (v9fs_parse_options): Handle kstrdup and match_strdup failure.
  9p: Documentation updates
  add match_strlcpy() us it to make v9fs make uname and remotename parsing more robust
parents 8978a318 887b3ece
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -22,6 +22,21 @@

#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 {
	spinlock_t lock; /* protect fidlist */
	struct list_head fidlist;
+44 −13
Original line number Diff line number Diff line
@@ -71,19 +71,19 @@ static match_table_t tokens = {

/**
 * v9fs_parse_options - parse mount options into session structure
 * @options: options string passed from mount
 * @v9ses: existing v9fs session information
 *
 * Return 0 upon success, -ERRNO upon failure.
 */

static void v9fs_parse_options(struct v9fs_session_info *v9ses)
static int v9fs_parse_options(struct v9fs_session_info *v9ses)
{
	char *options;
	substring_t args[MAX_OPT_ARGS];
	char *p;
	int option = 0;
	char *s, *e;
	int ret;
	int ret = 0;

	/* setup defaults */
	v9ses->afid = ~0;
@@ -91,19 +91,26 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses)
	v9ses->cache = 0;

	if (!v9ses->options)
		return;
		return 0;

	options = kstrdup(v9ses->options, GFP_KERNEL);
	if (!options) {
		P9_DPRINTK(P9_DEBUG_ERROR,
			   "failed to allocate copy of option string\n");
		return -ENOMEM;
	}

	while ((p = strsep(&options, ",")) != NULL) {
		int token;
		if (!*p)
			continue;
		token = match_token(p, tokens, args);
		if (token < Opt_uname) {
			ret = match_int(&args[0], &option);
			if (ret < 0) {
			int r = match_int(&args[0], &option);
			if (r < 0) {
				P9_DPRINTK(P9_DEBUG_ERROR,
					"integer field, but no integer?\n");
				ret = r;
				continue;
			}
		}
@@ -125,10 +132,10 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses)
			v9ses->afid = option;
			break;
		case Opt_uname:
			match_strcpy(v9ses->uname, &args[0]);
			match_strlcpy(v9ses->uname, &args[0], PATH_MAX);
			break;
		case Opt_remotename:
			match_strcpy(v9ses->aname, &args[0]);
			match_strlcpy(v9ses->aname, &args[0], PATH_MAX);
			break;
		case Opt_nodevmap:
			v9ses->nodev = 1;
@@ -139,6 +146,13 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses)

		case Opt_access:
			s = match_strdup(&args[0]);
			if (!s) {
				P9_DPRINTK(P9_DEBUG_ERROR,
					   "failed to allocate copy"
					   " of option argument\n");
				ret = -ENOMEM;
				break;
			}
			v9ses->flags &= ~V9FS_ACCESS_MASK;
			if (strcmp(s, "user") == 0)
				v9ses->flags |= V9FS_ACCESS_USER;
@@ -158,6 +172,7 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses)
		}
	}
	kfree(options);
	return ret;
}

/**
@@ -173,6 +188,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
{
	int retval = -EINVAL;
	struct p9_fid *fid;
	int rc;

	v9ses->uname = __getname();
	if (!v9ses->uname)
@@ -190,8 +206,21 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
	v9ses->uid = ~0;
	v9ses->dfltuid = V9FS_DEFUID;
	v9ses->dfltgid = V9FS_DEFGID;
	if (data) {
		v9ses->options = kstrdup(data, GFP_KERNEL);
	v9fs_parse_options(v9ses);
		if (!v9ses->options) {
			P9_DPRINTK(P9_DEBUG_ERROR,
			   "failed to allocate copy of option string\n");
			retval = -ENOMEM;
			goto error;
		}
	}

	rc = v9fs_parse_options(v9ses);
	if (rc < 0) {
		retval = rc;
		goto error;
	}

	v9ses->clnt = p9_client_create(dev_name, v9ses->options);

@@ -233,7 +262,6 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
	return fid;

error:
	v9fs_session_close(v9ses);
	return ERR_PTR(retval);
}

@@ -256,9 +284,12 @@ void v9fs_session_close(struct v9fs_session_info *v9ses)
}

/**
 * v9fs_session_cancel - mark transport as disconnected
 * 	and cancel all pending requests.
 * v9fs_session_cancel - terminate a session
 * @v9ses: session to terminate
 *
 * mark transport as disconnected and cancel all pending requests.
 */

void v9fs_session_cancel(struct v9fs_session_info *v9ses) {
	P9_DPRINTK(P9_DEBUG_ERROR, "cancel session %p\n", v9ses);
	p9_client_disconnect(v9ses->clnt);
+60 −25
Original line number Diff line number Diff line
@@ -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 {
	/* options */
	unsigned char flags;	/* session flags */
	unsigned char nodev;	/* set to 1 if no disable device mapping */
	unsigned short debug;	/* debug level */
	unsigned int afid;	/* authentication fid */
	unsigned int cache;	/* cache mode */
	unsigned char flags;
	unsigned char nodev;
	unsigned short debug;
	unsigned int afid;
	unsigned int cache;

	char *options;		/* copy of mount options */
	char *uname;		/* user name to mount as */
@@ -45,22 +96,6 @@ struct v9fs_session_info {
	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;

struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *,
+1 −1
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@
/**
 * v9fs_vfs_readpage - read an entire page in from 9P
 *
 * @file: file being read
 * @filp: file being read
 * @page: structure to page
 *
 */
+1 −1
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ static inline int dt_type(struct p9_stat *mistat)

/**
 * v9fs_dir_readdir - read a directory
 * @filep: opened file structure
 * @filp: opened file structure
 * @dirent: directory structure ???
 * @filldir: function to populate directory structure ???
 *
Loading