~ubuntu-branches/ubuntu/lucid/linux-rt/lucid

« back to all changes in this revision

Viewing changes to fs/nfs/super.c

  • Committer: Bazaar Package Importer
  • Author(s): Luke Yelavich
  • Date: 2009-08-05 23:00:52 UTC
  • Revision ID: james.westby@ubuntu.com-20090805230052-7xedvqcyk9dnnxb2
Tags: 2.6.31-1.1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
#include <linux/smp_lock.h>
43
43
#include <linux/seq_file.h>
44
44
#include <linux/mount.h>
 
45
#include <linux/mnt_namespace.h>
 
46
#include <linux/namei.h>
45
47
#include <linux/nfs_idmap.h>
46
48
#include <linux/vfs.h>
47
49
#include <linux/inet.h>
60
62
#include "delegation.h"
61
63
#include "iostat.h"
62
64
#include "internal.h"
 
65
#include "fscache.h"
63
66
 
64
67
#define NFSDBG_FACILITY         NFSDBG_VFS
65
68
 
76
79
        Opt_rdirplus, Opt_nordirplus,
77
80
        Opt_sharecache, Opt_nosharecache,
78
81
        Opt_resvport, Opt_noresvport,
 
82
        Opt_fscache, Opt_nofscache,
79
83
 
80
84
        /* Mount options that take integer arguments */
81
85
        Opt_port,
88
92
        Opt_mountport,
89
93
        Opt_mountvers,
90
94
        Opt_nfsvers,
 
95
        Opt_minorversion,
91
96
 
92
97
        /* Mount options that take string arguments */
93
98
        Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost,
94
99
        Opt_addr, Opt_mountaddr, Opt_clientaddr,
95
100
        Opt_lookupcache,
 
101
        Opt_fscache_uniq,
96
102
 
97
103
        /* Special mount options */
98
104
        Opt_userspace, Opt_deprecated, Opt_sloppy,
132
138
        { Opt_nosharecache, "nosharecache" },
133
139
        { Opt_resvport, "resvport" },
134
140
        { Opt_noresvport, "noresvport" },
 
141
        { Opt_fscache, "fsc" },
 
142
        { Opt_fscache_uniq, "fsc=%s" },
 
143
        { Opt_nofscache, "nofsc" },
135
144
 
136
 
        { Opt_port, "port=%u" },
137
 
        { Opt_rsize, "rsize=%u" },
138
 
        { Opt_wsize, "wsize=%u" },
139
 
        { Opt_bsize, "bsize=%u" },
140
 
        { Opt_timeo, "timeo=%u" },
141
 
        { Opt_retrans, "retrans=%u" },
142
 
        { Opt_acregmin, "acregmin=%u" },
143
 
        { Opt_acregmax, "acregmax=%u" },
144
 
        { Opt_acdirmin, "acdirmin=%u" },
145
 
        { Opt_acdirmax, "acdirmax=%u" },
146
 
        { Opt_actimeo, "actimeo=%u" },
147
 
        { Opt_namelen, "namlen=%u" },
148
 
        { Opt_mountport, "mountport=%u" },
149
 
        { Opt_mountvers, "mountvers=%u" },
150
 
        { Opt_nfsvers, "nfsvers=%u" },
151
 
        { Opt_nfsvers, "vers=%u" },
 
145
        { Opt_port, "port=%s" },
 
146
        { Opt_rsize, "rsize=%s" },
 
147
        { Opt_wsize, "wsize=%s" },
 
148
        { Opt_bsize, "bsize=%s" },
 
149
        { Opt_timeo, "timeo=%s" },
 
150
        { Opt_retrans, "retrans=%s" },
 
151
        { Opt_acregmin, "acregmin=%s" },
 
152
        { Opt_acregmax, "acregmax=%s" },
 
153
        { Opt_acdirmin, "acdirmin=%s" },
 
154
        { Opt_acdirmax, "acdirmax=%s" },
 
155
        { Opt_actimeo, "actimeo=%s" },
 
156
        { Opt_namelen, "namlen=%s" },
 
157
        { Opt_mountport, "mountport=%s" },
 
158
        { Opt_mountvers, "mountvers=%s" },
 
159
        { Opt_nfsvers, "nfsvers=%s" },
 
160
        { Opt_nfsvers, "vers=%s" },
 
161
        { Opt_minorversion, "minorversion=%u" },
152
162
 
153
163
        { Opt_sec, "sec=%s" },
154
164
        { Opt_proto, "proto=%s" },
