Whamcloud - gitweb
ORNL-28 recovery: rework extend_recovery_timer()
[fs/lustre-release.git] / lustre / obdfilter / filter.c
index 76e12fe..6f2b7b9 100644 (file)
@@ -30,6 +30,9 @@
  * Use is subject to license terms.
  */
 /*
+ * Copyright (c) 2011 Whamcloud, Inc.
+ */
+/*
  * This file is part of Lustre, http://www.lustre.org/
  * Lustre is a trademark of Sun Microsystems, Inc.
  *
@@ -901,6 +904,7 @@ static int filter_init_server_data(struct obd_device *obd, struct file * filp)
         obd->obd_last_committed = le64_to_cpu(lsd->lsd_last_transno);
 out:
         obd->u.obt.obt_mount_count = mount_count + 1;
+        obd->u.obt.obt_instance = (__u32)obd->u.obt.obt_mount_count;
         lsd->lsd_mount_count = cpu_to_le64(obd->u.obt.obt_mount_count);
 
         /* save it, so mount count and last_transno is current */
@@ -1207,10 +1211,10 @@ static int filter_prep_groups(struct obd_device *obd)
 
         O_dentry = simple_mkdir(cfs_fs_pwd(current->fs), obd->u.obt.obt_vfsmnt,
                                 "O", 0700, 1);
-        CDEBUG(D_INODE, "got/created O: %p\n", O_dentry);
+        CDEBUG(D_INODE, "%s: got/created O: %p\n", obd->obd_name, O_dentry);
         if (IS_ERR(O_dentry)) {
                 rc = PTR_ERR(O_dentry);
-                CERROR("cannot open/create O: rc = %d\n", rc);
+                CERROR("%s: cannot open/create O: rc = %d\n", obd->obd_name,rc);
                 GOTO(cleanup, rc);
         }
         filter->fo_dentry_O = O_dentry;
@@ -1220,22 +1224,24 @@ static int filter_prep_groups(struct obd_device *obd)
          * clients because they may send create/destroy for any group -bzzz */
         filp = filp_open("LAST_GROUP", O_CREAT | O_RDWR, 0700);
         if (IS_ERR(filp)) {
-                CERROR("cannot create LAST_GROUP: rc = %ld\n", PTR_ERR(filp));
+                CERROR("%s: cannot create LAST_GROUP: rc = %ld\n",
+                       obd->obd_name, PTR_ERR(filp));
                 GOTO(cleanup, rc = PTR_ERR(filp));
         }
         cleanup_phase = 2; /* filp */
 
         rc = fsfilt_read_record(obd, filp, &last_group, sizeof(__u32), &off);
         if (rc) {
-                CDEBUG(D_INODE, "error reading LAST_GROUP: rc %d\n", rc);
+                CERROR("%s: error reading LAST_GROUP: rc %d\n",
+                       obd->obd_name, rc);
                 GOTO(cleanup, rc);
         }
 
         if (off == 0)
                 last_group = FID_SEQ_OST_MDT0;
 
-        CWARN("%s: initialize groups [%u,%u]\n", obd->obd_name,
-              FID_SEQ_OST_MDT0, last_group);
+        CDEBUG(D_INODE, "%s: initialize group %u (max %u)\n", obd->obd_name,
+               FID_SEQ_OST_MDT0, last_group);
         filter->fo_committed_group = last_group;
         rc = filter_read_groups(obd, last_group, 1);
         if (rc)
