diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/direct-io.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/fs/direct-io.c b/fs/direct-io.c index b01ea0d7160d..6bb04409e725 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c | |||
@@ -140,7 +140,9 @@ struct dio { | |||
140 | * wish that they not be zeroed. | 140 | * wish that they not be zeroed. |
141 | */ | 141 | */ |
142 | struct page *pages[DIO_PAGES]; /* page buffer */ | 142 | struct page *pages[DIO_PAGES]; /* page buffer */ |
143 | }; | 143 | } ____cacheline_aligned_in_smp; |
144 | |||
145 | static struct kmem_cache *dio_cache __read_mostly; | ||
144 | 146 | ||
145 | static void __inode_dio_wait(struct inode *inode) | 147 | static void __inode_dio_wait(struct inode *inode) |
146 | { | 148 | { |
@@ -330,7 +332,7 @@ static void dio_bio_end_aio(struct bio *bio, int error) | |||
330 | 332 | ||
331 | if (remaining == 0) { | 333 | if (remaining == 0) { |
332 | dio_complete(dio, dio->iocb->ki_pos, 0, true); | 334 | dio_complete(dio, dio->iocb->ki_pos, 0, true); |
333 | kfree(dio); | 335 | kmem_cache_free(dio_cache, dio); |
334 | } | 336 | } |
335 | } | 337 | } |
336 | 338 | ||
@@ -1180,7 +1182,7 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, | |||
1180 | 1182 | ||
1181 | if (ret2 == 0) { | 1183 | if (ret2 == 0) { |
1182 | ret = dio_complete(dio, offset, ret, false); | 1184 | ret = dio_complete(dio, offset, ret, false); |
1183 | kfree(dio); | 1185 | kmem_cache_free(dio_cache, dio); |
1184 | } else | 1186 | } else |
1185 | BUG_ON(ret != -EIOCBQUEUED); | 1187 | BUG_ON(ret != -EIOCBQUEUED); |
1186 | 1188 | ||
@@ -1256,7 +1258,7 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, | |||
1256 | if (rw == READ && end == offset) | 1258 | if (rw == READ && end == offset) |
1257 | return 0; | 1259 | return 0; |
1258 | 1260 | ||
1259 | dio = kmalloc(sizeof(*dio), GFP_KERNEL); | 1261 | dio = kmem_cache_alloc(dio_cache, GFP_KERNEL); |
1260 | retval = -ENOMEM; | 1262 | retval = -ENOMEM; |
1261 | if (!dio) | 1263 | if (!dio) |
1262 | goto out; | 1264 | goto out; |
@@ -1280,7 +1282,7 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, | |||
1280 | end - 1); | 1282 | end - 1); |
1281 | if (retval) { | 1283 | if (retval) { |
1282 | mutex_unlock(&inode->i_mutex); | 1284 | mutex_unlock(&inode->i_mutex); |
1283 | kfree(dio); | 1285 | kmem_cache_free(dio_cache, dio); |
1284 | goto out; | 1286 | goto out; |
1285 | } | 1287 | } |
1286 | } | 1288 | } |
@@ -1308,3 +1310,10 @@ out: | |||
1308 | return retval; | 1310 | return retval; |
1309 | } | 1311 | } |
1310 | EXPORT_SYMBOL(__blockdev_direct_IO); | 1312 | EXPORT_SYMBOL(__blockdev_direct_IO); |
1313 | |||
1314 | static __init int dio_init(void) | ||
1315 | { | ||
1316 | dio_cache = KMEM_CACHE(dio, SLAB_PANIC); | ||
1317 | return 0; | ||
1318 | } | ||
1319 | module_init(dio_init) | ||