summaryrefslogtreecommitdiffstats
path: root/fs/ext2
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-04-10 13:25:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-10 13:25:57 -0400
commit9f3a0941fb5efaa4d27911e251dc595034d58baa (patch)
tree7212d9872b41b73a0b3c4f8c991039b639add212 /fs/ext2
parentfbe173e3ffbd897b5a859020d714c0eaf4af2a1a (diff)
parente13e75b86ef2f88e3a47d672dd4c52a293efb95b (diff)
Merge tag 'libnvdimm-for-4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm
Pull libnvdimm updates from Dan Williams: "This cycle was was not something I ever want to repeat as there were several late changes that have only now just settled. Half of the branch up to commit d2c997c0f145 ("fs, dax: use page->mapping to warn...") have been in -next for several releases. The of_pmem driver and the address range scrub rework were late arrivals, and the dax work was scaled back at the last moment. The of_pmem driver missed a previous merge window due to an oversight. A sense of obligation to rectify that miss is why it is included for 4.17. It has acks from PowerPC folks. Stephen reported a build failure that only occurs when merging it with your latest tree, for now I have fixed that up by disabling modular builds of of_pmem. A test merge with your tree has received a build success report from the 0day robot over 156 configs. An initial version of the ARS rework was submitted before the merge window. It is self contained to libnvdimm, a net code reduction, and passing all unit tests. The filesystem-dax changes are based on the wait_var_event() functionality from tip/sched/core. However, late review feedback showed that those changes regressed truncate performance to a large degree. The branch was rewound to drop the truncate behavior change and now only includes preparation patches and cleanups (with full acks and reviews). The finalization of this dax-dma-vs-trnucate work will need to wait for 4.18. Summary: - A rework of the filesytem-dax implementation provides for detection of unmap operations (truncate / hole punch) colliding with in-progress device-DMA. A fix for these collisions remains a work-in-progress pending resolution of truncate latency and starvation regressions. - The of_pmem driver expands the users of libnvdimm outside of x86 and ACPI to describe an implementation of persistent memory on PowerPC with Open Firmware / Device tree. - Address Range Scrub (ARS) handling is completely rewritten to account for the fact that ARS may run for 100s of seconds and there is no platform defined way to cancel it. ARS will now no longer block namespace initialization. - The NVDIMM Namespace Label implementation is updated to handle label areas as small as 1K, down from 128K. - Miscellaneous cleanups and updates to unit test infrastructure" * tag 'libnvdimm-for-4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm: (39 commits) libnvdimm, of_pmem: workaround OF_NUMA=n build error nfit, address-range-scrub: add module option to skip initial ars nfit, address-range-scrub: rework and simplify ARS state machine nfit, address-range-scrub: determine one platform max_ars value powerpc/powernv: Create platform devs for nvdimm buses doc/devicetree: Persistent memory region bindings libnvdimm: Add device-tree based driver libnvdimm: Add of_node to region and bus descriptors libnvdimm, region: quiet region probe libnvdimm, namespace: use a safe lookup for dimm device name libnvdimm, dimm: fix dpa reservation vs uninitialized label area libnvdimm, testing: update the default smart ctrl_temperature libnvdimm, testing: Add emulation for smart injection commands nfit, address-range-scrub: introduce nfit_spa->ars_state libnvdimm: add an api to cast a 'struct nd_region' to its 'struct device' nfit, address-range-scrub: fix scrub in-progress reporting dax, dm: allow device-mapper to operate without dax support dax: introduce CONFIG_DAX_DRIVER fs, dax: use page->mapping to warn if truncate collides with a busy page ext2, dax: introduce ext2_dax_aops ...
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);