aboutsummaryrefslogtreecommitdiffstats
path: root/fs/block_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/block_dev.c')
-rw-r--r--fs/block_dev.c414
1 files changed, 250 insertions, 164 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 36c0e7af9d0f..8b18e43b82fe 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -129,43 +129,191 @@ blkdev_get_block(struct inode *inode, sector_t iblock,
129 return 0; 129 return 0;
130} 130}
131 131
132static int 132static int blk_end_aio(struct bio *bio, unsigned int bytes_done, int error)
133blkdev_get_blocks(struct inode *inode, sector_t iblock,
134 struct buffer_head *bh, int create)
135{ 133{
136 sector_t end_block = max_block(I_BDEV(inode)); 134 struct kiocb *iocb = bio->bi_private;
137 unsigned long max_blocks = bh->b_size >> inode->i_blkbits; 135 atomic_t *bio_count = &iocb->ki_bio_count;
138 136
139 if ((iblock + max_blocks) > end_block) { 137 if (bio_data_dir(bio) == READ)
140 max_blocks = end_block - iblock; 138 bio_check_pages_dirty(bio);
141 if ((long)max_blocks <= 0) { 139 else {
142 if (create) 140 bio_release_pages(bio);
143 return -EIO; /* write fully beyond EOF */ 141 bio_put(bio);
144 /* 142 }
145 * It is a read which is fully beyond EOF. We return 143
146 * a !buffer_mapped buffer 144 /* iocb->ki_nbytes stores error code from LLDD */
147 */ 145 if (error)
148 max_blocks = 0; 146 iocb->ki_nbytes = -EIO;
149 } 147
148 if (atomic_dec_and_test(bio_count)) {
149 if (iocb->ki_nbytes < 0)
150 aio_complete(iocb, iocb->ki_nbytes, 0);
151 else
152 aio_complete(iocb, iocb->ki_left, 0);
150 } 153 }
151 154
152 bh->b_bdev = I_BDEV(inode);
153 bh->b_blocknr = iblock;
154 bh->b_size = max_blocks << inode->i_blkbits;
155 if (max_blocks)
156 set_buffer_mapped(bh);
157 return 0; 155 return 0;
158} 156}
159 157
158#define VEC_SIZE 16
159struct pvec {
160 unsigned short nr;
161 unsigned short idx;
162 struct page *page[VEC_SIZE];
163};
164
165#define PAGES_SPANNED(addr, len) \
166 (DIV_ROUND_UP((addr) + (len), PAGE_SIZE) - (addr) / PAGE_SIZE);
167
168/*
169 * get page pointer for user addr, we internally cache struct page array for
170 * (addr, count) range in pvec to avoid frequent call to get_user_pages. If
171 * internal page list is exhausted, a batch count of up to VEC_SIZE is used
172 * to get next set of page struct.
173 */
174static struct page *blk_get_page(unsigned long addr, size_t count, int rw,
175 struct pvec *pvec)
176{
177 int ret, nr_pages;
178 if (pvec->idx == pvec->nr) {
179 nr_pages = PAGES_SPANNED(addr, count);
180 nr_pages = min(nr_pages, VEC_SIZE);
181 down_read(&current->mm->mmap_sem);
182 ret = get_user_pages(current, current->mm, addr, nr_pages,
183 rw == READ, 0, pvec->page, NULL);
184 up_read(&current->mm->mmap_sem);
185 if (ret < 0)
186 return ERR_PTR(ret);
187 pvec->nr = ret;
188 pvec->idx = 0;
189 }
190 return pvec->page[pvec->idx++];
191}
192
160static ssize_t 193static ssize_t
161blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, 194blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
162 loff_t offset, unsigned long nr_segs) 195 loff_t pos, unsigned long nr_segs)
163{ 196{
164 struct file *file = iocb->ki_filp; 197 struct inode *inode = iocb->ki_filp->f_mapping->host;
165 struct inode *inode = file->f_mapping->host; 198 unsigned blkbits = blksize_bits(bdev_hardsect_size(I_BDEV(inode)));
199 unsigned blocksize_mask = (1 << blkbits) - 1;
200 unsigned long seg = 0; /* iov segment iterator */
201 unsigned long nvec; /* number of bio vec needed */
202 unsigned long cur_off; /* offset into current page */
203 unsigned long cur_len; /* I/O len of current page, up to PAGE_SIZE */
204
205 unsigned long addr; /* user iovec address */
206 size_t count; /* user iovec len */
207 size_t nbytes = iocb->ki_nbytes = iocb->ki_left; /* total xfer size */
208 loff_t size; /* size of block device */
209 struct bio *bio;
210 atomic_t *bio_count = &iocb->ki_bio_count;
211 struct page *page;
212 struct pvec pvec;
213
214 pvec.nr = 0;
215 pvec.idx = 0;
216
217 if (pos & blocksize_mask)
218 return -EINVAL;
219
220 size = i_size_read(inode);
221 if (pos + nbytes > size) {
222 nbytes = size - pos;
223 iocb->ki_left = nbytes;
224 }
225
226 /*
227 * check first non-zero iov alignment, the remaining
228 * iov alignment is checked inside bio loop below.
229 */
230 do {
231 addr = (unsigned long) iov[seg].iov_base;
232 count = min(iov[seg].iov_len, nbytes);
233 if (addr & blocksize_mask || count & blocksize_mask)
234 return -EINVAL;
235 } while (!count && ++seg < nr_segs);
236 atomic_set(bio_count, 1);
237
238 while (nbytes) {
239 /* roughly estimate number of bio vec needed */
240 nvec = (nbytes + PAGE_SIZE - 1) / PAGE_SIZE;
241 nvec = max(nvec, nr_segs - seg);
242 nvec = min(nvec, (unsigned long) BIO_MAX_PAGES);
243
244 /* bio_alloc should not fail with GFP_KERNEL flag */
245 bio = bio_alloc(GFP_KERNEL, nvec);
246 bio->bi_bdev = I_BDEV(inode);
247 bio->bi_end_io = blk_end_aio;
248 bio->bi_private = iocb;
249 bio->bi_sector = pos >> blkbits;
250same_bio:
251 cur_off = addr & ~PAGE_MASK;
252 cur_len = PAGE_SIZE - cur_off;
253 if (count < cur_len)
254 cur_len = count;
255
256 page = blk_get_page(addr, count, rw, &pvec);
257 if (unlikely(IS_ERR(page)))
258 goto backout;
259
260 if (bio_add_page(bio, page, cur_len, cur_off)) {
261 pos += cur_len;
262 addr += cur_len;
263 count -= cur_len;
264 nbytes -= cur_len;
265
266 if (count)
267 goto same_bio;
268 while (++seg < nr_segs) {
269 addr = (unsigned long) iov[seg].iov_base;
270 count = iov[seg].iov_len;
271 if (!count)
272 continue;
273 if (unlikely(addr & blocksize_mask ||
274 count & blocksize_mask)) {
275 page = ERR_PTR(-EINVAL);
276 goto backout;
277 }
278 count = min(count, nbytes);
279 goto same_bio;
280 }
281 }
282
283 /* bio is ready, submit it */
284 if (rw == READ)
285 bio_set_pages_dirty(bio);
286 atomic_inc(bio_count);
287 submit_bio(rw, bio);
288 }
289
290completion:
291 iocb->ki_left -= nbytes;
292 nbytes = iocb->ki_left;
293 iocb->ki_pos += nbytes;
294
295 blk_run_address_space(inode->i_mapping);
296 if (atomic_dec_and_test(bio_count))
297 aio_complete(iocb, nbytes, 0);
298
299 return -EIOCBQUEUED;
166 300
167 return blockdev_direct_IO_no_locking(rw, iocb, inode, I_BDEV(inode), 301backout:
168 iov, offset, nr_segs, blkdev_get_blocks, NULL); 302 /*
303 * back out nbytes count constructed so far for this bio,
304 * we will throw away current bio.
305 */
306 nbytes += bio->bi_size;
307 bio_release_pages(bio);
308 bio_put(bio);
309
310 /*
311 * if no bio was submmitted, return the error code.
312 * otherwise, proceed with pending I/O completion.
313 */
314 if (atomic_read(bio_count) == 1)
315 return PTR_ERR(page);
316 goto completion;
169} 317}
170 318
171static int blkdev_writepage(struct page *page, struct writeback_control *wbc) 319static int blkdev_writepage(struct page *page, struct writeback_control *wbc)
@@ -190,7 +338,7 @@ static int blkdev_commit_write(struct file *file, struct page *page, unsigned fr
190 338
191/* 339/*
192 * private llseek: 340 * private llseek:
193 * for a block special file file->f_dentry->d_inode->i_size is zero 341 * for a block special file file->f_path.dentry->d_inode->i_size is zero
194 * so we compute the size by hand (just as in block_read/write above) 342 * so we compute the size by hand (just as in block_read/write above)
195 */ 343 */
196static loff_t block_llseek(struct file *file, loff_t offset, int origin) 344static loff_t block_llseek(struct file *file, loff_t offset, int origin)
@@ -235,11 +383,11 @@ static int block_fsync(struct file *filp, struct dentry *dentry, int datasync)
235 */ 383 */
236 384
237static __cacheline_aligned_in_smp DEFINE_SPINLOCK(bdev_lock); 385static __cacheline_aligned_in_smp DEFINE_SPINLOCK(bdev_lock);
238static kmem_cache_t * bdev_cachep __read_mostly; 386static struct kmem_cache * bdev_cachep __read_mostly;
239 387
240static struct inode *bdev_alloc_inode(struct super_block *sb) 388static struct inode *bdev_alloc_inode(struct super_block *sb)
241{ 389{
242 struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, SLAB_KERNEL); 390 struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, GFP_KERNEL);
243 if (!ei) 391 if (!ei)
244 return NULL; 392 return NULL;
245 return &ei->vfs_inode; 393 return &ei->vfs_inode;
@@ -253,7 +401,7 @@ static void bdev_destroy_inode(struct inode *inode)
253 kmem_cache_free(bdev_cachep, bdi); 401 kmem_cache_free(bdev_cachep, bdi);
254} 402}
255 403
256static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) 404static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
257{ 405{
258 struct bdev_inode *ei = (struct bdev_inode *) foo; 406 struct bdev_inode *ei = (struct bdev_inode *) foo;
259 struct block_device *bdev = &ei->bdev; 407 struct block_device *bdev = &ei->bdev;
@@ -263,7 +411,7 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
263 { 411 {
264 memset(bdev, 0, sizeof(*bdev)); 412 memset(bdev, 0, sizeof(*bdev));
265 mutex_init(&bdev->bd_mutex); 413 mutex_init(&bdev->bd_mutex);
266 mutex_init(&bdev->bd_mount_mutex); 414 sema_init(&bdev->bd_mount_sem, 1);
267 INIT_LIST_HEAD(&bdev->bd_inodes); 415 INIT_LIST_HEAD(&bdev->bd_inodes);
268 INIT_LIST_HEAD(&bdev->bd_list); 416 INIT_LIST_HEAD(&bdev->bd_list);
269#ifdef CONFIG_SYSFS 417#ifdef CONFIG_SYSFS
@@ -762,7 +910,7 @@ static int bd_claim_by_kobject(struct block_device *bdev, void *holder,
762 if (!bo) 910 if (!bo)
763 return -ENOMEM; 911 return -ENOMEM;
764 912
765 mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_PARTITION); 913 mutex_lock(&bdev->bd_mutex);
766 res = bd_claim(bdev, holder); 914 res = bd_claim(bdev, holder);
767 if (res == 0) { 915 if (res == 0) {
768 found = find_bd_holder(bdev, bo); 916 found = find_bd_holder(bdev, bo);
@@ -796,7 +944,7 @@ static void bd_release_from_kobject(struct block_device *bdev,
796 if (!kobj) 944 if (!kobj)
797 return; 945 return;
798 946
799 mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_PARTITION); 947 mutex_lock(&bdev->bd_mutex);
800 bd_release(bdev); 948 bd_release(bdev);
801 if ((bo = del_bd_holder(bdev, kobj))) 949 if ((bo = del_bd_holder(bdev, kobj)))
802 free_bd_holder(bo); 950 free_bd_holder(bo);
@@ -854,22 +1002,6 @@ struct block_device *open_by_devnum(dev_t dev, unsigned mode)
854 1002
855EXPORT_SYMBOL(open_by_devnum); 1003EXPORT_SYMBOL(open_by_devnum);
856 1004
857static int
858blkdev_get_partition(struct block_device *bdev, mode_t mode, unsigned flags);
859
860struct block_device *open_partition_by_devnum(dev_t dev, unsigned mode)
861{
862 struct block_device *bdev = bdget(dev);
863 int err = -ENOMEM;
864 int flags = mode & FMODE_WRITE ? O_RDWR : O_RDONLY;
865 if (bdev)
866 err = blkdev_get_partition(bdev, mode, flags);
867 return err ? ERR_PTR(err) : bdev;
868}
869
870EXPORT_SYMBOL(open_partition_by_devnum);
871
872
873/* 1005/*
874 * This routine checks whether a removable media has been changed, 1006 * This routine checks whether a removable media has been changed,
875 * and invalidates all buffer-cache-entries in that case. This 1007 * and invalidates all buffer-cache-entries in that case. This
@@ -916,66 +1048,11 @@ void bd_set_size(struct block_device *bdev, loff_t size)
916} 1048}
917EXPORT_SYMBOL(bd_set_size); 1049EXPORT_SYMBOL(bd_set_size);
918 1050
919static int __blkdev_put(struct block_device *bdev, unsigned int subclass) 1051static int __blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags,
920{ 1052 int for_part);
921 int ret = 0; 1053static int __blkdev_put(struct block_device *bdev, int for_part);
922 struct inode *bd_inode = bdev->bd_inode;
923 struct gendisk *disk = bdev->bd_disk;
924 1054
925 mutex_lock_nested(&bdev->bd_mutex, subclass); 1055static int do_open(struct block_device *bdev, struct file *file, int for_part)
926 lock_kernel();
927 if (!--bdev->bd_openers) {
928 sync_blockdev(bdev);
929 kill_bdev(bdev);
930 }
931 if (bdev->bd_contains == bdev) {
932 if (disk->fops->release)
933 ret = disk->fops->release(bd_inode, NULL);
934 } else {
935 mutex_lock_nested(&bdev->bd_contains->bd_mutex,
936 subclass + 1);
937 bdev->bd_contains->bd_part_count--;
938 mutex_unlock(&bdev->bd_contains->bd_mutex);
939 }
940 if (!bdev->bd_openers) {
941 struct module *owner = disk->fops->owner;
942
943 put_disk(disk);
944 module_put(owner);
945
946 if (bdev->bd_contains != bdev) {
947 kobject_put(&bdev->bd_part->kobj);
948 bdev->bd_part = NULL;
949 }
950 bdev->bd_disk = NULL;
951 bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info;
952 if (bdev != bdev->bd_contains)
953 __blkdev_put(bdev->bd_contains, subclass + 1);
954 bdev->bd_contains = NULL;
955 }
956 unlock_kernel();
957 mutex_unlock(&bdev->bd_mutex);
958 bdput(bdev);
959 return ret;
960}
961
962int blkdev_put(struct block_device *bdev)
963{
964 return __blkdev_put(bdev, BD_MUTEX_NORMAL);
965}
966EXPORT_SYMBOL(blkdev_put);
967
968int blkdev_put_partition(struct block_device *bdev)
969{
970 return __blkdev_put(bdev, BD_MUTEX_PARTITION);
971}
972EXPORT_SYMBOL(blkdev_put_partition);
973
974static int
975blkdev_get_whole(struct block_device *bdev, mode_t mode, unsigned flags);
976
977static int
978do_open(struct block_device *bdev, struct file *file, unsigned int subclass)
979{ 1056{
980 struct module *owner = NULL; 1057 struct module *owner = NULL;
981 struct gendisk *disk; 1058 struct gendisk *disk;
@@ -992,8 +1069,7 @@ do_open(struct block_device *bdev, struct file *file, unsigned int subclass)
992 } 1069 }
993 owner = disk->fops->owner; 1070 owner = disk->fops->owner;
994 1071
995 mutex_lock_nested(&bdev->bd_mutex, subclass); 1072 mutex_lock_nested(&bdev->bd_mutex, for_part);
996
997 if (!bdev->bd_openers) { 1073 if (!bdev->bd_openers) {
998 bdev->bd_disk = disk; 1074 bdev->bd_disk = disk;
999 bdev->bd_contains = bdev; 1075 bdev->bd_contains = bdev;
@@ -1020,25 +1096,21 @@ do_open(struct block_device *bdev, struct file *file, unsigned int subclass)
1020 ret = -ENOMEM; 1096 ret = -ENOMEM;
1021 if (!whole) 1097 if (!whole)
1022 goto out_first; 1098 goto out_first;
1023 ret = blkdev_get_whole(whole, file->f_mode, file->f_flags); 1099 BUG_ON(for_part);
1100 ret = __blkdev_get(whole, file->f_mode, file->f_flags, 1);
1024 if (ret) 1101 if (ret)
1025 goto out_first; 1102 goto out_first;
1026 bdev->bd_contains = whole; 1103 bdev->bd_contains = whole;
1027 mutex_lock_nested(&whole->bd_mutex, BD_MUTEX_WHOLE);
1028 whole->bd_part_count++;
1029 p = disk->part[part - 1]; 1104 p = disk->part[part - 1];
1030 bdev->bd_inode->i_data.backing_dev_info = 1105 bdev->bd_inode->i_data.backing_dev_info =
1031 whole->bd_inode->i_data.backing_dev_info; 1106 whole->bd_inode->i_data.backing_dev_info;
1032 if (!(disk->flags & GENHD_FL_UP) || !p || !p->nr_sects) { 1107 if (!(disk->flags & GENHD_FL_UP) || !p || !p->nr_sects) {
1033 whole->bd_part_count--;
1034 mutex_unlock(&whole->bd_mutex);
1035 ret = -ENXIO; 1108 ret = -ENXIO;
1036 goto out_first; 1109 goto out_first;
1037 } 1110 }
1038 kobject_get(&p->kobj); 1111 kobject_get(&p->kobj);
1039 bdev->bd_part = p; 1112 bdev->bd_part = p;
1040 bd_set_size(bdev, (loff_t) p->nr_sects << 9); 1113 bd_set_size(bdev, (loff_t) p->nr_sects << 9);
1041 mutex_unlock(&whole->bd_mutex);
1042 } 1114 }
1043 } else { 1115 } else {
1044 put_disk(disk); 1116 put_disk(disk);
@@ -1051,14 +1123,11 @@ do_open(struct block_device *bdev, struct file *file, unsigned int subclass)
1051 } 1123 }
1052 if (bdev->bd_invalidated) 1124 if (bdev->bd_invalidated)
1053 rescan_partitions(bdev->bd_disk, bdev); 1125 rescan_partitions(bdev->bd_disk, bdev);
1054 } else {
1055 mutex_lock_nested(&bdev->bd_contains->bd_mutex,
1056 BD_MUTEX_WHOLE);
1057 bdev->bd_contains->bd_part_count++;
1058 mutex_unlock(&bdev->bd_contains->bd_mutex);
1059 } 1126 }
1060 } 1127 }
1061 bdev->bd_openers++; 1128 bdev->bd_openers++;
1129 if (for_part)
1130 bdev->bd_part_count++;
1062 mutex_unlock(&bdev->bd_mutex); 1131 mutex_unlock(&bdev->bd_mutex);
1063 unlock_kernel(); 1132 unlock_kernel();
1064 return 0; 1133 return 0;
@@ -1067,7 +1136,7 @@ out_first:
1067 bdev->bd_disk = NULL; 1136 bdev->bd_disk = NULL;
1068 bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; 1137 bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info;
1069 if (bdev != bdev->bd_contains) 1138 if (bdev != bdev->bd_contains)
1070 __blkdev_put(bdev->bd_contains, BD_MUTEX_WHOLE); 1139 __blkdev_put(bdev->bd_contains, 1);
1071 bdev->bd_contains = NULL; 1140 bdev->bd_contains = NULL;
1072 put_disk(disk); 1141 put_disk(disk);
1073 module_put(owner); 1142 module_put(owner);
@@ -1079,7 +1148,8 @@ out:
1079 return ret; 1148 return ret;
1080} 1149}
1081 1150
1082int blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags) 1151static int __blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags,
1152 int for_part)
1083{ 1153{
1084 /* 1154 /*
1085 * This crockload is due to bad choice of ->open() type. 1155 * This crockload is due to bad choice of ->open() type.
@@ -1091,51 +1161,17 @@ int blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags)
1091 struct dentry fake_dentry = {}; 1161 struct dentry fake_dentry = {};
1092 fake_file.f_mode = mode; 1162 fake_file.f_mode = mode;
1093 fake_file.f_flags = flags; 1163 fake_file.f_flags = flags;
1094 fake_file.f_dentry = &fake_dentry; 1164 fake_file.f_path.dentry = &fake_dentry;
1095 fake_dentry.d_inode = bdev->bd_inode; 1165 fake_dentry.d_inode = bdev->bd_inode;
1096 1166
1097 return do_open(bdev, &fake_file, BD_MUTEX_NORMAL); 1167 return do_open(bdev, &fake_file, for_part);
1098} 1168}
1099 1169
1100EXPORT_SYMBOL(blkdev_get); 1170int blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags)
1101
1102static int
1103blkdev_get_whole(struct block_device *bdev, mode_t mode, unsigned flags)
1104{
1105 /*
1106 * This crockload is due to bad choice of ->open() type.
1107 * It will go away.
1108 * For now, block device ->open() routine must _not_
1109 * examine anything in 'inode' argument except ->i_rdev.
1110 */
1111 struct file fake_file = {};
1112 struct dentry fake_dentry = {};
1113 fake_file.f_mode = mode;
1114 fake_file.f_flags = flags;
1115 fake_file.f_dentry = &fake_dentry;
1116 fake_dentry.d_inode = bdev->bd_inode;
1117
1118 return do_open(bdev, &fake_file, BD_MUTEX_WHOLE);
1119}
1120
1121static int
1122blkdev_get_partition(struct block_device *bdev, mode_t mode, unsigned flags)
1123{ 1171{
1124 /* 1172 return __blkdev_get(bdev, mode, flags, 0);
1125 * This crockload is due to bad choice of ->open() type.
1126 * It will go away.
1127 * For now, block device ->open() routine must _not_
1128 * examine anything in 'inode' argument except ->i_rdev.
1129 */
1130 struct file fake_file = {};
1131 struct dentry fake_dentry = {};
1132 fake_file.f_mode = mode;
1133 fake_file.f_flags = flags;
1134 fake_file.f_dentry = &fake_dentry;
1135 fake_dentry.d_inode = bdev->bd_inode;
1136
1137 return do_open(bdev, &fake_file, BD_MUTEX_PARTITION);
1138} 1173}
1174EXPORT_SYMBOL(blkdev_get);
1139 1175
1140static int blkdev_open(struct inode * inode, struct file * filp) 1176static int blkdev_open(struct inode * inode, struct file * filp)
1141{ 1177{
@@ -1154,7 +1190,7 @@ static int blkdev_open(struct inode * inode, struct file * filp)
1154 if (bdev == NULL) 1190 if (bdev == NULL)
1155 return -ENOMEM; 1191 return -ENOMEM;
1156 1192
1157 res = do_open(bdev, filp, BD_MUTEX_NORMAL); 1193 res = do_open(bdev, filp, 0);
1158 if (res) 1194 if (res)
1159 return res; 1195 return res;
1160 1196
@@ -1168,6 +1204,56 @@ static int blkdev_open(struct inode * inode, struct file * filp)
1168 return res; 1204 return res;
1169} 1205}
1170 1206
1207static int __blkdev_put(struct block_device *bdev, int for_part)
1208{
1209 int ret = 0;
1210 struct inode *bd_inode = bdev->bd_inode;
1211 struct gendisk *disk = bdev->bd_disk;
1212 struct block_device *victim = NULL;
1213
1214 mutex_lock_nested(&bdev->bd_mutex, for_part);
1215 lock_kernel();
1216 if (for_part)
1217 bdev->bd_part_count--;
1218
1219 if (!--bdev->bd_openers) {
1220 sync_blockdev(bdev);
1221 kill_bdev(bdev);
1222 }
1223 if (bdev->bd_contains == bdev) {
1224 if (disk->fops->release)
1225 ret = disk->fops->release(bd_inode, NULL);
1226 }
1227 if (!bdev->bd_openers) {
1228 struct module *owner = disk->fops->owner;
1229
1230 put_disk(disk);
1231 module_put(owner);
1232
1233 if (bdev->bd_contains != bdev) {
1234 kobject_put(&bdev->bd_part->kobj);
1235 bdev->bd_part = NULL;
1236 }
1237 bdev->bd_disk = NULL;
1238 bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info;
1239 if (bdev != bdev->bd_contains)
1240 victim = bdev->bd_contains;
1241 bdev->bd_contains = NULL;
1242 }
1243 unlock_kernel();
1244 mutex_unlock(&bdev->bd_mutex);
1245 bdput(bdev);
1246 if (victim)
1247 __blkdev_put(victim, 1);
1248 return ret;
1249}
1250
1251int blkdev_put(struct block_device *bdev)
1252{
1253 return __blkdev_put(bdev, 0);
1254}
1255EXPORT_SYMBOL(blkdev_put);
1256
1171static int blkdev_close(struct inode * inode, struct file * filp) 1257static int blkdev_close(struct inode * inode, struct file * filp)
1172{ 1258{
1173 struct block_device *bdev = I_BDEV(filp->f_mapping->host); 1259 struct block_device *bdev = I_BDEV(filp->f_mapping->host);