CLST lcn, clen;
frame = valid >> frame_bits;
- frame_vbo = valid & ~(frame_size - 1);
+ frame_vbo = valid & ~(u64)(frame_size - 1);
off = valid & (frame_size - 1);
err = attr_data_get_block(ni, frame << NTFS_LZNT_CUNIT, 1, &lcn,
if (bytes > count)
bytes = count;
- frame_vbo = pos & ~(frame_size - 1);
+ frame_vbo = pos & ~(u64)(frame_size - 1);
index = frame_vbo >> PAGE_SHIFT;
if (unlikely(fault_in_iov_iter_readable(from, bytes))) {
loff_t maxbytes = ntfs_get_maxbytes(ni);
loff_t ret;
- if (whence == SEEK_DATA || whence == SEEK_HOLE) {
+ if (whence != SEEK_DATA && whence != SEEK_HOLE) {
+ ret = generic_file_llseek_size(file, offset, whence, maxbytes,
+ i_size_read(inode));
+ } else if ((unsigned long long)offset >= i_size_read(inode)) {
+ ret = -ENXIO;
+ } else {
inode_lock_shared(inode);
/* Scan file for hole or data. */
ret = ni_seek_data_or_hole(ni, offset, whence == SEEK_DATA);
if (ret >= 0)
ret = vfs_setpos(file, ret, maxbytes);
- } else {
- ret = generic_file_llseek_size(file, offset, whence, maxbytes,
- i_size_read(inode));
}
return ret;
}
* the file offset is set to offset.
*/
if (lcn != SPARSE_LCN) {
- vbo = (u64)vcn << cluster_bits;
- return max(vbo, offset);
+ /* Normal cluster. */
+ break;
+ }
+
+ if ((ni->std_fa & FILE_ATTRIBUTE_COMPRESSED) &&
+ (vcn & (NTFS_LZNT_CLUSTERS - 1))) {
+ /* Compressed cluster in compressed frame. */
+ break;
}
} else {
/*
/* native compression hole begins at aligned vcn. */
(!(ni->std_fa & FILE_ATTRIBUTE_COMPRESSED) ||
!(vcn & (NTFS_LZNT_CLUSTERS - 1)))) {
- vbo = (u64)vcn << cluster_bits;
- return max(vbo, offset);
+ /* Hole in sparsed or compressed file frame. */
+ break;
}
}
return -EINVAL;
}
}
+
+ vbo = (u64)vcn << cluster_bits;
+ return max(vbo, offset);
}
/*