summaryrefslogtreecommitdiffstats
path: root/fs/ext2
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2018-04-09 13:50:17 -0400
committerDan Williams <dan.j.williams@intel.com>2018-04-09 13:50:17 -0400
commite13e75b86ef2f88e3a47d672dd4c52a293efb95b (patch)
tree2617aebd952d1aec09d323f6b2484b93f659e753 /fs/ext2
parent1ed41b5696ccc3ff40a1dee39fe14eff273faf82 (diff)
parent976431b02c2ef92ae3f8b6a7d699fc554025e118 (diff)
Merge branch 'for-4.17/dax' into libnvdimm-for-next
Diffstat (limited to 'fs/ext2')
-rw-r--r--fs/ext2/ext2.h1
-rw-r--r--fs/ext2/inode.c46
-rw-r--r--fs/ext2/namei.c18
3 files changed, 30 insertions, 35 deletions
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 032295e1d386..cc40802ddfa8 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -814,6 +814,7 @@ extern const struct inode_operations ext2_file_inode_operations;
814extern const struct file_operations ext2_file_operations; 814extern const struct file_operations ext2_file_operations;
815 815
816/* inode.c */ 816/* inode.c */
817extern void ext2_set_file_ops(struct inode *inode);
817extern const struct address_space_operations ext2_aops; 818extern const struct address_space_operations ext2_aops;
818extern const struct address_space_operations ext2_nobh_aops; 819extern const struct address_space_operations ext2_nobh_aops;
819extern const struct iomap_ops ext2_iomap_ops; 820extern const struct iomap_ops ext2_iomap_ops;
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 9b2ac55ac34f..1e01fabef130 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -940,9 +940,6 @@ ext2_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
940 loff_t offset = iocb->ki_pos; 940 loff_t offset = iocb->ki_pos;
941 ssize_t ret; 941 ssize_t ret;
942 942
943 if (WARN_ON_ONCE(IS_DAX(inode)))
944 return -EIO;
945
946 ret = blockdev_direct_IO(iocb, inode, iter, ext2_get_block); 943 ret = blockdev_direct_IO(iocb, inode, iter, ext2_get_block);
947 if (ret < 0 && iov_iter_rw(iter) == WRITE) 944 if (ret < 0 && iov_iter_rw(iter) == WRITE)
948 ext2_write_failed(mapping, offset + count); 945 ext2_write_failed(mapping, offset + count);
@@ -952,17 +949,16 @@ ext2_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
952static int 949static int
953ext2_writepages(struct address_space *mapping, struct writeback_control *wbc) 950ext2_writepages(struct address_space *mapping, struct writeback_control *wbc)
954{ 951{
955#ifdef CONFIG_FS_DAX
956 if (dax_mapping(mapping)) {
957 return dax_writeback_mapping_range(mapping,
958 mapping->host->i_sb->s_bdev,
959 wbc);
960 }
961#endif
962
963 return mpage_writepages(mapping, wbc, ext2_get_block); 952 return mpage_writepages(mapping, wbc, ext2_get_block);
964} 953}
965 954
955static int
956ext2_dax_writepages(struct address_space *mapping, struct writeback_control *wbc)
957{
958 return dax_writeback_mapping_range(mapping,
959 mapping->host->i_sb->s_bdev, wbc);
960}
961
966const struct address_space_operations ext2_aops = { 962const struct address_space_operations ext2_aops = {
967 .readpage = ext2_readpage, 963 .readpage = ext2_readpage,
968 .readpages = ext2_readpages, 964 .readpages = ext2_readpages,
@@ -990,6 +986,13 @@ const struct address_space_operations ext2_nobh_aops = {
990 .error_remove_page = generic_error_remove_page, 986 .error_remove_page = generic_error_remove_page,
991}; 987};
992 988
989static const struct address_space_operations ext2_dax_aops = {
990 .writepages = ext2_dax_writepages,
991 .direct_IO = noop_direct_IO,
992 .set_page_dirty = noop_set_page_dirty,
993 .invalidatepage = noop_invalidatepage,
994};
995
993/* 996/*
994 * Probably it should be a library function... search for first non-zero word 997 * Probably it should be a library function... search for first non-zero word
995 * or memcmp with zero_page, whatever is better for particular architecture. 998 * or memcmp with zero_page, whatever is better for particular architecture.
@@ -1388,6 +1391,18 @@ void ext2_set_inode_flags(struct inode *inode)
1388 inode->i_flags |= S_DAX; 1391 inode->i_flags |= S_DAX;
1389} 1392}
1390 1393
1394void ext2_set_file_ops(struct inode *inode)
1395{
1396 inode->i_op = &ext2_file_inode_operations;
1397 inode->i_fop = &ext2_file_operations;
1398 if (IS_DAX(inode))
1399 inode->i_mapping->a_ops = &ext2_dax_aops;
1400 else if (test_opt(inode->i_sb, NOBH))
1401 inode->i_mapping->a_ops = &ext2_nobh_aops;
1402 else
1403 inode->i_mapping->a_ops = &ext2_aops;
1404}
1405
1391struct inode *ext2_iget (struct super_block *sb, unsigned long ino) 1406struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
1392{ 1407{
1393 struct ext2_inode_info *ei; 1408 struct ext2_inode_info *ei;
@@ -1480,14 +1495,7 @@ struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
1480 ei->i_data[n] = raw_inode->i_block[n]; 1495 ei->i_data[n] = raw_inode->i_block[n];
1481 1496
1482 if (S_ISREG(inode->i_mode)) { 1497 if (S_ISREG(inode->i_mode)) {
1483 inode->i_op = &ext2_file_inode_operations; 1498 ext2_set_file_ops(inode);
1484 if (test_opt(inode->i_sb, NOBH)) {
1485 inode->i_mapping->a_ops = &ext2_nobh_aops;
1486 inode->i_fop = &ext2_file_operations;
1487 } else {
1488 inode->i_mapping->a_ops = &ext2_aops;
1489 inode->i_fop = &ext2_file_operations;
1490 }
1491 } else if (S_ISDIR(inode->i_mode)) { 1499 } else if (S_ISDIR(inode->i_mode)) {
1492 inode->i_op = &ext2_dir_inode_operations; 1500 inode->i_op = &ext2_dir_inode_operations;
1493 inode->i_fop = &ext2_dir_operations; 1501 inode->i_fop = &ext2_dir_operations;
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index e078075dc66f..55f7caadb093 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -107,14 +107,7 @@ static int ext2_create (struct inode * dir, struct dentry * dentry, umode_t mode
107 if (IS_ERR(inode)) 107 if (IS_ERR(inode))
108 return PTR_ERR(inode); 108 return PTR_ERR(inode);
109 109
110 inode->i_op = &ext2_file_inode_operations; 110 ext2_set_file_ops(inode);
111 if (test_opt(inode->i_sb, NOBH)) {
112 inode->i_mapping->a_ops = &ext2_nobh_aops;
113 inode->i_fop = &ext2_file_operations;
114 } else {
115 inode->i_mapping->a_ops = &ext2_aops;
116 inode->i_fop = &ext2_file_operations;
117 }
118 mark_inode_dirty(inode); 111 mark_inode_dirty(inode);
119 return ext2_add_nondir(dentry, inode); 112 return ext2_add_nondir(dentry, inode);
120} 113}
@@ -125,14 +118,7 @@ static int ext2_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
125 if (IS_ERR(inode)) 118 if (IS_ERR(inode))
126 return PTR_ERR(inode); 119 return PTR_ERR(inode);
127 120
128 inode->i_op = &ext2_file_inode_operations; 121 ext2_set_file_ops(inode);
129 if (test_opt(inode->i_sb, NOBH)) {
130 inode->i_mapping->a_ops = &ext2_nobh_aops;
131 inode->i_fop = &ext2_file_operations;
132 } else {
133 inode->i_mapping->a_ops = &ext2_aops;
134 inode->i_fop = &ext2_file_operations;
135 }
136 mark_inode_dirty(inode); 122 mark_inode_dirty(inode);
137 d_tmpfile(dentry, inode); 123 d_tmpfile(dentry, inode);
138 unlock_new_inode(inode); 124 unlock_new_inode(inode);