diff options
-rw-r--r-- | drivers/md/bitmap.c | 1 | ||||
-rw-r--r-- | drivers/md/md.c | 49 | ||||
-rw-r--r-- | drivers/md/md.h | 1 |
3 files changed, 16 insertions, 35 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 4195a01b1535..9a8e66ae04f5 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -1988,7 +1988,6 @@ location_store(struct mddev *mddev, const char *buf, size_t len) | |||
1988 | if (mddev->bitmap_info.file) { | 1988 | if (mddev->bitmap_info.file) { |
1989 | struct file *f = mddev->bitmap_info.file; | 1989 | struct file *f = mddev->bitmap_info.file; |
1990 | mddev->bitmap_info.file = NULL; | 1990 | mddev->bitmap_info.file = NULL; |
1991 | restore_bitmap_write_access(f); | ||
1992 | fput(f); | 1991 | fput(f); |
1993 | } | 1992 | } |
1994 | } else { | 1993 | } else { |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 4ad5cc4e63e8..3fa2fc0a5dd2 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -5181,32 +5181,6 @@ static int restart_array(struct mddev *mddev) | |||
5181 | return 0; | 5181 | return 0; |
5182 | } | 5182 | } |
5183 | 5183 | ||
5184 | /* similar to deny_write_access, but accounts for our holding a reference | ||
5185 | * to the file ourselves */ | ||
5186 | static int deny_bitmap_write_access(struct file * file) | ||
5187 | { | ||
5188 | struct inode *inode = file->f_mapping->host; | ||
5189 | |||
5190 | spin_lock(&inode->i_lock); | ||
5191 | if (atomic_read(&inode->i_writecount) > 1) { | ||
5192 | spin_unlock(&inode->i_lock); | ||
5193 | return -ETXTBSY; | ||
5194 | } | ||
5195 | atomic_set(&inode->i_writecount, -1); | ||
5196 | spin_unlock(&inode->i_lock); | ||
5197 | |||
5198 | return 0; | ||
5199 | } | ||
5200 | |||
5201 | void restore_bitmap_write_access(struct file *file) | ||
5202 | { | ||
5203 | struct inode *inode = file->f_mapping->host; | ||
5204 | |||
5205 | spin_lock(&inode->i_lock); | ||
5206 | atomic_set(&inode->i_writecount, 1); | ||
5207 | spin_unlock(&inode->i_lock); | ||
5208 | } | ||
5209 | |||
5210 | static void md_clean(struct mddev *mddev) | 5184 | static void md_clean(struct mddev *mddev) |
5211 | { | 5185 | { |
5212 | mddev->array_sectors = 0; | 5186 | mddev->array_sectors = 0; |
@@ -5427,7 +5401,6 @@ static int do_md_stop(struct mddev * mddev, int mode, | |||
5427 | 5401 | ||
5428 | bitmap_destroy(mddev); | 5402 | bitmap_destroy(mddev); |
5429 | if (mddev->bitmap_info.file) { | 5403 | if (mddev->bitmap_info.file) { |
5430 | restore_bitmap_write_access(mddev->bitmap_info.file); | ||
5431 | fput(mddev->bitmap_info.file); | 5404 | fput(mddev->bitmap_info.file); |
5432 | mddev->bitmap_info.file = NULL; | 5405 | mddev->bitmap_info.file = NULL; |
5433 | } | 5406 | } |
@@ -5979,7 +5952,7 @@ abort_export: | |||
5979 | 5952 | ||
5980 | static int set_bitmap_file(struct mddev *mddev, int fd) | 5953 | static int set_bitmap_file(struct mddev *mddev, int fd) |
5981 | { | 5954 | { |
5982 | int err; | 5955 | int err = 0; |
5983 | 5956 | ||
5984 | if (mddev->pers) { | 5957 | if (mddev->pers) { |
5985 | if (!mddev->pers->quiesce) | 5958 | if (!mddev->pers->quiesce) |
@@ -5991,6 +5964,7 @@ static int set_bitmap_file(struct mddev *mddev, int fd) | |||
5991 | 5964 | ||
5992 | 5965 | ||
5993 | if (fd >= 0) { | 5966 | if (fd >= 0) { |
5967 | struct inode *inode; | ||
5994 | if (mddev->bitmap) | 5968 | if (mddev->bitmap) |
5995 | return -EEXIST; /* cannot add when bitmap is present */ | 5969 | return -EEXIST; /* cannot add when bitmap is present */ |
5996 | mddev->bitmap_info.file = fget(fd); | 5970 | mddev->bitmap_info.file = fget(fd); |
@@ -6001,10 +5975,21 @@ static int set_bitmap_file(struct mddev *mddev, int fd) | |||
6001 | return -EBADF; | 5975 | return -EBADF; |
6002 | } | 5976 | } |
6003 | 5977 | ||
6004 | err = deny_bitmap_write_access(mddev->bitmap_info.file); | 5978 | inode = mddev->bitmap_info.file->f_mapping->host; |
6005 | if (err) { | 5979 | if (!S_ISREG(inode->i_mode)) { |
5980 | printk(KERN_ERR "%s: error: bitmap file must be a regular file\n", | ||
5981 | mdname(mddev)); | ||
5982 | err = -EBADF; | ||
5983 | } else if (!(mddev->bitmap_info.file->f_mode & FMODE_WRITE)) { | ||
5984 | printk(KERN_ERR "%s: error: bitmap file must open for write\n", | ||
5985 | mdname(mddev)); | ||
5986 | err = -EBADF; | ||
5987 | } else if (atomic_read(&inode->i_writecount) != 1) { | ||
6006 | printk(KERN_ERR "%s: error: bitmap file is already in use\n", | 5988 | printk(KERN_ERR "%s: error: bitmap file is already in use\n", |
6007 | mdname(mddev)); | 5989 | mdname(mddev)); |
5990 | err = -EBUSY; | ||
5991 | } | ||
5992 | if (err) { | ||
6008 | fput(mddev->bitmap_info.file); | 5993 | fput(mddev->bitmap_info.file); |
6009 | mddev->bitmap_info.file = NULL; | 5994 | mddev->bitmap_info.file = NULL; |
6010 | return err; | 5995 | return err; |
@@ -6027,10 +6012,8 @@ static int set_bitmap_file(struct mddev *mddev, int fd) | |||
6027 | mddev->pers->quiesce(mddev, 0); | 6012 | mddev->pers->quiesce(mddev, 0); |
6028 | } | 6013 | } |
6029 | if (fd < 0) { | 6014 | if (fd < 0) { |
6030 | if (mddev->bitmap_info.file) { | 6015 | if (mddev->bitmap_info.file) |
6031 | restore_bitmap_write_access(mddev->bitmap_info.file); | ||
6032 | fput(mddev->bitmap_info.file); | 6016 | fput(mddev->bitmap_info.file); |
6033 | } | ||
6034 | mddev->bitmap_info.file = NULL; | 6017 | mddev->bitmap_info.file = NULL; |
6035 | } | 6018 | } |
6036 | 6019 | ||
diff --git a/drivers/md/md.h b/drivers/md/md.h index 07bba96de260..a49d991f3fe1 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h | |||
@@ -605,7 +605,6 @@ extern int md_check_no_bitmap(struct mddev *mddev); | |||
605 | extern int md_integrity_register(struct mddev *mddev); | 605 | extern int md_integrity_register(struct mddev *mddev); |
606 | extern void md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev); | 606 | extern void md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev); |
607 | extern int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale); | 607 | extern int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale); |
608 | extern void restore_bitmap_write_access(struct file *file); | ||
609 | 608 | ||
610 | extern void mddev_init(struct mddev *mddev); | 609 | extern void mddev_init(struct mddev *mddev); |
611 | extern int md_run(struct mddev *mddev); | 610 | extern int md_run(struct mddev *mddev); |