@@ -1898,6 +1898,47 @@ enum REPARSE_SIGN ni_parse_reparse(struct ntfs_inode *ni, struct ATTRIB *attr,
1898
1898
return REPARSE_LINK ;
1899
1899
}
1900
1900
1901
+ /*
1902
+ * fiemap_fill_next_extent_k - a copy of fiemap_fill_next_extent
1903
+ * but it accepts kernel address for fi_extents_start
1904
+ */
1905
+ static int fiemap_fill_next_extent_k (struct fiemap_extent_info * fieinfo ,
1906
+ u64 logical , u64 phys , u64 len , u32 flags )
1907
+ {
1908
+ struct fiemap_extent extent ;
1909
+ struct fiemap_extent __user * dest = fieinfo -> fi_extents_start ;
1910
+
1911
+ /* only count the extents */
1912
+ if (fieinfo -> fi_extents_max == 0 ) {
1913
+ fieinfo -> fi_extents_mapped ++ ;
1914
+ return (flags & FIEMAP_EXTENT_LAST ) ? 1 : 0 ;
1915
+ }
1916
+
1917
+ if (fieinfo -> fi_extents_mapped >= fieinfo -> fi_extents_max )
1918
+ return 1 ;
1919
+
1920
+ if (flags & FIEMAP_EXTENT_DELALLOC )
1921
+ flags |= FIEMAP_EXTENT_UNKNOWN ;
1922
+ if (flags & FIEMAP_EXTENT_DATA_ENCRYPTED )
1923
+ flags |= FIEMAP_EXTENT_ENCODED ;
1924
+ if (flags & (FIEMAP_EXTENT_DATA_TAIL | FIEMAP_EXTENT_DATA_INLINE ))
1925
+ flags |= FIEMAP_EXTENT_NOT_ALIGNED ;
1926
+
1927
+ memset (& extent , 0 , sizeof (extent ));
1928
+ extent .fe_logical = logical ;
1929
+ extent .fe_physical = phys ;
1930
+ extent .fe_length = len ;
1931
+ extent .fe_flags = flags ;
1932
+
1933
+ dest += fieinfo -> fi_extents_mapped ;
1934
+ memcpy (dest , & extent , sizeof (extent ));
1935
+
1936
+ fieinfo -> fi_extents_mapped ++ ;
1937
+ if (fieinfo -> fi_extents_mapped == fieinfo -> fi_extents_max )
1938
+ return 1 ;
1939
+ return (flags & FIEMAP_EXTENT_LAST ) ? 1 : 0 ;
1940
+ }
1941
+
1901
1942
/*
1902
1943
* ni_fiemap - Helper for file_fiemap().
1903
1944
*
@@ -1908,6 +1949,8 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
1908
1949
__u64 vbo , __u64 len )
1909
1950
{
1910
1951
int err = 0 ;
1952
+ struct fiemap_extent __user * fe_u = fieinfo -> fi_extents_start ;
1953
+ struct fiemap_extent * fe_k = NULL ;
1911
1954
struct ntfs_sb_info * sbi = ni -> mi .sbi ;
1912
1955
u8 cluster_bits = sbi -> cluster_bits ;
1913
1956
struct runs_tree * run ;
@@ -1955,6 +1998,18 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
1955
1998
goto out ;
1956
1999
}
1957
2000
2001
+ /*
2002
+ * To avoid lock problems replace pointer to user memory by pointer to kernel memory.
2003
+ */
2004
+ fe_k = kmalloc_array (fieinfo -> fi_extents_max ,
2005
+ sizeof (struct fiemap_extent ),
2006
+ GFP_NOFS | __GFP_ZERO );
2007
+ if (!fe_k ) {
2008
+ err = - ENOMEM ;
2009
+ goto out ;
2010
+ }
2011
+ fieinfo -> fi_extents_start = fe_k ;
2012
+
1958
2013
end = vbo + len ;
1959
2014
alloc_size = le64_to_cpu (attr -> nres .alloc_size );
1960
2015
if (end > alloc_size )
@@ -2043,8 +2098,9 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
2043
2098
if (vbo + dlen >= end )
2044
2099
flags |= FIEMAP_EXTENT_LAST ;
2045
2100
2046
- err = fiemap_fill_next_extent (fieinfo , vbo , lbo , dlen ,
2047
- flags );
2101
+ err = fiemap_fill_next_extent_k (fieinfo , vbo , lbo , dlen ,
2102
+ flags );
2103
+
2048
2104
if (err < 0 )
2049
2105
break ;
2050
2106
if (err == 1 ) {
@@ -2064,7 +2120,8 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
2064
2120
if (vbo + bytes >= end )
2065
2121
flags |= FIEMAP_EXTENT_LAST ;
2066
2122
2067
- err = fiemap_fill_next_extent (fieinfo , vbo , lbo , bytes , flags );
2123
+ err = fiemap_fill_next_extent_k (fieinfo , vbo , lbo , bytes ,
2124
+ flags );
2068
2125
if (err < 0 )
2069
2126
break ;
2070
2127
if (err == 1 ) {
@@ -2077,7 +2134,19 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
2077
2134
2078
2135
up_read (run_lock );
2079
2136
2137
+ /*
2138
+ * Copy to user memory out of lock
2139
+ */
2140
+ if (copy_to_user (fe_u , fe_k ,
2141
+ fieinfo -> fi_extents_max *
2142
+ sizeof (struct fiemap_extent ))) {
2143
+ err = - EFAULT ;
2144
+ }
2145
+
2080
2146
out :
2147
+ /* Restore original pointer. */
2148
+ fieinfo -> fi_extents_start = fe_u ;
2149
+ kfree (fe_k );
2081
2150
return err ;
2082
2151
}
2083
2152
0 commit comments