264
274
#ifdef CONFIG_NFS_V4
265
275
static int nfs4_get_sb(struct file_system_type *fs_type,
266
276
        int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
 
277
static int nfs4_remote_get_sb(struct file_system_type *fs_type,
 
278
        int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
267
279
static int nfs4_xdev_get_sb(struct file_system_type *fs_type,
268
280
        int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
269
281
static int nfs4_referral_get_sb(struct file_system_type *fs_type,
270
282
        int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
 
283
static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type,
 
284
        int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
271
285
static void nfs4_kill_super(struct super_block *sb);
272
286
 
273
287
static struct file_system_type nfs4_fs_type = {
278
292
        .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
279
293
};
280
294
 
 
295
static struct file_system_type nfs4_remote_fs_type = {
 
296
        .owner          = THIS_MODULE,
 
297
        .name           = "nfs4",
 
298
        .get_sb         = nfs4_remote_get_sb,
 
299
        .kill_sb        = nfs4_kill_super,
 
300
        .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
 
301
};
 
302
 
281
303
struct file_system_type nfs4_xdev_fs_type = {
282
304
        .owner          = THIS_MODULE,
283
305
        .name           = "nfs4",
286
308
        .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
287
309
};
288
310
 
 
311
static struct file_system_type nfs4_remote_referral_fs_type = {
 
312
        .owner          = THIS_MODULE,
 
313
        .name           = "nfs4",
 
314
        .get_sb         = nfs4_remote_referral_get_sb,
 
315
        .kill_sb        = nfs4_kill_super,
 
316
        .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
 
317
};
 
318
 
289
319
struct file_system_type nfs4_referral_fs_type = {
290
320
        .owner          = THIS_MODULE,
291
321
        .name           = "nfs4",
508
538
                const char *nostr;
509
539
        } nfs_info[] = {
510
540
                { NFS_MOUNT_SOFT, ",soft", ",hard" },
511
 
                { NFS_MOUNT_INTR, ",intr", ",nointr" },
512
541
                { NFS_MOUNT_POSIX, ",posix", "" },
513
542
                { NFS_MOUNT_NOCTO, ",nocto", "" },
514
543
                { NFS_MOUNT_NOAC, ",noac", "" },
563
592
        if (clp->rpc_ops->version == 4)
564
593
                seq_printf(m, ",clientaddr=%s", clp->cl_ipaddr);
565
594
#endif
 
595
        if (nfss->options & NFS_OPTION_FSCACHE)
 
596
                seq_printf(m, ",fsc");
566
597
}
567
598
 
568
599
/*
641
672
                        totals.events[i] += stats->events[i];
642
673
                for (i = 0; i < __NFSIOS_BYTESMAX; i++)
643
674
                        totals.bytes[i] += stats->bytes[i];
 
675
#ifdef CONFIG_NFS_FSCACHE
 
676
                for (i = 0; i < __NFSIOS_FSCACHEMAX; i++)
 
677
                        totals.fscache[i] += stats->fscache[i];
 
678
#endif
644
679
 
645
680
                preempt_enable();
646
681
        }
651
686
        seq_printf(m, "\n\tbytes:\t");
652
687
        for (i = 0; i < __NFSIOS_BYTESMAX; i++)
653
688
                seq_printf(m, "%Lu ", totals.bytes[i]);
 
689
#ifdef CONFIG_NFS_FSCACHE
 
690
        if (nfss->options & NFS_OPTION_FSCACHE) {
 
691
                seq_printf(m, "\n\tfsc:\t");
 
692
                for (i = 0; i < __NFSIOS_FSCACHEMAX; i++)
 
693
                        seq_printf(m, "%Lu ", totals.bytes[i]);
 
694
        }
 
695
#endif
654
696
        seq_printf(m, "\n");
655
697
 
656
698
        rpc_print_iostats(m, nfss->client);
664
706
 */
665
707
static void nfs_umount_begin(struct super_block *sb)
666
708
{
667
 
        struct nfs_server *server = NFS_SB(sb);
 
709
        struct nfs_server *server;
668
710
        struct rpc_clnt *rpc;
669
711
 
 
712
        lock_kernel();
 
713
 
 
714
        server = NFS_SB(sb);
670
715
        /* -EIO all pending I/O */
671
716
        rpc = server->client_acl;
672
717
        if (!IS_ERR(rpc))
674
719
        rpc = server->client;
675
720
        if (!IS_ERR(rpc))
676
721
                rpc_killall_tasks(rpc);
 
722
 
 
723
        unlock_kernel();
677
724
}
678
725
 
679
726
/*
919
966
        return 1;
920
967
}
921
968
 
922
 
static void nfs_parse_invalid_value(const char *option)
923
 
{
924
 
        dfprintk(MOUNT, "NFS:   bad value specified for %s option\n", option);
925
 
}
926
 
 
927
969
/*
928
970
 * Error-check and convert a string of mount options from user space into
929
971
 * a data structure.  The whole mount string is processed; bad options are
934
976
                                   struct nfs_parsed_mount_data *mnt)
935
977
{
936
978
        char *p, *string, *secdata;
937
 
        int rc, sloppy = 0, errors = 0;
 
979
        int rc, sloppy = 0, invalid_option = 0;
938
980
 
939
981
        if (!raw) {
940
982
                dfprintk(MOUNT, "NFS: mount options string was NULL.\n");
958
1000
 
959
1001
        while ((p = strsep(&raw, ",")) != NULL) {
960
1002
                substring_t args[MAX_OPT_ARGS];
961
 
                int option, token;
 
1003
                unsigned long option;
 
1004
                int int_option;
 
1005
                int token;
962
1006
 
963
1007
                if (!*p)
964
1008
                        continue;
1018
1062
                case Opt_rdma:
1019
1063
                        mnt->flags |= NFS_MOUNT_TCP; /* for side protocols */
1020
1064
                        mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
 
1065
                        xprt_load_transport(p);
1021
1066
                        break;
1022
1067
                case Opt_acl:
1023
1068
                        mnt->flags &= ~NFS_MOUNT_NOACL;
1043
1088
                case Opt_noresvport:
1044
1089
                        mnt->flags |= NFS_MOUNT_NORESVPORT;
1045
1090
                        break;
 
1091
                case Opt_fscache:
 
1092
                        mnt->options |= NFS_OPTION_FSCACHE;
 
1093
                        kfree(mnt->fscache_uniq);
 
1094
                        mnt->fscache_uniq = NULL;
 
1095
                        break;
 
1096
                case Opt_nofscache:
 
1097
                        mnt->options &= ~NFS_OPTION_FSCACHE;
 
1098
                        kfree(mnt->fscache_uniq);
 
1099
                        mnt->fscache_uniq = NULL;
 
1100
                        break;
 
1101
                case Opt_fscache_uniq:
 
1102
                        string = match_strdup(args);
 
1103
                        if (!string)
 
1104
                                goto out_nomem;
 
1105
                        kfree(mnt->fscache_uniq);
 
1106
                        mnt->fscache_uniq = string;
 
1107
                        mnt->options |= NFS_OPTION_FSCACHE;
 
1108
                        break;
1046
1109
 
1047
1110
                /*
1048
1111
                 * options that take numeric values
1049
1112
                 */
1050
1113
                case Opt_port:
1051
 
                        if (match_int(args, &option) ||
1052
 
                            option < 0 || option > USHORT_MAX) {
1053
 
                                errors++;
1054
 
                                nfs_parse_invalid_value("port");
1055
 
                        } else
1056
 
                                mnt->nfs_server.port = option;
 
1114
                        string = match_strdup(args);
 
1115
                        if (string == NULL)
 
1116
                                goto out_nomem;
 
1117
                        rc = strict_strtoul(string, 10, &option);
 
1118
                        kfree(string);
 
1119
                        if (rc != 0 || option > USHORT_MAX)
 
1120
                                goto out_invalid_value;
 
1121
                        mnt->nfs_server.port = option;
1057
1122
                        break;
1058
1123
                case Opt_rsize:
1059
 
                        if (match_int(args, &option) || option < 0) {
1060
 
                                errors++;
1061
 
                                nfs_parse_invalid_value("rsize");
1062
 
                        } else
1063
 
                                mnt->rsize = option;
 
1124
                        string = match_strdup(args);
 
1125
                        if (string == NULL)
 
1126
                                goto out_nomem;
 
1127
                        rc = strict_strtoul(string, 10, &option);
 
1128
                        kfree(string);
 
1129
                        if (rc != 0)
 
1130
                                goto out_invalid_value;
 
1131
                        mnt->rsize = option;
1064
1132
                        break;
1065
1133
                case Opt_wsize:
1066
 
                        if (match_int(args, &option) || option < 0) {
1067
 
                                errors++;
1068
 
                                nfs_parse_invalid_value("wsize");
1069
 
                        } else
1070
 
                                mnt->wsize = option;
 
1134
                        string = match_strdup(args);
 
1135
                        if (string == NULL)
 
1136
                                goto out_nomem;
 
1137
                        rc = strict_strtoul(string, 10, &option);
 
1138
                        kfree(string);
 
1139
                        if (rc != 0)
 
1140
                                goto out_invalid_value;
 
1141
                        mnt->wsize = option;
1071
1142
                        break;
1072
1143
                case Opt_bsize:
1073
 
                        if (match_int(args, &option) || option < 0) {
1074
 
                                errors++;
1075
 
                                nfs_parse_invalid_value("bsize");
1076
 
                        } else
1077
 
                                mnt->bsize = option;
 
1144
                        string = match_strdup(args);
 
1145
                        if (string == NULL)
 
1146
                                goto out_nomem;
 
1147
                        rc = strict_strtoul(string, 10, &option);
 
1148
                        kfree(string);
 
1149
                        if (rc != 0)
 
1150
                                goto out_invalid_value;
 
1151
                        mnt->bsize = option;
1078
1152
                        break;
1079
1153
                case Opt_timeo:
1080
 
                        if (match_int(args, &option) || option <= 0) {
1081
 
                                errors++;
1082
 
                                nfs_parse_invalid_value("timeo");
1083
 
                        } else
1084
 
                                mnt->timeo = option;
 
1154
                        string = match_strdup(args);
 
1155
                        if (string == NULL)
 
1156
                                goto out_nomem;
 
1157
                        rc = strict_strtoul(string, 10, &option);
 
1158
                        kfree(string);
 
1159
                        if (rc != 0 || option == 0)
 
1160
                                goto out_invalid_value;
 
1161
                        mnt->timeo = option;
1085
1162
                        break;
1086
1163
                case Opt_retrans:
1087
 
                        if (match_int(args, &option) || option <= 0) {
1088
 
                                errors++;
1089
 
                                nfs_parse_invalid_value("retrans");
1090
 
                        } else
1091
 
                                mnt->retrans = option;
 
1164
                        string = match_strdup(args);
 
1165
                        if (string == NULL)
 
1166
                                goto out_nomem;
 
1167
                        rc = strict_strtoul(string, 10, &option);
 
1168
                        kfree(string);
 
1169
                        if (rc != 0 || option == 0)
 
1170
                                goto out_invalid_value;
 
1171
                        mnt->retrans = option;
1092
1172
                        break;
1093
1173
                case Opt_acregmin:
1094
 
                        if (match_int(args, &option) || option < 0) {
1095
 
                                errors++;
1096
 
                                nfs_parse_invalid_value("acregmin");
1097
 
                        } else
1098
 
                                mnt->acregmin = option;
 
1174
                        string = match_strdup(args);
 
1175
                        if (string == NULL)
 
1176
                                goto out_nomem;
 
1177
                        rc = strict_strtoul(string, 10, &option);
 
1178
                        kfree(string);
 
1179
                        if (rc != 0)
 
1180
                                goto out_invalid_value;
 
1181
                        mnt->acregmin = option;
1099
1182
                        break;
1100
1183
                case Opt_acregmax:
1101
 
                        if (match_int(args, &option) || option < 0) {
1102
 
                                errors++;
1103
 
                                nfs_parse_invalid_value("acregmax");
1104
 
                        } else
1105
 
                                mnt->acregmax = option;
 
1184
                        string = match_strdup(args);
 
1185
                        if (string == NULL)
 
1186
                                goto out_nomem;
 
1187
                        rc = strict_strtoul(string, 10, &option);
 
1188
                        kfree(string);
 
1189
                        if (rc != 0)
 
1190
                                goto out_invalid_value;
 
1191
                        mnt->acregmax = option;
1106
1192
                        break;
1107
1193
                case Opt_acdirmin:
1108
 
                        if (match_int(args, &option) || option < 0) {
1109
 
                                errors++;
1110
 
                                nfs_parse_invalid_value("acdirmin");
1111
 
                        } else
1112
 
                                mnt->acdirmin = option;
 
1194
                        string = match_strdup(args);
 
1195
                        if (string == NULL)
 
1196
                                goto out_nomem;
 
1197
                        rc = strict_strtoul(string, 10, &option);
 
1198
                        kfree(string);
 
1199
                        if (rc != 0)
 
1200
                                goto out_invalid_value;
 
1201
                        mnt->acdirmin = option;
1113
1202
                        break;
1114
1203
                case Opt_acdirmax:
1115
 
                        if (match_int(args, &option) || option < 0) {
1116
 
                                errors++;
1117
 
                                nfs_parse_invalid_value("acdirmax");
1118
 
                        } else
1119
 
                                mnt->acdirmax = option;
 
1204
                        string = match_strdup(args);
 
1205
                        if (string == NULL)
 
1206
                                goto out_nomem;
 
1207
                        rc = strict_strtoul(string, 10, &option);
 
1208
                        kfree(string);
 
1209
                        if (rc != 0)
 
1210
                                goto out_invalid_value;
 
1211
                        mnt->acdirmax = option;
1120
1212
                        break;
1121
1213
                case Opt_actimeo:
1122
 
                        if (match_int(args, &option) || option < 0) {
1123
 
                                errors++;
1124
 
                                nfs_parse_invalid_value("actimeo");
1125
 
                        } else
1126
 
                                mnt->acregmin = mnt->acregmax =
1127
 
                                mnt->acdirmin = mnt->acdirmax = option;
 
1214
                        string = match_strdup(args);
 
1215
                        if (string == NULL)
 
1216
                                goto out_nomem;
 
1217
                        rc = strict_strtoul(string, 10, &option);
 
1218
                        kfree(string);
 
1219
                        if (rc != 0)
 
1220
                                goto out_invalid_value;
 
1221
                        mnt->acregmin = mnt->acregmax =
 
1222
                        mnt->acdirmin = mnt->acdirmax = option;
1128
1223
                        break;
1129
1224
                case Opt_namelen:
1130
 
                        if (match_int(args, &option) || option < 0) {
1131
 
                                errors++;
1132
 
                                nfs_parse_invalid_value("namlen");
1133
 
                        } else
1134
 
                                mnt->namlen = option;
 
1225
                        string = match_strdup(args);
 
1226
                        if (string == NULL)
 
1227
                                goto out_nomem;
 
1228
                        rc = strict_strtoul(string, 10, &option);
 
1229
                        kfree(string);
 
1230
                        if (rc != 0)
 
1231
                                goto out_invalid_value;
 
1232
                        mnt->namlen = option;
1135
1233
                        break;
1136
1234
                case Opt_mountport:
1137
 
                        if (match_int(args, &option) ||
1138
 
                            option < 0 || option > USHORT_MAX) {
1139
 
                                errors++;
1140
 
                                nfs_parse_invalid_value("mountport");
1141
 
                        } else
1142
 
                                mnt->mount_server.port = option;
 
1235
                        string = match_strdup(args);
 
1236
                        if (string == NULL)
 
1237
                                goto out_nomem;
 
1238
                        rc = strict_strtoul(string, 10, &option);
 
1239
                        kfree(string);
 
1240
                        if (rc != 0 || option > USHORT_MAX)
 
1241
                                goto out_invalid_value;
 
1242
                        mnt->mount_server.port = option;
1143
1243
                        break;
1144
1244
                case Opt_mountvers:
1145
 
                        if (match_int(args, &option) ||
 
1245
                        string = match_strdup(args);
 
1246
                        if (string == NULL)
 
1247
                                goto out_nomem;
 
1248
                        rc = strict_strtoul(string, 10, &option);
 
1249
                        kfree(string);
 
1250
                        if (rc != 0 ||
1146
1251
                            option < NFS_MNT_VERSION ||
1147
 
                            option > NFS_MNT3_VERSION) {
1148
 
                                errors++;
1149
 
                                nfs_parse_invalid_value("mountvers");
1150
 
                        } else
1151
 
                                mnt->mount_server.version = option;
 
1252
                            option > NFS_MNT3_VERSION)
 
1253
                                goto out_invalid_value;
 
1254
                        mnt->mount_server.version = option;
1152
1255
                        break;
1153
1256
                case Opt_nfsvers:
1154
 
                        if (match_int(args, &option)) {
1155
 
                                errors++;
1156
 
                                nfs_parse_invalid_value("nfsvers");
1157
 
                                break;
1158
 
                        }
 
1257
                        string = match_strdup(args);
 
1258
                        if (string == NULL)
 
1259
                                goto out_nomem;
 
1260
                        rc = strict_strtoul(string, 10, &option);
 
1261
                        kfree(string);
 
1262
                        if (rc != 0)
 
1263
                                goto out_invalid_value;
1159
1264
                        switch (option) {
1160
1265
                        case NFS2_VERSION:
1161
1266
                                mnt->flags &= ~NFS_MOUNT_VER3;
1164
1269
                                mnt->flags |= NFS_MOUNT_VER3;
1165
1270
                                break;
1166
1271
                        default:
1167
 
                                errors++;
1168
 
                                nfs_parse_invalid_value("nfsvers");
 
1272
                                goto out_invalid_value;
1169
1273
                        }
1170
1274
                        break;
 
1275
                case Opt_minorversion:
 
1276
                        if (match_int(args, &int_option))
 
1277
                                return 0;
 
1278
                        if (int_option < 0 || int_option > NFS4_MAX_MINOR_VERSION)
 
1279
                                return 0;
 
1280
                        mnt->minorversion = int_option;
 
1281
                        break;
1171
1282
 
1172
1283
                /*
1173
1284
                 * options that take text values
1179
1290
                        rc = nfs_parse_security_flavors(string, mnt);
1180
1291
                        kfree(string);
1181
1292
                        if (!rc) {
1182
 
                                errors++;
1183
1293
                                dfprintk(MOUNT, "NFS:   unrecognized "
1184
1294
                                                "security flavor\n");
 
1295
                                return 0;
1185
1296
                        }
1186
1297
                        break;
1187
1298
                case Opt_proto:
1190
1301
                                goto out_nomem;
1191
1302
                        token = match_token(string,
1192
1303
                                            nfs_xprt_protocol_tokens, args);
1193
 
                        kfree(string);
1194
1304
 
1195
1305
                        switch (token) {
1196
1306
                        case Opt_xprt_udp:
1197
1307
                                mnt->flags &= ~NFS_MOUNT_TCP;
1198
1308
                                mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
 
1309
                                kfree(string);
1199
1310
                                break;
1200
1311
                        case Opt_xprt_tcp:
1201
1312
                                mnt->flags |= NFS_MOUNT_TCP;
1202
1313
                                mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
 
1314
                                kfree(string);
1203
1315
                                break;
1204
1316
                        case Opt_xprt_rdma:
1205
1317
                                /* vector side protocols to TCP */
1206
1318
                                mnt->flags |= NFS_MOUNT_TCP;
1207
1319
                                mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
 
1320
                                xprt_load_transport(string);
 
1321
                                kfree(string);
1208
1322
                                break;
1209
1323
                        default:
1210
 
                                errors++;
1211
1324
                                dfprintk(MOUNT, "NFS:   unrecognized "
1212
1325
                                                "transport protocol\n");
 
1326
                                return 0;
1213
1327
                        }
1214
1328
                        break;
1215
1329
                case Opt_mountproto:
1229
1343
                                break;
1230
1344
                        case Opt_xprt_rdma: /* not used for side protocols */
1231
1345
                        default:
1232
 
                                errors++;
1233
1346
                                dfprintk(MOUNT, "NFS:   unrecognized "
1234
1347
                                                "transport protocol\n");
 
1348
                                return 0;
1235
1349
                        }
1236
1350
                        break;
1237
1351
                case Opt_addr:
1287
1401
                                        mnt->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE;
1288
1402
                                        break;
1289
1403
                                default:
1290
 
                                        errors++;
1291
1404
                                        dfprintk(MOUNT, "NFS:   invalid "
1292
1405
                                                        "lookupcache argument\n");
 
1406
                                        return 0;
1293
1407
                        };
1294
1408
                        break;
1295
1409
 
1307
1421
                        break;
1308
1422
 
1309
1423
                default:
1310
 
                        errors++;
 
1424
                        invalid_option = 1;
1311
1425
                        dfprintk(MOUNT, "NFS:   unrecognized mount option "
1312
1426
                                        "'%s'\n", p);
1313
1427
                }
