int ops, bool force,
enum oi_check_flags flags)
{
- const struct lu_env *env = info->oti_env;
- struct thandle *th;
- struct osd_thandle *oh;
- int rc;
+ handle_t *th;
+ int rc;
ENTRY;
if (dev->od_scrub.os_file.sf_param & SP_DRYRUN && !force)
RETURN(0);
- th = dt_trans_create(env, &dev->od_dt_dev);
- if (IS_ERR(th))
- RETURN(PTR_ERR(th));
-
- oh = container_of0(th, struct osd_thandle, ot_super);
- LASSERT(oh->ot_handle == NULL);
+ /* DTO_INDEX_INSERT is enough for other two ops:
+ * delete/update, but save stack. */
+ th = ldiskfs_journal_start_sb(osd_sb(dev),
+ osd_dto_credits_noquota[DTO_INDEX_INSERT]);
+ if (IS_ERR(th)) {
+ rc = PTR_ERR(th);
+ CERROR("%s: fail to start trans for scrub %d: rc = %d\n",
+ osd_name(dev), ops, rc);
+ RETURN(rc);
+ }
switch (ops) {
case DTO_INDEX_UPDATE:
- osd_trans_declare_op(env, oh, OSD_OT_UPDATE,
- osd_dto_credits_noquota[DTO_INDEX_UPDATE]);
- rc = dt_trans_start_local(env, &dev->od_dt_dev, th);
- if (rc != 0)
- GOTO(stop, rc);
-
rc = osd_oi_update(info, dev, fid, id, th, flags);
if (unlikely(rc == -ENOENT)) {
/* Some unlink thread may removed the OI mapping. */
}
break;
case DTO_INDEX_INSERT:
- osd_trans_declare_op(env, oh, OSD_OT_INSERT,
- osd_dto_credits_noquota[DTO_INDEX_INSERT]);
- rc = dt_trans_start_local(env, &dev->od_dt_dev, th);
- if (rc != 0)
- GOTO(stop, rc);
-
rc = osd_oi_insert(info, dev, fid, id, th, flags);
if (unlikely(rc == -EEXIST)) {
rc = 1;
}
break;
case DTO_INDEX_DELETE:
- osd_trans_declare_op(env, oh, OSD_OT_DELETE,
- osd_dto_credits_noquota[DTO_INDEX_DELETE]);
- rc = dt_trans_start_local(env, &dev->od_dt_dev, th);
- if (rc != 0)
- GOTO(stop, rc);
-
rc = osd_oi_delete(info, dev, fid, th, flags);
if (rc == -ENOENT) {
/* It is normal that the unlink thread has removed the
break;
}
- GOTO(stop, rc);
-
-stop:
- dt_trans_stop(env, &dev->od_dt_dev, th);
+ ldiskfs_journal_stop(th);
return rc;
}
}
*fid = lma->lma_self_fid;
+ if (unlikely(fid_is_last_id(fid))) {
+ if (scrub) {
+ if (lma->lma_compat & LMAC_FID_ON_OST)
+ rc = SCRUB_NEXT_OSTOBJ;
+ else
+ rc = osd_scrub_check_local_fldb(info,
+ dev, fid);
+ }
+
+ /* XXX: For up layer iteration, LAST_ID is a visible
+ * object to be checked and repaired, so return
+ * it directly.
+ *
+ * In fact, the OSD layer otable-based iteration
+ * should not care about the FID type, it is the
+ * up layer user's duty (LFSCK) to handle that.
+ * It will be fixed in other patch in future. */
+ return rc;
+ }
+
if (fid_is_internal(&lma->lma_self_fid)) {
if (!scrub)
rc = SCRUB_NEXT_CONTINUE;
if (lma->lma_compat & LMAC_FID_ON_OST)
return SCRUB_NEXT_OSTOBJ;
- if (fid_is_idif(fid) || fid_is_last_id(fid))
+ if (fid_is_idif(fid))
return SCRUB_NEXT_OSTOBJ_OLD;
if (lma->lma_incompat & LMAI_AGENT)
loff_t offset, __u64 ino, unsigned d_type);
static int osd_ios_lf_fill(void *buf, const char *name, int namelen,
loff_t offset, __u64 ino, unsigned d_type);
+static int osd_ios_dl_fill(void *buf, const char *name, int namelen,
+ loff_t offset, __u64 ino, unsigned d_type);
static int
osd_ios_general_scan(struct osd_thread_info *info, struct osd_device *dev,
{ NULL, { 0, 0, 0 }, 0, NULL, NULL }
};
+/* Add the new introduced files under .lustre/ in the list in the future. */
+static const struct osd_lf_map osd_dl_maps[] = {
+ /* .lustre/fid */
+ { "fid", { FID_SEQ_DOT_LUSTRE, FID_OID_DOT_LUSTRE_OBF, 0 }, 0,
+ NULL, NULL },
+
+ { NULL, { 0, 0, 0 }, 0, NULL, NULL }
+};
+
struct osd_ios_item {
cfs_list_t oii_list;
struct dentry *oii_dentry;
RETURN(rc);
}
+static int osd_ios_dl_fill(void *buf, const char *name, int namelen,
+ loff_t offset, __u64 ino, unsigned d_type)
+{
+ struct osd_ios_filldir_buf *fill_buf = buf;
+ struct osd_device *dev = fill_buf->oifb_dev;
+ const struct osd_lf_map *map;
+ struct dentry *child;
+ int rc = 0;
+ ENTRY;
+
+ /* skip any '.' started names */
+ if (name[0] == '.')
+ RETURN(0);
+
+ for (map = osd_dl_maps; map->olm_name != NULL; map++) {
+ if (strlen(map->olm_name) != namelen)
+ continue;
+
+ if (strncmp(map->olm_name, name, namelen) == 0)
+ break;
+ }
+
+ if (map->olm_name == NULL)
+ RETURN(0);
+
+ child = osd_ios_lookup_one_len(name, fill_buf->oifb_dentry, namelen);
+ if (IS_ERR(child))
+ RETURN(PTR_ERR(child));
+
+ rc = osd_ios_scan_one(fill_buf->oifb_info, dev, child->d_inode,
+ &map->olm_fid, map->olm_flags);
+ dput(child);
+
+ RETURN(rc);
+}
+
static int osd_ios_root_fill(void *buf, const char *name, int namelen,
loff_t offset, __u64 ino, unsigned d_type)
{
* to the solution 2). */
rc = osd_ios_scan_one(info, dev, child->d_inode,
&LU_DOT_LUSTRE_FID, 0);
+ if (rc == 0)
+ rc = osd_ios_new_item(dev, child, osd_ios_general_scan,
+ osd_ios_dl_fill);
dput(child);
}
spin_lock_init(&scrub->os_lock);
CFS_INIT_LIST_HEAD(&scrub->os_inconsistent_items);
- push_ctxt(&saved, ctxt, NULL);
+ push_ctxt(&saved, ctxt);
filp = filp_open(osd_scrub_name, O_RDWR | O_CREAT, 0644);
if (IS_ERR(filp)) {
- pop_ctxt(&saved, ctxt, NULL);
+ pop_ctxt(&saved, ctxt);
RETURN(PTR_ERR(filp));
}
rc = osd_ea_fid_set(info, inode, fid, LMAC_NOT_IN_OI, 0);
if (rc != 0) {
filp_close(filp, 0);
- pop_ctxt(&saved, ctxt, NULL);
+ pop_ctxt(&saved, ctxt);
RETURN(rc);
}
scrub->os_inode = igrab(inode);
filp_close(filp, 0);
- pop_ctxt(&saved, ctxt, NULL);
+ pop_ctxt(&saved, ctxt);
rc = osd_scrub_file_load(scrub);
if (rc == -ENOENT) {