diff options
Diffstat (limited to 'fs/ntfs/attrib.c')
| -rw-r--r-- | fs/ntfs/attrib.c | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index 3b9de4040216..41859343a0c8 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c | |||
| @@ -1376,19 +1376,6 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni) | |||
| 1376 | err = ntfs_attr_record_resize(m, a, arec_size); | 1376 | err = ntfs_attr_record_resize(m, a, arec_size); |
| 1377 | if (unlikely(err)) | 1377 | if (unlikely(err)) |
| 1378 | goto err_out; | 1378 | goto err_out; |
| 1379 | /* Setup the in-memory attribute structure to be non-resident. */ | ||
| 1380 | NInoSetNonResident(ni); | ||
| 1381 | ni->runlist.rl = rl; | ||
| 1382 | write_lock_irqsave(&ni->size_lock, flags); | ||
| 1383 | ni->allocated_size = new_size; | ||
| 1384 | write_unlock_irqrestore(&ni->size_lock, flags); | ||
| 1385 | /* | ||
| 1386 | * FIXME: For now just clear all of these as we do not support them | ||
| 1387 | * when writing. | ||
| 1388 | */ | ||
| 1389 | NInoClearCompressed(ni); | ||
| 1390 | NInoClearSparse(ni); | ||
| 1391 | NInoClearEncrypted(ni); | ||
| 1392 | /* | 1379 | /* |
| 1393 | * Convert the resident part of the attribute record to describe a | 1380 | * Convert the resident part of the attribute record to describe a |
| 1394 | * non-resident attribute. | 1381 | * non-resident attribute. |
| @@ -1399,7 +1386,10 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni) | |||
| 1399 | memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset), | 1386 | memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset), |
| 1400 | a->name_length * sizeof(ntfschar)); | 1387 | a->name_length * sizeof(ntfschar)); |
| 1401 | a->name_offset = cpu_to_le16(name_ofs); | 1388 | a->name_offset = cpu_to_le16(name_ofs); |
| 1402 | /* Update the flags to match the in-memory ones. */ | 1389 | /* |
| 1390 | * FIXME: For now just clear all of these as we do not support them | ||
| 1391 | * when writing. | ||
| 1392 | */ | ||
| 1403 | a->flags &= cpu_to_le16(0xffff & ~le16_to_cpu(ATTR_IS_SPARSE | | 1393 | a->flags &= cpu_to_le16(0xffff & ~le16_to_cpu(ATTR_IS_SPARSE | |
| 1404 | ATTR_IS_ENCRYPTED | ATTR_COMPRESSION_MASK)); | 1394 | ATTR_IS_ENCRYPTED | ATTR_COMPRESSION_MASK)); |
| 1405 | /* Setup the fields specific to non-resident attributes. */ | 1395 | /* Setup the fields specific to non-resident attributes. */ |
| @@ -1422,6 +1412,25 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni) | |||
| 1422 | err); | 1412 | err); |
| 1423 | goto undo_err_out; | 1413 | goto undo_err_out; |
| 1424 | } | 1414 | } |
| 1415 | /* Setup the in-memory attribute structure to be non-resident. */ | ||
| 1416 | /* | ||
| 1417 | * FIXME: For now just clear all of these as we do not support them | ||
| 1418 | * when writing. | ||
| 1419 | */ | ||
| 1420 | NInoClearSparse(ni); | ||
| 1421 | NInoClearEncrypted(ni); | ||
| 1422 | NInoClearCompressed(ni); | ||
| 1423 | ni->runlist.rl = rl; | ||
| 1424 | write_lock_irqsave(&ni->size_lock, flags); | ||
| 1425 | ni->allocated_size = new_size; | ||
| 1426 | write_unlock_irqrestore(&ni->size_lock, flags); | ||
| 1427 | /* | ||
| 1428 | * This needs to be last since the address space operations ->readpage | ||
| 1429 | * and ->writepage can run concurrently with us as they are not | ||
| 1430 | * serialized on i_sem. Note, we are not allowed to fail once we flip | ||
| 1431 | * this switch, which is another reason to do this last. | ||
| 1432 | */ | ||
| 1433 | NInoSetNonResident(ni); | ||
| 1425 | /* Mark the mft record dirty, so it gets written back. */ | 1434 | /* Mark the mft record dirty, so it gets written back. */ |
| 1426 | flush_dcache_mft_record_page(ctx->ntfs_ino); | 1435 | flush_dcache_mft_record_page(ctx->ntfs_ino); |
| 1427 | mark_mft_record_dirty(ctx->ntfs_ino); | 1436 | mark_mft_record_dirty(ctx->ntfs_ino); |
| @@ -1431,6 +1440,7 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni) | |||
| 1431 | if (page) { | 1440 | if (page) { |
| 1432 | set_page_dirty(page); | 1441 | set_page_dirty(page); |
| 1433 | unlock_page(page); | 1442 | unlock_page(page); |
| 1443 | mark_page_accessed(page); | ||
| 1434 | page_cache_release(page); | 1444 | page_cache_release(page); |
| 1435 | } | 1445 | } |
| 1436 | ntfs_debug("Done."); | 1446 | ntfs_debug("Done."); |
| @@ -1492,11 +1502,10 @@ undo_err_out: | |||
| 1492 | memcpy((u8*)a + mp_ofs, kaddr, attr_size); | 1502 | memcpy((u8*)a + mp_ofs, kaddr, attr_size); |
| 1493 | kunmap_atomic(kaddr, KM_USER0); | 1503 | kunmap_atomic(kaddr, KM_USER0); |
| 1494 | } | 1504 | } |
| 1495 | /* Finally setup the ntfs inode appropriately. */ | 1505 | /* Setup the allocated size in the ntfs inode in case it changed. */ |
| 1496 | write_lock_irqsave(&ni->size_lock, flags); | 1506 | write_lock_irqsave(&ni->size_lock, flags); |
| 1497 | ni->allocated_size = arec_size - mp_ofs; | 1507 | ni->allocated_size = arec_size - mp_ofs; |
| 1498 | write_unlock_irqrestore(&ni->size_lock, flags); | 1508 | write_unlock_irqrestore(&ni->size_lock, flags); |
| 1499 | NInoClearNonResident(ni); | ||
| 1500 | /* Mark the mft record dirty, so it gets written back. */ | 1509 | /* Mark the mft record dirty, so it gets written back. */ |
| 1501 | flush_dcache_mft_record_page(ctx->ntfs_ino); | 1510 | flush_dcache_mft_record_page(ctx->ntfs_ino); |
| 1502 | mark_mft_record_dirty(ctx->ntfs_ino); | 1511 | mark_mft_record_dirty(ctx->ntfs_ino); |