1314
1428
        }
1315
1429
 
1316
 
        if (errors > 0) {
1317
 
                dfprintk(MOUNT, "NFS: parsing encountered %d error%s\n",
1318
 
                                errors, (errors == 1 ? "" : "s"));
1319
 
                if (!sloppy)
1320
 
                        return 0;
1321
 
        }
 
1430
        if (!sloppy && invalid_option)
 
1431
                return 0;
 
1432
 
1322
1433
        return 1;
1323
1434
 
 
1435
out_invalid_value:
 
1436
        printk(KERN_INFO "NFS: bad mount option value specified: %s \n", p);
 
1437
        return 0;
1324
1438
out_nomem:
1325
1439
        printk(KERN_INFO "NFS: not enough memory to parse option\n");
1326
1440
        return 0;
1337
1451
static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1338
1452
                         struct nfs_fh *root_fh)
1339
1453
{
 
1454
        unsigned int auth_flavor_len = 0;
1340
1455
        struct nfs_mount_request request = {
1341
1456
                .sap            = (struct sockaddr *)
1342
1457
                                                &args->mount_server.address,
1344
1459
                .protocol       = args->mount_server.protocol,
1345
1460
                .fh             = root_fh,
1346
1461
                .noresvport     = args->flags & NFS_MOUNT_NORESVPORT,
 
1462
                .auth_flav_len  = &auth_flavor_len,
1347
1463
        };
1348
1464
        int status;
1349
1465
 
1769
1885
        if (data == NULL)
1770
1886
                return -ENOMEM;
1771
1887
 
 
1888
        lock_kernel();
1772
1889
        /* fill out struct with values from existing mount */
1773
1890
        data->flags = nfss->flags;
1774
1891
        data->rsize = nfss->rsize;
1793
1910
        error = nfs_compare_remount_data(nfss, data);
1794
1911
out:
1795
1912
        kfree(data);
 
1913
        unlock_kernel();
1796
1914
        return error;
1797
1915
}
1798
1916
 
