For ldiskfs backend, the return of readdir() does NOT means
the whole directory being read. Instead, it is the caller's
duty to count whether there are new items read via the last
readdir() then determine whether or not the whole directroy
has been read.
Unfortunately, some old osd-ldiskfs logic, such as OI scrub,
did not handle that properly, as to some directory, such as
lost+found, may be partly scanned. That is why some orphans
cannot be recovered.
Lustre-change: https://review.whamcloud.com/30770
Lustre-commit:
1e2cd1c7025080879a27f9ad9a3896fd3e0e8753
Signed-off-by: Fan Yong <fan.yong@intel.com>
Change-Id: Ib328643c4cdcdb14b548807ed05e8835f80bbf6a
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Lai Siyao <lai.siyao@intel.com>
Signed-off-by: Minh Diep <minh.diep@intel.com>
Reviewed-on: https://review.whamcloud.com/31019
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: John L. Hammond <john.hammond@intel.com>
struct osd_thread_info *oclb_info;
struct osd_device *oclb_dev;
struct osd_idmap_cache *oclb_oic;
+ int oclb_items;
+ bool oclb_found;
};
/**
struct osd_device *dev = oclb->oclb_dev;
struct osd_idmap_cache *oic = oclb->oclb_oic;
struct inode *inode;
- int rc;
+
+ oclb->oclb_items++;
if (name[0] == '.')
return 0;
oic->oic_fid = *fid;
oic->oic_lid = *id;
oic->oic_dev = dev;
- rc = osd_oii_insert(dev, oic, true);
+ osd_oii_insert(dev, oic, true);
+ oclb->oclb_found = true;
- return rc == 0 ? 1 : rc;
+ return 1;
}
/* When lookup item under striped directory, we need to locate the master
#endif
.oclb_info = oti,
.oclb_dev = dev,
- .oclb_oic = oic
+ .oclb_oic = oic,
+ .oclb_found = false,
};
int rc = 0;
ENTRY;
filp->private_data = NULL;
set_file_inode(filp, inode);
+ do {
+ oclb.oclb_items = 0;
#ifdef HAVE_DIR_CONTEXT
- oclb.ctx.pos = filp->f_pos;
- rc = fops->iterate(filp, &oclb.ctx);
- filp->f_pos = oclb.ctx.pos;
+ oclb.ctx.pos = filp->f_pos;
+ rc = fops->iterate(filp, &oclb.ctx);
+ filp->f_pos = oclb.ctx.pos;
#else
- rc = fops->readdir(filp, &oclb, osd_stripe_dir_filldir);
+ rc = fops->readdir(filp, &oclb, osd_stripe_dir_filldir);
#endif
+ } while (rc >= 0 && oclb.oclb_items > 0 && !oclb.oclb_found &&
+ filp->f_pos != LDISKFS_HTREE_EOF_64BIT);
fops->release(inode, filp);
out:
struct osd_thread_info *oifb_info;
struct osd_device *oifb_dev;
struct dentry *oifb_dentry;
+ int oifb_items;
};
static inline struct dentry *
int rc;
ENTRY;
+ fill_buf->oifb_items++;
+
/* skip any '.' started names */
if (name[0] == '.')
RETURN(0);
int rc;
ENTRY;
+ fill_buf->oifb_items++;
+
/* skip any '.' started names */
if (name[0] == '.')
RETURN(0);
int rc = 0;
ENTRY;
+ fill_buf->oifb_items++;
+
/* skip any '.' started names */
if (name[0] == '.')
RETURN(0);
int rc = 0;
ENTRY;
+ fill_buf->oifb_items++;
+
/* skip any non-DFID format name */
if (name[0] != '[')
RETURN(0);
int rc = 0;
ENTRY;
+ fill_buf->oifb_items++;
+
/* skip any '.' started names */
if (name[0] == '.')
RETURN(0);
filp->private_data = NULL;
set_file_inode(filp, inode);
+ do {
+ buf.oifb_items = 0;
#ifdef HAVE_DIR_CONTEXT
- buf.ctx.pos = filp->f_pos;
- rc = fops->iterate(filp, &buf.ctx);
- filp->f_pos = buf.ctx.pos;
+ buf.ctx.pos = filp->f_pos;
+ rc = fops->iterate(filp, &buf.ctx);
+ filp->f_pos = buf.ctx.pos;
#else
- rc = fops->readdir(filp, &buf, filldir);
+ rc = fops->readdir(filp, &buf, filldir);
#endif
+ } while (rc >= 0 && buf.oifb_items > 0 &&
+ filp->f_pos != LDISKFS_HTREE_EOF_64BIT);
fops->release(inode, filp);
RETURN(rc);
do_facet ost1 $LCTL set_param fail_loc=0x196
local count=$(precreated_ost_obj_count 0 0)
- createmany -o $DIR/$tdir/f $((count + 32))
+ createmany -o $DIR/$tdir/f $((count + 1000))
do_facet ost1 $LCTL set_param fail_loc=0
umount_client $MOUNT || error "(1) Fail to stop client!"
local LF_REPAIRED=$($SHOW_SCRUB_ON_OST |
awk '/^lf_repa[ri]*ed/ { print $2 }')
- [ $LF_REPAIRED -gt 0 ] ||
+ [ $LF_REPAIRED -ge 1000 ] ||
error "(6) Some entry under /lost+found should be repaired"
ls -ail $DIR/$tdir > /dev/null || error "(7) ls should succeed"