--- x/fs/ntfs3/file.c +++ y/fs/ntfs3/file.c @@ -1240,12 +1240,8 @@ int ntfs_fiemap(struct inode *inode, str if (err) return err; - ni_lock(ni); - err = ni_fiemap(ni, fieinfo, start, len); - ni_unlock(ni); - return err; } --- x/fs/ntfs3/frecord.c +++ y/fs/ntfs3/frecord.c @@ -1906,6 +1906,8 @@ int ni_fiemap(struct ntfs_inode *ni, str u32 flags; bool ok; + ni_lock(ni); + if (S_ISDIR(ni->vfs_inode.i_mode)) { run = &ni->dir.alloc_run; attr = ni_find_attr(ni, NULL, NULL, ATTR_ALLOC, I30_NAME, @@ -1917,6 +1919,7 @@ int ni_fiemap(struct ntfs_inode *ni, str NULL); if (!attr) { err = -EINVAL; + ni_unlock(ni); goto out; } if (is_attr_compressed(attr)) { @@ -1925,17 +1928,19 @@ int ni_fiemap(struct ntfs_inode *ni, str ntfs_inode_warn( &ni->vfs_inode, "fiemap is not supported for compressed file (cp -r)"); + ni_unlock(ni); goto out; } run_lock = &ni->file.run_lock; } if (!attr || !attr->non_res) { - err = fiemap_fill_next_extent( - fieinfo, 0, 0, - attr ? le32_to_cpu(attr->res.data_size) : 0, - FIEMAP_EXTENT_DATA_INLINE | FIEMAP_EXTENT_LAST | - FIEMAP_EXTENT_MERGED); + u64 sz = attr ? le32_to_cpu(attr->res.data_size) : 0; + ni_unlock(ni); + err = fiemap_fill_next_extent(fieinfo, 0, 0, sz, + FIEMAP_EXTENT_DATA_INLINE | + FIEMAP_EXTENT_LAST | + FIEMAP_EXTENT_MERGED); goto out; } @@ -1945,6 +1950,7 @@ int ni_fiemap(struct ntfs_inode *ni, str end = alloc_size; down_read(run_lock); + ni_unlock(ni); while (vbo < end) { if (idx == -1) { @@ -2027,8 +2033,10 @@ int ni_fiemap(struct ntfs_inode *ni, str if (vbo + dlen >= end) flags |= FIEMAP_EXTENT_LAST; + up_read(run_lock); err = fiemap_fill_next_extent(fieinfo, vbo, lbo, dlen, flags); + down_read(run_lock); if (err < 0) break; if (err == 1) { @@ -2048,7 +2056,9 @@ int ni_fiemap(struct ntfs_inode *ni, str if (vbo + bytes >= end) flags |= FIEMAP_EXTENT_LAST; + up_read(run_lock); err = fiemap_fill_next_extent(fieinfo, vbo, lbo, bytes, flags); + down_read(run_lock); if (err < 0) break; if (err == 1) {