Whamcloud - gitweb
LU-12598 osd-ldiskfs: always return errors for osd_ios_lf_fill
[fs/lustre-release.git] / lustre / osd-ldiskfs / osd_scrub.c
index 184c83a..628771a 100644 (file)
@@ -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);