Skip to content

Commit

Permalink
NFSv4/v4.1: Verify the client owner id during trunking detection
Browse files Browse the repository at this point in the history
While we normally expect the NFSv4 client to always send the same client
owner to all servers, there are a couple of situations where that is not
the case:
 1) In NFSv4.0, switching between use of '-omigration' and not will cause
    the kernel to switch between using the non-uniform and uniform client
    strings.
 2) In NFSv4.1, or NFSv4.0 when using uniform client strings, if the
    uniquifier string is suddenly changed.

This patch will catch those situations by checking the client owner id
in the trunking detection code, and will do the right thing if it notices
that the strings differ.

Cc: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
  • Loading branch information
Trond Myklebust committed Jan 6, 2015
1 parent ceb3a16 commit 55b9df9
Showing 1 changed file with 18 additions and 0 deletions.
18 changes: 18 additions & 0 deletions fs/nfs/nfs4client.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,14 @@ static void nfs4_swap_callback_idents(struct nfs_client *keep,
spin_unlock(&nn->nfs_client_lock);
}

static bool nfs4_match_client_owner_id(const struct nfs_client *clp1,
const struct nfs_client *clp2)
{
if (clp1->cl_owner_id == NULL || clp2->cl_owner_id == NULL)
return true;
return strcmp(clp1->cl_owner_id, clp2->cl_owner_id) == 0;
}

/**
* nfs40_walk_client_list - Find server that recognizes a client ID
*
Expand Down Expand Up @@ -511,6 +519,9 @@ int nfs40_walk_client_list(struct nfs_client *new,
if (pos->cl_clientid != new->cl_clientid)
continue;

if (!nfs4_match_client_owner_id(pos, new))
continue;

atomic_inc(&pos->cl_count);
spin_unlock(&nn->nfs_client_lock);

Expand Down Expand Up @@ -657,6 +668,13 @@ int nfs41_walk_client_list(struct nfs_client *new,
if (!nfs4_check_clientid_trunking(pos, new))
continue;

/* Unlike NFSv4.0, we know that NFSv4.1 always uses the
* uniform string, however someone might switch the
* uniquifier string on us.
*/
if (!nfs4_match_client_owner_id(pos, new))
continue;

atomic_inc(&pos->cl_count);
*result = pos;
status = 0;
Expand Down

0 comments on commit 55b9df9

Please sign in to comment.