* Use is subject to license terms.
*/
/*
+ * Copyright (c) 2011 Whamcloud, Inc.
+ */
+/*
* This file is part of Lustre, http://www.lustre.org/
* Lustre is a trademark of Sun Microsystems, Inc.
*
if (oti->oti_transno == 0) {
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(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_up(&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);
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, reconnect, &newnid);
+ rc = lprocfs_exp_setup(exp, client_nid, &newnid);
if (rc) {
/* Mask error for already created
* /proc entries */
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);
+ 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);
if (off == 0)
last_group = FID_SEQ_OST_MDT0;
- CWARN("%s: initialize groups [%d,%d]\n", obd->obd_name,
+ CWARN("%s: initialize groups [%u,%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);
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) {
}
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)) {
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);
+ }
+ /* 2.6.9 selinux wants a full option page for do_kern_mount (bug6471) */
+ OBD_PAGE_ALLOC(page, CFS_ALLOC_STD);
+ if (!page)
+ GOTO(remove_entry_clear, 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(remove_entry_clear, rc);
}
+ RETURN(0);
+
+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;
}
*/
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;
if (group == FID_SEQ_LLOG)
RETURN(&obd->obd_olg);
+ 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) {
} 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);
cfs_list_add(&olg->olg_list, &filter->fo_llog_list);
out_unlock:
cfs_spin_unlock(&filter->fo_llog_list_lock);
- GOTO(out, olg);
+ if (olg_new)
+ OBD_FREE_PTR(olg_new);
+ goto out;
}
static int filter_llog_connect(struct obd_export *exp,
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);
}
} 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) {
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);
}
rc = filter_connect_internal(exp, data, 1);
if (rc == 0)
- filter_export_stats_init(obd, exp, 1, localdata);
+ filter_export_stats_init(obd, exp, localdata);
RETURN(rc);
}
if (rc)
GOTO(cleanup, rc);
- filter_export_stats_init(obd, lexp, 0, localdata);
+ filter_export_stats_init(obd, lexp, localdata);
if (obd->obd_replayable) {
struct lsd_client_data *lcd = lexp->exp_target_data.ted_lcd;
LASSERT(lcd);
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);
}
struct lr_server_data *lsd = class_server_data(obd);
int index = le32_to_cpu(lsd->lsd_ost_index);
- if (obd_fail_val == -1 ||
- index == obd_fail_val)
+ if (cfs_fail_val == -1 || index == cfs_fail_val)
osfs->os_bfree = osfs->os_bavail = 2;
- else if (obd_fail_loc & OBD_FAIL_ONCE)
- obd_fail_loc &= ~OBD_FAILED; /* reset flag */
+ else if (cfs_fail_loc & OBD_FAIL_ONCE)
+ cfs_fail_loc &= ~OBD_FAILED; /* reset flag */
}
/* set EROFS to state field if FS is mounted as RDONLY. The goal is to
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;
dchild->d_inode->i_ino);
set_last_id:
+ /* Set a/c/m time to a insane large negative value at creation
+ * time so that any timestamp arriving from the client will
+ * always be newer and update the inode.
+ * See LU-221 for details */
+ iattr.ia_valid = ATTR_ATIME | ATTR_MTIME | ATTR_CTIME;
+ LTIME_S(iattr.ia_atime) = INT_MIN + 24 * 3600;
+ LTIME_S(iattr.ia_mtime) = INT_MIN + 24 * 3600;
+ LTIME_S(iattr.ia_ctime) = INT_MIN + 24 * 3600;
+ err = fsfilt_setattr(obd, dchild, handle, &iattr, 0);
+ if (err)
+ CERROR("unable to initialize a/c/m time of newly"
+ "created inode\n");
+
if (!recreate_obj) {
filter_set_last_id(filter, next_id, group);
err = filter_update_last_objid(obd, group, 0);
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(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 obd_device_target *obt;
int rc, rc2;
ENTRY;
- rc = filter_auth_capa(exp, NULL, oa->o_seq,
- (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);
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)) {
+ 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->o_oi);
+ dentry = filter_oa2dentry(exp->exp_obd, &oinfo->oi_oa->o_oi);
if (IS_ERR(dentry))
RETURN(PTR_ERR(dentry));
}
UNLOCK_INODE_MUTEX(dentry->d_inode);
- oa->o_valid = OBD_MD_FLID;
- obdo_from_inode(oa, dentry->d_inode, NULL, FILTER_VALID_FLAGS);
+ oinfo->oi_oa->o_valid = OBD_MD_FLID;
+ obdo_from_inode(oinfo->oi_oa, dentry->d_inode, NULL,
+ FILTER_VALID_FLAGS);
pop_ctxt(&saved, &exp->exp_obd->obd_lvfs_ctxt, NULL);