It makes more sense to report bitmap_info->file, rather than
bitmap->file (the later is only available once the array is
active).
With that change, use mddev->lock to protect bitmap_info being
set to NULL, and we can call get_bitmap_file() without taking
the mutex.
Signed-off-by: NeilBrown <neilb@suse.de>
bitmap_destroy(mddev);
if (mddev->bitmap_info.file) {
bitmap_destroy(mddev);
if (mddev->bitmap_info.file) {
- fput(mddev->bitmap_info.file);
+ struct file *f = mddev->bitmap_info.file;
+ spin_lock(&mddev->lock);
mddev->bitmap_info.file = NULL;
mddev->bitmap_info.file = NULL;
+ spin_unlock(&mddev->lock);
+ fput(f);
}
mddev->bitmap_info.offset = 0;
}
mddev->bitmap_info.offset = 0;
{
mdu_bitmap_file_t *file = NULL; /* too big for stack allocation */
char *ptr;
{
mdu_bitmap_file_t *file = NULL; /* too big for stack allocation */
char *ptr;
file = kmalloc(sizeof(*file), GFP_NOIO);
file = kmalloc(sizeof(*file), GFP_NOIO);
+ err = 0;
+ spin_lock(&mddev->lock);
/* bitmap disabled, zero the first byte and copy out */
/* bitmap disabled, zero the first byte and copy out */
- if (!mddev->bitmap || !mddev->bitmap->storage.file) {
+ if (!mddev->bitmap_info.file)
file->pathname[0] = '\0';
file->pathname[0] = '\0';
- goto copy_out;
- }
-
- ptr = d_path(&mddev->bitmap->storage.file->f_path,
- file->pathname, sizeof(file->pathname));
- if (IS_ERR(ptr))
- goto out;
-
- memmove(file->pathname, ptr,
- sizeof(file->pathname)-(ptr-file->pathname));
+ else if ((ptr = d_path(&mddev->bitmap_info.file->f_path,
+ file->pathname, sizeof(file->pathname))),
+ IS_ERR(ptr))
+ err = PTR_ERR(ptr);
+ else
+ memmove(file->pathname, ptr,
+ sizeof(file->pathname)-(ptr-file->pathname));
+ spin_unlock(&mddev->lock);
-copy_out:
- err = 0;
- if (copy_to_user(arg, file, sizeof(*file)))
+ if (err == 0 &&
+ copy_to_user(arg, file, sizeof(*file)))
kfree(file);
return err;
}
kfree(file);
return err;
}
mddev->pers->quiesce(mddev, 0);
}
if (fd < 0) {
mddev->pers->quiesce(mddev, 0);
}
if (fd < 0) {
- if (mddev->bitmap_info.file)
- fput(mddev->bitmap_info.file);
- mddev->bitmap_info.file = NULL;
+ struct file *f = mddev->bitmap_info.file;
+ if (f) {
+ spin_lock(&mddev->lock);
+ mddev->bitmap_info.file = NULL;
+ spin_unlock(&mddev->lock);
+ fput(f);
+ }
case SET_DISK_FAULTY:
err = set_disk_faulty(mddev, new_decode_dev(arg));
goto out;
case SET_DISK_FAULTY:
err = set_disk_faulty(mddev, new_decode_dev(arg));
goto out;
+
+ case GET_BITMAP_FILE:
+ err = get_bitmap_file(mddev, argp);
+ goto out;
+
}
if (cmd == ADD_NEW_DISK)
}
if (cmd == ADD_NEW_DISK)
* Commands even a read-only array can execute:
*/
switch (cmd) {
* Commands even a read-only array can execute:
*/
switch (cmd) {
- case GET_BITMAP_FILE:
- err = get_bitmap_file(mddev, argp);
- goto unlock;
-
case RESTART_ARRAY_RW:
err = restart_array(mddev);
goto unlock;
case RESTART_ARRAY_RW:
err = restart_array(mddev);
goto unlock;
* in_sync - and related safemode and MD_CHANGE changes
* pers (also protected by reconfig_mutex and pending IO).
* clearing ->bitmap
* in_sync - and related safemode and MD_CHANGE changes
* pers (also protected by reconfig_mutex and pending IO).
* clearing ->bitmap
+ * clearing ->bitmap_info.file
*/
spinlock_t lock;
wait_queue_head_t sb_wait; /* for waiting on superblock updates */
*/
spinlock_t lock;
wait_queue_head_t sb_wait; /* for waiting on superblock updates */