X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fosd-ldiskfs%2Fosd_scrub.c;h=628771a0e8bfb714693977d62bbba9c9c376a889;hp=184c83a2160fc2efcf7733b10c26906bfc9fad9b;hb=1cab7fafd016621160f49030ea46f155fe34d70b;hpb=c769ba3025c59f110c38c44552a05142705c94c3 diff --git a/lustre/osd-ldiskfs/osd_scrub.c b/lustre/osd-ldiskfs/osd_scrub.c index 184c83a..628771a 100644 --- a/lustre/osd-ldiskfs/osd_scrub.c +++ b/lustre/osd-ldiskfs/osd_scrub.c @@ -783,16 +783,12 @@ static int osd_scrub_next(struct osd_thread_info *info, struct osd_device *dev, struct osd_inode_id *lid; int rc; - if (OBD_FAIL_CHECK(OBD_FAIL_OSD_SCRUB_DELAY) && cfs_fail_val > 0) { - struct l_wait_info lwi; - - lwi = LWI_TIMEOUT(cfs_time_seconds(cfs_fail_val), NULL, NULL); - if (likely(lwi.lwi_timeout > 0)) - l_wait_event(thread->t_ctl_waitq, - !list_empty(&scrub->os_inconsistent_items) || - !thread_is_running(thread), - &lwi); - } + if (OBD_FAIL_CHECK(OBD_FAIL_OSD_SCRUB_DELAY) && cfs_fail_val > 0) + wait_event_idle_timeout( + thread->t_ctl_waitq, + !list_empty(&scrub->os_inconsistent_items) || + !thread_is_running(thread), + cfs_time_seconds(cfs_fail_val)); if (OBD_FAIL_CHECK(OBD_FAIL_OSD_SCRUB_CRASH)) { spin_lock(&scrub->os_lock); @@ -882,7 +878,6 @@ static int osd_scrub_exec(struct osd_thread_info *info, struct osd_device *dev, struct osd_iit_param *param, struct osd_idmap_cache *oic, bool *noslot, int rc) { - struct l_wait_info lwi = { 0 }; struct lustre_scrub *scrub = &dev->od_scrub.os_scrub; struct scrub_file *sf = &scrub->os_file; struct ptlrpc_thread *thread = &scrub->os_thread; @@ -937,8 +932,8 @@ wait: } if (it != NULL) - l_wait_event(thread->t_ctl_waitq, osd_scrub_wakeup(scrub, it), - &lwi); + wait_event_idle(thread->t_ctl_waitq, + osd_scrub_wakeup(scrub, it)); if (!ooc || osd_scrub_has_window(scrub, ooc)) *noslot = false; @@ -1042,7 +1037,6 @@ static int osd_inode_iteration(struct osd_thread_info *info, __u64 *pos; __u64 *count; struct osd_iit_param *param; - struct l_wait_info lwi = { 0 }; __u32 limit; int rc; bool noslot = true; @@ -1105,12 +1099,12 @@ wait: sf->sf_flags &= ~(SF_RECREATED | SF_INCONSISTENT | SF_UPGRADE | SF_AUTO); sf->sf_status = SS_COMPLETED; - l_wait_event(thread->t_ctl_waitq, - !thread_is_running(thread) || - !scrub->os_partial_scan || - scrub->os_in_join || - !list_empty(&scrub->os_inconsistent_items), - &lwi); + wait_event_idle( + thread->t_ctl_waitq, + !thread_is_running(thread) || + !scrub->os_partial_scan || + scrub->os_in_join || + !list_empty(&scrub->os_inconsistent_items)); sf->sf_flags = saved_flags; sf->sf_status = SS_SCANNING; @@ -1132,9 +1126,9 @@ wait: full: if (!preload) { - l_wait_event(thread->t_ctl_waitq, - !thread_is_running(thread) || !scrub->os_in_join, - &lwi); + wait_event_idle(thread->t_ctl_waitq, + !thread_is_running(thread) || + !scrub->os_in_join); if (unlikely(!thread_is_running(thread))) RETURN(0); @@ -1288,13 +1282,12 @@ static int osd_scrub_main(void *args) } if (!scrub->os_full_speed && !scrub->os_partial_scan) { - struct l_wait_info lwi = { 0 }; struct osd_otable_it *it = dev->od_otable_it; struct osd_otable_cache *ooc = &it->ooi_cache; - l_wait_event(thread->t_ctl_waitq, - it->ooi_user_ready || !thread_is_running(thread), - &lwi); + wait_event_idle(thread->t_ctl_waitq, + it->ooi_user_ready || + !thread_is_running(thread)); if (unlikely(!thread_is_running(thread))) GOTO(post, rc = 0); @@ -1731,10 +1724,8 @@ struct osd_ios_item { }; struct osd_ios_filldir_buf { -#ifdef HAVE_DIR_CONTEXT /* please keep it as first member */ struct dir_context ctx; -#endif struct osd_thread_info *oifb_info; struct osd_device *oifb_dev; struct dentry *oifb_dentry; @@ -1959,7 +1950,8 @@ osd_ios_scan_one(struct osd_thread_info *info, struct osd_device *dev, inode); } - rc = osd_oi_lookup(info, dev, &tfid, id2, 0); + /* Since this called from iterate_dir() the inode lock will be taken */ + rc = osd_oi_lookup(info, dev, &tfid, id2, OI_LOCKED); if (rc != 0) { if (rc != -ENOENT) RETURN(rc); @@ -2022,16 +2014,17 @@ static int osd_ios_lf_fill(void *buf, RETURN(0); scrub->os_lf_scanned++; - child = osd_ios_lookup_one_len(name, parent, namelen); + child = osd_lookup_one_len(dev, name, parent, namelen); if (IS_ERR(child)) { + rc = PTR_ERR(child); CDEBUG(D_LFSCK, "%s: cannot lookup child '%.*s': rc = %d\n", - osd_name(dev), namelen, name, (int)PTR_ERR(child)); - RETURN(0); + osd_name(dev), namelen, name, rc); + RETURN(rc); } else if (!child->d_inode) { dput(child); CDEBUG(D_INODE, "%s: child '%.*s' lacks inode\n", osd_name(dev), namelen, name); - RETURN(0); + RETURN(-ENOENT); } inode = child->d_inode; @@ -2096,7 +2089,7 @@ static int osd_ios_varfid_fill(void *buf, if (name[0] == '.') RETURN(0); - child = osd_ios_lookup_one_len(name, fill_buf->oifb_dentry, namelen); + child = osd_lookup_one_len(dev, name, fill_buf->oifb_dentry, namelen); if (IS_ERR(child)) RETURN(PTR_ERR(child)); @@ -2144,7 +2137,7 @@ static int osd_ios_dl_fill(void *buf, if (map->olm_name == NULL) RETURN(0); - child = osd_ios_lookup_one_len(name, fill_buf->oifb_dentry, namelen); + child = osd_lookup_one_len(dev, name, fill_buf->oifb_dentry, namelen); if (IS_ERR(child)) RETURN(PTR_ERR(child)); @@ -2166,6 +2159,7 @@ static int osd_ios_uld_fill(void *buf, { struct osd_ios_filldir_buf *fill_buf = (struct osd_ios_filldir_buf *)buf; + struct osd_device *dev = fill_buf->oifb_dev; struct dentry *child; struct lu_fid tfid; int rc = 0; @@ -2177,7 +2171,7 @@ static int osd_ios_uld_fill(void *buf, if (name[0] != '[') RETURN(0); - child = osd_ios_lookup_one_len(name, fill_buf->oifb_dentry, namelen); + child = osd_lookup_one_len(dev, name, fill_buf->oifb_dentry, namelen); if (IS_ERR(child)) RETURN(PTR_ERR(child)); @@ -2227,7 +2221,7 @@ static int osd_ios_root_fill(void *buf, if (map->olm_name == NULL) RETURN(0); - child = osd_ios_lookup_one_len(name, fill_buf->oifb_dentry, namelen); + child = osd_lookup_one_len(dev, name, fill_buf->oifb_dentry, namelen); if (IS_ERR(child)) RETURN(PTR_ERR(child)); else if (!child->d_inode) @@ -2251,9 +2245,7 @@ osd_ios_general_scan(struct osd_thread_info *info, struct osd_device *dev, struct dentry *dentry, filldir_t filldir) { struct osd_ios_filldir_buf buf = { -#ifdef HAVE_DIR_CONTEXT .ctx.actor = filldir, -#endif .oifb_info = info, .oifb_dev = dev, .oifb_dentry = dentry }; @@ -2267,25 +2259,20 @@ osd_ios_general_scan(struct osd_thread_info *info, struct osd_device *dev, filp->f_pos = 0; filp->f_path.dentry = dentry; - filp->f_mode = FMODE_64BITHASH; + filp->f_flags |= O_NOATIME; + filp->f_mode = FMODE_64BITHASH | FMODE_NONOTIFY; filp->f_mapping = inode->i_mapping; filp->f_op = fops; filp->private_data = NULL; + filp->f_cred = current_cred(); set_file_inode(filp, inode); + rc = osd_security_file_alloc(filp); + if (rc) + RETURN(rc); do { buf.oifb_items = 0; -#ifdef HAVE_DIR_CONTEXT - buf.ctx.pos = filp->f_pos; -#ifdef HAVE_ITERATE_SHARED - rc = fops->iterate_shared(filp, &buf.ctx); -#else - rc = fops->iterate(filp, &buf.ctx); -#endif - filp->f_pos = buf.ctx.pos; -#else - rc = fops->readdir(filp, &buf, filldir); -#endif + rc = iterate_dir(filp, &buf.ctx); } while (rc >= 0 && buf.oifb_items > 0 && filp->f_pos != LDISKFS_HTREE_EOF_64BIT); fops->release(inode, filp); @@ -2317,8 +2304,8 @@ osd_ios_ROOT_scan(struct osd_thread_info *info, struct osd_device *dev, * OI mapping crashed or lost also, then we have to give up under * double failure cases. */ scrub->os_convert_igif = 1; - child = osd_ios_lookup_one_len(dot_lustre_name, dentry, - strlen(dot_lustre_name)); + child = osd_lookup_one_len_unlocked(dev, dot_lustre_name, dentry, + strlen(dot_lustre_name)); if (IS_ERR(child)) { if (PTR_ERR(child) != -ENOENT) RETURN(PTR_ERR(child)); @@ -2349,10 +2336,12 @@ osd_ios_ROOT_scan(struct osd_thread_info *info, struct osd_device *dev, * to access the ".lustre" with cached IGIF. So we prefer * to the solution 2). */ + inode_lock(dentry->d_inode); rc = osd_ios_scan_one(info, dev, dentry->d_inode, child->d_inode, &LU_DOT_LUSTRE_FID, dot_lustre_name, strlen(dot_lustre_name), 0); + inode_unlock(dentry->d_inode); if (rc == -ENOENT) { out_scrub: /* It is 1.8 MDT device. */ @@ -2390,26 +2379,32 @@ osd_ios_OBJECTS_scan(struct osd_thread_info *info, struct osd_device *dev, RETURN(rc); } - child = osd_ios_lookup_one_len(ADMIN_USR, dentry, strlen(ADMIN_USR)); + child = osd_lookup_one_len_unlocked(dev, ADMIN_USR, dentry, + strlen(ADMIN_USR)); if (IS_ERR(child)) { rc = PTR_ERR(child); } else { + inode_lock(dentry->d_inode); rc = osd_ios_scan_one(info, dev, dentry->d_inode, child->d_inode, NULL, ADMIN_USR, strlen(ADMIN_USR), 0); + inode_unlock(dentry->d_inode); dput(child); } if (rc != 0 && rc != -ENOENT) GOTO(out, rc); - child = osd_ios_lookup_one_len(ADMIN_GRP, dentry, strlen(ADMIN_GRP)); + child = osd_lookup_one_len_unlocked(dev, ADMIN_GRP, dentry, + strlen(ADMIN_GRP)); if (IS_ERR(child)) GOTO(out, rc = PTR_ERR(child)); + inode_lock(dentry->d_inode); rc = osd_ios_scan_one(info, dev, dentry->d_inode, child->d_inode, NULL, ADMIN_GRP, strlen(ADMIN_GRP), 0); + inode_unlock(dentry->d_inode); dput(child); out: RETURN(rc == -ENOENT ? 0 : rc); @@ -2429,6 +2424,12 @@ static void osd_initial_OI_scrub(struct osd_thread_info *info, dev->od_igif_inoi = 1; while (1) { + /* Don't take inode_lock here since scandir() callbacks + * can call VFS functions which may manully take the + * inode lock itself like iterate_dir(). Since this + * is the case it is best to leave the scandir() + * callbacks to managing the inode lock. + */ scandir(info, dev, dentry, filldir); if (item != NULL) { dput(item->oii_dentry); @@ -2459,9 +2460,9 @@ static void osd_initial_OI_scrub(struct osd_thread_info *info, continue; } - child = osd_ios_lookup_one_len(map->olm_name, - osd_sb(dev)->s_root, - map->olm_namelen); + child = osd_lookup_one_len_unlocked(dev, map->olm_name, + osd_sb(dev)->s_root, + map->olm_namelen); if (PTR_ERR(child) == -ENOENT || (!IS_ERR(child) && !child->d_inode)) osd_scrub_refresh_mapping(info, dev, &map->olm_fid, @@ -2868,7 +2869,6 @@ static int osd_otable_it_next(const struct lu_env *env, struct dt_it *di) struct lustre_scrub *scrub = &dev->od_scrub.os_scrub; struct osd_otable_cache *ooc = &it->ooi_cache; struct ptlrpc_thread *thread = &scrub->os_thread; - struct l_wait_info lwi = { 0 }; int rc; ENTRY; @@ -2886,9 +2886,8 @@ again: } if (it->ooi_all_cached) { - l_wait_event(thread->t_ctl_waitq, - !thread_is_running(thread), - &lwi); + wait_event_idle(thread->t_ctl_waitq, + !thread_is_running(thread)); RETURN(1); } @@ -2900,9 +2899,8 @@ again: } if (it->ooi_cache.ooc_pos_preload >= scrub->os_pos_current) - l_wait_event(thread->t_ctl_waitq, - osd_otable_it_wakeup(scrub, it), - &lwi); + wait_event_idle(thread->t_ctl_waitq, + osd_otable_it_wakeup(scrub, it)); if (!thread_is_running(thread) && !it->ooi_used_outside) RETURN(1);