1868
1986
        nfs_initialise_sb(sb);
1869
1987
}
1870
1988
 
1871
 
#define NFS_MS_MASK (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_SYNCHRONOUS)
1872
 
 
1873
1989
static int nfs_compare_mount_options(const struct super_block *s, const struct nfs_server *b, int flags)
1874
1990
{
1875
1991
        const struct nfs_server *a = s->s_fs_info;
2034
2150
        if (!s->s_root) {
2035
2151
                /* initial superblock/root creation */
2036
2152
                nfs_fill_super(s, data);
 
2153
                nfs_fscache_get_super_cookie(s, data);
2037
2154
        }
2038
2155
 
2039
2156
        mntroot = nfs_get_root(s, mntfh);
2054
2171
out:
2055
2172
        kfree(data->nfs_server.hostname);
2056
2173
        kfree(data->mount_server.hostname);
 
2174
        kfree(data->fscache_uniq);
2057
2175
        security_free_mnt_opts(&data->lsm_opts);
2058
2176
out_free_fh:
2059
2177
        kfree(mntfh);
2067
2185
error_splat_root:
2068
2186
        dput(mntroot);
2069
2187
error_splat_super:
2070
 
        up_write(&s->s_umount);
2071
 
        deactivate_super(s);
 
2188
        deactivate_locked_super(s);
2072
2189
        goto out;
2073
2190
}
2074
2191
 
