aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/dax.c37
-rw-r--r--fs/ext2/inode.c8
-rw-r--r--fs/ext2/xip.c14
-rw-r--r--fs/ext2/xip.h3
-rw-r--r--include/linux/fs.h1
5 files changed, 43 insertions, 20 deletions
diff --git a/fs/dax.c b/fs/dax.c
index 1a2bdbfa3ea9..69c3126a05b4 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -20,8 +20,45 @@
20#include <linux/fs.h> 20#include <linux/fs.h>
21#include <linux/genhd.h> 21#include <linux/genhd.h>
22#include <linux/mutex.h> 22#include <linux/mutex.h>
23#include <linux/sched.h>
23#include <linux/uio.h> 24#include <linux/uio.h>
24 25
26int dax_clear_blocks(struct inode *inode, sector_t block, long size)
27{
28 struct block_device *bdev = inode->i_sb->s_bdev;
29 sector_t sector = block << (inode->i_blkbits - 9);
30
31 might_sleep();
32 do {
33 void *addr;
34 unsigned long pfn;
35 long count;
36
37 count = bdev_direct_access(bdev, sector, &addr, &pfn, size);
38 if (count < 0)
39 return count;
40 BUG_ON(size < count);
41 while (count > 0) {
42 unsigned pgsz = PAGE_SIZE - offset_in_page(addr);
43 if (pgsz > count)
44 pgsz = count;
45 if (pgsz < PAGE_SIZE)
46 memset(addr, 0, pgsz);
47 else
48 clear_page(addr);
49 addr += pgsz;
50 size -= pgsz;
51 count -= pgsz;
52 BUG_ON(pgsz & 511);
53 sector += pgsz / 512;
54 cond_resched();
55 }
56 } while (size);
57
58 return 0;
59}
60EXPORT_SYMBOL_GPL(dax_clear_blocks);
61
25static long dax_get_addr(struct buffer_head *bh, void **addr, unsigned blkbits) 62static long dax_get_addr(struct buffer_head *bh, void **addr, unsigned blkbits)
26{ 63{
27 unsigned long pfn; 64 unsigned long pfn;
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 3ccd5fd47d66..52978b853226 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -733,10 +733,12 @@ static int ext2_get_blocks(struct inode *inode,
733 733
734 if (IS_DAX(inode)) { 734 if (IS_DAX(inode)) {
735 /* 735 /*
736 * we need to clear the block 736 * block must be initialised before we put it in the tree
737 * so that it's not found by another thread before it's
738 * initialised
737 */ 739 */
738 err = ext2_clear_xip_target (inode, 740 err = dax_clear_blocks(inode, le32_to_cpu(chain[depth-1].key),
739 le32_to_cpu(chain[depth-1].key)); 741 1 << inode->i_blkbits);
740 if (err) { 742 if (err) {
741 mutex_unlock(&ei->truncate_mutex); 743 mutex_unlock(&ei->truncate_mutex);
742 goto cleanup; 744 goto cleanup;
diff --git a/fs/ext2/xip.c b/fs/ext2/xip.c
index bbc5fec6ff7f..8cfca3a4cd58 100644
--- a/fs/ext2/xip.c
+++ b/fs/ext2/xip.c
@@ -42,20 +42,6 @@ __ext2_get_block(struct inode *inode, pgoff_t pgoff, int create,
42 return rc; 42 return rc;
43} 43}
44 44
45int
46ext2_clear_xip_target(struct inode *inode, sector_t block)
47{
48 void *kaddr;
49 unsigned long pfn;
50 long size;
51
52 size = __inode_direct_access(inode, block, &kaddr, &pfn, PAGE_SIZE);
53 if (size < 0)
54 return size;
55 clear_page(kaddr);
56 return 0;
57}
58
59void ext2_xip_verify_sb(struct super_block *sb) 45void ext2_xip_verify_sb(struct super_block *sb)
60{ 46{
61 struct ext2_sb_info *sbi = EXT2_SB(sb); 47 struct ext2_sb_info *sbi = EXT2_SB(sb);
diff --git a/fs/ext2/xip.h b/fs/ext2/xip.h
index 29be73781419..b2592f2f3c9d 100644
--- a/fs/ext2/xip.h
+++ b/fs/ext2/xip.h
@@ -7,8 +7,6 @@
7 7
8#ifdef CONFIG_EXT2_FS_XIP 8#ifdef CONFIG_EXT2_FS_XIP
9extern void ext2_xip_verify_sb (struct super_block *); 9extern void ext2_xip_verify_sb (struct super_block *);
10extern int ext2_clear_xip_target (struct inode *, sector_t);
11
12static inline int ext2_use_xip (struct super_block *sb) 10static inline int ext2_use_xip (struct super_block *sb)
13{ 11{
14 struct ext2_sb_info *sbi = EXT2_SB(sb); 12 struct ext2_sb_info *sbi = EXT2_SB(sb);
@@ -19,6 +17,5 @@ int ext2_get_xip_mem(struct address_space *, pgoff_t, int,
19#else 17#else
20#define ext2_xip_verify_sb(sb) do { } while (0) 18#define ext2_xip_verify_sb(sb) do { } while (0)
21#define ext2_use_xip(sb) 0 19#define ext2_use_xip(sb) 0
22#define ext2_clear_xip_target(inode, chain) 0
23#define ext2_get_xip_mem NULL 20#define ext2_get_xip_mem NULL
24#endif 21#endif
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 241c3c030fb5..8084934a5676 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2589,6 +2589,7 @@ extern int nonseekable_open(struct inode * inode, struct file * filp);
2589 2589
2590ssize_t dax_do_io(int rw, struct kiocb *, struct inode *, struct iov_iter *, 2590ssize_t dax_do_io(int rw, struct kiocb *, struct inode *, struct iov_iter *,
2591 loff_t, get_block_t, dio_iodone_t, int flags); 2591 loff_t, get_block_t, dio_iodone_t, int flags);
2592int dax_clear_blocks(struct inode *, sector_t block, long size);
2592 2593
2593#ifdef CONFIG_FS_XIP 2594#ifdef CONFIG_FS_XIP
2594extern int xip_file_mmap(struct file * file, struct vm_area_struct * vma); 2595extern int xip_file_mmap(struct file * file, struct vm_area_struct * vma);