diff options
Diffstat (limited to 'fs/nfs/super.c')
-rw-r--r-- | fs/nfs/super.c | 222 |
1 files changed, 51 insertions, 171 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index e1e5eab0259b..85583414a3ca 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -60,52 +60,6 @@ | |||
60 | */ | 60 | */ |
61 | #define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1) | 61 | #define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1) |
62 | 62 | ||
63 | /* | ||
64 | * RPC cruft for NFS | ||
65 | */ | ||
66 | static struct rpc_version * nfs_version[] = { | ||
67 | NULL, | ||
68 | NULL, | ||
69 | &nfs_version2, | ||
70 | #if defined(CONFIG_NFS_V3) | ||
71 | &nfs_version3, | ||
72 | #elif defined(CONFIG_NFS_V4) | ||
73 | NULL, | ||
74 | #endif | ||
75 | #if defined(CONFIG_NFS_V4) | ||
76 | &nfs_version4, | ||
77 | #endif | ||
78 | }; | ||
79 | |||
80 | static struct rpc_program nfs_program = { | ||
81 | .name = "nfs", | ||
82 | .number = NFS_PROGRAM, | ||
83 | .nrvers = ARRAY_SIZE(nfs_version), | ||
84 | .version = nfs_version, | ||
85 | .stats = &nfs_rpcstat, | ||
86 | .pipe_dir_name = "/nfs", | ||
87 | }; | ||
88 | |||
89 | struct rpc_stat nfs_rpcstat = { | ||
90 | .program = &nfs_program | ||
91 | }; | ||
92 | |||
93 | |||
94 | #ifdef CONFIG_NFS_V3_ACL | ||
95 | static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program }; | ||
96 | static struct rpc_version * nfsacl_version[] = { | ||
97 | [3] = &nfsacl_version3, | ||
98 | }; | ||
99 | |||
100 | struct rpc_program nfsacl_program = { | ||
101 | .name = "nfsacl", | ||
102 | .number = NFS_ACL_PROGRAM, | ||
103 | .nrvers = ARRAY_SIZE(nfsacl_version), | ||
104 | .version = nfsacl_version, | ||
105 | .stats = &nfsacl_rpcstat, | ||
106 | }; | ||
107 | #endif /* CONFIG_NFS_V3_ACL */ | ||
108 | |||
109 | static void nfs_umount_begin(struct vfsmount *, int); | 63 | static void nfs_umount_begin(struct vfsmount *, int); |
110 | static int nfs_statfs(struct dentry *, struct kstatfs *); | 64 | static int nfs_statfs(struct dentry *, struct kstatfs *); |
111 | static int nfs_show_options(struct seq_file *, struct vfsmount *); | 65 | static int nfs_show_options(struct seq_file *, struct vfsmount *); |
@@ -376,8 +330,8 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, | |||
376 | proto = buf; | 330 | proto = buf; |
377 | } | 331 | } |
378 | seq_printf(m, ",proto=%s", proto); | 332 | seq_printf(m, ",proto=%s", proto); |
379 | seq_printf(m, ",timeo=%lu", 10U * nfss->retrans_timeo / HZ); | 333 | seq_printf(m, ",timeo=%lu", 10U * clp->retrans_timeo / HZ); |
380 | seq_printf(m, ",retrans=%u", nfss->retrans_count); | 334 | seq_printf(m, ",retrans=%u", clp->retrans_count); |
381 | seq_printf(m, ",sec=%s", nfs_pseudoflavour_to_name(nfss->client->cl_auth->au_flavor)); | 335 | seq_printf(m, ",sec=%s", nfs_pseudoflavour_to_name(nfss->client->cl_auth->au_flavor)); |
382 | } | 336 | } |
383 | 337 | ||
@@ -622,49 +576,16 @@ out_no_root: | |||
622 | } | 576 | } |
623 | 577 | ||
624 | /* | 578 | /* |
625 | * Initialise the timeout values for a connection | ||
626 | */ | ||
627 | static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, unsigned int timeo, unsigned int retrans) | ||
628 | { | ||
629 | to->to_initval = timeo * HZ / 10; | ||
630 | to->to_retries = retrans; | ||
631 | if (!to->to_retries) | ||
632 | to->to_retries = 2; | ||
633 | |||
634 | switch (proto) { | ||
635 | case IPPROTO_TCP: | ||
636 | if (!to->to_initval) | ||
637 | to->to_initval = 60 * HZ; | ||
638 | if (to->to_initval > NFS_MAX_TCP_TIMEOUT) | ||
639 | to->to_initval = NFS_MAX_TCP_TIMEOUT; | ||
640 | to->to_increment = to->to_initval; | ||
641 | to->to_maxval = to->to_initval + (to->to_increment * to->to_retries); | ||
642 | to->to_exponential = 0; | ||
643 | break; | ||
644 | case IPPROTO_UDP: | ||
645 | default: | ||
646 | if (!to->to_initval) | ||
647 | to->to_initval = 11 * HZ / 10; | ||
648 | if (to->to_initval > NFS_MAX_UDP_TIMEOUT) | ||
649 | to->to_initval = NFS_MAX_UDP_TIMEOUT; | ||
650 | to->to_maxval = NFS_MAX_UDP_TIMEOUT; | ||
651 | to->to_exponential = 1; | ||
652 | break; | ||
653 | } | ||
654 | } | ||
655 | |||
656 | /* | ||
657 | * Create an RPC client handle. | 579 | * Create an RPC client handle. |
658 | */ | 580 | */ |
659 | static struct rpc_clnt * | 581 | static struct rpc_clnt * |
660 | nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data) | 582 | nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data) |
661 | { | 583 | { |
662 | struct nfs_client *clp; | 584 | struct nfs_client *clp; |
663 | struct rpc_timeout timeparms; | 585 | struct rpc_clnt *clnt; |
664 | struct rpc_xprt *xprt = NULL; | ||
665 | struct rpc_clnt *clnt = NULL; | ||
666 | int proto = (data->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP; | 586 | int proto = (data->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP; |
667 | int nfsversion = 2; | 587 | int nfsversion = 2; |
588 | int err; | ||
668 | 589 | ||
669 | #ifdef CONFIG_NFS_V3 | 590 | #ifdef CONFIG_NFS_V3 |
670 | if (server->flags & NFS_MOUNT_VER3) | 591 | if (server->flags & NFS_MOUNT_VER3) |
@@ -677,52 +598,54 @@ nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data) | |||
677 | return ERR_PTR(PTR_ERR(clp)); | 598 | return ERR_PTR(PTR_ERR(clp)); |
678 | } | 599 | } |
679 | 600 | ||
680 | nfs_init_timeout_values(&timeparms, proto, data->timeo, data->retrans); | 601 | if (clp->cl_cons_state == NFS_CS_INITING) { |
681 | 602 | /* Check NFS protocol revision and initialize RPC op | |
682 | server->retrans_timeo = timeparms.to_initval; | 603 | * vector and file handle pool. */ |
683 | server->retrans_count = timeparms.to_retries; | ||
684 | |||
685 | /* Check NFS protocol revision and initialize RPC op vector | ||
686 | * and file handle pool. */ | ||
687 | #ifdef CONFIG_NFS_V3 | 604 | #ifdef CONFIG_NFS_V3 |
688 | if (nfsversion == 3) { | 605 | if (nfsversion == 3) { |
689 | clp->rpc_ops = &nfs_v3_clientops; | 606 | clp->rpc_ops = &nfs_v3_clientops; |
690 | server->caps |= NFS_CAP_READDIRPLUS; | 607 | server->caps |= NFS_CAP_READDIRPLUS; |
691 | } else { | 608 | } else { |
692 | clp->rpc_ops = &nfs_v2_clientops; | 609 | clp->rpc_ops = &nfs_v2_clientops; |
693 | } | 610 | } |
694 | #else | 611 | #else |
695 | clp->rpc_ops = &nfs_v2_clientops; | 612 | clp->rpc_ops = &nfs_v2_clientops; |
696 | #endif | 613 | #endif |
697 | 614 | ||
698 | /* create transport and client */ | 615 | /* create transport and client */ |
699 | xprt = xprt_create_proto(proto, &server->addr, &timeparms); | 616 | err = nfs_create_rpc_client(clp, proto, data->timeo, |
700 | if (IS_ERR(xprt)) { | 617 | data->retrans, RPC_AUTH_UNIX); |
701 | dprintk("%s: cannot create RPC transport. Error = %ld\n", | 618 | if (err < 0) |
702 | __FUNCTION__, PTR_ERR(xprt)); | 619 | goto client_init_error; |
703 | nfs_mark_client_ready(clp, PTR_ERR(xprt)); | 620 | |
704 | nfs_put_client(clp); | 621 | nfs_mark_client_ready(clp, 0); |
705 | return (struct rpc_clnt *)xprt; | ||
706 | } | 622 | } |
707 | clnt = rpc_create_client(xprt, server->hostname, &nfs_program, | 623 | |
708 | clp->cl_nfsversion, data->pseudoflavor); | 624 | /* create an nfs_server-specific client */ |
625 | clnt = rpc_clone_client(clp->cl_rpcclient); | ||
709 | if (IS_ERR(clnt)) { | 626 | if (IS_ERR(clnt)) { |
710 | dprintk("%s: cannot create RPC client. Error = %ld\n", | 627 | dprintk("%s: couldn't create rpc_client!\n", __FUNCTION__); |
711 | __FUNCTION__, PTR_ERR(xprt)); | 628 | nfs_put_client(clp); |
712 | goto out_fail; | 629 | return ERR_PTR(PTR_ERR(clnt)); |
713 | } | 630 | } |
714 | 631 | ||
715 | clnt->cl_intr = 1; | 632 | if (data->pseudoflavor != clp->cl_rpcclient->cl_auth->au_flavor) { |
716 | clnt->cl_softrtry = 1; | 633 | struct rpc_auth *auth; |
634 | |||
635 | auth = rpcauth_create(data->pseudoflavor, server->client); | ||
636 | if (IS_ERR(auth)) { | ||
637 | dprintk("%s: couldn't create credcache!\n", __FUNCTION__); | ||
638 | return ERR_PTR(PTR_ERR(auth)); | ||
639 | } | ||
640 | } | ||
717 | 641 | ||
718 | nfs_mark_client_ready(clp, 0); | ||
719 | server->nfs_client = clp; | 642 | server->nfs_client = clp; |
720 | return clnt; | 643 | return clnt; |
721 | 644 | ||
722 | out_fail: | 645 | client_init_error: |
723 | nfs_mark_client_ready(clp, PTR_ERR(xprt)); | 646 | nfs_mark_client_ready(clp, err); |
724 | nfs_put_client(clp); | 647 | nfs_put_client(clp); |
725 | return clnt; | 648 | return ERR_PTR(err); |
726 | } | 649 | } |
727 | 650 | ||
728 | /* | 651 | /* |
@@ -741,7 +664,7 @@ static struct nfs_server *nfs_clone_server(struct super_block *sb, struct nfs_cl | |||
741 | sb->s_blocksize_bits = data->sb->s_blocksize_bits; | 664 | sb->s_blocksize_bits = data->sb->s_blocksize_bits; |
742 | sb->s_maxbytes = data->sb->s_maxbytes; | 665 | sb->s_maxbytes = data->sb->s_maxbytes; |
743 | 666 | ||
744 | server->client_sys = server->client_acl = ERR_PTR(-EINVAL); | 667 | server->client_acl = ERR_PTR(-EINVAL); |
745 | server->io_stats = nfs_alloc_iostats(); | 668 | server->io_stats = nfs_alloc_iostats(); |
746 | if (server->io_stats == NULL) | 669 | if (server->io_stats == NULL) |
747 | goto out; | 670 | goto out; |
@@ -750,11 +673,6 @@ static struct nfs_server *nfs_clone_server(struct super_block *sb, struct nfs_cl | |||
750 | if (IS_ERR((err = server->client))) | 673 | if (IS_ERR((err = server->client))) |
751 | goto out; | 674 | goto out; |
752 | 675 | ||
753 | if (!IS_ERR(parent->client_sys)) { | ||
754 | server->client_sys = rpc_clone_client(parent->client_sys); | ||
755 | if (IS_ERR((err = server->client_sys))) | ||
756 | goto out; | ||
757 | } | ||
758 | if (!IS_ERR(parent->client_acl)) { | 676 | if (!IS_ERR(parent->client_acl)) { |
759 | server->client_acl = rpc_clone_client(parent->client_acl); | 677 | server->client_acl = rpc_clone_client(parent->client_acl); |
760 | if (IS_ERR((err = server->client_acl))) | 678 | if (IS_ERR((err = server->client_acl))) |
@@ -813,7 +731,7 @@ static int nfs_clone_generic_sb(struct nfs_clone_mount *data, | |||
813 | error = PTR_ERR(sb); | 731 | error = PTR_ERR(sb); |
814 | goto kill_rpciod; | 732 | goto kill_rpciod; |
815 | } | 733 | } |
816 | 734 | ||
817 | if (sb->s_root) | 735 | if (sb->s_root) |
818 | goto out_rpciod_down; | 736 | goto out_rpciod_down; |
819 | 737 | ||
@@ -896,19 +814,6 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent) | |||
896 | return PTR_ERR(server->client); | 814 | return PTR_ERR(server->client); |
897 | 815 | ||
898 | /* RFC 2623, sec 2.3.2 */ | 816 | /* RFC 2623, sec 2.3.2 */ |
899 | if (authflavor != RPC_AUTH_UNIX) { | ||
900 | struct rpc_auth *auth; | ||
901 | |||
902 | server->client_sys = rpc_clone_client(server->client); | ||
903 | if (IS_ERR(server->client_sys)) | ||
904 | return PTR_ERR(server->client_sys); | ||
905 | auth = rpcauth_create(RPC_AUTH_UNIX, server->client_sys); | ||
906 | if (IS_ERR(auth)) | ||
907 | return PTR_ERR(auth); | ||
908 | } else { | ||
909 | atomic_inc(&server->client->cl_count); | ||
910 | server->client_sys = server->client; | ||
911 | } | ||
912 | if (server->flags & NFS_MOUNT_VER3) { | 817 | if (server->flags & NFS_MOUNT_VER3) { |
913 | #ifdef CONFIG_NFS_V3_ACL | 818 | #ifdef CONFIG_NFS_V3_ACL |
914 | if (!(server->flags & NFS_MOUNT_NOACL)) { | 819 | if (!(server->flags & NFS_MOUNT_NOACL)) { |
@@ -1012,7 +917,7 @@ static int nfs_get_sb(struct file_system_type *fs_type, | |||
1012 | goto out_err_noserver; | 917 | goto out_err_noserver; |
1013 | /* Zero out the NFS state stuff */ | 918 | /* Zero out the NFS state stuff */ |
1014 | init_nfsv4_state(server); | 919 | init_nfsv4_state(server); |
1015 | server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL); | 920 | server->client = server->client_acl = ERR_PTR(-EINVAL); |
1016 | 921 | ||
1017 | root = &server->fh; | 922 | root = &server->fh; |
1018 | if (data->flags & NFS_MOUNT_VER3) | 923 | if (data->flags & NFS_MOUNT_VER3) |
@@ -1083,8 +988,6 @@ static void nfs_kill_super(struct super_block *s) | |||
1083 | 988 | ||
1084 | if (!IS_ERR(server->client)) | 989 | if (!IS_ERR(server->client)) |
1085 | rpc_shutdown_client(server->client); | 990 | rpc_shutdown_client(server->client); |
1086 | if (!IS_ERR(server->client_sys)) | ||
1087 | rpc_shutdown_client(server->client_sys); | ||
1088 | if (!IS_ERR(server->client_acl)) | 991 | if (!IS_ERR(server->client_acl)) |
1089 | rpc_shutdown_client(server->client_acl); | 992 | rpc_shutdown_client(server->client_acl); |
1090 | 993 | ||
@@ -1121,10 +1024,9 @@ static int nfs_clone_nfs_sb(struct file_system_type *fs_type, | |||
1121 | 1024 | ||
1122 | #ifdef CONFIG_NFS_V4 | 1025 | #ifdef CONFIG_NFS_V4 |
1123 | static struct rpc_clnt *nfs4_create_client(struct nfs_server *server, | 1026 | static struct rpc_clnt *nfs4_create_client(struct nfs_server *server, |
1124 | struct rpc_timeout *timeparms, int proto, rpc_authflavor_t flavor) | 1027 | int timeo, int retrans, int proto, rpc_authflavor_t flavor) |
1125 | { | 1028 | { |
1126 | struct nfs_client *clp; | 1029 | struct nfs_client *clp; |
1127 | struct rpc_xprt *xprt = NULL; | ||
1128 | struct rpc_clnt *clnt = NULL; | 1030 | struct rpc_clnt *clnt = NULL; |
1129 | int err = -EIO; | 1031 | int err = -EIO; |
1130 | 1032 | ||
@@ -1138,26 +1040,10 @@ static struct rpc_clnt *nfs4_create_client(struct nfs_server *server, | |||
1138 | if (clp->cl_cons_state == NFS_CS_INITING) { | 1040 | if (clp->cl_cons_state == NFS_CS_INITING) { |
1139 | clp->rpc_ops = &nfs_v4_clientops; | 1041 | clp->rpc_ops = &nfs_v4_clientops; |
1140 | 1042 | ||
1141 | xprt = xprt_create_proto(proto, &server->addr, timeparms); | 1043 | err = nfs_create_rpc_client(clp, proto, timeo, retrans, flavor); |
1142 | if (IS_ERR(xprt)) { | 1044 | if (err < 0) |
1143 | err = PTR_ERR(xprt); | ||
1144 | dprintk("%s: cannot create RPC transport. Error = %d\n", | ||
1145 | __FUNCTION__, err); | ||
1146 | goto client_init_error; | 1045 | goto client_init_error; |
1147 | } | 1046 | |
1148 | /* Bind to a reserved port! */ | ||
1149 | xprt->resvport = 1; | ||
1150 | clnt = rpc_create_client(xprt, server->hostname, &nfs_program, | ||
1151 | clp->cl_nfsversion, flavor); | ||
1152 | if (IS_ERR(clnt)) { | ||
1153 | err = PTR_ERR(clnt); | ||
1154 | dprintk("%s: cannot create RPC client. Error = %d\n", | ||
1155 | __FUNCTION__, err); | ||
1156 | goto client_init_error; | ||
1157 | } | ||
1158 | clnt->cl_intr = 1; | ||
1159 | clnt->cl_softrtry = 1; | ||
1160 | clp->cl_rpcclient = clnt; | ||
1161 | memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr)); | 1047 | memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr)); |
1162 | err = nfs_idmap_new(clp); | 1048 | err = nfs_idmap_new(clp); |
1163 | if (err < 0) { | 1049 | if (err < 0) { |
@@ -1205,7 +1091,6 @@ client_init_error: | |||
1205 | static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, int silent) | 1091 | static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, int silent) |
1206 | { | 1092 | { |
1207 | struct nfs_server *server; | 1093 | struct nfs_server *server; |
1208 | struct rpc_timeout timeparms; | ||
1209 | rpc_authflavor_t authflavour; | 1094 | rpc_authflavor_t authflavour; |
1210 | int err = -EIO; | 1095 | int err = -EIO; |
1211 | 1096 | ||
@@ -1224,11 +1109,6 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, | |||
1224 | server->acdirmin = data->acdirmin*HZ; | 1109 | server->acdirmin = data->acdirmin*HZ; |
1225 | server->acdirmax = data->acdirmax*HZ; | 1110 | server->acdirmax = data->acdirmax*HZ; |
1226 | 1111 | ||
1227 | nfs_init_timeout_values(&timeparms, data->proto, data->timeo, data->retrans); | ||
1228 | |||
1229 | server->retrans_timeo = timeparms.to_initval; | ||
1230 | server->retrans_count = timeparms.to_retries; | ||
1231 | |||
1232 | /* Now create transport and client */ | 1112 | /* Now create transport and client */ |
1233 | authflavour = RPC_AUTH_UNIX; | 1113 | authflavour = RPC_AUTH_UNIX; |
1234 | if (data->auth_flavourlen != 0) { | 1114 | if (data->auth_flavourlen != 0) { |
@@ -1244,7 +1124,8 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, | |||
1244 | } | 1124 | } |
1245 | } | 1125 | } |
1246 | 1126 | ||
1247 | server->client = nfs4_create_client(server, &timeparms, data->proto, authflavour); | 1127 | server->client = nfs4_create_client(server, data->timeo, data->retrans, |
1128 | data->proto, authflavour); | ||
1248 | if (IS_ERR(server->client)) { | 1129 | if (IS_ERR(server->client)) { |
1249 | err = PTR_ERR(server->client); | 1130 | err = PTR_ERR(server->client); |
1250 | dprintk("%s: cannot create RPC client. Error = %d\n", | 1131 | dprintk("%s: cannot create RPC client. Error = %d\n", |
@@ -1318,7 +1199,7 @@ static int nfs4_get_sb(struct file_system_type *fs_type, | |||
1318 | return -ENOMEM; | 1199 | return -ENOMEM; |
1319 | /* Zero out the NFS state stuff */ | 1200 | /* Zero out the NFS state stuff */ |
1320 | init_nfsv4_state(server); | 1201 | init_nfsv4_state(server); |
1321 | server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL); | 1202 | server->client = server->client_acl = ERR_PTR(-EINVAL); |
1322 | 1203 | ||
1323 | p = nfs_copy_user_string(NULL, &data->hostname, 256); | 1204 | p = nfs_copy_user_string(NULL, &data->hostname, 256); |
1324 | if (IS_ERR(p)) | 1205 | if (IS_ERR(p)) |
@@ -1489,7 +1370,6 @@ err: | |||
1489 | static struct nfs_server *nfs4_referral_server(struct super_block *sb, struct nfs_clone_mount *data) | 1370 | static struct nfs_server *nfs4_referral_server(struct super_block *sb, struct nfs_clone_mount *data) |
1490 | { | 1371 | { |
1491 | struct nfs_server *server = NFS_SB(sb); | 1372 | struct nfs_server *server = NFS_SB(sb); |
1492 | struct rpc_timeout timeparms; | ||
1493 | int proto, timeo, retrans; | 1373 | int proto, timeo, retrans; |
1494 | void *err; | 1374 | void *err; |
1495 | 1375 | ||
@@ -1498,11 +1378,11 @@ static struct nfs_server *nfs4_referral_server(struct super_block *sb, struct nf | |||
1498 | set the timeouts and retries to low values */ | 1378 | set the timeouts and retries to low values */ |
1499 | timeo = 2; | 1379 | timeo = 2; |
1500 | retrans = 1; | 1380 | retrans = 1; |
1501 | nfs_init_timeout_values(&timeparms, proto, timeo, retrans); | ||
1502 | 1381 | ||
1503 | nfs_put_client(server->nfs_client); | 1382 | nfs_put_client(server->nfs_client); |
1504 | server->nfs_client = NULL; | 1383 | server->nfs_client = NULL; |
1505 | server->client = nfs4_create_client(server, &timeparms, proto, data->authflavor); | 1384 | server->client = nfs4_create_client(server, timeo, retrans, proto, |
1385 | data->authflavor); | ||
1506 | if (IS_ERR((err = server->client))) | 1386 | if (IS_ERR((err = server->client))) |
1507 | goto out_err; | 1387 | goto out_err; |
1508 | 1388 | ||