* 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.
*/
/*
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 lr_server_data *fsd = class_server_data(exp->exp_obd);
+ 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;
if (!exp->exp_obd->obd_replayable || oti == NULL)
RETURN(rc);
- cfs_mutex_down(&fed->fed_lcd_lock);
- lcd = fed->fed_lcd;
+ cfs_mutex_down(&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_up(&fed->fed_lcd_lock);
+ cfs_mutex_up(&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);
}
/* we don't allocate new transnos for replayed requests */
- cfs_spin_lock(&filter->fo_translock);
+ cfs_spin_lock(&obt->obt_lut->lut_translock);
if (oti->oti_transno == 0) {
- last_rcvd = le64_to_cpu(fsd->lsd_last_transno) + 1;
- 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);
} else {
last_rcvd = oti->oti_transno;
- if (last_rcvd > le64_to_cpu(fsd->lsd_last_transno))
- 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);
}
oti->oti_transno = last_rcvd;
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);
- cfs_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);
- cfs_mutex_up(&fed->fed_lcd_lock);
+ last_rcvd, lcd->lcd_uuid, ted->ted_lr_idx, err);
+ cfs_mutex_up(&ted->ted_lcd_lock);
RETURN(rc);
}
plus the procfs overhead :( */
static int filter_export_stats_init(struct obd_device *obd,
struct obd_export *exp,
+ int reconnect,
void *client_nid)
{
int rc, newnid = 0;
/* Self-export gets no proc entry */
RETURN(0);
- rc = lprocfs_exp_setup(exp, client_nid, &newnid);
+ rc = lprocfs_exp_setup(exp, client_nid, reconnect, &newnid);
if (rc) {
/* Mask error for already created
* /proc entries */
tmp->nid_stats);
if (rc)
GOTO(clean, 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)
- GOTO(clean, rc = -ENOMEM);
-
- lprocfs_init_ldlm_stats(tmp->nid_ldlm_stats);
- rc = lprocfs_register_stats(tmp->nid_proc, "ldlm_stats",
- tmp->nid_ldlm_stats);
+ rc = lprocfs_nid_ldlm_stats_init(tmp);
if (rc)
GOTO(clean, rc);
}
RETURN(0);
clean:
- lprocfs_exp_cleanup(exp);
return rc;
}
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;
- struct lr_server_data *fsd = class_server_data(obd);
- 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
}
}
- fed->fed_lr_idx = cl_idx;
- fed->fed_lr_off = le32_to_cpu(fsd->lsd_client_start) +
- cl_idx * le16_to_cpu(fsd->lsd_client_size);
- cfs_init_mutex(&fed->fed_lcd_lock);
- 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_init_mutex(&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 = 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->exp_need_sync = 1;
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);
}
}
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;
- struct lsd_client_data *lcd = fed->fed_lcd;
int rc;
loff_t off;
ENTRY;
- if (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(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, 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 (!cfs_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();
}
- push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+ 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(obd);
-
- cfs_mutex_down(&fed->fed_lcd_lock);
- memset(fed->fed_lcd->lcd_uuid, 0, sizeof fed->fed_lcd->lcd_uuid);
- rc = fsfilt_write_record(obd, filter->fo_rcvd_filp,
- fed->fed_lcd,
- sizeof(*fed->fed_lcd), &off, 0);
- cfs_mutex_up(&fed->fed_lcd_lock);
- pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+ filter_update_server_data(exp->exp_obd);
+
+ cfs_mutex_down(&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_up(&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",
- lcd->lcd_uuid, fed->fed_lr_idx, fed->fed_lr_off,
+ ted->ted_lcd->lcd_uuid, ted->ted_lr_idx, ted->ted_lr_off,
LAST_RCVD, rc);
EXIT;
free:
static int filter_init_export(struct obd_export *exp)
{
+ int rc;
cfs_spin_lock_init(&exp->exp_filter_data.fed_lock);
CFS_INIT_LIST_HEAD(&exp->exp_filter_data.fed_mod_list);
cfs_spin_lock(&exp->exp_lock);
exp->exp_connecting = 1;
cfs_spin_unlock(&exp->exp_lock);
+ rc = lut_client_alloc(exp);
+ if (rc == 0)
+ rc = ldlm_init_export(exp);
- 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)
{
- lut_fini(NULL, filter->fo_obt.obt_lut);
- OBD_FREE_PTR(filter->fo_obt.obt_lut);
+ lut_fini(NULL, obt->obt_lut);
+ OBD_FREE_PTR(obt->obt_lut);
return 0;
}
int filter_update_server_data(struct obd_device *obd)
{
struct file *filp = obd->u.obt.obt_rcvd_filp;
- struct lr_server_data *fsd = class_server_data(obd);
+ 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, 0);
+ rc = fsfilt_write_record(obd, filp, lsd, sizeof(*lsd), &off, 0);
if (rc)
CERROR("error writing lr_server_data: rc = %d\n", rc);
}
CDEBUG(D_INODE, "%s: server last_objid for "POSTID"\n",
- obd->obd_name, group, filter->fo_last_objids[group]);
+ 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],
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);
/* 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);
RETURN(-ENOMEM);
rc = lut_init(NULL, lut, obd, NULL);
if (rc)
- GOTO(err_fsd, rc);
- fsd = class_server_data(obd);
+ 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",
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;
- cfs_spin_lock(&exp->exp_lock);
- exp->exp_connecting = 0;
- exp->exp_in_recovery = 0;
- cfs_spin_unlock(&exp->exp_lock);
- cfs_spin_lock_bh(&obd->obd_processing_task_lock);
- obd->obd_max_recoverable_clients++;
- cfs_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);
+ 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, 0, 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(fsd->lsd_last_transno))
- 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);
}
+ OBD_FREE_PTR(lcd);
- if (lcd)
- OBD_FREE_PTR(lcd);
-
- obd->obd_last_committed = le64_to_cpu(fsd->lsd_last_transno);
+ 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;
+ 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);
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));
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]);
loff_t off = 0;
ENTRY;
- O_dentry = simple_mkdir(current->fs->pwd, filter->fo_vfsmnt,
+ O_dentry = simple_mkdir(current->fs->pwd, obd->u.obt.obt_vfsmnt,
"O", 0700, 1);
CDEBUG(D_INODE, "got/created O: %p\n", O_dentry);
if (IS_ERR(O_dentry)) {
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);
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;
}
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);
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);
}
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) {
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);
}
}
- filter->fo_vfsmnt = mnt;
+ obd->u.obt.obt_vfsmnt = mnt;
obd->u.obt.obt_sb = mnt->mnt_sb;
+ obd->u.obt.obt_magic = OBT_MAGIC;
filter->fo_fstype = mnt->mnt_sb->s_type->name;
CDEBUG(D_SUPER, "%s: mnt = %p\n", filter->fo_fstype, mnt);
CFS_INIT_LIST_HEAD(&filter->fo_export_list);
cfs_sema_init(&filter->fo_alloc_lock, 1);
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)
obd->obd_name, body->lgdc_logid.lgl_oid,
body->lgdc_logid.lgl_oseq, body->lgdc_logid.lgl_ogen);
- cfs_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;
- cfs_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);
LL_DQUOT_OFF(obd->u.obt.obt_sb);
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);
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. */
}
rc = filter_connect_internal(exp, data, 1);
if (rc == 0)
- filter_export_stats_init(obd, exp, localdata);
+ filter_export_stats_init(obd, exp, 1, localdata);
RETURN(rc);
}
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);
+ filter_export_stats_init(obd, lexp, 0, 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);
cleanup:
if (rc) {
class_disconnect(lexp);
- lprocfs_exp_cleanup(lexp);
*exp = NULL;
} else {
*exp = lexp;
target_destroy_export(exp);
ldlm_destroy_export(exp);
+ lut_client_free(exp);
if (obd_uuid_equals(&exp->exp_client_uuid, &exp->exp_obd->obd_uuid))
RETURN(0);
- lut_client_free(exp);
-
if (!exp->exp_obd->obd_replayable)
fsfilt_sync(exp->exp_obd, exp->exp_obd->u.obt.obt_sb);
if (dchild->d_inode == NULL) {
if (!quiet)
CERROR("%s: %s on non-existent object: "POSTID" \n",
- obd->obd_name, what, ostid->oi_seq,ostid->oi_id);
+ obd->obd_name, what, ostid->oi_id,ostid->oi_seq);
f_dput(dchild);
RETURN(ERR_PTR(-ENOENT));
}
int rc = 0;
ENTRY;
- rc = filter_validate_obdo(oinfo->oi_oa, exp);
- if (rc)
- RETURN(rc);
-
rc = filter_auth_capa(exp, NULL, oinfo->oi_oa->o_seq,
oinfo_capa(oinfo), CAPA_OPC_META_READ);
if (rc)
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);
rc = filter_finish_transno(exp, inode, oti, rc, sync);
if (sync) {
int rc;
ENTRY;
- rc = filter_validate_obdo(oinfo->oi_oa, exp);
- if (rc)
- RETURN(rc);
-
if (oa->o_valid & OBD_FL_TRUNC)
opc |= CAPA_OPC_OSS_TRUNC;
CERROR("%s: setattr from %s trying to truncate objid "POSTID
"%s\n", exp->exp_obd->obd_name, obd_export_nid2str(exp),
- oa->o_seq, oa->o_id, mdsinum);
+ oa->o_id, oa->o_seq, mdsinum);
RETURN(-EPERM);
}
int skip_orphan;
ENTRY;
- rc = filter_validate_obdo(oa, exp);
- if (rc)
- RETURN(rc);
-
LASSERT(down_trylock(&filter->fo_create_locks[oa->o_seq]) != 0);
memset(&doa, 0, sizeof(doa));
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;
}
OBD_ALLOC(osfs, sizeof(*osfs));
if (osfs == NULL)
RETURN(-ENOMEM);
- rc = filter_statfs(obd, osfs, cfs_time_current_64() - CFS_HZ,
+ rc = filter_statfs(obd, 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;
rc = -ENOSPC;
}
/* Temporary solution for oid in CMD before fid-on-OST */
if ((fid_seq_is_mdt0(oa->o_seq) && next_id >= IDIF_MAX_OID) &&
(fid_seq_is_cmd(oa->o_seq) && next_id >= OBIF_MAX_OID)) {
- CERROR("%s:"POSTID" hit the max IDIF_MAX_OID(1 << 48) !\n",
- obd->obd_name, group, next_id);
+ CERROR("%s:"POSTID" hit the max IDIF_MAX_OID(1<<48)!\n",
+ obd->obd_name, next_id, group);
GOTO(cleanup, rc = -ENOSPC);
}
if (rc)
break;
if (cfs_time_after(jiffies, enough_time)) {
+ i++;
CDEBUG(D_RPCTRACE,
"%s: precreate slow - want %d got %d \n",
obd->obd_name, *num, i);
CDEBUG(D_RPCTRACE,
"%s: created %d objects for group "POSTID" rc %d\n",
- obd->obd_name, i, group, filter->fo_last_objids[group], rc);
+ 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(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;
int rc = 0, diff;
ENTRY;
- rc = filter_validate_obdo(oa, exp);
- if (rc)
- RETURN(rc);
-
CDEBUG(D_INODE, "%s: filter_create(group="LPU64",id="
LPU64")\n", obd->obd_name, oa->o_seq, oa->o_id);
if ((oa->o_valid & OBD_MD_FLFLAGS) &&
(oa->o_flags & OBD_FL_RECREATE_OBJS)) {
- if (oa->o_id > filter_last_id(filter, oa->o_seq)) {
+ 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_seq));
rc = -EINVAL;
struct iattr iattr;
ENTRY;
- rc = filter_validate_obdo(oa, exp);
- if (rc)
- RETURN(rc);
rc = filter_auth_capa(exp, NULL, oa->o_seq,
(struct lustre_capa *)capa, CAPA_OPC_OSS_DESTROY);
if (rc)
if (dchild->d_inode == NULL) {
CDEBUG(D_INODE, "destroying non-existent object "POSTID"\n",
- oa->o_seq, oa->o_id);
+ 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;
void *capa)
{
struct lvfs_run_ctxt saved;
- struct filter_obd *filter;
+ struct obd_device_target *obt;
struct dentry *dentry;
int rc, rc2;
ENTRY;
- rc = filter_validate_obdo(oa, exp);
- if (rc)
- RETURN(rc);
-
rc = filter_auth_capa(exp, NULL, oa->o_seq,
(struct lustre_capa *)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);
+ 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);
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);
struct lvfs_run_ctxt saved;
int rc;
- rc = filter_validate_obdo(&fm_key->oa, exp);
- if (rc)
- RETURN(rc);
if (fiemap == NULL) {
*vallen = fiemap_count_to_size(
fm_key->fiemap.fm_extent_count);
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);
}