[pnfs] [PATCH 1/2] Slot Table Implementation
Iyer, Rahul
Rahul.Iyer at netapp.com
Fri Mar 16 17:28:24 EDT 2007
Hi Andy,
I've split up the patch for the 4.1-sessions branch. I split it up by
file. So, I think the largest patch is 400 odd lines.
I'll send the pNFS patches next. These patches should be applied before
you apply the other patches.
So, the order is:
[PATCH 1/8] Slot Table Implementation
through
[PATCH 8/8] Slot Table Implementation
[PATCH 2/2] Slot Table Implementation
I think I understand what you mean about patches being small and atomic
now. I'll make my next patches small.
Regards
Rahul
> -----Original Message-----
> From: William A. (Andy) Adamson [mailto:andros at citi.umich.edu]
> Sent: Friday, March 16, 2007 10:00 AM
> To: Iyer, Rahul
> Cc: pnfs at linux-nfs.org
> Subject: Re: [pnfs] [PATCH 1/2] Slot Table Implementation
>
> hi rahul
>
> this patch is too big! please break it up..
>
> -->Andy
>
>
> On 3/15/07, iyer at netapp.com < iyer at netapp.com
> <mailto:iyer at netapp.com> > wrote:
>
> From: iyer <iyer at netapp.com >
>
> Added code to implement a slot table.
>
> Signed-off-by: iyer <iyer at netapp.com>
> ---
> fs/nfs/nfs41_sessions.h | 62 --------
> fs/nfs/nfs4_fs.h | 2 +-
> fs/nfs/nfs4proc.c | 326
> +++++++++++++++++++++++++++++++++++-----
> fs/nfs/nfs4xdr.c | 24 ++--
> fs/nfs/super.c | 6 +-
> include/linux/nfs41_sessions.h | 72 +++++++++
> include/linux/nfs_xdr.h | 4 +
> include/linux/nfsd/state.h | 2 -
> 8 files changed, 378 insertions(+), 120 deletions(-)
> delete mode 100644 fs/nfs/nfs41_sessions.h
> create mode 100644 include/linux/nfs41_sessions.h
>
> diff --git a/fs/nfs/nfs41_sessions.h b/fs/nfs/nfs41_sessions.h
> deleted file mode 100644
> index fc658c5..0000000
> --- a/fs/nfs/nfs41_sessions.h
> +++ /dev/null
> @@ -1,62 +0,0 @@
> -#ifndef __NFS4_1_SESSIONS_H__
> -#define __NFS4_1_SESSIONS_H__
> -
> -typedef unsigned char sessionid_t[16];
> -typedef u32 streamchannel_attrs;
> -typedef u32 rdmachannel_attrs;
> -
> -struct nfs4_channel_attrs {
> - unsigned long max_rqst_sz;
> - unsigned long max_resp_sz;
> - unsigned long max_resp_sz_cached;
> - unsigned long max_ops;
> - unsigned long max_reqs;
> - streamchannel_attrs stream_attrs;
> - rdmachannel_attrs rdma_attrs;
> -};
> -
> -struct nfs4_channel {
> - struct nfs4_channel_attrs chan_attrs;
> - unsigned long nr_conns;
> - struct list_head rpc_clients;
> -};
> -
> -struct nfs4_session {
> - /* Session related params */
> - sessionid_t sess_id;
> - u32 seqid; /* The seqid
> returned by exchange_id */
> - u32 persist;
> - u32 header_padding;
> - u32 hash_alg;
> - u32 ssv_len;
> - u32 use_for_back_chan;
> - u32 rdma_mode;
> -
> - /* Slotid management */
> - unsigned long nr_slots_in_use;
> - struct list_head slots_in_use;
> - struct list_head unused_slots;
> - struct rpc_wait_queue slot_waitq;
> -
> - /* The fore and back channel */
> - struct nfs4_channel fore_channel;
> - struct nfs4_channel back_channel;
> -
> - unsigned int expired;
> - struct nfs4_client * client;
> - struct list_head session_hashtbl;
> - spinlock_t session_lock;
> - /* To prevent races between create_session and
> sequence */
> - int mutating;
> - struct semaphore session_sem;
> - atomic_t ref_count;
> -};
> -
> -struct nfs4_slot {
> - u32 slot_nr;
> - u32 seq_nr;
> - struct nfs4_session * session;
> - struct list_head slot_list;
> -};
> -
> -#endif
> diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
> index 195d757..e50657e 100644
> --- a/fs/nfs/nfs4_fs.h
> +++ b/fs/nfs/nfs4_fs.h
> @@ -9,7 +9,7 @@
> #ifndef __LINUX_FS_NFS_NFS4_FS_H
> #define __LINUX_FS_NFS_NFS4_FS_H
>
> -#include "nfs41_sessions.h"
> +#include <linux/nfs41_sessions.h>
>
> #ifdef CONFIG_NFS_V4
> #define NFSV4_MAX_MINORVERSION 1
> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
> index 167ff4a..28513a1 100644
> --- a/fs/nfs/nfs4proc.c
> +++ b/fs/nfs/nfs4proc.c
> @@ -49,6 +49,7 @@
> #include <linux/namei.h>
> #include <linux/mount.h>
> #include <linux/module.h>
> +#include <linux/bitops.h>
>
> #include "nfs4_fs.h"
> #include "delegation.h"
> @@ -221,8 +222,10 @@ static int
> nfs41_proc_sequence_done(struct nfs4_session *session, struct nfs41_s
> unsigned long timestamp;
> struct nfs4_client *clp;
>
> - if (!session || !(clp = session->client))
> - return 0;
> + if (!session || !(clp = session->client)) {
> + printk(KERN_EMERG "%s is NULL!!!\n",
> (!session)?"session":"clp");
> + BUG();
> + }
>
> if (!status) {
> timestamp = jiffies;
> @@ -233,17 +236,131 @@ static int
> nfs41_proc_sequence_done(struct nfs4_session *session, struct nfs41_s
> spin_unlock(&clp->cl_lock);
> }
>
> + /* Clear the 'busy' bit on the slot that was used */
> + smp_mb__before_clear_bit();
> + clear_bit(NFS4_SLOT_BUSY, &res->slot->flags);
> + smp_mb__after_clear_bit();
> +
> + printk(KERN_EMERG "waking up waiters on slot
> %d\n", res->slot->slot_nr);
> +
> + /* Wake up the threads waiting on this slot */
> + wake_up_bit(&res->slot->flags, NFS4_SLOT_BUSY);
> +
> return status;
> }
>
> +static int nfs4_wait_bit_interruptible(void *word)
> +{
> + if (signal_pending(current))
> + return -ERESTARTSYS;
> + schedule();
> + return 0;
> +}
> +
> +/* Find the lowest numbered slot or sleep on the least
> loaded slot */
> +struct nfs4_slot *nfs4_find_slot(struct nfs4_channel *channel)
> +{
> + struct nfs4_slot_table *tbl;
> + struct nfs4_slot *slot;
> + struct nfs4_slot *target_slot;
> + u32 max_slots;
> + u32 min_waiters;
> + int i;
> + int need_to_sleep;
> +
> + might_sleep();
> +
> + tbl = &channel->slot_table;
> + min_waiters = tbl->slots[0].nr_waiters;
> + target_slot = &tbl->slots[0];
> +
> + spin_lock(&tbl->slot_tbl_lock);
> + /* Make a local copy of max slots so we don't
> need to hold it through
> + * out.
> + * XXX Will need to revalidate this if slots
> are reclaimed
> + */
> + max_slots = tbl->max_slots;
> + spin_unlock(&tbl->slot_tbl_lock);
> +
> + do {
> + need_to_sleep = 1;
> + for (i = 0; i < max_slots; ++i) {
> + slot = &tbl->slots[i];
> + if
> (!test_and_set_bit(NFS4_SLOT_BUSY, &slot->flags)){
> + /* We found an empty slot */
> + target_slot = slot;
> + need_to_sleep = 0;
> + break;
> + }
> +
> + spin_lock(&slot->slot_lock);
> + if (min_waiters > slot->nr_waiters) {
> + min_waiters = slot->nr_waiters;
> + target_slot = slot;
> + }
> + spin_unlock(&slot->slot_lock);
> + printk(KERN_EMERG "slot %d has
> busy bit %s and nr_waiters is %u\n"
> + , slot->slot_nr,
> +
> (need_to_sleep)?"set":"unset",
> + slot->nr_waiters);
> + }
> +
> + /* Check whether we need to sleep. If
> so, sleep on the BUSY bit
> + * Increment the nr_waiters before
> sleeping and decrement it
> + * when woken up
> + */
> + if (need_to_sleep) {
> + printk(KERN_EMERG "sleeping on
> slot %d; seq_nr: %d\n",
> + target_slot->slot_nr,
> + target_slot->seq_nr);
> + spin_lock(&target_slot->slot_lock);
> + ++target_slot->nr_waiters;
> + spin_unlock(&target_slot->slot_lock);
> +
> + /* XXX: We need to check the
> return value of
> + * eait_on_bit so that we can
> check if it's
> + * interrupted.
> + */
> +
> wait_on_bit(&target_slot->flags, NFS4_SLOT_BUSY,
> +
> nfs4_wait_bit_interruptible,
> + TASK_INTERRUPTIBLE);
> +
> + spin_lock(&target_slot->slot_lock);
> + --target_slot->nr_waiters;
> + spin_unlock(&target_slot->slot_lock);
> + }
> + else
> + break;
> + }while (test_and_set_bit(NFS4_SLOT_BUSY,
> &target_slot->flags));
> +
> + printk(KERN_EMERG "slot id: %u\nseqid: %u\n
> max_slots: %u\n",
> + target_slot->slot_nr,
> target_slot->seq_nr,
> + max_slots);
> +
> + return target_slot;
> +}
> +
> static int _nfs41_proc_setup_sequence(struct
> nfs4_session *session, struct nfs41_sequence_args *args,
> struct nfs41_sequence_res *res)
> {
> u32 *ptr;
> -
> + struct nfs4_slot *slot;
> +
> ptr = (u32 *)session->sess_id;
> dprintk("%s: %u:%u:%u:%u\n", __FUNCTION__,
> ptr[0], ptr[1], ptr[2], ptr[3]);
>
> - memcpy(args->sessionid, (unsigned char
> *)session->sess_id, NFS4_MAX_SESSIONID_LEN);
> + memcpy(args->sessionid, (unsigned char
> *)session->sess_id,
> +
> NFS4_MAX_SESSIONID_LEN);
> +
> + slot = nfs4_find_slot(&session->fore_channel);
> +
> + /* XXX: Do we always increment this? Are there
> any errors for which we
> + * don't increment the sequence number?
> + */
> + args->seqid = slot->seq_nr++;
> + args->slotid = slot->slot_nr;
> + args->maxslots =
> session->fore_channel.slot_table.max_slots;
> +
> + res->slot = slot;
>
> return 0;
> }
> @@ -1685,11 +1802,6 @@ static int
> nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
> };
> int status;
>
> - if (server->rpc_ops->setup_sequence && (status =
> -
> server->rpc_ops->setup_sequence(server->nfs4_state->cl_session,
> - &seqargs, &seqres)))
> - return status;
> -
> /*
> * Now we do a separate LOOKUP for each
> component of the mount path.
> * The LOOKUPs are done separately so that we
> can conveniently
> @@ -1714,9 +1826,21 @@ static int
> nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
>
> do {
> nfs_fattr_init(fattr);
> + if
> (server->rpc_ops->setup_sequence && (status =
> + server->rpc_ops->setup_sequence(
> + server->nfs4_state->cl_session,
> + &seqargs, &seqres)))
> + return status;
> +
> status = nfs4_handle_exception(server,
>
> rpc_call_sync(server->client, &msg, 0),
> &exception);
> +
> + if (server->rpc_ops->sequence_done)
> + server->rpc_ops->sequence_done(
> +
> server->nfs4_state->cl_session,
> +
> &seqres, status);
> +
> } while (exception.retry);
> if (status == 0)
> continue;
> @@ -1731,10 +1855,6 @@ static int
> nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
> if (status == 0)
> status = nfs4_do_fsinfo(server, fhandle, info);
> out:
> - if (server->rpc_ops->sequence_done)
> -
> server->rpc_ops->sequence_done(server->nfs4_state->cl_session,
> -
> &seqres, status);
> -
> return nfs4_map_errors(status);
> }
>
> @@ -3268,6 +3388,7 @@ int
> nfs4_proc_async_sequence(struct nfs4_client *clp, struct
> rpc_cred *cred)
> ret = rpc_call_async(clp->cl_rpcclient, &msg,
> RPC_TASK_SOFT,
> &nfs4_sequence_ops, (void *)jiffies);
>
> + nfs41_proc_sequence_done(clp->cl_session, res, ret);
> out:
> return ret;
> out_free:
> @@ -3581,14 +3702,6 @@ nfs4_async_handle_error(struct
> rpc_task *task, const struct nfs_server *server)
> return 0;
> }
>
> -static int nfs4_wait_bit_interruptible(void *word)
> -{
> - if (signal_pending(current))
> - return -ERESTARTSYS;
> - schedule();
> - return 0;
> -}
> -
> static int nfs4_wait_clnt_recover(struct rpc_clnt
> *clnt, struct nfs4_client *clp)
> {
> sigset_t oldset;
> @@ -3823,6 +3936,111 @@ int
> nfs4_proc_get_lease_time(struct nfs4_client *clp, struct
> nfs_fsinfo *fsinfo)
> return status;
> }
>
> +/* Initialize a slot table */
> +int nfs4_init_slot_table(struct nfs4_channel *channel)
> +{
> + int i;
> + struct nfs4_slot_table *tbl;
> + struct nfs4_slot *slot;
> +
> + tbl = &channel->slot_table;
> + tbl->max_slots = channel->chan_attrs.max_reqs;
> +
> + tbl->slots = kzalloc(tbl->max_slots *
> sizeof(struct nfs4_slot), GFP_ATOMIC);
> + if (!tbl->slots)
> + return -ENOMEM;
> +
> + spin_lock_init(&tbl->slot_tbl_lock);
> +
> + for (i = 0; i < tbl->max_slots; ++i) {
> + slot = &tbl->slots[i];
> +
> + slot->slot_nr = i;
> + slot->seq_nr = 1;
> + slot->flags = 0;
> + slot->nr_waiters = 0;
> + spin_lock_init(&slot->slot_lock);
> + }
> +
> + return 0;
> +}
> +
> +/* Destroy the slot table */
> +void nfs4_destroy_slot_table(struct nfs4_channel *channel)
> +{
> + int i;
> + struct nfs4_slot *slot;
> + struct nfs4_slot_table *tbl;
> +
> + tbl = &channel->slot_table;
> +
> + for (i = 0; i < tbl->max_slots;++i) {
> + slot = &tbl->slots[i];
> +
> + if (slot->nr_waiters)
> + BUG();
> + }
> +
> + kfree(channel->slot_table.slots);
> + channel->slot_table.slots = NULL;
> +
> + return;
> +}
> +
> +/* dump the channel attributes */
> +void nfs4_dump_channel_attrs(struct nfs4_channel_attrs *attrs)
> +{
> + printk(KERN_INFO "max_rqst_sz: %u\n",
> attrs->max_rqst_sz);
> + printk(KERN_INFO "max_resp_sz: %u\n",
> attrs->max_resp_sz);
> + printk(KERN_INFO "max_resp_sz_cached: %u\n",
> attrs->max_resp_sz_cached);
> + printk(KERN_INFO "max_ops: %u\n", attrs->max_ops);
> + printk(KERN_INFO "max_reqs: %u\n", attrs->max_reqs);
> +}
> +
> +/* Initialize the values to be used by the client in
> CREATE_SESSION */
> +void nfs4_init_channel_attrs(struct nfs4_client *clp,
> + struct
> nfs4_channel_attrs *fc_attrs,
> + struct
> nfs4_channel_attrs *bc_attrs)
> +{
> + /* XXX: We need to have good values here... 32K
> is a wild guess */
> + fc_attrs->max_rqst_sz = bc_attrs->max_rqst_sz = 32768;
> + fc_attrs->max_resp_sz = bc_attrs->max_resp_sz = 32768;
> + fc_attrs->max_resp_sz_cached =
> bc_attrs->max_resp_sz_cached = 32768;
> + fc_attrs->max_ops = bc_attrs->max_ops = 0xFFFFFFFF;
> + fc_attrs->max_reqs = bc_attrs->max_reqs =
> +
> clp->cl_rpcclient->cl_xprt->max_reqs;
> + fc_attrs->stream_attrs = bc_attrs->stream_attrs = 0;
> + fc_attrs->rdma_attrs = bc_attrs->rdma_attrs = 0;
> +
> +}
> +
> +/* Check the values returned by the server for
> CREATE_SESSION. Since we made
> + * our needs known, if the server gives us more than
> we need, we don't bother
> + * with it.
> + */
> +void nfs4_adjust_channel_attrs(struct
> nfs4_channel_attrs *req_attrs,
> + struct
> nfs4_channel_attrs *resp_attrs)
> +{
> + if (req_attrs->max_rqst_sz < resp_attrs->max_rqst_sz)
> + resp_attrs->max_rqst_sz =
> req_attrs->max_rqst_sz;
> +
> + if (req_attrs->max_resp_sz < resp_attrs->max_resp_sz)
> + resp_attrs->max_resp_sz =
> req_attrs->max_resp_sz;
> +
> + if (req_attrs->max_resp_sz_cached <
> resp_attrs->max_resp_sz)
> + resp_attrs->max_resp_sz =
> req_attrs->max_resp_sz_cached;
> +
> + if (req_attrs->max_ops < resp_attrs->max_ops)
> + resp_attrs->max_ops = req_attrs->max_ops;
> +
> + if (req_attrs->max_reqs < resp_attrs->max_reqs)
> + resp_attrs->max_reqs = req_attrs->max_reqs;
> +
> + /* XXX: We ignore the stream channel
> attributes... we have no idea what
> + * to do with them anyways!
> + */
> +}
> +
> int _nfs4_proc_create_session(struct nfs4_client *clp,
> struct nfs4_session *session, struct rpc_clnt *clnt)
> {
> struct nfs41_create_session_args args = {
> @@ -3845,7 +4063,19 @@ int
> _nfs4_proc_create_session(struct nfs4_client *clp, struct
> nfs4_session *sess
> };
> int status;
>
> - status = rpc_call_sync(clnt, &msg, 0);
> + nfs4_init_channel_attrs(clp, &args.fc_attrs,
> &args.bc_attrs);
> +
> + status = rpc_call_sync(clnt, &msg, 0);
> +
> + /* Set the negotiated values in the session's
> channel_attrs struct */
> +
> + if (!status) {
> + nfs4_adjust_channel_attrs(&args.fc_attrs,
> +
> &session->fore_channel.chan_attrs);
> + nfs4_adjust_channel_attrs(&args.bc_attrs,
> +
> &session->back_channel.chan_attrs);
> + }
> +
> return status;
> }
> EXPORT_SYMBOL(_nfs4_proc_create_session);
> @@ -3853,29 +4083,28 @@
> EXPORT_SYMBOL(_nfs4_proc_create_session);
> int nfs4_proc_create_session(struct nfs4_client *clp)
> {
> int status;
> - unsigned long now;
> struct nfs4_session *session;
> - struct nfs_fsinfo fsinfo;
> u32 *ptr;
>
> - now = jiffies;
> -
> status = _nfs4_proc_create_session(clp,
> clp->cl_session, clp->cl_rpcclient);
> if (status)
> return status;
>
> - status = nfs4_proc_get_lease_time(clp, &fsinfo);
> - if (status == 0) {
> - /* Update lease time and schedule renewal */
> - spin_lock(&clp->cl_lock);
> - clp->cl_lease_time = fsinfo.lease_time * HZ;
> - clp->cl_last_renewal = now;
> - clear_bit(NFS4CLNT_LEASE_EXPIRED,
> &clp->cl_state);
> - spin_unlock(&clp->cl_lock);
> + session = clp->cl_session;
>
> - nfs4_schedule_state_renewal(clp);
> + /* Init the fore channel */
> + status = nfs4_init_slot_table(&session->fore_channel);
> + dprintk("fc init returned %d\n", status);
> + if (status)
> + return status;
> +
> + /* Init the back channel */
> + status = nfs4_init_slot_table(&session->back_channel);
> + dprintk("bc init returned %d\n", status);
> + if (status) {
> + nfs4_destroy_slot_table(&session->fore_channel);
> + return status;
> }
> - session = clp->cl_session;
>
> ptr = (int *)session->sess_id;
> dprintk("sessionid is: %d:%d:%d:%d\n", ptr[0],
> ptr[1], ptr[2], ptr[3]);
> @@ -4769,11 +4998,8 @@ struct nfs4_session
> *nfs41_alloc_session(void)
>
> session->expired = 1;
>
> - INIT_LIST_HEAD(&session->slots_in_use);
> - INIT_LIST_HEAD(&session->unused_slots);
> INIT_LIST_HEAD(&session->session_hashtbl);
>
> - //rpc_init_wait_queue(&session->slot_waitq,
> "Slot waitqueue");
> spin_lock_init(&session->session_lock);
>
> sema_init(&session->session_sem, 1);
> @@ -4797,6 +5023,8 @@ void nfs4_get_session(struct
> nfs4_session *session)
> void nfs4_put_session(struct nfs4_session **session)
> {
> if (atomic_dec_and_test(&((*session)->ref_count))) {
> +
> nfs4_destroy_slot_table(&((*session)->fore_channel));
> +
> nfs4_destroy_slot_table(&((*session)->back_channel));
> nfs41_free_session(*session);
> *session = NULL;
> }
> @@ -4806,7 +5034,11 @@ int
> nfs41_proc_setup_session(struct nfs4_client *clp)
> {
> int status;
>
> - dprintk("in %s!\n", __FUNCTION__);
> + struct nfs_fsinfo fsinfo;
> + unsigned long now;
> +
> + now = jiffies;
> +
> if (!clp->cl_session) {
> /* create the session struct to hold
> the session parameters */
> clp->cl_session = nfs41_alloc_session();
> @@ -4844,6 +5076,20 @@ int
> nfs41_proc_setup_session(struct nfs4_client *clp)
> clp->cl_session->expired = 0;
> clp->cl_session->client = clp;
>
> + status = nfs4_proc_get_lease_time(clp, &fsinfo);
> +
> + if (status)
> + goto out_free;
> +
> + /* Update lease time and schedule renewal */
> + spin_lock(&clp->cl_lock);
> + clp->cl_lease_time = fsinfo.lease_time * HZ;
> + clp->cl_last_renewal = now;
> + clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
> + spin_unlock(&clp->cl_lock);
> +
> + nfs4_schedule_state_renewal(clp);
> +
> clp->cl_session->mutating = 0;
> out:
> up(&clp->cl_session->session_sem);
> diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
> index 5ef6d70..7da9a6a 100644
> --- a/fs/nfs/nfs4xdr.c
> +++ b/fs/nfs/nfs4xdr.c
> @@ -1429,20 +1429,22 @@ static int
> encode_create_session(struct xdr_stream *xdr, struct nfs41_create_ses
> RESERVE_SPACE(2*28); /* 2
> channel_attrs */
>
> /* Fore Channel */
> - WRITE32(32768); /* max
> req size */
> - WRITE32(32768); /* max
> resp size */
> - WRITE32(32768); /* Max
> resp size cached */
> - WRITE32(RPC_DEF_SLOT_TABLE); /* max
> operations */
> - WRITE32(RPC_DEF_SLOT_TABLE); /* max
> requests */
> + WRITE32(args->fc_attrs.max_rqst_sz); /* max
> req size */
> + WRITE32(args->fc_attrs.max_resp_sz); /* max
> resp size */
> + WRITE32(args->fc_attrs.max_resp_sz_cached);
> /* Max resp sz cached */
> + WRITE32(args->fc_attrs.max_ops); /* max
> operations */
> + WRITE32(args->fc_attrs.max_reqs); /* max
> requests */
> +
> WRITE32(0); /*
> Streamchannel attrs */
> WRITE32(0);
> /*rdmachannel_attrs */
>
> /* Back Channel */
> - WRITE32(32768); /* max
> req size */
> - WRITE32(32768); /* max
> resp size */
> - WRITE32(32768); /* Max
> resp size cached */
> - WRITE32(RPC_DEF_SLOT_TABLE); /* max
> operations */
> - WRITE32(RPC_DEF_SLOT_TABLE); /* max
> requests */
> + WRITE32(args->bc_attrs.max_rqst_sz); /* max
> req size */
> + WRITE32(args->bc_attrs.max_resp_sz); /* max
> resp size */
> + WRITE32(args->bc_attrs.max_resp_sz_cached);
> /* Max resp sz cached */
> + WRITE32(args->bc_attrs.max_ops); /* max
> operations */
> + WRITE32(args->bc_attrs.max_reqs); /* max
> requests */
> +
> WRITE32(0); /*
> Streamchannel attrs */
> WRITE32(0);
> /*rdmachannel_attrs */
>
> @@ -6404,7 +6406,7 @@ static int
> nfs41_xdr_dec_get_lease_time(struct rpc_rqst *rqstp, uint32_t *p, str
> status = decode_putrootfh(&xdr);
> if (!status)
> status = decode_fsinfo(&xdr, res->fsinfo);
> - if (!status)
> + if (status)
> status = -nfs_stat_to_errno( hdr.status);
> return status;
> }
> diff --git a/fs/nfs/super.c b/fs/nfs/super.c
> index a3bc630..89eb564 100644
> --- a/fs/nfs/super.c
> +++ b/fs/nfs/super.c
> @@ -1260,15 +1260,13 @@ static int
> nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
> server->nfs4_state->cl_minorversion = i;
>
> if (server->rpc_ops->setup_session) {
> - int status;
> -
> lock_kernel();
>
> down_write(&server->nfs4_state->cl_sem);
> - status =
> server->rpc_ops->setup_session(server->nfs4_state);
> + err =
> server->rpc_ops->setup_session(server->nfs4_state);
> up_write(&server->nfs4_state->cl_sem);
> unlock_kernel();
>
> - if (status) {
> + if (err) {
> printk(KERN_EMERG
> "Couldn't mount using minorversion %d\n", i);
>
> rpc_shutdown_client(server->client);
> }
> diff --git a/include/linux/nfs41_sessions.h
> b/include/linux/nfs41_sessions.h
> new file mode 100644
> index 0000000..02f45db
> --- /dev/null
> +++ b/include/linux/nfs41_sessions.h
> @@ -0,0 +1,72 @@
> +#ifndef __NFS4_1_SESSIONS_H__
> +#define __NFS4_1_SESSIONS_H__
> +
> +/* The flags for the nfs4_slot struct */
> +#define NFS4_SLOT_BUSY 0X0 /* Slot in use */
> +#define NFS4_SLOT_RECLAIMED 0x1 /* Slot has
> been reclaimed by
> + the server */
> +
> +typedef unsigned char sessionid_t[16];
> +typedef u32 streamchannel_attrs;
> +typedef u32 rdmachannel_attrs;
> +
> +struct nfs4_channel_attrs {
> + u32 max_rqst_sz;
> + u32 max_resp_sz;
> + u32 max_resp_sz_cached;
> + u32 max_ops;
> + u32 max_reqs;
> + streamchannel_attrs stream_attrs;
> + rdmachannel_attrs rdma_attrs;
> +};
> +
> +struct nfs4_slot {
> + u32 slot_nr;
> + u32 seq_nr;
> + unsigned long flags;
> + u32 nr_waiters;
> + spinlock_t slot_lock;
> +};
> +
> +struct nfs4_slot_table {
> + struct nfs4_slot *slots;
> + u32 max_slots;
> + spinlock_t slot_tbl_lock;
> +};
> +
> +struct nfs4_channel {
> + struct nfs4_channel_attrs chan_attrs;
> + struct rpc_clnt *rpc_client;
> + struct nfs4_slot_table slot_table;
> +};
> +
> +struct nfs4_session {
> + /* Session related params */
> + sessionid_t sess_id;
> + u32 seqid; /* The
> seqid returned by
> +
> exchange_id */
> + u32 persist;
> + u32 header_padding;
> + u32 hash_alg;
> + u32 ssv_len;
> + u32 use_for_back_chan;
> + u32 rdma_mode;
> +
> + /* The fore and back channel */
> + struct nfs4_channel fore_channel;
> + struct nfs4_channel back_channel;
> +
> + unsigned int expired;
> + struct nfs4_client * client;
> + struct list_head session_hashtbl;
> + spinlock_t session_lock;
> + /* To prevent races between create_session and
> sequence */
> + int mutating;
> + struct semaphore session_sem;
> + atomic_t ref_count;
> +};
> +
> +
> +#endif
> +
> +
> diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
> index 4648707..52b9e38 100644
> --- a/include/linux/nfs_xdr.h
> +++ b/include/linux/nfs_xdr.h
> @@ -3,6 +3,7 @@
>
> #include <linux/sunrpc/xprt.h>
> #include <linux/nfsacl.h>
> +#include <linux/nfs41_sessions.h>
>
> /*
> * To change the maximum rsize and wsize supported by
> the NFS client, adjust
> @@ -778,6 +779,8 @@ struct nfs41_create_session_args {
> uint32_t use_for_backchannel;
> uint32_t use_for_rdma;
> uint32_t cb_program;
> + struct nfs4_channel_attrs fc_attrs;
> /* Fore Channel */
> + struct nfs4_channel_attrs bc_attrs;
> /* Back Channel */
> };
>
> struct nfs41_create_session_res {
> @@ -805,6 +808,7 @@ struct nfs41_sequence_res {
> u32 target_maxslots;
> u32 status_flags;
> struct nfs4_state_owner *sp;
> + struct nfs4_slot *slot;
> };
>
> struct nfs4_get_lease_time_args {
> diff --git a/include/linux/nfsd/state.h
> b/include/linux/nfsd/state.h
> index 8f699b4..fde667e 100644
> --- a/include/linux/nfsd/state.h
> +++ b/include/linux/nfsd/state.h
> @@ -47,8 +47,6 @@ typedef struct {
> u32 cl_id;
> } clientid_t;
>
> -typedef unsigned char sessionid_t[16];
> -
> typedef struct {
> u32 so_boot;
> u32 so_stateownerid;
> --
> 1.5.0.2
> _______________________________________________
> pNFS mailing list
> pNFS at linux-nfs.org
> http://linux-nfs.org/cgi-bin/mailman/listinfo/pnfs
>
>
>
>
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: slot_table1.patch
Type: application/octet-stream
Size: 1842 bytes
Desc: slot_table1.patch
Url : http://linux-nfs.org/pipermail/pnfs/attachments/20070316/7d540b01/attachment-0008.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: slot_table2.patch
Type: application/octet-stream
Size: 528 bytes
Desc: slot_table2.patch
Url : http://linux-nfs.org/pipermail/pnfs/attachments/20070316/7d540b01/attachment-0009.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: slot_table3.patch
Type: application/octet-stream
Size: 4684 bytes
Desc: slot_table3.patch
Url : http://linux-nfs.org/pipermail/pnfs/attachments/20070316/7d540b01/attachment-0010.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: slot_table5.patch
Type: application/octet-stream
Size: 2373 bytes
Desc: slot_table5.patch
Url : http://linux-nfs.org/pipermail/pnfs/attachments/20070316/7d540b01/attachment-0011.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: slot_table6.patch
Type: application/octet-stream
Size: 1223 bytes
Desc: slot_table6.patch
Url : http://linux-nfs.org/pipermail/pnfs/attachments/20070316/7d540b01/attachment-0012.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: slot_table7.patch
Type: application/octet-stream
Size: 2008 bytes
Desc: slot_table7.patch
Url : http://linux-nfs.org/pipermail/pnfs/attachments/20070316/7d540b01/attachment-0013.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: slot_table8.patch
Type: application/octet-stream
Size: 1066 bytes
Desc: slot_table8.patch
Url : http://linux-nfs.org/pipermail/pnfs/attachments/20070316/7d540b01/attachment-0014.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: slot_table9.patch
Type: application/octet-stream
Size: 573 bytes
Desc: slot_table9.patch
Url : http://linux-nfs.org/pipermail/pnfs/attachments/20070316/7d540b01/attachment-0015.obj
More information about the pNFS
mailing list