mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
NFS client updates for Linux 3.6
Features include:
- More preparatory patches for modularising NFSv2/v3/v4.
Split out the various NFSv2/v3/v4-specific code into separate
files
- More preparation for the NFSv4 migration code
- Ensure that OPEN(O_CREATE) observes the pNFS mds threshold parameters
- pNFS fast failover when the data servers are down
- Various cleanups and debugging patches
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)
iQIcBAABAgAGBQJQFwYRAAoJEGcL54qWCgDy6YAQAIZuUPFCQbuzWev4L/XA0uhg
0xjr9YBmg57UOs8e7FhS0azJip+D/kmF2Rx5gCMX0QO/IwaEVoms4BS8zjFOr3yL
cPIyY5ErF+WJ25f3Mz8k0wOHTzrOvMdq4/7TQf5hztsrGYFid78sSb3O9ZO9bgb4
QxqhgA0Z4S2vIqeObJAF9BT5UOT/cXfVKV0iTd52ZQVA+ZhqJ2SDlNFsoxnVOweV
qzKOi0FZCPsjH+Z4a/LLdieHG5AYRPhOScBdG7gTFAdkysI8DDtSNCmJ68dMHYRw
OHtyt/X4k9TImfwauV3Eww1sw3NkDswX+dv3GOSDTlMvVBrm0WXWj2zoHZbOB+0Q
ETI9Zpolvd9pADtyfu9c+kCYIR+NdB4lGKd15iZfdEy/CZ0CtbLAbn5Szo2YcwNR
iVjswR0jsbklD+mZjlMeZoG4JX2d9ZRqLs20POz7QQBmdIQ8jb9/SwVj9zGvX0w0
NyVUHTFlGaNwkpo7oeRoWi1xjZWE6OzfoncV/46DOJWb08OKZ4fR4ugMYJWGi7Xx
I4nQrIiHtInqL+sF5Y3wlZ48dufLuIhAcHh7klxgud4GRj7t8j+a99pTrRmpHvvC
4K2Yu69VYcIA7N2RsSLohIllGPFmMwpdar7yERdD0So8/fz/zf7wn0dFFYY11+bL
YNVVGhvNxccMU5EU9YR4
=Lc59
-----END PGP SIGNATURE-----
Merge tag 'nfs-for-3.6-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates from Trond Myklebust:
"Features include:
- More preparatory patches for modularising NFSv2/v3/v4. Split out
the various NFSv2/v3/v4-specific code into separate files
- More preparation for the NFSv4 migration code
- Ensure that OPEN(O_CREATE) observes the pNFS mds threshold
parameters
- pNFS fast failover when the data servers are down
- Various cleanups and debugging patches"
* tag 'nfs-for-3.6-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (67 commits)
nfs: fix fl_type tests in NFSv4 code
NFS: fix pnfs regression with directio writes
NFS: fix pnfs regression with directio reads
sunrpc: clnt: Add missing braces
nfs: fix stub return type warnings
NFS: exit_nfs_v4() shouldn't be an __exit function
SUNRPC: Add a missing spin_unlock to gss_mech_list_pseudoflavors
NFS: Split out NFS v4 client functions
NFS: Split out the NFS v4 filesystem types
NFS: Create a single nfs_clone_super() function
NFS: Split out NFS v4 server creating code
NFS: Initialize the NFS v4 client from init_nfs_v4()
NFS: Move the v4 getroot code to nfs4getroot.c
NFS: Split out NFS v4 file operations
NFS: Initialize v4 sysctls from nfs_init_v4()
NFS: Create an init_nfs_v4() function
NFS: Split out NFS v4 inode operations
NFS: Split out NFS v3 inode operations
NFS: Split out NFS v2 inode operations
NFS: Clean up nfs4_proc_setclientid() and friends
...
This commit is contained in:
commit
1fad1e9a74
45 changed files with 2220 additions and 1825 deletions
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/errno.h>
|
||||
#include <linux/hash.h>
|
||||
#include <linux/sunrpc/clnt.h>
|
||||
#include <linux/sunrpc/gss_api.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#ifdef RPC_DEBUG
|
||||
|
|
@ -122,6 +123,59 @@ rpcauth_unregister(const struct rpc_authops *ops)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(rpcauth_unregister);
|
||||
|
||||
/**
|
||||
* rpcauth_list_flavors - discover registered flavors and pseudoflavors
|
||||
* @array: array to fill in
|
||||
* @size: size of "array"
|
||||
*
|
||||
* Returns the number of array items filled in, or a negative errno.
|
||||
*
|
||||
* The returned array is not sorted by any policy. Callers should not
|
||||
* rely on the order of the items in the returned array.
|
||||
*/
|
||||
int
|
||||
rpcauth_list_flavors(rpc_authflavor_t *array, int size)
|
||||
{
|
||||
rpc_authflavor_t flavor;
|
||||
int result = 0;
|
||||
|
||||
spin_lock(&rpc_authflavor_lock);
|
||||
for (flavor = 0; flavor < RPC_AUTH_MAXFLAVOR; flavor++) {
|
||||
const struct rpc_authops *ops = auth_flavors[flavor];
|
||||
rpc_authflavor_t pseudos[4];
|
||||
int i, len;
|
||||
|
||||
if (result >= size) {
|
||||
result = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ops == NULL)
|
||||
continue;
|
||||
if (ops->list_pseudoflavors == NULL) {
|
||||
array[result++] = ops->au_flavor;
|
||||
continue;
|
||||
}
|
||||
len = ops->list_pseudoflavors(pseudos, ARRAY_SIZE(pseudos));
|
||||
if (len < 0) {
|
||||
result = len;
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < len; i++) {
|
||||
if (result >= size) {
|
||||
result = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
array[result++] = pseudos[i];
|
||||
}
|
||||
}
|
||||
spin_unlock(&rpc_authflavor_lock);
|
||||
|
||||
dprintk("RPC: %s returns %d\n", __func__, result);
|
||||
return result;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rpcauth_list_flavors);
|
||||
|
||||
struct rpc_auth *
|
||||
rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1619,6 +1619,7 @@ static const struct rpc_authops authgss_ops = {
|
|||
.crcreate = gss_create_cred,
|
||||
.pipes_create = gss_pipes_dentries_create,
|
||||
.pipes_destroy = gss_pipes_dentries_destroy,
|
||||
.list_pseudoflavors = gss_mech_list_pseudoflavors,
|
||||
};
|
||||
|
||||
static const struct rpc_credops gss_credops = {
|
||||
|
|
|
|||
|
|
@ -239,14 +239,28 @@ gss_mech_get_by_pseudoflavor(u32 pseudoflavor)
|
|||
|
||||
EXPORT_SYMBOL_GPL(gss_mech_get_by_pseudoflavor);
|
||||
|
||||
int gss_mech_list_pseudoflavors(rpc_authflavor_t *array_ptr)
|
||||
/**
|
||||
* gss_mech_list_pseudoflavors - Discover registered GSS pseudoflavors
|
||||
* @array: array to fill in
|
||||
* @size: size of "array"
|
||||
*
|
||||
* Returns the number of array items filled in, or a negative errno.
|
||||
*
|
||||
* The returned array is not sorted by any policy. Callers should not
|
||||
* rely on the order of the items in the returned array.
|
||||
*/
|
||||
int gss_mech_list_pseudoflavors(rpc_authflavor_t *array_ptr, int size)
|
||||
{
|
||||
struct gss_api_mech *pos = NULL;
|
||||
int j, i = 0;
|
||||
|
||||
spin_lock(®istered_mechs_lock);
|
||||
list_for_each_entry(pos, ®istered_mechs, gm_list) {
|
||||
for (j=0; j < pos->gm_pf_num; j++) {
|
||||
for (j = 0; j < pos->gm_pf_num; j++) {
|
||||
if (i >= size) {
|
||||
spin_unlock(®istered_mechs_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
array_ptr[i++] = pos->gm_pfs[j].pseudoflavor;
|
||||
}
|
||||
}
|
||||
|
|
@ -254,8 +268,6 @@ int gss_mech_list_pseudoflavors(rpc_authflavor_t *array_ptr)
|
|||
return i;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(gss_mech_list_pseudoflavors);
|
||||
|
||||
u32
|
||||
gss_svc_to_pseudoflavor(struct gss_api_mech *gm, u32 service)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1844,12 +1844,13 @@ call_timeout(struct rpc_task *task)
|
|||
return;
|
||||
}
|
||||
if (RPC_IS_SOFT(task)) {
|
||||
if (clnt->cl_chatty)
|
||||
if (clnt->cl_chatty) {
|
||||
rcu_read_lock();
|
||||
printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
|
||||
clnt->cl_protname,
|
||||
rcu_dereference(clnt->cl_xprt)->servername);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
if (task->tk_flags & RPC_TASK_TIMEOUT)
|
||||
rpc_exit(task, -ETIMEDOUT);
|
||||
else
|
||||
|
|
|
|||
127
net/sunrpc/xdr.c
127
net/sunrpc/xdr.c
|
|
@ -128,34 +128,6 @@ xdr_terminate_string(struct xdr_buf *buf, const u32 len)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(xdr_terminate_string);
|
||||
|
||||
void
|
||||
xdr_encode_pages(struct xdr_buf *xdr, struct page **pages, unsigned int base,
|
||||
unsigned int len)
|
||||
{
|
||||
struct kvec *tail = xdr->tail;
|
||||
u32 *p;
|
||||
|
||||
xdr->pages = pages;
|
||||
xdr->page_base = base;
|
||||
xdr->page_len = len;
|
||||
|
||||
p = (u32 *)xdr->head[0].iov_base + XDR_QUADLEN(xdr->head[0].iov_len);
|
||||
tail->iov_base = p;
|
||||
tail->iov_len = 0;
|
||||
|
||||
if (len & 3) {
|
||||
unsigned int pad = 4 - (len & 3);
|
||||
|
||||
*p = 0;
|
||||
tail->iov_base = (char *)p + (len & 3);
|
||||
tail->iov_len = pad;
|
||||
len += pad;
|
||||
}
|
||||
xdr->buflen += len;
|
||||
xdr->len += len;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xdr_encode_pages);
|
||||
|
||||
void
|
||||
xdr_inline_pages(struct xdr_buf *xdr, unsigned int offset,
|
||||
struct page **pages, unsigned int base, unsigned int len)
|
||||
|
|
@ -456,6 +428,16 @@ xdr_shift_buf(struct xdr_buf *buf, size_t len)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(xdr_shift_buf);
|
||||
|
||||
/**
|
||||
* xdr_stream_pos - Return the current offset from the start of the xdr_stream
|
||||
* @xdr: pointer to struct xdr_stream
|
||||
*/
|
||||
unsigned int xdr_stream_pos(const struct xdr_stream *xdr)
|
||||
{
|
||||
return (unsigned int)(XDR_QUADLEN(xdr->buf->len) - xdr->nwords) << 2;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xdr_stream_pos);
|
||||
|
||||
/**
|
||||
* xdr_init_encode - Initialize a struct xdr_stream for sending data.
|
||||
* @xdr: pointer to xdr_stream struct
|
||||
|
|
@ -556,13 +538,11 @@ void xdr_write_pages(struct xdr_stream *xdr, struct page **pages, unsigned int b
|
|||
EXPORT_SYMBOL_GPL(xdr_write_pages);
|
||||
|
||||
static void xdr_set_iov(struct xdr_stream *xdr, struct kvec *iov,
|
||||
__be32 *p, unsigned int len)
|
||||
unsigned int len)
|
||||
{
|
||||
if (len > iov->iov_len)
|
||||
len = iov->iov_len;
|
||||
if (p == NULL)
|
||||
p = (__be32*)iov->iov_base;
|
||||
xdr->p = p;
|
||||
xdr->p = (__be32*)iov->iov_base;
|
||||
xdr->end = (__be32*)(iov->iov_base + len);
|
||||
xdr->iov = iov;
|
||||
xdr->page_ptr = NULL;
|
||||
|
|
@ -609,7 +589,7 @@ static void xdr_set_next_page(struct xdr_stream *xdr)
|
|||
newbase -= xdr->buf->page_base;
|
||||
|
||||
if (xdr_set_page_base(xdr, newbase, PAGE_SIZE) < 0)
|
||||
xdr_set_iov(xdr, xdr->buf->tail, NULL, xdr->buf->len);
|
||||
xdr_set_iov(xdr, xdr->buf->tail, xdr->buf->len);
|
||||
}
|
||||
|
||||
static bool xdr_set_next_buffer(struct xdr_stream *xdr)
|
||||
|
|
@ -618,7 +598,7 @@ static bool xdr_set_next_buffer(struct xdr_stream *xdr)
|
|||
xdr_set_next_page(xdr);
|
||||
else if (xdr->iov == xdr->buf->head) {
|
||||
if (xdr_set_page_base(xdr, 0, PAGE_SIZE) < 0)
|
||||
xdr_set_iov(xdr, xdr->buf->tail, NULL, xdr->buf->len);
|
||||
xdr_set_iov(xdr, xdr->buf->tail, xdr->buf->len);
|
||||
}
|
||||
return xdr->p != xdr->end;
|
||||
}
|
||||
|
|
@ -634,10 +614,15 @@ void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p)
|
|||
xdr->buf = buf;
|
||||
xdr->scratch.iov_base = NULL;
|
||||
xdr->scratch.iov_len = 0;
|
||||
xdr->nwords = XDR_QUADLEN(buf->len);
|
||||
if (buf->head[0].iov_len != 0)
|
||||
xdr_set_iov(xdr, buf->head, p, buf->len);
|
||||
xdr_set_iov(xdr, buf->head, buf->len);
|
||||
else if (buf->page_len != 0)
|
||||
xdr_set_page_base(xdr, 0, buf->len);
|
||||
if (p != NULL && p > xdr->p && xdr->end >= p) {
|
||||
xdr->nwords -= p - xdr->p;
|
||||
xdr->p = p;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xdr_init_decode);
|
||||
|
||||
|
|
@ -662,12 +647,14 @@ EXPORT_SYMBOL_GPL(xdr_init_decode_pages);
|
|||
|
||||
static __be32 * __xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes)
|
||||
{
|
||||
unsigned int nwords = XDR_QUADLEN(nbytes);
|
||||
__be32 *p = xdr->p;
|
||||
__be32 *q = p + XDR_QUADLEN(nbytes);
|
||||
__be32 *q = p + nwords;
|
||||
|
||||
if (unlikely(q > xdr->end || q < p))
|
||||
if (unlikely(nwords > xdr->nwords || q > xdr->end || q < p))
|
||||
return NULL;
|
||||
xdr->p = q;
|
||||
xdr->nwords -= nwords;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
|
@ -734,6 +721,31 @@ __be32 * xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(xdr_inline_decode);
|
||||
|
||||
static unsigned int xdr_align_pages(struct xdr_stream *xdr, unsigned int len)
|
||||
{
|
||||
struct xdr_buf *buf = xdr->buf;
|
||||
struct kvec *iov;
|
||||
unsigned int nwords = XDR_QUADLEN(len);
|
||||
unsigned int cur = xdr_stream_pos(xdr);
|
||||
|
||||
if (xdr->nwords == 0)
|
||||
return 0;
|
||||
if (nwords > xdr->nwords) {
|
||||
nwords = xdr->nwords;
|
||||
len = nwords << 2;
|
||||
}
|
||||
/* Realign pages to current pointer position */
|
||||
iov = buf->head;
|
||||
if (iov->iov_len > cur)
|
||||
xdr_shrink_bufhead(buf, iov->iov_len - cur);
|
||||
|
||||
/* Truncate page data and move it into the tail */
|
||||
if (buf->page_len > len)
|
||||
xdr_shrink_pagelen(buf, buf->page_len - len);
|
||||
xdr->nwords = XDR_QUADLEN(buf->len - cur);
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* xdr_read_pages - Ensure page-based XDR data to decode is aligned at current pointer position
|
||||
* @xdr: pointer to xdr_stream struct
|
||||
|
|
@ -742,39 +754,37 @@ EXPORT_SYMBOL_GPL(xdr_inline_decode);
|
|||
* Moves data beyond the current pointer position from the XDR head[] buffer
|
||||
* into the page list. Any data that lies beyond current position + "len"
|
||||
* bytes is moved into the XDR tail[].
|
||||
*
|
||||
* Returns the number of XDR encoded bytes now contained in the pages
|
||||
*/
|
||||
void xdr_read_pages(struct xdr_stream *xdr, unsigned int len)
|
||||
unsigned int xdr_read_pages(struct xdr_stream *xdr, unsigned int len)
|
||||
{
|
||||
struct xdr_buf *buf = xdr->buf;
|
||||
struct kvec *iov;
|
||||
ssize_t shift;
|
||||
unsigned int nwords;
|
||||
unsigned int end;
|
||||
int padding;
|
||||
unsigned int padding;
|
||||
|
||||
/* Realign pages to current pointer position */
|
||||
iov = buf->head;
|
||||
shift = iov->iov_len + (char *)iov->iov_base - (char *)xdr->p;
|
||||
if (shift > 0)
|
||||
xdr_shrink_bufhead(buf, shift);
|
||||
|
||||
/* Truncate page data and move it into the tail */
|
||||
if (buf->page_len > len)
|
||||
xdr_shrink_pagelen(buf, buf->page_len - len);
|
||||
padding = (XDR_QUADLEN(len) << 2) - len;
|
||||
len = xdr_align_pages(xdr, len);
|
||||
if (len == 0)
|
||||
return 0;
|
||||
nwords = XDR_QUADLEN(len);
|
||||
padding = (nwords << 2) - len;
|
||||
xdr->iov = iov = buf->tail;
|
||||
/* Compute remaining message length. */
|
||||
end = iov->iov_len;
|
||||
shift = buf->buflen - buf->len;
|
||||
if (shift < end)
|
||||
end -= shift;
|
||||
else if (shift > 0)
|
||||
end = 0;
|
||||
end = ((xdr->nwords - nwords) << 2) + padding;
|
||||
if (end > iov->iov_len)
|
||||
end = iov->iov_len;
|
||||
|
||||
/*
|
||||
* Position current pointer at beginning of tail, and
|
||||
* set remaining message length.
|
||||
*/
|
||||
xdr->p = (__be32 *)((char *)iov->iov_base + padding);
|
||||
xdr->end = (__be32 *)((char *)iov->iov_base + end);
|
||||
xdr->page_ptr = NULL;
|
||||
xdr->nwords = XDR_QUADLEN(end - padding);
|
||||
return len;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xdr_read_pages);
|
||||
|
||||
|
|
@ -790,12 +800,13 @@ EXPORT_SYMBOL_GPL(xdr_read_pages);
|
|||
*/
|
||||
void xdr_enter_page(struct xdr_stream *xdr, unsigned int len)
|
||||
{
|
||||
xdr_read_pages(xdr, len);
|
||||
len = xdr_align_pages(xdr, len);
|
||||
/*
|
||||
* Position current pointer at beginning of tail, and
|
||||
* set remaining message length.
|
||||
*/
|
||||
xdr_set_page_base(xdr, 0, len);
|
||||
if (len != 0)
|
||||
xdr_set_page_base(xdr, 0, len);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xdr_enter_page);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue