Skip to content

Commit

Permalink
Merge tag 'for-linus-3.11-merge-window-part-2' of git://git.kernel.or…
Browse files Browse the repository at this point in the history
…g/pub/scm/linux/kernel/git/ericvh/v9fs

Pull second round of 9p patches from Eric Van Hensbergen:
 "Several of these patches were rebased in order to correct style
  issues.  Only stylistic changes were made versus the patches which
  were in linux-next for two weeks.  The rebases have been in linux-next
  for 3 days and have passed my regressions.

  The bulk of these are RDMA fixes and improvements.  There's also some
  additions on the extended attributes front to support some additional
  namespaces and a new option for TCP to force allocation of mount
  requests from a priviledged port"

* tag 'for-linus-3.11-merge-window-part-2' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs:
  fs/9p: Remove the unused variable "err" in v9fs_vfs_getattr()
  9P: Add cancelled() to the transport functions.
  9P/RDMA: count posted buffers without a pending request
  9P/RDMA: Improve error handling in rdma_request
  9P/RDMA: Do not free req->rc in error handling in rdma_request()
  9P/RDMA: Use a semaphore to protect the RQ
  9P/RDMA: Protect against duplicate replies
  9P/RDMA: increase P9_RDMA_MAXSIZE to 1MB
  9pnet: refactor struct p9_fcall alloc code
  9P/RDMA: rdma_request() needs not allocate req->rc
  9P: Fix fcall allocation for rdma
  fs/9p: xattr: add trusted and security namespaces
  net/9p: add privport option to 9p tcp transport
  • Loading branch information
torvalds committed Jul 11, 2013
2 parents 746919d + f2692ea commit 19d2f8e
Show file tree
Hide file tree
Showing 11 changed files with 355 additions and 79 deletions.
13 changes: 13 additions & 0 deletions fs/9p/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,16 @@ config 9P_FS_POSIX_ACL
If you don't know what Access Control Lists are, say N

endif


config 9P_FS_SECURITY
bool "9P Security Labels"
depends on 9P_FS
help
Security labels support alternative access control models
implemented by security modules like SELinux. This option
enables an extended attribute handler for file security
labels in the 9P filesystem.

If you are not using a security module that requires using
extended attributes for file security labels, say N.
4 changes: 3 additions & 1 deletion fs/9p/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ obj-$(CONFIG_9P_FS) := 9p.o
v9fs.o \
fid.o \
xattr.o \
xattr_user.o
xattr_user.o \
xattr_trusted.o

9p-$(CONFIG_9P_FSCACHE) += cache.o
9p-$(CONFIG_9P_FS_POSIX_ACL) += acl.o
9p-$(CONFIG_9P_FS_SECURITY) += xattr_security.o
2 changes: 0 additions & 2 deletions fs/9p/vfs_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1054,13 +1054,11 @@ static int
v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
{
int err;
struct v9fs_session_info *v9ses;
struct p9_fid *fid;
struct p9_wstat *st;

p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry);
err = -EPERM;
v9ses = v9fs_dentry2v9ses(dentry);
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
generic_fillattr(dentry->d_inode, stat);
Expand Down
4 changes: 4 additions & 0 deletions fs/9p/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,13 @@ ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)

const struct xattr_handler *v9fs_xattr_handlers[] = {
&v9fs_xattr_user_handler,
&v9fs_xattr_trusted_handler,
#ifdef CONFIG_9P_FS_POSIX_ACL
&v9fs_xattr_acl_access_handler,
&v9fs_xattr_acl_default_handler,
#endif
#ifdef CONFIG_9P_FS_SECURITY
&v9fs_xattr_security_handler,
#endif
NULL
};
2 changes: 2 additions & 0 deletions fs/9p/xattr.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

extern const struct xattr_handler *v9fs_xattr_handlers[];
extern struct xattr_handler v9fs_xattr_user_handler;
extern struct xattr_handler v9fs_xattr_trusted_handler;
extern struct xattr_handler v9fs_xattr_security_handler;
extern const struct xattr_handler v9fs_xattr_acl_access_handler;
extern const struct xattr_handler v9fs_xattr_acl_default_handler;

