NFSv4.1: Fix nfs4_callback_recallslot to work with dynamic slot allocation
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 20 Nov 2012 20:16:30 +0000 (15:16 -0500)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Wed, 5 Dec 2012 23:30:37 +0000 (00:30 +0100)
Ensure that the NFSv4.1 CB_RECALL_SLOT callback updates the slot table
target max slotid safely.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/nfs/callback_proc.c
fs/nfs/nfs4_fs.h
fs/nfs/nfs4proc.c

index 0ef047b7d28dab76ed660720d928749c856e0d17..15b9879d6fbb1ccd23178af143a42ee4fd3fe374 100644 (file)
@@ -576,7 +576,7 @@ __be32 nfs4_callback_recallslot(struct cb_recallslotargs *args, void *dummy,
        if (args->crsa_target_max_slots == fc_tbl->max_slots)
                goto out;
 
-       fc_tbl->target_highest_slotid = args->crsa_target_max_slots;
+       nfs41_set_target_slotid(fc_tbl, args->crsa_target_max_slots);
        nfs41_handle_recall_slot(cps->clp);
 out:
        dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
index 42c58691fb4180ead5a0bd1ded00bb5ac99529fe..5d4e82b10c3c63dccce73c2e5d768b4c783a26db 100644 (file)
@@ -260,6 +260,8 @@ extern int nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data,
 
 extern struct nfs4_slot *nfs4_alloc_slots(struct nfs4_slot_table *table,
                u32 max_slots, gfp_t gfp_flags);
+extern void nfs41_set_target_slotid(struct nfs4_slot_table *tbl,
+               u32 target_highest_slotid);
 
 static inline bool
 is_ds_only_client(struct nfs_client *clp)
index 52435ec441932b878e2824a9cd5ad3a24714328e..62212231ce622f7b30f0c77a76e01497c2cbc639 100644 (file)
@@ -498,6 +498,14 @@ static void nfs41_set_target_slotid_locked(struct nfs4_slot_table *tbl,
        tbl->generation++;
 }
 
+void nfs41_set_target_slotid(struct nfs4_slot_table *tbl,
+               u32 target_highest_slotid)
+{
+       spin_lock(&tbl->slot_tbl_lock);
+       nfs41_set_target_slotid_locked(tbl, target_highest_slotid);
+       spin_unlock(&tbl->slot_tbl_lock);
+}
+
 static void nfs41_set_server_slotid_locked(struct nfs4_slot_table *tbl,
                u32 highest_slotid)
 {