Skip to content

Commit

Permalink
NFSv4.1 dereference a disconnected data server client record
Browse files Browse the repository at this point in the history
When the last DS io is processed, the data server client record will be
freed.

Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
  • Loading branch information
Andy Adamson authored and Trond Myklebust committed May 19, 2012
1 parent 3a7936c commit b4a2967
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 0 deletions.
1 change: 1 addition & 0 deletions fs/nfs/nfs4filelayout.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ static int filelayout_async_handle_error(struct rpc_task *task,
_pnfs_return_layout(state->inode);
filelayout_mark_devid_invalid(devid);
rpc_wake_up(&tbl->slot_tbl_waitq);
nfs4_ds_disconnect(clp);
/* fall through */
default:
dprintk("%s Retry through MDS. Error %d\n", __func__,
Expand Down
1 change: 1 addition & 0 deletions fs/nfs/nfs4filelayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,5 +146,6 @@ extern void nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr);
extern void nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr);
struct nfs4_file_layout_dsaddr *
get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags);
void nfs4_ds_disconnect(struct nfs_client *clp);

#endif /* FS_NFS_NFS4FILELAYOUT_H */
22 changes: 22 additions & 0 deletions fs/nfs/nfs4filelayoutdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,28 @@ _data_server_lookup_locked(const struct list_head *dsaddrs)
return NULL;
}

/*
* Lookup DS by nfs_client pointer. Zero data server client pointer
*/
void nfs4_ds_disconnect(struct nfs_client *clp)
{
struct nfs4_pnfs_ds *ds;
struct nfs_client *found = NULL;

dprintk("%s clp %p\n", __func__, clp);
spin_lock(&nfs4_ds_cache_lock);
list_for_each_entry(ds, &nfs4_data_server_cache, ds_node)
if (ds->ds_clp && ds->ds_clp == clp) {
found = ds->ds_clp;
ds->ds_clp = NULL;
}
spin_unlock(&nfs4_ds_cache_lock);
if (found) {
set_bit(NFS_CS_STOP_RENEW, &clp->cl_res_state);
nfs_put_client(clp);
}
}

/*
* Create an rpc connection to the nfs4_pnfs_ds data server
* Currently only supports IPv4 and IPv6 addresses
Expand Down

0 comments on commit b4a2967

Please sign in to comment.