2081
2198
 
2082
2199
        bdi_unregister(&server->backing_dev_info);
2083
2200
        kill_anon_super(s);
 
2201
        nfs_fscache_release_super_cookie(s);
2084
2202
        nfs_free_server(server);
2085
2203
}
2086
2204
 
2163
2281
        return error;
2164
2282
 
2165
2283
error_splat_super:
2166
 
        up_write(&s->s_umount);
2167
 
        deactivate_super(s);
 
2284
        deactivate_locked_super(s);
2168
2285
        dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error);
2169
2286
        return error;
2170
2287
}
2195
2312
        nfs_initialise_sb(sb);
2196
2313
}
2197
2314
 
 
2315
static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args)
 
2316
{
 
2317
        args->flags &= ~(NFS_MOUNT_NONLM|NFS_MOUNT_NOACL|NFS_MOUNT_VER3);
 
2318
}
 
2319
 
2198
2320
/*
2199
2321
 * Validate NFSv4 mount options
2200
2322
 */
2218
2340
        args->nfs_server.port   = NFS_PORT; /* 2049 unless user set port= */
2219
2341
        args->auth_flavors[0]   = RPC_AUTH_UNIX;
2220
2342
        args->auth_flavor_len   = 0;
 
2343
        args->minorversion      = 0;
