diff options
author | Stanislav Kinsbursky <skinsbursky@parallels.com> | 2012-12-04 06:29:27 -0500 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2012-12-10 16:25:30 -0500 |
commit | 9a9c6478a8b6ce8b6da6b6d1e15f365b505895cd (patch) | |
tree | 6e76bd072bc6d18e8a0c6279139a2f927e163135 /fs | |
parent | 9b2ef62b1541f176ea1b1f6e13b16df14bb16e99 (diff) |
nfsd: make NFSv4 recovery client tracking options per net
Pointer to client tracking operations - client_tracking_ops - have to be
containerized, because different environment can support different trackers
(for example, legacy tracker currently is not suported in container).
Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfsd/netns.h | 2 | ||||
-rw-r--r-- | fs/nfsd/nfs4recover.c | 48 |
2 files changed, 30 insertions, 20 deletions
diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h index 964b5542f02..fac4123c918 100644 --- a/fs/nfsd/netns.h +++ b/fs/nfsd/netns.h | |||
@@ -35,6 +35,7 @@ | |||
35 | #define SESSION_HASH_SIZE 512 | 35 | #define SESSION_HASH_SIZE 512 |
36 | 36 | ||
37 | struct cld_net; | 37 | struct cld_net; |
38 | struct nfsd4_client_tracking_ops; | ||
38 | 39 | ||
39 | struct nfsd_net { | 40 | struct nfsd_net { |
40 | struct cld_net *cld_net; | 41 | struct cld_net *cld_net; |
@@ -87,6 +88,7 @@ struct nfsd_net { | |||
87 | 88 | ||
88 | struct file *rec_file; | 89 | struct file *rec_file; |
89 | bool in_grace; | 90 | bool in_grace; |
91 | struct nfsd4_client_tracking_ops *client_tracking_ops; | ||
90 | 92 | ||
91 | time_t nfsd4_lease; | 93 | time_t nfsd4_lease; |
92 | time_t nfsd4_grace; | 94 | time_t nfsd4_grace; |
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index 359793f8949..ba6fdd4a045 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c | |||
@@ -63,7 +63,6 @@ struct nfsd4_client_tracking_ops { | |||
63 | 63 | ||
64 | /* Globals */ | 64 | /* Globals */ |
65 | static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery"; | 65 | static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery"; |
66 | static struct nfsd4_client_tracking_ops *client_tracking_ops; | ||
67 | 66 | ||
68 | static int | 67 | static int |
69 | nfs4_save_creds(const struct cred **original_creds) | 68 | nfs4_save_creds(const struct cred **original_creds) |
@@ -1262,17 +1261,18 @@ nfsd4_client_tracking_init(struct net *net) | |||
1262 | { | 1261 | { |
1263 | int status; | 1262 | int status; |
1264 | struct path path; | 1263 | struct path path; |
1264 | struct nfsd_net *nn = net_generic(net, nfsd_net_id); | ||
1265 | 1265 | ||
1266 | /* just run the init if it the method is already decided */ | 1266 | /* just run the init if it the method is already decided */ |
1267 | if (client_tracking_ops) | 1267 | if (nn->client_tracking_ops) |
1268 | goto do_init; | 1268 | goto do_init; |
1269 | 1269 | ||
1270 | /* | 1270 | /* |
1271 | * First, try a UMH upcall. It should succeed or fail quickly, so | 1271 | * First, try a UMH upcall. It should succeed or fail quickly, so |
1272 | * there's little harm in trying that first. | 1272 | * there's little harm in trying that first. |
1273 | */ | 1273 | */ |
1274 | client_tracking_ops = &nfsd4_umh_tracking_ops; | 1274 | nn->client_tracking_ops = &nfsd4_umh_tracking_ops; |
1275 | status = client_tracking_ops->init(net); | 1275 | status = nn->client_tracking_ops->init(net); |
1276 | if (!status) | 1276 | if (!status) |
1277 | return status; | 1277 | return status; |
1278 | 1278 | ||
@@ -1280,7 +1280,7 @@ nfsd4_client_tracking_init(struct net *net) | |||
1280 | * See if the recoverydir exists and is a directory. If it is, | 1280 | * See if the recoverydir exists and is a directory. If it is, |
1281 | * then use the legacy ops. | 1281 | * then use the legacy ops. |
1282 | */ | 1282 | */ |
1283 | client_tracking_ops = &nfsd4_legacy_tracking_ops; | 1283 | nn->client_tracking_ops = &nfsd4_legacy_tracking_ops; |
1284 | status = kern_path(nfs4_recoverydir(), LOOKUP_FOLLOW, &path); | 1284 | status = kern_path(nfs4_recoverydir(), LOOKUP_FOLLOW, &path); |
1285 | if (!status) { | 1285 | if (!status) { |
1286 | status = S_ISDIR(path.dentry->d_inode->i_mode); | 1286 | status = S_ISDIR(path.dentry->d_inode->i_mode); |
@@ -1290,16 +1290,16 @@ nfsd4_client_tracking_init(struct net *net) | |||
1290 | } | 1290 | } |
1291 | 1291 | ||
1292 | /* Finally, try to use nfsdcld */ | 1292 | /* Finally, try to use nfsdcld */ |
1293 | client_tracking_ops = &nfsd4_cld_tracking_ops; | 1293 | nn->client_tracking_ops = &nfsd4_cld_tracking_ops; |
1294 | printk(KERN_WARNING "NFSD: the nfsdcld client tracking upcall will be " | 1294 | printk(KERN_WARNING "NFSD: the nfsdcld client tracking upcall will be " |
1295 | "removed in 3.10. Please transition to using " | 1295 | "removed in 3.10. Please transition to using " |
1296 | "nfsdcltrack.\n"); | 1296 | "nfsdcltrack.\n"); |
1297 | do_init: | 1297 | do_init: |
1298 | status = client_tracking_ops->init(net); | 1298 | status = nn->client_tracking_ops->init(net); |
1299 | if (status) { | 1299 | if (status) { |
1300 | printk(KERN_WARNING "NFSD: Unable to initialize client " | 1300 | printk(KERN_WARNING "NFSD: Unable to initialize client " |
1301 | "recovery tracking! (%d)\n", status); | 1301 | "recovery tracking! (%d)\n", status); |
1302 | client_tracking_ops = NULL; | 1302 | nn->client_tracking_ops = NULL; |
1303 | } | 1303 | } |
1304 | return status; | 1304 | return status; |
1305 | } | 1305 | } |
@@ -1307,32 +1307,40 @@ do_init: | |||
1307 | void | 1307 | void |
1308 | nfsd4_client_tracking_exit(struct net *net) | 1308 | nfsd4_client_tracking_exit(struct net *net) |
1309 | { | 1309 | { |
1310 | if (client_tracking_ops) { | 1310 | struct nfsd_net *nn = net_generic(net, nfsd_net_id); |
1311 | if (client_tracking_ops->exit) | 1311 | |
1312 | client_tracking_ops->exit(net); | 1312 | if (nn->client_tracking_ops) { |
1313 | client_tracking_ops = NULL; | 1313 | if (nn->client_tracking_ops->exit) |
1314 | nn->client_tracking_ops->exit(net); | ||
1315 | nn->client_tracking_ops = NULL; | ||
1314 | } | 1316 | } |
1315 | } | 1317 | } |
1316 | 1318 | ||
1317 | void | 1319 | void |
1318 | nfsd4_client_record_create(struct nfs4_client *clp) | 1320 | nfsd4_client_record_create(struct nfs4_client *clp) |
1319 | { | 1321 | { |
1320 | if (client_tracking_ops) | 1322 | struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id); |
1321 | client_tracking_ops->create(clp); | 1323 | |
1324 | if (nn->client_tracking_ops) | ||
1325 | nn->client_tracking_ops->create(clp); | ||
1322 | } | 1326 | } |
1323 | 1327 | ||
1324 | void | 1328 | void |
1325 | nfsd4_client_record_remove(struct nfs4_client *clp) | 1329 | nfsd4_client_record_remove(struct nfs4_client *clp) |
1326 | { | 1330 | { |
1327 | if (client_tracking_ops) | 1331 | struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id); |
1328 | client_tracking_ops->remove(clp); | 1332 | |
1333 | if (nn->client_tracking_ops) | ||
1334 | nn->client_tracking_ops->remove(clp); | ||
1329 | } | 1335 | } |
1330 | 1336 | ||
1331 | int | 1337 | int |
1332 | nfsd4_client_record_check(struct nfs4_client *clp) | 1338 | nfsd4_client_record_check(struct nfs4_client *clp) |
1333 | { | 1339 | { |
1334 | if (client_tracking_ops) | 1340 | struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id); |
1335 | return client_tracking_ops->check(clp); | 1341 | |
1342 | if (nn->client_tracking_ops) | ||
1343 | return nn->client_tracking_ops->check(clp); | ||
1336 | 1344 | ||
1337 | return -EOPNOTSUPP; | 1345 | return -EOPNOTSUPP; |
1338 | } | 1346 | } |
@@ -1340,8 +1348,8 @@ nfsd4_client_record_check(struct nfs4_client *clp) | |||
1340 | void | 1348 | void |
1341 | nfsd4_record_grace_done(struct nfsd_net *nn, time_t boot_time) | 1349 | nfsd4_record_grace_done(struct nfsd_net *nn, time_t boot_time) |
1342 | { | 1350 | { |
1343 | if (client_tracking_ops) | 1351 | if (nn->client_tracking_ops) |
1344 | client_tracking_ops->grace_done(nn, boot_time); | 1352 | nn->client_tracking_ops->grace_done(nn, boot_time); |
1345 | } | 1353 | } |
1346 | 1354 | ||
1347 | static int | 1355 | static int |