Commit bdcb864c authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag '9p-for-7.1-rc1' of https://github.com/martinetd/linux

Pull 9p updates from Dominique Martinet:

 - 9p access flag fix (cannot change access flag since new mount API implem)

 - some minor cleanup

* tag '9p-for-7.1-rc1' of https://github.com/martinetd/linux:
  9p/trans_xen: replace simple_strto* with kstrtouint
  9p/trans_xen: make cleanup idempotent after dataring alloc errors
  9p: document missing enum values in kernel-doc comments
  9p: fix access mode flags being ORed instead of replaced
  9p: fix memory leak in v9fs_init_fs_context error path
parents f9569c6c 8fc518e4
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -413,7 +413,11 @@ static void v9fs_apply_options(struct v9fs_session_info *v9ses,
	/*
	 * Note that we must |= flags here as session_init already
	 * set basic flags. This adds in flags from parsed options.
	 * Default access flags must be cleared if session options
	 * changes them to avoid mangling the setting.
	 */
	if (ctx->session_opts.flags & V9FS_ACCESS_MASK)
		v9ses->flags &= ~V9FS_ACCESS_MASK;
	v9ses->flags |= ctx->session_opts.flags;
#ifdef CONFIG_9P_FSCACHE
	v9ses->cachetag = ctx->session_opts.cachetag;
+3 −3
Original line number Diff line number Diff line
@@ -312,6 +312,9 @@ static int v9fs_init_fs_context(struct fs_context *fc)
	if (!ctx)
		return -ENOMEM;

	fc->ops = &v9fs_context_ops;
	fc->fs_private = ctx;

	/* initialize core options */
	ctx->session_opts.afid = ~0;
	ctx->session_opts.cache = CACHE_NONE;
@@ -345,9 +348,6 @@ static int v9fs_init_fs_context(struct fs_context *fc)
	ctx->rdma_opts.timeout = P9_RDMA_TIMEOUT;
	ctx->rdma_opts.privport = false;

	fc->ops = &v9fs_context_ops;
	fc->fs_private = ctx;

	return 0;
error:
	fc->need_free = 1;
+35 −3
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@
 * @P9_DEBUG_PKT: packet marshalling/unmarshalling
 * @P9_DEBUG_FSC: FS-cache tracing
 * @P9_DEBUG_VPKT: Verbose packet debugging (full packet dump)
 * @P9_DEBUG_CACHE: cache operations tracing
 * @P9_DEBUG_MMAP: memory-mapped I/O tracing
 *
 * These flags are passed at mount time to turn on various levels of
 * verbosity and tracing which will be output to the system logs.
@@ -68,13 +70,39 @@ void _p9_debug(enum p9_debug_flags level, const char *func,
 * @P9_RSYMLINK: make symlink response
 * @P9_TMKNOD: create a special file object request
 * @P9_RMKNOD: create a special file object response
 * @P9_TLOPEN: open a file for I/O (9P2000.L)
 * @P9_RLOPEN: response with qid and iounit (9P2000.L)
 * @P9_TLCREATE: prepare a handle for I/O on an new file for 9P2000.L
 * @P9_RLCREATE: response with file access information for 9P2000.L
 * @P9_TRENAME: rename request
 * @P9_RRENAME: rename response
 * @P9_TMKDIR: create a directory request
 * @P9_RMKDIR: create a directory response
 * @P9_TVERSION: version handshake request
 * @P9_TREADLINK: read symbolic link target (9P2000.L)
 * @P9_RREADLINK: response with symbolic link target (9P2000.L)
 * @P9_TGETATTR: get file attributes request (9P2000.L)
 * @P9_RGETATTR: get file attributes response (9P2000.L)
 * @P9_TSETATTR: set file attributes request (9P2000.L)
 * @P9_RSETATTR: set file attributes response (9P2000.L)
 * @P9_TXATTRWALK: prepare to read/list extended attributes (9P2000.L)
 * @P9_RXATTRWALK: response with extended attribute size (9P2000.L)
 * @P9_TXATTRCREATE: prepare to set extended attribute (9P2000.L)
 * @P9_RXATTRCREATE: set extended attribute response (9P2000.L)
 * @P9_TREADDIR: read directory entries request (9P2000.L)
 * @P9_RREADDIR: read directory entries response (9P2000.L)
 * @P9_TFSYNC: flush cached file data to storage request (9P2000.L)
 * @P9_RFSYNC: flush cached file data to storage response (9P2000.L)
 * @P9_TLOCK: acquire or release a POSIX record lock (9P2000.L)
 * @P9_RLOCK: POSIX record lock response (9P2000.L)
 * @P9_TGETLOCK: test for existence of POSIX record lock (9P2000.L)
 * @P9_RGETLOCK: POSIX record lock test response (9P2000.L)
 * @P9_TLINK: create a hard link (9P2000.L)
 * @P9_RLINK: hard link response (9P2000.L)
 * @P9_TRENAMEAT: safely rename across directories (9P2000.L)
 * @P9_RRENAMEAT: rename response (9P2000.L)
 * @P9_TUNLINKAT: unlink a file or directory (9P2000.L)
 * @P9_RUNLINKAT: unlink response (9P2000.L)
 * @P9_TMKDIR: create a directory request (9P2000.L)
 * @P9_RMKDIR: create a directory response (9P2000.L)
 * @P9_TVERSION: negotiate protocol version and message size
 * @P9_RVERSION: version handshake response
 * @P9_TAUTH: request to establish authentication channel
 * @P9_RAUTH: response with authentication information
@@ -194,6 +222,10 @@ enum p9_msg_t {
 * @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
 * @P9L_MODE_MASK: mask for protocol mode bits (client-side only)
 * @P9L_DIRECT: disable client-side caching for this file
 * @P9L_NOWRITECACHE: disable write caching for this file
 * @P9L_LOOSE: enable loose cache consistency
 *
 * 9P open modes differ slightly from Posix standard modes.
 * In particular, there are extra modes which specify different
+53 −24
Original line number Diff line number Diff line
@@ -283,25 +283,33 @@ static void xen_9pfs_front_free(struct xen_9pfs_front_priv *priv)

			cancel_work_sync(&ring->work);

			if (!priv->rings[i].intf)
			if (!ring->intf)
				break;
			if (priv->rings[i].irq > 0)
				unbind_from_irqhandler(priv->rings[i].irq, ring);
			if (priv->rings[i].data.in) {
				for (j = 0;
				     j < (1 << priv->rings[i].intf->ring_order);
			if (ring->irq >= 0) {
				unbind_from_irqhandler(ring->irq, ring);
				ring->irq = -1;
			}
			if (ring->data.in) {
				for (j = 0; j < (1 << ring->intf->ring_order);
				     j++) {
					grant_ref_t ref;

					ref = priv->rings[i].intf->ref[j];
					ref = ring->intf->ref[j];
					gnttab_end_foreign_access(ref, NULL);
					ring->intf->ref[j] = INVALID_GRANT_REF;
				}
				free_pages_exact(priv->rings[i].data.in,
				   1UL << (priv->rings[i].intf->ring_order +
				free_pages_exact(ring->data.in,
						 1UL << (ring->intf->ring_order +
							 XEN_PAGE_SHIFT));
				ring->data.in = NULL;
				ring->data.out = NULL;
			}
			gnttab_end_foreign_access(priv->rings[i].ref, NULL);
			free_page((unsigned long)priv->rings[i].intf);
			if (ring->ref != INVALID_GRANT_REF) {
				gnttab_end_foreign_access(ring->ref, NULL);
				ring->ref = INVALID_GRANT_REF;
			}
			free_page((unsigned long)ring->intf);
			ring->intf = NULL;
		}
		kfree(priv->rings);
	}
@@ -334,6 +342,12 @@ static int xen_9pfs_front_alloc_dataring(struct xenbus_device *dev,
	int ret = -ENOMEM;
	void *bytes = NULL;

	ring->intf = NULL;
	ring->data.in = NULL;
	ring->data.out = NULL;
	ring->ref = INVALID_GRANT_REF;
	ring->irq = -1;

	init_waitqueue_head(&ring->wq);
	spin_lock_init(&ring->lock);
	INIT_WORK(&ring->work, p9_xen_response);
@@ -379,9 +393,18 @@ static int xen_9pfs_front_alloc_dataring(struct xenbus_device *dev,
		for (i--; i >= 0; i--)
			gnttab_end_foreign_access(ring->intf->ref[i], NULL);
		free_pages_exact(bytes, 1UL << (order + XEN_PAGE_SHIFT));
		ring->data.in = NULL;
		ring->data.out = NULL;
	}
	if (ring->ref != INVALID_GRANT_REF) {
		gnttab_end_foreign_access(ring->ref, NULL);
		ring->ref = INVALID_GRANT_REF;
	}
	if (ring->intf) {
		free_page((unsigned long)ring->intf);
		ring->intf = NULL;
	}
	ring->irq = -1;
	return ret;
}

@@ -390,23 +413,29 @@ static int xen_9pfs_front_init(struct xenbus_device *dev)
	int ret, i;
	struct xenbus_transaction xbt;
	struct xen_9pfs_front_priv *priv;
	char *versions, *v;
	unsigned int max_rings, max_ring_order, len = 0;
	char *versions, *v, *token;
	bool version_1 = false;
	unsigned int max_rings, max_ring_order, len = 0, version;

	versions = xenbus_read(XBT_NIL, dev->otherend, "versions", &len);
	if (IS_ERR(versions))
		return PTR_ERR(versions);
	for (v = versions; *v; v++) {
		if (simple_strtoul(v, &v, 10) == 1) {
			v = NULL;
			break;
	for (v = versions; (token = strsep(&v, ",")); ) {
		if (!*token)
			continue;

		ret = kstrtouint(token, 10, &version);
		if (ret) {
			kfree(versions);
			return ret;
		}
		if (version == 1)
			version_1 = true;
	}
	if (v) {
	kfree(versions);
	if (!version_1)
		return -EINVAL;
	}
	kfree(versions);

	max_rings = xenbus_read_unsigned(dev->otherend, "max-rings", 0);
	if (max_rings < XEN_9PFS_NUM_RINGS)
		return -EINVAL;