aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-09 13:24:54 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-09 13:24:54 -0400
commit8cbc95ee748741939222c3d38584a40c92bedcdd (patch)
tree7fc4ace333ef68e6f17ef531138bf16b711def88 /fs/nfs
parentea44083a7081ac8d9cc84d49525e6041025a7a17 (diff)
parentc23266d532b4de796a346f57a66587c5db17d27e (diff)
Merge tag 'nfs-for-3.10-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull more NFS client bugfixes from Trond Myklebust: - Ensure that we match the 'sec=' mount flavour against the server list - Fix the NFSv4 byte range locking in the presence of delegations - Ensure that we conform to the NFSv4.1 spec w.r.t. freeing lock stateids - Fix a pNFS data server connection race * tag 'nfs-for-3.10-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: NFS4.1 Fix data server connection race NFSv3: match sec= flavor against server list NFSv4.1: Ensure that we free the lock stateid on the server NFSv4: Convert nfs41_free_stateid to use an asynchronous RPC call SUNRPC: Don't spam syslog with "Pseudoflavor not found" messages NFSv4.x: Fix handling of partially delegated locks
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4_fs.h3
-rw-r--r--fs/nfs/nfs4filelayout.h2
-rw-r--r--fs/nfs/nfs4filelayoutdev.c26
-rw-r--r--fs/nfs/nfs4proc.c119
-rw-r--r--fs/nfs/nfs4state.c11
-rw-r--r--fs/nfs/nfs4xdr.c2
-rw-r--r--fs/nfs/super.c48
7 files changed, 169 insertions, 42 deletions
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 553a83cc4106..a1dd768d0a35 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -47,6 +47,8 @@ struct nfs4_minor_version_ops {
47 const nfs4_stateid *); 47 const nfs4_stateid *);
48 int (*find_root_sec)(struct nfs_server *, struct nfs_fh *, 48 int (*find_root_sec)(struct nfs_server *, struct nfs_fh *,
49 struct nfs_fsinfo *); 49 struct nfs_fsinfo *);
50 int (*free_lock_state)(struct nfs_server *,
51 struct nfs4_lock_state *);
50 const struct nfs4_state_recovery_ops *reboot_recovery_ops; 52 const struct nfs4_state_recovery_ops *reboot_recovery_ops;
51 const struct nfs4_state_recovery_ops *nograce_recovery_ops; 53 const struct nfs4_state_recovery_ops *nograce_recovery_ops;
52 const struct nfs4_state_maintenance_ops *state_renewal_ops; 54 const struct nfs4_state_maintenance_ops *state_renewal_ops;
@@ -234,7 +236,6 @@ extern int nfs4_proc_fs_locations(struct rpc_clnt *, struct inode *, const struc
234extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *, struct qstr *, 236extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *, struct qstr *,
235 struct nfs_fh *, struct nfs_fattr *); 237 struct nfs_fh *, struct nfs_fattr *);
236extern int nfs4_proc_secinfo(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *); 238extern int nfs4_proc_secinfo(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *);
237extern int nfs4_release_lockowner(struct nfs4_lock_state *);
238extern const struct xattr_handler *nfs4_xattr_handlers[]; 239extern const struct xattr_handler *nfs4_xattr_handlers[];
239extern int nfs4_set_rw_stateid(nfs4_stateid *stateid, 240extern int nfs4_set_rw_stateid(nfs4_stateid *stateid,
240 const struct nfs_open_context *ctx, 241 const struct nfs_open_context *ctx,
diff --git a/fs/nfs/nfs4filelayout.h b/fs/nfs/nfs4filelayout.h
index b8da95548d3d..235ff952d3c8 100644
--- a/fs/nfs/nfs4filelayout.h
+++ b/fs/nfs/nfs4filelayout.h
@@ -70,6 +70,8 @@ struct nfs4_pnfs_ds {
70 struct list_head ds_addrs; 70 struct list_head ds_addrs;
71 struct nfs_client *ds_clp; 71 struct nfs_client *ds_clp;
72 atomic_t ds_count; 72 atomic_t ds_count;
73 unsigned long ds_state;
74#define NFS4DS_CONNECTING 0 /* ds is establishing connection */
73}; 75};
74 76
75struct nfs4_file_layout_dsaddr { 77struct nfs4_file_layout_dsaddr {
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
index 1fe284f01f8b..661a0f611215 100644
--- a/fs/nfs/nfs4filelayoutdev.c
+++ b/fs/nfs/nfs4filelayoutdev.c
@@ -775,6 +775,22 @@ nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j)
775 return flseg->fh_array[i]; 775 return flseg->fh_array[i];
776} 776}
777 777
778static void nfs4_wait_ds_connect(struct nfs4_pnfs_ds *ds)
779{
780 might_sleep();
781 wait_on_bit(&ds->ds_state, NFS4DS_CONNECTING,
782 nfs_wait_bit_killable, TASK_KILLABLE);
783}
784
785static void nfs4_clear_ds_conn_bit(struct nfs4_pnfs_ds *ds)
786{
787 smp_mb__before_clear_bit();
788 clear_bit(NFS4DS_CONNECTING, &ds->ds_state);
789 smp_mb__after_clear_bit();
790 wake_up_bit(&ds->ds_state, NFS4DS_CONNECTING);
791}
792
793
778struct nfs4_pnfs_ds * 794struct nfs4_pnfs_ds *
779nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx) 795nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx)
780{ 796{
@@ -791,16 +807,22 @@ nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx)
791 filelayout_mark_devid_invalid(devid); 807 filelayout_mark_devid_invalid(devid);
792 return NULL; 808 return NULL;
793 } 809 }
810 if (ds->ds_clp)
811 return ds;
794 812
795 if (!ds->ds_clp) { 813 if (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) == 0) {
796 struct nfs_server *s = NFS_SERVER(lseg->pls_layout->plh_inode); 814 struct nfs_server *s = NFS_SERVER(lseg->pls_layout->plh_inode);
797 int err; 815 int err;
798 816
799 err = nfs4_ds_connect(s, ds); 817 err = nfs4_ds_connect(s, ds);
800 if (err) { 818 if (err) {
801 nfs4_mark_deviceid_unavailable(devid); 819 nfs4_mark_deviceid_unavailable(devid);
802 return NULL; 820 ds = NULL;
803 } 821 }
822 nfs4_clear_ds_conn_bit(ds);
823 } else {
824 /* Either ds is connected, or ds is NULL */
825 nfs4_wait_ds_connect(ds);
804 } 826 }
805 return ds; 827 return ds;
806} 828}
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 9da4bd55eb30..8fbc10054115 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -4766,9 +4766,9 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
4766 if (status != 0) 4766 if (status != 0)
4767 goto out; 4767 goto out;
4768 /* Is this a delegated lock? */ 4768 /* Is this a delegated lock? */
4769 if (test_bit(NFS_DELEGATED_STATE, &state->flags))
4770 goto out;
4771 lsp = request->fl_u.nfs4_fl.owner; 4769 lsp = request->fl_u.nfs4_fl.owner;
4770 if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) == 0)
4771 goto out;
4772 seqid = nfs_alloc_seqid(&lsp->ls_seqid, GFP_KERNEL); 4772 seqid = nfs_alloc_seqid(&lsp->ls_seqid, GFP_KERNEL);
4773 status = -ENOMEM; 4773 status = -ENOMEM;
4774 if (seqid == NULL) 4774 if (seqid == NULL)
@@ -5238,9 +5238,8 @@ static const struct rpc_call_ops nfs4_release_lockowner_ops = {
5238 .rpc_release = nfs4_release_lockowner_release, 5238 .rpc_release = nfs4_release_lockowner_release,
5239}; 5239};
5240 5240
5241int nfs4_release_lockowner(struct nfs4_lock_state *lsp) 5241static int nfs4_release_lockowner(struct nfs_server *server, struct nfs4_lock_state *lsp)
5242{ 5242{
5243 struct nfs_server *server = lsp->ls_state->owner->so_server;
5244 struct nfs_release_lockowner_data *data; 5243 struct nfs_release_lockowner_data *data;
5245 struct rpc_message msg = { 5244 struct rpc_message msg = {
5246 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RELEASE_LOCKOWNER], 5245 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RELEASE_LOCKOWNER],
@@ -6783,26 +6782,76 @@ static int nfs41_test_stateid(struct nfs_server *server, nfs4_stateid *stateid)
6783 return err; 6782 return err;
6784} 6783}
6785 6784
6786static int _nfs4_free_stateid(struct nfs_server *server, nfs4_stateid *stateid) 6785struct nfs_free_stateid_data {
6787{ 6786 struct nfs_server *server;
6788 struct nfs41_free_stateid_args args = { 6787 struct nfs41_free_stateid_args args;
6789 .stateid = stateid,
6790 };
6791 struct nfs41_free_stateid_res res; 6788 struct nfs41_free_stateid_res res;
6789};
6790
6791static void nfs41_free_stateid_prepare(struct rpc_task *task, void *calldata)
6792{
6793 struct nfs_free_stateid_data *data = calldata;
6794 nfs41_setup_sequence(nfs4_get_session(data->server),
6795 &data->args.seq_args,
6796 &data->res.seq_res,
6797 task);
6798}
6799
6800static void nfs41_free_stateid_done(struct rpc_task *task, void *calldata)
6801{
6802 struct nfs_free_stateid_data *data = calldata;
6803
6804 nfs41_sequence_done(task, &data->res.seq_res);
6805
6806 switch (task->tk_status) {
6807 case -NFS4ERR_DELAY:
6808 if (nfs4_async_handle_error(task, data->server, NULL) == -EAGAIN)
6809 rpc_restart_call_prepare(task);
6810 }
6811}
6812
6813static void nfs41_free_stateid_release(void *calldata)
6814{
6815 kfree(calldata);
6816}
6817
6818const struct rpc_call_ops nfs41_free_stateid_ops = {
6819 .rpc_call_prepare = nfs41_free_stateid_prepare,
6820 .rpc_call_done = nfs41_free_stateid_done,
6821 .rpc_release = nfs41_free_stateid_release,
6822};
6823
6824static struct rpc_task *_nfs41_free_stateid(struct nfs_server *server,
6825 nfs4_stateid *stateid,
6826 bool privileged)
6827{
6792 struct rpc_message msg = { 6828 struct rpc_message msg = {
6793 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FREE_STATEID], 6829 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FREE_STATEID],
6794 .rpc_argp = &args,
6795 .rpc_resp = &res,
6796 }; 6830 };
6797 int status; 6831 struct rpc_task_setup task_setup = {
6832 .rpc_client = server->client,
6833 .rpc_message = &msg,
6834 .callback_ops = &nfs41_free_stateid_ops,
6835 .flags = RPC_TASK_ASYNC,
6836 };
6837 struct nfs_free_stateid_data *data;
6798 6838
6799 dprintk("NFS call free_stateid %p\n", stateid); 6839 dprintk("NFS call free_stateid %p\n", stateid);
6800 nfs41_init_sequence(&args.seq_args, &res.seq_res, 0); 6840 data = kmalloc(sizeof(*data), GFP_NOFS);
6801 nfs4_set_sequence_privileged(&args.seq_args); 6841 if (!data)
6802 status = nfs4_call_sync_sequence(server->client, server, &msg, 6842 return ERR_PTR(-ENOMEM);
6803 &args.seq_args, &res.seq_res); 6843 data->server = server;
6804 dprintk("NFS reply free_stateid: %d\n", status); 6844 nfs4_stateid_copy(&data->args.stateid, stateid);
6805 return status; 6845
6846 task_setup.callback_data = data;
6847
6848 msg.rpc_argp = &data->args;
6849 msg.rpc_resp = &data->res;
6850 nfs41_init_sequence(&data->args.seq_args, &data->res.seq_res, 0);
6851 if (privileged)
6852 nfs4_set_sequence_privileged(&data->args.seq_args);
6853
6854 return rpc_run_task(&task_setup);
6806} 6855}
6807 6856
6808/** 6857/**
@@ -6816,15 +6865,29 @@ static int _nfs4_free_stateid(struct nfs_server *server, nfs4_stateid *stateid)
6816 */ 6865 */
6817static int nfs41_free_stateid(struct nfs_server *server, nfs4_stateid *stateid) 6866static int nfs41_free_stateid(struct nfs_server *server, nfs4_stateid *stateid)
6818{ 6867{
6819 struct nfs4_exception exception = { }; 6868 struct rpc_task *task;
6820 int err; 6869 int ret;
6821 do { 6870
6822 err = _nfs4_free_stateid(server, stateid); 6871 task = _nfs41_free_stateid(server, stateid, true);
6823 if (err != -NFS4ERR_DELAY) 6872 if (IS_ERR(task))
6824 break; 6873 return PTR_ERR(task);
6825 nfs4_handle_exception(server, err, &exception); 6874 ret = rpc_wait_for_completion_task(task);
6826 } while (exception.retry); 6875 if (!ret)
6827 return err; 6876 ret = task->tk_status;
6877 rpc_put_task(task);
6878 return ret;
6879}
6880
6881static int nfs41_free_lock_state(struct nfs_server *server, struct nfs4_lock_state *lsp)
6882{
6883 struct rpc_task *task;
6884
6885 task = _nfs41_free_stateid(server, &lsp->ls_stateid, false);
6886 nfs4_free_lock_state(server, lsp);
6887 if (IS_ERR(task))
6888 return PTR_ERR(task);
6889 rpc_put_task(task);
6890 return 0;
6828} 6891}
6829 6892
6830static bool nfs41_match_stateid(const nfs4_stateid *s1, 6893static bool nfs41_match_stateid(const nfs4_stateid *s1,
@@ -6916,6 +6979,7 @@ static const struct nfs4_minor_version_ops nfs_v4_0_minor_ops = {
6916 .call_sync = _nfs4_call_sync, 6979 .call_sync = _nfs4_call_sync,
6917 .match_stateid = nfs4_match_stateid, 6980 .match_stateid = nfs4_match_stateid,
6918 .find_root_sec = nfs4_find_root_sec, 6981 .find_root_sec = nfs4_find_root_sec,
6982 .free_lock_state = nfs4_release_lockowner,
6919 .reboot_recovery_ops = &nfs40_reboot_recovery_ops, 6983 .reboot_recovery_ops = &nfs40_reboot_recovery_ops,
6920 .nograce_recovery_ops = &nfs40_nograce_recovery_ops, 6984 .nograce_recovery_ops = &nfs40_nograce_recovery_ops,
6921 .state_renewal_ops = &nfs40_state_renewal_ops, 6985 .state_renewal_ops = &nfs40_state_renewal_ops,
@@ -6933,6 +6997,7 @@ static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = {
6933 .call_sync = nfs4_call_sync_sequence, 6997 .call_sync = nfs4_call_sync_sequence,
6934 .match_stateid = nfs41_match_stateid, 6998 .match_stateid = nfs41_match_stateid,
6935 .find_root_sec = nfs41_find_root_sec, 6999 .find_root_sec = nfs41_find_root_sec,
7000 .free_lock_state = nfs41_free_lock_state,
6936 .reboot_recovery_ops = &nfs41_reboot_recovery_ops, 7001 .reboot_recovery_ops = &nfs41_reboot_recovery_ops,
6937 .nograce_recovery_ops = &nfs41_nograce_recovery_ops, 7002 .nograce_recovery_ops = &nfs41_nograce_recovery_ops,
6938 .state_renewal_ops = &nfs41_state_renewal_ops, 7003 .state_renewal_ops = &nfs41_state_renewal_ops,
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 0b32f9483b7a..300d17d85c0e 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -921,6 +921,7 @@ static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_
921 */ 921 */
922void nfs4_put_lock_state(struct nfs4_lock_state *lsp) 922void nfs4_put_lock_state(struct nfs4_lock_state *lsp)
923{ 923{
924 struct nfs_server *server;
924 struct nfs4_state *state; 925 struct nfs4_state *state;
925 926
926 if (lsp == NULL) 927 if (lsp == NULL)
@@ -932,11 +933,13 @@ void nfs4_put_lock_state(struct nfs4_lock_state *lsp)
932 if (list_empty(&state->lock_states)) 933 if (list_empty(&state->lock_states))
933 clear_bit(LK_STATE_IN_USE, &state->flags); 934 clear_bit(LK_STATE_IN_USE, &state->flags);
934 spin_unlock(&state->state_lock); 935 spin_unlock(&state->state_lock);
936 server = state->owner->so_server;
935 if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags)) { 937 if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags)) {
936 if (nfs4_release_lockowner(lsp) == 0) 938 struct nfs_client *clp = server->nfs_client;
937 return; 939
938 } 940 clp->cl_mvops->free_lock_state(server, lsp);
939 nfs4_free_lock_state(lsp->ls_state->owner->so_server, lsp); 941 } else
942 nfs4_free_lock_state(server, lsp);
940} 943}
941 944
942static void nfs4_fl_copy_lock(struct file_lock *dst, struct file_lock *src) 945static void nfs4_fl_copy_lock(struct file_lock *dst, struct file_lock *src)
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 3c79c5878c6d..4be8d135ed61 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -2003,7 +2003,7 @@ static void encode_free_stateid(struct xdr_stream *xdr,
2003 struct compound_hdr *hdr) 2003 struct compound_hdr *hdr)
2004{ 2004{
2005 encode_op_hdr(xdr, OP_FREE_STATEID, decode_free_stateid_maxsz, hdr); 2005 encode_op_hdr(xdr, OP_FREE_STATEID, decode_free_stateid_maxsz, hdr);
2006 encode_nfs4_stateid(xdr, args->stateid); 2006 encode_nfs4_stateid(xdr, &args->stateid);
2007} 2007}
2008#endif /* CONFIG_NFS_V4_1 */ 2008#endif /* CONFIG_NFS_V4_1 */
2009 2009
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 1bb071dca9ab..a366107a7331 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1610,16 +1610,15 @@ out_security_failure:
1610/* 1610/*
1611 * Select a security flavor for this mount. The selected flavor 1611 * Select a security flavor for this mount. The selected flavor
1612 * is planted in args->auth_flavors[0]. 1612 * is planted in args->auth_flavors[0].
1613 *
1614 * Returns 0 on success, -EACCES on failure.
1613 */ 1615 */
1614static void nfs_select_flavor(struct nfs_parsed_mount_data *args, 1616static int nfs_select_flavor(struct nfs_parsed_mount_data *args,
1615 struct nfs_mount_request *request) 1617 struct nfs_mount_request *request)
1616{ 1618{
1617 unsigned int i, count = *(request->auth_flav_len); 1619 unsigned int i, count = *(request->auth_flav_len);
1618 rpc_authflavor_t flavor; 1620 rpc_authflavor_t flavor;
1619 1621
1620 if (args->auth_flavors[0] != RPC_AUTH_MAXFLAVOR)
1621 goto out;
1622
1623 /* 1622 /*
1624 * The NFSv2 MNT operation does not return a flavor list. 1623 * The NFSv2 MNT operation does not return a flavor list.
1625 */ 1624 */
@@ -1634,6 +1633,25 @@ static void nfs_select_flavor(struct nfs_parsed_mount_data *args,
1634 goto out_default; 1633 goto out_default;
1635 1634
1636 /* 1635 /*
1636 * If the sec= mount option is used, the specified flavor or AUTH_NULL
1637 * must be in the list returned by the server.
1638 *
1639 * AUTH_NULL has a special meaning when it's in the server list - it
1640 * means that the server will ignore the rpc creds, so any flavor
1641 * can be used.
1642 */
1643 if (args->auth_flavors[0] != RPC_AUTH_MAXFLAVOR) {
1644 for (i = 0; i < count; i++) {
1645 if (args->auth_flavors[0] == request->auth_flavs[i] ||
1646 request->auth_flavs[i] == RPC_AUTH_NULL)
1647 goto out;
1648 }
1649 dfprintk(MOUNT, "NFS: auth flavor %d not supported by server\n",
1650 args->auth_flavors[0]);
1651 goto out_err;
1652 }
1653
1654 /*
1637 * RFC 2623, section 2.7 suggests we SHOULD prefer the 1655 * RFC 2623, section 2.7 suggests we SHOULD prefer the
1638 * flavor listed first. However, some servers list 1656 * flavor listed first. However, some servers list
1639 * AUTH_NULL first. Avoid ever choosing AUTH_NULL. 1657 * AUTH_NULL first. Avoid ever choosing AUTH_NULL.
@@ -1653,12 +1671,29 @@ static void nfs_select_flavor(struct nfs_parsed_mount_data *args,
1653 } 1671 }
1654 } 1672 }
1655 1673
1674 /*
1675 * As a last chance, see if the server list contains AUTH_NULL -
1676 * if it does, use the default flavor.
1677 */
1678 for (i = 0; i < count; i++) {
1679 if (request->auth_flavs[i] == RPC_AUTH_NULL)
1680 goto out_default;
1681 }
1682
1683 dfprintk(MOUNT, "NFS: no auth flavors in common with server\n");
1684 goto out_err;
1685
1656out_default: 1686out_default:
1657 flavor = RPC_AUTH_UNIX; 1687 /* use default if flavor not already set */
1688 flavor = (args->auth_flavors[0] == RPC_AUTH_MAXFLAVOR) ?
1689 RPC_AUTH_UNIX : args->auth_flavors[0];
1658out_set: 1690out_set:
1659 args->auth_flavors[0] = flavor; 1691 args->auth_flavors[0] = flavor;
1660out: 1692out:
1661 dfprintk(MOUNT, "NFS: using auth flavor %d\n", args->auth_flavors[0]); 1693 dfprintk(MOUNT, "NFS: using auth flavor %d\n", args->auth_flavors[0]);
1694 return 0;
1695out_err:
1696 return -EACCES;
1662} 1697}
1663 1698
1664/* 1699/*
@@ -1721,8 +1756,7 @@ static int nfs_request_mount(struct nfs_parsed_mount_data *args,
1721 return status; 1756 return status;
1722 } 1757 }
1723 1758
1724 nfs_select_flavor(args, &request); 1759 return nfs_select_flavor(args, &request);
1725 return 0;
1726} 1760}
1727 1761
1728struct dentry *nfs_try_mount(int flags, const char *dev_name, 1762struct dentry *nfs_try_mount(int flags, const char *dev_name,