0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/module.h>
0010 #include <linux/init.h>
0011 #include <linux/sched.h>
0012 #include <linux/time.h>
0013 #include <linux/kernel.h>
0014 #include <linux/mm.h>
0015 #include <linux/string.h>
0016 #include <linux/stat.h>
0017 #include <linux/errno.h>
0018 #include <linux/unistd.h>
0019 #include <linux/sunrpc/addr.h>
0020 #include <linux/sunrpc/clnt.h>
0021 #include <linux/sunrpc/stats.h>
0022 #include <linux/sunrpc/metrics.h>
0023 #include <linux/sunrpc/xprtsock.h>
0024 #include <linux/sunrpc/xprtrdma.h>
0025 #include <linux/nfs_fs.h>
0026 #include <linux/nfs_mount.h>
0027 #include <linux/nfs4_mount.h>
0028 #include <linux/lockd/bind.h>
0029 #include <linux/seq_file.h>
0030 #include <linux/mount.h>
0031 #include <linux/vfs.h>
0032 #include <linux/inet.h>
0033 #include <linux/in6.h>
0034 #include <linux/slab.h>
0035 #include <linux/idr.h>
0036 #include <net/ipv6.h>
0037 #include <linux/nfs_xdr.h>
0038 #include <linux/sunrpc/bc_xprt.h>
0039 #include <linux/nsproxy.h>
0040 #include <linux/pid_namespace.h>
0041
0042
0043 #include "nfs4_fs.h"
0044 #include "callback.h"
0045 #include "delegation.h"
0046 #include "iostat.h"
0047 #include "internal.h"
0048 #include "fscache.h"
0049 #include "pnfs.h"
0050 #include "nfs.h"
0051 #include "netns.h"
0052 #include "sysfs.h"
0053 #include "nfs42.h"
0054
0055 #define NFSDBG_FACILITY NFSDBG_CLIENT
0056
0057 static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq);
0058 static DEFINE_SPINLOCK(nfs_version_lock);
0059 static DEFINE_MUTEX(nfs_version_mutex);
0060 static LIST_HEAD(nfs_versions);
0061
0062
0063
0064
0065 static const struct rpc_version *nfs_version[5] = {
0066 [2] = NULL,
0067 [3] = NULL,
0068 [4] = NULL,
0069 };
0070
0071 const struct rpc_program nfs_program = {
0072 .name = "nfs",
0073 .number = NFS_PROGRAM,
0074 .nrvers = ARRAY_SIZE(nfs_version),
0075 .version = nfs_version,
0076 .stats = &nfs_rpcstat,
0077 .pipe_dir_name = NFS_PIPE_DIRNAME,
0078 };
0079
0080 struct rpc_stat nfs_rpcstat = {
0081 .program = &nfs_program
0082 };
0083
0084 static struct nfs_subversion *find_nfs_version(unsigned int version)
0085 {
0086 struct nfs_subversion *nfs;
0087 spin_lock(&nfs_version_lock);
0088
0089 list_for_each_entry(nfs, &nfs_versions, list) {
0090 if (nfs->rpc_ops->version == version) {
0091 spin_unlock(&nfs_version_lock);
0092 return nfs;
0093 }
0094 }
0095
0096 spin_unlock(&nfs_version_lock);
0097 return ERR_PTR(-EPROTONOSUPPORT);
0098 }
0099
0100 struct nfs_subversion *get_nfs_version(unsigned int version)
0101 {
0102 struct nfs_subversion *nfs = find_nfs_version(version);
0103
0104 if (IS_ERR(nfs)) {
0105 mutex_lock(&nfs_version_mutex);
0106 request_module("nfsv%d", version);
0107 nfs = find_nfs_version(version);
0108 mutex_unlock(&nfs_version_mutex);
0109 }
0110
0111 if (!IS_ERR(nfs) && !try_module_get(nfs->owner))
0112 return ERR_PTR(-EAGAIN);
0113 return nfs;
0114 }
0115
0116 void put_nfs_version(struct nfs_subversion *nfs)
0117 {
0118 module_put(nfs->owner);
0119 }
0120
0121 void register_nfs_version(struct nfs_subversion *nfs)
0122 {
0123 spin_lock(&nfs_version_lock);
0124
0125 list_add(&nfs->list, &nfs_versions);
0126 nfs_version[nfs->rpc_ops->version] = nfs->rpc_vers;
0127
0128 spin_unlock(&nfs_version_lock);
0129 }
0130 EXPORT_SYMBOL_GPL(register_nfs_version);
0131
0132 void unregister_nfs_version(struct nfs_subversion *nfs)
0133 {
0134 spin_lock(&nfs_version_lock);
0135
0136 nfs_version[nfs->rpc_ops->version] = NULL;
0137 list_del(&nfs->list);
0138
0139 spin_unlock(&nfs_version_lock);
0140 }
0141 EXPORT_SYMBOL_GPL(unregister_nfs_version);
0142
0143
0144
0145
0146
0147
0148
0149 struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
0150 {
0151 struct nfs_client *clp;
0152 int err = -ENOMEM;
0153
0154 if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL)
0155 goto error_0;
0156
0157 clp->cl_minorversion = cl_init->minorversion;
0158 clp->cl_nfs_mod = cl_init->nfs_mod;
0159 if (!try_module_get(clp->cl_nfs_mod->owner))
0160 goto error_dealloc;
0161
0162 clp->rpc_ops = clp->cl_nfs_mod->rpc_ops;
0163
0164 refcount_set(&clp->cl_count, 1);
0165 clp->cl_cons_state = NFS_CS_INITING;
0166
0167 memcpy(&clp->cl_addr, cl_init->addr, cl_init->addrlen);
0168 clp->cl_addrlen = cl_init->addrlen;
0169
0170 if (cl_init->hostname) {
0171 err = -ENOMEM;
0172 clp->cl_hostname = kstrdup(cl_init->hostname, GFP_KERNEL);
0173 if (!clp->cl_hostname)
0174 goto error_cleanup;
0175 }
0176
0177 INIT_LIST_HEAD(&clp->cl_superblocks);
0178 clp->cl_rpcclient = ERR_PTR(-EINVAL);
0179
0180 clp->cl_flags = cl_init->init_flags;
0181 clp->cl_proto = cl_init->proto;
0182 clp->cl_nconnect = cl_init->nconnect;
0183 clp->cl_max_connect = cl_init->max_connect ? cl_init->max_connect : 1;
0184 clp->cl_net = get_net(cl_init->net);
0185
0186 clp->cl_principal = "*";
0187 return clp;
0188
0189 error_cleanup:
0190 put_nfs_version(clp->cl_nfs_mod);
0191 error_dealloc:
0192 kfree(clp);
0193 error_0:
0194 return ERR_PTR(err);
0195 }
0196 EXPORT_SYMBOL_GPL(nfs_alloc_client);
0197
0198 #if IS_ENABLED(CONFIG_NFS_V4)
0199 static void nfs_cleanup_cb_ident_idr(struct net *net)
0200 {
0201 struct nfs_net *nn = net_generic(net, nfs_net_id);
0202
0203 idr_destroy(&nn->cb_ident_idr);
0204 }
0205
0206
0207 static void nfs_cb_idr_remove_locked(struct nfs_client *clp)
0208 {
0209 struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id);
0210
0211 if (clp->cl_cb_ident)
0212 idr_remove(&nn->cb_ident_idr, clp->cl_cb_ident);
0213 }
0214
0215 static void pnfs_init_server(struct nfs_server *server)
0216 {
0217 rpc_init_wait_queue(&server->roc_rpcwaitq, "pNFS ROC");
0218 }
0219
0220 #else
0221 static void nfs_cleanup_cb_ident_idr(struct net *net)
0222 {
0223 }
0224
0225 static void nfs_cb_idr_remove_locked(struct nfs_client *clp)
0226 {
0227 }
0228
0229 static void pnfs_init_server(struct nfs_server *server)
0230 {
0231 }
0232
0233 #endif
0234
0235
0236
0237
0238 void nfs_free_client(struct nfs_client *clp)
0239 {
0240
0241 if (!IS_ERR(clp->cl_rpcclient))
0242 rpc_shutdown_client(clp->cl_rpcclient);
0243
0244 put_net(clp->cl_net);
0245 put_nfs_version(clp->cl_nfs_mod);
0246 kfree(clp->cl_hostname);
0247 kfree(clp->cl_acceptor);
0248 kfree(clp);
0249 }
0250 EXPORT_SYMBOL_GPL(nfs_free_client);
0251
0252
0253
0254
0255 void nfs_put_client(struct nfs_client *clp)
0256 {
0257 struct nfs_net *nn;
0258
0259 if (!clp)
0260 return;
0261
0262 nn = net_generic(clp->cl_net, nfs_net_id);
0263
0264 if (refcount_dec_and_lock(&clp->cl_count, &nn->nfs_client_lock)) {
0265 list_del(&clp->cl_share_link);
0266 nfs_cb_idr_remove_locked(clp);
0267 spin_unlock(&nn->nfs_client_lock);
0268
0269 WARN_ON_ONCE(!list_empty(&clp->cl_superblocks));
0270
0271 clp->rpc_ops->free_client(clp);
0272 }
0273 }
0274 EXPORT_SYMBOL_GPL(nfs_put_client);
0275
0276
0277
0278
0279
0280 static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *data)
0281 {
0282 struct nfs_client *clp;
0283 const struct sockaddr *sap = data->addr;
0284 struct nfs_net *nn = net_generic(data->net, nfs_net_id);
0285 int error;
0286
0287 again:
0288 list_for_each_entry(clp, &nn->nfs_client_list, cl_share_link) {
0289 const struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr;
0290
0291 if (clp->cl_cons_state < 0)
0292 continue;
0293
0294
0295 if (clp->cl_cons_state > NFS_CS_READY) {
0296 refcount_inc(&clp->cl_count);
0297 spin_unlock(&nn->nfs_client_lock);
0298 error = nfs_wait_client_init_complete(clp);
0299 nfs_put_client(clp);
0300 spin_lock(&nn->nfs_client_lock);
0301 if (error < 0)
0302 return ERR_PTR(error);
0303 goto again;
0304 }
0305
0306
0307 if (clp->rpc_ops != data->nfs_mod->rpc_ops)
0308 continue;
0309
0310 if (clp->cl_proto != data->proto)
0311 continue;
0312
0313 if (clp->cl_minorversion != data->minorversion)
0314 continue;
0315
0316
0317 if (test_bit(NFS_CS_DS, &data->init_flags) !=
0318 test_bit(NFS_CS_DS, &clp->cl_flags))
0319 continue;
0320
0321
0322 if (!rpc_cmp_addr_port(sap, clap))
0323
0324 if (IS_ERR(clp->cl_rpcclient) ||
0325 !rpc_clnt_xprt_switch_has_addr(clp->cl_rpcclient,
0326 sap))
0327 continue;
0328
0329 refcount_inc(&clp->cl_count);
0330 return clp;
0331 }
0332 return NULL;
0333 }
0334
0335
0336
0337
0338
0339
0340 bool nfs_client_init_is_complete(const struct nfs_client *clp)
0341 {
0342 return clp->cl_cons_state <= NFS_CS_READY;
0343 }
0344 EXPORT_SYMBOL_GPL(nfs_client_init_is_complete);
0345
0346
0347
0348
0349
0350
0351
0352 int nfs_client_init_status(const struct nfs_client *clp)
0353 {
0354
0355 if (clp->cl_cons_state > NFS_CS_READY) {
0356 WARN_ON_ONCE(1);
0357 return -EINVAL;
0358 }
0359 return clp->cl_cons_state;
0360 }
0361 EXPORT_SYMBOL_GPL(nfs_client_init_status);
0362
0363 int nfs_wait_client_init_complete(const struct nfs_client *clp)
0364 {
0365 return wait_event_killable(nfs_client_active_wq,
0366 nfs_client_init_is_complete(clp));
0367 }
0368 EXPORT_SYMBOL_GPL(nfs_wait_client_init_complete);
0369
0370
0371
0372
0373 static struct nfs_client *
0374 nfs_found_client(const struct nfs_client_initdata *cl_init,
0375 struct nfs_client *clp)
0376 {
0377 int error;
0378
0379 error = nfs_wait_client_init_complete(clp);
0380 if (error < 0) {
0381 nfs_put_client(clp);
0382 return ERR_PTR(-ERESTARTSYS);
0383 }
0384
0385 if (clp->cl_cons_state < NFS_CS_READY) {
0386 error = clp->cl_cons_state;
0387 nfs_put_client(clp);
0388 return ERR_PTR(error);
0389 }
0390
0391 smp_rmb();
0392 return clp;
0393 }
0394
0395
0396
0397
0398
0399 struct nfs_client *nfs_get_client(const struct nfs_client_initdata *cl_init)
0400 {
0401 struct nfs_client *clp, *new = NULL;
0402 struct nfs_net *nn = net_generic(cl_init->net, nfs_net_id);
0403 const struct nfs_rpc_ops *rpc_ops = cl_init->nfs_mod->rpc_ops;
0404
0405 if (cl_init->hostname == NULL) {
0406 WARN_ON(1);
0407 return ERR_PTR(-EINVAL);
0408 }
0409
0410
0411 do {
0412 spin_lock(&nn->nfs_client_lock);
0413
0414 clp = nfs_match_client(cl_init);
0415 if (clp) {
0416 spin_unlock(&nn->nfs_client_lock);
0417 if (new)
0418 new->rpc_ops->free_client(new);
0419 if (IS_ERR(clp))
0420 return clp;
0421 return nfs_found_client(cl_init, clp);
0422 }
0423 if (new) {
0424 list_add_tail(&new->cl_share_link,
0425 &nn->nfs_client_list);
0426 spin_unlock(&nn->nfs_client_lock);
0427 return rpc_ops->init_client(new, cl_init);
0428 }
0429
0430 spin_unlock(&nn->nfs_client_lock);
0431
0432 new = rpc_ops->alloc_client(cl_init);
0433 } while (!IS_ERR(new));
0434
0435 return new;
0436 }
0437 EXPORT_SYMBOL_GPL(nfs_get_client);
0438
0439
0440
0441
0442 void nfs_mark_client_ready(struct nfs_client *clp, int state)
0443 {
0444 smp_wmb();
0445 clp->cl_cons_state = state;
0446 wake_up_all(&nfs_client_active_wq);
0447 }
0448 EXPORT_SYMBOL_GPL(nfs_mark_client_ready);
0449
0450
0451
0452
0453 void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
0454 int timeo, int retrans)
0455 {
0456 to->to_initval = timeo * HZ / 10;
0457 to->to_retries = retrans;
0458
0459 switch (proto) {
0460 case XPRT_TRANSPORT_TCP:
0461 case XPRT_TRANSPORT_RDMA:
0462 if (retrans == NFS_UNSPEC_RETRANS)
0463 to->to_retries = NFS_DEF_TCP_RETRANS;
0464 if (timeo == NFS_UNSPEC_TIMEO || to->to_initval == 0)
0465 to->to_initval = NFS_DEF_TCP_TIMEO * HZ / 10;
0466 if (to->to_initval > NFS_MAX_TCP_TIMEOUT)
0467 to->to_initval = NFS_MAX_TCP_TIMEOUT;
0468 to->to_increment = to->to_initval;
0469 to->to_maxval = to->to_initval + (to->to_increment * to->to_retries);
0470 if (to->to_maxval > NFS_MAX_TCP_TIMEOUT)
0471 to->to_maxval = NFS_MAX_TCP_TIMEOUT;
0472 if (to->to_maxval < to->to_initval)
0473 to->to_maxval = to->to_initval;
0474 to->to_exponential = 0;
0475 break;
0476 case XPRT_TRANSPORT_UDP:
0477 if (retrans == NFS_UNSPEC_RETRANS)
0478 to->to_retries = NFS_DEF_UDP_RETRANS;
0479 if (timeo == NFS_UNSPEC_TIMEO || to->to_initval == 0)
0480 to->to_initval = NFS_DEF_UDP_TIMEO * HZ / 10;
0481 if (to->to_initval > NFS_MAX_UDP_TIMEOUT)
0482 to->to_initval = NFS_MAX_UDP_TIMEOUT;
0483 to->to_maxval = NFS_MAX_UDP_TIMEOUT;
0484 to->to_exponential = 1;
0485 break;
0486 default:
0487 BUG();
0488 }
0489 }
0490 EXPORT_SYMBOL_GPL(nfs_init_timeout_values);
0491
0492
0493
0494
0495 int nfs_create_rpc_client(struct nfs_client *clp,
0496 const struct nfs_client_initdata *cl_init,
0497 rpc_authflavor_t flavor)
0498 {
0499 struct rpc_clnt *clnt = NULL;
0500 struct rpc_create_args args = {
0501 .net = clp->cl_net,
0502 .protocol = clp->cl_proto,
0503 .nconnect = clp->cl_nconnect,
0504 .address = (struct sockaddr *)&clp->cl_addr,
0505 .addrsize = clp->cl_addrlen,
0506 .timeout = cl_init->timeparms,
0507 .servername = clp->cl_hostname,
0508 .nodename = cl_init->nodename,
0509 .program = &nfs_program,
0510 .version = clp->rpc_ops->version,
0511 .authflavor = flavor,
0512 .cred = cl_init->cred,
0513 };
0514
0515 if (test_bit(NFS_CS_DISCRTRY, &clp->cl_flags))
0516 args.flags |= RPC_CLNT_CREATE_DISCRTRY;
0517 if (test_bit(NFS_CS_NO_RETRANS_TIMEOUT, &clp->cl_flags))
0518 args.flags |= RPC_CLNT_CREATE_NO_RETRANS_TIMEOUT;
0519 if (test_bit(NFS_CS_NORESVPORT, &clp->cl_flags))
0520 args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
0521 if (test_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags))
0522 args.flags |= RPC_CLNT_CREATE_INFINITE_SLOTS;
0523 if (test_bit(NFS_CS_NOPING, &clp->cl_flags))
0524 args.flags |= RPC_CLNT_CREATE_NOPING;
0525 if (test_bit(NFS_CS_REUSEPORT, &clp->cl_flags))
0526 args.flags |= RPC_CLNT_CREATE_REUSEPORT;
0527
0528 if (!IS_ERR(clp->cl_rpcclient))
0529 return 0;
0530
0531 clnt = rpc_create(&args);
0532 if (IS_ERR(clnt)) {
0533 dprintk("%s: cannot create RPC client. Error = %ld\n",
0534 __func__, PTR_ERR(clnt));
0535 return PTR_ERR(clnt);
0536 }
0537
0538 clnt->cl_principal = clp->cl_principal;
0539 clp->cl_rpcclient = clnt;
0540 clnt->cl_max_connect = clp->cl_max_connect;
0541 return 0;
0542 }
0543 EXPORT_SYMBOL_GPL(nfs_create_rpc_client);
0544
0545
0546
0547
0548 static void nfs_destroy_server(struct nfs_server *server)
0549 {
0550 if (server->nlm_host)
0551 nlmclnt_done(server->nlm_host);
0552 }
0553
0554
0555
0556
0557 static int nfs_start_lockd(struct nfs_server *server)
0558 {
0559 struct nlm_host *host;
0560 struct nfs_client *clp = server->nfs_client;
0561 struct nlmclnt_initdata nlm_init = {
0562 .hostname = clp->cl_hostname,
0563 .address = (struct sockaddr *)&clp->cl_addr,
0564 .addrlen = clp->cl_addrlen,
0565 .nfs_version = clp->rpc_ops->version,
0566 .noresvport = server->flags & NFS_MOUNT_NORESVPORT ?
0567 1 : 0,
0568 .net = clp->cl_net,
0569 .nlmclnt_ops = clp->cl_nfs_mod->rpc_ops->nlmclnt_ops,
0570 .cred = server->cred,
0571 };
0572
0573 if (nlm_init.nfs_version > 3)
0574 return 0;
0575 if ((server->flags & NFS_MOUNT_LOCAL_FLOCK) &&
0576 (server->flags & NFS_MOUNT_LOCAL_FCNTL))
0577 return 0;
0578
0579 switch (clp->cl_proto) {
0580 default:
0581 nlm_init.protocol = IPPROTO_TCP;
0582 break;
0583 #ifndef CONFIG_NFS_DISABLE_UDP_SUPPORT
0584 case XPRT_TRANSPORT_UDP:
0585 nlm_init.protocol = IPPROTO_UDP;
0586 #endif
0587 }
0588
0589 host = nlmclnt_init(&nlm_init);
0590 if (IS_ERR(host))
0591 return PTR_ERR(host);
0592
0593 server->nlm_host = host;
0594 server->destroy = nfs_destroy_server;
0595 return 0;
0596 }
0597
0598
0599
0600
0601 int nfs_init_server_rpcclient(struct nfs_server *server,
0602 const struct rpc_timeout *timeo,
0603 rpc_authflavor_t pseudoflavour)
0604 {
0605 struct nfs_client *clp = server->nfs_client;
0606
0607 server->client = rpc_clone_client_set_auth(clp->cl_rpcclient,
0608 pseudoflavour);
0609 if (IS_ERR(server->client)) {
0610 dprintk("%s: couldn't create rpc_client!\n", __func__);
0611 return PTR_ERR(server->client);
0612 }
0613
0614 memcpy(&server->client->cl_timeout_default,
0615 timeo,
0616 sizeof(server->client->cl_timeout_default));
0617 server->client->cl_timeout = &server->client->cl_timeout_default;
0618 server->client->cl_softrtry = 0;
0619 if (server->flags & NFS_MOUNT_SOFTERR)
0620 server->client->cl_softerr = 1;
0621 if (server->flags & NFS_MOUNT_SOFT)
0622 server->client->cl_softrtry = 1;
0623
0624 return 0;
0625 }
0626 EXPORT_SYMBOL_GPL(nfs_init_server_rpcclient);
0627
0628
0629
0630
0631
0632
0633
0634
0635
0636 struct nfs_client *nfs_init_client(struct nfs_client *clp,
0637 const struct nfs_client_initdata *cl_init)
0638 {
0639 int error;
0640
0641
0642 if (clp->cl_cons_state == NFS_CS_READY)
0643 return clp;
0644
0645
0646
0647
0648
0649 error = nfs_create_rpc_client(clp, cl_init, RPC_AUTH_UNIX);
0650 nfs_mark_client_ready(clp, error == 0 ? NFS_CS_READY : error);
0651 if (error < 0) {
0652 nfs_put_client(clp);
0653 clp = ERR_PTR(error);
0654 }
0655 return clp;
0656 }
0657 EXPORT_SYMBOL_GPL(nfs_init_client);
0658
0659
0660
0661
0662 static int nfs_init_server(struct nfs_server *server,
0663 const struct fs_context *fc)
0664 {
0665 const struct nfs_fs_context *ctx = nfs_fc2context(fc);
0666 struct rpc_timeout timeparms;
0667 struct nfs_client_initdata cl_init = {
0668 .hostname = ctx->nfs_server.hostname,
0669 .addr = (const struct sockaddr *)&ctx->nfs_server.address,
0670 .addrlen = ctx->nfs_server.addrlen,
0671 .nfs_mod = ctx->nfs_mod,
0672 .proto = ctx->nfs_server.protocol,
0673 .net = fc->net_ns,
0674 .timeparms = &timeparms,
0675 .cred = server->cred,
0676 .nconnect = ctx->nfs_server.nconnect,
0677 .init_flags = (1UL << NFS_CS_REUSEPORT),
0678 };
0679 struct nfs_client *clp;
0680 int error;
0681
0682 nfs_init_timeout_values(&timeparms, ctx->nfs_server.protocol,
0683 ctx->timeo, ctx->retrans);
0684 if (ctx->flags & NFS_MOUNT_NORESVPORT)
0685 set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
0686
0687
0688 clp = nfs_get_client(&cl_init);
0689 if (IS_ERR(clp))
0690 return PTR_ERR(clp);
0691
0692 server->nfs_client = clp;
0693
0694
0695 server->flags = ctx->flags;
0696 server->options = ctx->options;
0697 server->caps |= NFS_CAP_HARDLINKS | NFS_CAP_SYMLINKS;
0698
0699 switch (clp->rpc_ops->version) {
0700 case 2:
0701 server->fattr_valid = NFS_ATTR_FATTR_V2;
0702 break;
0703 case 3:
0704 server->fattr_valid = NFS_ATTR_FATTR_V3;
0705 break;
0706 default:
0707 server->fattr_valid = NFS_ATTR_FATTR_V4;
0708 }
0709
0710 if (ctx->rsize)
0711 server->rsize = nfs_io_size(ctx->rsize, clp->cl_proto);
0712 if (ctx->wsize)
0713 server->wsize = nfs_io_size(ctx->wsize, clp->cl_proto);
0714
0715 server->acregmin = ctx->acregmin * HZ;
0716 server->acregmax = ctx->acregmax * HZ;
0717 server->acdirmin = ctx->acdirmin * HZ;
0718 server->acdirmax = ctx->acdirmax * HZ;
0719
0720
0721 error = nfs_start_lockd(server);
0722 if (error < 0)
0723 goto error;
0724
0725 server->port = ctx->nfs_server.port;
0726 server->auth_info = ctx->auth_info;
0727
0728 error = nfs_init_server_rpcclient(server, &timeparms,
0729 ctx->selected_flavor);
0730 if (error < 0)
0731 goto error;
0732
0733
0734 if (ctx->mount_server.addrlen) {
0735 memcpy(&server->mountd_address, &ctx->mount_server.address,
0736 ctx->mount_server.addrlen);
0737 server->mountd_addrlen = ctx->mount_server.addrlen;
0738 }
0739 server->mountd_version = ctx->mount_server.version;
0740 server->mountd_port = ctx->mount_server.port;
0741 server->mountd_protocol = ctx->mount_server.protocol;
0742
0743 server->namelen = ctx->namlen;
0744 return 0;
0745
0746 error:
0747 server->nfs_client = NULL;
0748 nfs_put_client(clp);
0749 return error;
0750 }
0751
0752
0753
0754
0755 static void nfs_server_set_fsinfo(struct nfs_server *server,
0756 struct nfs_fsinfo *fsinfo)
0757 {
0758 struct nfs_client *clp = server->nfs_client;
0759 unsigned long max_rpc_payload, raw_max_rpc_payload;
0760
0761
0762 if (server->rsize == 0)
0763 server->rsize = nfs_io_size(fsinfo->rtpref, clp->cl_proto);
0764 if (server->wsize == 0)
0765 server->wsize = nfs_io_size(fsinfo->wtpref, clp->cl_proto);
0766
0767 if (fsinfo->rtmax >= 512 && server->rsize > fsinfo->rtmax)
0768 server->rsize = nfs_io_size(fsinfo->rtmax, clp->cl_proto);
0769 if (fsinfo->wtmax >= 512 && server->wsize > fsinfo->wtmax)
0770 server->wsize = nfs_io_size(fsinfo->wtmax, clp->cl_proto);
0771
0772 raw_max_rpc_payload = rpc_max_payload(server->client);
0773 max_rpc_payload = nfs_block_size(raw_max_rpc_payload, NULL);
0774
0775 if (server->rsize > max_rpc_payload)
0776 server->rsize = max_rpc_payload;
0777 if (server->rsize > NFS_MAX_FILE_IO_SIZE)
0778 server->rsize = NFS_MAX_FILE_IO_SIZE;
0779 server->rpages = (server->rsize + PAGE_SIZE - 1) >> PAGE_SHIFT;
0780
0781 if (server->wsize > max_rpc_payload)
0782 server->wsize = max_rpc_payload;
0783 if (server->wsize > NFS_MAX_FILE_IO_SIZE)
0784 server->wsize = NFS_MAX_FILE_IO_SIZE;
0785 server->wpages = (server->wsize + PAGE_SIZE - 1) >> PAGE_SHIFT;
0786
0787 server->wtmult = nfs_block_bits(fsinfo->wtmult, NULL);
0788
0789 server->dtsize = nfs_block_size(fsinfo->dtpref, NULL);
0790 if (server->dtsize > NFS_MAX_FILE_IO_SIZE)
0791 server->dtsize = NFS_MAX_FILE_IO_SIZE;
0792 if (server->dtsize > server->rsize)
0793 server->dtsize = server->rsize;
0794
0795 if (server->flags & NFS_MOUNT_NOAC) {
0796 server->acregmin = server->acregmax = 0;
0797 server->acdirmin = server->acdirmax = 0;
0798 }
0799
0800 server->maxfilesize = fsinfo->maxfilesize;
0801
0802 server->time_delta = fsinfo->time_delta;
0803 server->change_attr_type = fsinfo->change_attr_type;
0804
0805 server->clone_blksize = fsinfo->clone_blksize;
0806
0807 rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
0808
0809 #ifdef CONFIG_NFS_V4_2
0810
0811
0812
0813 server->gxasize = min_t(unsigned int, raw_max_rpc_payload,
0814 XATTR_SIZE_MAX);
0815 server->sxasize = min_t(unsigned int, raw_max_rpc_payload,
0816 XATTR_SIZE_MAX);
0817 server->lxasize = min_t(unsigned int, raw_max_rpc_payload,
0818 nfs42_listxattr_xdrsize(XATTR_LIST_MAX));
0819
0820 if (fsinfo->xattr_support)
0821 server->caps |= NFS_CAP_XATTR;
0822 #endif
0823 }
0824
0825
0826
0827
0828 static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs_fattr *fattr)
0829 {
0830 struct nfs_fsinfo fsinfo;
0831 struct nfs_client *clp = server->nfs_client;
0832 int error;
0833
0834 if (clp->rpc_ops->set_capabilities != NULL) {
0835 error = clp->rpc_ops->set_capabilities(server, mntfh);
0836 if (error < 0)
0837 return error;
0838 }
0839
0840 fsinfo.fattr = fattr;
0841 fsinfo.nlayouttypes = 0;
0842 memset(fsinfo.layouttype, 0, sizeof(fsinfo.layouttype));
0843 error = clp->rpc_ops->fsinfo(server, mntfh, &fsinfo);
0844 if (error < 0)
0845 return error;
0846
0847 nfs_server_set_fsinfo(server, &fsinfo);
0848
0849
0850 if (server->namelen == 0) {
0851 struct nfs_pathconf pathinfo;
0852
0853 pathinfo.fattr = fattr;
0854 nfs_fattr_init(fattr);
0855
0856 if (clp->rpc_ops->pathconf(server, mntfh, &pathinfo) >= 0)
0857 server->namelen = pathinfo.max_namelen;
0858 }
0859
0860 if (clp->rpc_ops->discover_trunking != NULL &&
0861 (server->caps & NFS_CAP_FS_LOCATIONS &&
0862 (server->flags & NFS_MOUNT_TRUNK_DISCOVERY))) {
0863 error = clp->rpc_ops->discover_trunking(server, mntfh);
0864 if (error < 0)
0865 return error;
0866 }
0867
0868 return 0;
0869 }
0870
0871
0872
0873
0874
0875
0876
0877 int nfs_probe_server(struct nfs_server *server, struct nfs_fh *mntfh)
0878 {
0879 struct nfs_fattr *fattr;
0880 int error;
0881
0882 fattr = nfs_alloc_fattr();
0883 if (fattr == NULL)
0884 return -ENOMEM;
0885
0886
0887
0888 error = nfs_probe_fsinfo(server, mntfh, fattr);
0889
0890 nfs_free_fattr(fattr);
0891 return error;
0892 }
0893 EXPORT_SYMBOL_GPL(nfs_probe_server);
0894
0895
0896
0897
0898 void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source)
0899 {
0900 target->flags = source->flags;
0901 target->rsize = source->rsize;
0902 target->wsize = source->wsize;
0903 target->acregmin = source->acregmin;
0904 target->acregmax = source->acregmax;
0905 target->acdirmin = source->acdirmin;
0906 target->acdirmax = source->acdirmax;
0907 target->caps = source->caps;
0908 target->options = source->options;
0909 target->auth_info = source->auth_info;
0910 target->port = source->port;
0911 }
0912 EXPORT_SYMBOL_GPL(nfs_server_copy_userdata);
0913
0914 void nfs_server_insert_lists(struct nfs_server *server)
0915 {
0916 struct nfs_client *clp = server->nfs_client;
0917 struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id);
0918
0919 spin_lock(&nn->nfs_client_lock);
0920 list_add_tail_rcu(&server->client_link, &clp->cl_superblocks);
0921 list_add_tail(&server->master_link, &nn->nfs_volume_list);
0922 clear_bit(NFS_CS_STOP_RENEW, &clp->cl_res_state);
0923 spin_unlock(&nn->nfs_client_lock);
0924
0925 }
0926 EXPORT_SYMBOL_GPL(nfs_server_insert_lists);
0927
0928 void nfs_server_remove_lists(struct nfs_server *server)
0929 {
0930 struct nfs_client *clp = server->nfs_client;
0931 struct nfs_net *nn;
0932
0933 if (clp == NULL)
0934 return;
0935 nn = net_generic(clp->cl_net, nfs_net_id);
0936 spin_lock(&nn->nfs_client_lock);
0937 list_del_rcu(&server->client_link);
0938 if (list_empty(&clp->cl_superblocks))
0939 set_bit(NFS_CS_STOP_RENEW, &clp->cl_res_state);
0940 list_del(&server->master_link);
0941 spin_unlock(&nn->nfs_client_lock);
0942
0943 synchronize_rcu();
0944 }
0945 EXPORT_SYMBOL_GPL(nfs_server_remove_lists);
0946
0947
0948
0949
0950 struct nfs_server *nfs_alloc_server(void)
0951 {
0952 struct nfs_server *server;
0953
0954 server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL);
0955 if (!server)
0956 return NULL;
0957
0958 server->client = server->client_acl = ERR_PTR(-EINVAL);
0959
0960
0961 INIT_LIST_HEAD(&server->client_link);
0962 INIT_LIST_HEAD(&server->master_link);
0963 INIT_LIST_HEAD(&server->delegations);
0964 INIT_LIST_HEAD(&server->layouts);
0965 INIT_LIST_HEAD(&server->state_owners_lru);
0966 INIT_LIST_HEAD(&server->ss_copies);
0967
0968 atomic_set(&server->active, 0);
0969
0970 server->io_stats = nfs_alloc_iostats();
0971 if (!server->io_stats) {
0972 kfree(server);
0973 return NULL;
0974 }
0975
0976 server->change_attr_type = NFS4_CHANGE_TYPE_IS_UNDEFINED;
0977
0978 ida_init(&server->openowner_id);
0979 ida_init(&server->lockowner_id);
0980 pnfs_init_server(server);
0981 rpc_init_wait_queue(&server->uoc_rpcwaitq, "NFS UOC");
0982
0983 return server;
0984 }
0985 EXPORT_SYMBOL_GPL(nfs_alloc_server);
0986
0987
0988
0989
0990 void nfs_free_server(struct nfs_server *server)
0991 {
0992 nfs_server_remove_lists(server);
0993
0994 if (server->destroy != NULL)
0995 server->destroy(server);
0996
0997 if (!IS_ERR(server->client_acl))
0998 rpc_shutdown_client(server->client_acl);
0999 if (!IS_ERR(server->client))
1000 rpc_shutdown_client(server->client);
1001
1002 nfs_put_client(server->nfs_client);
1003
1004 ida_destroy(&server->lockowner_id);
1005 ida_destroy(&server->openowner_id);
1006 nfs_free_iostats(server->io_stats);
1007 put_cred(server->cred);
1008 kfree(server);
1009 nfs_release_automount_timer();
1010 }
1011 EXPORT_SYMBOL_GPL(nfs_free_server);
1012
1013
1014
1015
1016
1017 struct nfs_server *nfs_create_server(struct fs_context *fc)
1018 {
1019 struct nfs_fs_context *ctx = nfs_fc2context(fc);
1020 struct nfs_server *server;
1021 struct nfs_fattr *fattr;
1022 int error;
1023
1024 server = nfs_alloc_server();
1025 if (!server)
1026 return ERR_PTR(-ENOMEM);
1027
1028 server->cred = get_cred(fc->cred);
1029
1030 error = -ENOMEM;
1031 fattr = nfs_alloc_fattr();
1032 if (fattr == NULL)
1033 goto error;
1034
1035
1036 error = nfs_init_server(server, fc);
1037 if (error < 0)
1038 goto error;
1039
1040
1041 error = nfs_probe_fsinfo(server, ctx->mntfh, fattr);
1042 if (error < 0)
1043 goto error;
1044 if (server->nfs_client->rpc_ops->version == 3) {
1045 if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
1046 server->namelen = NFS3_MAXNAMLEN;
1047 if (!(ctx->flags & NFS_MOUNT_NORDIRPLUS))
1048 server->caps |= NFS_CAP_READDIRPLUS;
1049 } else {
1050 if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
1051 server->namelen = NFS2_MAXNAMLEN;
1052 }
1053
1054 if (!(fattr->valid & NFS_ATTR_FATTR)) {
1055 error = ctx->nfs_mod->rpc_ops->getattr(server, ctx->mntfh,
1056 fattr, NULL);
1057 if (error < 0) {
1058 dprintk("nfs_create_server: getattr error = %d\n", -error);
1059 goto error;
1060 }
1061 }
1062 memcpy(&server->fsid, &fattr->fsid, sizeof(server->fsid));
1063
1064 dprintk("Server FSID: %llx:%llx\n",
1065 (unsigned long long) server->fsid.major,
1066 (unsigned long long) server->fsid.minor);
1067
1068 nfs_server_insert_lists(server);
1069 server->mount_time = jiffies;
1070 nfs_free_fattr(fattr);
1071 return server;
1072
1073 error:
1074 nfs_free_fattr(fattr);
1075 nfs_free_server(server);
1076 return ERR_PTR(error);
1077 }
1078 EXPORT_SYMBOL_GPL(nfs_create_server);
1079
1080
1081
1082
1083 struct nfs_server *nfs_clone_server(struct nfs_server *source,
1084 struct nfs_fh *fh,
1085 struct nfs_fattr *fattr,
1086 rpc_authflavor_t flavor)
1087 {
1088 struct nfs_server *server;
1089 int error;
1090
1091 server = nfs_alloc_server();
1092 if (!server)
1093 return ERR_PTR(-ENOMEM);
1094
1095 server->cred = get_cred(source->cred);
1096
1097
1098 server->nfs_client = source->nfs_client;
1099 server->destroy = source->destroy;
1100 refcount_inc(&server->nfs_client->cl_count);
1101 nfs_server_copy_userdata(server, source);
1102
1103 server->fsid = fattr->fsid;
1104
1105 error = nfs_init_server_rpcclient(server,
1106 source->client->cl_timeout,
1107 flavor);
1108 if (error < 0)
1109 goto out_free_server;
1110
1111
1112 error = nfs_probe_server(server, fh);
1113 if (error < 0)
1114 goto out_free_server;
1115
1116 if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
1117 server->namelen = NFS4_MAXNAMLEN;
1118
1119 error = nfs_start_lockd(server);
1120 if (error < 0)
1121 goto out_free_server;
1122
1123 nfs_server_insert_lists(server);
1124 server->mount_time = jiffies;
1125
1126 return server;
1127
1128 out_free_server:
1129 nfs_free_server(server);
1130 return ERR_PTR(error);
1131 }
1132 EXPORT_SYMBOL_GPL(nfs_clone_server);
1133
1134 void nfs_clients_init(struct net *net)
1135 {
1136 struct nfs_net *nn = net_generic(net, nfs_net_id);
1137
1138 INIT_LIST_HEAD(&nn->nfs_client_list);
1139 INIT_LIST_HEAD(&nn->nfs_volume_list);
1140 #if IS_ENABLED(CONFIG_NFS_V4)
1141 idr_init(&nn->cb_ident_idr);
1142 #endif
1143 spin_lock_init(&nn->nfs_client_lock);
1144 nn->boot_time = ktime_get_real();
1145
1146 nfs_netns_sysfs_setup(nn, net);
1147 }
1148
1149 void nfs_clients_exit(struct net *net)
1150 {
1151 struct nfs_net *nn = net_generic(net, nfs_net_id);
1152
1153 nfs_netns_sysfs_destroy(nn);
1154 nfs_cleanup_cb_ident_idr(net);
1155 WARN_ON_ONCE(!list_empty(&nn->nfs_client_list));
1156 WARN_ON_ONCE(!list_empty(&nn->nfs_volume_list));
1157 }
1158
1159 #ifdef CONFIG_PROC_FS
1160 static void *nfs_server_list_start(struct seq_file *p, loff_t *pos);
1161 static void *nfs_server_list_next(struct seq_file *p, void *v, loff_t *pos);
1162 static void nfs_server_list_stop(struct seq_file *p, void *v);
1163 static int nfs_server_list_show(struct seq_file *m, void *v);
1164
1165 static const struct seq_operations nfs_server_list_ops = {
1166 .start = nfs_server_list_start,
1167 .next = nfs_server_list_next,
1168 .stop = nfs_server_list_stop,
1169 .show = nfs_server_list_show,
1170 };
1171
1172 static void *nfs_volume_list_start(struct seq_file *p, loff_t *pos);
1173 static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos);
1174 static void nfs_volume_list_stop(struct seq_file *p, void *v);
1175 static int nfs_volume_list_show(struct seq_file *m, void *v);
1176
1177 static const struct seq_operations nfs_volume_list_ops = {
1178 .start = nfs_volume_list_start,
1179 .next = nfs_volume_list_next,
1180 .stop = nfs_volume_list_stop,
1181 .show = nfs_volume_list_show,
1182 };
1183
1184
1185
1186
1187 static void *nfs_server_list_start(struct seq_file *m, loff_t *_pos)
1188 __acquires(&nn->nfs_client_lock)
1189 {
1190 struct nfs_net *nn = net_generic(seq_file_net(m), nfs_net_id);
1191
1192
1193 spin_lock(&nn->nfs_client_lock);
1194 return seq_list_start_head(&nn->nfs_client_list, *_pos);
1195 }
1196
1197
1198
1199
1200 static void *nfs_server_list_next(struct seq_file *p, void *v, loff_t *pos)
1201 {
1202 struct nfs_net *nn = net_generic(seq_file_net(p), nfs_net_id);
1203
1204 return seq_list_next(v, &nn->nfs_client_list, pos);
1205 }
1206
1207
1208
1209
1210 static void nfs_server_list_stop(struct seq_file *p, void *v)
1211 __releases(&nn->nfs_client_lock)
1212 {
1213 struct nfs_net *nn = net_generic(seq_file_net(p), nfs_net_id);
1214
1215 spin_unlock(&nn->nfs_client_lock);
1216 }
1217
1218
1219
1220
1221 static int nfs_server_list_show(struct seq_file *m, void *v)
1222 {
1223 struct nfs_client *clp;
1224 struct nfs_net *nn = net_generic(seq_file_net(m), nfs_net_id);
1225
1226
1227 if (v == &nn->nfs_client_list) {
1228 seq_puts(m, "NV SERVER PORT USE HOSTNAME\n");
1229 return 0;
1230 }
1231
1232
1233 clp = list_entry(v, struct nfs_client, cl_share_link);
1234
1235
1236 if (clp->cl_cons_state != NFS_CS_READY)
1237 return 0;
1238
1239 rcu_read_lock();
1240 seq_printf(m, "v%u %s %s %3d %s\n",
1241 clp->rpc_ops->version,
1242 rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR),
1243 rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_PORT),
1244 refcount_read(&clp->cl_count),
1245 clp->cl_hostname);
1246 rcu_read_unlock();
1247
1248 return 0;
1249 }
1250
1251
1252
1253
1254 static void *nfs_volume_list_start(struct seq_file *m, loff_t *_pos)
1255 __acquires(&nn->nfs_client_lock)
1256 {
1257 struct nfs_net *nn = net_generic(seq_file_net(m), nfs_net_id);
1258
1259
1260 spin_lock(&nn->nfs_client_lock);
1261 return seq_list_start_head(&nn->nfs_volume_list, *_pos);
1262 }
1263
1264
1265
1266
1267 static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos)
1268 {
1269 struct nfs_net *nn = net_generic(seq_file_net(p), nfs_net_id);
1270
1271 return seq_list_next(v, &nn->nfs_volume_list, pos);
1272 }
1273
1274
1275
1276
1277 static void nfs_volume_list_stop(struct seq_file *p, void *v)
1278 __releases(&nn->nfs_client_lock)
1279 {
1280 struct nfs_net *nn = net_generic(seq_file_net(p), nfs_net_id);
1281
1282 spin_unlock(&nn->nfs_client_lock);
1283 }
1284
1285
1286
1287
1288 static int nfs_volume_list_show(struct seq_file *m, void *v)
1289 {
1290 struct nfs_server *server;
1291 struct nfs_client *clp;
1292 char dev[13];
1293 char fsid[34];
1294 struct nfs_net *nn = net_generic(seq_file_net(m), nfs_net_id);
1295
1296
1297 if (v == &nn->nfs_volume_list) {
1298 seq_puts(m, "NV SERVER PORT DEV FSID"
1299 " FSC\n");
1300 return 0;
1301 }
1302
1303 server = list_entry(v, struct nfs_server, master_link);
1304 clp = server->nfs_client;
1305
1306 snprintf(dev, sizeof(dev), "%u:%u",
1307 MAJOR(server->s_dev), MINOR(server->s_dev));
1308
1309 snprintf(fsid, sizeof(fsid), "%llx:%llx",
1310 (unsigned long long) server->fsid.major,
1311 (unsigned long long) server->fsid.minor);
1312
1313 rcu_read_lock();
1314 seq_printf(m, "v%u %s %s %-12s %-33s %s\n",
1315 clp->rpc_ops->version,
1316 rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR),
1317 rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_PORT),
1318 dev,
1319 fsid,
1320 nfs_server_fscache_state(server));
1321 rcu_read_unlock();
1322
1323 return 0;
1324 }
1325
1326 int nfs_fs_proc_net_init(struct net *net)
1327 {
1328 struct nfs_net *nn = net_generic(net, nfs_net_id);
1329 struct proc_dir_entry *p;
1330
1331 nn->proc_nfsfs = proc_net_mkdir(net, "nfsfs", net->proc_net);
1332 if (!nn->proc_nfsfs)
1333 goto error_0;
1334
1335
1336 p = proc_create_net("servers", S_IFREG|S_IRUGO, nn->proc_nfsfs,
1337 &nfs_server_list_ops, sizeof(struct seq_net_private));
1338 if (!p)
1339 goto error_1;
1340
1341
1342 p = proc_create_net("volumes", S_IFREG|S_IRUGO, nn->proc_nfsfs,
1343 &nfs_volume_list_ops, sizeof(struct seq_net_private));
1344 if (!p)
1345 goto error_1;
1346 return 0;
1347
1348 error_1:
1349 remove_proc_subtree("nfsfs", net->proc_net);
1350 error_0:
1351 return -ENOMEM;
1352 }
1353
1354 void nfs_fs_proc_net_exit(struct net *net)
1355 {
1356 remove_proc_subtree("nfsfs", net->proc_net);
1357 }
1358
1359
1360
1361
1362 int __init nfs_fs_proc_init(void)
1363 {
1364 if (!proc_mkdir("fs/nfsfs", NULL))
1365 goto error_0;
1366
1367
1368 if (!proc_symlink("fs/nfsfs/servers", NULL, "../../net/nfsfs/servers"))
1369 goto error_1;
1370
1371
1372 if (!proc_symlink("fs/nfsfs/volumes", NULL, "../../net/nfsfs/volumes"))
1373 goto error_1;
1374
1375 return 0;
1376 error_1:
1377 remove_proc_subtree("fs/nfsfs", NULL);
1378 error_0:
1379 return -ENOMEM;
1380 }
1381
1382
1383
1384
1385 void nfs_fs_proc_exit(void)
1386 {
1387 remove_proc_subtree("fs/nfsfs", NULL);
1388 }
1389
1390 #endif