Expand Down
80 changes: 80 additions & 0 deletions fs/9p/xattr_security.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright IBM Corporation, 2010
* Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/


#include <linux/module.h>
#include <linux/string.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include "xattr.h"

static int v9fs_xattr_security_get(struct dentry *dentry, const char *name,
void *buffer, size_t size, int type)
{
int retval;
char *full_name;
size_t name_len;
size_t prefix_len = XATTR_SECURITY_PREFIX_LEN;

if (name == NULL)
return -EINVAL;

if (strcmp(name, "") == 0)
return -EINVAL;

name_len = strlen(name);
full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
if (!full_name)
return -ENOMEM;
memcpy(full_name, XATTR_SECURITY_PREFIX, prefix_len);
memcpy(full_name+prefix_len, name, name_len);
full_name[prefix_len + name_len] = '\0';

retval = v9fs_xattr_get(dentry, full_name, buffer, size);
kfree(full_name);
return retval;
}

static int v9fs_xattr_security_set(struct dentry *dentry, const char *name,
const void *value, size_t size, int flags, int type)
{
int retval;
char *full_name;
size_t name_len;
size_t prefix_len = XATTR_SECURITY_PREFIX_LEN;

if (name == NULL)
return -EINVAL;

if (strcmp(name, "") == 0)
return -EINVAL;

name_len = strlen(name);
full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
if (!full_name)
return -ENOMEM;
memcpy(full_name, XATTR_SECURITY_PREFIX, prefix_len);
memcpy(full_name + prefix_len, name, name_len);
full_name[prefix_len + name_len] = '\0';

retval = v9fs_xattr_set(dentry, full_name, value, size, flags);
kfree(full_name);
return retval;
}

struct xattr_handler v9fs_xattr_security_handler = {
.prefix = XATTR_SECURITY_PREFIX,
.get = v9fs_xattr_security_get,
.set = v9fs_xattr_security_set,
};
80 changes: 80 additions & 0 deletions fs/9p/xattr_trusted.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright IBM Corporation, 2010
* Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/


#include <linux/module.h>
#include <linux/string.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include "xattr.h"

static int v9fs_xattr_trusted_get(struct dentry *dentry, const char *name,
void *buffer, size_t size, int type)
{
int retval;
char *full_name;
size_t name_len;
size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN;

if (name == NULL)
return -EINVAL;

if (strcmp(name, "") == 0)
return -EINVAL;

name_len = strlen(name);
full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
if (!full_name)
return -ENOMEM;
memcpy(full_name, XATTR_TRUSTED_PREFIX, prefix_len);
memcpy(full_name+prefix_len, name, name_len);
full_name[prefix_len + name_len] = '\0';

retval = v9fs_xattr_get(dentry, full_name, buffer, size);
kfree(full_name);
return retval;
}

static int v9fs_xattr_trusted_set(struct dentry *dentry, const char *name,
const void *value, size_t size, int flags, int type)
{
int retval;
char *full_name;
size_t name_len;
size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN;

if (name == NULL)
return -EINVAL;

if (strcmp(name, "") == 0)
return -EINVAL;

name_len = strlen(name);
full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
if (!full_name)
return -ENOMEM;
memcpy(full_name, XATTR_TRUSTED_PREFIX, prefix_len);
memcpy(full_name + prefix_len, name, name_len);
full_name[prefix_len + name_len] = '\0';

retval = v9fs_xattr_set(dentry, full_name, value, size, flags);
kfree(full_name);
return retval;
}

struct xattr_handler v9fs_xattr_trusted_handler = {
.prefix = XATTR_TRUSTED_PREFIX,
.get = v9fs_xattr_trusted_get,
.set = v9fs_xattr_trusted_set,
};
6 changes: 6 additions & 0 deletions include/net/9p/transport.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
#ifndef NET_9P_TRANSPORT_H
#define NET_9P_TRANSPORT_H

#define P9_DEF_MIN_RESVPORT (665U)
#define P9_DEF_MAX_RESVPORT (1023U)

