static u32 do_callback_layoutrecall(struct nfs_client *clp,
struct cb_layoutrecallargs *args)
{
+ write_seqcount_begin(&clp->cl_callback_count);
+ write_seqcount_end(&clp->cl_callback_count);
if (args->cbl_recall_type == RETURN_FILE)
return initiate_file_draining(clp, args);
return initiate_bulk_draining(clp, args);
nfs4_stateid_copy(&lgp->args.stateid, stateid);
lgp->gfp_flags = gfp_flags;
lgp->cred = get_rpccred(ctx->cred);
+ lgp->callback_count = raw_seqcount_begin(&server->nfs_client->cl_callback_count);
return lgp;
}
{
struct pnfs_layout_hdr *lo;
struct pnfs_layout_segment *lseg;
+ struct nfs_server *srv = NFS_SERVER(ino);
u32 iomode;
if (!lgp)
/* FIXME - Any error not listed above permanently
* halts lgopen attempts.
*/
- NFS_SERVER(ino)->caps &= ~NFS_CAP_LGOPEN;
+ srv->caps &= ~NFS_CAP_LGOPEN;
}
return;
}
lo = NFS_I(lgp->args.inode)->layout;
pnfs_get_layout_hdr(lo);
+ if (read_seqcount_retry(&srv->nfs_client->cl_callback_count,
+ lgp->callback_count))
+ goto out;
lseg = pnfs_layout_process(lgp);
atomic_dec(&lo->plh_outstanding);
if (IS_ERR(lseg)) {
pnfs_layout_clear_fail_bit(lo, pnfs_iomode_to_fail_bit(iomode));
pnfs_put_lseg(lseg);
}
+out:
pnfs_clear_first_layoutget(lo);
pnfs_put_layout_hdr(lo);
}
struct nfs_client {
refcount_t cl_count;
atomic_t cl_mds_count;
+ seqcount_t cl_callback_count;
int cl_cons_state; /* current construction state (-ve: init error) */
#define NFS_CS_READY 0 /* ready to be used */
#define NFS_CS_INITING 1 /* busy initialising */