@@ -1418,7 +1424,7 @@ struct dentry *filter_parent(struct obd_device *obd, obd_seq group, obd_id objid
         struct filter_subdirs *subdirs;
 
         if (group >= filter->fo_group_count) /* FIXME: object groups */
-               return ERR_PTR(-EBADF);
+                return ERR_PTR(-EBADF);
 
         if (!fid_seq_is_mdt(group) || filter->fo_subdir_count == 0)
                 return filter->fo_dentry_O_groups[group];
@@ -1977,14 +1983,6 @@ int filter_common_setup(struct obd_device *obd, struct lustre_cfg* lcfg,
                 struct lustre_sb_info *lsi = s2lsi(lmi->lmi_sb);
                 mnt = lmi->lmi_mnt;
                 obd->obd_fsops = fsfilt_get_ops(MT_STR(lsi->lsi_ldd));
-
-                /* gets recovery timeouts from mount data */
-                if (lsi->lsi_lmd && lsi->lsi_lmd->lmd_recovery_time_soft)
-                        obd->obd_recovery_timeout =
-                                lsi->lsi_lmd->lmd_recovery_time_soft;
-                if (lsi->lsi_lmd && lsi->lsi_lmd->lmd_recovery_time_hard)
-                        obd->obd_recovery_time_hard =
-                                lsi->lsi_lmd->lmd_recovery_time_hard;
         } else {
                 /* old path - used by lctl */
                 CERROR("Using old MDS mount method\n");
@@ -2016,6 +2014,9 @@ int filter_common_setup(struct obd_device *obd, struct lustre_cfg* lcfg,
         /* failover is the default */
         obd->obd_replayable = 1;
 
+        /* disable connection until configuration finishes */
+        obd->obd_no_conn = 1;
+
         if (lcfg->lcfg_bufcount > 3 && LUSTRE_CFG_BUFLEN(lcfg, 3) > 0) {
                 str = lustre_cfg_string(lcfg, 3);
                 if (strchr(str, 'n')) {
@@ -2024,9 +2025,9 @@ int filter_common_setup(struct obd_device *obd, struct lustre_cfg* lcfg,
                 }
         }
 
+        obd->u.obt.obt_magic = OBT_MAGIC;
         obd->u.obt.obt_vfsmnt = mnt;
         obd->u.obt.obt_sb = mnt->mnt_sb;
-        obd->u.obt.obt_magic = OBT_MAGIC;
         filter->fo_fstype = mnt->mnt_sb->s_type->name;
         CDEBUG(D_SUPER, "%s: mnt = %p\n", filter->fo_fstype, mnt);
 
@@ -2123,17 +2124,6 @@ int filter_common_setup(struct obd_device *obd, struct lustre_cfg* lcfg,
                       lmi ? s2lsi(lmi->lmi_sb)->lsi_lmd->lmd_dev : "",
                       obd->obd_replayable ? "enabled" : "disabled");
 
-        if (obd->obd_recovering)
-                LCONSOLE_WARN("%s: Will be in recovery for at least %d:%.02d, "
-                              "or until %d client%s reconnect%s\n",
-                              obd->obd_name,
-                              obd->obd_recovery_timeout / 60,
-                              obd->obd_recovery_timeout % 60,
-                              obd->obd_max_recoverable_clients,
-                              (obd->obd_max_recoverable_clients == 1) ? "" : "s",
-                              (obd->obd_max_recoverable_clients == 1) ? "s": "");
-
-
         RETURN(0);
 
 err_post:
@@ -2689,8 +2679,10 @@ static int filter_connect_internal(struct obd_export *exp,
         data->ocd_version = LUSTRE_VERSION_CODE;
 
         /* Kindly make sure the SKIP_ORPHAN flag is from MDS. */
-        if (!ergo(data->ocd_connect_flags & OBD_CONNECT_SKIP_ORPHAN,
-                  data->ocd_connect_flags & OBD_CONNECT_MDS))
+        if (data->ocd_connect_flags & OBD_CONNECT_MDS)
+                CWARN("%s: Received MDS connection for group %u\n",
+                      exp->exp_obd->obd_name, data->ocd_group);
+        else if (data->ocd_connect_flags & OBD_CONNECT_SKIP_ORPHAN)
                 RETURN(-EPROTO);
 
         if (exp->exp_connect_flags & OBD_CONNECT_GRANT) {
@@ -2764,9 +2756,10 @@ static int filter_connect_internal(struct obd_export *exp,
                 /* The client set in ocd_cksum_types the checksum types it
                  * supports. We have to mask off the algorithms that we don't
                  * support */
-                if (cksum_types & OBD_CKSUM_ALL)
-                        data->ocd_cksum_types &= OBD_CKSUM_ALL;
-                else
+                data->ocd_cksum_types &= cksum_types_supported();
+
+                /* 1.6.4- only support CRC32 and didn't set ocd_cksum_types */
+                if (unlikely(data->ocd_cksum_types == 0))
                         data->ocd_cksum_types = OBD_CKSUM_CRC32;
 
                 CDEBUG(D_RPCTRACE, "%s: cli %s supports cksum type %x, return "
@@ -2782,6 +2775,9 @@ static int filter_connect_internal(struct obd_export *exp,
                                    obd_export_nid2str(exp));
         }
 
+        if (data->ocd_connect_flags & OBD_CONNECT_MAXBYTES)
+                data->ocd_maxbytes = exp->exp_obd->u.obt.obt_sb->s_maxbytes;
+
         RETURN(0);
 }
 
@@ -2804,7 +2800,6 @@ static int filter_reconnect(const struct lu_env *env,
         RETURN(rc);
 }
 
-/* nearly identical to mds_connect */
 static int filter_connect(const struct lu_env *env,
                           struct obd_export **exp, struct obd_device *obd,
                           struct obd_uuid *cluuid,
@@ -2813,7 +2808,6 @@ static int filter_connect(const struct lu_env *env,
         struct lvfs_run_ctxt saved;
         struct lustre_handle conn = { 0 };
         struct obd_export *lexp;
-        __u32 group;
         int rc;
         ENTRY;
 
@@ -2840,16 +2834,11 @@ static int filter_connect(const struct lu_env *env,
                         GOTO(cleanup, rc);
         }
 
-        group = data->ocd_group;
-
-        CWARN("%s: Received MDS connection ("LPX64"); group %d\n",
-              obd->obd_name, lexp->exp_handle.h_cookie, group);
-
         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-        rc = filter_read_groups(obd, group, 1);
+        rc = filter_read_groups(obd, data->ocd_group, 1);
         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
         if (rc != 0) {
-                CERROR("can't read group %u\n", group);
+                CERROR("can't read group %u\n", data->ocd_group);
                 GOTO(cleanup, rc);
         }
 
@@ -3538,7 +3527,7 @@ static int filter_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp,
                 LASSERT((*lsmp)->lsm_object_id);
         }
 
-        (*lsmp)->lsm_maxbytes = LUSTRE_STRIPE_MAXBYTES;
+        (*lsmp)->lsm_maxbytes = exp->exp_obd->u.obt.obt_sb->s_maxbytes;
 
         RETURN(lsm_size);
 }
@@ -3803,6 +3792,7 @@ static int filter_precreate(struct obd_device *obd, struct obdo *oa,
         struct dentry *dchild = NULL, *dparent = NULL;
         struct filter_obd *filter;
         struct obd_statfs *osfs;
+        struct iattr iattr;
         int err = 0, rc = 0, recreate_obj = 0, i;
         cfs_time_t enough_time = cfs_time_shift(DISK_TIMEOUT/2);
         __u64 os_ffree;
@@ -3831,6 +3821,13 @@ static int filter_precreate(struct obd_device *obd, struct obdo *oa,
                                LPU64"\n", obd->obd_name, osfs->os_bavail <<
                                obd->u.obt.obt_vfsmnt->mnt_sb->s_blocksize_bits);
                         *num = 0;
+                        if (oa->o_valid & OBD_MD_FLFLAGS)
+                                oa->o_flags |= OBD_FL_NOSPC_BLK;
+                        else {
+                                oa->o_valid |= OBD_MD_FLFLAGS;
+                                oa->o_flags = OBD_FL_NOSPC_BLK;
+                        }
+
                         rc = -ENOSPC;
                 }
                 OBD_FREE(osfs, sizeof(*osfs));
@@ -3935,9 +3932,21 @@ static int filter_precreate(struct obd_device *obd, struct obdo *oa,
                         CERROR("create failed rc = %d\n", rc);
                         if (rc == -ENOSPC) {
                                 os_ffree = filter_calc_free_inodes(obd);
-                                if (os_ffree != -1)
+                                if (os_ffree == -1) 
+                                        GOTO(cleanup, rc);
+
+                                if (obd->obd_osfs.os_bavail <
+                                    (obd->obd_osfs.os_blocks >> 10)) {
+                                        if (oa->o_valid & OBD_MD_FLFLAGS)
+                                                oa->o_flags |= OBD_FL_NOSPC_BLK;
+                                        else {
+                                                oa->o_valid |= OBD_MD_FLFLAGS;
+                                                oa->o_flags = OBD_FL_NOSPC_BLK;
+                                        }
+
                                         CERROR("%s: free inode "LPU64"\n",
                                                obd->obd_name, os_ffree);
+                                }
                         }
                         GOTO(cleanup, rc);
                 }
@@ -3947,6 +3956,19 @@ static int filter_precreate(struct obd_device *obd, struct obdo *oa,
                                        dchild->d_inode->i_ino);
 
 set_last_id:
+                /* Set a/c/m time to a insane large negative value at creation
+                 * time so that any timestamp arriving from the client will
+                 * always be newer and update the inode.
+                 * See LU-221 for details */
+                iattr.ia_valid = ATTR_ATIME | ATTR_MTIME | ATTR_CTIME;
+                LTIME_S(iattr.ia_atime) = INT_MIN + 24 * 3600;
+                LTIME_S(iattr.ia_mtime) = INT_MIN + 24 * 3600;
+                LTIME_S(iattr.ia_ctime) = INT_MIN + 24 * 3600;
+                err = fsfilt_setattr(obd, dchild, handle, &iattr, 0);
+                if (err)
+                        CERROR("unable to initialize a/c/m time of newly"
+                               "created inode\n");
+
                 if (!recreate_obj) {
                         filter_set_last_id(filter, next_id, group);
                         err = filter_update_last_objid(obd, group, 0);
@@ -4008,7 +4030,17 @@ int filter_create(struct obd_export *exp, struct obdo *oa,
         fed = &exp->exp_filter_data;
         filter = &obd->u.filter;
 
-        if (fed->fed_group != oa->o_seq) {
+        /* 1.8 client doesn't carry the ocd_group with connect request,
+         * so the fed_group will always be zero for 1.8 client. */
+        if (!(exp->exp_connect_flags & OBD_CONNECT_FULL20)) {
+                if (oa->o_seq != FID_SEQ_OST_MDT0 &&
+                    oa->o_seq != FID_SEQ_LLOG &&
+                    oa->o_seq != FID_SEQ_ECHO) {
+                        CERROR("The request from older client has invalid"
+                               " group "LPU64"!\n", oa->o_seq);
+                        RETURN(-EINVAL);
+                }
+        } else if (fed->fed_group != oa->o_seq) {
                 CERROR("%s: this export (nid %s) used object group %d "
                         "earlier; now it's trying to use group "LPU64"!"
                         " This could be a bug in the MDS. Please report to "
@@ -4651,6 +4683,24 @@ static int filter_process_config(struct obd_device *obd, obd_count len,
         return rc;
 }
 
+static int filter_notify(struct obd_device *obd,
+                         struct obd_device *unused,
+                         enum obd_notify_event ev, void *data)
+{
+        switch (ev) {
+        case OBD_NOTIFY_CONFIG:
+                LASSERT(obd->obd_no_conn);
+                cfs_spin_lock(&obd->obd_dev_lock);
+                obd->obd_no_conn = 0;
+                cfs_spin_unlock(&obd->obd_dev_lock);
+                break;
+        default:
+                CDEBUG(D_INFO, "%s: Unhandled notification %#x\n",
+                       obd->obd_name, ev);
+        }
+        return 0;
+}
+
 static struct lvfs_callback_ops filter_lvfs_ops = {
         l_fid2dentry:     filter_lvfs_fid2dentry,
 };
@@ -4685,6 +4735,7 @@ static struct obd_ops filter_obd_ops = {
         .o_iocontrol      = filter_iocontrol,
         .o_health_check   = filter_health_check,
         .o_process_config = filter_process_config,
+        .o_notify         = filter_notify,
 };
 
 quota_interface_t *filter_quota_interface_ref;