Skip to content

Commit f80e166

Browse files
iridesakpm00
authored andcommitted
fsdax: invalidate pages when CoW
CoW changes the share state of a dax page, but the share count of the page isn't updated. The next time access this page, it should have been a newly accessed, but old association exists. So, we need to clear the share state when CoW happens, in both dax_iomap_rw() and dax_zero_iter(). Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Shiyang Ruan <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Cc: Alistair Popple <[email protected]> Cc: Dan Williams <[email protected]> Cc: Dave Chinner <[email protected]> Cc: Jason Gunthorpe <[email protected]> Cc: John Hubbard <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 1690042 commit f80e166

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

fs/dax.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,6 +1264,15 @@ static s64 dax_zero_iter(struct iomap_iter *iter, bool *did_zero)
12641264
if (srcmap->type == IOMAP_HOLE || srcmap->type == IOMAP_UNWRITTEN)
12651265
return length;
12661266

1267+
/*
1268+
* invalidate the pages whose sharing state is to be changed
1269+
* because of CoW.
1270+
*/
1271+
if (iomap->flags & IOMAP_F_SHARED)
1272+
invalidate_inode_pages2_range(iter->inode->i_mapping,
1273+
pos >> PAGE_SHIFT,
1274+
(pos + length - 1) >> PAGE_SHIFT);
1275+
12671276
do {
12681277
unsigned offset = offset_in_page(pos);
12691278
unsigned size = min_t(u64, PAGE_SIZE - offset, length);
@@ -1324,12 +1333,13 @@ static loff_t dax_iomap_iter(const struct iomap_iter *iomi,
13241333
struct iov_iter *iter)
13251334
{
13261335
const struct iomap *iomap = &iomi->iomap;
1327-
const struct iomap *srcmap = &iomi->srcmap;
1336+
const struct iomap *srcmap = iomap_iter_srcmap(iomi);
13281337
loff_t length = iomap_length(iomi);
13291338
loff_t pos = iomi->pos;
13301339
struct dax_device *dax_dev = iomap->dax_dev;
13311340
loff_t end = pos + length, done = 0;
13321341
bool write = iov_iter_rw(iter) == WRITE;
1342+
bool cow = write && iomap->flags & IOMAP_F_SHARED;
13331343
ssize_t ret = 0;
13341344
size_t xfer;
13351345
int id;
@@ -1356,7 +1366,7 @@ static loff_t dax_iomap_iter(const struct iomap_iter *iomi,
13561366
* into page tables. We have to tear down these mappings so that data
13571367
* written by write(2) is visible in mmap.
13581368
*/
1359-
if (iomap->flags & IOMAP_F_NEW) {
1369+
if (iomap->flags & IOMAP_F_NEW || cow) {
13601370
invalidate_inode_pages2_range(iomi->inode->i_mapping,
13611371
pos >> PAGE_SHIFT,
13621372
(end - 1) >> PAGE_SHIFT);
@@ -1390,8 +1400,7 @@ static loff_t dax_iomap_iter(const struct iomap_iter *iomi,
13901400
break;
13911401
}
13921402

1393-
if (write &&
1394-
srcmap->type != IOMAP_HOLE && srcmap->addr != iomap->addr) {
1403+
if (cow) {
13951404
ret = dax_iomap_cow_copy(pos, length, PAGE_SIZE, srcmap,
13961405
kaddr);
13971406
if (ret)

0 commit comments

Comments
 (0)