Dan Carpenter
2023-Jun-06  08:22 UTC
[Ocfs2-devel] [bug report] ocfs2/cluster: Pin/unpin o2hb regions
[ This is ancient code. - dan ]
fs/fs_context.c
    168 {
    169         int ret;
    170 
    171         struct fs_parameter param = {
    172                 .key        = key,
    173                 .type        = fs_value_is_flag,
    174                 .size        = v_size,
    175         };
    176 
    177         if (value) {
--> 178                 param.string = kmemdup_nul(value, v_size,
GFP_KERNEL);
                                                                  ^^^^^^^^^^
Sleeping
    179                 if (!param.string)
    180                         return -ENOMEM;
    181                 param.type = fs_value_is_string;
    182         }
    183 
    184         ret = vfs_parse_fs_param(fc, ¶m);
    185         kfree(param.string);
    186         return ret;
    187 }
There are a couple OCFS functions which call this sleeping function
while holding a spinlock.
o2hb_heartbeat_group_drop_item() <- disables preempt
o2hb_region_inc_user() <- disables preempt
-> o2hb_region_pin()
   -> o2nm_depend_item()
      -> configfs_depend_item()
         -> configfs_pin_fs()
            -> simple_pin_fs()
               -> vfs_kern_mount()
                  -> vfs_parse_fs_string()
fs/ocfs2/cluster/heartbeat.c
  2338  static int o2hb_region_inc_user(const char *region_uuid)
  2339  {
  2340          int ret = 0;
  2341  
  2342          spin_lock(&o2hb_live_lock);
Lock.
  2343  
  2344          /* local heartbeat */
  2345          if (!o2hb_global_heartbeat_active()) {
  2346              ret = o2hb_region_pin(region_uuid);
This function starts the call tree to vfs_parse_fs_string().
  2347              goto unlock;
  2348          }
  2349  
regards,
dan carpenter