2221
2344
 
2222
2345
        switch (data->version) {
2223
2346
        case 1:
2291
2414
 
2292
2415
                nfs_validate_transport_protocol(args);
2293
2416
 
 
2417
                nfs4_validate_mount_flags(args);
 
2418
 
2294
2419
                if (args->auth_flavor_len > 1)
2295
2420
                        goto out_inval_auth;
2296
2421
 
2330
2455
}
2331
2456
 
2332
2457
/*
2333
 
 * Get the superblock for an NFS4 mountpoint
 
2458
 * Get the superblock for the NFS4 root partition
2334
2459
 */
2335
 
static int nfs4_get_sb(struct file_system_type *fs_type,
 
2460
static int nfs4_remote_get_sb(struct file_system_type *fs_type,
2336
2461
        int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
2337
2462
{
2338
 
        struct nfs_parsed_mount_data *data;
 
2463
        struct nfs_parsed_mount_data *data = raw_data;
2339
2464
        struct super_block *s;
2340
2465
        struct nfs_server *server;
2341
2466
        struct nfs_fh *mntfh;
2346
2471
        };
2347
2472
        int error = -ENOMEM;
2348
2473
 
2349
 
        data = kzalloc(sizeof(*data), GFP_KERNEL);
2350
2474
        mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL);
2351
2475
        if (data == NULL || mntfh == NULL)
2352
2476
                goto out_free_fh;
2353
2477
 
2354
2478
        security_init_mnt_opts(&data->lsm_opts);
2355
2479
 
2356
 
        /* Validate the mount data */
2357
 
        error = nfs4_validate_mount_data(raw_data, data, dev_name);
2358
 
        if (error < 0)
2359
 
                goto out;
2360
 
 
2361
2480
        /* Get a volume representation */
2362
2481
        server = nfs4_create_server(data, mntfh);
2363
2482
        if (IS_ERR(server)) {
2370
2489
                compare_super = NULL;
2371
2490
 
2372
2491
        /* Get a superblock - note that we may end up sharing one that already exists */
2373
 
        s = sget(fs_type, compare_super, nfs_set_super, &sb_mntdata);
 
2492
        s = sget(&nfs4_fs_type, compare_super, nfs_set_super, &sb_mntdata);
2374
2493
        if (IS_ERR(s)) {
2375
2494
                error = PTR_ERR(s);
2376
2495
                goto out_free;
2388
2507
        if (!s->s_root) {
2389
2508
                /* initial superblock/root creation */
2390
2509
                nfs4_fill_super(s);
 
2510
                nfs_fscache_get_super_cookie(s, data);
2391
2511
        }
2392
2512
 
2393
2513
        mntroot = nfs4_get_root(s, mntfh);
2406
2526
        error = 0;
2407
2527
 
2408
2528
out:
 
2529
        security_free_mnt_opts(&data->lsm_opts);
 
2530
out_free_fh:
 
2531
        kfree(mntfh);
 
2532
        return error;
 
2533
 
 
2534
out_free:
 
2535
        nfs_free_server(server);
 
2536
        goto out;
 
2537
 
 
2538
error_splat_root:
 
2539
        dput(mntroot);
 
2540
error_splat_super:
 
2541
        deactivate_locked_super(s);
 
2542
        goto out;
 
2543
}
 
2544
 
 
2545
static struct vfsmount *nfs_do_root_mount(struct file_system_type *fs_type,
 
2546
                int flags, void *data, const char *hostname)
 
2547
{
 
2548
        struct vfsmount *root_mnt;
 
2549
        char *root_devname;
 
2550
        size_t len;
 
2551
 
 
2552
        len = strlen(hostname) + 3;
 
2553
        root_devname = kmalloc(len, GFP_KERNEL);
 
2554
        if (root_devname == NULL)
 
2555
                return ERR_PTR(-ENOMEM);
 
2556
        snprintf(root_devname, len, "%s:/", hostname);
 
2557
        root_mnt = vfs_kern_mount(fs_type, flags, root_devname, data);
 
2558
        kfree(root_devname);
 
2559
        return root_mnt;
 
2560
}
 
2561
 
 
2562
static void nfs_fix_devname(const struct path *path, struct vfsmount *mnt)
 
2563
{
 
2564
        char *page = (char *) __get_free_page(GFP_KERNEL);
 
2565
        char *devname, *tmp;
 
2566
 
 
2567
        if (page == NULL)
 
2568
                return;
 
2569
        devname = nfs_path(path->mnt->mnt_devname,
 
2570
                        path->mnt->mnt_root, path->dentry,
 
2571
                        page, PAGE_SIZE);
 
2572
        if (devname == NULL)
 
2573
                goto out_freepage;
 
2574
        tmp = kstrdup(devname, GFP_KERNEL);
 
2575
        if (tmp == NULL)
 
2576
                goto out_freepage;
 
2577
        kfree(mnt->mnt_devname);
 
2578
        mnt->mnt_devname = tmp;
 
2579
out_freepage:
 
2580
        free_page((unsigned long)page);
 
2581
}
 
2582
 
 
2583
static int nfs_follow_remote_path(struct vfsmount *root_mnt,
 
2584
                const char *export_path, struct vfsmount *mnt_target)
 
2585
{
 
2586
        struct mnt_namespace *ns_private;
 
2587
        struct nameidata nd;
 
2588
        struct super_block *s;
 
2589
        int ret;
 
2590
 
 
2591
        ns_private = create_mnt_ns(root_mnt);
 
2592
        ret = PTR_ERR(ns_private);
 
2593
        if (IS_ERR(ns_private))
 
2594
                goto out_mntput;
 
2595
 
 
2596
        ret = vfs_path_lookup(root_mnt->mnt_root, root_mnt,
 
2597
                        export_path, LOOKUP_FOLLOW, &nd);
 
2598
 
 
2599
        put_mnt_ns(ns_private);
 
2600
 
 
2601
        if (ret != 0)
 
2602
                goto out_err;
 
2603
 
 
2604
        s = nd.path.mnt->mnt_sb;
 
2605
        atomic_inc(&s->s_active);
 
2606
        mnt_target->mnt_sb = s;
 
2607
        mnt_target->mnt_root = dget(nd.path.dentry);
 
2608
 
 
2609
        /* Correct the device pathname */
 
2610
        nfs_fix_devname(&nd.path, mnt_target);
 
2611
 
 
2612
        path_put(&nd.path);
 
2613
        down_write(&s->s_umount);
 
2614
        return 0;
 
2615
out_mntput:
 
2616
        mntput(root_mnt);
 
2617
out_err:
 
2618
        return ret;
 
2619
}
 
2620
 
 
2621
/*
 
2622
 * Get the superblock for an NFS4 mountpoint
 
2623
 */
 
2624
static int nfs4_get_sb(struct file_system_type *fs_type,
 
2625
        int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
 
2626
{
 
2627
        struct nfs_parsed_mount_data *data;
 
2628
        char *export_path;
 
2629
        struct vfsmount *root_mnt;
 
2630
        int error = -ENOMEM;
 
2631
 
 
2632
        data = kzalloc(sizeof(*data), GFP_KERNEL);
 
2633
        if (data == NULL)
 
2634
                goto out_free_data;
 
2635
 
 
2636
        /* Validate the mount data */
 
2637
        error = nfs4_validate_mount_data(raw_data, data, dev_name);
 
2638
        if (error < 0)
 
2639
                goto out;
 
2640
 
 
2641
        export_path = data->nfs_server.export_path;
 
2642
        data->nfs_server.export_path = "/";
 
2643
        root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, data,
 
2644
                        data->nfs_server.hostname);
 
2645
        data->nfs_server.export_path = export_path;
 
2646
 
 
2647
        error = PTR_ERR(root_mnt);
 
2648
        if (IS_ERR(root_mnt))
 
2649
                goto out;
 
2650
 
 
2651
        error = nfs_follow_remote_path(root_mnt, export_path, mnt);
 
2652
 
 
2653
out:
2409
2654
        kfree(data->client_address);
2410
2655
        kfree(data->nfs_server.export_path);
2411
2656
        kfree(data->nfs_server.hostname);
2412
 
        security_free_mnt_opts(&data->lsm_opts);
2413
 
out_free_fh:
2414
 
        kfree(mntfh);
 
2657
        kfree(data->fscache_uniq);
 
2658
out_free_data:
2415
2659
        kfree(data);
 
2660
        dprintk("<-- nfs4_get_sb() = %d%s\n", error,
 
2661
                        error != 0 ? " [error]" : "");
2416
2662
        return error;
2417
 
 
2418
 
out_free:
2419
 
        nfs_free_server(server);
2420
 
        goto out;
2421
 
 
2422
 
error_splat_root:
2423
 
        dput(mntroot);
2424
 
error_splat_super:
2425
 
        up_write(&s->s_umount);
2426
 
        deactivate_super(s);
2427
 
        goto out;
2428
2663
}
2429
2664
 
2430
2665
static void nfs4_kill_super(struct super_block *sb)
2431
2666
{
2432
2667
        struct nfs_server *server = NFS_SB(sb);
2433
2668
 
 
2669
        dprintk("--> %s\n", __func__);
2434
2670
        nfs_super_return_all_delegations(sb);
2435
2671
        kill_anon_super(sb);
2436
 
 
2437
2672
        nfs4_renewd_prepare_shutdown(server);
 
2673
        nfs_fscache_release_super_cookie(sb);
2438
2674
        nfs_free_server(server);
 
2675
        dprintk("<-- %s\n", __func__);
2439
2676
}
2440
2677
 
2441
2678
/*
2516
2753
        return error;
2517
2754
 
2518
2755
error_splat_super:
2519
 
        up_write(&s->s_umount);
2520
 
        deactivate_super(s);
 
2756
        deactivate_locked_super(s);
2521
2757
        dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error);
2522
2758
        return error;
2523
2759
}
2524
2760
 
2525
 
/*
2526
 
 * Create an NFS4 server record on referral traversal
2527
 
 */
2528
 
static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags,
2529
 
                                const char *dev_name, void *raw_data,
2530
 
                                struct vfsmount *mnt)
 
2761
static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type,
 
2762
                int flags, const char *dev_name, void *raw_data,
 
2763
                struct vfsmount *mnt)
