1. Initialize FID client for OSP on MDT.
2. Pull out OSP precreate stuff into a separate structure,
so OSP on MDT does not have to allocate precreate.
Signed-off-by: wang di <di.wang@intel.com>
Change-Id: I3c4a87e2fbea2a733fc6a4a296a50ba67652aa32
Reviewed-on: http://review.whamcloud.com/7158
Reviewed-by: John L. Hammond <john.hammond@intel.com>
Tested-by: Jenkins
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
Tested-by: Oleg Drokin <oleg.drokin@intel.com>
req->rq_no_delay = req->rq_no_resend = 1;
debug_mask = D_CONSOLE;
} else {
- if (seq->lcs_type == LUSTRE_SEQ_METADATA)
+ if (seq->lcs_type == LUSTRE_SEQ_METADATA) {
+ req->rq_reply_portal = MDC_REPLY_PORTAL;
req->rq_request_portal = SEQ_METADATA_PORTAL;
- else
+ } else {
+ req->rq_reply_portal = OSC_REPLY_PORTAL;
req->rq_request_portal = SEQ_DATA_PORTAL;
+ }
+
debug_mask = D_INFO;
}
struct obd_device *obd = data;
struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
- if (osp == NULL)
+ if (osp == NULL || osp->opd_pre == NULL)
return 0;
return snprintf(page, count, "%d\n", osp->opd_pre_grow_count);
struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
int val, rc, i;
- if (osp == NULL)
+ if (osp == NULL || osp->opd_pre == NULL)
return 0;
rc = lprocfs_write_helper(buffer, count, &val);
struct obd_device *obd = data;
struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
- if (osp == NULL)
+ if (osp == NULL || osp->opd_pre == NULL)
return 0;
return snprintf(page, count, "%d\n", osp->opd_pre_max_grow_count);
struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
int val, rc;
- if (osp == NULL)
+ if (osp == NULL || osp->opd_pre == NULL)
return 0;
rc = lprocfs_write_helper(buffer, count, &val);
struct obd_device *obd = data;
struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
- if (osp == NULL)
+ if (osp == NULL || osp->opd_pre == NULL)
return 0;
return snprintf(page, count, "%u\n",
struct obd_device *obd = data;
struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
- if (osp == NULL)
+ if (osp == NULL || osp->opd_pre == NULL)
return 0;
return snprintf(page, count, "%u\n",
struct obd_device *obd = data;
struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
- if (osp == NULL)
+ if (osp == NULL || osp->opd_pre == NULL)
return 0;
return snprintf(page, count, LPX64"\n",
struct obd_device *obd = data;
struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
- if (osp == NULL)
+ if (osp == NULL || osp->opd_pre == NULL)
return 0;
return snprintf(page, count, LPX64"\n",
struct obd_device *obd = data;
struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
- if (osp == NULL)
+ if (osp == NULL || osp->opd_pre == NULL)
return 0;
return snprintf(page, count, LPU64"\n", osp->opd_pre_reserved);
struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
int rc;
- if (osp == NULL)
+ if (osp == NULL || osp->opd_pre == NULL)
return -EINVAL;
rc = snprintf(page, count, "%d\n", osp->opd_pre_status);
ENTRY;
osp->opd_recovery_completed = 1;
- if (!osp->opd_connect_mdt)
+
+ if (!osp->opd_connect_mdt && osp->opd_pre != NULL)
wake_up(&osp->opd_pre_waitq);
RETURN(rc);
}
if (unlikely(d->opd_imp_active == 0))
RETURN(-ENOTCONN);
+ if (d->opd_pre == NULL)
+ RETURN(0);
+
/* return recently updated data */
*sfs = d->opd_statfs;
* layer above osp (usually lod) can use ffree to estimate
* how many objects are available for immediate creation
*/
-
spin_lock(&d->opd_pre_lock);
LASSERTF(fid_seq(&d->opd_pre_last_created_fid) ==
fid_seq(&d->opd_pre_used_fid),
osp_lprocfs_init(m);
+ rc = obd_fid_init(m->opd_obd, NULL, m->opd_connect_mdt ?
+ LUSTRE_SEQ_METADATA : LUSTRE_SEQ_DATA);
+ if (rc) {
+ CERROR("%s: fid init error: rc = %d\n",
+ m->opd_obd->obd_name, rc);
+ GOTO(out_proc, rc);
+ }
+
if (!m->opd_connect_mdt) {
/* Initialize last id from the storage - will be
* used in orphan cleanup. */
if (rc)
GOTO(out_proc, rc);
- rc = obd_fid_init(m->opd_obd, NULL, LUSTRE_SEQ_DATA);
- if (rc) {
- CERROR("%s: fid init error: rc = %d\n",
- m->opd_obd->obd_name, rc);
- GOTO(out_last_used, rc);
- }
/* Initialize precreation thread, it handles new
* connections as well. */
rc = osp_sync_init(env, m);
if (rc)
GOTO(out_precreat, rc);
-
}
+
/*
* Initiate connect to OST
*/
return 0;
}
+static int osp_prepare_fid_client(struct osp_device *osp)
+{
+ int rc;
+
+ LASSERT(osp->opd_obd->u.cli.cl_seq != NULL);
+ if (osp->opd_obd->u.cli.cl_seq->lcs_exp != NULL)
+ return 0;
+
+ LASSERT(osp->opd_exp != NULL);
+ osp->opd_obd->u.cli.cl_seq->lcs_exp =
+ class_export_get(osp->opd_exp);
+ if (osp->opd_pre == NULL)
+ return 0;
+
+ /* Init fid for osp_precreate if necessary */
+ rc = osp_init_pre_fid(osp);
+ if (rc != 0) {
+ class_export_put(osp->opd_exp);
+ osp->opd_obd->u.cli.cl_seq->lcs_exp = NULL;
+ CERROR("%s: init pre fid error: rc = %d\n",
+ osp->opd_obd->obd_name, rc);
+ return rc;
+ }
+
+ return 0;
+}
+
/*
* we use exports to track all LOD users
*/
d->opd_imp_connected = 0;
if (d->opd_connect_mdt)
break;
- osp_pre_update_status(d, -ENODEV);
- wake_up(&d->opd_pre_waitq);
+
+ if (d->opd_pre != NULL) {
+ osp_pre_update_status(d, -ENODEV);
+ wake_up(&d->opd_pre_waitq);
+ }
+
CDEBUG(D_HA, "got disconnected\n");
break;
case IMP_EVENT_INACTIVE:
d->opd_imp_active = 0;
if (d->opd_connect_mdt)
break;
- osp_pre_update_status(d, -ENODEV);
- wake_up(&d->opd_pre_waitq);
+
+ if (d->opd_pre != NULL) {
+ osp_pre_update_status(d, -ENODEV);
+ wake_up(&d->opd_pre_waitq);
+ }
+
CDEBUG(D_HA, "got inactive\n");
break;
case IMP_EVENT_ACTIVE:
d->opd_imp_active = 1;
+
+ if (osp_prepare_fid_client(d) != 0)
+ break;
+
if (d->opd_got_disconnected)
d->opd_new_connection = 1;
d->opd_imp_connected = 1;
d->opd_imp_seen_connected = 1;
if (d->opd_connect_mdt)
break;
- wake_up(&d->opd_pre_waitq);
+
+ if (d->opd_pre != NULL)
+ wake_up(&d->opd_pre_waitq);
+
__osp_sync_check_for_work(d);
CDEBUG(D_HA, "got connected\n");
break;
cfs_atomic_t otr_refcount;
};
+struct osp_precreate {
+ /*
+ * Precreation pool
+ */
+ spinlock_t osp_pre_lock;
+
+ /* last fid to assign in creation */
+ struct lu_fid osp_pre_used_fid;
+ /* last created id OST reported, next-created - available id's */
+ struct lu_fid osp_pre_last_created_fid;
+ /* how many ids are reserved in declare, we shouldn't block in create */
+ __u64 osp_pre_reserved;
+ /* thread waits for signals about pool going empty */
+ wait_queue_head_t osp_pre_waitq;
+ /* consumers (who needs new ids) wait here */
+ wait_queue_head_t osp_pre_user_waitq;
+ /* current precreation status: working, failed, stopping? */
+ int osp_pre_status;
+ /* how many to precreate next time */
+ int osp_pre_grow_count;
+ int osp_pre_min_grow_count;
+ int osp_pre_max_grow_count;
+ /* whether to grow precreation window next time or not */
+ int osp_pre_grow_slow;
+ /* cleaning up orphans or recreating missing objects */
+ int osp_pre_recovering;
+};
+
struct osp_device {
struct dt_device opd_dt_dev;
/* corresponded OST index */
* reported via ->ldo_recovery_complete() */
int opd_recovery_completed;
- /*
- * Precreation pool
- */
- spinlock_t opd_pre_lock;
-
- /* last fid to assign in creation */
- struct lu_fid opd_pre_used_fid;
- /* last created id OST reported, next-created - available id's */
- struct lu_fid opd_pre_last_created_fid;
- /* how many ids are reserved in declare, we shouldn't block in create */
- __u64 opd_pre_reserved;
+ /* precreate structure for OSP */
+ struct osp_precreate *opd_pre;
/* dedicate precreate thread */
struct ptlrpc_thread opd_pre_thread;
- /* thread waits for signals about pool going empty */
- wait_queue_head_t opd_pre_waitq;
- /* consumers (who needs new ids) wait here */
- wait_queue_head_t opd_pre_user_waitq;
- /* current precreation status: working, failed, stopping? */
- int opd_pre_status;
- /* how many to precreate next time */
- int opd_pre_grow_count;
- int opd_pre_min_grow_count;
- int opd_pre_max_grow_count;
- /* whether to grow precreation window next time or not */
- int opd_pre_grow_slow;
- /* cleaning up orphans or recreating missing objects */
- int opd_pre_recovering;
/*
* OST synchronization
cfs_proc_dir_entry_t *opd_symlink;
};
+#define opd_pre_lock opd_pre->osp_pre_lock
+#define opd_pre_used_fid opd_pre->osp_pre_used_fid
+#define opd_pre_last_created_fid opd_pre->osp_pre_last_created_fid
+#define opd_pre_reserved opd_pre->osp_pre_reserved
+#define opd_pre_waitq opd_pre->osp_pre_waitq
+#define opd_pre_user_waitq opd_pre->osp_pre_user_waitq
+#define opd_pre_status opd_pre->osp_pre_status
+#define opd_pre_grow_count opd_pre->osp_pre_grow_count
+#define opd_pre_min_grow_count opd_pre->osp_pre_min_grow_count
+#define opd_pre_max_grow_count opd_pre->osp_pre_max_grow_count
+#define opd_pre_grow_slow opd_pre->osp_pre_grow_slow
+#define opd_pre_recovering opd_pre->osp_pre_recovering
+
extern struct kmem_cache *osp_object_kmem;
/* this is a top object */
int osp_reset_last_used(const struct lu_env *env, struct osp_device *osp);
int osp_write_last_oid_seq_files(struct lu_env *env, struct osp_device *osp,
struct lu_fid *fid, int sync);
+int osp_init_pre_fid(struct osp_device *osp);
/* lproc_osp.c */
void lprocfs_osp_init_vars(struct lprocfs_static_vars *lvars);
int buf_count;
int rc;
-
update = osp_find_create_update_loc(th, dt);
if (IS_ERR(update)) {
CERROR("%s: Get OSP update buf failed: rc = %d\n",
if (!o->opo_reserved) {
/* special case, id was assigned outside of transaction
* see comments in osp_declare_attr_set */
+ LASSERT(d->opd_pre != NULL);
spin_lock(&d->opd_pre_lock);
osp_update_last_fid(d, fid);
spin_unlock(&d->opd_pre_lock);
/* we might have lost precreated objects */
if (unlikely(d->opd_gap_count) > 0) {
+ LASSERT(d->opd_pre != NULL);
spin_lock(&d->opd_pre_lock);
if (d->opd_gap_count > 0) {
int count = d->opd_gap_count;
* this may require lu_object_put() in LOD
*/
if (unlikely(po->opo_reserved)) {
+ LASSERT(d->opd_pre != NULL);
LASSERT(d->opd_pre_reserved > 0);
spin_lock(&d->opd_pre_lock);
d->opd_pre_reserved--;
wake_up(&d->opd_pre_user_waitq);
}
-static int osp_init_pre_fid(struct osp_device *osp)
+int osp_init_pre_fid(struct osp_device *osp)
{
struct lu_env env;
struct osp_thread_info *osi;
int rc;
ENTRY;
+ LASSERT(osp->opd_pre != NULL);
+
/* Return if last_used fid has been initialized */
if (!fid_is_zero(&osp->opd_last_used_fid))
RETURN(0);
break;
LASSERT(d->opd_obd->u.cli.cl_seq != NULL);
- if (d->opd_obd->u.cli.cl_seq->lcs_exp == NULL) {
- /* Get new sequence for client first */
- LASSERT(d->opd_exp != NULL);
- d->opd_obd->u.cli.cl_seq->lcs_exp =
- class_export_get(d->opd_exp);
- rc = osp_init_pre_fid(d);
- if (rc != 0) {
- class_export_put(d->opd_exp);
- d->opd_obd->u.cli.cl_seq->lcs_exp = NULL;
- CERROR("%s: init pre fid error: rc = %d\n",
- d->opd_obd->obd_name, rc);
- continue;
- }
- }
+ /* Sigh, fid client is not ready yet */
+ if (d->opd_obd->u.cli.cl_seq->lcs_exp == NULL)
+ continue;
osp_statfs_update(d);
ENTRY;
+ OBD_ALLOC_PTR(d->opd_pre);
+ if (d->opd_pre == NULL)
+ RETURN(-ENOMEM);
+
/* initially precreation isn't ready */
d->opd_pre_status = -EAGAIN;
fid_zero(&d->opd_pre_used_fid);
void osp_precreate_fini(struct osp_device *d)
{
- struct ptlrpc_thread *thread = &d->opd_pre_thread;
+ struct ptlrpc_thread *thread;
ENTRY;
cfs_timer_disarm(&d->opd_statfs_timer);
+ if (d->opd_pre == NULL)
+ RETURN_EXIT;
+
+ thread = &d->opd_pre_thread;
+
thread->t_flags = SVC_STOPPING;
wake_up(&d->opd_pre_waitq);
wait_event(thread->t_ctl_waitq, thread->t_flags & SVC_STOPPED);
+ OBD_FREE_PTR(d->opd_pre);
+ d->opd_pre = NULL;
+
EXIT;
}
rc, (unsigned) req->rq_transno);
LASSERT(rc || req->rq_transno);
+ LASSERT(d->opd_pre != NULL);
+
if (rc == -ENOENT) {
/*
* we tried to destroy object or update attributes,
* notice: we do this upon commit as well because some backends
* (like DMU) do not release space right away.
*/
+ LASSERT(d->opd_pre != NULL);
if (unlikely(d->opd_pre_status == -ENOSPC))
osp_statfs_need_now(d);