On Apr 23, 2012, at 4:48 PM, Myklebust, Trond wrote:
> On Mon, 2012-04-23 at 16:44 -0400, Chuck Lever wrote:
>> Hi-
>>
>> I wish you had told me you were going to fix this too. I've been testing a fix for this for a couple weeks. Was going to post this afternoon. Shall I toss mine?
>
> I was hitting that BAD_SEQID storm during testing of the other open
> fixes last week.
Fair enough, but I announced I had a fix in my April 15 status report. Oh well.
So, I decided that a timestamp would leak information about the client, so I'm using a simple counter instead. Would you consider that for your patch?
>> On Apr 23, 2012, at 4:36 PM, Trond Myklebust wrote:
>>
>>> The NFSv4 spec is ambiguous about whether or not it is permissible
>>> to reuse open owner names, so play it safe. This patch adds a timestamp
>>> to the state_owner structure, and combines that with the IDA based
>>> uniquifier.
>>> Fixes a regression whereby the Linux server returns NFS4ERR_BAD_SEQID.
>>>
>>> Signed-off-by: Trond Myklebust <Trond.Myklebust@xxxxxxxxxx>
>>> ---
>>> fs/nfs/nfs4_fs.h | 1 +
>>> fs/nfs/nfs4proc.c | 6 +++---
>>> fs/nfs/nfs4state.c | 1 +
>>> fs/nfs/nfs4xdr.c | 9 +++++----
>>> include/linux/nfs_xdr.h | 7 ++++++-
>>> 5 files changed, 16 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
>>> index 97ecc86..b6db9e3 100644
>>> --- a/fs/nfs/nfs4_fs.h
>>> +++ b/fs/nfs/nfs4_fs.h
>>> @@ -59,6 +59,7 @@ struct nfs_unique_id {
>>>
>>> #define NFS_SEQID_CONFIRMED 1
>>> struct nfs_seqid_counter {
>>> + ktime_t create_time;
>>> int owner_id;
>>> int flags;
>>> u32 counter;
>>> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
>>> index f875cf3..60d5f4c 100644
>>> --- a/fs/nfs/nfs4proc.c
>>> +++ b/fs/nfs/nfs4proc.c
>>> @@ -838,7 +838,8 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
>>> p->o_arg.open_flags = flags;
>>> p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE);
>>> p->o_arg.clientid = server->nfs_client->cl_clientid;
>>> - p->o_arg.id = sp->so_seqid.owner_id;
>>> + p->o_arg.id.create_time = ktime_to_ns(sp->so_seqid.create_time);
>>> + p->o_arg.id.uniquifier = sp->so_seqid.owner_id;
>>> p->o_arg.name = &dentry->d_name;
>>> p->o_arg.server = server;
>>> p->o_arg.bitmask = server->attr_bitmask;
>>> @@ -1466,8 +1467,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
>>> goto unlock_no_action;
>>> rcu_read_unlock();
>>> }
>>> - /* Update sequence id. */
>>> - data->o_arg.id = sp->so_seqid.owner_id;
>>> + /* Update client id. */
>>> data->o_arg.clientid = sp->so_server->nfs_client->cl_clientid;
>>> if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) {
>>> task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR];
>>> diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
>>> index 0f43414..3b07f09 100644
>>> --- a/fs/nfs/nfs4state.c
>>> +++ b/fs/nfs/nfs4state.c
>>> @@ -393,6 +393,7 @@ nfs4_remove_state_owner_locked(struct nfs4_state_owner *sp)
>>> static void
>>> nfs4_init_seqid_counter(struct nfs_seqid_counter *sc)
>>> {
>>> + sc->create_time = ktime_get();
>>> sc->flags = 0;
>>> sc->counter = 0;
>>> spin_lock_init(&sc->lock);
>>> diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
>>> index c74fdb1..77fc5f9 100644
>>> --- a/fs/nfs/nfs4xdr.c
>>> +++ b/fs/nfs/nfs4xdr.c
>>> @@ -74,7 +74,7 @@ static int nfs4_stat_to_errno(int);
>>> /* lock,open owner id:
>>> * we currently use size 2 (u64) out of (NFS4_OPAQUE_LIMIT >> 2)
>>> */
>>> -#define open_owner_id_maxsz (1 + 1 + 4)
>>> +#define open_owner_id_maxsz (1 + 2 + 1 + 1 + 2)
>>> #define lock_owner_id_maxsz (1 + 1 + 4)
>>> #define decode_lockowner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ))
>>> #define compound_encode_hdr_maxsz (3 + (NFS4_MAXTAGLEN >> 2))
>>> @@ -1340,12 +1340,13 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena
>>> */
>>> encode_nfs4_seqid(xdr, arg->seqid);
>>> encode_share_access(xdr, arg->fmode);
>>> - p = reserve_space(xdr, 32);
>>> + p = reserve_space(xdr, 36);
>>> p = xdr_encode_hyper(p, arg->clientid);
>>> - *p++ = cpu_to_be32(20);
>>> + *p++ = cpu_to_be32(24);
>>> p = xdr_encode_opaque_fixed(p, "open id:", 8);
>>> *p++ = cpu_to_be32(arg->server->s_dev);
>>> - xdr_encode_hyper(p, arg->id);
>>> + *p++ = cpu_to_be32(arg->id.uniquifier);
>>> + xdr_encode_hyper(p, arg->id.create_time);
>>> }
>>>
>>> static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg)
>>> diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
>>> index bfd0d1b..7ba3551 100644
>>> --- a/include/linux/nfs_xdr.h
>>> +++ b/include/linux/nfs_xdr.h
>>> @@ -312,6 +312,11 @@ struct nfs4_layoutreturn {
>>> int rpc_status;
>>> };
>>>
>>> +struct stateowner_id {
>>> + __u64 create_time;
>>> + __u32 uniquifier;
>>> +};
>>> +
>>> /*
>>> * Arguments to the open call.
>>> */
>>> @@ -321,7 +326,7 @@ struct nfs_openargs {
>>> int open_flags;
>>> fmode_t fmode;
>>> __u64 clientid;
>>> - __u64 id;
>>> + struct stateowner_id id;
>>> union {
>>> struct {
>>> struct iattr * attrs; /* UNCHECKED, GUARDED */
>>> --
>>> 1.7.7.6
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
>>> the body of a message to majordomo@xxxxxxxxxxxxxxx
>>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
> --
> Trond Myklebust
> Linux NFS client maintainer
>
> NetApp
> Trond.Myklebust@xxxxxxxxxx
> www.netapp.com
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
Chuck Lever
chuck[dot]lever[at]oracle[dot]com
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
[Linux USB Development]
[Linux Media Development]
[Video for Linux]
[Linux NILFS]
[Linux Audio Users]
[Photo]
[Yosemite Info]
[Yosemite Photos]
[POF Sucks]
[Linux Kernel]
[Linux SCSI]
[XFree86]