Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 311120ec authored by Anton Altaparmakov's avatar Anton Altaparmakov
Browse files

NTFS: Fixup handling of sparse, compressed, and encrypted attributes in


      fs/ntfs/aops.c::ntfs_readpage().

Signed-off-by: default avatarAnton Altaparmakov <aia21@cantab.net>
parent 8273d5d4
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -76,11 +76,10 @@ ToDo/Notes:
	- Truncate {a,c,m}time to the ntfs supported time granularity when
	  updating the times in the inode in ntfs_setattr().
	- Fixup handling of sparse, compressed, and encrypted attributes in
	  fs/ntfs/inode.c::ntfs_read_locked_{,attr_,index_}inode().
	  fs/ntfs/inode.c::ntfs_read_locked_{,attr_,index_}inode(),
	  fs/ntfs/aops.c::ntfs_{read,write}page().
	- Make ntfs_write_block() not instantiate sparse blocks if they contain
	  only zeroes.
	- Fixup handling of sparse, compressed, and encrypted attributes in
	  fs/ntfs/aops.c::ntfs_writepage().
	- Optimize fs/ntfs/aops.c::ntfs_write_block() by extending the page
	  lock protection over the buffer submission for i/o which allows the
	  removal of the get_bh()/put_bh() pairs for each buffer.
+24 −17
Original line number Diff line number Diff line
@@ -379,31 +379,38 @@ retry_readpage:
		return 0;
	}
	ni = NTFS_I(page->mapping->host);

	/* NInoNonResident() == NInoIndexAllocPresent() */
	if (NInoNonResident(ni)) {
	/*
		 * Only unnamed $DATA attributes can be compressed or
		 * encrypted.
	 * Only $DATA attributes can be encrypted and only unnamed $DATA
	 * attributes can be compressed.  Index root can have the flags set but
	 * this means to create compressed/encrypted files, not that the
	 * attribute is compressed/encrypted.
	 */
		if (ni->type == AT_DATA && !ni->name_len) {
			/* If file is encrypted, deny access, just like NT4. */
	if (ni->type != AT_INDEX_ROOT) {
		/* If attribute is encrypted, deny access, just like NT4. */
		if (NInoEncrypted(ni)) {
			BUG_ON(ni->type != AT_DATA);
			err = -EACCES;
			goto err_out;
		}
		/* Compressed data streams are handled in compress.c. */
			if (NInoCompressed(ni))
		if (NInoNonResident(ni) && NInoCompressed(ni)) {
			BUG_ON(ni->type != AT_DATA);
			BUG_ON(ni->name_len);
			return ntfs_read_compressed_block(page);
		}
		/* Normal data stream. */
	}
	/* NInoNonResident() == NInoIndexAllocPresent() */
	if (NInoNonResident(ni)) {
		/* Normal, non-resident data stream. */
		return ntfs_read_block(page);
	}
	/*
	 * Attribute is resident, implying it is not compressed or encrypted.
	 * This also means the attribute is smaller than an mft record and
	 * hence smaller than a page, so can simply zero out any pages with
	 * index above 0.
	 * index above 0.  Note the attribute can actually be marked compressed
	 * but if it is resident the actual data is not compressed so we are
	 * ok to ignore the compressed flag here.
	 */
	if (unlikely(page->index > 0)) {
		kaddr = kmap_atomic(page, KM_USER0);