/**
* struct p9_trans_module - transport module interface
* @list: used to maintain a list of currently available transports
Expand All @@ -37,6 +40,8 @@
* @close: member function to discard a connection on this transport
* @request: member function to issue a request to the transport
* @cancel: member function to cancel a request (if it hasn't been sent)
* @cancelled: member function to notify that a cancelled request will not
* not receive a reply
*
* This is the basic API for a transport module which is registered by the
* transport module with the 9P core network module and used by the client
Expand All @@ -55,6 +60,7 @@ struct p9_trans_module {
void (*close) (struct p9_client *);
int (*request) (struct p9_client *, struct p9_req_t *req);
int (*cancel) (struct p9_client *, struct p9_req_t *req);
int (*cancelled)(struct p9_client *, struct p9_req_t *req);
int (*zc_request)(struct p9_client *, struct p9_req_t *,
char *, char *, int , int, int, int);
};
Expand Down
70 changes: 43 additions & 27 deletions net/9p/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,17 @@ static int parse_opts(char *opts, struct p9_client *clnt)
return ret;
}

struct p9_fcall *p9_fcall_alloc(int alloc_msize)
{
struct p9_fcall *fc;
fc = kmalloc(sizeof(struct p9_fcall) + alloc_msize, GFP_NOFS);
if (!fc)
return NULL;
fc->capacity = alloc_msize;
fc->sdata = (char *) fc + sizeof(struct p9_fcall);
return fc;
}

/**
* p9_tag_alloc - lookup/allocate a request by tag
* @c: client session to lookup tag within
Expand Down Expand Up @@ -256,39 +267,36 @@ p9_tag_alloc(struct p9_client *c, u16 tag, unsigned int max_size)
col = tag % P9_ROW_MAXTAG;

req = &c->reqs[row][col];
if (!req->tc) {
if (!req->wq) {
req->wq = kmalloc(sizeof(wait_queue_head_t), GFP_NOFS);
if (!req->wq) {
pr_err("Couldn't grow tag array\n");
return ERR_PTR(-ENOMEM);
}
if (!req->wq)
goto grow_failed;
init_waitqueue_head(req->wq);
req->tc = kmalloc(sizeof(struct p9_fcall) + alloc_msize,
GFP_NOFS);
req->rc = kmalloc(sizeof(struct p9_fcall) + alloc_msize,
GFP_NOFS);
if ((!req->tc) || (!req->rc)) {
pr_err("Couldn't grow tag array\n");
kfree(req->tc);
kfree(req->rc);
kfree(req->wq);
req->tc = req->rc = NULL;
req->wq = NULL;
return ERR_PTR(-ENOMEM);
}
req->tc->capacity = alloc_msize;
req->rc->capacity = alloc_msize;
req->tc->sdata = (char *) req->tc + sizeof(struct p9_fcall);
req->rc->sdata = (char *) req->rc + sizeof(struct p9_fcall);
}

if (!req->tc)
req->tc = p9_fcall_alloc(alloc_msize);
if (!req->rc)
req->rc = p9_fcall_alloc(alloc_msize);
if (!req->tc || !req->rc)
goto grow_failed;

p9pdu_reset(req->tc);
p9pdu_reset(req->rc);

req->tc->tag = tag-1;
req->status = REQ_STATUS_ALLOC;

return &c->reqs[row][col];
return req;

grow_failed:
pr_err("Couldn't grow tag array\n");
kfree(req->tc);
kfree(req->rc);
kfree(req->wq);
req->tc = req->rc = NULL;
req->wq = NULL;
return ERR_PTR(-ENOMEM);
}

/**
Expand Down Expand Up @@ -648,12 +656,20 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
return PTR_ERR(req);


/* if we haven't received a response for oldreq,
remove it from the list. */
/*
* if we haven't received a response for oldreq,
* remove it from the list, and notify the transport
* layer that the reply will never arrive.
*/
spin_lock(&c->lock);
if (oldreq->status == REQ_STATUS_FLSH)
if (oldreq->status == REQ_STATUS_FLSH) {
list_del(&oldreq->req_list);
spin_unlock(&c->lock);
spin_unlock(&c->lock);
if (c->trans_mod->cancelled)
c->trans_mod->cancelled(c, req);
} else {
spin_unlock(&c->lock);
}

p9_free_req(c, req);
return 0;
Expand Down
Loading

0 comments on commit 19d2f8e

Please sign in to comment.