summaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4recover.c
diff options
context:
space:
mode:
authorJeff Layton2012-11-12 21:00:49 +0100
committerJ. Bruce Fields2012-11-13 00:55:10 +0100
commit2d77bf0a55d64559adb2d48a37bc7e876d6adc11 (patch)
treee1ac2048306f446d03038c68b1b7a94a601b2735 /fs/nfsd/nfs4recover.c
parentnfsd: add a usermodehelper upcall for NFSv4 client ID tracking (diff)
downloadkernel-qcow2-linux-2d77bf0a55d64559adb2d48a37bc7e876d6adc11.tar.gz
kernel-qcow2-linux-2d77bf0a55d64559adb2d48a37bc7e876d6adc11.tar.xz
kernel-qcow2-linux-2d77bf0a55d64559adb2d48a37bc7e876d6adc11.zip
nfsd: change heuristic for selecting the client_tracking_ops
First, try to use the new usermodehelper upcall. It should succeed or fail quickly, so there's little cost to doing so. If it fails, and the legacy tracking dir exists, use that. If it doesn't exist then fall back to using nfsdcld. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4recover.c')
-rw-r--r--fs/nfsd/nfs4recover.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 2fc2f6cb8d95..e71f713bd7c0 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -1064,17 +1064,35 @@ nfsd4_client_tracking_init(struct net *net)
int status;
struct path path;
- if (!client_tracking_ops) {
- client_tracking_ops = &nfsd4_cld_tracking_ops;
- status = kern_path(nfs4_recoverydir(), LOOKUP_FOLLOW, &path);
- if (!status) {
- if (S_ISDIR(path.dentry->d_inode->i_mode))
- client_tracking_ops =
- &nfsd4_legacy_tracking_ops;
- path_put(&path);
- }
+ /* just run the init if it the method is already decided */
+ if (client_tracking_ops)
+ goto do_init;
+
+ /*
+ * First, try a UMH upcall. It should succeed or fail quickly, so
+ * there's little harm in trying that first.
+ */
+ client_tracking_ops = &nfsd4_umh_tracking_ops;
+ status = client_tracking_ops->init(net);
+ if (!status)
+ return status;
+
+ /*
+ * See if the recoverydir exists and is a directory. If it is,
+ * then use the legacy ops.
+ */
+ client_tracking_ops = &nfsd4_legacy_tracking_ops;
+ status = kern_path(nfs4_recoverydir(), LOOKUP_FOLLOW, &path);
+ if (!status) {
+ status = S_ISDIR(path.dentry->d_inode->i_mode);
+ path_put(&path);
+ if (status)
+ goto do_init;
}
+ /* Finally, try to use nfsdcld */
+ client_tracking_ops = &nfsd4_cld_tracking_ops;
+do_init:
status = client_tracking_ops->init(net);
if (status) {
printk(KERN_WARNING "NFSD: Unable to initialize client "