Whamcloud - gitweb
- do not call any obd_fid_init() from llite, do that from lmv only;
authoryury <yury>
Tue, 24 Oct 2006 12:27:15 +0000 (12:27 +0000)
committeryury <yury>
Tue, 24 Oct 2006 12:27:15 +0000 (12:27 +0000)
- handle adding new mdc in lvm correctly from POV of seq init;
- move tgt disconnect to lmv_disconnect_mdc(), call obd_fid_fini() from it;
- deny adding new fld target on fly, continue to work with old targets set (hack until DHT is not used);
- fix sanity 24g, use mdd_is_root() for root comparisons as lu_fid_eq() can't be used fo root fids.

lustre/fld/fld_request.c
lustre/include/lustre_fld.h
lustre/liblustre/llite_fid.c
lustre/liblustre/llite_lib.h
lustre/liblustre/super.c
lustre/llite/llite_fid.c
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/lmv/lmv_obd.c
lustre/mdd/mdd_dir.c

index 2c6a3ed..b2fd751 100644 (file)
@@ -165,8 +165,15 @@ int fld_client_add_target(struct lu_client_fld *fld,
         LASSERT(name != NULL);
         LASSERT(tar->ft_srv != NULL || tar->ft_exp != NULL);
 
-        CDEBUG(D_INFO|D_WARNING, "%s: Adding target %s (idx "LPU64")\n",
-              fld->lcf_name, name, tar->ft_idx);
+        if (fld->lcf_flags != LUSTRE_FLD_INIT) {
+                CERROR("%s: Attempt to add target %s (idx "LPU64") "
+                       "on fly - skip it\n", fld->lcf_name, name,
+                       tar->ft_idx);
+                RETURN(0);
+        } else {
+                CDEBUG(D_INFO|D_WARNING, "%s: Adding target %s (idx "
+                       LPU64")\n", fld->lcf_name, name, tar->ft_idx);
+        }
 
         OBD_ALLOC_PTR(target);
         if (target == NULL)
@@ -310,6 +317,7 @@ int fld_client_init(struct lu_client_fld *fld,
         fld->lcf_count = 0;
         spin_lock_init(&fld->lcf_lock);
         fld->lcf_hash = &fld_hash[hash];
+        fld->lcf_flags = LUSTRE_FLD_INIT;
         INIT_LIST_HEAD(&fld->lcf_targets);
 
 #ifdef __KERNEL__
@@ -437,6 +445,7 @@ int fld_client_create(struct lu_client_fld *fld,
         int rc;
         ENTRY;
 
+        fld->lcf_flags |= LUSTRE_FLD_RUN;
         target = fld_client_get_target(fld, seq);
         LASSERT(target != NULL);
 
@@ -482,6 +491,7 @@ int fld_client_delete(struct lu_client_fld *fld, seqno_t seq,
         int rc;
         ENTRY;
 
+        fld->lcf_flags |= LUSTRE_FLD_RUN;
         fld_cache_delete(fld->lcf_cache, seq);
 
         target = fld_client_get_target(fld, seq);
@@ -517,7 +527,8 @@ int fld_client_lookup(struct lu_client_fld *fld,
         int rc;
         ENTRY;
 
-        /* Lookup it in the cache */
+        fld->lcf_flags |= LUSTRE_FLD_RUN;
+
         rc = fld_cache_lookup(fld->lcf_cache, seq, mds);
         if (rc == 0)
                 RETURN(0);
index 4f84e06..54b32bb 100644 (file)
@@ -126,6 +126,11 @@ struct lu_server_fld {
         char                     lsf_name[80];
 };
 
+enum {
+        LUSTRE_FLD_INIT = 1 << 0,
+        LUSTRE_FLD_RUN  = 1 << 1
+};
+
 struct lu_client_fld {
         /* Client side proc entry. */
         cfs_proc_dir_entry_t    *lcf_proc_dir;
@@ -149,6 +154,8 @@ struct lu_client_fld {
         char                     lcf_name[80];
 
         const struct lu_context *lcf_ctx;
+        
+        int                      lcf_flags;
 };
 
 int fld_query(struct com_thread_info *info);
index 01979a0..4de84fe 100644 (file)
@@ -76,69 +76,12 @@ int llu_fid_dt_alloc(struct llu_sb_info *sbi, struct lu_fid *fid,
         RETURN(llu_fid_alloc(sbi->ll_dt_exp, fid, hint));
 }
 
-static int llu_fid_init(struct obd_export *exp)
-{
-        int rc;
-        ENTRY;
-
-        rc = obd_fid_init(exp);
-        if (rc) {
-                CERROR("cannot initialize FIDs framework, "
-                       "rc %d\n", rc);
-                RETURN(rc);
-        }
-
-        RETURN(rc);
-}
-
-int llu_fid_md_init(struct llu_sb_info *sbi)
-{
-        ENTRY;
-        RETURN(llu_fid_init(sbi->ll_md_exp));
-}
-
-int llu_fid_dt_init(struct llu_sb_info *sbi)
-{
-        ENTRY;
-        RETURN(llu_fid_init(sbi->ll_dt_exp));
-}
-
-static int llu_fid_fini(struct obd_export *exp)
-{
-        int rc;
-        ENTRY;
-
-        rc = obd_fid_fini(exp);
-        if (rc) {
-                CERROR("cannot finalize FIDs framework, "
-                       "rc %d\n", rc);
-                RETURN(rc);
-        }
-
-        RETURN(rc);
-}
-
-int llu_fid_md_fini(struct llu_sb_info *sbi)
-{
-        ENTRY;
-        RETURN(llu_fid_fini(sbi->ll_md_exp));
-}
-
-int llu_fid_dt_fini(struct llu_sb_info *sbi)
-{
-        ENTRY;
-        RETURN(llu_fid_fini(sbi->ll_dt_exp));
-}
-
 /* build inode number on passed @fid */
 unsigned long llu_fid_build_ino(struct llu_sb_info *sbi,
                                 struct lu_fid *fid)
 {
         unsigned long ino;
         ENTRY;
-
-        /* very stupid and having many downsides inode allocation algorithm
-         * based on fid. */
         ino = (fid_seq(fid) - 1) * LUSTRE_SEQ_MAX_WIDTH + fid_oid(fid);
-        RETURN(ino);
+        RETURN(ino & 0x7fffffff);
 }
index c01f962..f1d230f 100644 (file)
@@ -244,12 +244,6 @@ ssize_t llu_iop_filldirentries(struct inode *ino, _SYSIO_OFF_T *basep,
                                char *buf, size_t nbytes);
 
 /* liblustre/llite_fid.c*/
-int llu_fid_md_init(struct llu_sb_info *sbi);
-int llu_fid_dt_init(struct llu_sb_info *sbi);
-
-int llu_fid_md_fini(struct llu_sb_info *sbi);
-int llu_fid_dt_fini(struct llu_sb_info *sbi);
-
 int llu_fid_md_alloc(struct llu_sb_info *sbi, struct lu_fid *fid, 
                      struct lu_placement_hint *hint);
 
index 0abd987..45bf9fb 100644 (file)
@@ -2083,11 +2083,7 @@ llu_fsswop_mount(const char *source,
 
         err = obd_statfs(obd, &osfs, 100000000);
         if (err)
-                GOTO(out_mdc, err);
-
-        err = llu_fid_md_init(sbi);
-        if (err)
-                GOTO(out_mdc, err);
+                GOTO(out_md, err);
 
         /*
          * FIXME fill fs stat data into sbi here!!! FIXME
@@ -2097,7 +2093,7 @@ llu_fsswop_mount(const char *source,
         obd = class_name2obd(osc);
         if (!obd) {
                 CERROR("OSC %s: not setup or attached\n", osc);
-                GOTO(out_md_fid, err = -EINVAL);
+                GOTO(out_md, err = -EINVAL);
         }
         obd_set_info_async(obd->obd_self_export, strlen("async"), "async",
                            sizeof(async), &async, NULL);
@@ -2111,21 +2107,17 @@ llu_fsswop_mount(const char *source,
         err = obd_connect(NULL, &dt_conn, obd, &sbi->ll_sb_uuid, &ocd);
         if (err) {
                 CERROR("cannot connect to %s: rc = %d\n", osc, err);
-                GOTO(out_mdc, err);
+                GOTO(out_md, err);
         }
         sbi->ll_dt_exp = class_conn2export(&dt_conn);
         sbi->ll_lco.lco_flags = ocd.ocd_connect_flags;
 
-        err = llu_fid_dt_init(sbi);
-        if (err)
-                GOTO(out_osc, err);
-
         llu_init_ea_size(sbi->ll_md_exp, sbi->ll_dt_exp);
 
         err = md_getstatus(sbi->ll_md_exp, &rootfid, NULL);
         if (err) {
                 CERROR("cannot mds_connect: rc = %d\n", err);
-                GOTO(out_dt_fid, err);
+                GOTO(out_dt, err);
         }
         CDEBUG(D_SUPER, "rootfid "DFID"\n", PFID(&rootfid));
         sbi->ll_root_fid = rootfid;
@@ -2135,7 +2127,7 @@ llu_fsswop_mount(const char *source,
                          OBD_MD_FLGETATTR | OBD_MD_FLBLOCKS, 0, &request);
         if (err) {
                 CERROR("md_getattr failed for root: rc = %d\n", err);
-                GOTO(out_osc, err);
+                GOTO(out_dt, err);
         }
 
         err = md_get_lustre_md(sbi->ll_md_exp, request, REPLY_REC_OFF,
@@ -2179,13 +2171,9 @@ out_inode:
         _sysio_i_gone(root);
 out_request:
         ptlrpc_req_finished(request);
-out_dt_fid:
-        llu_fid_dt_fini(sbi);
-out_osc:
+out_dt:
         obd_disconnect(sbi->ll_dt_exp);
-out_md_fid:
-        llu_fid_md_fini(sbi);
-out_mdc:
+out_md:
         obd_disconnect(sbi->ll_md_exp);
 out_free:
         if (osc)
index db63a3c..0242b4c 100644 (file)
@@ -68,76 +68,6 @@ int ll_fid_dt_alloc(struct ll_sb_info *sbi, struct lu_fid *fid,
         RETURN(ll_fid_alloc(sbi->ll_dt_exp, fid, hint));
 }
 
-static int ll_fid_init(struct obd_export *exp)
-{
-        int rc;
-        ENTRY;
-
-        rc = obd_fid_init(exp);
-        if (rc) {
-                CERROR("cannot initialize FIDs framework, "
-                       "rc %d\n", rc);
-                RETURN(rc);
-        }
-
-        RETURN(rc);
-}
-
-int ll_fid_md_init(struct ll_sb_info *sbi)
-{
-        ENTRY;
-        RETURN(ll_fid_init(sbi->ll_md_exp));
-}
-
-int ll_fid_dt_init(struct ll_sb_info *sbi)
-{
-#if 0
-        ENTRY;
-        RETURN(ll_fid_init(sbi->ll_dt_exp));
-#endif
-        /* 
-         * XXX: enable this when DT stack supports new FIDs and has implemented
-         * obd_fid_init().
-         */
-        ENTRY;
-        RETURN(0);
-}
-
-static int ll_fid_fini(struct obd_export *exp)
-{
-        int rc;
-        ENTRY;
-
-        rc = obd_fid_fini(exp);
-        if (rc) {
-                CERROR("cannot finalize FIDs framework, "
-                       "rc %d\n", rc);
-        }
-
-        RETURN(rc);
-}
-
-int ll_fid_md_fini(struct ll_sb_info *sbi)
-{
-        ENTRY;
-        RETURN(ll_fid_fini(sbi->ll_md_exp));
-}
-
-int ll_fid_dt_fini(struct ll_sb_info *sbi)
-{
-#if 0
-        ENTRY;
-        RETURN(ll_fid_fini(sbi->ll_dt_exp));
-#else
-        /* 
-         * XXX: enable this when DT stack supports new FIDs and has implemented
-         * obd_fid_fini().
-         */
-        ENTRY;
-        RETURN(0);
-#endif
-}
-
 /* build inode number on passed @fid */
 ino_t ll_fid_build_ino(struct ll_sb_info *sbi,
                        struct lu_fid *fid)
index 2065b09..040f653 100644 (file)
@@ -726,13 +726,7 @@ void free_rmtperm_hash(struct hlist_head *hash);
 int ll_update_remote_perm(struct inode *inode, struct mdt_remote_perm *perm);
 int lustre_check_remote_perm(struct inode *inode, int mask);
 
-/* llite/llite_fid.c*/
-int ll_fid_md_init(struct ll_sb_info *sbi);
-int ll_fid_dt_init(struct ll_sb_info *sbi);
-
-int ll_fid_md_fini(struct ll_sb_info *sbi);
-int ll_fid_dt_fini(struct ll_sb_info *sbi);
-
+/* llite/llite_fid.c */
 int ll_fid_md_alloc(struct ll_sb_info *sbi, struct lu_fid *fid,
                     struct lu_placement_hint *hint);
 
index 3a8e89c..afbf4b0 100644 (file)
@@ -312,17 +312,10 @@ static int client_common_fill_super(struct super_block *sb,
                                  strlen(sbi2mdc(sbi)->cl_target_uuid.uuid));
 #endif
 
-        /* init FIDs framework */
-        err = ll_fid_md_init(sbi);
-        if (err) {
-                CERROR("can't init FIDs framework, rc %d\n", err);
-                GOTO(out_md, err);
-        }
-
         obd = class_name2obd(dt);
         if (!obd) {
                 CERROR("DT %s: not setup or attached\n", dt);
-                GOTO(out_md_fid, err = -ENODEV);
+                GOTO(out_md, err = -ENODEV);
         }
 
         data->ocd_connect_flags = OBD_CONNECT_GRANT | OBD_CONNECT_VERSION |
@@ -376,17 +369,10 @@ static int client_common_fill_super(struct super_block *sb,
                         GOTO(out_dt, err = -ENOMEM);
         }
 
-        /* init FIDs framework */
-        err = ll_fid_dt_init(sbi);
-        if (err) {
-                CERROR("can't init FIDs framework, rc %d\n", err);
-                GOTO(out_dt, err);
-        }
-
         err = md_getstatus(sbi->ll_md_exp, &rootfid, &oc);
         if (err) {
                 CERROR("cannot mds_connect: rc = %d\n", err);
-                GOTO(out_dt_fid, err);
+                GOTO(out_dt, err);
         }
         CDEBUG(D_SUPER, "rootfid "DFID"\n", PFID(&rootfid));
         sbi->ll_root_fid = rootfid;
@@ -457,13 +443,9 @@ static int client_common_fill_super(struct super_block *sb,
 out_root:
         if (root)
                 iput(root);
-out_dt_fid:
-        obd_fid_fini(sbi->ll_dt_exp);
 out_dt:
         obd_disconnect(sbi->ll_dt_exp);
         sbi->ll_dt_exp = NULL;
-out_md_fid:
-        obd_fid_fini(sbi->ll_md_exp);
 out_md:
         obd_disconnect(sbi->ll_md_exp);
         sbi->ll_md_exp = NULL;
@@ -656,13 +638,11 @@ void client_common_put_super(struct super_block *sb)
         prune_deathrow(sbi, 0);
 
         list_del(&sbi->ll_conn_chain);
-        ll_fid_dt_fini(sbi);
         obd_disconnect(sbi->ll_dt_exp);
         sbi->ll_dt_exp = NULL;
 
         lprocfs_unregister_mountpoint(sbi);
 
-        ll_fid_md_fini(sbi);
         obd_disconnect(sbi->ll_md_exp);
         sbi->ll_md_exp = NULL;
 
index 59ef7dc..a60ea04 100644 (file)
@@ -392,6 +392,12 @@ int lmv_connect_mdc(struct obd_device *obd, struct lmv_tgt_desc *tgt)
 
         mdc_exp = class_conn2export(&conn);
 
+        /* Init fid sequence client for this mdc. */
+        rc = obd_fid_init(mdc_exp);
+        if (rc)
+                RETURN(rc);
+
+        /* Add new FLD target. */
         target.ft_srv = NULL;
         target.ft_exp = mdc_exp;
         target.ft_idx = tgt->ltd_idx;
@@ -579,14 +585,68 @@ int lmv_check_connect(struct obd_device *obd)
         RETURN(rc);
 }
 
-static int lmv_disconnect(struct obd_export *exp)
+static int lmv_disconnect_mdc(struct obd_device *obd, struct lmv_tgt_desc *tgt)
 {
-        struct obd_device *obd = class_exp2obd(exp);
+#ifdef __KERNEL__
+        struct proc_dir_entry *lmv_proc_dir;
+#endif
         struct lmv_obd *lmv = &obd->u.lmv;
+        struct obd_device *mdc_obd;
+        int rc;
+        ENTRY;
+
+        LASSERT(tgt != NULL);
+        LASSERT(obd != NULL);
+        
+        mdc_obd = class_exp2obd(tgt->ltd_exp);
+
+        if (mdc_obd)
+                mdc_obd->obd_no_recov = obd->obd_no_recov;
 
 #ifdef __KERNEL__
+        lmv_proc_dir = lprocfs_srch(obd->obd_proc_entry, "target_obds");
+        if (lmv_proc_dir) {
+                struct proc_dir_entry *mdc_symlink;
+
+                mdc_symlink = lprocfs_srch(lmv_proc_dir, mdc_obd->obd_name);
+                if (mdc_symlink) {
+                        lprocfs_remove(mdc_symlink);
+                } else {
+                        CERROR("/proc/fs/lustre/%s/%s/target_obds/%s missing\n",
+                               obd->obd_type->typ_name, obd->obd_name,
+                               mdc_obd->obd_name);
+                }
+        }
+#endif
+        rc = obd_fid_fini(tgt->ltd_exp);
+        if (rc)
+                CERROR("Can't finanize fids factory\n");
+                
+        CDEBUG(D_OTHER, "Disconnected from %s(%s) successfully\n",
+               tgt->ltd_exp->exp_obd->obd_name,
+               tgt->ltd_exp->exp_obd->obd_uuid.uuid);
+
+        obd_register_observer(tgt->ltd_exp->exp_obd, NULL);
+        rc = obd_disconnect(tgt->ltd_exp);
+        if (rc) {
+                if (tgt->ltd_active) {
+                        CERROR("Target %s disconnect error %d\n",
+                               tgt->ltd_uuid.uuid, rc);
+                }
+        }
+
+        lmv_activate_target(lmv, tgt, 0);
+        tgt->ltd_exp = NULL;
+        RETURN(0);
+}
+
+static int lmv_disconnect(struct obd_export *exp)
+{
+        struct obd_device *obd = class_exp2obd(exp);
+#ifdef __KERNEL__
         struct proc_dir_entry *lmv_proc_dir;
 #endif
+        struct lmv_obd *lmv = &obd->u.lmv;
         int rc, i;
         ENTRY;
 
@@ -598,54 +658,14 @@ static int lmv_disconnect(struct obd_export *exp)
         if (lmv->refcount != 0)
                 goto out_local;
 
-#ifdef __KERNEL__
-        lmv_proc_dir = lprocfs_srch(obd->obd_proc_entry, "target_obds");
-#endif
-
         for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
-                struct obd_device *mdc_obd;
-
                 if (lmv->tgts[i].ltd_exp == NULL)
                         continue;
-
-                mdc_obd = class_exp2obd(lmv->tgts[i].ltd_exp);
-
-                if (mdc_obd)
-                        mdc_obd->obd_no_recov = obd->obd_no_recov;
-
-#ifdef __KERNEL__
-                if (lmv_proc_dir) {
-                        struct proc_dir_entry *mdc_symlink;
-
-                        mdc_symlink = lprocfs_srch(lmv_proc_dir, mdc_obd->obd_name);
-                        if (mdc_symlink) {
-                                lprocfs_remove(mdc_symlink);
-                        } else {
-                                CERROR("/proc/fs/lustre/%s/%s/target_obds/%s missing\n",
-                                       obd->obd_type->typ_name, obd->obd_name,
-                                       mdc_obd->obd_name);
-                        }
-                }
-#endif
-                CDEBUG(D_OTHER, "disconnected from %s(%s) successfully\n",
-                        lmv->tgts[i].ltd_exp->exp_obd->obd_name,
-                        lmv->tgts[i].ltd_exp->exp_obd->obd_uuid.uuid);
-
-                obd_register_observer(lmv->tgts[i].ltd_exp->exp_obd, NULL);
-                rc = obd_disconnect(lmv->tgts[i].ltd_exp);
-                if (rc) {
-                        if (lmv->tgts[i].ltd_active) {
-                                CERROR("Target %s disconnect error %d\n",
-                                       lmv->tgts[i].ltd_uuid.uuid, rc);
-                        }
-                        rc = 0;
-                }
-
-                lmv_activate_target(lmv, &lmv->tgts[i], 0);
-                lmv->tgts[i].ltd_exp = NULL;
+                lmv_disconnect_mdc(obd, &lmv->tgts[i]);
         }
 
 #ifdef __KERNEL__
+        lmv_proc_dir = lprocfs_srch(obd->obd_proc_entry, "target_obds");
         if (lmv_proc_dir) {
                 lprocfs_remove(lmv_proc_dir);
         } else {
@@ -655,8 +675,10 @@ static int lmv_disconnect(struct obd_export *exp)
 #endif
 
 out_local:
-        /* this is the case when no real connection is established by
-         * lmv_check_connect(). */
+        /*
+         * This is the case when no real connection is established by
+         * lmv_check_connect().
+         */
         if (!lmv->connected)
                 class_export_put(exp);
         rc = class_disconnect(exp);
@@ -789,42 +811,6 @@ exit:
         RETURN(rc);
 }
 
-static int lmv_fid_init(struct obd_export *exp)
-{
-        struct obd_device *obd = class_exp2obd(exp);
-        struct lmv_obd *lmv = &obd->u.lmv;
-        int i, rc = 0;
-        ENTRY;
-
-        for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
-                if (lmv->tgts[i].ltd_exp == NULL)
-                        continue;
-
-                rc = obd_fid_init(lmv->tgts[i].ltd_exp);
-                if (rc)
-                        RETURN(rc);
-        }
-        RETURN(rc);
-}
-
-static int lmv_fid_fini(struct obd_export *exp)
-{
-        struct obd_device *obd = class_exp2obd(exp);
-        struct lmv_obd *lmv = &obd->u.lmv;
-        int i, rc = 0;
-        ENTRY;
-
-        for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
-                if (lmv->tgts[i].ltd_exp == NULL)
-                        continue;
-
-                rc = obd_fid_fini(lmv->tgts[i].ltd_exp);
-                if (rc)
-                        break;
-        }
-        RETURN(rc);
-}
-
 int __lmv_fid_alloc(struct lmv_obd *lmv, struct lu_fid *fid,
                     mdsno_t mds)
 {
@@ -2530,8 +2516,6 @@ struct obd_ops lmv_obd_ops = {
         .o_packmd               = lmv_packmd,
         .o_unpackmd             = lmv_unpackmd,
         .o_notify               = lmv_notify,
-        .o_fid_init             = lmv_fid_init,
-        .o_fid_fini             = lmv_fid_fini,
         .o_fid_alloc            = lmv_fid_alloc,
         .o_fid_delete           = lmv_fid_delete,
         .o_iocontrol            = lmv_iocontrol
index 26af156..e79a68f 100644 (file)
@@ -85,6 +85,16 @@ static int mdd_parent_fid(const struct lu_env *env, struct mdd_object *obj,
 }
 
 /*
+ * For root fid use special function, whcih does not compare version component
+ * of fid. Vresion component is different for root fids on all MDTs.
+ */
+static int mdd_is_root(struct mdd_device *mdd, const struct lu_fid *fid)
+{
+        return fid_seq(&mdd->mdd_root_fid) == fid_seq(fid) &&
+                fid_oid(&mdd->mdd_root_fid) == fid_oid(fid);
+}
+
+/*
  * return 1: if lf is the fid of the ancestor of p1;
  * return 0: if not;
  *
@@ -108,14 +118,14 @@ static int mdd_is_parent(const struct lu_env *env,
         pfid = &mdd_env_info(env)->mti_fid;
 
         /* Check for root first. */
-        if (lu_fid_eq(mdo2fid(p1), &mdd->mdd_root_fid))
+        if (mdd_is_root(mdd, mdo2fid(p1)))
                 RETURN(0);
 
         for(;;) {
                 rc = mdd_parent_fid(env, p1, pfid);
                 if (rc)
                         GOTO(out, rc);
-                if (lu_fid_eq(pfid, &mdd->mdd_root_fid))
+                if (mdd_is_root(mdd, pfid))
                         GOTO(out, rc = 0);
                 if (lu_fid_eq(pfid, lf))
                         GOTO(out, rc = 1);