-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* GPL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Whamcloud, Inc.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
oti->oti_pre_version != curr_version) {
CDEBUG(D_INODE, "Version mismatch "LPX64" != "LPX64"\n",
oti->oti_pre_version, curr_version);
- spin_lock(&exp->exp_lock);
+ cfs_spin_lock(&exp->exp_lock);
exp->exp_vbr_failed = 1;
- spin_unlock(&exp->exp_lock);
+ cfs_spin_unlock(&exp->exp_lock);
RETURN (-EOVERFLOW);
}
oti->oti_pre_version = curr_version;
int filter_finish_transno(struct obd_export *exp, struct inode *inode,
struct obd_trans_info *oti, int rc, int force_sync)
{
- struct filter_obd *filter = &exp->exp_obd->u.filter;
- struct filter_export_data *fed = &exp->exp_filter_data;
- struct lsd_client_data *lcd = fed->fed_lcd;
+ struct obd_device_target *obt = &exp->exp_obd->u.obt;
+ struct tg_export_data *ted = &exp->exp_target_data;
+ struct lr_server_data *lsd = class_server_data(exp->exp_obd);
+ struct lsd_client_data *lcd;
__u64 last_rcvd;
loff_t off;
int err, log_pri = D_RPCTRACE;
if (!exp->exp_obd->obd_replayable || oti == NULL)
RETURN(rc);
+ cfs_mutex_lock(&ted->ted_lcd_lock);
+ lcd = ted->ted_lcd;
+ /* if the export has already been disconnected, we have no last_rcvd slot,
+ * update server data with latest transno then */
+ if (lcd == NULL) {
+ cfs_mutex_unlock(&ted->ted_lcd_lock);
+ CWARN("commit transaction for disconnected client %s: rc %d\n",
+ exp->exp_client_uuid.uuid, rc);
+ err = filter_update_server_data(exp->exp_obd);
+ RETURN(err);
+ }
+
/* we don't allocate new transnos for replayed requests */
- spin_lock(&filter->fo_translock);
+ cfs_spin_lock(&obt->obt_lut->lut_translock);
if (oti->oti_transno == 0) {
- last_rcvd = le64_to_cpu(filter->fo_fsd->lsd_last_transno) + 1;
- filter->fo_fsd->lsd_last_transno = cpu_to_le64(last_rcvd);
+ last_rcvd = le64_to_cpu(lsd->lsd_last_transno) + 1;
+ lsd->lsd_last_transno = cpu_to_le64(last_rcvd);
+ LASSERT(last_rcvd >= le64_to_cpu(lcd->lcd_last_transno));
} else {
last_rcvd = oti->oti_transno;
- if (last_rcvd > le64_to_cpu(filter->fo_fsd->lsd_last_transno))
- filter->fo_fsd->lsd_last_transno =
- cpu_to_le64(last_rcvd);
+ if (last_rcvd > le64_to_cpu(lsd->lsd_last_transno))
+ lsd->lsd_last_transno = cpu_to_le64(last_rcvd);
+ if (unlikely(last_rcvd < le64_to_cpu(lcd->lcd_last_transno))) {
+ CERROR("Trying to overwrite bigger transno, on-disk: "
+ LPU64", new: "LPU64"\n",
+ le64_to_cpu(lcd->lcd_last_transno), last_rcvd);
+ cfs_spin_lock(&exp->exp_lock);
+ exp->exp_vbr_failed = 1;
+ cfs_spin_unlock(&exp->exp_lock);
+ cfs_spin_unlock(&obt->obt_lut->lut_translock);
+ cfs_mutex_unlock(&ted->ted_lcd_lock);
+ RETURN(-EOVERFLOW);
+ }
}
oti->oti_transno = last_rcvd;
- LASSERT(last_rcvd >= le64_to_cpu(lcd->lcd_last_transno));
lcd->lcd_last_transno = cpu_to_le64(last_rcvd);
lcd->lcd_pre_versions[0] = cpu_to_le64(oti->oti_pre_version);
lcd->lcd_last_xid = cpu_to_le64(oti->oti_xid);
- spin_unlock(&filter->fo_translock);
+ cfs_spin_unlock(&obt->obt_lut->lut_translock);
if (inode)
fsfilt_set_version(exp->exp_obd, inode, last_rcvd);
- off = fed->fed_lr_off;
+ off = ted->ted_lr_off;
if (off <= 0) {
CERROR("%s: client idx %d is %lld\n", exp->exp_obd->obd_name,
- fed->fed_lr_idx, fed->fed_lr_off);
+ ted->ted_lr_idx, ted->ted_lr_off);
err = -EINVAL;
} else {
class_export_cb_get(exp); /* released when the cb is called */
filter_commit_cb,
exp);
- err = fsfilt_write_record(exp->exp_obd, filter->fo_rcvd_filp,
+ err = fsfilt_write_record(exp->exp_obd, obt->obt_rcvd_filp,
lcd, sizeof(*lcd), &off,
force_sync | exp->exp_need_sync);
if (force_sync)
}
CDEBUG(log_pri, "wrote trans "LPU64" for client %s at #%d: err = %d\n",
- last_rcvd, lcd->lcd_uuid, fed->fed_lr_idx, err);
-
+ last_rcvd, lcd->lcd_uuid, ted->ted_lr_idx, err);
+ cfs_mutex_unlock(&ted->ted_lcd_lock);
RETURN(rc);
}
{
int i;
for (i = 0; i < BRW_LAST; i++)
- spin_lock_init(&brw_stats->hist[i].oh_lock);
+ cfs_spin_lock_init(&brw_stats->hist[i].oh_lock);
}
static int lprocfs_init_rw_stats(struct obd_device *obd,
OBD_ALLOC(tmp->nid_brw_stats, sizeof(struct brw_stats));
if (tmp->nid_brw_stats == NULL)
- RETURN(-ENOMEM);
+ GOTO(clean, rc = -ENOMEM);
init_brw_stats(tmp->nid_brw_stats);
rc = lprocfs_seq_create(exp->exp_nid_stats->nid_proc, "brw_stats",
rc = lprocfs_init_rw_stats(obd, &exp->exp_nid_stats->nid_stats);
if (rc)
- RETURN(rc);
+ GOTO(clean, rc);
rc = lprocfs_register_stats(tmp->nid_proc, "stats",
tmp->nid_stats);
if (rc)
- RETURN(rc);
- /* Always add in ldlm_stats */
- tmp->nid_ldlm_stats =
- lprocfs_alloc_stats(LDLM_LAST_OPC - LDLM_FIRST_OPC,
- LPROCFS_STATS_FLAG_NOPERCPU);
- if (tmp->nid_ldlm_stats == NULL)
- return -ENOMEM;
-
- lprocfs_init_ldlm_stats(tmp->nid_ldlm_stats);
- rc = lprocfs_register_stats(tmp->nid_proc, "ldlm_stats",
- tmp->nid_ldlm_stats);
+ GOTO(clean, rc);
+ rc = lprocfs_nid_ldlm_stats_init(tmp);
if (rc)
- RETURN(rc);
+ GOTO(clean, rc);
}
RETURN(0);
+ clean:
+ return rc;
}
/* Add client data to the FILTER. We use a bitmap to locate a free space
static int filter_client_add(struct obd_device *obd, struct obd_export *exp,
int cl_idx)
{
- struct filter_obd *filter = &obd->u.filter;
- struct filter_export_data *fed = &exp->exp_filter_data;
- unsigned long *bitmap = filter->fo_last_rcvd_slots;
+ struct obd_device_target *obt = &obd->u.obt;
+ struct tg_export_data *ted = &exp->exp_target_data;
+ struct lr_server_data *lsd = class_server_data(obd);
+ unsigned long *bitmap = obt->obt_lut->lut_client_bitmap;
int new_client = (cl_idx == -1);
ENTRY;
LASSERTF(cl_idx > -2, "%d\n", cl_idx);
/* Self-export */
- if (strcmp(fed->fed_lcd->lcd_uuid, obd->obd_uuid.uuid) == 0)
+ if (strcmp(ted->ted_lcd->lcd_uuid, obd->obd_uuid.uuid) == 0)
RETURN(0);
/* the bitmap operations can handle cl_idx > sizeof(long) * 8, so
* there's no need for extra complication here
*/
if (new_client) {
- cl_idx = find_first_zero_bit(bitmap, LR_MAX_CLIENTS);
+ cl_idx = cfs_find_first_zero_bit(bitmap, LR_MAX_CLIENTS);
repeat:
if (cl_idx >= LR_MAX_CLIENTS) {
CERROR("no room for %u client - fix LR_MAX_CLIENTS\n",
cl_idx);
RETURN(-EOVERFLOW);
}
- if (test_and_set_bit(cl_idx, bitmap)) {
- cl_idx = find_next_zero_bit(bitmap, LR_MAX_CLIENTS,
- cl_idx);
+ if (cfs_test_and_set_bit(cl_idx, bitmap)) {
+ cl_idx = cfs_find_next_zero_bit(bitmap, LR_MAX_CLIENTS,
+ cl_idx);
goto repeat;
}
} else {
- if (test_and_set_bit(cl_idx, bitmap)) {
+ if (cfs_test_and_set_bit(cl_idx, bitmap)) {
CERROR("FILTER client %d: bit already set in bitmap!\n",
cl_idx);
LBUG();
}
}
- fed->fed_lr_idx = cl_idx;
- fed->fed_lr_off = le32_to_cpu(filter->fo_fsd->lsd_client_start) +
- cl_idx * le16_to_cpu(filter->fo_fsd->lsd_client_size);
- LASSERTF(fed->fed_lr_off > 0, "fed_lr_off = %llu\n", fed->fed_lr_off);
+ ted->ted_lr_idx = cl_idx;
+ ted->ted_lr_off = le32_to_cpu(lsd->lsd_client_start) +
+ cl_idx * le16_to_cpu(lsd->lsd_client_size);
+ cfs_mutex_init(&ted->ted_lcd_lock);
+ LASSERTF(ted->ted_lr_off > 0, "ted_lr_off = %llu\n", ted->ted_lr_off);
CDEBUG(D_INFO, "client at index %d (%llu) with UUID '%s' added\n",
- fed->fed_lr_idx, fed->fed_lr_off, fed->fed_lcd->lcd_uuid);
+ ted->ted_lr_idx, ted->ted_lr_off, ted->ted_lcd->lcd_uuid);
if (new_client) {
struct lvfs_run_ctxt saved;
- loff_t off = fed->fed_lr_off;
+ loff_t off = ted->ted_lr_off;
int rc;
void *handle;
CDEBUG(D_INFO, "writing client lcd at idx %u (%llu) (len %u)\n",
- fed->fed_lr_idx,off,(unsigned int)sizeof(*fed->fed_lcd));
+ ted->ted_lr_idx,off,(unsigned int)sizeof(*ted->ted_lcd));
+
+ if (OBD_FAIL_CHECK(OBD_FAIL_TGT_CLIENT_ADD))
+ RETURN(-ENOSPC);
push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
/* Transaction needed to fix bug 1403 */
handle = fsfilt_start(obd,
- filter->fo_rcvd_filp->f_dentry->d_inode,
+ obt->obt_rcvd_filp->f_dentry->d_inode,
FSFILT_OP_SETATTR, NULL);
if (IS_ERR(handle)) {
rc = PTR_ERR(handle);
CERROR("unable to start transaction: rc %d\n", rc);
} else {
- fed->fed_lcd->lcd_last_epoch =
- filter->fo_fsd->lsd_start_epoch;
+ ted->ted_lcd->lcd_last_epoch = lsd->lsd_start_epoch;
exp->exp_last_request_time = cfs_time_current_sec();
rc = fsfilt_add_journal_cb(obd, 0, handle,
- target_client_add_cb, exp);
+ target_client_add_cb,
+ class_export_cb_get(exp));
if (rc == 0) {
- spin_lock(&exp->exp_lock);
+ cfs_spin_lock(&exp->exp_lock);
exp->exp_need_sync = 1;
- spin_unlock(&exp->exp_lock);
+ cfs_spin_unlock(&exp->exp_lock);
}
- rc = fsfilt_write_record(obd, filter->fo_rcvd_filp,
- fed->fed_lcd,
- sizeof(*fed->fed_lcd),
+ rc = fsfilt_write_record(obd, obt->obt_rcvd_filp,
+ ted->ted_lcd,
+ sizeof(*ted->ted_lcd),
&off, rc /* sync if no cb */);
fsfilt_commit(obd,
- filter->fo_rcvd_filp->f_dentry->d_inode,
+ obt->obt_rcvd_filp->f_dentry->d_inode,
handle, 0);
}
pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
if (rc) {
CERROR("error writing %s client idx %u: rc %d\n",
- LAST_RCVD, fed->fed_lr_idx, rc);
+ LAST_RCVD, ted->ted_lr_idx, rc);
RETURN(rc);
}
}
RETURN(0);
}
-struct lsd_client_data zero_lcd; /* globals are implicitly zeroed */
-
-static int filter_client_free(struct obd_export *exp)
+static int filter_client_del(struct obd_export *exp)
{
- struct filter_export_data *fed = &exp->exp_filter_data;
- struct filter_obd *filter = &exp->exp_obd->u.filter;
- struct obd_device *obd = exp->exp_obd;
+ struct tg_export_data *ted = &exp->exp_target_data;
+ struct obd_device_target *obt = &exp->exp_obd->u.obt;
struct lvfs_run_ctxt saved;
int rc;
loff_t off;
ENTRY;
- if (fed->fed_lcd == NULL)
+ if (ted->ted_lcd == NULL)
RETURN(0);
/* XXX if lcd_uuid were a real obd_uuid, I could use obd_uuid_equals */
- if (strcmp(fed->fed_lcd->lcd_uuid, obd->obd_uuid.uuid ) == 0)
+ if (strcmp(ted->ted_lcd->lcd_uuid, exp->exp_obd->obd_uuid.uuid ) == 0)
GOTO(free, 0);
- LASSERT(filter->fo_last_rcvd_slots != NULL);
+ LASSERT(obt->obt_lut->lut_client_bitmap != NULL);
- off = fed->fed_lr_off;
+ off = ted->ted_lr_off;
CDEBUG(D_INFO, "freeing client at idx %u, offset %lld with UUID '%s'\n",
- fed->fed_lr_idx, fed->fed_lr_off, fed->fed_lcd->lcd_uuid);
+ ted->ted_lr_idx, ted->ted_lr_off, ted->ted_lcd->lcd_uuid);
- /* Don't clear fed_lr_idx here as it is likely also unset. At worst
+ /* Don't clear ted_lr_idx here as it is likely also unset. At worst
* we leak a client slot that will be cleaned on the next recovery. */
if (off <= 0) {
CERROR("%s: client idx %d has med_off %lld\n",
- obd->obd_name, fed->fed_lr_idx, off);
+ exp->exp_obd->obd_name, ted->ted_lr_idx, off);
GOTO(free, rc = -EINVAL);
}
/* Clear the bit _after_ zeroing out the client so we don't
race with filter_client_add and zero out new clients.*/
- if (!test_bit(fed->fed_lr_idx, filter->fo_last_rcvd_slots)) {
+ if (!cfs_test_bit(ted->ted_lr_idx, obt->obt_lut->lut_client_bitmap)) {
CERROR("FILTER client %u: bit already clear in bitmap!!\n",
- fed->fed_lr_idx);
+ ted->ted_lr_idx);
LBUG();
}
- if (!(exp->exp_flags & OBD_OPT_FAILOVER)) {
- /* Don't force sync on disconnect if aborting recovery,
- * or it does num_clients * num_osts. b=17194 */
- int need_sync = exp->exp_need_sync &&
- !(exp->exp_flags&OBD_OPT_ABORT_RECOV);
- push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
- rc = fsfilt_write_record(obd, filter->fo_rcvd_filp, &zero_lcd,
- sizeof(zero_lcd), &off, 0);
-
- /* Make sure the server's last_transno is up to date. Do this
- * after the client is freed so we know all the client's
- * transactions have been committed. */
- if (rc == 0)
- filter_update_server_data(obd, filter->fo_rcvd_filp,
- filter->fo_fsd, need_sync);
- pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-
- CDEBUG(rc == 0 ? D_INFO : D_ERROR,
- "zero out client %s at idx %u/%llu in %s %ssync rc %d\n",
- fed->fed_lcd->lcd_uuid, fed->fed_lr_idx, fed->fed_lr_off,
- LAST_RCVD, need_sync ? "" : "a", rc);
- }
-
- if (!test_and_clear_bit(fed->fed_lr_idx, filter->fo_last_rcvd_slots)) {
- CERROR("FILTER client %u: bit already clear in bitmap!!\n",
- fed->fed_lr_idx);
- LBUG();
- }
+ push_ctxt(&saved, &exp->exp_obd->obd_lvfs_ctxt, NULL);
+ /* Make sure the server's last_transno is up to date.
+ * This should be done before zeroing client slot so last_transno will
+ * be in server data or in client data in case of failure */
+ filter_update_server_data(exp->exp_obd);
+
+ cfs_mutex_lock(&ted->ted_lcd_lock);
+ memset(ted->ted_lcd->lcd_uuid, 0, sizeof ted->ted_lcd->lcd_uuid);
+ rc = fsfilt_write_record(exp->exp_obd, obt->obt_rcvd_filp,
+ ted->ted_lcd,
+ sizeof(*ted->ted_lcd), &off, 0);
+ cfs_mutex_unlock(&ted->ted_lcd_lock);
+ pop_ctxt(&saved, &exp->exp_obd->obd_lvfs_ctxt, NULL);
+ CDEBUG(rc == 0 ? D_INFO : D_ERROR,
+ "zero out client %s at idx %u/%llu in %s, rc %d\n",
+ ted->ted_lcd->lcd_uuid, ted->ted_lr_idx, ted->ted_lr_off,
+ LAST_RCVD, rc);
EXIT;
free:
- OBD_FREE_PTR(fed->fed_lcd);
- fed->fed_lcd = NULL;
-
return 0;
}
/* XXX when we have persistent reservations and the handle
* is stored herein we need to drop it here. */
fed->fed_mod_count--;
- list_del(&fmd->fmd_list);
+ cfs_list_del(&fmd->fmd_list);
OBD_SLAB_FREE(fmd, ll_fmd_cachep, sizeof(*fmd));
}
}
return;
fed = &exp->exp_filter_data;
- spin_lock(&fed->fed_lock);
+ cfs_spin_lock(&fed->fed_lock);
filter_fmd_put_nolock(fed, fmd); /* caller reference */
- spin_unlock(&fed->fed_lock);
+ cfs_spin_unlock(&fed->fed_lock);
}
/* expire entries from the end of the list if there are too many
{
struct filter_mod_data *fmd, *tmp;
- list_for_each_entry_safe(fmd, tmp, &fed->fed_mod_list, fmd_list) {
+ cfs_list_for_each_entry_safe(fmd, tmp, &fed->fed_mod_list, fmd_list) {
if (fmd == keep)
break;
- if (time_before(jiffies, fmd->fmd_expire) &&
+ if (cfs_time_before(jiffies, fmd->fmd_expire) &&
fed->fed_mod_count < filter->fo_fmd_max_num)
break;
- list_del_init(&fmd->fmd_list);
+ cfs_list_del_init(&fmd->fmd_list);
filter_fmd_put_nolock(fed, fmd); /* list reference */
}
}
void filter_fmd_expire(struct obd_export *exp)
{
- spin_lock(&exp->exp_filter_data.fed_lock);
+ cfs_spin_lock(&exp->exp_filter_data.fed_lock);
filter_fmd_expire_nolock(&exp->exp_obd->u.filter,
&exp->exp_filter_data, NULL);
- spin_unlock(&exp->exp_filter_data.fed_lock);
+ cfs_spin_unlock(&exp->exp_filter_data.fed_lock);
}
/* find specified objid, group in export fmd list.
* caller must hold fed_lock and take fmd reference itself */
static struct filter_mod_data *filter_fmd_find_nolock(struct filter_obd *filter,
struct filter_export_data *fed,
- obd_id objid, obd_gr group)
+ obd_id objid, obd_seq group)
{
struct filter_mod_data *found = NULL, *fmd;
LASSERT_SPIN_LOCKED(&fed->fed_lock);
- list_for_each_entry_reverse(fmd, &fed->fed_mod_list, fmd_list) {
+ cfs_list_for_each_entry_reverse(fmd, &fed->fed_mod_list, fmd_list) {
if (fmd->fmd_id == objid && fmd->fmd_gr == group) {
found = fmd;
- list_del(&fmd->fmd_list);
- list_add_tail(&fmd->fmd_list, &fed->fed_mod_list);
+ cfs_list_del(&fmd->fmd_list);
+ cfs_list_add_tail(&fmd->fmd_list, &fed->fed_mod_list);
fmd->fmd_expire = jiffies + filter->fo_fmd_max_age;
break;
}
/* Find fmd based on objid and group, or return NULL if not found. */
struct filter_mod_data *filter_fmd_find(struct obd_export *exp,
- obd_id objid, obd_gr group)
+ obd_id objid, obd_seq group)
{
struct filter_mod_data *fmd;
- spin_lock(&exp->exp_filter_data.fed_lock);
+ cfs_spin_lock(&exp->exp_filter_data.fed_lock);
fmd = filter_fmd_find_nolock(&exp->exp_obd->u.filter,
&exp->exp_filter_data, objid, group);
if (fmd)
fmd->fmd_refcount++; /* caller reference */
- spin_unlock(&exp->exp_filter_data.fed_lock);
+ cfs_spin_unlock(&exp->exp_filter_data.fed_lock);
return fmd;
}
* Currently this is not fatal because any fmd state is transient and
* may also be freed when it gets sufficiently old. */
struct filter_mod_data *filter_fmd_get(struct obd_export *exp,
- obd_id objid, obd_gr group)
+ obd_id objid, obd_seq group)
{
struct filter_export_data *fed = &exp->exp_filter_data;
struct filter_mod_data *found = NULL, *fmd_new = NULL;
OBD_SLAB_ALLOC_PTR_GFP(fmd_new, ll_fmd_cachep, CFS_ALLOC_IO);
- spin_lock(&fed->fed_lock);
+ cfs_spin_lock(&fed->fed_lock);
found = filter_fmd_find_nolock(&exp->exp_obd->u.filter,fed,objid,group);
if (fmd_new) {
if (found == NULL) {
- list_add_tail(&fmd_new->fmd_list, &fed->fed_mod_list);
+ cfs_list_add_tail(&fmd_new->fmd_list,
+ &fed->fed_mod_list);
fmd_new->fmd_id = objid;
fmd_new->fmd_gr = group;
fmd_new->fmd_refcount++; /* list reference */
exp->exp_obd->u.filter.fo_fmd_max_age;
}
- spin_unlock(&fed->fed_lock);
+ cfs_spin_unlock(&fed->fed_lock);
return found;
}
* This isn't so critical because it would in fact only affect the one client
* that is doing the unlink and at worst we have an stale entry referencing
* an object that should never be used again. */
-static void filter_fmd_drop(struct obd_export *exp, obd_id objid, obd_gr group)
+static void filter_fmd_drop(struct obd_export *exp, obd_id objid, obd_seq group)
{
struct filter_mod_data *found = NULL;
- spin_lock(&exp->exp_filter_data.fed_lock);
+ cfs_spin_lock(&exp->exp_filter_data.fed_lock);
found = filter_fmd_find_nolock(&exp->exp_filter_data, objid, group);
if (found) {
- list_del_init(&found->fmd_list);
+ cfs_list_del_init(&found->fmd_list);
filter_fmd_put_nolock(&exp->exp_filter_data, found);
}
- spin_unlock(&exp->exp_filter_data.fed_lock);
+ cfs_spin_unlock(&exp->exp_filter_data.fed_lock);
}
#else
#define filter_fmd_drop(exp, objid, group)
struct filter_export_data *fed = &exp->exp_filter_data;
struct filter_mod_data *fmd = NULL, *tmp;
- spin_lock(&fed->fed_lock);
- list_for_each_entry_safe(fmd, tmp, &fed->fed_mod_list, fmd_list) {
- list_del_init(&fmd->fmd_list);
+ cfs_spin_lock(&fed->fed_lock);
+ cfs_list_for_each_entry_safe(fmd, tmp, &fed->fed_mod_list, fmd_list) {
+ cfs_list_del_init(&fmd->fmd_list);
filter_fmd_put_nolock(fed, fmd);
}
- spin_unlock(&fed->fed_lock);
+ cfs_spin_unlock(&fed->fed_lock);
}
static int filter_init_export(struct obd_export *exp)
{
- spin_lock_init(&exp->exp_filter_data.fed_lock);
+ int rc;
+ ENTRY;
+
+ cfs_spin_lock_init(&exp->exp_filter_data.fed_lock);
CFS_INIT_LIST_HEAD(&exp->exp_filter_data.fed_mod_list);
- spin_lock(&exp->exp_lock);
+ cfs_spin_lock(&exp->exp_lock);
exp->exp_connecting = 1;
- spin_unlock(&exp->exp_lock);
+ cfs_spin_unlock(&exp->exp_lock);
+
+ /* self-export doesn't need client data and ldlm initialization */
+ if (unlikely(obd_uuid_equals(&exp->exp_obd->obd_uuid,
+ &exp->exp_client_uuid)))
+ RETURN(0);
+
+ rc = lut_client_alloc(exp);
+ if (rc == 0)
+ rc = ldlm_init_export(exp);
+ if (rc)
+ CERROR("%s: Can't initialize export: rc %d\n",
+ exp->exp_obd->obd_name, rc);
- return ldlm_init_export(exp);
+ RETURN(rc);
}
-static int filter_free_server_data(struct filter_obd *filter)
+static int filter_free_server_data(struct obd_device_target *obt)
{
- OBD_FREE_PTR(filter->fo_fsd);
- filter->fo_fsd = NULL;
- OBD_FREE(filter->fo_last_rcvd_slots, LR_MAX_CLIENTS / 8);
- filter->fo_last_rcvd_slots = NULL;
+ lut_fini(NULL, obt->obt_lut);
+ OBD_FREE_PTR(obt->obt_lut);
return 0;
}
/* assumes caller is already in kernel ctxt */
-int filter_update_server_data(struct obd_device *obd, struct file *filp,
- struct lr_server_data *fsd, int force_sync)
+int filter_update_server_data(struct obd_device *obd)
{
+ struct file *filp = obd->u.obt.obt_rcvd_filp;
+ struct lr_server_data *lsd = class_server_data(obd);
loff_t off = 0;
int rc;
ENTRY;
- CDEBUG(D_INODE, "server uuid : %s\n", fsd->lsd_uuid);
+ CDEBUG(D_INODE, "server uuid : %s\n", lsd->lsd_uuid);
CDEBUG(D_INODE, "server last_rcvd : "LPU64"\n",
- le64_to_cpu(fsd->lsd_last_transno));
+ le64_to_cpu(lsd->lsd_last_transno));
CDEBUG(D_INODE, "server last_mount: "LPU64"\n",
- le64_to_cpu(fsd->lsd_mount_count));
+ le64_to_cpu(lsd->lsd_mount_count));
- rc = fsfilt_write_record(obd, filp, fsd, sizeof(*fsd), &off, force_sync);
+ rc = fsfilt_write_record(obd, filp, lsd, sizeof(*lsd), &off, 0);
if (rc)
CERROR("error writing lr_server_data: rc = %d\n", rc);
RETURN(rc);
}
-int filter_update_last_objid(struct obd_device *obd, obd_gr group,
+int filter_update_last_objid(struct obd_device *obd, obd_seq group,
int force_sync)
{
struct filter_obd *filter = &obd->u.filter;
ENTRY;
if (filter->fo_last_objid_files[group] == NULL) {
- CERROR("Object group "LPU64" not fully setup; not updating "
+ CERROR("Object seq "LPU64" not fully setup; not updating "
"last_objid\n", group);
RETURN(-EINVAL);
}
- CDEBUG(D_INODE, "%s: server last_objid for group "LPU64": "LPU64"\n",
- obd->obd_name, group, filter->fo_last_objids[group]);
+ CDEBUG(D_INODE, "%s: server last_objid for "POSTID"\n",
+ obd->obd_name, filter->fo_last_objids[group], group);
tmp = cpu_to_le64(filter->fo_last_objids[group]);
rc = fsfilt_write_record(obd, filter->fo_last_objid_files[group],
&tmp, sizeof(tmp), &off, force_sync);
if (rc)
- CERROR("error writing group "LPU64" last objid: rc = %d\n",
+ CERROR("error writing seq "LPU64" last objid: rc = %d\n",
group, rc);
RETURN(rc);
}
static int filter_init_server_data(struct obd_device *obd, struct file * filp)
{
struct filter_obd *filter = &obd->u.filter;
- struct lr_server_data *fsd;
+ struct lr_server_data *lsd;
struct lsd_client_data *lcd = NULL;
struct inode *inode = filp->f_dentry->d_inode;
unsigned long last_rcvd_size = i_size_read(inode);
+ struct lu_target *lut;
__u64 mount_count;
__u32 start_epoch;
int cl_idx;
/* ensure padding in the struct is the correct size */
CLASSERT (offsetof(struct lr_server_data, lsd_padding) +
- sizeof(fsd->lsd_padding) == LR_SERVER_SIZE);
+ sizeof(lsd->lsd_padding) == LR_SERVER_SIZE);
CLASSERT (offsetof(struct lsd_client_data, lcd_padding) +
sizeof(lcd->lcd_padding) == LR_CLIENT_SIZE);
- OBD_ALLOC(fsd, sizeof(*fsd));
- if (!fsd)
- RETURN(-ENOMEM);
- filter->fo_fsd = fsd;
-
- OBD_ALLOC(filter->fo_last_rcvd_slots, LR_MAX_CLIENTS / 8);
- if (filter->fo_last_rcvd_slots == NULL) {
- OBD_FREE(fsd, sizeof(*fsd));
+ /* allocate and initialize lu_target */
+ OBD_ALLOC_PTR(lut);
+ if (lut == NULL)
RETURN(-ENOMEM);
- }
-
+ rc = lut_init(NULL, lut, obd, NULL);
+ if (rc)
+ GOTO(err_lut, rc);
+ lsd = class_server_data(obd);
if (last_rcvd_size == 0) {
LCONSOLE_WARN("%s: new disk, initializing\n", obd->obd_name);
- memcpy(fsd->lsd_uuid, obd->obd_uuid.uuid,sizeof(fsd->lsd_uuid));
- fsd->lsd_last_transno = 0;
- mount_count = fsd->lsd_mount_count = 0;
- fsd->lsd_server_size = cpu_to_le32(LR_SERVER_SIZE);
- fsd->lsd_client_start = cpu_to_le32(LR_CLIENT_START);
- fsd->lsd_client_size = cpu_to_le16(LR_CLIENT_SIZE);
- fsd->lsd_subdir_count = cpu_to_le16(FILTER_SUBDIR_COUNT);
+ memcpy(lsd->lsd_uuid, obd->obd_uuid.uuid,sizeof(lsd->lsd_uuid));
+ lsd->lsd_last_transno = 0;
+ mount_count = lsd->lsd_mount_count = 0;
+ lsd->lsd_server_size = cpu_to_le32(LR_SERVER_SIZE);
+ lsd->lsd_client_start = cpu_to_le32(LR_CLIENT_START);
+ lsd->lsd_client_size = cpu_to_le16(LR_CLIENT_SIZE);
+ lsd->lsd_subdir_count = cpu_to_le16(FILTER_SUBDIR_COUNT);
filter->fo_subdir_count = FILTER_SUBDIR_COUNT;
/* OBD_COMPAT_OST is set in filter_connect_internal when the
* MDS first connects and assigns the OST index number. */
- fsd->lsd_feature_incompat = cpu_to_le32(OBD_INCOMPAT_COMMON_LR|
+ lsd->lsd_feature_incompat = cpu_to_le32(OBD_INCOMPAT_COMMON_LR|
OBD_INCOMPAT_OST);
} else {
- rc = fsfilt_read_record(obd, filp, fsd, sizeof(*fsd), &off);
+ rc = fsfilt_read_record(obd, filp, lsd, sizeof(*lsd), &off);
if (rc) {
CDEBUG(D_INODE,"OBD filter: error reading %s: rc %d\n",
LAST_RCVD, rc);
- GOTO(err_fsd, rc);
+ GOTO(err_lut, rc);
}
- if (strcmp(fsd->lsd_uuid, obd->obd_uuid.uuid) != 0) {
+ if (strcmp(lsd->lsd_uuid, obd->obd_uuid.uuid) != 0) {
LCONSOLE_ERROR_MSG(0x134, "Trying to start OBD %s "
"using the wrong disk %s. Were the "
"/dev/ assignments rearranged?\n",
- obd->obd_uuid.uuid, fsd->lsd_uuid);
- GOTO(err_fsd, rc = -EINVAL);
+ obd->obd_uuid.uuid, lsd->lsd_uuid);
+ GOTO(err_lut, rc = -EINVAL);
}
- mount_count = le64_to_cpu(fsd->lsd_mount_count);
- filter->fo_subdir_count = le16_to_cpu(fsd->lsd_subdir_count);
+ mount_count = le64_to_cpu(lsd->lsd_mount_count);
+ filter->fo_subdir_count = le16_to_cpu(lsd->lsd_subdir_count);
/* COMPAT_146 */
/* Assume old last_rcvd format unless I_C_LR is set */
- if (!(fsd->lsd_feature_incompat &
+ if (!(lsd->lsd_feature_incompat &
cpu_to_le32(OBD_INCOMPAT_COMMON_LR)))
- fsd->lsd_last_transno = fsd->lsd_compat14;
+ lsd->lsd_last_transno = lsd->lsd_compat14;
/* end COMPAT_146 */
/* OBD_COMPAT_OST is set in filter_connect_internal when the
* MDS first connects and assigns the OST index number. */
- fsd->lsd_feature_incompat |= cpu_to_le32(OBD_INCOMPAT_COMMON_LR|
+ lsd->lsd_feature_incompat |= cpu_to_le32(OBD_INCOMPAT_COMMON_LR|
OBD_INCOMPAT_OST);
}
- if (fsd->lsd_feature_incompat & ~cpu_to_le32(FILTER_INCOMPAT_SUPP)) {
+ if (lsd->lsd_feature_incompat & ~cpu_to_le32(FILTER_INCOMPAT_SUPP)) {
CERROR("%s: unsupported incompat filesystem feature(s) %x\n",
- obd->obd_name, le32_to_cpu(fsd->lsd_feature_incompat) &
+ obd->obd_name, le32_to_cpu(lsd->lsd_feature_incompat) &
~FILTER_INCOMPAT_SUPP);
- GOTO(err_fsd, rc = -EINVAL);
+ GOTO(err_lut, rc = -EINVAL);
}
- if (fsd->lsd_feature_rocompat & ~cpu_to_le32(FILTER_ROCOMPAT_SUPP)) {
+ if (lsd->lsd_feature_rocompat & ~cpu_to_le32(FILTER_ROCOMPAT_SUPP)) {
CERROR("%s: unsupported read-only filesystem feature(s) %x\n",
- obd->obd_name, le32_to_cpu(fsd->lsd_feature_rocompat) &
+ obd->obd_name, le32_to_cpu(lsd->lsd_feature_rocompat) &
~FILTER_ROCOMPAT_SUPP);
/* Do something like remount filesystem read-only */
- GOTO(err_fsd, rc = -EINVAL);
+ GOTO(err_lut, rc = -EINVAL);
}
- start_epoch = le32_to_cpu(fsd->lsd_start_epoch);
+ start_epoch = le32_to_cpu(lsd->lsd_start_epoch);
CDEBUG(D_INODE, "%s: server start_epoch : %#x\n",
obd->obd_name, start_epoch);
CDEBUG(D_INODE, "%s: server last_transno : "LPX64"\n",
- obd->obd_name, le64_to_cpu(fsd->lsd_last_transno));
+ obd->obd_name, le64_to_cpu(lsd->lsd_last_transno));
CDEBUG(D_INODE, "%s: server mount_count: "LPU64"\n",
obd->obd_name, mount_count + 1);
CDEBUG(D_INODE, "%s: server data size: %u\n",
- obd->obd_name, le32_to_cpu(fsd->lsd_server_size));
+ obd->obd_name, le32_to_cpu(lsd->lsd_server_size));
CDEBUG(D_INODE, "%s: per-client data start: %u\n",
- obd->obd_name, le32_to_cpu(fsd->lsd_client_start));
+ obd->obd_name, le32_to_cpu(lsd->lsd_client_start));
CDEBUG(D_INODE, "%s: per-client data size: %u\n",
- obd->obd_name, le32_to_cpu(fsd->lsd_client_size));
+ obd->obd_name, le32_to_cpu(lsd->lsd_client_size));
CDEBUG(D_INODE, "%s: server subdir_count: %u\n",
- obd->obd_name, le16_to_cpu(fsd->lsd_subdir_count));
+ obd->obd_name, le16_to_cpu(lsd->lsd_subdir_count));
CDEBUG(D_INODE, "%s: last_rcvd clients: %lu\n", obd->obd_name,
- last_rcvd_size <= le32_to_cpu(fsd->lsd_client_start) ? 0 :
- (last_rcvd_size - le32_to_cpu(fsd->lsd_client_start)) /
- le16_to_cpu(fsd->lsd_client_size));
+ last_rcvd_size <= le32_to_cpu(lsd->lsd_client_start) ? 0 :
+ (last_rcvd_size - le32_to_cpu(lsd->lsd_client_start)) /
+ le16_to_cpu(lsd->lsd_client_size));
if (!obd->obd_replayable) {
CWARN("%s: recovery support OFF\n", obd->obd_name);
GOTO(out, rc = 0);
}
- for (cl_idx = 0, off = le32_to_cpu(fsd->lsd_client_start);
+ OBD_ALLOC_PTR(lcd);
+ if (!lcd)
+ GOTO(err_client, rc = -ENOMEM);
+
+ for (cl_idx = 0, off = le32_to_cpu(lsd->lsd_client_start);
off < last_rcvd_size; cl_idx++) {
__u64 last_rcvd;
struct obd_export *exp;
struct filter_export_data *fed;
- if (!lcd) {
- OBD_ALLOC_PTR(lcd);
- if (!lcd)
- GOTO(err_client, rc = -ENOMEM);
- }
-
/* Don't assume off is incremented properly by
* fsfilt_read_record(), in case sizeof(*lcd)
- * isn't the same as fsd->lsd_client_size. */
- off = le32_to_cpu(fsd->lsd_client_start) +
- cl_idx * le16_to_cpu(fsd->lsd_client_size);
+ * isn't the same as lsd->lsd_client_size. */
+ off = le32_to_cpu(lsd->lsd_client_start) +
+ cl_idx * le16_to_cpu(lsd->lsd_client_size);
rc = fsfilt_read_record(obd, filp, lcd, sizeof(*lcd), &off);
if (rc) {
CERROR("error reading FILT %s idx %d off %llu: rc %d\n",
continue;
}
+ check_lcd(obd->obd_name, cl_idx, lcd);
+
last_rcvd = le64_to_cpu(lcd->lcd_last_transno);
+ CDEBUG(D_HA, "RCVRNG CLIENT uuid: %s idx: %d lr: "LPU64
+ " srv lr: "LPU64"\n", lcd->lcd_uuid, cl_idx,
+ last_rcvd, le64_to_cpu(lsd->lsd_last_transno));
+
/* These exports are cleaned up by filter_disconnect(), so they
* need to be set up like real exports as filter_connect() does.
*/
exp = class_new_export(obd, (struct obd_uuid *)lcd->lcd_uuid);
-
- CDEBUG(D_HA, "RCVRNG CLIENT uuid: %s idx: %d lr: "LPU64
- " srv lr: "LPU64"\n", lcd->lcd_uuid, cl_idx,
- last_rcvd, le64_to_cpu(fsd->lsd_last_transno));
if (IS_ERR(exp)) {
if (PTR_ERR(exp) == -EALREADY) {
/* export already exists, zero out this one */
- CERROR("Zeroing out duplicate export due to "
- "bug 10479.\n");
- lcd->lcd_uuid[0] = '\0';
- } else {
- GOTO(err_client, rc = PTR_ERR(exp));
+ CERROR("Duplicate export %s!\n", lcd->lcd_uuid);
+ continue;
}
- } else {
- fed = &exp->exp_filter_data;
- fed->fed_lcd = lcd;
- fed->fed_group = 0; /* will be assigned at connect */
- filter_export_stats_init(obd, exp, NULL);
- rc = filter_client_add(obd, exp, cl_idx);
- /* can't fail for existing client */
- LASSERTF(rc == 0, "rc = %d\n", rc);
-
- /* VBR: set export last committed */
- exp->exp_last_committed = last_rcvd;
- spin_lock(&exp->exp_lock);
- exp->exp_connecting = 0;
- exp->exp_in_recovery = 0;
- spin_unlock(&exp->exp_lock);
- spin_lock_bh(&obd->obd_processing_task_lock);
- obd->obd_max_recoverable_clients++;
- spin_unlock_bh(&obd->obd_processing_task_lock);
- lcd = NULL;
- class_export_put(exp);
+ OBD_FREE_PTR(lcd);
+ GOTO(err_client, rc = PTR_ERR(exp));
}
- /* Need to check last_rcvd even for duplicated exports. */
- CDEBUG(D_OTHER, "client at idx %d has last_rcvd = "LPU64"\n",
- cl_idx, last_rcvd);
-
- if (last_rcvd > le64_to_cpu(fsd->lsd_last_transno))
- fsd->lsd_last_transno = cpu_to_le64(last_rcvd);
- }
-
- if (lcd)
- OBD_FREE_PTR(lcd);
-
- obd->obd_last_committed = le64_to_cpu(fsd->lsd_last_transno);
+ fed = &exp->exp_filter_data;
+ *fed->fed_ted.ted_lcd = *lcd;
+ fed->fed_group = 0; /* will be assigned at connect */
+ filter_export_stats_init(obd, exp, NULL);
+ rc = filter_client_add(obd, exp, cl_idx);
+ /* can't fail for existing client */
+ LASSERTF(rc == 0, "rc = %d\n", rc);
+
+ /* VBR: set export last committed */
+ exp->exp_last_committed = last_rcvd;
+ cfs_spin_lock(&exp->exp_lock);
+ exp->exp_connecting = 0;
+ exp->exp_in_recovery = 0;
+ cfs_spin_unlock(&exp->exp_lock);
+ obd->obd_max_recoverable_clients++;
+ class_export_put(exp);
+
+ if (last_rcvd > le64_to_cpu(lsd->lsd_last_transno))
+ lsd->lsd_last_transno = cpu_to_le64(last_rcvd);
+ }
+ OBD_FREE_PTR(lcd);
+
+ obd->obd_last_committed = le64_to_cpu(lsd->lsd_last_transno);
out:
- filter->fo_mount_count = mount_count + 1;
- fsd->lsd_mount_count = cpu_to_le64(filter->fo_mount_count);
+ 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 */
- rc = filter_update_server_data(obd, filp, filter->fo_fsd, 1);
+ rc = filter_update_server_data(obd);
if (rc)
GOTO(err_client, rc);
err_client:
class_disconnect_exports(obd);
-err_fsd:
- filter_free_server_data(filter);
+err_lut:
+ filter_free_server_data(&obd->u.obt);
RETURN(rc);
}
RETURN(PTR_ERR(dentry));
}
} else {
- dentry = simple_mkdir(filter->fo_dentry_O, filter->fo_vfsmnt,
- name, 0700, 1);
+ dentry = simple_mkdir(filter->fo_dentry_O,
+ obd->u.obt.obt_vfsmnt, name, 0700, 1);
if (IS_ERR(dentry)) {
CERROR("cannot lookup/create O/%s: rc = %ld\n", name,
PTR_ERR(dentry));
GOTO(cleanup, rc);
}
- if (filter->fo_subdir_count && filter_group_is_mds(group)) {
+ if (filter->fo_subdir_count && fid_seq_is_mdt(group)) {
OBD_ALLOC(tmp_subdirs, sizeof(*tmp_subdirs));
if (tmp_subdirs == NULL)
GOTO(cleanup, rc = -ENOMEM);
snprintf(dir, sizeof(dir), "d%u", i);
tmp_subdirs->dentry[i] = simple_mkdir(dentry,
- filter->fo_vfsmnt,
+ obd->u.obt.obt_vfsmnt,
dir, 0700, 1);
if (IS_ERR(tmp_subdirs->dentry[i])) {
rc = PTR_ERR(tmp_subdirs->dentry[i]);
filter->fo_dentry_O_groups[group] = dentry;
filter->fo_last_objid_files[group] = filp;
- if (filter->fo_subdir_count && filter_group_is_mds(group)) {
+ if (filter->fo_subdir_count && fid_seq_is_mdt(group)) {
filter->fo_dentry_O_sub[group] = *tmp_subdirs;
OBD_FREE(tmp_subdirs, sizeof(*tmp_subdirs));
}
if (new_files != NULL)
OBD_FREE(new_files, len * sizeof(*new_files));
case 3:
- if (filter->fo_subdir_count && filter_group_is_mds(group)) {
+ if (filter->fo_subdir_count && fid_seq_is_mdt(group)) {
for (i = 0; i < filter->fo_subdir_count; i++) {
if (tmp_subdirs->dentry[i] != NULL)
dput(tmp_subdirs->dentry[i]);
struct filter_obd *filter = &obd->u.filter;
int old_count, group, rc = 0;
- down(&filter->fo_init_lock);
+ cfs_mutex_lock(&filter->fo_init_lock);
old_count = filter->fo_group_count;
for (group = old_count; group <= last_group; group++) {
rc = filter_read_group_internal(obd, group, create);
if (rc != 0)
break;
}
- up(&filter->fo_init_lock);
+ cfs_mutex_unlock(&filter->fo_init_lock);
return rc;
}
loff_t off = 0;
ENTRY;
- O_dentry = simple_mkdir(current->fs->pwd, filter->fo_vfsmnt,
+ 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;
* 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 = FILTER_GROUP_MDS0;
+ last_group = FID_SEQ_OST_MDT0;
- CWARN("%s: initialize groups [%d,%d]\n", obd->obd_name,
- FILTER_GROUP_MDS0, 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)
LAST_RCVD, rc);
GOTO(out, rc);
}
- filter->fo_rcvd_filp = file;
+ obd->u.obt.obt_rcvd_filp = file;
if (!S_ISREG(file->f_dentry->d_inode->i_mode)) {
CERROR("%s is not a regular file!: mode = %o\n", LAST_RCVD,
file->f_dentry->d_inode->i_mode);
GOTO(err_filp, rc = -EOPNOTSUPP);
}
- /** lu_target has very limited use in filter now */
- lut_init(NULL, &filter->fo_lut, obd, NULL);
-
rc = filter_init_server_data(obd, file);
if (rc) {
CERROR("cannot read %s: rc = %d\n", LAST_RCVD, rc);
GOTO(err_filp, rc);
}
-
- target_recovery_init(&filter->fo_lut, ost_handle);
+ LASSERT(obd->u.obt.obt_lut);
+ target_recovery_init(obd->u.obt.obt_lut, ost_handle);
/* open and create health check io file*/
file = filp_open(HEALTH_CHECK, O_RDWR | O_CREAT, 0644);
filter->fo_obt.obt_health_check_filp = NULL;
err_server_data:
target_recovery_fini(obd);
- filter_free_server_data(filter);
+ filter_free_server_data(&obd->u.obt);
err_filp:
- if (filp_close(filter->fo_rcvd_filp, 0))
+ if (filp_close(obd->u.obt.obt_rcvd_filp, 0))
CERROR("can't close %s after error\n", LAST_RCVD);
- filter->fo_rcvd_filp = NULL;
+ obd->u.obt.obt_rcvd_filp = NULL;
goto out;
}
* from lastobjid */
push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
- rc = filter_update_server_data(obd, filter->fo_rcvd_filp,
- filter->fo_fsd, 0);
+ rc = filter_update_server_data(obd);
if (rc)
CERROR("error writing server data: rc = %d\n", rc);
i, rc);
}
- rc = filp_close(filter->fo_rcvd_filp, 0);
- filter->fo_rcvd_filp = NULL;
+ rc = filp_close(obd->u.obt.obt_rcvd_filp, 0);
+ obd->u.obt.obt_rcvd_filp = NULL;
if (rc)
CERROR("error closing %s: rc = %d\n", LAST_RCVD, rc);
CERROR("error closing %s: rc = %d\n", HEALTH_CHECK, rc);
filter_cleanup_groups(obd);
- filter_free_server_data(filter);
+ filter_free_server_data(&obd->u.obt);
pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
filter_free_capa_keys(filter);
}
static void filter_set_last_id(struct filter_obd *filter,
- obd_id id, obd_gr group)
+ obd_id id, obd_seq group)
{
- LASSERT(filter->fo_fsd != NULL);
LASSERT(group <= filter->fo_group_count);
- spin_lock(&filter->fo_objidlock);
+ cfs_spin_lock(&filter->fo_objidlock);
filter->fo_last_objids[group] = id;
- spin_unlock(&filter->fo_objidlock);
+ cfs_spin_unlock(&filter->fo_objidlock);
}
-obd_id filter_last_id(struct filter_obd *filter, obd_gr group)
+obd_id filter_last_id(struct filter_obd *filter, obd_seq group)
{
obd_id id;
- LASSERT(filter->fo_fsd != NULL);
LASSERT(group <= filter->fo_group_count);
+ LASSERT(filter->fo_last_objids != NULL);
/* FIXME: object groups */
- spin_lock(&filter->fo_objidlock);
+ cfs_spin_lock(&filter->fo_objidlock);
id = filter->fo_last_objids[group];
- spin_unlock(&filter->fo_objidlock);
+ cfs_spin_unlock(&filter->fo_objidlock);
return id;
}
}
/* We never dget the object parent, so DON'T dput it either */
-struct dentry *filter_parent(struct obd_device *obd, obd_gr group, obd_id objid)
+struct dentry *filter_parent(struct obd_device *obd, obd_seq group, obd_id objid)
{
struct filter_obd *filter = &obd->u.filter;
struct filter_subdirs *subdirs;
- LASSERT(group < filter->fo_group_count); /* FIXME: object groups */
- if (!filter_group_is_mds(group) || filter->fo_subdir_count == 0)
+ if (group >= filter->fo_group_count) /* FIXME: object groups */
+ return ERR_PTR(-EBADF);
+
+ if (!fid_seq_is_mdt(group) || filter->fo_subdir_count == 0)
return filter->fo_dentry_O_groups[group];
subdirs = &filter->fo_dentry_O_sub[group];
}
/* We never dget the object parent, so DON'T dput it either */
-struct dentry *filter_parent_lock(struct obd_device *obd, obd_gr group,
+struct dentry *filter_parent_lock(struct obd_device *obd, obd_seq group,
obd_id objid)
{
unsigned long now = jiffies;
* internal to the filesystem code. */
struct dentry *filter_fid2dentry(struct obd_device *obd,
struct dentry *dir_dentry,
- obd_gr group, obd_id id)
+ obd_seq group, obd_id id)
{
struct dentry *dparent = dir_dentry;
struct dentry *dchild;
obd->u.filter.fo_destroys_in_progress == 0) {
/* don't fail lookups for orphan recovery, it causes
* later LBUGs when objects still exist during precreate */
- CDEBUG(D_INFO, "*** obd_fail_loc=%x ***\n",OBD_FAIL_OST_ENOENT);
+ CDEBUG(D_INFO, "*** cfs_fail_loc=%x ***\n",OBD_FAIL_OST_ENOENT);
RETURN(ERR_PTR(-ENOENT));
}
if (id == 0) {
if (dir_dentry == NULL) {
dparent = filter_parent_lock(obd, group, id);
if (IS_ERR(dparent)) {
- CERROR("%s: error getting object "LPU64":"LPU64
+ CERROR("%s: error getting object "POSTID
" parent: rc %ld\n", obd->obd_name,
id, group, PTR_ERR(dparent));
RETURN(dparent);
}
CDEBUG(D_INODE, "looking up object O/%.*s/%s\n",
dparent->d_name.len, dparent->d_name.name, name);
- dchild = /*ll_*/lookup_one_len(name, dparent, len);
+ /* dparent is already locked here, so we cannot use ll_lookup_one_len() */
+ dchild = lookup_one_len(name, dparent, len);
if (dir_dentry == NULL)
filter_parent_unlock(dparent);
if (IS_ERR(dchild)) {
- CERROR("%s: child lookup error %ld\n", obd->obd_name,
- PTR_ERR(dchild));
+ CERROR("%s: object "LPU64":"LPU64" lookup error: rc %ld\n",
+ obd->obd_name, id, group, PTR_ERR(dchild));
RETURN(dchild);
}
rc = ldlm_cli_enqueue_local(obd->obd_namespace, &res_id, LDLM_EXTENT,
&policy, LCK_PW, &flags, ldlm_blocking_ast,
ldlm_completion_ast, NULL, NULL, 0, NULL,
- NULL, lockh);
+ lockh);
if (rc != ELDLM_OK)
lockh->cookie = 0;
RETURN(rc);
static void filter_fini_destroy(struct obd_device *obd,
struct lustre_handle *lockh)
{
- if (lockh->cookie)
+ if (lustre_handle_is_used(lockh))
ldlm_lock_decref(lockh, LCK_PW);
}
GOTO(out, rc = -EPERM);
/* check_sticky() */
- if ((dentry->d_inode->i_uid != current->fsuid &&
+ if ((dentry->d_inode->i_uid != cfs_curproc_fsuid() &&
!cfs_capable(CFS_CAP_FOWNER)) || IS_APPEND(dentry->d_inode) ||
IS_IMMUTABLE(dentry->d_inode))
GOTO(out, rc = -EPERM);
- /* NOTE: This might need to go outside i_mutex, though it isn't clear if
- * that was done because of journal_start (which is already done
- * here) or some other ordering issue. */
- DQUOT_INIT(dir);
+ /* Locking order: i_mutex -> journal_lock -> dqptr_sem. LU-952 */
+ ll_vfs_dq_init(dir);
rc = ll_security_inode_unlink(dir, dentry, mnt);
if (rc)
* Caller must hold child i_mutex, we drop it always.
* Caller is also required to ensure that dchild->d_inode exists. */
static int filter_destroy_internal(struct obd_device *obd, obd_id objid,
- obd_gr group, struct dentry *dparent,
+ obd_seq group, struct dentry *dparent,
struct dentry *dchild)
{
struct inode *inode = dchild->d_inode;
- struct filter_obd *filter = &obd->u.filter;
int rc;
- if (inode->i_nlink != 1 || atomic_read(&inode->i_count) != 1) {
+ /* There should be 2 references to the inode:
+ * 1) taken by filter_prepare_destroy
+ * 2) taken by filter_destroy */
+ if (inode->i_nlink != 1 || atomic_read(&inode->i_count) != 2) {
CERROR("destroying objid %.*s ino %lu nlink %lu count %d\n",
dchild->d_name.len, dchild->d_name.name, inode->i_ino,
(unsigned long)inode->i_nlink,
atomic_read(&inode->i_count));
}
- rc = filter_vfs_unlink(dparent->d_inode, dchild, filter->fo_vfsmnt);
+ rc = filter_vfs_unlink(dparent->d_inode, dchild, obd->u.obt.obt_vfsmnt);
if (rc)
CERROR("error unlinking objid %.*s: rc %d\n",
dchild->d_name.len, dchild->d_name.name, rc);
if (interval_high(n) <= size)
return INTERVAL_ITER_STOP;
- list_for_each_entry(lck, &node->li_group, l_sl_policy) {
+ cfs_list_for_each_entry(lck, &node->li_group, l_sl_policy) {
/* Don't send glimpse ASTs to liblustre clients.
* They aren't listening for them, and they do
* entirely synchronous I/O anyways. */
struct ldlm_lock **lockp, void *req_cookie,
ldlm_mode_t mode, int flags, void *data)
{
- CFS_LIST_HEAD(rpc_list);
struct ptlrpc_request *req = req_cookie;
struct ldlm_lock *lock = *lockp, *l = NULL;
struct ldlm_resource *res = lock->l_resource;
* lock, and should not be granted if the lock will be blocked.
*/
- LASSERT(ns == res->lr_namespace);
- lock_res(res);
- rc = policy(lock, &tmpflags, 0, &err, &rpc_list);
- check_res_locked(res);
+ if (flags & LDLM_FL_BLOCK_NOWAIT) {
+ OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_AGL_DELAY, 5);
- /* FIXME: we should change the policy function slightly, to not make
- * this list at all, since we just turn around and free it */
- while (!list_empty(&rpc_list)) {
- struct ldlm_lock *wlock =
- list_entry(rpc_list.next, struct ldlm_lock, l_cp_ast);
- LASSERT((lock->l_flags & LDLM_FL_AST_SENT) == 0);
- LASSERT(lock->l_flags & LDLM_FL_CP_REQD);
- lock->l_flags &= ~LDLM_FL_CP_REQD;
- list_del_init(&wlock->l_cp_ast);
- LDLM_LOCK_RELEASE(wlock);
+ if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_AGL_NOLOCK))
+ RETURN(ELDLM_LOCK_ABORTED);
}
+ LASSERT(ns == ldlm_res_to_ns(res));
+ lock_res(res);
+ rc = policy(lock, &tmpflags, 0, &err, NULL);
+ check_res_locked(res);
+
/* The lock met with no resistance; we're finished. */
if (rc == LDLM_ITER_CONTINUE) {
/* do not grant locks to the liblustre clients: they cannot
* handle ASTs robustly. We need to do this while still
- * holding ns_lock to avoid the lock remaining on the res_link
+ * holding lr_lock to avoid the lock remaining on the res_link
* list (and potentially being added to l_pending_list by an
* AST) when we are going to drop this lock ASAP. */
if (lock->l_export->exp_libclient ||
}
unlock_res(res);
RETURN(err);
+ } else if (flags & LDLM_FL_BLOCK_NOWAIT) {
+ /* LDLM_FL_BLOCK_NOWAIT means it is for AGL. Do not send glimpse
+ * callback for glimpse size. The real size user will trigger
+ * the glimpse callback when necessary. */
+ unlock_res(res);
+ RETURN(ELDLM_LOCK_ABORTED);
}
/* Do not grant any lock, but instead send GL callbacks. The extent
*reply_lvb = *res_lvb;
/*
- * ->ns_lock guarantees that no new locks are granted, and,
+ * lr_lock guarantees that no new locks are granted, and,
* therefore, that res->lr_lvb_data cannot increase beyond the
* end of already granted lock. As a result, it is safe to
* check against "stale" reply_lvb->lvb_size value without
- * res->lr_lvb_sem.
+ * res->lr_lvb_mutex.
*/
arg.size = reply_lvb->lvb_size;
arg.victim = &l;
*
* Of course, this will all disappear when we switch to
* taking liblustre locks on the OST. */
- ldlm_res_lvbo_update(res, NULL, 0, 1);
+ ldlm_res_lvbo_update(res, NULL, 1);
}
RETURN(ELDLM_LOCK_ABORTED);
}
LASSERTF(l->l_glimpse_ast != NULL, "l == %p", l);
rc = l->l_glimpse_ast(l, NULL); /* this will update the LVB */
- /* Update the LVB from disk if the AST failed (this is a legal race) */
- /*
- * XXX nikita: situation when ldlm_server_glimpse_ast() failed before
- * sending ast is not handled. This can result in lost client writes.
- */
- if (rc != 0)
- ldlm_res_lvbo_update(res, NULL, 0, 1);
lock_res(res);
*reply_lvb = *res_lvb;
sptlrpc_target_update_exp_flavor(obd, &tmp_rset);
- write_lock(&filter->fo_sptlrpc_lock);
+ cfs_write_lock(&filter->fo_sptlrpc_lock);
sptlrpc_rule_set_free(&filter->fo_sptlrpc_rset);
filter->fo_sptlrpc_rset = tmp_rset;
- write_unlock(&filter->fo_sptlrpc_lock);
+ cfs_write_unlock(&filter->fo_sptlrpc_lock);
return 0;
}
OBD_ALLOC_GFP(filter->fo_iobuf_pool, OSS_THREADS_MAX * sizeof(*pool),
- GFP_KERNEL);
+ CFS_ALLOC_KERNEL);
if (filter->fo_iobuf_pool == NULL)
RETURN(-ENOMEM);
{
struct filter_obd *filter = &obd->u.filter;
struct vfsmount *mnt;
+ struct file_system_type *type;
struct lustre_mount_info *lmi;
struct obd_uuid uuid;
__u8 *uuid_ptr;
char *str, *label;
char ns_name[48];
- request_queue_t *q;
+ struct request_queue *q;
int rc, i;
ENTRY;
} else {
/* old path - used by lctl */
CERROR("Using old MDS mount method\n");
- mnt = ll_kern_mount(lustre_cfg_string(lcfg, 2),
- MS_NOATIME|MS_NODIRATIME,
- lustre_cfg_string(lcfg, 1), option);
+ type = get_fs_type(lustre_cfg_string(lcfg, 2));
+ if (!type) {
+ CERROR("get_fs_type failed\n");
+ RETURN(-ENODEV);
+ }
+ mnt = vfs_kern_mount(type, MS_NOATIME|MS_NODIRATIME,
+ lustre_cfg_string(lcfg, 1), option);
+ cfs_module_put(type->owner);
if (IS_ERR(mnt)) {
rc = PTR_ERR(mnt);
LCONSOLE_ERROR_MSG(0x135, "Can't mount disk %s (%d)\n",
/* 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')) {
}
}
- filter->fo_vfsmnt = mnt;
+ obd->u.obt.obt_magic = OBT_MAGIC;
+ obd->u.obt.obt_vfsmnt = mnt;
obd->u.obt.obt_sb = mnt->mnt_sb;
filter->fo_fstype = mnt->mnt_sb->s_type->name;
CDEBUG(D_SUPER, "%s: mnt = %p\n", filter->fo_fstype, mnt);
- fsfilt_setup(obd, obd->u.obt.obt_sb);
+ rc = fsfilt_setup(obd, obd->u.obt.obt_sb);
+ if (rc)
+ GOTO(err_ops, rc);
OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt);
obd->obd_lvfs_ctxt.pwdmnt = mnt;
obd->obd_lvfs_ctxt.fs = get_ds();
obd->obd_lvfs_ctxt.cb_ops = filter_lvfs_ops;
- init_mutex(&filter->fo_init_lock);
+ cfs_mutex_init(&filter->fo_init_lock);
filter->fo_committed_group = 0;
filter->fo_destroys_in_progress = 0;
for (i = 0; i < 32; i++)
- sema_init(&filter->fo_create_locks[i], 1);
+ cfs_mutex_init(&filter->fo_create_locks[i]);
- spin_lock_init(&filter->fo_translock);
- spin_lock_init(&filter->fo_objidlock);
+ cfs_spin_lock_init(&filter->fo_objidlock);
CFS_INIT_LIST_HEAD(&filter->fo_export_list);
- sema_init(&filter->fo_alloc_lock, 1);
+ cfs_mutex_init(&filter->fo_alloc_lock);
init_brw_stats(&filter->fo_filter_stats);
+ cfs_spin_lock_init(&filter->fo_flags_lock);
filter->fo_read_cache = 1; /* enable read-only cache by default */
filter->fo_writethrough_cache = 1; /* enable writethrough cache */
filter->fo_readcache_max_filesize = FILTER_MAX_CACHE_SIZE;
filter->fo_fmd_max_num = FILTER_FMD_MAX_NUM_DEFAULT;
filter->fo_fmd_max_age = FILTER_FMD_MAX_AGE_DEFAULT;
+ filter->fo_syncjournal = 0; /* Don't sync journals on i/o by default */
+ filter_slc_set(filter); /* initialize sync on lock cancel */
rc = filter_prep(obd);
if (rc)
GOTO(err_ops, rc);
CFS_INIT_LIST_HEAD(&filter->fo_llog_list);
- spin_lock_init(&filter->fo_llog_list_lock);
+ cfs_spin_lock_init(&filter->fo_llog_list_lock);
filter->fo_fl_oss_capa = 1;
GOTO(err_post, rc = -ENOMEM);
sprintf(ns_name, "filter-%s", obd->obd_uuid.uuid);
- obd->obd_namespace = ldlm_namespace_new(obd, ns_name, LDLM_NAMESPACE_SERVER,
- LDLM_NAMESPACE_GREEDY);
+ obd->obd_namespace = ldlm_namespace_new(obd, ns_name,
+ LDLM_NAMESPACE_SERVER,
+ LDLM_NAMESPACE_GREEDY,
+ LDLM_NS_TYPE_OST);
if (obd->obd_namespace == NULL)
GOTO(err_post, rc = -ENOMEM);
obd->obd_namespace->ns_lvbp = obd;
GOTO(err_post, rc);
}
- rwlock_init(&filter->fo_sptlrpc_lock);
+ cfs_rwlock_init(&filter->fo_sptlrpc_lock);
sptlrpc_rule_set_init(&filter->fo_sptlrpc_rset);
/* do this after llog being initialized */
filter_adapt_sptlrpc_conf(obd, 1);
GOTO(err_post, rc);
q = bdev_get_queue(mnt->mnt_sb->s_bdev);
- if (q->max_sectors < q->max_hw_sectors &&
- q->max_sectors < PTLRPC_MAX_BRW_SIZE >> 9)
+ if (queue_max_sectors(q) < queue_max_hw_sectors(q) &&
+ queue_max_sectors(q) < PTLRPC_MAX_BRW_SIZE >> 9)
LCONSOLE_INFO("%s: underlying device %s should be tuned "
"for larger I/O requests: max_sectors = %u "
"could be up to max_hw_sectors=%u\n",
obd->obd_name, mnt->mnt_sb->s_id,
- q->max_sectors, q->max_hw_sectors);
+ queue_max_sectors(q), queue_max_hw_sectors(q));
uuid_ptr = fsfilt_uuid(obd, obd->u.obt.obt_sb);
if (uuid_ptr != NULL) {
}
label = fsfilt_get_label(obd, obd->u.obt.obt_sb);
-
- if (obd->obd_recovering) {
- LCONSOLE_WARN("OST %s now serving %s (%s%s%s), but will be in "
- "recovery for at least %d:%.02d, or until %d "
- "client%s reconnect%s.\n",
- obd->obd_name, lustre_cfg_string(lcfg, 1),
- label ?: "", label ? "/" : "", str,
- 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":"");
- } else {
- LCONSOLE_INFO("OST %s now serving %s (%s%s%s) with recovery "
- "%s\n", obd->obd_name, lustre_cfg_string(lcfg, 1),
- label ?: "", label ? "/" : "", str,
- obd->obd_replayable ? "enabled" : "disabled");
- }
+ LCONSOLE_INFO("%s: Now serving %s %s%s with recovery %s\n",
+ obd->obd_name, label ?: str, lmi ? "on " : "",
+ lmi ? s2lsi(lmi->lmi_sb)->lsi_lmd->lmd_dev : "",
+ obd->obd_replayable ? "enabled" : "disabled");
RETURN(0);
static int filter_setup(struct obd_device *obd, struct lustre_cfg* lcfg)
{
struct lprocfs_static_vars lvars;
+ cfs_proc_dir_entry_t *entry;
unsigned long addr;
struct page *page;
int rc;
+ ENTRY;
CLASSERT(offsetof(struct obd_device, u.obt) ==
offsetof(struct obd_device, u.filter.fo_obt));
if (!LUSTRE_CFG_BUFLEN(lcfg, 1) || !LUSTRE_CFG_BUFLEN(lcfg, 2))
RETURN(-EINVAL);
- /* 2.6.9 selinux wants a full option page for do_kern_mount (bug6471) */
- OBD_PAGE_ALLOC(page, CFS_ALLOC_STD);
- if (!page)
- RETURN(-ENOMEM);
- addr = (unsigned long)cfs_page_address(page);
- clear_page((void *)addr);
-
/* lprocfs must be setup before the filter so state can be safely added
* to /proc incrementally as the filter is setup */
lprocfs_filter_init_vars(&lvars);
- if (lprocfs_obd_setup(obd, lvars.obd_vars) == 0 &&
- lprocfs_alloc_obd_stats(obd, LPROC_FILTER_LAST) == 0) {
- /* Init obdfilter private stats here */
- lprocfs_counter_init(obd->obd_stats, LPROC_FILTER_READ_BYTES,
- LPROCFS_CNTR_AVGMINMAX,
- "read_bytes", "bytes");
- lprocfs_counter_init(obd->obd_stats, LPROC_FILTER_WRITE_BYTES,
- LPROCFS_CNTR_AVGMINMAX,
- "write_bytes", "bytes");
- lprocfs_counter_init(obd->obd_stats, LPROC_FILTER_GET_PAGE,
- LPROCFS_CNTR_AVGMINMAX|LPROCFS_CNTR_STDDEV,
- "get_page", "usec");
- lprocfs_counter_init(obd->obd_stats, LPROC_FILTER_NO_PAGE,
- LPROCFS_CNTR_AVGMINMAX,
- "get_page_failures", "num");
- lprocfs_counter_init(obd->obd_stats, LPROC_FILTER_CACHE_ACCESS,
- LPROCFS_CNTR_AVGMINMAX,
- "cache_access", "pages");
- lprocfs_counter_init(obd->obd_stats, LPROC_FILTER_CACHE_HIT,
- LPROCFS_CNTR_AVGMINMAX,
- "cache_hit", "pages");
- lprocfs_counter_init(obd->obd_stats, LPROC_FILTER_CACHE_MISS,
- LPROCFS_CNTR_AVGMINMAX,
- "cache_miss", "pages");
-
- lproc_filter_attach_seqstat(obd);
- obd->obd_proc_exports_entry = lprocfs_register("exports",
- obd->obd_proc_entry,
- NULL, NULL);
- if (IS_ERR(obd->obd_proc_exports_entry)) {
- rc = PTR_ERR(obd->obd_proc_exports_entry);
- CERROR("error %d setting up lprocfs for %s\n",
- rc, "exports");
- obd->obd_proc_exports_entry = NULL;
- }
+ rc = lprocfs_obd_setup(obd, lvars.obd_vars);
+ if (rc) {
+ CERROR("%s: lprocfs_obd_setup failed: %d.\n",
+ obd->obd_name, rc);
+ RETURN(rc);
+ }
+
+ rc = lprocfs_alloc_obd_stats(obd, LPROC_FILTER_LAST);
+ if (rc) {
+ CERROR("%s: lprocfs_alloc_obd_stats failed: %d.\n",
+ obd->obd_name, rc);
+ GOTO(obd_cleanup, rc);
+ }
+
+ /* Init obdfilter private stats here */
+ lprocfs_counter_init(obd->obd_stats, LPROC_FILTER_READ_BYTES,
+ LPROCFS_CNTR_AVGMINMAX, "read_bytes", "bytes");
+ lprocfs_counter_init(obd->obd_stats, LPROC_FILTER_WRITE_BYTES,
+ LPROCFS_CNTR_AVGMINMAX, "write_bytes", "bytes");
+ lprocfs_counter_init(obd->obd_stats, LPROC_FILTER_GET_PAGE,
+ LPROCFS_CNTR_AVGMINMAX|LPROCFS_CNTR_STDDEV,
+ "get_page", "usec");
+ lprocfs_counter_init(obd->obd_stats, LPROC_FILTER_NO_PAGE,
+ LPROCFS_CNTR_AVGMINMAX, "get_page_failures", "num");
+ lprocfs_counter_init(obd->obd_stats, LPROC_FILTER_CACHE_ACCESS,
+ LPROCFS_CNTR_AVGMINMAX, "cache_access", "pages");
+ lprocfs_counter_init(obd->obd_stats, LPROC_FILTER_CACHE_HIT,
+ LPROCFS_CNTR_AVGMINMAX, "cache_hit", "pages");
+ lprocfs_counter_init(obd->obd_stats, LPROC_FILTER_CACHE_MISS,
+ LPROCFS_CNTR_AVGMINMAX, "cache_miss", "pages");
+
+ rc = lproc_filter_attach_seqstat(obd);
+ if (rc) {
+ CERROR("%s: create seqstat failed: %d.\n", obd->obd_name, rc);
+ GOTO(free_obd_stats, rc);
+ }
+
+ entry = lprocfs_register("exports", obd->obd_proc_entry, NULL, NULL);
+ if (IS_ERR(entry)) {
+ rc = PTR_ERR(entry);
+ CERROR("%s: error %d setting up lprocfs for %s\n",
+ obd->obd_name, rc, "exports");
+ GOTO(free_obd_stats, rc);
}
- if (obd->obd_proc_exports_entry)
- lprocfs_add_simple(obd->obd_proc_exports_entry, "clear",
+ obd->obd_proc_exports_entry = entry;
+
+ entry = lprocfs_add_simple(obd->obd_proc_exports_entry, "clear",
lprocfs_nid_stats_clear_read,
lprocfs_nid_stats_clear_write, obd, NULL);
+ if (IS_ERR(entry)) {
+ rc = PTR_ERR(entry);
+ CERROR("%s: add proc entry 'clear' failed: %d.\n",
+ obd->obd_name, rc);
+ GOTO(free_obd_stats, rc);
+ }
+
+ rc = lprocfs_job_stats_init(obd, LPROC_FILTER_STATS_LAST,
+ filter_stats_counter_init);
+ if (rc)
+ GOTO(remove_entry_clear, rc);
+ /* 2.6.9 selinux wants a full option page for do_kern_mount (bug6471) */
+ OBD_PAGE_ALLOC(page, CFS_ALLOC_STD);
+ if (!page)
+ GOTO(job_stats_fini, rc = -ENOMEM);
+ addr = (unsigned long)cfs_page_address(page);
+ clear_page((void *)addr);
memcpy((void *)addr, lustre_cfg_buf(lcfg, 4),
LUSTRE_CFG_BUFLEN(lcfg, 4));
rc = filter_common_setup(obd, lcfg, (void *)addr);
OBD_PAGE_FREE(page);
-
if (rc) {
- lprocfs_remove_proc_entry("clear", obd->obd_proc_exports_entry);
- lprocfs_free_per_client_stats(obd);
- lprocfs_free_obd_stats(obd);
- lprocfs_obd_cleanup(obd);
+ CERROR("%s: filter_common_setup failed: %d.\n",
+ obd->obd_name, rc);
+ GOTO(job_stats_fini, rc);
}
+ RETURN(0);
+
+job_stats_fini:
+ lprocfs_job_stats_fini(obd);
+remove_entry_clear:
+ lprocfs_remove_proc_entry("clear", obd->obd_proc_exports_entry);
+free_obd_stats:
+ lprocfs_free_obd_stats(obd);
+obd_cleanup:
+ lprocfs_obd_cleanup(obd);
return rc;
}
* We actually do sync in disconnect time, but disconnect
* may not come being marked rq_no_resend = 1.
*/
- llog_sync(ctxt, NULL);
+ llog_sync(ctxt, NULL, OBD_LLOG_FL_EXIT);
/*
* Balance class_import_get() in llog_receptor_accept().
* This is safe to do, as llog is already synchronized
* and its import may go.
*/
- mutex_down(&ctxt->loc_sem);
+ cfs_mutex_lock(&ctxt->loc_mutex);
if (ctxt->loc_imp) {
class_import_put(ctxt->loc_imp);
ctxt->loc_imp = NULL;
}
- mutex_up(&ctxt->loc_sem);
+
+ if (filter->fo_lcm) {
+ llog_recov_thread_fini(filter->fo_lcm, obd->obd_force);
+ filter->fo_lcm = NULL;
+ }
+
+ cfs_mutex_unlock(&ctxt->loc_mutex);
llog_ctxt_put(ctxt);
}
- if (filter->fo_lcm) {
- mutex_down(&ctxt->loc_sem);
- llog_recov_thread_fini(filter->fo_lcm, obd->obd_force);
- filter->fo_lcm = NULL;
- mutex_up(&ctxt->loc_sem);
- }
RETURN(filter_olg_fini(&obd->obd_olg));
}
struct obd_llog_group *olg;
LASSERT_SPIN_LOCKED(&filter->fo_llog_list_lock);
- list_for_each_entry(olg, &filter->fo_llog_list, olg_list) {
- if (olg->olg_group == group)
+ cfs_list_for_each_entry(olg, &filter->fo_llog_list, olg_list) {
+ if (olg->olg_seq == group)
RETURN(olg);
}
RETURN(NULL);
filter = &obd->u.filter;
- if (group == FILTER_GROUP_LLOG)
+ if (group == FID_SEQ_LLOG)
RETURN(&obd->obd_olg);
- spin_lock(&filter->fo_llog_list_lock);
+ cfs_spin_lock(&filter->fo_llog_list_lock);
olg = filter_find_olg_internal(filter, group);
- spin_unlock(&filter->fo_llog_list_lock);
+ cfs_spin_unlock(&filter->fo_llog_list_lock);
RETURN(olg);
}
*/
struct obd_llog_group *filter_find_create_olg(struct obd_device *obd, int group)
{
- struct obd_llog_group *olg = NULL;
+ struct obd_llog_group *olg = NULL, *olg_new = NULL;
struct filter_obd *filter;
int rc;
filter = &obd->u.filter;
- if (group == FILTER_GROUP_LLOG)
+ if (group == FID_SEQ_LLOG)
RETURN(&obd->obd_olg);
- spin_lock(&filter->fo_llog_list_lock);
+ OBD_ALLOC_PTR(olg_new);
+ if (olg_new == NULL)
+ RETURN(ERR_PTR(-ENOMEM));
+
+ cfs_spin_lock(&filter->fo_llog_list_lock);
olg = filter_find_olg_internal(filter, group);
if (olg) {
if (olg->olg_initializing) {
} else {
GOTO(out_unlock, olg);
}
+ } else {
+ /* set as the newly allocated one */
+ olg = olg_new;
+ olg_new = NULL;
}
- OBD_ALLOC_PTR(olg);
- if (olg == NULL)
- GOTO(out_unlock, olg = ERR_PTR(-ENOMEM));
llog_group_init(olg, group);
- list_add(&olg->olg_list, &filter->fo_llog_list);
+ cfs_list_add(&olg->olg_list, &filter->fo_llog_list);
olg->olg_initializing = 1;
- spin_unlock(&filter->fo_llog_list_lock);
+ cfs_spin_unlock(&filter->fo_llog_list_lock);
rc = obd_llog_init(obd, olg, obd, NULL);
if (rc) {
- spin_lock(&filter->fo_llog_list_lock);
- list_del(&olg->olg_list);
- spin_unlock(&filter->fo_llog_list_lock);
+ cfs_spin_lock(&filter->fo_llog_list_lock);
+ cfs_list_del(&olg->olg_list);
+ cfs_spin_unlock(&filter->fo_llog_list_lock);
OBD_FREE_PTR(olg);
GOTO(out, olg = ERR_PTR(-ENOMEM));
}
- spin_lock(&filter->fo_llog_list_lock);
+ cfs_spin_lock(&filter->fo_llog_list_lock);
olg->olg_initializing = 0;
- spin_unlock(&filter->fo_llog_list_lock);
+ cfs_spin_unlock(&filter->fo_llog_list_lock);
CDEBUG(D_OTHER, "%s: new llog group %u (0x%p)\n",
obd->obd_name, group, olg);
out:
RETURN(olg);
out_unlock:
- spin_unlock(&filter->fo_llog_list_lock);
- GOTO(out, olg);
+ cfs_spin_unlock(&filter->fo_llog_list_lock);
+ if (olg_new)
+ OBD_FREE_PTR(olg_new);
+ goto out;
}
static int filter_llog_connect(struct obd_export *exp,
CDEBUG(D_OTHER, "%s: LLog connect for: "LPX64"/"LPX64":%x\n",
obd->obd_name, body->lgdc_logid.lgl_oid,
- body->lgdc_logid.lgl_ogr, body->lgdc_logid.lgl_ogen);
+ body->lgdc_logid.lgl_oseq, body->lgdc_logid.lgl_ogen);
- olg = filter_find_olg(obd, body->lgdc_logid.lgl_ogr);
+ olg = filter_find_olg(obd, body->lgdc_logid.lgl_oseq);
if (!olg) {
CERROR(" %s: can not find olg of group %d\n",
- obd->obd_name, (int)body->lgdc_logid.lgl_ogr);
+ obd->obd_name, (int)body->lgdc_logid.lgl_oseq);
RETURN(-ENOENT);
}
llog_group_set_export(olg, exp);
LASSERTF(ctxt != NULL, "ctxt is not null, ctxt idx %d \n",
body->lgdc_ctxt_idx);
- CWARN("%s: Recovery from log "LPX64"/"LPX64":%x\n",
- obd->obd_name, body->lgdc_logid.lgl_oid,
- body->lgdc_logid.lgl_ogr, body->lgdc_logid.lgl_ogen);
+ CDEBUG(D_HA, "%s: Recovery from log "LPX64"/"LPX64":%x\n",
+ obd->obd_name, body->lgdc_logid.lgl_oid,
+ body->lgdc_logid.lgl_oseq, body->lgdc_logid.lgl_ogen);
- spin_lock_bh(&obd->obd_processing_task_lock);
+ cfs_spin_lock(&obd->u.filter.fo_flags_lock);
obd->u.filter.fo_mds_ost_sync = 1;
- spin_unlock_bh(&obd->obd_processing_task_lock);
+ cfs_spin_unlock(&obd->u.filter.fo_flags_lock);
rc = llog_connect(ctxt, &body->lgdc_logid,
&body->lgdc_gen, NULL);
llog_ctxt_put(ctxt);
{
struct obd_llog_group *olg, *tmp;
struct filter_obd *filter;
- struct list_head remove_list;
+ cfs_list_t remove_list;
int rc = 0;
ENTRY;
filter = &obd->u.filter;
CFS_INIT_LIST_HEAD(&remove_list);
- spin_lock(&filter->fo_llog_list_lock);
- while (!list_empty(&filter->fo_llog_list)) {
- olg = list_entry(filter->fo_llog_list.next,
- struct obd_llog_group, olg_list);
- list_del(&olg->olg_list);
- list_add(&olg->olg_list, &remove_list);
+ cfs_spin_lock(&filter->fo_llog_list_lock);
+ while (!cfs_list_empty(&filter->fo_llog_list)) {
+ olg = cfs_list_entry(filter->fo_llog_list.next,
+ struct obd_llog_group, olg_list);
+ cfs_list_del(&olg->olg_list);
+ cfs_list_add(&olg->olg_list, &remove_list);
}
- spin_unlock(&filter->fo_llog_list_lock);
+ cfs_spin_unlock(&filter->fo_llog_list_lock);
- list_for_each_entry_safe(olg, tmp, &remove_list, olg_list) {
- list_del_init(&olg->olg_list);
+ cfs_list_for_each_entry_safe(olg, tmp, &remove_list, olg_list) {
+ cfs_list_del_init(&olg->olg_list);
rc = filter_olg_fini(olg);
if (rc)
CERROR("failed to cleanup llogging subsystem for %u\n",
- olg->olg_group);
+ olg->olg_seq);
OBD_FREE_PTR(olg);
}
case OBD_CLEANUP_EXPORTS:
/* Stop recovery before namespace cleanup. */
target_recovery_fini(obd);
+
+ obd_exports_barrier(obd);
+ obd_zombie_barrier();
+
rc = filter_llog_preclean(obd);
+ lprocfs_job_stats_fini(obd);
+ lprocfs_remove_proc_entry("clear", obd->obd_proc_exports_entry);
+ lprocfs_free_per_client_stats(obd);
+ lprocfs_obd_cleanup(obd);
+ lprocfs_free_obd_stats(obd);
+ lquota_cleanup(filter_quota_interface_ref, obd);
break;
}
RETURN(rc);
LCONSOLE_WARN("%s: shutting down for failover; client state "
"will be preserved.\n", obd->obd_name);
- obd_exports_barrier(obd);
- obd_zombie_barrier();
-
- lprocfs_remove_proc_entry("clear", obd->obd_proc_exports_entry);
- lprocfs_free_per_client_stats(obd);
- lprocfs_free_obd_stats(obd);
- lprocfs_obd_cleanup(obd);
- lquota_cleanup(filter_quota_interface_ref, obd);
-
ldlm_namespace_free(obd->obd_namespace, NULL, obd->obd_force);
obd->obd_namespace = NULL;
filter_post(obd);
- LL_DQUOT_OFF(obd->u.obt.obt_sb);
+ ll_vfs_dq_off(obd->u.obt.obt_sb, 0);
shrink_dcache_sb(obd->u.obt.obt_sb);
- server_put_mount(obd->obd_name, filter->fo_vfsmnt);
+ server_put_mount(obd->obd_name, obd->u.obt.obt_vfsmnt);
obd->u.obt.obt_sb = NULL;
fsfilt_put_ops(obd->obd_fsops);
CWARN("!!! This export (nid %s) used object group %d "
"earlier; now it's trying to use group %d! This could "
"be a bug in the MDS. Please report to "
- "http://bugzilla.lustre.org/\n",
+ "http://bugs.whamcloud.com/\n",
obd_export_nid2str(exp), fed->fed_group,data->ocd_group);
RETURN(-EPROTO);
}
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)
+ CDEBUG(D_HA, "%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) {
struct filter_obd *filter = &exp->exp_obd->u.filter;
obd_size left, want;
- spin_lock(&exp->exp_obd->obd_osfs_lock);
+ cfs_spin_lock(&exp->exp_obd->obd_osfs_lock);
left = filter_grant_space_left(exp);
want = data->ocd_grant;
filter_grant(exp, fed->fed_grant, want, left, (reconnect == 0));
data->ocd_grant = fed->fed_grant;
- spin_unlock(&exp->exp_obd->obd_osfs_lock);
+ cfs_spin_unlock(&exp->exp_obd->obd_osfs_lock);
CDEBUG(D_CACHE, "%s: cli %s/%p ocd_grant: %d want: "
LPU64" left: "LPU64"\n", exp->exp_obd->obd_name,
exp->exp_client_uuid.uuid, exp,
data->ocd_grant, want, left);
-
+
filter->fo_tot_granted_clients ++;
}
if (data->ocd_connect_flags & OBD_CONNECT_INDEX) {
- struct filter_obd *filter = &exp->exp_obd->u.filter;
- struct lr_server_data *lsd = filter->fo_fsd;
+ struct lr_server_data *lsd = class_server_data(exp->exp_obd);
int index = le32_to_cpu(lsd->lsd_ost_index);
if (!(lsd->lsd_feature_compat &
/* this will only happen on the first connect */
lsd->lsd_ost_index = cpu_to_le32(data->ocd_index);
lsd->lsd_feature_compat |= cpu_to_le32(OBD_COMPAT_OST);
- filter_update_server_data(exp->exp_obd,
- filter->fo_rcvd_filp, lsd, 1);
+ /* sync is not needed here as filter_client_add will
+ * set exp_need_sync flag */
+ filter_update_server_data(exp->exp_obd);
} else if (index != data->ocd_index) {
LCONSOLE_ERROR_MSG(0x136, "Connection from %s to index"
" %u doesn't match actual OST index"
data->ocd_index);
RETURN(-EBADF);
}
- /* FIXME: Do the same with the MDS UUID and fsd_peeruuid.
+ /* FIXME: Do the same with the MDS UUID and lsd_peeruuid.
* FIXME: We don't strictly need the COMPAT flag for that,
- * FIXME: as fsd_peeruuid[0] will tell us if that is set.
+ * FIXME: as lsd_peeruuid[0] will tell us if that is set.
* FIXME: We needed it for the index, as index 0 is valid. */
}
} else if (data->ocd_connect_flags & OBD_CONNECT_BRW_SIZE) {
data->ocd_brw_size = min(data->ocd_brw_size,
(__u32)(PTLRPC_MAX_BRW_PAGES << CFS_PAGE_SHIFT));
- LASSERT(data->ocd_brw_size);
+ if (data->ocd_brw_size == 0) {
+ CERROR("%s: cli %s/%p ocd_connect_flags: "LPX64
+ " ocd_version: %x ocd_grant: %d ocd_index: %u "
+ "ocd_brw_size is unexpectedly zero, "
+ "network data corruption?"
+ "Refusing connection of this client\n",
+ exp->exp_obd->obd_name,
+ exp->exp_client_uuid.uuid,
+ exp, data->ocd_connect_flags, data->ocd_version,
+ data->ocd_grant, data->ocd_index);
+ RETURN(-EPROTO);
+ }
}
if (data->ocd_connect_flags & OBD_CONNECT_CKSUM) {
/* 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 "
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);
}
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,
struct lvfs_run_ctxt saved;
struct lustre_handle conn = { 0 };
struct obd_export *lexp;
- struct filter_export_data *fed;
- struct lsd_client_data *lcd = NULL;
- __u32 group;
int rc;
ENTRY;
lexp = class_conn2export(&conn);
LASSERT(lexp != NULL);
- fed = &lexp->exp_filter_data;
-
rc = filter_connect_internal(lexp, data, 0);
if (rc)
GOTO(cleanup, rc);
filter_export_stats_init(obd, lexp, localdata);
if (obd->obd_replayable) {
- OBD_ALLOC(lcd, sizeof(*lcd));
- if (!lcd) {
- CERROR("filter: out of memory for client data\n");
- GOTO(cleanup, rc = -ENOMEM);
- }
-
+ struct lsd_client_data *lcd = lexp->exp_target_data.ted_lcd;
+ LASSERT(lcd);
memcpy(lcd->lcd_uuid, cluuid, sizeof(lcd->lcd_uuid));
- fed->fed_lcd = lcd;
rc = filter_client_add(obd, lexp, -1);
if (rc)
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);
}
cleanup:
if (rc) {
- if (lcd) {
- OBD_FREE_PTR(lcd);
- fed->fed_lcd = NULL;
- }
class_disconnect(lexp);
*exp = NULL;
} else {
obd_size tot_dirty = 0, tot_pending = 0, tot_granted = 0;
obd_size fo_tot_dirty, fo_tot_pending, fo_tot_granted;
- if (list_empty(&obd->obd_exports))
+ if (cfs_list_empty(&obd->obd_exports))
return;
/* We don't want to do this for large machines that do lots of
if (obd->obd_num_exports > 100)
return;
- spin_lock(&obd->obd_osfs_lock);
- spin_lock(&obd->obd_dev_lock);
- list_for_each_entry(exp, &obd->obd_exports, exp_obd_chain) {
+ cfs_spin_lock(&obd->obd_osfs_lock);
+ cfs_spin_lock(&obd->obd_dev_lock);
+ cfs_list_for_each_entry(exp, &obd->obd_exports, exp_obd_chain) {
int error = 0;
fed = &exp->exp_filter_data;
if (fed->fed_grant < 0 || fed->fed_pending < 0 ||
fo_tot_granted = obd->u.filter.fo_tot_granted;
fo_tot_pending = obd->u.filter.fo_tot_pending;
fo_tot_dirty = obd->u.filter.fo_tot_dirty;
- spin_unlock(&obd->obd_dev_lock);
- spin_unlock(&obd->obd_osfs_lock);
+ cfs_spin_unlock(&obd->obd_dev_lock);
+ cfs_spin_unlock(&obd->obd_osfs_lock);
/* Do these assertions outside the spinlocks so we don't kill system */
if (tot_granted != fo_tot_granted)
struct filter_obd *filter = &obd->u.filter;
struct filter_export_data *fed = &exp->exp_filter_data;
- spin_lock(&obd->obd_osfs_lock);
+ cfs_spin_lock(&obd->obd_osfs_lock);
LASSERTF(filter->fo_tot_granted >= fed->fed_grant,
"%s: tot_granted "LPU64" cli %s/%p fed_grant %ld\n",
obd->obd_name, filter->fo_tot_granted,
fed->fed_dirty = 0;
fed->fed_grant = 0;
- spin_unlock(&obd->obd_osfs_lock);
+ cfs_spin_unlock(&obd->obd_osfs_lock);
}
static int filter_destroy_export(struct obd_export *exp)
{
+ struct filter_export_data *fed = &exp->exp_filter_data;
ENTRY;
- if (exp->exp_filter_data.fed_pending)
+ if (fed->fed_pending)
CERROR("%s: cli %s/%p has %lu pending on destroyed export\n",
exp->exp_obd->obd_name, exp->exp_client_uuid.uuid,
- exp, exp->exp_filter_data.fed_pending);
+ exp, fed->fed_pending);
lquota_clearinfo(filter_quota_interface_ref, exp, exp->exp_obd);
target_destroy_export(exp);
- ldlm_destroy_export(exp);
- if (obd_uuid_equals(&exp->exp_client_uuid, &exp->exp_obd->obd_uuid))
- RETURN(0);
+ if (unlikely(obd_uuid_equals(&exp->exp_obd->obd_uuid,
+ &exp->exp_client_uuid)))
+ RETURN(0);
+ ldlm_destroy_export(exp);
+ lut_client_free(exp);
- if (exp->exp_obd->obd_replayable)
- filter_client_free(exp);
- else
+ if (!exp->exp_obd->obd_replayable)
fsfilt_sync(exp->exp_obd, exp->exp_obd->u.obt.obt_sb);
filter_grant_discard(exp);
}
if (!(exp->exp_flags & OBD_OPT_FORCE))
- filter_grant_sanity_check(exp->exp_obd, __FUNCTION__);
+ filter_grant_sanity_check(exp->exp_obd, __func__);
RETURN(0);
}
/* look for group with min. number, but > worked */
olg_min = NULL;
group = 1 << 30;
- spin_lock(&filter->fo_llog_list_lock);
- list_for_each_entry(olg, &filter->fo_llog_list, olg_list) {
- if (olg->olg_group <= worked) {
+ cfs_spin_lock(&filter->fo_llog_list_lock);
+ cfs_list_for_each_entry(olg, &filter->fo_llog_list, olg_list) {
+ if (olg->olg_seq <= worked) {
/* this group is already synced */
continue;
}
- if (group < olg->olg_group) {
+ if (group < olg->olg_seq) {
/* we have group with smaller number to sync */
continue;
}
/* store current minimal group */
olg_min = olg;
- group = olg->olg_group;
+ group = olg->olg_seq;
}
- spin_unlock(&filter->fo_llog_list_lock);
+ cfs_spin_unlock(&filter->fo_llog_list_lock);
if (olg_min == NULL)
break;
- worked = olg_min->olg_group;
+ worked = olg_min->olg_seq;
if (olg_min->olg_exp &&
(dexp == olg_min->olg_exp || dexp == NULL)) {
int err;
ctxt = llog_group_get_ctxt(olg_min,
LLOG_MDS_OST_REPL_CTXT);
if (ctxt) {
- err = llog_sync(ctxt, olg_min->olg_exp);
+ err = llog_sync(ctxt, olg_min->olg_exp, 0);
llog_ctxt_put(ctxt);
if (err) {
CERROR("error flushing logs to MDS: "
class_export_get(exp);
if (!(exp->exp_flags & OBD_OPT_FORCE))
- filter_grant_sanity_check(obd, __FUNCTION__);
+ filter_grant_sanity_check(obd, __func__);
filter_grant_discard(exp);
/* Flush any remaining cancel messages out to the target */
rc = server_disconnect_export(exp);
- fsfilt_sync(obd, obd->u.obt.obt_sb);
+ /* Do not erase record for recoverable client. */
+ if (obd->obd_replayable && (!obd->obd_fail || exp->exp_failed))
+ filter_client_del(exp);
+ else
+ fsfilt_sync(obd, obd->u.obt.obt_sb);
class_export_put(exp);
RETURN(rc);
EXIT;
}
-static int filter_ping(struct obd_export *exp)
+static int filter_ping(const struct lu_env *env, struct obd_export *exp)
{
filter_fmd_expire(exp);
return 0;
}
-struct dentry *__filter_oa2dentry(struct obd_device *obd, struct obdo *oa,
+struct dentry *__filter_oa2dentry(struct obd_device *obd, struct ost_id *ostid,
const char *what, int quiet)
{
struct dentry *dchild = NULL;
- obd_gr group = 0;
-
- if (oa->o_valid & OBD_MD_FLGROUP)
- group = oa->o_gr;
- dchild = filter_fid2dentry(obd, NULL, group, oa->o_id);
+ dchild = filter_fid2dentry(obd, NULL, ostid->oi_seq, ostid->oi_id);
if (IS_ERR(dchild)) {
- CERROR("%s error looking up object: "LPU64":"LPU64"\n",
- what, group, oa->o_id);
+ CERROR("%s error looking up object: "POSTID"\n",
+ what, ostid->oi_id, ostid->oi_seq);
RETURN(dchild);
}
if (dchild->d_inode == NULL) {
if (!quiet)
- CERROR("%s: %s on non-existent object: "LPU64"\n",
- obd->obd_name, what, oa->o_id);
+ CERROR("%s: %s on non-existent object: "POSTID" \n",
+ obd->obd_name, what, ostid->oi_id,ostid->oi_seq);
f_dput(dchild);
RETURN(ERR_PTR(-ENOENT));
}
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2,7,50,0)
+ /* Try to correct for a bug in 2.1.0 (LU-221) that caused negative
+ * timestamps to appear to be in the far future, due old timestamp
+ * being stored on disk as an unsigned value. This fixes up any
+ * bad values stored on disk before returning them to the client,
+ * and ensures any timestamp updates are correct. LU-1042 */
+ if (unlikely(LTIME_S(dchild->d_inode->i_atime) == LU221_BAD_TIME))
+ LTIME_S(dchild->d_inode->i_atime) = 0;
+ if (unlikely(LTIME_S(dchild->d_inode->i_mtime) == LU221_BAD_TIME))
+ LTIME_S(dchild->d_inode->i_mtime) = 0;
+ if (unlikely(LTIME_S(dchild->d_inode->i_ctime) == LU221_BAD_TIME))
+ LTIME_S(dchild->d_inode->i_ctime) = 0;
+#else
+#warning "remove old LU-221/LU-1042 workaround code"
+#endif
+
return dchild;
}
-static int filter_getattr(struct obd_export *exp, struct obd_info *oinfo)
+static int filter_getattr(const struct lu_env *env, struct obd_export *exp,
+ struct obd_info *oinfo)
{
struct dentry *dentry = NULL;
struct obd_device *obd;
+ __u64 curr_version;
int rc = 0;
ENTRY;
- LASSERT(oinfo->oi_oa->o_valid & OBD_MD_FLGROUP);
- rc = filter_auth_capa(exp, NULL, oinfo->oi_oa->o_gr,
+ rc = filter_auth_capa(exp, NULL, oinfo->oi_oa->o_seq,
oinfo_capa(oinfo), CAPA_OPC_META_READ);
if (rc)
RETURN(rc);
RETURN(-EINVAL);
}
- dentry = filter_oa2dentry(obd, oinfo->oi_oa);
+ dentry = filter_oa2dentry(obd, &oinfo->oi_oa->o_oi);
if (IS_ERR(dentry))
RETURN(PTR_ERR(dentry));
oinfo->oi_oa->o_valid = OBD_MD_FLID;
obdo_from_inode(oinfo->oi_oa, dentry->d_inode, FILTER_VALID_FLAGS);
+ /* Store inode version in reply */
+ curr_version = fsfilt_get_version(exp->exp_obd, dentry->d_inode);
+ if ((__s64)curr_version != -EOPNOTSUPP) {
+ oinfo->oi_oa->o_valid |= OBD_MD_FLDATAVERSION;
+ oinfo->oi_oa->o_data_version = curr_version;
+ }
+
f_dput(dentry);
RETURN(rc);
}
struct filter_fid ff;
if (!(oa->o_valid & OBD_MD_FLGROUP))
- oa->o_gr = 0;
+ oa->o_seq = 0;
/* packing fid and converting it to LE for storing into EA.
* Here ->o_stripe_idx should be filled by LOV and rest of
* fields - by client. */
- ff.ff_fid.id = cpu_to_le64(oa->o_fid);
- ff.ff_fid.f_type = cpu_to_le32(oa->o_stripe_idx);
- ff.ff_fid.generation = cpu_to_le32(oa->o_generation);
+ ff.ff_parent.f_seq = cpu_to_le64(oa->o_parent_seq);
+ ff.ff_parent.f_oid = cpu_to_le32(oa->o_parent_oid);
+ /* XXX: we are ignoring o_parent_ver here, since this should
+ * be the same for all objects in this fileset. */
+ ff.ff_parent.f_ver = cpu_to_le32(oa->o_stripe_idx);
ff.ff_objid = cpu_to_le64(oa->o_id);
- ff.ff_group = cpu_to_le64(oa->o_gr);
+ ff.ff_seq = cpu_to_le64(oa->o_seq);
- CDEBUG(D_INODE, "storing filter fid EA ("LPU64"/%u/%u"
- LPU64"/"LPU64")\n", oa->o_fid, oa->o_stripe_idx,
- oa->o_generation, oa->o_id, oa->o_gr);
+ CDEBUG(D_INODE, "storing filter fid EA (parent "DFID" "
+ LPU64"/"LPU64")\n", PFID(&ff.ff_parent), oa->o_id,
+ oa->o_seq);
rc = fsfilt_set_md(obd, inode, handle, &ff, sizeof(ff), "fid");
if (rc)
*fcc = oa->o_lcookie;
}
if (ia_valid & (ATTR_SIZE | ATTR_UID | ATTR_GID)) {
- DQUOT_INIT(inode);
+ unsigned long now = jiffies;
/* Filter truncates and writes are serialized by
* i_alloc_sem, see the comment in
* filter_preprw_write.*/
if (ia_valid & ATTR_SIZE)
down_write(&inode->i_alloc_sem);
LOCK_INODE_MUTEX(inode);
+ fsfilt_check_slow(exp->exp_obd, now, "i_alloc_sem and i_mutex");
old_size = i_size_read(inode);
}
if (IS_ERR(handle))
GOTO(out_unlock, rc = PTR_ERR(handle));
}
+
+ /* Locking order: i_mutex -> journal_lock -> dqptr_sem. LU-952 */
+ if (ia_valid & (ATTR_SIZE | ATTR_UID | ATTR_GID))
+ ll_vfs_dq_init(inode);
+
if (oa->o_valid & OBD_MD_FLFLAGS) {
rc = fsfilt_iocontrol(exp->exp_obd, dentry,
FSFILT_IOC_SETFLAGS, (long)&oa->o_flags);
if (OBD_FAIL_CHECK(OBD_FAIL_OST_SETATTR_CREDITS))
fsfilt_extend(exp->exp_obd, inode, 0, handle);
- /* The truncate might have used up our transaction credits. Make
- * sure we have one left for the last_rcvd update. */
- err = fsfilt_extend(exp->exp_obd, inode, 1, handle);
+ /* The truncate might have used up our transaction credits. Make sure
+ * we have two left for the last_rcvd and VBR inode version updates. */
+ err = fsfilt_extend(exp->exp_obd, inode, 2, handle);
+
+ /* Update inode version only if data has changed => size has changed */
+ rc = filter_finish_transno(exp, ia_valid & ATTR_SIZE ? inode : NULL,
+ oti, rc, sync);
- rc = filter_finish_transno(exp, inode, oti, rc, sync);
if (sync) {
filter_cancel_cookies_cb(exp->exp_obd, 0, fcc, rc);
fcc = NULL;
}
/* this is called from filter_truncate() until we have filter_punch() */
-int filter_setattr(struct obd_export *exp, struct obd_info *oinfo,
- struct obd_trans_info *oti)
+int filter_setattr(const struct lu_env *env, struct obd_export *exp,
+ struct obd_info *oinfo, struct obd_trans_info *oti)
{
struct obdo *oa = oinfo->oi_oa;
struct lustre_capa *capa = oinfo_capa(oinfo);
int rc;
ENTRY;
- if (oa->o_valid & OBD_FL_TRUNC)
+ if (oinfo->oi_flags & OBD_FL_PUNCH)
opc |= CAPA_OPC_OSS_TRUNC;
- LASSERT(oa->o_valid & OBD_MD_FLGROUP);
- rc = filter_auth_capa(exp, NULL, oa->o_gr, capa, opc);
+ rc = filter_auth_capa(exp, NULL, oa->o_seq, capa, opc);
if (rc)
RETURN(rc);
if (oa->o_valid & (OBD_MD_FLUID | OBD_MD_FLGID)) {
- rc = filter_capa_fixoa(exp, oa, oa->o_gr, capa);
+ rc = filter_capa_fixoa(exp, oa, oa->o_seq, capa);
if (rc)
RETURN(rc);
}
- osc_build_res_name(oa->o_id, oa->o_gr, &res_id);
+ osc_build_res_name(oa->o_id, oa->o_seq, &res_id);
/* This would be very bad - accidentally truncating a file when
* changing the time or similar - bug 12203. */
if (oa->o_valid & OBD_MD_FLSIZE &&
static char mdsinum[48];
if (oa->o_valid & OBD_MD_FLFID)
- snprintf(mdsinum, sizeof(mdsinum) - 1,
- " of inode "LPU64"/%u", oa->o_fid,
- oa->o_generation);
+ snprintf(mdsinum, sizeof(mdsinum) - 1, " of inode "DFID,
+ oa->o_parent_seq, oa->o_parent_oid,
+ oa->o_parent_ver);
else
mdsinum[0] = '\0';
- CERROR("%s: setattr from %s trying to truncate objid "LPU64
- " %s\n",
- exp->exp_obd->obd_name, obd_export_nid2str(exp),
- oa->o_id, mdsinum);
+ CERROR("%s: setattr from %s trying to truncate objid "POSTID
+ "%s\n", exp->exp_obd->obd_name, obd_export_nid2str(exp),
+ oa->o_id, oa->o_seq, mdsinum);
RETURN(-EPERM);
}
- dentry = __filter_oa2dentry(exp->exp_obd, oa, __FUNCTION__, 1);
+ dentry = __filter_oa2dentry(exp->exp_obd, &oinfo->oi_oa->o_oi, __func__, 1);
if (IS_ERR(dentry))
RETURN(PTR_ERR(dentry));
filter = &exp->exp_obd->u.filter;
push_ctxt(&saved, &exp->exp_obd->obd_lvfs_ctxt, NULL);
+ /*
+ * We need to be atomic against a concurrent write
+ * (which takes the semaphore for reading). fmd_mactime_xid
+ * checks will have no effect if a write request with lower
+ * xid starts just before a setattr and finishes later than
+ * the setattr (see bug 21489, comment 27).
+ */
if (oa->o_valid &
(OBD_MD_FLMTIME | OBD_MD_FLATIME | OBD_MD_FLCTIME)) {
- fmd = filter_fmd_get(exp, oa->o_id, oa->o_gr);
+ unsigned long now = jiffies;
+ down_write(&dentry->d_inode->i_alloc_sem);
+ fsfilt_check_slow(exp->exp_obd, now, "i_alloc_sem");
+ fmd = filter_fmd_get(exp, oa->o_id, oa->o_seq);
if (fmd && fmd->fmd_mactime_xid < oti->oti_xid)
fmd->fmd_mactime_xid = oti->oti_xid;
filter_fmd_put(exp, fmd);
+ up_write(&dentry->d_inode->i_alloc_sem);
}
/* setting objects attributes (including owner/group) */
if (res != NULL) {
LDLM_RESOURCE_ADDREF(res);
- rc = ldlm_res_lvbo_update(res, NULL, 0, 0);
+ rc = ldlm_res_lvbo_update(res, NULL, 0);
LDLM_RESOURCE_DELREF(res);
ldlm_resource_putref(res);
}
obdo_from_inode(oa, dentry->d_inode,
FILTER_VALID_FLAGS | OBD_MD_FLUID | OBD_MD_FLGID);
+ filter_counter_incr(exp, LPROC_FILTER_STATS_SETATTR,
+ oti ? oti->oti_jobid : NULL, 1);
EXIT;
out_unlock:
f_dput(dentry);
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);
}
-/* caller must hold fo_create_locks[oa->o_gr] */
+/* caller must hold fo_create_locks[oa->o_seq] */
static int filter_destroy_precreated(struct obd_export *exp, struct obdo *oa,
struct filter_obd *filter)
{
int skip_orphan;
ENTRY;
- LASSERT(oa);
- LASSERT_MDS_GROUP(oa->o_gr);
- LASSERT(oa->o_valid & OBD_MD_FLGROUP);
- LASSERT(down_trylock(&filter->fo_create_locks[oa->o_gr]) != 0);
+ LASSERT_MUTEX_LOCKED(&filter->fo_create_locks[oa->o_seq]);
memset(&doa, 0, sizeof(doa));
doa.o_valid |= OBD_MD_FLGROUP;
- doa.o_gr = oa->o_gr;
+ doa.o_seq = oa->o_seq;
doa.o_mode = S_IFREG;
- if (!test_bit(doa.o_gr, &filter->fo_destroys_in_progress)) {
+ if (!cfs_test_bit(doa.o_seq, &filter->fo_destroys_in_progress)) {
CERROR("%s:["LPU64"] destroys_in_progress already cleared\n",
- exp->exp_obd->obd_name, doa.o_gr);
+ exp->exp_obd->obd_name, doa.o_seq);
RETURN(0);
}
- last = filter_last_id(filter, doa.o_gr);
+ last = filter_last_id(filter, doa.o_seq);
skip_orphan = !!(exp->exp_connect_flags & OBD_CONNECT_SKIP_ORPHAN);
for (id = last; id > oa->o_id; id--) {
doa.o_id = id;
- rc = filter_destroy(exp, &doa, NULL, NULL, NULL, NULL);
+ rc = filter_destroy(NULL, exp, &doa, NULL, NULL, NULL, NULL);
if (rc && rc != -ENOENT) /* this is pretty fatal... */
CEMERG("error destroying precreate objid "LPU64": %d\n",
id, rc);
/* update last_id on disk periodically so that if we restart
* we don't need to re-scan all of the just-deleted objects. */
if ((id & 511) == 0 && !skip_orphan) {
- filter_set_last_id(filter, id - 1, doa.o_gr);
- filter_update_last_objid(exp->exp_obd, doa.o_gr, 0);
+ filter_set_last_id(filter, id - 1, doa.o_seq);
+ filter_update_last_objid(exp->exp_obd, doa.o_seq, 0);
}
}
CDEBUG(D_HA, "%s: after destroy: set last_objids["LPU64"] = "LPU64"\n",
- exp->exp_obd->obd_name, doa.o_gr, oa->o_id);
+ exp->exp_obd->obd_name, doa.o_seq, oa->o_id);
if (!skip_orphan) {
- filter_set_last_id(filter, id, doa.o_gr);
- rc = filter_update_last_objid(exp->exp_obd, doa.o_gr, 1);
+ filter_set_last_id(filter, id, doa.o_seq);
+ rc = filter_update_last_objid(exp->exp_obd, doa.o_seq, 1);
} else {
- /* don't reuse orphan object, return last used objid */
+ /*
+ * We have destroyed orphan objects, but don't want to reuse
+ * them. Therefore we don't reset last_id to the last created
+ * objects. Instead, we report back to the MDS the object id
+ * of the last orphan, so that the MDS can restart allocating
+ * objects from this id + 1 and thus skip the whole orphan
+ * object id range
+ */
oa->o_id = last;
rc = 0;
}
- clear_bit(doa.o_gr, &filter->fo_destroys_in_progress);
+ cfs_clear_bit(doa.o_seq, &filter->fo_destroys_in_progress);
RETURN(rc);
}
static int filter_precreate(struct obd_device *obd, struct obdo *oa,
- obd_gr group, int *num);
+ obd_seq group, int *num);
/* returns a negative error or a nonnegative number of files to create */
static int filter_handle_precreate(struct obd_export *exp, struct obdo *oa,
- obd_gr group, struct obd_trans_info *oti)
+ obd_seq group, struct obd_trans_info *oti)
{
struct obd_device *obd = exp->exp_obd;
struct filter_obd *filter = &obd->u.filter;
RETURN(0);
}
/* This causes inflight precreates to abort and drop lock */
- set_bit(group, &filter->fo_destroys_in_progress);
- down(&filter->fo_create_locks[group]);
- if (!test_bit(group, &filter->fo_destroys_in_progress)) {
+ cfs_set_bit(group, &filter->fo_destroys_in_progress);
+ cfs_mutex_lock(&filter->fo_create_locks[group]);
+ if (!cfs_test_bit(group, &filter->fo_destroys_in_progress)) {
CERROR("%s:["LPU64"] destroys_in_progress already cleared\n",
exp->exp_obd->obd_name, group);
- up(&filter->fo_create_locks[group]);
+ cfs_mutex_unlock(&filter->fo_create_locks[group]);
RETURN(0);
}
diff = oa->o_id - last;
CDEBUG(D_HA, "filter_last_id() = "LPU64" -> diff = %d\n",
last, diff);
- if (-diff > OST_MAX_PRECREATE) {
+ if (-diff > (OST_MAX_PRECREATE * 3) / 2) {
CERROR("%s: ignoring bogus orphan destroy request: "
"obdid "LPU64" last_id "LPU64"\n", obd->obd_name,
oa->o_id, last);
GOTO(out, rc);
} else {
/* XXX: Used by MDS for the first time! */
- clear_bit(group, &filter->fo_destroys_in_progress);
+ cfs_clear_bit(group, &filter->fo_destroys_in_progress);
}
} else {
- down(&filter->fo_create_locks[group]);
+ cfs_mutex_lock(&filter->fo_create_locks[group]);
if (oti->oti_conn_cnt < exp->exp_conn_cnt) {
CERROR("%s: dropping old precreate request\n",
obd->obd_name);
GOTO(out, rc = 0);
}
/* only precreate if group == 0 and o_id is specfied */
- if (!filter_group_is_mds(group) || oa->o_id == 0)
+ if (!fid_seq_is_mdt(group) || oa->o_id == 0)
diff = 1;
else
diff = oa->o_id - filter_last_id(filter, group);
oa->o_id = filter_last_id(&obd->u.filter, group);
rc = filter_precreate(obd, oa, group, &diff);
oa->o_id = filter_last_id(&obd->u.filter, group);
- oa->o_gr = group;
- oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP;
+ oa->o_seq = group;
+ oa->o_valid |= (OBD_MD_FLID | OBD_MD_FLGROUP);
GOTO(out, rc);
}
/* else diff == 0 */
GOTO(out, rc = 0);
out:
- up(&filter->fo_create_locks[group]);
+ cfs_mutex_unlock(&filter->fo_create_locks[group]);
return rc;
}
-static int filter_statfs(struct obd_device *obd, struct obd_statfs *osfs,
- __u64 max_age, __u32 flags)
+static int filter_statfs(const struct lu_env *env, struct obd_export *exp,
+ struct obd_statfs *osfs, __u64 max_age, __u32 flags)
{
+ struct obd_device *obd = class_exp2obd(exp);
struct filter_obd *filter = &obd->u.filter;
int blockbits = obd->u.obt.obt_sb->s_blocksize_bits;
+ struct lr_server_data *lsd = class_server_data(obd);
int rc;
ENTRY;
/* at least try to account for cached pages. its still racey and
* might be under-reporting if clients haven't announced their
* caches with brw recently */
- spin_lock(&obd->obd_osfs_lock);
+ cfs_spin_lock(&obd->obd_osfs_lock);
rc = fsfilt_statfs(obd, obd->u.obt.obt_sb, max_age);
memcpy(osfs, &obd->obd_osfs, sizeof(*osfs));
- spin_unlock(&obd->obd_osfs_lock);
+ cfs_spin_unlock(&obd->obd_osfs_lock);
CDEBUG(D_SUPER | D_CACHE, "blocks cached "LPU64" granted "LPU64
" pending "LPU64" free "LPU64" avail "LPU64"\n",
filter->fo_tot_pending,
osfs->os_bfree << blockbits, osfs->os_bavail << blockbits);
- filter_grant_sanity_check(obd, __FUNCTION__);
+ filter_grant_sanity_check(obd, __func__);
osfs->os_bavail -= min(osfs->os_bavail, GRANT_FOR_LLOG(obd) +
((filter->fo_tot_dirty + filter->fo_tot_pending +
osfs->os_bsize - 1) >> blockbits));
+ if (OBD_FAIL_CHECK_VALUE(OBD_FAIL_OST_ENOSPC,
+ le32_to_cpu(lsd->lsd_ost_index)))
+ osfs->os_bfree = osfs->os_bavail = 2;
+
+ if (OBD_FAIL_CHECK_VALUE(OBD_FAIL_OST_ENOINO,
+ le32_to_cpu(lsd->lsd_ost_index)))
+ osfs->os_ffree = 0;
+
/* set EROFS to state field if FS is mounted as RDONLY. The goal is to
* stop creating files on MDS if OST is not good shape to create
* objects.*/
int rc;
__u64 os_ffree = -1;
- spin_lock(&obd->obd_osfs_lock);
+ cfs_spin_lock(&obd->obd_osfs_lock);
rc = fsfilt_statfs(obd, obd->u.obt.obt_sb, cfs_time_shift_64(1));
if (rc == 0)
os_ffree = obd->obd_osfs.os_ffree;
- spin_unlock(&obd->obd_osfs_lock);
+ cfs_spin_unlock(&obd->obd_osfs_lock);
return os_ffree;
}
* Caller must hold fo_create_locks[group]
*/
static int filter_precreate(struct obd_device *obd, struct obdo *oa,
- obd_gr group, int *num)
+ obd_seq group, int *num)
{
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;
filter = &obd->u.filter;
- LASSERT(down_trylock(&filter->fo_create_locks[group]) != 0);
+ LASSERT_MUTEX_LOCKED(&filter->fo_create_locks[group]);
OBD_FAIL_TIMEOUT(OBD_FAIL_TGT_DELAY_PRECREATE, obd_timeout / 2);
OBD_ALLOC(osfs, sizeof(*osfs));
if (osfs == NULL)
RETURN(-ENOMEM);
- rc = filter_statfs(obd, osfs, cfs_time_current_64() - HZ, 0);
+ rc = filter_statfs(NULL, obd->obd_self_export, osfs,
+ cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
+ 0);
if (rc == 0 && osfs->os_bavail < (osfs->os_blocks >> 10)) {
CDEBUG(D_RPCTRACE,"%s: not enough space for create "
LPU64"\n", obd->obd_name, osfs->os_bavail <<
- filter->fo_vfsmnt->mnt_sb->s_blocksize_bits);
+ 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));
for (i = 0; i < *num && err == 0; i++) {
int cleanup_phase = 0;
- if (test_bit(group, &filter->fo_destroys_in_progress)) {
+ if (cfs_test_bit(group, &filter->fo_destroys_in_progress)) {
CWARN("%s: create aborted by destroy\n",
obd->obd_name);
rc = -EAGAIN;
} else
next_id = filter_last_id(filter, group) + 1;
+ /* Don't create objects beyond the valid range for this SEQ */
+ if (unlikely(fid_seq_is_mdt0(group) &&
+ next_id >= IDIF_MAX_OID)) {
+ CERROR("%s:"POSTID" hit the IDIF_MAX_OID (1<<48)!\n",
+ obd->obd_name, next_id, group);
+ GOTO(cleanup, rc = -ENOSPC);
+ } else if (unlikely(!fid_seq_is_mdt0(group) &&
+ next_id >= OBIF_MAX_OID)) {
+ CERROR("%s:"POSTID" hit the OBIF_MAX_OID (1<<32)!\n",
+ obd->obd_name, next_id, group);
+ GOTO(cleanup, rc = -ENOSPC);
+ }
+
dparent = filter_parent_lock(obd, group, next_id);
if (IS_ERR(dparent))
GOTO(cleanup, rc = PTR_ERR(dparent));
} else {
/* Use these existing objects if they are
* zero length. */
- if (dchild->d_inode->i_size == 0) {
+ if (i_size_read(dchild->d_inode) == 0) {
rc = filter_use_existing_obj(obd,dchild,
&handle, &cleanup_phase);
if (rc == 0)
GOTO(cleanup, rc = PTR_ERR(handle));
cleanup_phase = 3;
- CDEBUG(D_INODE, "%s: filter_precreate(od->o_gr="LPU64
+ CDEBUG(D_INODE, "%s: filter_precreate(od->o_seq="LPU64
",od->o_id="LPU64")\n", obd->obd_name, group,
next_id);
rc = ll_vfs_create(dparent->d_inode, dchild,
S_IFREG | S_ISUID | S_ISGID | 0666, NULL);
if (rc) {
- CERROR("create failed rc = %d\n", rc);
+ CWARN("%s: create failed: rc = %d\n", obd->obd_name,rc);
if (rc == -ENOSPC) {
os_ffree = filter_calc_free_inodes(obd);
- if (os_ffree != -1)
- CERROR("%s: free inode "LPU64"\n",
- obd->obd_name, os_ffree);
+ 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;
+ }
+
+ CWARN("%s: free inode "LPU64"\n",
+ obd->obd_name, os_ffree);
+ }
}
GOTO(cleanup, rc);
}
dchild->d_inode->i_ino);
set_last_id:
+ /* Initialize a/c/m time so any client timestamp will always
+ * be newer and update the inode. ctime = 0 is also handled
+ * specially in fsfilt_ext3_setattr(). See LU-221, LU-1042 */
+ iattr.ia_valid = ATTR_ATIME | ATTR_MTIME | ATTR_CTIME;
+ LTIME_S(iattr.ia_atime) = 0;
+ LTIME_S(iattr.ia_mtime) = 0;
+ LTIME_S(iattr.ia_ctime) = 0;
+ err = fsfilt_setattr(obd, dchild, handle, &iattr, 0);
+ if (err)
+ CWARN("%s: unable to initialize a/c/m time of newly "
+ "created object %.*s: rc = %d\n",
+ obd->obd_name, dchild->d_name.len,
+ dchild->d_name.name, err);
+
if (!recreate_obj) {
filter_set_last_id(filter, next_id, group);
err = filter_update_last_objid(obd, group, 0);
if (err)
- CERROR("unable to write lastobjid "
- "but file created\n");
+ CERROR("%s: unable to write lastobjid "
+ "but file created: rc = %d\n",
+ obd->obd_name, err);
}
cleanup:
if (rc)
break;
- if (time_after(jiffies, enough_time)) {
+ if (cfs_time_after(jiffies, enough_time)) {
+ i++;
CDEBUG(D_RPCTRACE,
"%s: precreate slow - want %d got %d \n",
obd->obd_name, *num, i);
*num = i;
CDEBUG(D_RPCTRACE,
- "%s: created %d objects for group "LPU64": "LPU64" rc %d\n",
- obd->obd_name, i, group, filter->fo_last_objids[group], rc);
+ "%s: created %d objects for group "POSTID" rc %d\n",
+ obd->obd_name, i, filter->fo_last_objids[group], group, rc);
RETURN(rc);
}
-static int filter_create(struct obd_export *exp, struct obdo *oa,
- struct lov_stripe_md **ea, struct obd_trans_info *oti)
+int filter_create(const struct lu_env *env, struct obd_export *exp,
+ struct obdo *oa, struct lov_stripe_md **ea,
+ struct obd_trans_info *oti)
{
struct obd_device *obd = exp->exp_obd;
struct filter_export_data *fed;
struct filter_obd *filter;
struct lvfs_run_ctxt saved;
struct lov_stripe_md *lsm = NULL;
- int rc = 0, diff, group = oa->o_gr;
+ int rc = 0, diff;
ENTRY;
- CDEBUG(D_INODE, "%s: filter_create(od->o_gr="LPU64",od->o_id="
- LPU64")\n", obd->obd_name, oa->o_gr, oa->o_id);
-
- if (!(oa->o_valid & OBD_MD_FLGROUP)) {
- CERROR("!!! nid %s sent invalid object group %d\n",
- obd_export_nid2str(exp), group);
- RETURN(-EINVAL);
- }
+ CDEBUG(D_INODE, "%s: filter_create(group="LPU64",id="
+ LPU64")\n", obd->obd_name, oa->o_seq, oa->o_id);
fed = &exp->exp_filter_data;
filter = &obd->u.filter;
- if (fed->fed_group != group) {
- CERROR("!!! this export (nid %s) used object group %d "
- "earlier; now it's trying to use group %d! This could "
- "be a bug in the MDS. Please report to "
- "http://bugzilla.lustre.org/\n",
- obd_export_nid2str(exp), fed->fed_group, group);
+ /* 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 "
+ "http://bugzilla.lustre.org/\n", obd->obd_name,
+ obd_export_nid2str(exp), fed->fed_group, oa->o_seq);
RETURN(-ENOTUNIQ);
}
if ((oa->o_valid & OBD_MD_FLFLAGS) &&
(oa->o_flags & OBD_FL_RECREATE_OBJS)) {
- if (oa->o_id > filter_last_id(filter, oa->o_gr)) {
+ if (!obd->obd_recovering ||
+ oa->o_id > filter_last_id(filter, oa->o_seq)) {
CERROR("recreate objid "LPU64" > last id "LPU64"\n",
- oa->o_id, filter_last_id(filter,
- oa->o_gr));
+ oa->o_id, filter_last_id(filter, oa->o_seq));
rc = -EINVAL;
} else {
diff = 1;
- down(&filter->fo_create_locks[oa->o_gr]);
- rc = filter_precreate(obd, oa, oa->o_gr, &diff);
- up(&filter->fo_create_locks[oa->o_gr]);
+ cfs_mutex_lock(&filter->fo_create_locks[oa->o_seq]);
+ rc = filter_precreate(obd, oa, oa->o_seq, &diff);
+ cfs_mutex_unlock(&filter->fo_create_locks[oa->o_seq]);
}
} else {
- rc = filter_handle_precreate(exp, oa, oa->o_gr, oti);
+ rc = filter_handle_precreate(exp, oa, oa->o_seq, oti);
}
pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
RETURN(rc);
}
-int filter_destroy(struct obd_export *exp, struct obdo *oa,
- struct lov_stripe_md *md, struct obd_trans_info *oti,
- struct obd_export *md_exp, void *capa)
+int filter_destroy(const struct lu_env *env, struct obd_export *exp,
+ struct obdo *oa, struct lov_stripe_md *md,
+ struct obd_trans_info *oti, struct obd_export *md_exp,
+ void *capa)
{
unsigned int qcids[MAXQUOTAS] = {0, 0};
struct obd_device *obd;
struct llog_cookie *fcc = NULL;
int rc, rc2, cleanup_phase = 0, sync = 0;
struct iattr iattr;
+ unsigned long now;
ENTRY;
- LASSERT(oa->o_valid & OBD_MD_FLGROUP);
- rc = filter_auth_capa(exp, NULL, oa->o_gr,
+ rc = filter_auth_capa(exp, NULL, oa->o_seq,
(struct lustre_capa *)capa, CAPA_OPC_OSS_DESTROY);
if (rc)
RETURN(rc);
push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
cleanup_phase = 1;
- CDEBUG(D_INODE, "%s: filter_destroy(od->o_gr="LPU64",od->o_id="
- LPU64")\n", obd->obd_name, oa->o_gr, oa->o_id);
+ CDEBUG(D_INODE, "%s: filter_destroy(group="LPU64",oid="
+ LPU64")\n", obd->obd_name, oa->o_seq, oa->o_id);
- dchild = filter_fid2dentry(obd, NULL, oa->o_gr, oa->o_id);
+ dchild = filter_fid2dentry(obd, NULL, oa->o_seq, oa->o_id);
if (IS_ERR(dchild))
GOTO(cleanup, rc = PTR_ERR(dchild));
cleanup_phase = 2;
if (dchild->d_inode == NULL) {
- CDEBUG(D_INODE, "destroying non-existent object "LPU64"\n",
- oa->o_id);
+ CDEBUG(D_INODE, "destroying non-existent object "POSTID"\n",
+ oa->o_id, oa->o_seq);
/* If object already gone, cancel cookie right now */
if (oa->o_valid & OBD_MD_FLCOOKIE) {
struct llog_ctxt *ctxt;
struct obd_llog_group *olg;
- olg = filter_find_olg(obd, oa->o_gr);
+ olg = filter_find_olg(obd, oa->o_seq);
if (!olg) {
CERROR(" %s: can not find olg of group %d\n",
- obd->obd_name, (int)oa->o_gr);
+ obd->obd_name, (int)oa->o_seq);
GOTO(cleanup, rc = PTR_ERR(olg));
}
fcc = &oa->o_lcookie;
GOTO(cleanup, rc = -ENOENT);
}
- filter_prepare_destroy(obd, oa->o_id, oa->o_gr, &lockh);
+ rc = filter_prepare_destroy(obd, oa->o_id, oa->o_seq, &lockh);
+ if (rc)
+ GOTO(cleanup, rc);
/* Our MDC connection is established by the MDS to us */
if (oa->o_valid & OBD_MD_FLCOOKIE) {
if (fcc != NULL)
*fcc = oa->o_lcookie;
}
- DQUOT_INIT(dchild->d_inode);
/* we're gonna truncate it first in order to avoid possible deadlock:
* P1 P2
* between page lock, i_mutex & starting new journal handle.
* (see bug 20321) -johann
*/
+ now = jiffies;
down_write(&dchild->d_inode->i_alloc_sem);
LOCK_INODE_MUTEX(dchild->d_inode);
+ fsfilt_check_slow(exp->exp_obd, now, "i_alloc_sem and i_mutex");
/* VBR: version recovery check */
rc = filter_version_get_check(exp, oti, dchild->d_inode);
GOTO(cleanup, rc = PTR_ERR(handle));
}
+ /* Locking order: i_mutex -> journal_lock -> dqptr_sem. LU-952 */
+ ll_vfs_dq_init(dchild->d_inode);
+
iattr.ia_valid = ATTR_SIZE;
iattr.ia_size = 0;
rc = fsfilt_setattr(obd, dchild, handle, &iattr, 1);
* here, and not while truncating above. That avoids holding the
* parent lock for a long time during truncate, which can block other
* threads from doing anything to objects in that directory. bug 7171 */
- dparent = filter_parent_lock(obd, oa->o_gr, oa->o_id);
+ dparent = filter_parent_lock(obd, oa->o_seq, oa->o_id);
if (IS_ERR(dparent))
GOTO(cleanup, rc = PTR_ERR(dparent));
cleanup_phase = 3; /* filter_parent_unlock */
cleanup_phase = 4; /* fsfilt_commit */
/* Quota release need uid/gid of inode */
- obdo_from_inode(oa, dchild->d_inode, OBD_MD_FLUID|OBD_MD_FLGID);
+ obdo_from_inode(oa, dchild->d_inode, OBD_MD_FLUID | OBD_MD_FLGID);
- filter_fmd_drop(exp, oa->o_id, oa->o_gr);
+ filter_fmd_drop(exp, oa->o_id, oa->o_seq);
/* this drops dchild->d_inode->i_mutex unconditionally */
- rc = filter_destroy_internal(obd, oa->o_id, oa->o_gr, dparent, dchild);
+ rc = filter_destroy_internal(obd, oa->o_id, oa->o_seq, dparent, dchild);
EXIT;
cleanup:
}
/* NB start and end are used for punch, but not truncate */
-static int filter_truncate(struct obd_export *exp, struct obd_info *oinfo,
- struct obd_trans_info *oti,
+static int filter_truncate(const struct lu_env *env, struct obd_export *exp,
+ struct obd_info *oinfo, struct obd_trans_info *oti,
struct ptlrpc_request_set *rqset)
{
int rc;
}
CDEBUG(D_INODE, "calling truncate for object "LPU64", valid = "LPX64
- ", o_size = "LPD64"\n", oinfo->oi_oa->o_id,
- oinfo->oi_oa->o_valid, oinfo->oi_policy.l_extent.start);
+ ", o_size = "LPD64"\n", oinfo->oi_oa->o_id,oinfo->oi_oa->o_valid,
+ oinfo->oi_policy.l_extent.start);
oinfo->oi_oa->o_size = oinfo->oi_policy.l_extent.start;
- oinfo->oi_oa->o_valid |= OBD_FL_TRUNC;
- rc = filter_setattr(exp, oinfo, oti);
- oinfo->oi_oa->o_valid &= ~OBD_FL_TRUNC;
+ rc = filter_setattr(env, exp, oinfo, oti);
RETURN(rc);
}
-static int filter_sync(struct obd_export *exp, struct obdo *oa,
- struct lov_stripe_md *lsm, obd_off start, obd_off end,
- void *capa)
+static int filter_sync(const struct lu_env *env, struct obd_export *exp,
+ struct obd_info *oinfo, obd_off start, obd_off end,
+ struct ptlrpc_request_set *set)
{
struct lvfs_run_ctxt saved;
- struct filter_obd *filter;
+ struct obd_device_target *obt;
struct dentry *dentry;
int rc, rc2;
ENTRY;
- LASSERT(oa->o_valid & OBD_MD_FLGROUP);
- rc = filter_auth_capa(exp, NULL, oa->o_gr,
- (struct lustre_capa *)capa, CAPA_OPC_OSS_WRITE);
+ rc = filter_auth_capa(exp, NULL, oinfo->oi_oa->o_seq,
+ (struct lustre_capa *)oinfo->oi_capa,
+ CAPA_OPC_OSS_WRITE);
if (rc)
RETURN(rc);
- filter = &exp->exp_obd->u.filter;
+ obt = &exp->exp_obd->u.obt;
/* An objid of zero is taken to mean "sync whole filesystem" */
- if (!oa || !(oa->o_valid & OBD_MD_FLID)) {
- rc = fsfilt_sync(exp->exp_obd, filter->fo_obt.obt_sb);
+ if (!oinfo->oi_oa || !(oinfo->oi_oa->o_valid & OBD_MD_FLID)) {
+ rc = fsfilt_sync(exp->exp_obd, obt->obt_sb);
/* Flush any remaining cancel messages out to the target */
filter_sync_llogs(exp->exp_obd, exp);
RETURN(rc);
}
- dentry = filter_oa2dentry(exp->exp_obd, oa);
+ dentry = filter_oa2dentry(exp->exp_obd, &oinfo->oi_oa->o_oi);
if (IS_ERR(dentry))
RETURN(PTR_ERR(dentry));
rc = filemap_fdatawrite(dentry->d_inode->i_mapping);
if (rc == 0) {
/* just any file to grab fsync method - "file" arg unused */
- struct file *file = filter->fo_rcvd_filp;
+ struct file *file = obt->obt_rcvd_filp;
if (file->f_op && file->f_op->fsync)
rc = file->f_op->fsync(NULL, dentry, 1);
}
UNLOCK_INODE_MUTEX(dentry->d_inode);
- oa->o_valid = OBD_MD_FLID;
- obdo_from_inode(oa, dentry->d_inode, FILTER_VALID_FLAGS);
+ oinfo->oi_oa->o_valid = OBD_MD_FLID;
+ obdo_from_inode(oinfo->oi_oa, dentry->d_inode, FILTER_VALID_FLAGS);
pop_ctxt(&saved, &exp->exp_obd->obd_lvfs_ctxt, NULL);
+ filter_counter_incr(exp, LPROC_FILTER_STATS_SYNC, oinfo->oi_jobid, 1);
f_dput(dentry);
RETURN(rc);
}
-static int filter_get_info(struct obd_export *exp, __u32 keylen,
- void *key, __u32 *vallen, void *val,
+static int filter_get_info(const struct lu_env *env, struct obd_export *exp,
+ __u32 keylen, void *key, __u32 *vallen, void *val,
struct lov_stripe_md *lsm)
{
struct obd_device *obd;
RETURN(0);
}
- dentry = __filter_oa2dentry(exp->exp_obd, &fm_key->oa,
- __FUNCTION__, 1);
+ dentry = __filter_oa2dentry(exp->exp_obd, &fm_key->oa.o_oi,
+ __func__, 1);
if (IS_ERR(dentry))
RETURN(PTR_ERR(dentry));
RETURN(rc);
}
+ if (KEY_IS(KEY_SYNC_LOCK_CANCEL)) {
+ *((__u32 *) val) = obd->u.filter.fo_sync_lock_cancel;
+ *vallen = sizeof(__u32);
+ RETURN(0);
+ }
+
CDEBUG(D_IOCTL, "invalid key\n");
RETURN(-EINVAL);
}
struct ost_body *body)
{
/* handle shrink grant */
- spin_lock(&exp->exp_obd->obd_osfs_lock);
+ cfs_spin_lock(&exp->exp_obd->obd_osfs_lock);
filter_grant_incoming(exp, &body->oa);
- spin_unlock(&exp->exp_obd->obd_osfs_lock);
+ cfs_spin_unlock(&exp->exp_obd->obd_osfs_lock);
RETURN(0);
else
group = 0; /* default value */
- LASSERT_MDS_GROUP(group);
+ LASSERT_SEQ_IS_MDT(group);
rc = filter_setup_llog_group(exp, obd, group);
if (rc)
goto out;
- if (group == FILTER_GROUP_MDS0) {
+ if (group == FID_SEQ_OST_MDT0) {
/* setup llog group 1 for interop */
- filter_setup_llog_group(exp, obd, FILTER_GROUP_LLOG);
+ filter_setup_llog_group(exp, obd, FID_SEQ_LLOG);
}
lquota_setinfo(filter_quota_interface_ref, obd, exp);
RETURN(rc);
}
-static int filter_set_info_async(struct obd_export *exp, __u32 keylen,
+static int filter_set_info_async(const struct lu_env *env,
+ struct obd_export *exp, __u32 keylen,
void *key, __u32 vallen, void *val,
struct ptlrpc_request_set *set)
{
CDEBUG(D_HA, "syncing ost %s\n", obd->obd_name);
rc = fsfilt_sync(obd, obd->u.obt.obt_sb);
- lvfs_set_rdonly(obd, obd->u.obt.obt_sb);
- RETURN(0);
+ rc = lvfs_set_rdonly(obd, obd->u.obt.obt_sb);
+ RETURN(rc);
}
case OBD_IOC_CATLOGLIST: {
RETURN(0);
}
-static int filter_health_check(struct obd_device *obd)
+static int filter_health_check(const struct lu_env *env, struct obd_device *obd)
{
#ifdef USE_HEALTH_CHECK_WRITE
struct filter_obd *filter = &obd->u.filter;
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,
};
.o_create = filter_create,
.o_setattr = filter_setattr,
.o_destroy = filter_destroy,
- .o_brw = filter_brw,
.o_punch = filter_truncate,
.o_sync = filter_sync,
.o_preprw = filter_preprw,
.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;
int rc, i;
/** sanity check for group<->mdsno conversion */
- for (i = 0; i < 32; i++)
- LASSERT(objgrp_to_mdsno(mdt_to_obd_objgrp(i)) == i);
+ for (i = 0; i < MAX_MDT_COUNT; i++)
+ LASSERT(objseq_to_mdsno(mdt_to_obd_objseq(i)) == i);
lprocfs_filter_init_vars(&lvars);
- request_module("%s", "lquota");
+ cfs_request_module("%s", "lquota");
OBD_ALLOC(obdfilter_created_scratchpad,
OBDFILTER_CREATED_SCRATCHPAD_ENTRIES *
sizeof(*obdfilter_created_scratchpad));