Whamcloud - gitweb
LU-7055 osd: move dput() out of osd_ost_fini()'s rwlock 89/19189/2
authorEmoly Liu <emoly.liu@intel.com>
Tue, 29 Mar 2016 07:04:44 +0000 (15:04 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Mon, 11 Apr 2016 02:51:54 +0000 (02:51 +0000)
osd_ost_fini() calls into osd_seq_free() under write lock, which
in turn calls into dput() that might sleep and cause "BUG: rwlock
wrong CPU on CPU#x, umount/xxx" sort of messages.
To fix this issue, this patch only keeps list_del_init() under
write lock, and moves sleeping function out of there.

Signed-off-by: Emoly Liu <emoly.liu@intel.com>
Change-Id: Ie1eef345d1735bb88aeb016a2409ea649cd20fe5
Reviewed-on: http://review.whamcloud.com/19189
Tested-by: Jenkins
Reviewed-by: Fan Yong <fan.yong@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
lustre/osd-ldiskfs/osd_compat.c

index d58b6c8..cec04db 100644 (file)
@@ -421,13 +421,10 @@ cleanup_alloc:
        return rc;
 }
 
        return rc;
 }
 
-static void osd_seq_free(struct osd_obj_map *map,
-                        struct osd_obj_seq *osd_seq)
+static void osd_seq_free(struct osd_obj_seq *osd_seq)
 {
        int j;
 
 {
        int j;
 
-       list_del_init(&osd_seq->oos_seq_list);
-
        if (osd_seq->oos_dirs) {
                for (j = 0; j < osd_seq->oos_subdir_count; j++) {
                        if (osd_seq->oos_dirs[j])
        if (osd_seq->oos_dirs) {
                for (j = 0; j < osd_seq->oos_subdir_count; j++) {
                        if (osd_seq->oos_dirs[j])
@@ -456,7 +453,10 @@ static void osd_ost_fini(struct osd_device *osd)
        write_lock(&map->om_seq_list_lock);
        list_for_each_entry_safe(osd_seq, tmp, &map->om_seq_list,
                                 oos_seq_list) {
        write_lock(&map->om_seq_list_lock);
        list_for_each_entry_safe(osd_seq, tmp, &map->om_seq_list,
                                 oos_seq_list) {
-               osd_seq_free(map, osd_seq);
+               list_del_init(&osd_seq->oos_seq_list);
+               write_unlock(&map->om_seq_list_lock);
+               osd_seq_free(osd_seq);
+               write_lock(&map->om_seq_list_lock);
        }
        write_unlock(&map->om_seq_list_lock);
        if (map->om_root)
        }
        write_unlock(&map->om_seq_list_lock);
        if (map->om_root)