aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ntfs/aops.c
diff options
context:
space:
mode:
authorAnton Altaparmakov <aia21@cantab.net>2005-01-12 08:08:26 -0500
committerAnton Altaparmakov <aia21@cantab.net>2005-05-05 05:39:08 -0400
commit07a4e2da7dd3c9345f84b2552872f9d38c257451 (patch)
tree8fbd4c3e11196752ae8ff7944ccb26b93cafbb1c /fs/ntfs/aops.c
parentf50f3ac51983025405a71b70b033cc6bcb0d1fc1 (diff)
NTFS: Use i_size_{read,write}() in fs/ntfs/{aops.c,mft.c} and protect
access to the i_size and other size fields using the size_lock. Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
Diffstat (limited to 'fs/ntfs/aops.c')
-rw-r--r--fs/ntfs/aops.c56
1 files changed, 41 insertions, 15 deletions
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
index 45d56e41ed98..a53212793809 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -66,19 +66,22 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
66 ni = NTFS_I(page->mapping->host); 66 ni = NTFS_I(page->mapping->host);
67 67
68 if (likely(uptodate)) { 68 if (likely(uptodate)) {
69 s64 file_ofs; 69 s64 file_ofs, initialized_size;
70 70
71 set_buffer_uptodate(bh); 71 set_buffer_uptodate(bh);
72 72
73 file_ofs = ((s64)page->index << PAGE_CACHE_SHIFT) + 73 file_ofs = ((s64)page->index << PAGE_CACHE_SHIFT) +
74 bh_offset(bh); 74 bh_offset(bh);
75 read_lock_irqsave(&ni->size_lock, flags);
76 initialized_size = ni->initialized_size;
77 read_unlock_irqrestore(&ni->size_lock, flags);
75 /* Check for the current buffer head overflowing. */ 78 /* Check for the current buffer head overflowing. */
76 if (file_ofs + bh->b_size > ni->initialized_size) { 79 if (file_ofs + bh->b_size > initialized_size) {
77 char *addr; 80 char *addr;
78 int ofs = 0; 81 int ofs = 0;
79 82
80 if (file_ofs < ni->initialized_size) 83 if (file_ofs < initialized_size)
81 ofs = ni->initialized_size - file_ofs; 84 ofs = initialized_size - file_ofs;
82 addr = kmap_atomic(page, KM_BIO_SRC_IRQ); 85 addr = kmap_atomic(page, KM_BIO_SRC_IRQ);
83 memset(addr + bh_offset(bh) + ofs, 0, bh->b_size - ofs); 86 memset(addr + bh_offset(bh) + ofs, 0, bh->b_size - ofs);
84 flush_dcache_page(page); 87 flush_dcache_page(page);
@@ -168,6 +171,7 @@ static int ntfs_read_block(struct page *page)
168 runlist_element *rl; 171 runlist_element *rl;
169 struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE]; 172 struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE];
170 sector_t iblock, lblock, zblock; 173 sector_t iblock, lblock, zblock;
174 unsigned long flags;
171 unsigned int blocksize, vcn_ofs; 175 unsigned int blocksize, vcn_ofs;
172 int i, nr; 176 int i, nr;
173 unsigned char blocksize_bits; 177 unsigned char blocksize_bits;
@@ -190,8 +194,10 @@ static int ntfs_read_block(struct page *page)
190 } 194 }
191 195
192 iblock = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits); 196 iblock = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits);
197 read_lock_irqsave(&ni->size_lock, flags);
193 lblock = (ni->allocated_size + blocksize - 1) >> blocksize_bits; 198 lblock = (ni->allocated_size + blocksize - 1) >> blocksize_bits;
194 zblock = (ni->initialized_size + blocksize - 1) >> blocksize_bits; 199 zblock = (ni->initialized_size + blocksize - 1) >> blocksize_bits;
200 read_unlock_irqrestore(&ni->size_lock, flags);
195 201
196 /* Loop through all the buffers in the page. */ 202 /* Loop through all the buffers in the page. */
197 rl = NULL; 203 rl = NULL;
@@ -463,12 +469,15 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
463{ 469{
464 VCN vcn; 470 VCN vcn;
465 LCN lcn; 471 LCN lcn;
472 s64 initialized_size;
473 loff_t i_size;
466 sector_t block, dblock, iblock; 474 sector_t block, dblock, iblock;
467 struct inode *vi; 475 struct inode *vi;
468 ntfs_inode *ni; 476 ntfs_inode *ni;
469 ntfs_volume *vol; 477 ntfs_volume *vol;
470 runlist_element *rl; 478 runlist_element *rl;
471 struct buffer_head *bh, *head; 479 struct buffer_head *bh, *head;
480 unsigned long flags;
472 unsigned int blocksize, vcn_ofs; 481 unsigned int blocksize, vcn_ofs;
473 int err; 482 int err;
474 BOOL need_end_writeback; 483 BOOL need_end_writeback;
@@ -510,11 +519,16 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
510 /* The first block in the page. */ 519 /* The first block in the page. */
511 block = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits); 520 block = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits);
512 521
522 read_lock_irqsave(&ni->size_lock, flags);
523 i_size = i_size_read(vi);
524 initialized_size = ni->initialized_size;
525 read_unlock_irqrestore(&ni->size_lock, flags);
526
513 /* The first out of bounds block for the data size. */ 527 /* The first out of bounds block for the data size. */
514 dblock = (vi->i_size + blocksize - 1) >> blocksize_bits; 528 dblock = (i_size + blocksize - 1) >> blocksize_bits;
515 529
516 /* The last (fully or partially) initialized block. */ 530 /* The last (fully or partially) initialized block. */
517 iblock = ni->initialized_size >> blocksize_bits; 531 iblock = initialized_size >> blocksize_bits;
518 532
519 /* 533 /*
520 * Be very careful. We have no exclusion from __set_page_dirty_buffers 534 * Be very careful. We have no exclusion from __set_page_dirty_buffers
@@ -559,7 +573,7 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
559 573
560 /* Make sure we have enough initialized size. */ 574 /* Make sure we have enough initialized size. */
561 if (unlikely((block >= iblock) && 575 if (unlikely((block >= iblock) &&
562 (ni->initialized_size < vi->i_size))) { 576 (initialized_size < i_size))) {
563 /* 577 /*
564 * If this page is fully outside initialized size, zero 578 * If this page is fully outside initialized size, zero
565 * out all pages between the current initialized size 579 * out all pages between the current initialized size
@@ -846,7 +860,7 @@ static int ntfs_write_mst_block(struct page *page,
846 (PAGE_CACHE_SHIFT - bh_size_bits); 860 (PAGE_CACHE_SHIFT - bh_size_bits);
847 861
848 /* The first out of bounds block for the data size. */ 862 /* The first out of bounds block for the data size. */
849 dblock = (vi->i_size + bh_size - 1) >> bh_size_bits; 863 dblock = (i_size_read(vi) + bh_size - 1) >> bh_size_bits;
850 864
851 rl = NULL; 865 rl = NULL;
852 err = err2 = nr_bhs = nr_recs = nr_locked_nis = 0; 866 err = err2 = nr_bhs = nr_recs = nr_locked_nis = 0;
@@ -1367,7 +1381,7 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
1367 */ 1381 */
1368 1382
1369 attr_len = le32_to_cpu(ctx->attr->data.resident.value_length); 1383 attr_len = le32_to_cpu(ctx->attr->data.resident.value_length);
1370 i_size = i_size_read(VFS_I(ni)); 1384 i_size = i_size_read(vi);
1371 kaddr = kmap_atomic(page, KM_USER0); 1385 kaddr = kmap_atomic(page, KM_USER0);
1372 if (unlikely(attr_len > i_size)) { 1386 if (unlikely(attr_len > i_size)) {
1373 /* Zero out of bounds area in the mft record. */ 1387 /* Zero out of bounds area in the mft record. */
@@ -1425,12 +1439,15 @@ static int ntfs_prepare_nonresident_write(struct page *page,
1425{ 1439{
1426 VCN vcn; 1440 VCN vcn;
1427 LCN lcn; 1441 LCN lcn;
1442 s64 initialized_size;
1443 loff_t i_size;
1428 sector_t block, ablock, iblock; 1444 sector_t block, ablock, iblock;
1429 struct inode *vi; 1445 struct inode *vi;
1430 ntfs_inode *ni; 1446 ntfs_inode *ni;
1431 ntfs_volume *vol; 1447 ntfs_volume *vol;
1432 runlist_element *rl; 1448 runlist_element *rl;
1433 struct buffer_head *bh, *head, *wait[2], **wait_bh = wait; 1449 struct buffer_head *bh, *head, *wait[2], **wait_bh = wait;
1450 unsigned long flags;
1434 unsigned int vcn_ofs, block_start, block_end, blocksize; 1451 unsigned int vcn_ofs, block_start, block_end, blocksize;
1435 int err; 1452 int err;
1436 BOOL is_retry; 1453 BOOL is_retry;
@@ -1462,6 +1479,7 @@ static int ntfs_prepare_nonresident_write(struct page *page,
1462 /* The first block in the page. */ 1479 /* The first block in the page. */
1463 block = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits); 1480 block = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits);
1464 1481
1482 read_lock_irqsave(&ni->size_lock, flags);
1465 /* 1483 /*
1466 * The first out of bounds block for the allocated size. No need to 1484 * The first out of bounds block for the allocated size. No need to
1467 * round up as allocated_size is in multiples of cluster size and the 1485 * round up as allocated_size is in multiples of cluster size and the
@@ -1470,8 +1488,12 @@ static int ntfs_prepare_nonresident_write(struct page *page,
1470 */ 1488 */
1471 ablock = ni->allocated_size >> blocksize_bits; 1489 ablock = ni->allocated_size >> blocksize_bits;
1472 1490
1491 i_size = i_size_read(vi);
1492 initialized_size = ni->initialized_size;
1493 read_unlock_irqrestore(&ni->size_lock, flags);
1494
1473 /* The last (fully or partially) initialized block. */ 1495 /* The last (fully or partially) initialized block. */
1474 iblock = ni->initialized_size >> blocksize_bits; 1496 iblock = initialized_size >> blocksize_bits;
1475 1497
1476 /* Loop through all the buffers in the page. */ 1498 /* Loop through all the buffers in the page. */
1477 block_start = 0; 1499 block_start = 0;
@@ -1518,7 +1540,7 @@ static int ntfs_prepare_nonresident_write(struct page *page,
1518 * request, i.e. block < ablock is true. 1540 * request, i.e. block < ablock is true.
1519 */ 1541 */
1520 if (unlikely((block >= iblock) && 1542 if (unlikely((block >= iblock) &&
1521 (ni->initialized_size < vi->i_size))) { 1543 (initialized_size < i_size))) {
1522 /* 1544 /*
1523 * If this page is fully outside initialized size, zero 1545 * If this page is fully outside initialized size, zero
1524 * out all pages between the current initialized size 1546 * out all pages between the current initialized size
@@ -1868,7 +1890,7 @@ static int ntfs_prepare_write(struct file *file, struct page *page,
1868 BUG_ON(page_has_buffers(page)); 1890 BUG_ON(page_has_buffers(page));
1869 new_size = ((s64)page->index << PAGE_CACHE_SHIFT) + to; 1891 new_size = ((s64)page->index << PAGE_CACHE_SHIFT) + to;
1870 /* If we do not need to resize the attribute allocation we are done. */ 1892 /* If we do not need to resize the attribute allocation we are done. */
1871 if (new_size <= vi->i_size) 1893 if (new_size <= i_size_read(vi))
1872 goto done; 1894 goto done;
1873 1895
1874 // FIXME: We abort for now as this code is not safe. 1896 // FIXME: We abort for now as this code is not safe.
@@ -1904,7 +1926,7 @@ static int ntfs_prepare_write(struct file *file, struct page *page,
1904 a = ctx->attr; 1926 a = ctx->attr;
1905 /* The total length of the attribute value. */ 1927 /* The total length of the attribute value. */
1906 attr_len = le32_to_cpu(a->data.resident.value_length); 1928 attr_len = le32_to_cpu(a->data.resident.value_length);
1907 BUG_ON(vi->i_size != attr_len); 1929 BUG_ON(i_size_read(vi) != attr_len);
1908 /* Check if new size is allowed in $AttrDef. */ 1930 /* Check if new size is allowed in $AttrDef. */
1909 err = ntfs_attr_size_bounds_check(vol, ni->type, new_size); 1931 err = ntfs_attr_size_bounds_check(vol, ni->type, new_size);
1910 if (unlikely(err)) { 1932 if (unlikely(err)) {
@@ -2047,7 +2069,7 @@ static int ntfs_commit_nonresident_write(struct page *page,
2047 * now we know ntfs_prepare_write() would have failed in the write 2069 * now we know ntfs_prepare_write() would have failed in the write
2048 * exceeds i_size case, so this will never trigger which is fine. 2070 * exceeds i_size case, so this will never trigger which is fine.
2049 */ 2071 */
2050 if (pos > vi->i_size) { 2072 if (pos > i_size_read(vi)) {
2051 ntfs_error(vi->i_sb, "Writing beyond the existing file size is " 2073 ntfs_error(vi->i_sb, "Writing beyond the existing file size is "
2052 "not supported yet. Sorry."); 2074 "not supported yet. Sorry.");
2053 return -EOPNOTSUPP; 2075 return -EOPNOTSUPP;
@@ -2183,9 +2205,13 @@ static int ntfs_commit_write(struct file *file, struct page *page,
2183 } 2205 }
2184 kunmap_atomic(kaddr, KM_USER0); 2206 kunmap_atomic(kaddr, KM_USER0);
2185 /* Update i_size if necessary. */ 2207 /* Update i_size if necessary. */
2186 if (vi->i_size < attr_len) { 2208 if (i_size_read(vi) < attr_len) {
2209 unsigned long flags;
2210
2211 write_lock_irqsave(&ni->size_lock, flags);
2187 ni->allocated_size = ni->initialized_size = attr_len; 2212 ni->allocated_size = ni->initialized_size = attr_len;
2188 i_size_write(vi, attr_len); 2213 i_size_write(vi, attr_len);
2214 write_unlock_irqrestore(&ni->size_lock, flags);
2189 } 2215 }
2190 /* Mark the mft record dirty, so it gets written back. */ 2216 /* Mark the mft record dirty, so it gets written back. */
2191 flush_dcache_mft_record_page(ctx->ntfs_ino); 2217 flush_dcache_mft_record_page(ctx->ntfs_ino);