diff options
-rw-r--r-- | fs/nfsd/nfs4recover.c | 29 | ||||
-rw-r--r-- | fs/nfsd/state.h | 1 |
2 files changed, 30 insertions, 0 deletions
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index b4289060ebaf..bf3a3575d060 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c | |||
@@ -1265,6 +1265,22 @@ nfsd4_umh_cltrack_init(struct net *net) | |||
1265 | } | 1265 | } |
1266 | 1266 | ||
1267 | static void | 1267 | static void |
1268 | nfsd4_cltrack_upcall_lock(struct nfs4_client *clp) | ||
1269 | { | ||
1270 | wait_on_bit_lock(&clp->cl_flags, NFSD4_CLIENT_UPCALL_LOCK, | ||
1271 | TASK_UNINTERRUPTIBLE); | ||
1272 | } | ||
1273 | |||
1274 | static void | ||
1275 | nfsd4_cltrack_upcall_unlock(struct nfs4_client *clp) | ||
1276 | { | ||
1277 | smp_mb__before_atomic(); | ||
1278 | clear_bit(NFSD4_CLIENT_UPCALL_LOCK, &clp->cl_flags); | ||
1279 | smp_mb__after_atomic(); | ||
1280 | wake_up_bit(&clp->cl_flags, NFSD4_CLIENT_UPCALL_LOCK); | ||
1281 | } | ||
1282 | |||
1283 | static void | ||
1268 | nfsd4_umh_cltrack_create(struct nfs4_client *clp) | 1284 | nfsd4_umh_cltrack_create(struct nfs4_client *clp) |
1269 | { | 1285 | { |
1270 | char *hexid, *has_session, *grace_start; | 1286 | char *hexid, *has_session, *grace_start; |
@@ -1275,9 +1291,14 @@ nfsd4_umh_cltrack_create(struct nfs4_client *clp) | |||
1275 | dprintk("%s: can't allocate memory for upcall!\n", __func__); | 1291 | dprintk("%s: can't allocate memory for upcall!\n", __func__); |
1276 | return; | 1292 | return; |
1277 | } | 1293 | } |
1294 | |||
1278 | has_session = nfsd4_cltrack_client_has_session(clp); | 1295 | has_session = nfsd4_cltrack_client_has_session(clp); |
1279 | grace_start = nfsd4_cltrack_grace_start(nn->boot_time); | 1296 | grace_start = nfsd4_cltrack_grace_start(nn->boot_time); |
1297 | |||
1298 | nfsd4_cltrack_upcall_lock(clp); | ||
1280 | nfsd4_umh_cltrack_upcall("create", hexid, has_session, grace_start); | 1299 | nfsd4_umh_cltrack_upcall("create", hexid, has_session, grace_start); |
1300 | nfsd4_cltrack_upcall_unlock(clp); | ||
1301 | |||
1281 | kfree(has_session); | 1302 | kfree(has_session); |
1282 | kfree(grace_start); | 1303 | kfree(grace_start); |
1283 | kfree(hexid); | 1304 | kfree(hexid); |
@@ -1293,7 +1314,11 @@ nfsd4_umh_cltrack_remove(struct nfs4_client *clp) | |||
1293 | dprintk("%s: can't allocate memory for upcall!\n", __func__); | 1314 | dprintk("%s: can't allocate memory for upcall!\n", __func__); |
1294 | return; | 1315 | return; |
1295 | } | 1316 | } |
1317 | |||
1318 | nfsd4_cltrack_upcall_lock(clp); | ||
1296 | nfsd4_umh_cltrack_upcall("remove", hexid, NULL, NULL); | 1319 | nfsd4_umh_cltrack_upcall("remove", hexid, NULL, NULL); |
1320 | nfsd4_cltrack_upcall_unlock(clp); | ||
1321 | |||
1297 | kfree(hexid); | 1322 | kfree(hexid); |
1298 | } | 1323 | } |
1299 | 1324 | ||
@@ -1311,7 +1336,11 @@ nfsd4_umh_cltrack_check(struct nfs4_client *clp) | |||
1311 | 1336 | ||
1312 | has_session = nfsd4_cltrack_client_has_session(clp); | 1337 | has_session = nfsd4_cltrack_client_has_session(clp); |
1313 | legacy = nfsd4_cltrack_legacy_recdir(&clp->cl_name); | 1338 | legacy = nfsd4_cltrack_legacy_recdir(&clp->cl_name); |
1339 | |||
1340 | nfsd4_cltrack_upcall_lock(clp); | ||
1314 | ret = nfsd4_umh_cltrack_upcall("check", hexid, has_session, legacy); | 1341 | ret = nfsd4_umh_cltrack_upcall("check", hexid, has_session, legacy); |
1342 | nfsd4_cltrack_upcall_unlock(clp); | ||
1343 | |||
1315 | kfree(has_session); | 1344 | kfree(has_session); |
1316 | kfree(legacy); | 1345 | kfree(legacy); |
1317 | kfree(hexid); | 1346 | kfree(hexid); |
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 854f0c574ccf..62a82ab06cf1 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h | |||
@@ -306,6 +306,7 @@ struct nfs4_client { | |||
306 | #define NFSD4_CLIENT_STABLE (2) /* client on stable storage */ | 306 | #define NFSD4_CLIENT_STABLE (2) /* client on stable storage */ |
307 | #define NFSD4_CLIENT_RECLAIM_COMPLETE (3) /* reclaim_complete done */ | 307 | #define NFSD4_CLIENT_RECLAIM_COMPLETE (3) /* reclaim_complete done */ |
308 | #define NFSD4_CLIENT_CONFIRMED (4) /* client is confirmed */ | 308 | #define NFSD4_CLIENT_CONFIRMED (4) /* client is confirmed */ |
309 | #define NFSD4_CLIENT_UPCALL_LOCK (5) /* upcall serialization */ | ||
309 | #define NFSD4_CLIENT_CB_FLAG_MASK (1 << NFSD4_CLIENT_CB_UPDATE | \ | 310 | #define NFSD4_CLIENT_CB_FLAG_MASK (1 << NFSD4_CLIENT_CB_UPDATE | \ |
310 | 1 << NFSD4_CLIENT_CB_KILL) | 311 | 1 << NFSD4_CLIENT_CB_KILL) |
311 | unsigned long cl_flags; | 312 | unsigned long cl_flags; |