2531
2764
{
2532
2765
        struct nfs_clone_mount *data = raw_data;
2533
2766
        struct super_block *s;
2601
2834
        return error;
2602
2835
 
2603
2836
error_splat_super:
2604
 
        up_write(&s->s_umount);
2605
 
        deactivate_super(s);
 
2837
        deactivate_locked_super(s);
2606
2838
        dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error);
2607
2839
        return error;
2608
2840
}
2609
2841
 
 
2842
/*
 
2843
 * Create an NFS4 server record on referral traversal
 
2844
 */
 
2845
static int nfs4_referral_get_sb(struct file_system_type *fs_type,
 
2846
                int flags, const char *dev_name, void *raw_data,
 
2847
                struct vfsmount *mnt)
 
2848
{
 
2849
        struct nfs_clone_mount *data = raw_data;
 
2850
        char *export_path;
 
2851
        struct vfsmount *root_mnt;
 
2852
        int error;
 
2853
 
 
2854
        dprintk("--> nfs4_referral_get_sb()\n");
 
2855
 
 
2856
        export_path = data->mnt_path;
 
2857
        data->mnt_path = "/";
 
2858
 
 
2859
        root_mnt = nfs_do_root_mount(&nfs4_remote_referral_fs_type,
 
2860
                        flags, data, data->hostname);
 
2861
        data->mnt_path = export_path;
 
2862
 
 
2863
        error = PTR_ERR(root_mnt);
 
2864
        if (IS_ERR(root_mnt))
 
2865
                goto out;
 
2866
 
 
2867
        error = nfs_follow_remote_path(root_mnt, export_path, mnt);
 
2868
out:
 
2869
        dprintk("<-- nfs4_referral_get_sb() = %d%s\n", error,
 
2870
                        error != 0 ? " [error]" : "");
 
2871
        return error;
 
2872
}
 
2873
 
2610
2874
#endif /* CONFIG_NFS_V4 */