[PATCH] 9p: return NULL when trans not found
v9fs_match_trans function returns arbitrary transport module instead of NULL when the requested transport is not registered. This patch modifies the function to return NULL in that case. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- commit 25ed88ed319e40fb6426e2aaefcc5f136aadd4ee tree 281feda9127a85178d44faca59a13645d08e314d parent 0c0b7fa3d4e80ab3e4e69b8a55661f649d1b41ff author Latchesar Ionkov <[EMAIL PROTECTED]> 1193438318 -0600 committer Latchesar Ionkov <[EMAIL PROTECTED]> 1193438318 -0600 net/9p/mod.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/9p/mod.c b/net/9p/mod.c index 41d70f4..8f9763a 100644 --- a/net/9p/mod.c +++ b/net/9p/mod.c @@ -76,9 +76,9 @@ struct p9_trans_module *v9fs_match_trans(const substring_t *name) list_for_each(p, &v9fs_trans_list) { t = list_entry(p, struct p9_trans_module, list); if (strncmp(t->name, name->from, name->to-name->from) == 0) - break; + return t; } - return t; + return NULL; } EXPORT_SYMBOL(v9fs_match_trans); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] 9p: add missing end-of-options record for trans_fd
The list of options that the fd transport accepts is missing end-of-options marker. This patch adds it. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- commit 70ec0c7936c2516d128fdb1a32d749071b8846ec tree 8de5495f83b94096825f8bfe0767e4fcbaf36ef3 parent 25ed88ed319e40fb6426e2aaefcc5f136aadd4ee author Latchesar Ionkov <[EMAIL PROTECTED]> 1193438452 -0600 committer Latchesar Ionkov <[EMAIL PROTECTED]> 1193438452 -0600 net/9p/trans_fd.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 30269a4..62332ed 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -62,13 +62,14 @@ struct p9_trans_fd { enum { /* Options that take integer arguments */ - Opt_port, Opt_rfdno, Opt_wfdno, + Opt_port, Opt_rfdno, Opt_wfdno, Opt_err, }; static match_table_t tokens = { {Opt_port, "port=%u"}, {Opt_rfdno, "rfdno=%u"}, {Opt_wfdno, "wfdno=%u"}, + {Opt_err, NULL}, }; /** - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] 9p: use copy of the options value instead of original
v9fs_parse_options function uses strsep which modifies the value of the v9ses->options field. That modified value is later passed to the function that creates the transport potentially making the transport creation function to fail. This patch creates a copy of v9ses->option field that v9fs_parse_options function uses instead of the original value. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- commit 0c0b7fa3d4e80ab3e4e69b8a55661f649d1b41ff tree eeb4ac6ea85387c153e3f7f6cad370e1c5dc8534 parent c9927c2bf4f45bb85e8b502ab3fb79ad6483c244 author Latchesar Ionkov <[EMAIL PROTECTED]> 1193438132 -0600 committer Latchesar Ionkov <[EMAIL PROTECTED]> 1193438132 -0600 fs/9p/v9fs.c |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 756f7e9..fbb12da 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c @@ -82,7 +82,7 @@ static match_table_t tokens = { static void v9fs_parse_options(struct v9fs_session_info *v9ses) { - char *options = v9ses->options; + char *options; substring_t args[MAX_OPT_ARGS]; char *p; int option; @@ -96,9 +96,10 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses) v9ses->cache = 0; v9ses->trans = v9fs_default_trans(); - if (!options) + if (!v9ses->options) return; + options = kstrdup(v9ses->options, GFP_KERNEL); while ((p = strsep(&options, ",")) != NULL) { int token; if (!*p) @@ -169,6 +170,7 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses) continue; } } + kfree(options); } /** - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: CTL_UNNUMBERED (Re: [PATCH] 9p: Don't use binary sysctl numbers.)
It doesn't really matter (for me) whether it is sysctl or sysfs interface. The sysctl approach seemed easier to implement. If the consensus is to use sysfs, I'll send a patch (for 2.6.24). Sorry for the incorrect implementation, I guess I stole the code from unappropriate place :) Thanks, Lucho On 7/23/07, Eric Van Hensbergen <[EMAIL PROTECTED]> wrote: On 7/21/07, Eric W. Biederman <[EMAIL PROTECTED]> wrote: > Alexey Dobriyan <[EMAIL PROTECTED]> writes: > > > > > That's separate patch but CTL_UNNUMBERED must die, because it's totally > > unneeded. If you don't want sysctl(2) interface just SKIP ->ctl_name > > initialization and save one line for something useful. > > As for the 9p code it doesn't seem to need or want a real binary > interface. The 9p debug code picking of a semi-random number and not > patching it into sysctl.h like it should for a binary interface is > an implementation bug, and a maintenance problem. > Now that -rc1 is out, lets talk a bit more about this. Lucho can you provide some level of justification of why you went for a sysctl interface versus something directly accessible within the file system -- that would seem more on-par with the 9p philosophy. Perhaps its time for a general cleanup of the debug_level stuff -- it was always ugly to have it as a global, but there was just no clear way to have the session structure available everywhere we use it. -eric - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [kvm-devel] [RFC] 9p: add KVM/QEMU pci transport
On 8/28/07, Arnd Bergmann <[EMAIL PROTECTED]> wrote: > On Tuesday 28 August 2007, Eric Van Hensbergen wrote: > > > This adds a shared memory transport for a synthetic 9p device for > > paravirtualized file system support under KVM/QEMU. > > Nice driver. I'm hoping we can do a virtio driver using a similar > concept. > > > +#define PCI_VENDOR_ID_9P 0x5002 > > +#define PCI_DEVICE_ID_9P 0x000D > > Where do these numbers come from? Can we be sure they don't conflict with > actual hardware? I stole the VENDOR_ID from kvm's hypercall driver. There are no any guarantees that it doesn't conflict with actual hardware. As it was discussed before, there is still no ID assigned for the virtual devices. > > +struct p9pci_trans { > > + struct pci_dev *pdev; > > + void __iomem*ioaddr; > > + void __iomem*tx; > > + void __iomem*rx; > > + int irq; > > + int pos; > > + int len; > > + wait_queue_head_t wait; > > +}; > > I would expect the data structure to contain an embedded struct p9_trans, > which is how most drivers work nowadays. > > > +static struct p9pci_trans *p9pci_trans; /* single channel for now */ > > As a result, it should be easier to get rid of this global. My feeling is > that it really should not be here. > > > +static irqreturn_t p9pci_interrupt(int irq, void *dev) > > +{ > > + p9pci_trans = dev; > > This can simply use a local variable. > > > + p9pci_trans->len = le32_to_cpu(readl(p9pci_trans->rx)); > > readl implies le32_to_cpu. Doing it twice on a PCI device is broken > on big-endian hardware. > > > + P9_DPRINTK(P9_DEBUG_TRANS, "%p len %d\n", p9pci_trans->pdev, > > + p9pci_trans->len); > > + iowrite32(0, p9pci_trans->ioaddr + 4); > > Also, you should not mix iowriteXX/ioreadXX and writeX/readX calls in one > driver. Since you use pci_iomap, iowriteXX/ioreadXX are the correct functions. > > > + wake_up_interruptible(&p9pci_trans->wait); > > + return IRQ_HANDLED; > > +} > > + > > +static int p9pci_read(struct p9_trans *trans, void *v, int len) > > +{ > > + struct p9pci_trans *ts; > > + > > + if (!trans || trans->status == Disconnected || !trans->priv) > > + return -EREMOTEIO; > > + > > + ts = trans->priv; > > + > > + P9_DPRINTK(P9_DEBUG_TRANS, "trans %p rx %p tx %p buf %p len %d\n", > > + trans, ts->rx, ts->tx, v, > > len); > > + if (len > ts->len) > > + len = ts->len; > > + > > + if (len) { > > + memcpy_fromio(v, ts->rx, len); > > + ts->len = 0; > > + /* let the host knows the message is consumed */ > > + writel(0, ts->rx); > > + iowrite32(0, p9pci_trans->ioaddr + 4); > > + P9_DPRINTK(P9_DEBUG_TRANS, "zero rxlen %d txlen %d\n", > > + readl(ts->rx), readl(ts->tx)); > > + } > > + > > + return len; > > +} > > I would expect memcpy_fromio and memcpy_toio to be relatively inefficient > compared to virtual DMA, depending on the hypervisor. Do you have plans > to change that, or did you have specific reasons to do the memcpy here? No specific reasons. We wanted to start with simple and easy transport and make things work before we start optimizing it. There are many areas where the transport can be improved, using virtual DMA sounds like a good suggestion. > > > + P9_DPRINTK(P9_DEBUG_TRANS, "trans %p rx %p tx %p buf %p len %d\n", > > + trans, ts->rx, ts->tx, v, > > len); > > + P9_DPRINTK(P9_DEBUG_TRANS, "rxlen %d\n", readl(ts->rx)); > > + if (readb(ts->tx) != 0) > > + return 0; > > + > > + P9_DPRINTK(P9_DEBUG_TRANS, "tx addr %p io addr %p\n", ts->tx, > > + ts->ioaddr); > > All these P9_DPRINTK statements somewhat limit readability. I would suggest > you kill them as soon as the driver is considered stable. > > > +static int __devinit p9pci_probe(struct pci_dev *pdev, > > + const struct pci_device_id *ent) > > +{ > > + int err; > > + u8 pci_rev; > > + > > + if (p9pci_trans) > > + return -1; > > probe should return -EBUSY or similar, not -1. > > > + pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev); > > + > > + if (pdev->vendor == PCI_VENDOR_ID_9P && > > + pdev->device == PCI_DEVICE_ID_9P) > > + printk(KERN_INFO "pci dev %s (id %04x:%04x rev %02x) is a > > 9P\n", > > +pci_name(pdev), pdev->vendor, pdev->device, pci_rev); > > You wouldn't be here for a different vendor/device code, so the check is > bogus. > > > + P9_DPRINTK(P9_DEBUG_TRANS, "%p\n", pdev); > > + p9pci_trans = kzalloc(sizeof(*p9pci_trans), GFP_KERNEL); > > + p9pci_trans->irq = -1; >
Re: [V9fs-developer] [kvm-devel] [RFC] 9p: add KVM/QEMU pci transport
That's also in our plans. There was no virtio support in KVM when I started working in the transport. Thanks, Lucho On 8/29/07, Anthony Liguori <[EMAIL PROTECTED]> wrote: > I think that it would be nicer to implement the p9 transport on top of > virtio instead of directly on top of PCI. I think your PCI transport > would make a pretty nice start of a PCI virtio transport though. > > Regards, > > Anthony Liguori > > On Tue, 2007-08-28 at 13:52 -0500, Eric Van Hensbergen wrote: > > From: Latchesar Ionkov <[EMAIL PROTECTED]> > > > > This adds a shared memory transport for a synthetic 9p device for > > paravirtualized file system support under KVM/QEMU. > > > > Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> > > Signed-off-by: Eric Van Hensbergen <[EMAIL PROTECTED]> > > --- > > Documentation/filesystems/9p.txt |2 + > > net/9p/Kconfig | 10 ++- > > net/9p/Makefile |4 + > > net/9p/trans_pci.c | 295 > > ++ > > 4 files changed, 310 insertions(+), 1 deletions(-) > > create mode 100644 net/9p/trans_pci.c > > > > diff --git a/Documentation/filesystems/9p.txt > > b/Documentation/filesystems/9p.txt > > index 1a5f50d..e1879bd 100644 > > --- a/Documentation/filesystems/9p.txt > > +++ b/Documentation/filesystems/9p.txt > > @@ -46,6 +46,8 @@ OPTIONS > > tcp - specifying a normal TCP/IP connection > > fd - used passed file descriptors for connection > > (see rfdno and wfdno) > > + pci - use a PCI pseudo device for 9p communication > > + over shared memory between a guest and host > > > >uname=name user name to attempt mount as on the remote server. The > > server may override or ignore this value. Certain user > > diff --git a/net/9p/Kconfig b/net/9p/Kconfig > > index 09566ae..8517560 100644 > > --- a/net/9p/Kconfig > > +++ b/net/9p/Kconfig > > @@ -16,13 +16,21 @@ menuconfig NET_9P > > config NET_9P_FD > > depends on NET_9P > > default y if NET_9P > > - tristate "9P File Descriptor Transports (Experimental)" > > + tristate "9p File Descriptor Transports (Experimental)" > > help > > This builds support for file descriptor transports for 9p > > which includes support for TCP/IP, named pipes, or passed > > file descriptors. TCP/IP is the default transport for 9p, > > so if you are going to use 9p, you'll likely want this. > > > > +config NET_9P_PCI > > + depends on NET_9P > > + tristate "9p PCI Shared Memory Transport (Experimental)" > > + help > > + This builds support for a PCI psuedo-device currently available > > + under KVM/QEMU which allows for 9p transactions over shared > > + memory between the guest and the host. > > + > > config NET_9P_DEBUG > > bool "Debug information" > > depends on NET_9P > > diff --git a/net/9p/Makefile b/net/9p/Makefile > > index 7b2a67a..26ce89d 100644 > > --- a/net/9p/Makefile > > +++ b/net/9p/Makefile > > @@ -1,5 +1,6 @@ > > obj-$(CONFIG_NET_9P) := 9pnet.o > > obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o > > +obj-$(CONFIG_NET_9P_PCI) += 9pnet_pci.o > > > > 9pnet-objs := \ > > mod.o \ > > @@ -14,3 +15,6 @@ obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o > > > > 9pnet_fd-objs := \ > > trans_fd.o \ > > + > > +9pnet_pci-objs := \ > > + trans_pci.o \ > > diff --git a/net/9p/trans_pci.c b/net/9p/trans_pci.c > > new file mode 100644 > > index 000..36ddc5f > > --- /dev/null > > +++ b/net/9p/trans_pci.c > > @@ -0,0 +1,295 @@ > > +/* > > + * net/9p/trans_pci.c > > + * > > + * 9P over PCI transport layer. For use with KVM/QEMU. > > + * > > + * Copyright (C) 2007 by Latchesar Ionkov <[EMAIL PROTECTED]> > > + * > > + * This program is free software; you can redistribute it and/or modify > > + * it under the terms of the GNU General Public License version 2 > > + * as published by the Free Software Foundation. > > + * > > + * This program is distributed in the hope that it will be useful, > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > > + * GNU General Public L
[PATCH] 9p: attach-per-user
The 9P2000 protocol requires the authentication and permission checks to be done in the file server. For that reason every user that accesses the file server tree has to authenticate and attach to the server separately. Multiple users can share the same connection to the server. Currently v9fs does a single attach and executes all I/O operations as a single user. This makes using v9fs in multiuser environment unsafe as it depends on the client doing the permission checking. This patch improves the 9P2000 support by allowing every user to attach separately. The patch defines three modes of access (new mount option 'access'): - attach-per-user (access=user) If a user tries to access a file served by v9fs for the first time, v9fs sends an attach command to the server (Tattach) specifying the user. If the attach succeeds, the user can access the v9fs tree. As there is no uname->uid (string->integer) mapping yet, this mode works only with the 9P2000.u dialect. - allow only one user to access the tree (access=) Only the user with uid can access the v9fs tree. Other users that attempt to access it will get EPERM error. - do all operations as a single user (access=any) V9fs does a single attach and all operations are done as a single user. If this mode is selected, the v9fs behavior is identical with the current one. The patch also renames uid and gid options to dfltuid and dfltgid. The new names describe better the values they set. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- commit 836f166ce5578b084c1cd75807e29474586bab61 tree c7e1eb631c3e6b0f1cd773ae7884379776c2857d parent 3ec910913c8c743cbe4cd9cdde17df26a75d02ec author Latchesar Ionkov <[EMAIL PROTECTED](none)> Mon, 03 Sep 2007 14:09:29 -0600 committer Latchesar Ionkov <[EMAIL PROTECTED](none)> Mon, 03 Sep 2007 14:09:29 -0600 fs/9p/fid.c | 157 +-- fs/9p/v9fs.c| 87 +++--- fs/9p/v9fs.h| 27 +++- fs/9p/vfs_inode.c | 52 include/net/9p/9p.h |7 +- include/net/9p/client.h |5 + net/9p/client.c | 10 ++- net/9p/conv.c | 32 -- 8 files changed, 278 insertions(+), 99 deletions(-) diff --git a/fs/9p/fid.c b/fs/9p/fid.c index 15e05a1..b16b14b 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c @@ -1,6 +1,7 @@ /* * V9FS FID Management * + * Copyright (C) 2007 by Latchesar Ionkov <[EMAIL PROTECTED]> * Copyright (C) 2005, 2006 by Eric Van Hensbergen <[EMAIL PROTECTED]> * * This program is free software; you can redistribute it and/or modify @@ -34,9 +35,9 @@ #include "fid.h" /** - * v9fs_fid_insert - add a fid to a dentry + * v9fs_fid_add - add a fid to a dentry + * @dentry: dentry that the fid is being added to * @fid: fid to add - * @dentry: dentry that it is being added to * */ @@ -66,52 +67,144 @@ int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid) } /** - * v9fs_fid_lookup - return a locked fid from a dentry + * v9fs_fid_find - retrieve a fid that belongs to the specified uid * @dentry: dentry to look for fid in - * - * find a fid in the dentry, obtain its semaphore and return a reference to it. - * code calling lookup is responsible for releasing lock - * - * TODO: only match fids that have the same uid as current user + * @uid: return fid that belongs to the specified user + * @any: if non-zero, return any fid associated with the dentry * */ -struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) +static struct p9_fid *v9fs_fid_find(struct dentry *dentry, u32 uid, int any) { struct v9fs_dentry *dent; - struct p9_fid *fid; - - P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); - dent = dentry->d_fsdata; - if (dent) - fid = list_entry(dent->fidlist.next, struct p9_fid, dlist); - else - fid = ERR_PTR(-EBADF); + struct p9_fid *fid, *ret; + + P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p) uid %d any %d\n", + dentry->d_iname, dentry, uid, any); + dent = (struct v9fs_dentry *) dentry->d_fsdata; + ret = NULL; + if (dent) { + spin_lock(&dent->lock); + list_for_each_entry(fid, &dent->fidlist, dlist) { + if (any || fid->uid == uid) { + ret = fid; + break; + } + } + spin_unlock(&dent->lock); + } - P9_DPRINTK(P9_DEBUG_VFS, " fid: %p\n", fid); - return fid; + return ret; } /** - * v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and - * release it + * v9fs_fid_lookup - lookup for a fid, try to walk if not found * @dentry: dentry to look for fid in * - * find a fid in the den
Re: net/9p/mux.c: use-after-free
Yep, it's a leak. Thanks, Lucho On 7/25/07, Eric Van Hensbergen <[EMAIL PROTECTED]> wrote: On 7/22/07, Adrian Bunk <[EMAIL PROTECTED]> wrote: > The Coverity checker spotted the following use-after-free > in net/9p/mux.c: > > <-- snip --> > > ... > struct p9_conn *p9_conn_create(struct p9_transport *trans, int msize, > unsigned char *extended) > { > ... > if (!m->tagpool) { > kfree(m); > return ERR_PTR(PTR_ERR(m->tagpool)); > } > ... > > <-- snip --> > I've got a fix for this one: if (!m->tagpool) { mtmp = ERR_PTR(PTR_ERR(m->tagpool)); kfree(m); return mtmp; } but I was wondering about one of the other returns further down the function: ... memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); m->poll_task = NULL; n = p9_mux_poll_start(m); if (n) return ERR_PTR(n); n = trans->poll(trans, &m->pt); ... lucho: doesn't that constitute a leak? Shouldn't we be doing: if (n) { kfree(m); return ERR_PTR(n); } -eric - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] 9p: v9fs_vfs_rename incorrect clunk order
In v9fs_vfs_rename function labels don't match the fids that are clunked. The correct clunk order is clunking newdirfid first and then olddirfid next. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- commit 0c9269a1384273b7a409a2163fdf91cd39092889 tree 8a4984196ccb7ed027c086a53866e5582835e61f parent 55b70a0300b873c0ec7ea6e33752af56f41250ce author Latchesar Ionkov <[EMAIL PROTECTED]> Mon, 22 Oct 2007 18:11:19 -0600 committer Latchesar Ionkov <[EMAIL PROTECTED]> Mon, 22 Oct 2007 18:11:19 -0600 fs/9p/vfs_inode.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 175b4d9..23581bc 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -687,10 +687,10 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, retval = p9_client_wstat(oldfid, &wstat); clunk_newdir: - p9_client_clunk(olddirfid); + p9_client_clunk(newdirfid); clunk_olddir: - p9_client_clunk(newdirfid); + p9_client_clunk(olddirfid); done: return retval; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] 9p: fix memory leak in v9fs_get_sb
This patch fixes a memory leak in v9fs_get_sb. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- commit 77250c234636881976ebd567f9edc7c36711bd4a tree 35d683472542706a3b78eb51bc29b92f690c314a parent 01e7ae8c13bb06a2ce622ebace33bb7e28ef596c author Latchesar Ionkov <[EMAIL PROTECTED]> 1193169149 -0600 committer Latchesar Ionkov <[EMAIL PROTECTED]> 1193169149 -0600 fs/9p/vfs_super.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index bb0cef9..678c02f 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c @@ -119,6 +119,7 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, P9_DPRINTK(P9_DEBUG_VFS, " \n"); + st = NULL; v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL); if (!v9ses) return -ENOMEM; @@ -164,10 +165,12 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, root->d_inode->i_ino = v9fs_qid2ino(&st->qid); v9fs_stat2inode(st, root->d_inode, sb); v9fs_fid_add(root, fid); + kfree(st); return simple_set_mnt(mnt, sb); error: + kfree(st); if (fid) p9_client_clunk(fid); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 9/10] 9p: tcp listener implementation
This patch adds a TCP listener for the trans_fd transport. The listener allows the in-kernel servers to listen on a TCP port for client connections. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- net/9p/mux.c | 269 +- 1 files changed, 265 insertions(+), 4 deletions(-) diff --git a/net/9p/mux.c b/net/9p/mux.c index ace135a..ad2e9a4 100644 --- a/net/9p/mux.c +++ b/net/9p/mux.c @@ -64,6 +64,7 @@ struct p9_trans_fd { struct file *rd;/* read descriptor */ struct file *wr;/* write descriptor */ u32 msize; + int client; /* non-zero if client transport */ struct list_head trans_list; struct p9fd_poll_task *poll_task; wait_queue_head_t equeue; @@ -90,6 +91,7 @@ enum { Rpending = 2, /* can read */ Wworksched = 4, /* write work scheduled or running */ Wpending = 8, /* can write */ + Destroy = 9, }; @@ -112,6 +114,15 @@ enum { Flushed, }; +struct p9fd_tcp_listener { + struct sockaddr_in saddr; + struct socket *sock; + struct p9_trans_listenerlistener; + struct work_struct wq; + void(*dr_save)(struct sock *, int); + u32 msize; +}; + enum { /* Options that take integer arguments */ Opt_port, Opt_rfdno, Opt_wfdno, Opt_msize, @@ -145,6 +156,10 @@ static struct p9_trans *p9fd_create_unix_client(const char *devname, char *options); static struct p9_trans *p9fd_create_fd_client(const char *devname, char *options); +static struct p9_trans_listener *p9fd_listener_create(char *); +static void p9fd_trans_listener_destroy(struct p9_trans_listener *); +static void p9fd_tcp_data_ready(struct sock *sock, int count); +static void p9fd_tcp_accept(struct work_struct *work); static DEFINE_MUTEX(p9fd_task_lock); static struct workqueue_struct *p9fd_wq; @@ -158,6 +173,7 @@ static struct p9_trans_module p9_tcp_trans = { .maxsize = MAX_SOCK_BUF, .def = 1, .create_client = p9fd_create_tcp_client, + .create_listener = p9fd_listener_create, }; static struct p9_trans_module p9_unix_trans = { @@ -292,8 +308,9 @@ static void p9fd_poll_stop(struct p9_trans_fd *trans) * @rfd - read file descriptor * @wfd - write file descriptor * @msize - maximum message size + * @client - nonzero if client transport */ -struct p9_trans *p9fd_trans_create(int rfd, int wfd, u32 msize) +struct p9_trans *p9fd_trans_create(int rfd, int wfd, u32 msize, int client) { int i, n, err; struct p9_trans *trans; @@ -317,6 +334,7 @@ struct p9_trans *p9fd_trans_create(int rfd, int wfd, u32 msize) spin_lock_init(&ts->lock); ts->trans = trans; ts->msize = msize; + ts->client = client; ts->rd = fget(rfd); ts->wr = fget(wfd); if (!ts->rd || !ts->wr) { @@ -386,6 +404,9 @@ void p9fd_trans_destroy(struct p9_trans *trans) struct p9_trans_fd *ts; ts = trans->priv; + if (test_and_set_bit(Destroy, &ts->wsched)) + return; + P9_DPRINTK(P9_DEBUG_TRANS, "trans %p prev %p next %p\n", ts, ts->trans_list.prev, ts->trans_list.next); p9fd_trans_shutdown(ts, -ECONNRESET); @@ -426,6 +447,9 @@ static void p9fd_trans_shutdown(struct p9_trans_fd *ts, int err) (*fdreq->req->cb)(trans, fdreq->req); kfree(fdreq); } + + if (!ts->client && !test_bit(Destroy, &ts->wsched)) + (*trans->request)(trans, NULL); } /** @@ -540,7 +564,11 @@ static void p9fd_fill_wbuf(struct p9_trans_fd *ts) req = list_first_entry(&ts->unsent_req_list, struct p9fd_trans_req, req_list); - tc = req->req->tc; + if (ts->client) + tc = req->req->tc; + else + tc = req->req->rc; + P9_DPRINTK(P9_DEBUG_TRANS, "tag %d size %d\n", tc->tag, tc->size); if (tc->size + ts->wsize > ts->msize) { @@ -710,6 +738,9 @@ void p9fd_client_request(struct p9_trans *trans, struct p9_trans_req *req) struct p9_trans_fd *ts; struct p9fd_trans_req *fdreq; + if (trans->err) + return; + ts = trans->priv; P9_DPRINTK(P9_DEBUG_TRANS, "trans %p tag %d\n", ts, req->tag); fdreq = p9fd_req_create(ts, req); @@ -810,6 +841,94 @@ int p9fd_client_rcvd(struct p9_trans_fd *ts, u16 tag, int start, int count) return 0; } +int p9fd_server_sent(struct p9_trans_fd *ts, struct p9fd_trans_req *fdreq) +{ +
[PATCH 7/10] 9p: sysfs support for in-kenel servers
Sysfs support for 9P servers. Every server type is represented as a directory in /sys/fs/9p/srv. Initially there is a single file in the directory -- 'clone'. Reading from the clone file creates a new instance of the file server and returns its id. Each instance is represented as a directory in /sys/fs/9p/srv//. The file server instance can be controlled by the 'ctl' file in its directory. Currently the ctl file accepts the following commands: listen-add listen-del destroy Example: echo 'listen-add tcp port=564' > /sys/fs/9p/srv/ramfs/0/ctl Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- include/net/9p/srv.h | 24 +++- net/9p/srv.c | 386 +- 2 files changed, 405 insertions(+), 5 deletions(-) diff --git a/include/net/9p/srv.h b/include/net/9p/srv.h index 72d011e..a81ae8f 100644 --- a/include/net/9p/srv.h +++ b/include/net/9p/srv.h @@ -69,11 +69,17 @@ struct p9srv { void(*wstat)(struct p9srv_req *); /* implementation specific */ + int id; atomic_trefcount; spinlock_t lock; /* covers all srv fields */ + unsigned long status; struct list_headconn_list; /* all connections for srv */ struct list_headreq_list; /* requests not yet worked on */ struct list_headworkreq_list; /* requests being worked on */ + struct kobject kobj; + struct list_headsrv_list; /* all servers of a type */ + struct list_headlis_list; /* all listeners for the srv */ + struct work_struct shutwork; }; struct p9srv_conn { @@ -90,6 +96,16 @@ struct p9srv_conn { wait_queue_head_t reset_wqueue; }; +struct p9srv_type { + spinlock_t lock; + char*name; + int nextid; + struct kobject kobj; + struct list_headsrv_list; /* all servers of a type */ + struct list_headstype_list; /* all server types */ + struct p9srv* (*create)(void); +}; + enum { /* connection status values */ Reset = 1, /* resetting */ @@ -149,11 +165,11 @@ extern char *Enotfound; extern char *Eopen; extern char *Eexist; extern char *Enotempty; - +extern struct kset p9srv_subsys; struct p9srv *p9srv_srv_create(void); void p9srv_srv_stop(struct p9srv *srv); -void p9srv_srv_destroy(struct p9srv *srv); +void p9srv_srv_shutdown(struct p9srv *srv); void p9srv_srv_start(struct p9srv *srv); void p9srv_respond(struct p9srv_req *req, struct p9_fcall *rc); void p9srv_respond_error(struct p9srv_req *req, char *ename, int ecode); @@ -165,5 +181,9 @@ void p9srv_conn_destroy(struct p9srv_conn *conn); struct p9srv_fid *p9srv_fid_find(struct p9srv_fidpool *fp, u32 fid); void p9srv_fid_incref(struct p9srv_fid *fid); void p9srv_fid_decref(struct p9srv_fid *fid); +struct p9srv_type *p9srv_type_register(char *name, struct p9srv *(*create)(void)); +void p9srv_type_unregister(char *name); +int p9srv_listener_add(struct p9srv *, char *, char *); +int p9srv_listener_del(struct p9srv *, char *, char *); #endif diff --git a/net/9p/srv.c b/net/9p/srv.c index 855ac70..e0c359b 100644 --- a/net/9p/srv.c +++ b/net/9p/srv.c @@ -37,6 +37,18 @@ struct p9srv_fidpool { struct hlist_head hash[FID_HTABLE_SIZE]; }; +struct p9srv_listener { + struct p9_trans_listener*listener; + char*name; + char*options; + struct list_headlis_list; +}; + +enum { + /* p9srv status */ + Shutdown = 1, +}; + enum { /* p9srv_req status */ Respond = 1, @@ -45,6 +57,8 @@ enum { }; struct workqueue_struct *p9srv_wq; +static DEFINE_SPINLOCK(p9srv_type_lock); +static LIST_HEAD(p9srv_type_list); char *Eunknownfid = "unknown fid"; EXPORT_SYMBOL(Eunknownfid); @@ -78,9 +92,12 @@ char *Eexist = "file or directory already exists"; EXPORT_SYMBOL(Eexist); char *Enotempty = "directory not empty"; EXPORT_SYMBOL(Enotempty); +decl_subsys_name(p9srv, srv, NULL, NULL); +EXPORT_SYMBOL(p9srv_subsys); static void p9srv_srv_ref(struct p9srv *srv); static void p9srv_srv_unref(struct p9srv *srv); +static void p9srv_shut_work(struct work_struct *work); static void p9srv_conn_reset(struct p9srv_conn *conn, struct p9srv_req *vreq); static void p9srv_conn_respond(struct p9srv_req *req); static struct p9srv_fidpool *p9srv_fidpool_create(void); @@ -109,6 +126,14 @@ static void p9srv_stat(struct p9srv_req *); static void p9srv_wstat(struct p9srv_req *); static void p9srv_preq_work(struct work_struct *work); static void p9srv_conn_request(struct p9_trans *, struct p9_trans_
[PATCH 6/10] 9p: in-kernel server basic support
This patch implements the basic functionality required for implementing in-kernel 9P file servers. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- include/net/9p/9p.h |2 + include/net/9p/srv.h | 169 +++ net/9p/Kconfig |5 + net/9p/Makefile |4 + net/9p/fcprint.c |2 + net/9p/srv.c | 1283 ++ 6 files changed, 1465 insertions(+), 0 deletions(-) diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h index f7bd839..a913cdb 100644 --- a/include/net/9p/9p.h +++ b/include/net/9p/9p.h @@ -65,6 +65,7 @@ do { \ /* Message Types */ enum { + P9_FIRST = 100, P9_TVERSION = 100, P9_RVERSION, P9_TAUTH = 102, @@ -93,6 +94,7 @@ enum { P9_RSTAT, P9_TWSTAT = 126, P9_RWSTAT, + P9_LAST, }; /* open modes */ diff --git a/include/net/9p/srv.h b/include/net/9p/srv.h new file mode 100644 index 000..72d011e --- /dev/null +++ b/include/net/9p/srv.h @@ -0,0 +1,169 @@ +/* + * include/net/9p/srv.h + * + * 9P server definitions. + * + * Copyright (C) 2007 by Latchesar Ionkov <[EMAIL PROTECTED]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to: + * Free Software Foundation + * 51 Franklin Street, Fifth Floor + * Boston, MA 02111-1301 USA + * + */ + +#ifndef NET_9PSRV_H +#define NET_9PSRV_H + +#define P9SRV_DEBUG_SRV(1<<16) +#define P9SRV_DEBUG_CONN (1<<17) +#define P9SRV_DEBUG_FID(1<<18) +#define P9SRV_DEBUG_REQ(1<<19) +#define P9SRV_DEBUG_FCALL (1<<20) +#define P9SRV_DEBUG_FS (1<<21) + +#define MAXPOLLWADDR 2 + +struct p9srv; +struct p9srv_fid; +struct p9srv_fidpool; +struct p9srv_conn; +struct p9srv_req; + +struct p9srv { + int msize; + int dotu; /* 9P2000.u */ + void*srvaux; + void*treeaux; + int debuglevel; + void(*start)(struct p9srv *); + void(*stop)(struct p9srv *); + void(*destroy)(struct p9srv *); + void(*connopen)(struct p9srv_conn *); + void(*connclose)(struct p9srv_conn *); + void(*fiddestroy)(struct p9srv_fid *); + void(*reqdestroy)(struct p9srv_req *); + + /* 9P message handlers */ + void(*attach)(struct p9srv_req *); + void(*auth)(struct p9srv_req *); + int (*flush)(struct p9srv_req *); + void(*walk)(struct p9srv_req *); + void(*open)(struct p9srv_req *); + void(*create)(struct p9srv_req *); + void(*read)(struct p9srv_req *); + void(*write)(struct p9srv_req *); + void(*clunk)(struct p9srv_req *); + void(*remove)(struct p9srv_req *); + void(*stat)(struct p9srv_req *); + void(*wstat)(struct p9srv_req *); + + /* implementation specific */ + atomic_trefcount; + spinlock_t lock; /* covers all srv fields */ + struct list_headconn_list; /* all connections for srv */ + struct list_headreq_list; /* requests not yet worked on */ + struct list_headworkreq_list; /* requests being worked on */ +}; + +struct p9srv_conn { + struct p9srv*srv; + struct p9_trans *trans; + int msize; + int dotu; /* 9P2000.u */ + + /* implementation specific */ + unsigned long status; + struct p9srv_fidpool*fidpool; + struct list_headconn_list; + atomic_treset_wcount; + wait_queue_head_t reset_wqueue; +}; + +enum { + /* connection status values */ + Reset = 1, /* resetting */ + Destroy = 2,/* destroying */ +}; + +struct p9srv_fid { + u32 fid; + atomic_trefcount; + struct p9srv_conn *conn; + void*aux; +
[PATCH 1/10] 9p: new transport interface
The current transport interface is tied too closely to the socket/file descriptor operations. It expects only a single message to be transmitted at any given time. It also depends on the vfs poll mechanism for notification when data can be sent/received. This patch modifies the transport interface making it more suitable for implementing various 9P transports. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- fs/9p/v9fs.c |1 - include/net/9p/9p.h|1 + include/net/9p/client.h| 13 ++- include/net/9p/conn.h | 57 include/net/9p/transport.h | 37 -- net/9p/Kconfig | 18 ++-- net/9p/Makefile|1 - net/9p/client.c| 333 net/9p/conv.c | 16 ++- net/9p/mod.c | 12 +-- 10 files changed, 368 insertions(+), 121 deletions(-) diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 873802d..eeca7c7 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include "v9fs.h" #include "v9fs_vfs.h" diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h index 9ace484..86fee63 100644 --- a/include/net/9p/9p.h +++ b/include/net/9p/9p.h @@ -383,6 +383,7 @@ int p9_deserialize_stat(void *buf, u32 buflen, struct p9_stat *stat, int dotu); int p9_deserialize_fcall(void *buf, u32 buflen, struct p9_fcall *fc, int dotu); void p9_set_tag(struct p9_fcall *fc, u16 tag); +struct p9_fcall *p9_fcall_alloc(u32 size); struct p9_fcall *p9_create_tversion(u32 msize, char *version); struct p9_fcall *p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname, u32 n_uname, int dotu); diff --git a/include/net/9p/client.h b/include/net/9p/client.h index 9b9221a..5efb57a 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h @@ -25,14 +25,14 @@ #ifndef NET_9P_CLIENT_H #define NET_9P_CLIENT_H +struct p9_trans_req; struct p9_client { spinlock_t lock; /* protect client structure */ int msize; unsigned char dotu; struct p9_trans *trans; - struct p9_conn *conn; - struct p9_idpool *fidpool; + struct p9_idpool *tagpool; struct list_head fidlist; }; @@ -78,4 +78,13 @@ struct p9_stat *p9_client_stat(struct p9_fid *fid); int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst); struct p9_stat *p9_client_dirread(struct p9_fid *fid, u64 offset); +void p9_client_req_incref(struct p9_trans_req *req); +void p9_client_req_decref(struct p9_trans_req *req); +struct p9_trans_req *p9_client_rpcnb(struct p9_client *clnt, + struct p9_fcall *tc, struct p9_fcall *rc, + void (*cb)(struct p9_trans_req *), void *cba); +void p9_client_flush_req(struct p9_trans_req *req); +int p9_client_rpc(struct p9_client *clnt, struct p9_fcall *tc, + struct p9_fcall **prc); + #endif /* NET_9P_CLIENT_H */ diff --git a/include/net/9p/conn.h b/include/net/9p/conn.h deleted file mode 100644 index 756d878..000 --- a/include/net/9p/conn.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * include/net/9p/conn.h - * - * Connection Definitions - * - * Copyright (C) 2005 by Latchesar Ionkov <[EMAIL PROTECTED]> - * Copyright (C) 2004 by Eric Van Hensbergen <[EMAIL PROTECTED]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to: - * Free Software Foundation - * 51 Franklin Street, Fifth Floor - * Boston, MA 02111-1301 USA - * - */ - -#ifndef NET_9P_CONN_H -#define NET_9P_CONN_H - -#undef P9_NONBLOCK - -struct p9_conn; -struct p9_req; - -/** - * p9_mux_req_callback - callback function that is called when the - * response of a request is received. The callback is called from - * a workqueue and shouldn't block. - * - * @req - request - * @a - the pointer that was specified when the request was send to be - * passed to the callback - */ -typedef void (*p9_conn_req_callback)(struct p9_req *req, void *a); - -struct p9_conn *p9_conn_create(struct p9_trans *trans, int msize, - unsigned char *dotu); -void p9_conn_destroy(struct p9_conn *); -int p9_conn_rpc(struct p9_conn *m, struct p9_fcall *tc, struct p9_fcall **rc); - -#ifdef P9_NONBLOCK -int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc, - p9_conn_req_callback cb, void *a); -#endif /* P9_NONBLOCK */ - -void p9_conn_cancel(struct p9_conn *m, int err); - -#endif /* N
[PATCH] 9p: basic sysfs support
This patch implements the basic sysfs support for 9p. If CONFIG_NET_9P_DEBUG is defined, allows reading and modifying the debug level via /sysfs/fs/9p/debuglevel. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- include/net/9p/9p.h |1 + net/9p/mod.c| 45 + 2 files changed, 46 insertions(+), 0 deletions(-) diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h index 686425a..9ace484 100644 --- a/include/net/9p/9p.h +++ b/include/net/9p/9p.h @@ -377,6 +377,7 @@ struct p9_fcall { }; struct p9_idpool; +extern struct kset p9_subsys; int p9_deserialize_stat(void *buf, u32 buflen, struct p9_stat *stat, int dotu); diff --git a/net/9p/mod.c b/net/9p/mod.c index 41d70f4..8205c4b 100644 --- a/net/9p/mod.c +++ b/net/9p/mod.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -37,8 +38,17 @@ unsigned int p9_debug_level = 0; /* feature-rific global debug level */ EXPORT_SYMBOL(p9_debug_level); module_param_named(debug, p9_debug_level, uint, 0); MODULE_PARM_DESC(debug, "9P debugging level"); + +static ssize_t p9_debug_show(struct kset *, char *); +static ssize_t p9_debug_store(struct kset *, const char *, size_t); + +static struct subsys_attribute p9_debug_attr = __ATTR(debuglevel, 0644, + p9_debug_show, p9_debug_store); #endif +decl_subsys_name(p9, 9p, NULL, NULL); +EXPORT_SYMBOL(p9_subsys); + extern int p9_mux_global_init(void); extern void p9_mux_global_exit(void); @@ -99,6 +109,27 @@ struct p9_trans_module *v9fs_default_trans(void) } EXPORT_SYMBOL(v9fs_default_trans); +#ifdef CONFIG_NET_9P_DEBUG + +static ssize_t p9_debug_show(struct kset *k, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", p9_debug_level); +} + +static ssize_t p9_debug_store(struct kset *k, const char *buf, size_t buflen) +{ + int n; + char *p; + + n = simple_strtol(buf, &p, 0); + if (*p != '\n' && *p != '\0') + return EINVAL; + + p9_debug_level = n; + return buflen; +} + +#endif /** * v9fs_init - Initialize module @@ -109,6 +140,19 @@ static int __init init_p9(void) int ret; p9_error_init(); + kobj_set_kset_s(&p9_subsys, fs_subsys); + ret = subsystem_register(&p9_subsys); + if (ret) + return ret; + +#ifdef CONFIG_NET_9P_DEBUG + ret = subsys_create_file(&p9_subsys, &p9_debug_attr); + if (ret) { + subsystem_unregister(&p9_subsys); + return ret; + } +#endif + printk(KERN_INFO "Installing 9P2000 support\n"); ret = p9_mux_global_init(); if (ret) { @@ -127,6 +171,7 @@ static int __init init_p9(void) static void __exit exit_p9(void) { p9_mux_global_exit(); + subsystem_unregister(&p9_subsys); } module_init(init_p9) - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/10] 9p: fcall deserialization changes
Modify p9_deserialize_fcall to read from p9_fcall's internal buffer instead of specifying an external one. Add functions that copy raw data to and from a fcall. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- include/net/9p/9p.h |4 +++- net/9p/conv.c | 34 -- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h index 86fee63..8de6eef 100644 --- a/include/net/9p/9p.h +++ b/include/net/9p/9p.h @@ -381,9 +381,11 @@ extern struct kset p9_subsys; int p9_deserialize_stat(void *buf, u32 buflen, struct p9_stat *stat, int dotu); -int p9_deserialize_fcall(void *buf, u32 buflen, struct p9_fcall *fc, int dotu); +int p9_deserialize_fcall(struct p9_fcall *fc, int dotu); void p9_set_tag(struct p9_fcall *fc, u16 tag); struct p9_fcall *p9_fcall_alloc(u32 size); +int p9_fcall_get(char *dst, int dstlen, struct p9_fcall *fc); +int p9_fcall_put(struct p9_fcall *fc, char *src, int srclen); struct p9_fcall *p9_create_tversion(u32 msize, char *version); struct p9_fcall *p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname, u32 n_uname, int dotu); diff --git a/net/9p/conv.c b/net/9p/conv.c index 3627753..74d57c7 100644 --- a/net/9p/conv.c +++ b/net/9p/conv.c @@ -322,18 +322,20 @@ EXPORT_SYMBOL(p9_deserialize_stat); * */ -int -p9_deserialize_fcall(void *buf, u32 buflen, struct p9_fcall *rcall, - int dotu) +int p9_deserialize_fcall(struct p9_fcall *rcall, int dotu) { - + u32 size; struct cbuf buffer; struct cbuf *bufp = &buffer; int i = 0; - buf_init(bufp, buf, buflen); + buf_init(bufp, rcall->sdata, rcall->size); - rcall->size = buf_get_int32(bufp); + size = buf_get_int32(bufp); + if (size > rcall->size) + return -EPROTO; + + rcall->size = size; rcall->id = buf_get_int8(bufp); rcall->tag = buf_get_int16(bufp); @@ -941,3 +943,23 @@ error: return fc; } EXPORT_SYMBOL(p9_create_twstat); + +int p9_fcall_get(char *dst, int dstlen, struct p9_fcall *fc) +{ + if (dstlen > fc->size) + dstlen = fc->size; + + memmove(dst, fc->sdata, dstlen); + return dstlen; +} +EXPORT_SYMBOL(p9_fcall_get); + +int p9_fcall_put(struct p9_fcall *fc, char *src, int srclen) +{ + if (srclen > fc->size) + return -ENOMEM; + + memmove(fc->sdata, src, srclen); + return srclen; +} +EXPORT_SYMBOL(p9_fcall_put); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 8/10] 9p: loopback transport
9P loopback transport that can be used between 9P in-kernel servers and v9fs on the same machine. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- net/9p/Kconfig |7 + net/9p/Makefile |4 + net/9p/trans_loop.c | 371 +++ 3 files changed, 382 insertions(+), 0 deletions(-) diff --git a/net/9p/Kconfig b/net/9p/Kconfig index 979c781..ae341f0 100644 --- a/net/9p/Kconfig +++ b/net/9p/Kconfig @@ -23,6 +23,13 @@ config NET_9P_FD file descriptors. TCP/IP is the default transport for 9p, so if you are going to use 9p, you'll likely want this. +config NET_9P_LOOP + depends on NET_9P + default y if NET_9P + tristate "9P Loopback Transport (Experimental)" + help + Loopback transport. + config NET_9P_DEBUG bool "Debug information" depends on NET_9P diff --git a/net/9p/Makefile b/net/9p/Makefile index d143e4a..da05d35 100644 --- a/net/9p/Makefile +++ b/net/9p/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_NET_9P) := 9pnet.o obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o +obj-$(CONFIG_NET_9P_LOOP) += 9pnet_loop.o obj-$(CONFIG_NET_9P_SRV) += 9psrv.o 9pnet-objs := \ @@ -10,6 +11,9 @@ obj-$(CONFIG_NET_9P_SRV) += 9psrv.o fcprint.o \ util.o \ +9pnet_loop-objs := \ + trans_loop.o \ + 9psrv-objs := \ srv.o \ diff --git a/net/9p/trans_loop.c b/net/9p/trans_loop.c new file mode 100644 index 000..7e7793b --- /dev/null +++ b/net/9p/trans_loop.c @@ -0,0 +1,371 @@ +/* + * linux/fs/9p/trans_fd.c + * + * Loopback transport. Used for testing. + * + * Copyright (C) 2007 by Latchesar Ionkov <[EMAIL PROTECTED]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to: + * Free Software Foundation + * 51 Franklin Street, Fifth Floor + * Boston, MA 02111-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct p9_trans_loop { + spinlock_t lock; + char*name; + struct p9_trans *ctrans; + struct p9_trans *strans; + struct p9_trans_listenerlistener; + struct list_headtrans_list; +}; + +struct p9_loop_opts { + char *name; +}; + +static struct p9_trans *p9lo_clt_create(const char *, char *); +static void p9lo_clt_request(struct p9_trans *, struct p9_trans_req *); +static int p9lo_clt_cancel(struct p9_trans *, struct p9_trans_req *); +static void p9lo_clt_destroy(struct p9_trans *); +static int p9lo_srv_create(struct p9_trans_loop *lt); +static void p9lo_srv_destroy(struct p9_trans *); +static int p9lo_srv_cancel(struct p9_trans *, struct p9_trans_req *); +static void p9lo_srv_respond(struct p9_trans *, struct p9_trans_req *); +static struct p9_trans_listener *p9lo_listener_create(char *); +static void p9lo_trans_listener_destroy(struct p9_trans_listener *); + +static struct p9_trans_module p9lo_trans_mod = { + .name = "loop", + .maxsize = 65536, + .def = 0, + .create_client = p9lo_clt_create, + .create_listener = p9lo_listener_create, +}; + +enum { + Opt_name, Opt_err, +}; + +static match_table_t tokens = { + {Opt_name, "name=%s"}, + {Opt_err, NULL}, +}; + +static DEFINE_MUTEX(p9lo_lock); +static LIST_HEAD(p9lo_trans_list); + +static void parse_opts(char *options, struct p9_loop_opts *opts) +{ + int token; + char *p; + substring_t args[MAX_OPT_ARGS]; + + opts->name = NULL; + if (!options) + return; + + while ((p = strsep(&options, ",")) != NULL) { + if (*p == '\0') + continue; + + token = match_token(p, tokens, args); + switch (token) { + case Opt_name: + opts->name = match_strdup(&args[0]); + break; + default: + continue; + } + } +} + +static struct p9_trans_loop *p9lo_trans_find(char *name) +{ + struct p9_trans_loop *lo; + + mutex_lock(&p9lo_lock); + list_for_each_entry(lo, &p9lo_trans_list, trans_list) { + if (!strcmp(name, lo->name)) { + mutex_unlock(&
[PATCH 5/10] 9p: marshalling changes for in-kernel server
This patch implements serialization/deserialization for the server-side 9P messages. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- include/net/9p/9p.h | 16 ++ net/9p/conv.c | 457 +-- 2 files changed, 462 insertions(+), 11 deletions(-) diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h index 8de6eef..08c4dd1 100644 --- a/include/net/9p/9p.h +++ b/include/net/9p/9p.h @@ -379,6 +379,7 @@ struct p9_fcall { struct p9_idpool; extern struct kset p9_subsys; +int p9_serialize_stat(struct p9_wstat *wstat, u8 *buf, int buflen, int dotu); int p9_deserialize_stat(void *buf, u32 buflen, struct p9_stat *stat, int dotu); int p9_deserialize_fcall(struct p9_fcall *fc, int dotu); @@ -407,6 +408,21 @@ struct p9_fcall *p9_create_tremove(u32 fid); struct p9_fcall *p9_create_tstat(u32 fid); struct p9_fcall *p9_create_twstat(u32 fid, struct p9_wstat *wstat, int dotu); +int p9_create_rversion(struct p9_fcall *, u32 msize, char *version); +int p9_create_rattach(struct p9_fcall *, struct p9_qid *qid); +int p9_create_rerror(struct p9_fcall *, char *ename, u32 ecode, int dotu); +int p9_create_rauth(struct p9_fcall *, struct p9_qid *qid); +int p9_create_rflush(struct p9_fcall *); +int p9_create_rwalk(struct p9_fcall *, int nwqid, struct p9_qid *wqids); +int p9_create_ropen(struct p9_fcall *, struct p9_qid *qid, u32 iounit); +int p9_create_rcreate(struct p9_fcall *, struct p9_qid *qid, u32 iounit); +int p9_init_rread(struct p9_fcall *fc); +void p9_set_rread_count(struct p9_fcall *fc, u32 count); +int p9_create_rwrite(struct p9_fcall *, u32 count); +int p9_create_rclunk(struct p9_fcall *); +int p9_create_rremove(struct p9_fcall *); +int p9_create_rstat(struct p9_fcall *, struct p9_wstat *st, int dotu); +int p9_create_rwstat(struct p9_fcall *); int p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int dotu); int p9_errstr2errno(char *errstr, int len); diff --git a/net/9p/conv.c b/net/9p/conv.c index 74d57c7..ed119bc 100644 --- a/net/9p/conv.c +++ b/net/9p/conv.c @@ -41,6 +41,8 @@ struct cbuf { unsigned char *ep; }; +static int p9_size_wstat(struct p9_wstat *wstat, int dotu); + static inline void buf_init(struct cbuf *buf, void *data, int datalen) { buf->sp = buf->p = data; @@ -133,6 +135,41 @@ static inline void buf_put_string(struct cbuf *buf, const char *s) buf_put_stringn(buf, s, s?strlen(s):0); } +static inline void buf_put_qid(struct cbuf *buf, struct p9_qid *qid) +{ + buf_put_int8(buf, qid->type); + buf_put_int32(buf, qid->version); + buf_put_int64(buf, qid->path); +} + +static inline void buf_put_wstat(struct cbuf *bufp, struct p9_wstat *wstat, + int dotu) +{ + int statsz; + + statsz = p9_size_wstat(wstat, dotu); + buf_put_int16(bufp, statsz); + buf_put_int16(bufp, wstat->type); + buf_put_int32(bufp, wstat->dev); + buf_put_qid(bufp, &wstat->qid); + buf_put_int32(bufp, wstat->mode); + buf_put_int32(bufp, wstat->atime); + buf_put_int32(bufp, wstat->mtime); + buf_put_int64(bufp, wstat->length); + + buf_put_string(bufp, wstat->name); + buf_put_string(bufp, wstat->uid); + buf_put_string(bufp, wstat->gid); + buf_put_string(bufp, wstat->muid); + + if (dotu) { + buf_put_string(bufp, wstat->extension); + buf_put_int32(bufp, wstat->n_uid); + buf_put_int32(bufp, wstat->n_gid); + buf_put_int32(bufp, wstat->n_muid); + } +} + static u8 buf_get_int8(struct cbuf *buf) { u8 ret = 0; @@ -181,6 +218,15 @@ static u64 buf_get_int64(struct cbuf *buf) return ret; } +static void buf_get_data(struct cbuf *buf, u32 count, u8 **data) +{ + if (buf_check_size(buf, count)) { + *data = buf->p; + buf->p += count; + } else + *data = NULL; +} + static void buf_get_str(struct cbuf *buf, struct p9_str *vstr) { vstr->len = buf_get_int16(buf); @@ -346,17 +392,63 @@ int p9_deserialize_fcall(struct p9_fcall *rcall, int dotu) default: P9_EPRINTK(KERN_ERR, "unknown message type: %d\n", rcall->id); return -EPROTO; + case P9_TVERSION: + rcall->params.tversion.msize = buf_get_int32(bufp); + buf_get_str(bufp, &rcall->params.tversion.version); + break; case P9_RVERSION: rcall->params.rversion.msize = buf_get_int32(bufp); buf_get_str(bufp, &rcall->params.rversion.version); break; + case P9_TAUTH: + rcall->params.tauth.afid = buf_get_int32(bufp); + buf_get_str(bufp, &rcall->params.tauth.uname); + buf_get_str(bufp,
[PATCH 4/10] 9p: tranport interface changes for in-kernel server
This patch adds in-kernel 9P server support to the transport interface. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- fs/9p/v9fs.c |2 +- include/net/9p/transport.h | 31 --- net/9p/mux.c |6 +++--- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index eeca7c7..c8bc530 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c @@ -210,7 +210,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, goto error; } - trans = v9ses->trans->create(dev_name, v9ses->options); + trans = v9ses->trans->create_client(dev_name, v9ses->options); if (IS_ERR(trans)) { retval = PTR_ERR(trans); trans = NULL; diff --git a/include/net/9p/transport.h b/include/net/9p/transport.h index b8eecc9..785595a 100644 --- a/include/net/9p/transport.h +++ b/include/net/9p/transport.h @@ -47,23 +47,48 @@ struct p9_trans { void *aux; void *priv; /* transport specific */ - /* The function schedules sending the data from the 'tc' + /* If client, the function schedules sending the data from the 'tc' over the transport. If the 'rc' is set, the response is read in it and the 'cb' is called. + + If server, when a request arrives p9_trans_req is allocated and + the request content is stored in 'tc'. The transport sets 'cb' + and 'cba' values. The server stores the response in the 'rc' + fcall (or allocates one if NULL) and calls 'cb'. + The server is responsible of freeing the req as well as req->tc + and req->rc once the response is sent. + The transport is allowed to call the request function with NULL + value for 'req' if it's status ('err') is changed. */ void (*request)(struct p9_trans *trans, struct p9_trans_req *req); - /* If the request is not sent down the wire, don't send it. */ + /* If client and the request is not sent down the wire, don't send it. + If server, inform the transport that the server won't respond to + that request. Returns error code, zero if successful. + */ int (*cancel)(struct p9_trans *trans, struct p9_trans_req *req); void (*destroy)(struct p9_trans *trans); }; +struct p9_trans_listener { + int err; + void *taux; /* transport specific */ + void *aux; /* user set */ + + /* The newtrans callback is set by the user of the listener + When there is a new incoming connection, newcann is called + with p9_trans that represents it */ + void (*newtrans)(struct p9_trans_listener *, struct p9_trans *); + void (*destroy)(struct p9_trans_listener *); +}; + struct p9_trans_module { struct list_head list; char *name; /* name of transport */ int maxsize;/* max message size of transport */ int def;/* this transport should be default */ - struct p9_trans * (*create)(const char *devname, char *options); + struct p9_trans *(*create_client)(const char *devname, char *options); + struct p9_trans_listener *(*create_listener)(char *options); }; void v9fs_register_trans(struct p9_trans_module *m); diff --git a/net/9p/mux.c b/net/9p/mux.c index 8a40a2e..3b0ed2c 100644 --- a/net/9p/mux.c +++ b/net/9p/mux.c @@ -157,21 +157,21 @@ static struct p9_trans_module p9_tcp_trans = { .name = "tcp", .maxsize = MAX_SOCK_BUF, .def = 1, - .create = p9fd_create_tcp_client, + .create_client = p9fd_create_tcp_client, }; static struct p9_trans_module p9_unix_trans = { .name = "unix", .maxsize = MAX_SOCK_BUF, .def = 0, - .create = p9fd_create_unix_client, + .create_client = p9fd_create_unix_client, }; static struct p9_trans_module p9_fd_trans = { .name = "fd", .maxsize = MAX_SOCK_BUF, .def = 0, - .create = p9fd_create_fd_client, + .create_client = p9fd_create_fd_client, }; /** - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH][REFERENCE ONLY] 9p: ramfs 9p server
Sample ramfs file server that uses the in-kernel 9P file server support. This code is for reference only. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- net/9p/Kconfig |8 +- net/9p/Makefile |1 + net/9p/ramfs/ramfs.c | 986 ++ 3 files changed, 994 insertions(+), 1 deletions(-) diff --git a/net/9p/Kconfig b/net/9p/Kconfig index 5b0dc28..68f7496 100644 --- a/net/9p/Kconfig +++ b/net/9p/Kconfig @@ -23,11 +23,17 @@ config NET_9P_FD file descriptors. TCP/IP is the default transport for 9p, so if you are going to use 9p, you'll likely want this. -config NET_9P_SRV +menuconfig NET_9P_SRV tristate "9P server support" depends on NET_9P help Say Y if you want the 9P server support + +config NET_9P_RAMFS +tristate "9P ramfs sample file server" +depends on NET_9P_SRV && NET_9P_LOOP +help + Say Y if you want the 9P ramfs support config NET_9P_VIRTIO depends on NET_9P && EXPERIMENTAL && VIRTIO tristate "9P Virtio Transport (Experimental)" diff --git a/net/9p/Makefile b/net/9p/Makefile index 6ee024e..3808c40 100644 --- a/net/9p/Makefile +++ b/net/9p/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o obj-$(CONFIG_NET_9P_LOOP) += 9pnet_loop.o obj-$(CONFIG_NET_9P_SRV) += 9psrv.o obj-$(CONFIG_NET_9P_VIRTIO) += 9pnet_virtio.o +obj-$(CONFIG_NET_9P_RAMFS) += ramfs/ 9pnet-objs := \ mod.o \ diff --git a/net/9p/ramfs/ramfs.c b/net/9p/ramfs/ramfs.c new file mode 100644 index 000..3aff620 --- /dev/null +++ b/net/9p/ramfs/ramfs.c @@ -0,0 +1,986 @@ +/* + * net/9p/srv/ramfs.c + * + * Simple RAM filesystem + * + * Copyright (C) 2007 by Latchesar Ionkov <[EMAIL PROTECTED]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to: + * Free Software Foundation + * 51 Franklin Street, Fifth Floor + * Boston, MA 02111-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ROOTPERM 0777 + +struct ramfs_file { + struct mutexlock; /* file lock */ + atomic_trefcount; + unsigned long status; + char*name; + u32 perm; + u64 length; + u32 atime; + u32 mtime; + u32 uid; + u32 gid; + u32 muid; + char*extension; + struct p9_qid qid; + int excl; + + struct ramfs_file *parent; + struct ramfs_file *next; /* protected by parent lock */ + struct ramfs_file *prev; + + struct ramfs_file *dirents; /* if directory */ + struct ramfs_file *dirlast; + + struct list_headfid_list; /* all fids for a file */ + + u8 *data; + u64 datasize; +}; + +struct ramfs_fid { + struct ramfs_file *file; + int omode; + u64 diroffset; + struct ramfs_file *dirent; + struct list_headfid_list; /* all fids for a file */ +}; + +enum { + Removed = 1, +}; + +static struct p9srv_type *ramfs_srv_type; +static struct ramfs_file *root; +static u64 qidpath; +static int blksize = 8192; + +static char *Enospace = "no space left"; +static char *Einternal = "internal error"; + +static void ramfs_attach(struct p9srv_req *req); +static void ramfs_walk(struct p9srv_req *req); +static void ramfs_open(struct p9srv_req *req); +static void ramfs_create(struct p9srv_req *req); +static void ramfs_read(struct p9srv_req *req); +static void ramfs_write(struct p9srv_req *req); +static void ramfs_clunk(struct p9srv_req *req); +static void ramfs_remove(struct p9srv_req *req); +static void ramfs_stat(struct p9srv_req *req); +static void ramfs_wstat(struct p9srv_req *req); +static void ramfs_fiddestroy(struct p9srv_fid *fid); +static void ramfs_connopen(struct p9srv_conn *conn); +static void ramfs_connclose(struct p9srv_conn *conn); + +static char *p9_strdup(struct p9_str *str) +{ + char *ret; + + ret = kmalloc(str-&
Re: [PATCH] 9p: basic sysfs support
This patch adds only the basic 9p functionality, we use the sysfs interface extensively for configuring the 9p in-kernel servers (patch 7 in the series). The v9fs filesyste will probably add some more subdirectories for authenticating users and mapping user names to uids... Thanks, Lucho On 11/2/07, Greg KH <[EMAIL PROTECTED]> wrote: > On Fri, Nov 02, 2007 at 10:53:31AM -0600, Latchesar Ionkov wrote: > > This patch implements the basic sysfs support for 9p. If CONFIG_NET_9P_DEBUG > > is defined, allows reading and modifying the debug level via > > /sysfs/fs/9p/debuglevel. > > Since this is a debug-only type file, why not just put it in debugfs > instead? > > And I have a huge patch-series pending that will make adding files like > this to sysfs much easier in the future. But nice job, it looks like > you got it all correct, which is pretty hard to do first time these days > due to the complexity of the current interface :) > > thanks, > > greg k-h > - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [V9fs-developer] [GIT PULL] 9p Patches for 2.6.23 merge window
I thought that it is not a good idea to keep the v9fs_ prefix for code that is in different places (fs/9p and net/9p). If keeping the old prefix is more acceptable, I can create a new patch without the "v9fs_"->"p9_" renames. Thanks, Lucho On 7/15/07, Linus Torvalds <[EMAIL PROTECTED]> wrote: On Sat, 14 Jul 2007, Eric Van Hensbergen wrote: > > The bulk of the changes were in the reorganization patch which mostly > moved files and interfaces around in preparation for work on an > in-kernel 9p server. Please use "git diff -C --stat --summary" to generate the diffstat summary. In particular, because you didn't use -C (or -M), git have you an old-style diffstat without renames, so the diffstat doesn't show that a lot of it was moving code around. (That said, you seem to have changed names a lot too, so it's not pure code movement). > 49 files changed, 5400 insertions(+), 5092 deletions(-) With rename detection enabled, I get 36 files changed, 3444 insertions(+), 3130 deletions(-) due to finding some (partially dubious) renames: rename fs/9p/mux.h => include/net/9p/conn.h (53%) rename {fs => include/net}/9p/transport.h (59%) rename {fs => net}/9p/conv.c (55%) rename {fs => net}/9p/fcprint.c (64%) rename {fs => net}/9p/mux.c (55%) even though is misses a lot of others (due to all the "v9fs" -> "p9" changes in the source code too - was that really worth it?). Linus - This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ ___ V9fs-developer mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/v9fs-developer - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [V9fs-developer] [GIT PULL] 9p Patches for 2.6.23 merge window
The original patchset had three patches: 1. Renames all functions and macros 2. Moves the header files from fs/9p to include/net/9p and updates the C files with the new header locations 3. Moves the C files from fs/9p to net/9p Unfortunately the three patches were applied as a single one in Eric's repository and made tracking of the changes harder. We will be more careful next time. Thanks for you comments, Lucho On 7/16/07, Linus Torvalds <[EMAIL PROTECTED]> wrote: On Sun, 15 Jul 2007, Latchesar Ionkov wrote: > > I thought that it is not a good idea to keep the v9fs_ prefix for code > that is in different places (fs/9p and net/9p). If keeping the old > prefix is more acceptable, I can create a new patch without the > "v9fs_"->"p9_" renames. It's fine, I don't care *that* much, and I already pulled. If it had been something more central, I'd have rejected it, but soemthing as specialized as the Plan9 fs, I just wanted to point out that this is now how we should do things. In other words: when doing renames it is generally *much* nicer to do a 100% rename (perhaps with just _trivial_ changes to make it compile - the include statements etc change, and maybe you want to change the name in the comment header too). Doing "move the code and change it at the same time" is considered bad form. Movement diffs are much harder to read anyway (a traditional diff will show it as a new-file + delete, of course), so the general rule is: - move code around _without_ modifying it, so that code movement (whether it's a whole file, or just a set of functions between files) doesn't really introduce any real changes, and is easier to look through the changes. - do the actual changes to the code as a separate thing. This should be true in just about *any* development model, and it's especially true in Linux, where patches are the main way people communicate. And when using git, the whole "keep code movement separate from changes" has an even more fundamental reason: git can track code movement (again, whether moving a whole file or just a function between files), and doing a "git blame -C" will actually follow code movement between files. It does that by similarity analysis, but it does mean that if you both move the code *and* change it at the same time, git cannot see that "oh, that function came originally from that other file", and now you get worse annotations about where code actually originated. So next time, please don't move code and change it at the same time. Linus - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] v9fs: don't use primary fid when removing file
v9fs_insert uses v9fs_fid_lookup (which also locks the fid) to get the primary fid associated with the dentry and destroys the v9fs_fid struct after removing the file. If another process called v9fs_fid_lookup on the same dentry, it may wait undefinitely for the fid's lock (as the struct is freed). This patch changes v9fs_remove to use a cloned fid, so the primary fid is not locked and freed. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- commit ca1a80584fc3211dac158492173467d4f87a27ac tree 787de07bd6d24bdcc9907f90d9085dcd774b2ea4 parent 0f851021c0f91e5073fa89f26b5ac68e23df8e11 author Latchesar Ionkov <[EMAIL PROTECTED]> Sat, 21 Apr 2007 13:37:15 -0600 committer Latchesar Ionkov <[EMAIL PROTECTED]> Sat, 21 Apr 2007 13:37:15 -0600 fs/9p/vfs_inode.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 124a085..b01b0a4 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -415,7 +415,7 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) file_inode = file->d_inode; sb = file_inode->i_sb; v9ses = v9fs_inode2v9ses(file_inode); - v9fid = v9fs_fid_lookup(file); + v9fid = v9fs_fid_clone(file); if(IS_ERR(v9fid)) return PTR_ERR(v9fid); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/4] v9fs: move non-vfs related headers to include/net/9p
This patchset moves non-filesystem interfaces of v9fs from fs/9p to net/9p. It moves the transport, packet marshalling and connection layers to net/9p leaving only the VFS related files in fs/9p. This patch: Moves the non-VFS related header files from fs/9p to include/net/9p. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- fs/9p/9p.h | 415 fs/9p/conn.h | 53 -- fs/9p/conv.c |2 +- fs/9p/fcall.c |6 +- fs/9p/fcprint.c|2 +- fs/9p/fid.c|2 +- fs/9p/mux.c|6 +- fs/9p/trans_fd.c |4 +- fs/9p/transport.h | 49 - fs/9p/util.c |2 +- fs/9p/v9fs.c |6 +- fs/9p/vfs_addr.c |2 +- fs/9p/vfs_dentry.c |2 +- fs/9p/vfs_dir.c|2 +- fs/9p/vfs_file.c |2 +- fs/9p/vfs_inode.c |2 +- fs/9p/vfs_super.c |2 +- include/net/9p/9p.h| 415 include/net/9p/conn.h | 53 ++ include/net/9p/transport.h | 49 + 20 files changed, 538 insertions(+), 538 deletions(-) diff --git a/fs/9p/9p.h b/fs/9p/9p.h deleted file mode 100644 index 153129b..000 --- a/fs/9p/9p.h +++ /dev/null @@ -1,415 +0,0 @@ -/* - * include/net/9p/9p.h - * - * 9P protocol definitions. - * - * Copyright (C) 2005 by Latchesar Ionkov <[EMAIL PROTECTED]> - * Copyright (C) 2004 by Eric Van Hensbergen <[EMAIL PROTECTED]> - * Copyright (C) 2002 by Ron Minnich <[EMAIL PROTECTED]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to: - * Free Software Foundation - * 51 Franklin Street, Fifth Floor - * Boston, MA 02111-1301 USA - * - */ - -#ifndef NET_9P_H -#define NET_9P_H - -#define CONFIG_NET_9P_DEBUG - -#ifdef CONFIG_NET_9P_DEBUG - -#define P9_DEBUG_ERROR (1<<0) -#define P9_DEBUG_9P(1<<2) -#define P9_DEBUG_VFS (1<<3) -#define P9_DEBUG_CONV (1<<4) -#define P9_DEBUG_MUX (1<<5) -#define P9_DEBUG_TRANS (1<<6) -#define P9_DEBUG_SLABS (1<<7) -#define P9_DEBUG_FCALL (1<<8) - -extern unsigned int p9_debug_level; - -#define P9_DPRINTK(level, format, arg...) \ -do { \ - if((p9_debug_level & level)==level) \ - printk(KERN_NOTICE "-- %s (%d): " \ - format , __FUNCTION__, current->pid , ## arg); \ -} while(0) - -#define PRINT_FCALL_ERROR(s, fcall) P9_DPRINTK(P9_DEBUG_ERROR, "%s: %.*s\n", s, \ - fcall?fcall->params.rerror.error.len:0, \ - fcall?fcall->params.rerror.error.str:""); - -#else -#define P9_DPRINTK(level, format, arg...) do { } while (0) -#define PRINT_FCALL_ERROR(s, fcall) do { } while (0) -#endif - -#define P9_EPRINTK(level, format, arg...) \ -do { \ - printk(level "9p: %s (%d): " \ - format , __FUNCTION__, current->pid , ## arg); \ -} while(0) - - -/* Message Types */ -enum { - P9_TVERSION = 100, - P9_RVERSION, - P9_TAUTH = 102, - P9_RAUTH, - P9_TATTACH = 104, - P9_RATTACH, - P9_TERROR = 106, - P9_RERROR, - P9_TFLUSH = 108, - P9_RFLUSH, - P9_TWALK = 110, - P9_RWALK, - P9_TOPEN = 112, - P9_ROPEN, - P9_TCREATE = 114, - P9_RCREATE, - P9_TREAD = 116, - P9_RREAD, - P9_TWRITE = 118, - P9_RWRITE, - P9_TCLUNK = 120, - P9_RCLUNK, - P9_TREMOVE = 122, - P9_RREMOVE, - P9_TSTAT = 124, - P9_RSTAT, - P9_TWSTAT = 126, - P9_RWSTAT, -}; - -/* open modes */ -enum { - P9_OREAD = 0x00, - P9_OWRITE = 0x01, - P9_ORDWR = 0x02, - P9_OEXEC = 0x03, - P9_OEXCL = 0x04, - P9_OTRUNC = 0x10, - P9_OREXEC = 0x20, - P9_ORCLOSE = 0x40, - P9_OAPPEND = 0x80, -}; - -/* permissions */ -enum { - P9_DMDIR = 0x8000, - P9_DMAPPEND = 0x4000, - P9_DMEXCL = 0x2000, - P9_DMMOUNT = 0x1000, - P9_DMAUTH = 0x0800, - P9_DMTMP = 0x0400, - P9_DMSYMLINK = 0x0200, - P9_DMLINK = 0x0100, - /* 9P2000.u extensions */ - P9_DMDEVICE = 0x0080, - P9_DMNAMEDPIPE = 0x0020, - P9_DMSOCKET = 0x0010, - P9_DMSETUID = 0x0008, - P9_DMS
Re: [PATCH] 9p: create separate 9p client interface
Hi, On 4/30/07, Christoph Hellwig <[EMAIL PROTECTED]> wrote: On Mon, Apr 30, 2007 at 09:32:41AM -0600, Latchesar Ionkov wrote: > Create a separate 9P client interface that can be used outside the VFS > layer. In addition to VFS, the new interface can be used to export the > authentication channel or from other interfaces. And what exact users would that be? We have a huge dislike for putting abstractions in just for the abstractions sake, so if you want this merged you'd better present a highly useful client to that interface. In the current implementation the 9p VFS layer uses directly the low-level 9p messages. It intermixes the logic required by VFS with managing some data structures (v9fs_fid for example) that belong to 9P. This makes the VFS code harder to understand and modify. Separating the low-level 9p interface makes the VFS operations shorter and easier to understand. Another scenario that we need separate interface for is exporting the authentication channels to user space so more than one user can be authenticated. The work on finishing the authentication will take some more time, but there are other changes that Eric is working on and that will also benefit from this change. The interface that this patch creates is internal to 9p and involves mainly moving code from the vfs_* files to a separate file. fs/9p is less than 50 LOC bigger than the previous version. Also the non-filesystem interface code shouldn't live in fs/ but rather in net/9p/ That makes sense, thanks. I can split the code and put the low-level transport/multiplexer/9pclient(and eventually Eric can add his 9pserver) in a net/9p directory. Thanks, Lucho - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] 9p: create separate 9p client interface
On 4/30/07, Jan Engelhardt <[EMAIL PROTECTED]> wrote: On Apr 30 2007 09:32, Latchesar Ionkov wrote: Hi! > --- a/fs/9p/Makefile > +++ b/fs/9p/Makefile > @@ -3,8 +3,8 @@ obj-$(CONFIG_9P_FS) := 9p.o > 9p-objs := \ > trans_fd.o \ > mux.o \ > - fcall.o \ > conv.o \ > + clnt.o \ Do you pay by the letter, or why is not the source file called client.c? :) The harder to understand, the better ;) I'll change it to client.c when I resubmit with part of the code in net/9p. Thanks, Lucho - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] 9p: define session flags
Create more general flags field in the v9fs_session_info struct and move the 'extended' flag as a bit in the flags. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- commit 52f23404fd5bd77b619460e00930087463ec0cd9 tree 41c68f68a211796fb65d9c772120e7b7587dc945 parent ce1bfbeb6af28c96b990a95b7d7dde52c601fb8c author Latchesar Ionkov <[EMAIL PROTECTED](none)> Wed, 12 Sep 2007 22:36:43 -0600 committer Latchesar Ionkov <[EMAIL PROTECTED](none)> Wed, 12 Sep 2007 22:36:43 -0600 fs/9p/v9fs.c |6 +++--- fs/9p/v9fs.h | 12 +++- fs/9p/vfs_inode.c | 26 +- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 08d880f..8ac2467 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c @@ -128,7 +128,7 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses) /* setup defaults */ v9ses->maxdata = 8192; - v9ses->extended = 1; + v9ses->flags = V9FS_EXTENDED; v9ses->afid = ~0; v9ses->debug = 0; v9ses->cache = 0; @@ -178,7 +178,7 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses) match_strcpy(v9ses->remotename, &args[0]); break; case Opt_legacy: - v9ses->extended = 0; + v9ses->flags &= ~V9FS_EXTENDED; break; case Opt_nodevmap: v9ses->nodev = 1; @@ -244,7 +244,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, v9ses->maxdata = v9ses->trans->maxsize-P9_IOHDRSZ; v9ses->clnt = p9_client_create(trans, v9ses->maxdata+P9_IOHDRSZ, - v9ses->extended); + v9fs_extended(v9ses)); if (IS_ERR(v9ses->clnt)) { retval = PTR_ERR(v9ses->clnt); diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index 7eb135c..804b3ef 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h @@ -29,7 +29,7 @@ struct v9fs_session_info { /* options */ unsigned int maxdata; - unsigned char extended; /* set to 1 if we are using UNIX extensions */ + 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 */ @@ -45,6 +45,11 @@ struct v9fs_session_info { struct dentry *debugfs_dir; }; +/* session flags */ +enum { + V9FS_EXTENDED, +}; + /* possible values of ->cache */ /* eventually support loose, tight, time, session, default always none */ enum { @@ -70,3 +75,8 @@ static inline struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode) { return (inode->i_sb->s_fs_info); } + +static inline int v9fs_extended(struct v9fs_session_info *v9ses) +{ + return v9ses->flags & V9FS_EXTENDED; +} diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index e5c45ee..2270d06 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -59,7 +59,7 @@ static int unixmode2p9mode(struct v9fs_session_info *v9ses, int mode) res = mode & 0777; if (S_ISDIR(mode)) res |= P9_DMDIR; - if (v9ses->extended) { + if (v9fs_extended(v9ses)) { if (S_ISLNK(mode)) res |= P9_DMSYMLINK; if (v9ses->nodev == 0) { @@ -99,21 +99,21 @@ static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode) if ((mode & P9_DMDIR) == P9_DMDIR) res |= S_IFDIR; - else if ((mode & P9_DMSYMLINK) && (v9ses->extended)) + else if ((mode & P9_DMSYMLINK) && (v9fs_extended(v9ses))) res |= S_IFLNK; - else if ((mode & P9_DMSOCKET) && (v9ses->extended) + else if ((mode & P9_DMSOCKET) && (v9fs_extended(v9ses)) && (v9ses->nodev == 0)) res |= S_IFSOCK; - else if ((mode & P9_DMNAMEDPIPE) && (v9ses->extended) + else if ((mode & P9_DMNAMEDPIPE) && (v9fs_extended(v9ses)) && (v9ses->nodev == 0)) res |= S_IFIFO; - else if ((mode & P9_DMDEVICE) && (v9ses->extended) + else if ((mode & P9_DMDEVICE) && (v9fs_extended(v9ses)) && (v9ses->nodev == 0)) res |= S_IFBLK; else res |= S_IFREG; - if (v9ses->extended) { + if (v9fs_extended(v9ses)) { if ((mode & P9_DMSETUID) == P9_DMSETUID) res |= S_ISUID; @@ -214,7 +214,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) case S_IFBLK: case S_IFCHR
[PATCH] 9p: rename uid and gid parameters
Change the names of 'uid' and 'gid' parameters to the more appropriate 'dfltuid' and 'dfltgid'. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- commit 13bf527796712619df072c0963e3f6c8c00189b8 tree 7211a2899dcfd58c76b901334a8726c7e60115e1 parent 52f23404fd5bd77b619460e00930087463ec0cd9 author Latchesar Ionkov <[EMAIL PROTECTED](none)> Wed, 12 Sep 2007 22:37:33 -0600 committer Latchesar Ionkov <[EMAIL PROTECTED](none)> Wed, 12 Sep 2007 22:37:33 -0600 Documentation/filesystems/9p.txt |4 ++-- fs/9p/v9fs.c | 16 +--- fs/9p/v9fs.h |6 -- fs/9p/vfs_inode.c|4 ++-- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/Documentation/filesystems/9p.txt b/Documentation/filesystems/9p.txt index 1a5f50d..e694cd1 100644 --- a/Documentation/filesystems/9p.txt +++ b/Documentation/filesystems/9p.txt @@ -78,9 +78,9 @@ OPTIONS noextend force legacy mode (no 9p2000.u semantics) - uid attempt to mount as a particular uid + dfltuid attempt to mount as a particular uid - gid attempt to mount with a particular gid + dfltgid attempt to mount with a particular gid afid security channel - used by Plan 9 authentication protocols diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 8ac2467..68f82be 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c @@ -84,7 +84,7 @@ static struct p9_trans_module *v9fs_match_trans(const substring_t *name) enum { /* Options that take integer arguments */ - Opt_debug, Opt_msize, Opt_uid, Opt_gid, Opt_afid, + Opt_debug, Opt_msize, Opt_dfltuid, Opt_dfltgid, Opt_afid, /* String options */ Opt_uname, Opt_remotename, Opt_trans, /* Options that take no arguments */ @@ -98,8 +98,8 @@ enum { static match_table_t tokens = { {Opt_debug, "debug=%x"}, {Opt_msize, "msize=%u"}, - {Opt_uid, "uid=%u"}, - {Opt_gid, "gid=%u"}, + {Opt_dfltuid, "dfltuid=%u"}, + {Opt_dfltgid, "dfltgid=%u"}, {Opt_afid, "afid=%u"}, {Opt_uname, "uname=%s"}, {Opt_remotename, "aname=%s"}, @@ -159,11 +159,11 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses) case Opt_msize: v9ses->maxdata = option; break; - case Opt_uid: - v9ses->uid = option; + case Opt_dfltuid: + v9ses->dfltuid = option; break; - case Opt_gid: - v9ses->gid = option; + case Opt_dfltgid: + v9ses->dfltgid = option; break; case Opt_afid: v9ses->afid = option; @@ -219,6 +219,8 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, strcpy(v9ses->name, V9FS_DEFUSER); strcpy(v9ses->remotename, V9FS_DEFANAME); + v9ses->dfltuid = V9FS_DEFUID; + v9ses->dfltgid = V9FS_DEFGID; v9ses->options = kstrdup(data, GFP_KERNEL); v9fs_parse_options(v9ses); diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index 804b3ef..5d0280a 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h @@ -38,8 +38,8 @@ struct v9fs_session_info { char *options; /* copy of mount options */ char *name; /* user name to mount as */ char *remotename; /* name of remote hierarchy being mounted */ - unsigned int uid; /* default uid/muid for legacy support */ - unsigned int gid; /* default gid for legacy support */ + unsigned int dfltuid; /* default uid/muid for legacy support */ + unsigned int dfltgid; /* default gid for legacy support */ struct p9_trans_module *trans; /* 9p transport */ struct p9_client *clnt; /* 9p client */ struct dentry *debugfs_dir; @@ -70,6 +70,8 @@ void v9fs_session_cancel(struct v9fs_session_info *v9ses); #define V9FS_PORT 564 #define V9FS_DEFUSER "nobody" #define V9FS_DEFANAME "" +#define V9FS_DEFUID(0) +#define V9FS_DEFGID(0) static inline struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode) { diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 2270d06..f08a35d 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -805,8 +805,8 @@ v9fs_stat2inode(struct p9_stat *stat, struct inode *inode, inode->i_mtime.tv_sec = stat->mtime; inode->i_ctime.tv_sec = stat->mtime; - inode->i_uid = v9ses->uid; - inode->i_gid = v9ses->gid; + inode->i_uid = v9ses->dfltuid; + inode->i_gid = v9ses->dfltgid; if (v9fs_extended(v9ses)) { inode-
[PATCH] 9p: attach-per-user
The 9P2000 protocol requires the authentication and permission checks to be done in the file server. For that reason every user that accesses the file server tree has to authenticate and attach to the server separately. Multiple users can share the same connection to the server. Currently v9fs does a single attach and executes all I/O operations as a single user. This makes using v9fs in multiuser environment unsafe as it depends on the client doing the permission checking. This patch improves the 9P2000 support by allowing every user to attach separately. The patch defines three modes of access (new mount option 'access'): - attach-per-user (access=user) (default mode for 9P2000.u) If a user tries to access a file served by v9fs for the first time, v9fs sends an attach command to the server (Tattach) specifying the user. If the attach succeeds, the user can access the v9fs tree. As there is no uname->uid (string->integer) mapping yet, this mode works only with the 9P2000.u dialect. - allow only one user to access the tree (access=) Only the user with uid can access the v9fs tree. Other users that attempt to access it will get EPERM error. - do all operations as a single user (access=any) (default for 9P2000) V9fs does a single attach and all operations are done as a single user. If this mode is selected, the v9fs behavior is identical with the current one. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- commit c3daf49339c2ba13b1d8bc5087c196093f2f78f5 tree a401d3d055bbfa3be2a4c7259f3b25f81f8c1272 parent 13bf527796712619df072c0963e3f6c8c00189b8 author Latchesar Ionkov <[EMAIL PROTECTED](none)> Wed, 12 Sep 2007 22:38:59 -0600 committer Latchesar Ionkov <[EMAIL PROTECTED](none)> Wed, 12 Sep 2007 22:38:59 -0600 Documentation/filesystems/9p.txt | 10 ++ fs/9p/fid.c | 157 ++ fs/9p/v9fs.c | 67 +--- fs/9p/v9fs.h | 11 ++- fs/9p/vfs_inode.c| 20 ++--- include/net/9p/9p.h |7 +- include/net/9p/client.h |5 + net/9p/client.c | 10 +- net/9p/conv.c| 32 +++- 9 files changed, 247 insertions(+), 72 deletions(-) diff --git a/Documentation/filesystems/9p.txt b/Documentation/filesystems/9p.txt index e694cd1..d6fd6c6 100644 --- a/Documentation/filesystems/9p.txt +++ b/Documentation/filesystems/9p.txt @@ -88,6 +88,16 @@ OPTIONS This can be used to share devices/named pipes/sockets between hosts. This functionality will be expanded in later versions. + access there are three access modes. + user = if a user tries to access a file on v9fs + filesystem for the first time, v9fs sends an + attach command (Tattach) for that user. + This is the default mode. += allows only user with uid= to access + the files on the mounted filesystem + any = v9fs does single attach and performs all + operations as one user + RESOURCES = diff --git a/fs/9p/fid.c b/fs/9p/fid.c index 15e05a1..b364da7 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c @@ -1,6 +1,7 @@ /* * V9FS FID Management * + * Copyright (C) 2007 by Latchesar Ionkov <[EMAIL PROTECTED]> * Copyright (C) 2005, 2006 by Eric Van Hensbergen <[EMAIL PROTECTED]> * * This program is free software; you can redistribute it and/or modify @@ -34,9 +35,9 @@ #include "fid.h" /** - * v9fs_fid_insert - add a fid to a dentry + * v9fs_fid_add - add a fid to a dentry + * @dentry: dentry that the fid is being added to * @fid: fid to add - * @dentry: dentry that it is being added to * */ @@ -66,52 +67,144 @@ int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid) } /** - * v9fs_fid_lookup - return a locked fid from a dentry + * v9fs_fid_find - retrieve a fid that belongs to the specified uid * @dentry: dentry to look for fid in - * - * find a fid in the dentry, obtain its semaphore and return a reference to it. - * code calling lookup is responsible for releasing lock - * - * TODO: only match fids that have the same uid as current user + * @uid: return fid that belongs to the specified user + * @any: if non-zero, return any fid associated with the dentry * */ -struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) +static struct p9_fid *v9fs_fid_find(struct dentry *dentry, u32 uid, int any) { struct v9fs_dentry *dent; - struct p9_fid *fid; - - P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); - dent = dentry->d_fsdata; - if (dent) - fid = list_entry(dent->fidlist.next, struct p9_fid, dlist); - e
Re: [PATCH] 9p: rename uid and gid parameters
Zero was the value that was used before, even though it wasn't defined explicitly. I just defined a macro so we can see and eventually change it to something better. I don't know if there is a good default value. Is nfsnobody the same on all Linux distributions? Thanks, Lucho On 9/13/07, Eric Van Hensbergen <[EMAIL PROTECTED]> wrote: > On 9/12/07, Latchesar Ionkov <[EMAIL PROTECTED]> wrote: > > Change the names of 'uid' and 'gid' parameters to the more appropriate > > 'dfltuid' and 'dfltgid'. > > > > ... > > > strcpy(v9ses->name, V9FS_DEFUSER); > > strcpy(v9ses->remotename, V9FS_DEFANAME); > > + v9ses->dfltuid = V9FS_DEFUID; > > + v9ses->dfltgid = V9FS_DEFGID; > > > ... > > +#define V9FS_DEFUID(0) > > +#define V9FS_DEFGID(0) > > I'm not sure if there is a good solution here, but I'm uncomfortable > with using uid=0 as the default. I'm not sure if there is a default > uid for nobody, but anything is probably better than 0. Looks like > nfsnobody is 65534, we could use that - even if only as a marker for > the server to map it to nobody on the target system? What do you > think? > > Particularly with attach-per-user, we probably need to look at > interacting with idmapd or create our own variant real soon. > > -eric > - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC][PATCH 6/6] 9p: 9P server Kconfig and Makefile changes
This patchset provides support for in-kernel 9P2000 servers. 9P server Kconfig and Makefile changes. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- net/9p/Kconfig |1 + net/9p/Makefile |1 + net/9p/srv/Kconfig |9 + net/9p/srv/Makefile |7 +++ 4 files changed, 18 insertions(+), 0 deletions(-) create mode 100644 net/9p/srv/Kconfig create mode 100644 net/9p/srv/Makefile diff --git a/net/9p/Kconfig b/net/9p/Kconfig index eecbf12..007ce2b 100644 --- a/net/9p/Kconfig +++ b/net/9p/Kconfig @@ -29,3 +29,4 @@ config NET_9P_DEBUG help Say Y if you want the 9P subsistem to log debug information. +source "net/9p/srv/Kconfig" diff --git a/net/9p/Makefile b/net/9p/Makefile index 5059bc0..be4d93e 100644 --- a/net/9p/Makefile +++ b/net/9p/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_NET_9P) := 9pnet.o obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o +obj-$(CONFIG_NET_9P_SRV) += srv/ 9pnet-objs := \ mod.o \ diff --git a/net/9p/srv/Kconfig b/net/9p/srv/Kconfig new file mode 100644 index 000..2013945 --- /dev/null +++ b/net/9p/srv/Kconfig @@ -0,0 +1,9 @@ +# +# 9P server configuration +# + +config NET_9P_SRV + tristate "9P server support" + depends on NET_9P + help + Say Y if you want the 9P server support diff --git a/net/9p/srv/Makefile b/net/9p/srv/Makefile new file mode 100644 index 000..c669592 --- /dev/null +++ b/net/9p/srv/Makefile @@ -0,0 +1,7 @@ +obj-$(CONFIG_NET_9P_SRV) += 9psrv.o + +9psrv-objs := \ + srv.o \ + conn.o \ + fid.o \ + socksrv.o \ -- 1.5.2.4 - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC][PATCH 4/6] 9p: 9P server fid management
This patchset provides support for in-kernel 9P2000 servers. This patch adds the 9P server fid management. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- net/9p/srv/fid.c | 178 ++ 1 files changed, 178 insertions(+), 0 deletions(-) create mode 100644 net/9p/srv/fid.c diff --git a/net/9p/srv/fid.c b/net/9p/srv/fid.c new file mode 100644 index 000..7c86204 --- /dev/null +++ b/net/9p/srv/fid.c @@ -0,0 +1,178 @@ +/* + * net/9p/srv/fid.c + * + * Fid Management + * + * Copyright (C) 2007 by Latchesar Ionkov <[EMAIL PROTECTED]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to: + * Free Software Foundation + * 51 Franklin Street, Fifth Floor + * Boston, MA 02111-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "srvimpl.h" + +struct p9srv_fidpool *p9srv_fidpool_create(void) +{ + int i; + struct p9srv_fidpool *fp; + + fp = kmalloc(sizeof(struct p9srv_fidpool), GFP_KERNEL); + if (!fp) + return ERR_PTR(-ENOMEM); + + spin_lock_init(&fp->lock); + for (i = 0; i < FID_HTABLE_SIZE; i++) + INIT_HLIST_HEAD(&fp->hash[i]); + + P9_DPRINTK(P9SRV_DEBUG_FID, "fidpool %p\n", fp); + return fp; +} + +void p9srv_fidpool_destroy(struct p9srv_fidpool *fp) +{ + int i; + + P9_DPRINTK(P9SRV_DEBUG_FID, "fidpool %p\n", fp); + for (i = 0; i < FID_HTABLE_SIZE; i++) + BUG_ON(!hlist_empty(&fp->hash[i])); + + kfree(fp); +} + +void p9srv_fidpool_reset(struct p9srv_fidpool *fp) +{ + int i; + struct p9srv_fid *cfid; + struct hlist_node *hn, *htmp; + HLIST_HEAD(hh); + + P9_DPRINTK(P9SRV_DEBUG_FID, "fidpool %p\n", fp); + spin_lock(&fp->lock); + for (i = 0; i < FID_HTABLE_SIZE; i++) { + hlist_for_each_entry_safe(cfid, hn, htmp, &fp->hash[i], + fid_list) { + hlist_del(hn); + hlist_add_head(hn, &hh); + } + } + spin_unlock(&fp->lock); + + hlist_for_each_entry_safe(cfid, hn, htmp, &hh, fid_list) { + atomic_set(&cfid->refcount, 1); + p9srv_fid_decref(cfid); + } +} + +struct p9srv_fid *p9srv_fid_create(struct p9srv_fidpool *fp, u32 fid) +{ + unsigned long hash; + struct p9srv_fid *cfid, *nfid; + struct hlist_node *hn; + + P9_DPRINTK(P9SRV_DEBUG_FID, "fidpool %p fid %d\n", fp, fid); + hash = hash_long(fid, FID_HTABLE_BITS); + nfid = kmalloc(sizeof(struct p9srv_fid), GFP_KERNEL); + if (!nfid) + return ERR_PTR(-ENOMEM); + + nfid->fid = fid; + atomic_set(&nfid->refcount, 0); + nfid->conn = NULL; + nfid->aux = NULL; + nfid->omode = ~0; + nfid->type = 0; + nfid->diroffset = 0; + nfid->uid = ~0; + nfid->fidpool = fp; + INIT_HLIST_NODE(&nfid->fid_list); + spin_lock(&fp->lock); + hlist_for_each_entry(cfid, hn, &fp->hash[hash], fid_list) { + if (cfid->fid == fid) { + spin_unlock(&fp->lock); + kfree(nfid); + return ERR_PTR(-EEXIST); + } + } + + hlist_add_head(&nfid->fid_list, &fp->hash[hash]); + spin_unlock(&fp->lock); + p9srv_fid_incref(nfid); + return nfid; +} + +struct p9srv_fid *p9srv_fid_find(struct p9srv_fidpool *fp, u32 fid) +{ + unsigned long hash; + struct p9srv_fid *cfid; + struct hlist_node *hn; + + hash = hash_long(fid, FID_HTABLE_BITS); + spin_lock(&fp->lock); + hlist_for_each_entry(cfid, hn, &fp->hash[hash], fid_list) { + if (cfid->fid == fid) { + spin_unlock(&fp->lock); + p9srv_fid_incref(cfid); + return cfid; + } + } + spin_unlock(&fp->lock); + + return NULL; +} +EXPORT_SYMBOL(p9srv_fid_find); + +void p9srv_fid_incref(struct p9srv_fid *fid) +{ + if (fid) + atomic_inc(&fid->ref
[RFC][REFERENCE ONLY] 9p: 9P ramfs sample implementation
Sample ramfs file server that uses the 9P in-kernel server implementation. This code is for reference only, it is not supposed to be merged into the kernel. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- net/9p/srv/Kconfig |6 + net/9p/srv/Makefile |4 + net/9p/srv/ramfs.c | 938 +++ 3 files changed, 948 insertions(+), 0 deletions(-) create mode 100644 net/9p/srv/ramfs.c diff --git a/net/9p/srv/Kconfig b/net/9p/srv/Kconfig index 2013945..ecb46ef 100644 --- a/net/9p/srv/Kconfig +++ b/net/9p/srv/Kconfig @@ -7,3 +7,9 @@ config NET_9P_SRV depends on NET_9P help Say Y if you want the 9P server support + +config NET_9P_RAMFS + tristate "9P ramfs sample" + depends on NET_9P_SRV + help + Say Y if you want the 9P ramfs support diff --git a/net/9p/srv/Makefile b/net/9p/srv/Makefile index c669592..9db1c31 100644 --- a/net/9p/srv/Makefile +++ b/net/9p/srv/Makefile @@ -1,7 +1,11 @@ obj-$(CONFIG_NET_9P_SRV) += 9psrv.o +obj-$(CONFIG_NET_9P_RAMFS) += 9pramfs.o 9psrv-objs := \ srv.o \ conn.o \ fid.o \ socksrv.o \ + +9pramfs-objs := \ + ramfs.o \ diff --git a/net/9p/srv/ramfs.c b/net/9p/srv/ramfs.c new file mode 100644 index 000..45b9cde --- /dev/null +++ b/net/9p/srv/ramfs.c @@ -0,0 +1,938 @@ +/* + * net/9p/srv/ramfs.c + * + * Simple RAM filesystem + * + * Copyright (C) 200xz7 by Latchesar Ionkov <[EMAIL PROTECTED]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to: + * Free Software Foundation + * 51 Franklin Street, Fifth Floor + * Boston, MA 02111-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ROOTPERM 0777 + +struct ramfs_file { + struct mutexlock; /* file lock */ + atomic_trefcount; + unsigned long status; + char*name; + u32 perm; + u64 length; + u32 atime; + u32 mtime; + u32 uid; + u32 gid; + u32 muid; + char*extension; + struct p9_qid qid; + int excl; + + struct ramfs_file *parent; + struct ramfs_file *next; /* protected by parent lock */ + struct ramfs_file *prev; + + struct ramfs_file *dirents; /* if directory */ + struct ramfs_file *dirlast; + + struct list_headfid_list; /* all fids for a file */ + + u8 *data; + u64 datasize; +}; + +struct ramfs_fid { + struct ramfs_file *file; + int omode; + u64 diroffset; + struct ramfs_file *dirent; + struct list_headfid_list; /* all fids for a file */ +}; + +enum { + Removed = 1, +}; + +int debug; +module_param(debug, int, 0); +MODULE_PARM_DESC(debug, "Debug level"); + +int port = 5641; +module_param(port, int, 0); +MODULE_PARM_DESC(port, "Port to listen on"); + +static struct p9srv *srv; +static struct ramfs_file *root; +static u64 qidpath; +static int blksize = 8192; + +static char *Enospace = "no space left"; + +static void ramfs_attach(struct p9srv_req *req); +static void ramfs_walk(struct p9srv_req *req); +static void ramfs_open(struct p9srv_req *req); +static void ramfs_create(struct p9srv_req *req); +static void ramfs_read(struct p9srv_req *req); +static void ramfs_write(struct p9srv_req *req); +static void ramfs_clunk(struct p9srv_req *req); +static void ramfs_remove(struct p9srv_req *req); +static void ramfs_stat(struct p9srv_req *req); +static void ramfs_wstat(struct p9srv_req *req); +static void ramfs_fiddestroy(struct p9srv_fid *fid); +static void ramfs_connopen(struct p9srv_conn *conn); +static void ramfs_connclose(struct p9srv_conn *conn); + +static char *p9_strdup(struct p9_str *str) +{ + char *ret; + + ret = kmalloc(str->len + 1, GFP_KERNEL); + memmove(ret, str->str, str->len); + ret[str->len] = '\0'; + + return ret; +} + +static void file_incref(struct ramfs_file *f) +{ + if (!f) +
[RFC][PATCH 1/6] 9p: 9P server low-level 9P messages support
This patchset provides support for in-kernel 9P2000 servers. Implement support for the 9P messages required by the server side. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- include/net/9p/9p.h | 19 ++ net/9p/conv.c | 508 ++- net/9p/fcprint.c|2 + 3 files changed, 525 insertions(+), 4 deletions(-) diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h index 686425a..eaa2385 100644 --- a/include/net/9p/9p.h +++ b/include/net/9p/9p.h @@ -65,6 +65,7 @@ do { \ /* Message Types */ enum { + P9_FIRST = 100, P9_TVERSION = 100, P9_RVERSION, P9_TAUTH = 102, @@ -93,6 +94,7 @@ enum { P9_RSTAT, P9_TWSTAT = 126, P9_RWSTAT, + P9_LAST, }; /* open modes */ @@ -381,6 +383,7 @@ struct p9_idpool; int p9_deserialize_stat(void *buf, u32 buflen, struct p9_stat *stat, int dotu); int p9_deserialize_fcall(void *buf, u32 buflen, struct p9_fcall *fc, int dotu); +int p9_serialize_stat(struct p9_wstat *wstat, u8 *buf, int buflen, int dotu); void p9_set_tag(struct p9_fcall *fc, u16 tag); struct p9_fcall *p9_create_tversion(u32 msize, char *version); struct p9_fcall *p9_create_tattach(u32 fid, u32 afid, char *uname, @@ -403,6 +406,22 @@ struct p9_fcall *p9_create_tremove(u32 fid); struct p9_fcall *p9_create_tstat(u32 fid); struct p9_fcall *p9_create_twstat(u32 fid, struct p9_wstat *wstat, int dotu); +struct p9_fcall *p9_create_rversion(u32 msize, char *version); +struct p9_fcall *p9_create_rattach(struct p9_qid *qid); +struct p9_fcall *p9_create_rerror(char *ename, u32 ecode, int dotu); +struct p9_fcall *p9_create_rauth(struct p9_qid *qid); +struct p9_fcall *p9_create_rflush(void); +struct p9_fcall *p9_create_rwalk(int nwqid, struct p9_qid *wqids); +struct p9_fcall *p9_create_ropen(struct p9_qid *qid, u32 iounit); +struct p9_fcall *p9_create_rcreate(struct p9_qid *qid, u32 iounit); +struct p9_fcall *p9_create_rread(u32 count, u8 *data); +struct p9_fcall *p9_create_rwrite(u32 count); +struct p9_fcall *p9_create_rclunk(void); +struct p9_fcall *p9_create_rremove(void); +struct p9_fcall *p9_create_rstat(struct p9_wstat *st, int dotu); +struct p9_fcall *p9_create_rwstat(void); +struct p9_fcall *p9_alloc_rread(u32 count); +void p9_set_rread_count(struct p9_fcall *fc, u32 count); int p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int dotu); int p9_errstr2errno(char *errstr, int len); diff --git a/net/9p/conv.c b/net/9p/conv.c index aa2aa98..7cb8faf 100644 --- a/net/9p/conv.c +++ b/net/9p/conv.c @@ -41,6 +41,8 @@ struct cbuf { unsigned char *ep; }; +static int p9_size_wstat(struct p9_wstat *wstat, int dotu); + static inline void buf_init(struct cbuf *buf, void *data, int datalen) { buf->sp = buf->p = data; @@ -130,9 +132,45 @@ static char *buf_put_stringn(struct cbuf *buf, const char *s, u16 slen) static inline void buf_put_string(struct cbuf *buf, const char *s) { - buf_put_stringn(buf, s, strlen(s)); + buf_put_stringn(buf, s, s?strlen(s):0); +} + +static inline void buf_put_qid(struct cbuf *buf, struct p9_qid *qid) +{ + buf_put_int8(buf, qid->type); + buf_put_int32(buf, qid->version); + buf_put_int64(buf, qid->path); +} + +static inline void buf_put_wstat(struct cbuf *bufp, struct p9_wstat *wstat, + int dotu) +{ + int statsz; + + statsz = p9_size_wstat(wstat, dotu); + buf_put_int16(bufp, statsz); + buf_put_int16(bufp, wstat->type); + buf_put_int32(bufp, wstat->dev); + buf_put_qid(bufp, &wstat->qid); + buf_put_int32(bufp, wstat->mode); + buf_put_int32(bufp, wstat->atime); + buf_put_int32(bufp, wstat->mtime); + buf_put_int64(bufp, wstat->length); + + buf_put_string(bufp, wstat->name); + buf_put_string(bufp, wstat->uid); + buf_put_string(bufp, wstat->gid); + buf_put_string(bufp, wstat->muid); + + if (dotu) { + buf_put_string(bufp, wstat->extension); + buf_put_int32(bufp, wstat->n_uid); + buf_put_int32(bufp, wstat->n_gid); + buf_put_int32(bufp, wstat->n_muid); + } } + static u8 buf_get_int8(struct cbuf *buf) { u8 ret = 0; @@ -344,17 +382,63 @@ p9_deserialize_fcall(void *buf, u32 buflen, struct p9_fcall *rcall, default: P9_EPRINTK(KERN_ERR, "unknown message type: %d\n", rcall->id); return -EPROTO; + case P9_TVERSION: + rcall->params.tversion.msize = buf_get_int32(bufp); + buf_get_str(bufp, &rcall->params.tversion.version); + break; case P9_RVERSION: rcall->params.rversion.msize = buf_get_int32(bufp); buf_get_str(bufp, &rcall->params.rversion.version); break; + case P9_TAUTH: +
[RFC][PATCH 2/6] 9p: 9P server interface and common srv code
This patchset provides support for in-kernel 9P2000 servers. This patch adds the header file that defines the 9P server interface as well as the code for the common support functions for the server. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- include/net/9p/srv.h | 208 net/9p/srv/srv.c | 891 ++ net/9p/srv/srvimpl.h | 46 +++ 3 files changed, 1145 insertions(+), 0 deletions(-) create mode 100644 include/net/9p/srv.h create mode 100644 net/9p/srv/srv.c create mode 100644 net/9p/srv/srvimpl.h diff --git a/include/net/9p/srv.h b/include/net/9p/srv.h new file mode 100644 index 000..36635c6 --- /dev/null +++ b/include/net/9p/srv.h @@ -0,0 +1,208 @@ +/* + * include/net/9p/srv.h + * + * 9P server definitions. + * + * Copyright (C) 2007 by Latchesar Ionkov <[EMAIL PROTECTED]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to: + * Free Software Foundation + * 51 Franklin Street, Fifth Floor + * Boston, MA 02111-1301 USA + * + */ + +#ifndef NET_9PSRV_H +#define NET_9PSRV_H + +#define P9SRV_DEBUG_SRV(1<<16) +#define P9SRV_DEBUG_CONN (1<<17) +#define P9SRV_DEBUG_FID(1<<18) +#define P9SRV_DEBUG_REQ(1<<19) +#define P9SRV_DEBUG_FCALL (1<<20) +#define P9SRV_DEBUG_FS (1<<21) + +#define MAXPOLLWADDR 2 + +struct p9srv; +struct p9srv_fid; +struct p9srv_fidpool; +struct p9srv_conn; +struct p9srv_req; + +struct p9srv { + int msize; + int dotu; /* 9P2000.u */ + void*srvaux; + void*treeaux; + int debuglevel; + void(*start)(struct p9srv *); + void(*stop)(struct p9srv *); + void(*destroy)(struct p9srv *); + void(*connopen)(struct p9srv_conn *); + void(*connclose)(struct p9srv_conn *); + void(*fiddestroy)(struct p9srv_fid *); + void(*reqdestroy)(struct p9srv_req *); + + /* 9P message handlers */ + void(*attach)(struct p9srv_req *); + void(*auth)(struct p9srv_req *); + int (*flush)(struct p9srv_req *); + void(*walk)(struct p9srv_req *); + void(*open)(struct p9srv_req *); + void(*create)(struct p9srv_req *); + void(*read)(struct p9srv_req *); + void(*write)(struct p9srv_req *); + void(*clunk)(struct p9srv_req *); + void(*remove)(struct p9srv_req *); + void(*stat)(struct p9srv_req *); + void(*wstat)(struct p9srv_req *); + + /* implementation specific */ + atomic_trefcount; + spinlock_t lock; /* covers all srv fields */ + unsigned long status; + struct list_headconn_list; /* all connections for srv */ + struct list_headreq_list; /* requests not yet worked on */ + struct list_headworkreq_list; /* requests being worked on */ + struct work_struct pq; /* process request */ +}; + +enum { + /* connection status values */ + Worksched = 1, /* work scheduled or running */ +}; + +struct p9srv_conn { + struct p9srv*srv; + struct p9_trans *trans; + int msize; + int dotu; /* 9P2000.u */ + + /* implementation specific */ + spinlock_t lock; /* covers all conn fields */ + unsigned long status; + struct p9srv_fidpool*fidpool; + struct work_struct rq; + struct work_struct wq; + struct list_headconn_list; /* all srv connections */ + struct list_headvpt_conn_list; /* all connections for vpt */ + + /* outgoing data */ + struct list_headoreq_list; + char*obuf; /* outgoing data */ + int opos; /* next byte in obuf */ + int
[RFC][PATCH 5/6] 9p: 9P server TCP socket connection support
This patchset provides support for in-kernel 9P2000 servers. Support for 9P servers listening on TCP sockets. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- net/9p/srv/socksrv.c | 252 ++ 1 files changed, 252 insertions(+), 0 deletions(-) create mode 100644 net/9p/srv/socksrv.c diff --git a/net/9p/srv/socksrv.c b/net/9p/srv/socksrv.c new file mode 100644 index 000..c304b91 --- /dev/null +++ b/net/9p/srv/socksrv.c @@ -0,0 +1,252 @@ +/* + * net/9p/srv/socksrv.c + * + * 9P Socket Server + * + * Copyright (C) 2007 by Latchesar Ionkov <[EMAIL PROTECTED]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to: + * Free Software Foundation + * 51 Franklin Street, Fifth Floor + * Boston, MA 02111-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "srvimpl.h" + +struct p9srv_socksrv { + struct sockaddr_in saddr; + struct socket *sock; + struct p9srv*srv; + struct work_struct wq; +}; + +void (*p9srv_socksrv_dr_save)(struct sock *sock, int count); + +static void p9srv_socksrv_start(struct p9srv *); +static void p9srv_socksrv_stop(struct p9srv *); +static void p9srv_socksrv_destroy(struct p9srv *); +static void p9srv_socksrv_data_ready(struct sock *sock, int count); +static void p9srv_socksrv_accept(struct work_struct *work); + +struct p9srv *p9srv_socksrv_create(int port) +{ + int n, err; + struct p9srv_socksrv *ss; + struct p9srv *srv; + + srv = NULL; + ss = kmalloc(sizeof(struct p9srv_socksrv), GFP_KERNEL); + if (!ss) + return ERR_PTR(-ENOMEM); + + ss->sock = NULL; + err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &ss->sock); + if (!ss->sock) { + P9_DPRINTK(P9SRV_DEBUG_SRV, "cannot create socket %d\n", err); + goto error; + } + + n = 1; + ss->saddr.sin_family = AF_INET; + memset(&ss->saddr.sin_zero, 0, sizeof(ss->saddr.sin_zero)); + ss->saddr.sin_addr.s_addr = htonl(INADDR_ANY); + ss->saddr.sin_port = htons(port); + err = ss->sock->ops->bind(ss->sock, (struct sockaddr *) &ss->saddr, + sizeof(ss->saddr)); + if (err < 0) { + P9_DPRINTK(P9SRV_DEBUG_SRV, "cannot create bind %d\n", err); + goto error; + } + + err = kernel_setsockopt(ss->sock, SOL_SOCKET, SO_REUSEADDR, (char *) &n, + sizeof(n)); + if (err < 0) { + P9_DPRINTK(P9SRV_DEBUG_SRV, "cannot create setsockopt\n"); + goto error; + } + + srv = p9srv_srv_create(); + if (!srv) { + err = PTR_ERR(srv); + srv = NULL; + goto error; + } + + ss->srv = srv; + INIT_WORK(&ss->wq, p9srv_socksrv_accept); + srv->srvaux = ss; + srv->start = p9srv_socksrv_start; + srv->stop = p9srv_socksrv_stop; + srv->destroy = p9srv_socksrv_destroy; + + P9_DPRINTK(P9SRV_DEBUG_SRV, "server %p on port %d created\n", + srv, port); + return srv; + +error: + if (ss->sock) + sock_release(ss->sock); + + if (srv) + p9srv_srv_destroy(srv); + + kfree(ss); + return ERR_PTR(err); +} +EXPORT_SYMBOL(p9srv_socksrv_create); + +static void p9srv_socksrv_start(struct p9srv *srv) +{ + int err; + struct p9srv_socksrv *ss; + + ss = srv->srvaux; + err = ss->sock->ops->listen(ss->sock, 5); + if (err < 0) { + P9_DPRINTK(P9SRV_DEBUG_SRV, "cannot listen %d\n", err); + return; + } + + p9srv_socksrv_dr_save = ss->sock->sk->sk_data_ready; + ss->sock->sk->sk_data_ready = p9srv_socksrv_data_ready; + ss->sock->sk->sk_user_data = srv; +} + +static void p9srv_socksrv_stop(struct p9srv *srv) +{ + struct p9srv_socksrv *ss; + + P9_DPRINTK(P9SRV_DEBUG_SRV, "srv %p\n", srv); + ss = srv->srvaux; + if (ss->sock) { + ss->sock->ops->shutdown(ss->sock, 2); + sock_release(ss->so
[RFC][PATCH 3/6] 9p: 9P server connection code
This patchset provides support for in-kernel 9P2000 servers. This patch add the 9P server connection code. Signed-off-by: Latchesar Ionkov <[EMAIL PROTECTED]> --- net/9p/srv/conn.c | 743 + 1 files changed, 743 insertions(+), 0 deletions(-) create mode 100644 net/9p/srv/conn.c diff --git a/net/9p/srv/conn.c b/net/9p/srv/conn.c new file mode 100644 index 000..335ee17 --- /dev/null +++ b/net/9p/srv/conn.c @@ -0,0 +1,743 @@ +/* + * net/9p/srv/conn.c + * + * Server connection + * + * Copyright (C) 2007 by Latchesar Ionkov <[EMAIL PROTECTED]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to: + * Free Software Foundation + * 51 Franklin Street, Fifth Floor + * Boston, MA 02111-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "srvimpl.h" + +#define SCHED_TIMEOUT 10 + +struct p9srv_poll_task { + struct task_struct *task; + struct list_head conn_list; + int connum; +}; + +static DEFINE_MUTEX(p9srv_task_lock); +struct workqueue_struct *p9srv_wq; + +static int p9srv_num; +static int p9srv_poll_task_num; +static struct p9srv_poll_task p9srv_poll_tasks[100]; + +static int p9srv_calc_poll_procs(int); +static int p9srv_poll_start(struct p9srv_conn *c); +static void p9srv_poll_stop(struct p9srv_conn *c); +static void p9srv_pollwait(struct file *, wait_queue_head_t *, poll_table *); +static void p9srv_poll_conn(struct p9srv_conn *c); +static int p9srv_poll_proc(void *a); +static void p9srv_read_work(struct work_struct *work); +static void p9srv_write_work(struct work_struct *work); + +int p9srv_conn_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(p9srv_poll_tasks); i++) + p9srv_poll_tasks[i].task = NULL; + + p9srv_wq = create_workqueue("9psrv"); + if (!p9srv_wq) { + printk(KERN_WARNING "9psrv: creating workqueue failed\n"); + return -ENOMEM; + } + + return 0; +} + +void p9srv_conn_exit(void) +{ + destroy_workqueue(p9srv_wq); + p9srv_wq = NULL; +} + +struct p9srv_conn *p9srv_conn_create(struct p9srv *srv, + struct p9_trans *trans) +{ + int i, n, err; + struct p9srv_conn *conn; + + conn = kmalloc(sizeof(struct p9srv_conn), GFP_KERNEL); + if (!conn) + return ERR_PTR(-ENOMEM); + + spin_lock_init(&conn->lock); + conn->srv = srv; + conn->trans = trans; + conn->msize = srv->msize; + conn->dotu = srv->dotu; + conn->status = 0; + INIT_WORK(&conn->rq, p9srv_read_work); + INIT_WORK(&conn->wq, p9srv_write_work); + INIT_LIST_HEAD(&conn->conn_list); + INIT_LIST_HEAD(&conn->vpt_conn_list); + INIT_LIST_HEAD(&conn->oreq_list); + conn->opos = 0; + conn->osize = 0; + conn->obuf = NULL; + conn->icall = NULL; + conn->ipos = 0; + conn->ibuf = 0; + conn->poll_task = NULL; + memset(&conn->poll_wait, 0, sizeof(conn->poll_wait)); + memset(&conn->poll_waddr, 0, sizeof(conn->poll_waddr)); + conn->fidpool = p9srv_fidpool_create(); + if (!conn->fidpool) { + err = PTR_ERR(conn->fidpool); + kfree(conn); + return ERR_PTR(err); + } + + err = p9srv_poll_start(conn); + if (err) { + p9srv_fidpool_destroy(conn->fidpool); + kfree(conn); + return ERR_PTR(err); + } + + n = trans->poll(trans, &conn->pt); + if (n & POLLIN) + set_bit(Rpending, &conn->status); + + if (n & POLLOUT) + set_bit(Wpending, &conn->status); + + for (i = 0; i < ARRAY_SIZE(conn->poll_waddr); i++) { + if (IS_ERR(conn->poll_waddr[i])) { + p9srv_poll_stop(conn); + err = PTR_ERR(conn->poll_waddr[i]); + p9srv_fidpool_destroy(conn->fidpool); + kfree(conn); + return ERR_PTR(err); + } + } + + spin_lock(&srv->lock); + list_add_tail(&conn->conn_list, &srv->conn_list); + spin_unlock(&srv->lock); + +
Re: [PATCH 4/5] 9p: introduce async read requests
If the user asked for more than msize-iohdrsz (or rather iounit) bytes, you should do your best to read as much as possible before you return to user space. That means that if a read returns the maximum possible count you HAVE to issue another read until you get a short read. What Al is hinting at is that you can issue multiple read requests simultaneously, assuming that most of them will return data. So the way I see your options are two, with an additional tweak. The first option is to issue more read calls when the previous ones complete (your second option). The second option is at the beginning to issue all the read calls simultaneously. And the tweak is to do something in between and issue up to a limit of simultaneous read calls. Thanks, Lucho On Mon, Dec 12, 2016 at 6:15 PM, Stefano Stabellini wrote: > Hi Al, > thanks for looking at the patch. > > On Sat, 10 Dec 2016, Al Viro wrote: >> On Thu, Dec 08, 2016 at 12:59:05PM -0800, Stefano Stabellini wrote: >> >> >> > + } else { >> > + req = p9_client_get_req(clnt, P9_TREAD, "dqd", >> > fid->fid, offset, rsize); >> > + if (IS_ERR(req)) { >> > + *err = PTR_ERR(req); >> > + break; >> > + } >> > + req->rsize = iov_iter_get_pages_alloc(to, >> > &req->pagevec, >> > + (size_t)rsize, &req->offset); >> > + req->kiocb = iocb; >> > + for (i = 0; i < req->rsize; i += PAGE_SIZE) >> > + >> > page_cache_get_speculative(req->pagevec[i/PAGE_SIZE]); >> > + req->callback = p9_client_read_complete; >> > + >> > + *err = clnt->trans_mod->request(clnt, req); >> > + if (*err < 0) { >> > + clnt->status = Disconnected; >> > + release_pages(req->pagevec, >> > + (req->rsize + PAGE_SIZE - 1) / >> > PAGE_SIZE, >> > + true); >> > + kvfree(req->pagevec); >> > + p9_free_req(clnt, req); >> > + break; >> > + } >> > + >> > + *err = -EIOCBQUEUED; >> >> IDGI. AFAICS, your code will result in shitloads of short reads - every >> time when you give it a multi-iovec array, only the first one will be >> issued and the rest won't be even looked at. Sure, it is technically >> legal, but I very much doubt that aio users will be happy with that. >> >> What am I missing here? > > There is a problem with short reads, but I don't think it is the one > you described, unless I made a mistake somewhere. > > The code above will issue one request as big as possible (size is > limited by clnt->msize, which is the size of the channel). No matter how > many segs in the iov_iter, the request will cover the maximum amount of > bytes allowed by the channel, typically 4K but can be larger. So > multi-iovec arrays should be handled correctly up to msize. Please let > me know if I am wrong, I am not an expert on this. I tried, but couldn't > actually get any multi-iovec arrays in my tests. > > > That said, reading the code again, there are indeed two possible causes > of short reads. The first one are responses which have a smaller byte > count than requested. Currently this case is not handled, forwarding > the short read up to the user. But I wrote and tested successfully a > patch that issues another follow-up request from the completion > function. Example: > p9_client_read, issue request, size 4K > p9_client_read_complete, receive response, count 2K > p9_client_read_complete, issue request size 4K-2K = 2K > p9_client_read_complete, receive response size 2K > p9_client_read_complete, call ki_complete > > > The second possible cause of short reads are requests which are bigger > than msize. For example a 2MB read over a 4K channel. In this patch we > simply issue one request as big as msize, and eventually return to the > caller a smaller byte count. One option is to simply fall back to sync > IO in these cases. Another solution is to use the same technique > described above: we issue the first request as big as msize, then, from > the callback function, we issue a follow-up request, and again, and > again, until we fully complete the large read. This way, although we are > not issuing any simultaneous requests for a specific large read, at > least we can issue other aio requests in parallel for other reads or > writes. It should still be more performant than sync IO. > > I am thinking of implementing this second option in the next version of > the series.
Re: [PATCH] fs/9p: Compare qid.path in v9fs_test_inode
Reviewed-by: Latchesar Ionkov On Tue, Feb 21, 2017 at 6:06 PM, Tuomas Tynkkynen wrote: > Commit fd2421f54423 ("fs/9p: When doing inode lookup compare qid details > and inode mode bits.") transformed v9fs_qid_iget() to use iget5_locked() > instead of iget_locked(). However, the test() callback is not checking > fid.path at all, which means that a lookup in the inode cache can now > accidentally locate a completely wrong inode from the same inode hash > bucket if the other fields (qid.type and qid.version) match. > > Fixes: fd2421f54423 ("fs/9p: When doing inode lookup compare qid details and > inode mode bits.") > Cc: sta...@vger.kernel.org > Signed-off-by: Tuomas Tynkkynen > --- > Does this sound sensible? I have never reproduced the problem myself but > reportedly this patch solves some really weird problems where the > symptoms match (wrong files being opened unpredictably). > --- > fs/9p/vfs_inode.c | 3 +++ > fs/9p/vfs_inode_dotl.c | 3 +++ > 2 files changed, 6 insertions(+) > > diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c > index 30ca770c5e0b..f8ab4a66acaf 100644 > --- a/fs/9p/vfs_inode.c > +++ b/fs/9p/vfs_inode.c > @@ -483,6 +483,9 @@ static int v9fs_test_inode(struct inode *inode, void > *data) > > if (v9inode->qid.type != st->qid.type) > return 0; > + > + if (v9inode->qid.path != st->qid.path) > + return 0; > return 1; > } > > diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c > index afaa4b6de801..c3dd0d42bb3a 100644 > --- a/fs/9p/vfs_inode_dotl.c > +++ b/fs/9p/vfs_inode_dotl.c > @@ -87,6 +87,9 @@ static int v9fs_test_inode_dotl(struct inode *inode, void > *data) > > if (v9inode->qid.type != st->qid.type) > return 0; > + > + if (v9inode->qid.path != st->qid.path) > + return 0; > return 1; > } > > -- > 2.11.1 >
Re: [PATCH 0/2] 9p: Fixes for hard-to-hit bugs
Acked-by: Latchesar Ionkov On Wed, Sep 6, 2017 at 8:59 AM, Tuomas Tynkkynen wrote: > These two patches fix two hard-to-hit (but really annoying) bugs in 9p. > The first one was posted earlier in February (with one R-b), the second > is a new one. > > Both of these have had soaking in NixOS distribution kernels for > a couple of months with no ill effects. > > Tuomas Tynkkynen (2): > fs/9p: Compare qid.path in v9fs_test_inode > net/9p: Switch to wait_event_killable() > > fs/9p/vfs_inode.c | 3 +++ > fs/9p/vfs_inode_dotl.c | 3 +++ > net/9p/client.c| 3 +-- > net/9p/trans_virtio.c | 13 ++--- > net/9p/trans_xen.c | 4 ++-- > 5 files changed, 15 insertions(+), 11 deletions(-) > > -- > 2.13.0 >