diff options
Diffstat (limited to 'mm/shmem.c')
-rw-r--r-- | mm/shmem.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/mm/shmem.c b/mm/shmem.c index 4ae47f54c822..c919ed578f0a 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -80,6 +80,7 @@ | |||
80 | enum sgp_type { | 80 | enum sgp_type { |
81 | SGP_READ, /* don't exceed i_size, don't allocate page */ | 81 | SGP_READ, /* don't exceed i_size, don't allocate page */ |
82 | SGP_CACHE, /* don't exceed i_size, may allocate page */ | 82 | SGP_CACHE, /* don't exceed i_size, may allocate page */ |
83 | SGP_DIRTY, /* like SGP_CACHE, but set new page dirty */ | ||
83 | SGP_WRITE, /* may exceed i_size, may allocate page */ | 84 | SGP_WRITE, /* may exceed i_size, may allocate page */ |
84 | }; | 85 | }; |
85 | 86 | ||
@@ -1333,6 +1334,8 @@ repeat: | |||
1333 | clear_highpage(filepage); | 1334 | clear_highpage(filepage); |
1334 | flush_dcache_page(filepage); | 1335 | flush_dcache_page(filepage); |
1335 | SetPageUptodate(filepage); | 1336 | SetPageUptodate(filepage); |
1337 | if (sgp == SGP_DIRTY) | ||
1338 | set_page_dirty(filepage); | ||
1336 | } | 1339 | } |
1337 | done: | 1340 | done: |
1338 | *pagep = filepage; | 1341 | *pagep = filepage; |
@@ -1518,6 +1521,15 @@ static void do_shmem_file_read(struct file *filp, loff_t *ppos, read_descriptor_ | |||
1518 | struct inode *inode = filp->f_path.dentry->d_inode; | 1521 | struct inode *inode = filp->f_path.dentry->d_inode; |
1519 | struct address_space *mapping = inode->i_mapping; | 1522 | struct address_space *mapping = inode->i_mapping; |
1520 | unsigned long index, offset; | 1523 | unsigned long index, offset; |
1524 | enum sgp_type sgp = SGP_READ; | ||
1525 | |||
1526 | /* | ||
1527 | * Might this read be for a stacking filesystem? Then when reading | ||
1528 | * holes of a sparse file, we actually need to allocate those pages, | ||
1529 | * and even mark them dirty, so it cannot exceed the max_blocks limit. | ||
1530 | */ | ||
1531 | if (segment_eq(get_fs(), KERNEL_DS)) | ||
1532 | sgp = SGP_DIRTY; | ||
1521 | 1533 | ||
1522 | index = *ppos >> PAGE_CACHE_SHIFT; | 1534 | index = *ppos >> PAGE_CACHE_SHIFT; |
1523 | offset = *ppos & ~PAGE_CACHE_MASK; | 1535 | offset = *ppos & ~PAGE_CACHE_MASK; |
@@ -1536,7 +1548,7 @@ static void do_shmem_file_read(struct file *filp, loff_t *ppos, read_descriptor_ | |||
1536 | break; | 1548 | break; |
1537 | } | 1549 | } |
1538 | 1550 | ||
1539 | desc->error = shmem_getpage(inode, index, &page, SGP_READ, NULL); | 1551 | desc->error = shmem_getpage(inode, index, &page, sgp, NULL); |
1540 | if (desc->error) { | 1552 | if (desc->error) { |
1541 | if (desc->error == -EINVAL) | 1553 | if (desc->error == -EINVAL) |
1542 | desc->error = 0; | 1554 | desc->error = 0; |