diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/bitmap.c | 8 | ||||
-rw-r--r-- | drivers/md/md.c | 49 |
2 files changed, 31 insertions, 26 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index dfe5e12741ba..e40d3e4b8d27 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -625,7 +625,6 @@ static void drain_write_queues(struct bitmap *bitmap) | |||
625 | static void bitmap_file_put(struct bitmap *bitmap) | 625 | static void bitmap_file_put(struct bitmap *bitmap) |
626 | { | 626 | { |
627 | struct file *file; | 627 | struct file *file; |
628 | struct inode *inode; | ||
629 | unsigned long flags; | 628 | unsigned long flags; |
630 | 629 | ||
631 | spin_lock_irqsave(&bitmap->lock, flags); | 630 | spin_lock_irqsave(&bitmap->lock, flags); |
@@ -637,13 +636,8 @@ static void bitmap_file_put(struct bitmap *bitmap) | |||
637 | 636 | ||
638 | bitmap_file_unmap(bitmap); | 637 | bitmap_file_unmap(bitmap); |
639 | 638 | ||
640 | if (file) { | 639 | if (file) |
641 | inode = file->f_mapping->host; | ||
642 | spin_lock(&inode->i_lock); | ||
643 | atomic_set(&inode->i_writecount, 1); /* allow writes again */ | ||
644 | spin_unlock(&inode->i_lock); | ||
645 | fput(file); | 640 | fput(file); |
646 | } | ||
647 | } | 641 | } |
648 | 642 | ||
649 | 643 | ||
diff --git a/drivers/md/md.c b/drivers/md/md.c index ea6837d45fc8..7da9e2d023bb 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -2877,6 +2877,32 @@ out: | |||
2877 | return err; | 2877 | return err; |
2878 | } | 2878 | } |
2879 | 2879 | ||
2880 | /* similar to deny_write_access, but accounts for our holding a reference | ||
2881 | * to the file ourselves */ | ||
2882 | static int deny_bitmap_write_access(struct file * file) | ||
2883 | { | ||
2884 | struct inode *inode = file->f_mapping->host; | ||
2885 | |||
2886 | spin_lock(&inode->i_lock); | ||
2887 | if (atomic_read(&inode->i_writecount) > 1) { | ||
2888 | spin_unlock(&inode->i_lock); | ||
2889 | return -ETXTBSY; | ||
2890 | } | ||
2891 | atomic_set(&inode->i_writecount, -1); | ||
2892 | spin_unlock(&inode->i_lock); | ||
2893 | |||
2894 | return 0; | ||
2895 | } | ||
2896 | |||
2897 | static void restore_bitmap_write_access(struct file *file) | ||
2898 | { | ||
2899 | struct inode *inode = file->f_mapping->host; | ||
2900 | |||
2901 | spin_lock(&inode->i_lock); | ||
2902 | atomic_set(&inode->i_writecount, 1); | ||
2903 | spin_unlock(&inode->i_lock); | ||
2904 | } | ||
2905 | |||
2880 | static int do_md_stop(mddev_t * mddev, int ro) | 2906 | static int do_md_stop(mddev_t * mddev, int ro) |
2881 | { | 2907 | { |
2882 | int err = 0; | 2908 | int err = 0; |
@@ -2940,7 +2966,7 @@ static int do_md_stop(mddev_t * mddev, int ro) | |||
2940 | 2966 | ||
2941 | bitmap_destroy(mddev); | 2967 | bitmap_destroy(mddev); |
2942 | if (mddev->bitmap_file) { | 2968 | if (mddev->bitmap_file) { |
2943 | atomic_set(&mddev->bitmap_file->f_dentry->d_inode->i_writecount, 1); | 2969 | restore_bitmap_write_access(mddev->bitmap_file); |
2944 | fput(mddev->bitmap_file); | 2970 | fput(mddev->bitmap_file); |
2945 | mddev->bitmap_file = NULL; | 2971 | mddev->bitmap_file = NULL; |
2946 | } | 2972 | } |
@@ -3544,23 +3570,6 @@ abort_export: | |||
3544 | return err; | 3570 | return err; |
3545 | } | 3571 | } |
3546 | 3572 | ||
3547 | /* similar to deny_write_access, but accounts for our holding a reference | ||
3548 | * to the file ourselves */ | ||
3549 | static int deny_bitmap_write_access(struct file * file) | ||
3550 | { | ||
3551 | struct inode *inode = file->f_mapping->host; | ||
3552 | |||
3553 | spin_lock(&inode->i_lock); | ||
3554 | if (atomic_read(&inode->i_writecount) > 1) { | ||
3555 | spin_unlock(&inode->i_lock); | ||
3556 | return -ETXTBSY; | ||
3557 | } | ||
3558 | atomic_set(&inode->i_writecount, -1); | ||
3559 | spin_unlock(&inode->i_lock); | ||
3560 | |||
3561 | return 0; | ||
3562 | } | ||
3563 | |||
3564 | static int set_bitmap_file(mddev_t *mddev, int fd) | 3573 | static int set_bitmap_file(mddev_t *mddev, int fd) |
3565 | { | 3574 | { |
3566 | int err; | 3575 | int err; |
@@ -3608,8 +3617,10 @@ static int set_bitmap_file(mddev_t *mddev, int fd) | |||
3608 | mddev->pers->quiesce(mddev, 0); | 3617 | mddev->pers->quiesce(mddev, 0); |
3609 | } | 3618 | } |
3610 | if (fd < 0) { | 3619 | if (fd < 0) { |
3611 | if (mddev->bitmap_file) | 3620 | if (mddev->bitmap_file) { |
3621 | restore_bitmap_write_access(mddev->bitmap_file); | ||
3612 | fput(mddev->bitmap_file); | 3622 | fput(mddev->bitmap_file); |
3623 | } | ||
3613 | mddev->bitmap_file = NULL; | 3624 | mddev->bitmap_file = NULL; |
3614 | } | 3625 | } |
3615 | 3626 | ||