aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAnton Altaparmakov <aia21@cantab.net>2004-11-18 15:34:59 -0500
committerAnton Altaparmakov <aia21@cantab.net>2005-05-05 05:34:45 -0400
commit218357ff1b1b2f1bfdce89d608dbe33dd2f9f14b (patch)
treeb7621daec3c516507fed85a25e9e82198589f216 /fs
parent206f9f35b2348b7b966ff18a5564b8a3ca325ed5 (diff)
NTFS: - Use i_size_read() in fs/ntfs/super.c once and then use the cached
value afterwards. Cache the initialized_size in the same way and protect access to the two sizes using the size_lock. - Minor optimization to fs/ntfs/super.c::ntfs_statfs() and its helpers. Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
Diffstat (limited to 'fs')
-rw-r--r--fs/ntfs/ChangeLog4
-rw-r--r--fs/ntfs/super.c102
2 files changed, 58 insertions, 48 deletions
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
index 7bbbb9152fee..f4e087a83e78 100644
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -43,6 +43,10 @@ ToDo/Notes:
43 same way and protect access to the two sizes using the size_lock. 43 same way and protect access to the two sizes using the size_lock.
44 - Use i_size_read() in fs/ntfs/dir.c once and then use the cached 44 - Use i_size_read() in fs/ntfs/dir.c once and then use the cached
45 value afterwards. 45 value afterwards.
46 - Use i_size_read() in fs/ntfs/super.c once and then use the cached
47 value afterwards. Cache the initialized_size in the same way and
48 protect access to the two sizes using the size_lock.
49 - Minor optimization to fs/ntfs/super.c::ntfs_statfs() and its helpers.
46 50
472.1.22 - Many bug and race fixes and error handling improvements. 512.1.22 - Many bug and race fixes and error handling improvements.
48 52
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 212a3d0f2073..0ad0c51e9eb9 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -990,12 +990,12 @@ static BOOL load_and_init_mft_mirror(ntfs_volume *vol)
990 */ 990 */
991static BOOL check_mft_mirror(ntfs_volume *vol) 991static BOOL check_mft_mirror(ntfs_volume *vol)
992{ 992{
993 unsigned long index;
994 struct super_block *sb = vol->sb; 993 struct super_block *sb = vol->sb;
995 ntfs_inode *mirr_ni; 994 ntfs_inode *mirr_ni;
996 struct page *mft_page, *mirr_page; 995 struct page *mft_page, *mirr_page;
997 u8 *kmft, *kmirr; 996 u8 *kmft, *kmirr;
998 runlist_element *rl, rl2[2]; 997 runlist_element *rl, rl2[2];
998 pgoff_t index;
999 int mrecs_per_page, i; 999 int mrecs_per_page, i;
1000 1000
1001 ntfs_debug("Entering."); 1001 ntfs_debug("Entering.");
@@ -1205,10 +1205,11 @@ static BOOL load_and_init_quota(ntfs_volume *vol)
1205 */ 1205 */
1206static BOOL load_and_init_attrdef(ntfs_volume *vol) 1206static BOOL load_and_init_attrdef(ntfs_volume *vol)
1207{ 1207{
1208 loff_t i_size;
1208 struct super_block *sb = vol->sb; 1209 struct super_block *sb = vol->sb;
1209 struct inode *ino; 1210 struct inode *ino;
1210 struct page *page; 1211 struct page *page;
1211 unsigned long index, max_index; 1212 pgoff_t index, max_index;
1212 unsigned int size; 1213 unsigned int size;
1213 1214
1214 ntfs_debug("Entering."); 1215 ntfs_debug("Entering.");
@@ -1220,13 +1221,14 @@ static BOOL load_and_init_attrdef(ntfs_volume *vol)
1220 goto failed; 1221 goto failed;
1221 } 1222 }
1222 /* The size of FILE_AttrDef must be above 0 and fit inside 31 bits. */ 1223 /* The size of FILE_AttrDef must be above 0 and fit inside 31 bits. */
1223 if (!ino->i_size || ino->i_size > 0x7fffffff) 1224 i_size = i_size_read(ino);
1225 if (i_size <= 0 || i_size > 0x7fffffff)
1224 goto iput_failed; 1226 goto iput_failed;
1225 vol->attrdef = (ATTR_DEF*)ntfs_malloc_nofs(ino->i_size); 1227 vol->attrdef = (ATTR_DEF*)ntfs_malloc_nofs(i_size);
1226 if (!vol->attrdef) 1228 if (!vol->attrdef)
1227 goto iput_failed; 1229 goto iput_failed;
1228 index = 0; 1230 index = 0;
1229 max_index = ino->i_size >> PAGE_CACHE_SHIFT; 1231 max_index = i_size >> PAGE_CACHE_SHIFT;
1230 size = PAGE_CACHE_SIZE; 1232 size = PAGE_CACHE_SIZE;
1231 while (index < max_index) { 1233 while (index < max_index) {
1232 /* Read the attrdef table and copy it into the linear buffer. */ 1234 /* Read the attrdef table and copy it into the linear buffer. */
@@ -1239,12 +1241,12 @@ read_partial_attrdef_page:
1239 ntfs_unmap_page(page); 1241 ntfs_unmap_page(page);
1240 }; 1242 };
1241 if (size == PAGE_CACHE_SIZE) { 1243 if (size == PAGE_CACHE_SIZE) {
1242 size = ino->i_size & ~PAGE_CACHE_MASK; 1244 size = i_size & ~PAGE_CACHE_MASK;
1243 if (size) 1245 if (size)
1244 goto read_partial_attrdef_page; 1246 goto read_partial_attrdef_page;
1245 } 1247 }
1246 vol->attrdef_size = ino->i_size; 1248 vol->attrdef_size = i_size;
1247 ntfs_debug("Read %llu bytes from $AttrDef.", ino->i_size); 1249 ntfs_debug("Read %llu bytes from $AttrDef.", i_size);
1248 iput(ino); 1250 iput(ino);
1249 return TRUE; 1251 return TRUE;
1250free_iput_failed: 1252free_iput_failed:
@@ -1267,10 +1269,11 @@ failed:
1267 */ 1269 */
1268static BOOL load_and_init_upcase(ntfs_volume *vol) 1270static BOOL load_and_init_upcase(ntfs_volume *vol)
1269{ 1271{
1272 loff_t i_size;
1270 struct super_block *sb = vol->sb; 1273 struct super_block *sb = vol->sb;
1271 struct inode *ino; 1274 struct inode *ino;
1272 struct page *page; 1275 struct page *page;
1273 unsigned long index, max_index; 1276 pgoff_t index, max_index;
1274 unsigned int size; 1277 unsigned int size;
1275 int i, max; 1278 int i, max;
1276 1279
@@ -1286,14 +1289,15 @@ static BOOL load_and_init_upcase(ntfs_volume *vol)
1286 * The upcase size must not be above 64k Unicode characters, must not 1289 * The upcase size must not be above 64k Unicode characters, must not
1287 * be zero and must be a multiple of sizeof(ntfschar). 1290 * be zero and must be a multiple of sizeof(ntfschar).
1288 */ 1291 */
1289 if (!ino->i_size || ino->i_size & (sizeof(ntfschar) - 1) || 1292 i_size = i_size_read(ino);
1290 ino->i_size > 64ULL * 1024 * sizeof(ntfschar)) 1293 if (!i_size || i_size & (sizeof(ntfschar) - 1) ||
1294 i_size > 64ULL * 1024 * sizeof(ntfschar))
1291 goto iput_upcase_failed; 1295 goto iput_upcase_failed;
1292 vol->upcase = (ntfschar*)ntfs_malloc_nofs(ino->i_size); 1296 vol->upcase = (ntfschar*)ntfs_malloc_nofs(i_size);
1293 if (!vol->upcase) 1297 if (!vol->upcase)
1294 goto iput_upcase_failed; 1298 goto iput_upcase_failed;
1295 index = 0; 1299 index = 0;
1296 max_index = ino->i_size >> PAGE_CACHE_SHIFT; 1300 max_index = i_size >> PAGE_CACHE_SHIFT;
1297 size = PAGE_CACHE_SIZE; 1301 size = PAGE_CACHE_SIZE;
1298 while (index < max_index) { 1302 while (index < max_index) {
1299 /* Read the upcase table and copy it into the linear buffer. */ 1303 /* Read the upcase table and copy it into the linear buffer. */
@@ -1306,13 +1310,13 @@ read_partial_upcase_page:
1306 ntfs_unmap_page(page); 1310 ntfs_unmap_page(page);
1307 }; 1311 };
1308 if (size == PAGE_CACHE_SIZE) { 1312 if (size == PAGE_CACHE_SIZE) {
1309 size = ino->i_size & ~PAGE_CACHE_MASK; 1313 size = i_size & ~PAGE_CACHE_MASK;
1310 if (size) 1314 if (size)
1311 goto read_partial_upcase_page; 1315 goto read_partial_upcase_page;
1312 } 1316 }
1313 vol->upcase_len = ino->i_size >> UCHAR_T_SIZE_BITS; 1317 vol->upcase_len = i_size >> UCHAR_T_SIZE_BITS;
1314 ntfs_debug("Read %llu bytes from $UpCase (expected %zu bytes).", 1318 ntfs_debug("Read %llu bytes from $UpCase (expected %zu bytes).",
1315 ino->i_size, 64 * 1024 * sizeof(ntfschar)); 1319 i_size, 64 * 1024 * sizeof(ntfschar));
1316 iput(ino); 1320 iput(ino);
1317 down(&ntfs_lock); 1321 down(&ntfs_lock);
1318 if (!default_upcase) { 1322 if (!default_upcase) {
@@ -1435,7 +1439,7 @@ static BOOL load_system_files(ntfs_volume *vol)
1435 iput(vol->lcnbmp_ino); 1439 iput(vol->lcnbmp_ino);
1436 goto bitmap_failed; 1440 goto bitmap_failed;
1437 } 1441 }
1438 if ((vol->nr_clusters + 7) >> 3 > vol->lcnbmp_ino->i_size) { 1442 if ((vol->nr_clusters + 7) >> 3 > i_size_read(vol->lcnbmp_ino)) {
1439 iput(vol->lcnbmp_ino); 1443 iput(vol->lcnbmp_ino);
1440bitmap_failed: 1444bitmap_failed:
1441 ntfs_error(sb, "Failed to load $Bitmap."); 1445 ntfs_error(sb, "Failed to load $Bitmap.");
@@ -1959,8 +1963,7 @@ static s64 get_nr_free_clusters(ntfs_volume *vol)
1959 struct address_space *mapping = vol->lcnbmp_ino->i_mapping; 1963 struct address_space *mapping = vol->lcnbmp_ino->i_mapping;
1960 filler_t *readpage = (filler_t*)mapping->a_ops->readpage; 1964 filler_t *readpage = (filler_t*)mapping->a_ops->readpage;
1961 struct page *page; 1965 struct page *page;
1962 unsigned long index, max_index; 1966 pgoff_t index, max_index;
1963 unsigned int max_size;
1964 1967
1965 ntfs_debug("Entering."); 1968 ntfs_debug("Entering.");
1966 /* Serialize accesses to the cluster bitmap. */ 1969 /* Serialize accesses to the cluster bitmap. */
@@ -1972,11 +1975,10 @@ static s64 get_nr_free_clusters(ntfs_volume *vol)
1972 */ 1975 */
1973 max_index = (((vol->nr_clusters + 7) >> 3) + PAGE_CACHE_SIZE - 1) >> 1976 max_index = (((vol->nr_clusters + 7) >> 3) + PAGE_CACHE_SIZE - 1) >>
1974 PAGE_CACHE_SHIFT; 1977 PAGE_CACHE_SHIFT;
1975 /* Use multiples of 4 bytes. */ 1978 /* Use multiples of 4 bytes, thus max_size is PAGE_CACHE_SIZE / 4. */
1976 max_size = PAGE_CACHE_SIZE >> 2; 1979 ntfs_debug("Reading $Bitmap, max_index = 0x%lx, max_size = 0x%lx.",
1977 ntfs_debug("Reading $Bitmap, max_index = 0x%lx, max_size = 0x%x.", 1980 max_index, PAGE_CACHE_SIZE / 4);
1978 max_index, max_size); 1981 for (index = 0; index < max_index; index++) {
1979 for (index = 0UL; index < max_index; index++) {
1980 unsigned int i; 1982 unsigned int i;
1981 /* 1983 /*
1982 * Read the page from page cache, getting it from backing store 1984 * Read the page from page cache, getting it from backing store
@@ -2008,7 +2010,7 @@ static s64 get_nr_free_clusters(ntfs_volume *vol)
2008 * the result as all out of range bytes are set to zero by 2010 * the result as all out of range bytes are set to zero by
2009 * ntfs_readpage(). 2011 * ntfs_readpage().
2010 */ 2012 */
2011 for (i = 0; i < max_size; i++) 2013 for (i = 0; i < PAGE_CACHE_SIZE / 4; i++)
2012 nr_free -= (s64)hweight32(kaddr[i]); 2014 nr_free -= (s64)hweight32(kaddr[i]);
2013 kunmap_atomic(kaddr, KM_USER0); 2015 kunmap_atomic(kaddr, KM_USER0);
2014 page_cache_release(page); 2016 page_cache_release(page);
@@ -2031,6 +2033,8 @@ static s64 get_nr_free_clusters(ntfs_volume *vol)
2031/** 2033/**
2032 * __get_nr_free_mft_records - return the number of free inodes on a volume 2034 * __get_nr_free_mft_records - return the number of free inodes on a volume
2033 * @vol: ntfs volume for which to obtain free inode count 2035 * @vol: ntfs volume for which to obtain free inode count
2036 * @nr_free: number of mft records in file system
2037 * @max_index: maximum number of pages containing set bits
2034 * 2038 *
2035 * Calculate the number of free mft records (inodes) on the mounted NTFS 2039 * Calculate the number of free mft records (inodes) on the mounted NTFS
2036 * volume @vol. We actually calculate the number of mft records in use instead 2040 * volume @vol. We actually calculate the number of mft records in use instead
@@ -2043,32 +2047,20 @@ static s64 get_nr_free_clusters(ntfs_volume *vol)
2043 * 2047 *
2044 * NOTE: Caller must hold mftbmp_lock rw_semaphore for reading or writing. 2048 * NOTE: Caller must hold mftbmp_lock rw_semaphore for reading or writing.
2045 */ 2049 */
2046static unsigned long __get_nr_free_mft_records(ntfs_volume *vol) 2050static unsigned long __get_nr_free_mft_records(ntfs_volume *vol,
2051 s64 nr_free, const pgoff_t max_index)
2047{ 2052{
2048 s64 nr_free;
2049 u32 *kaddr; 2053 u32 *kaddr;
2050 struct address_space *mapping = vol->mftbmp_ino->i_mapping; 2054 struct address_space *mapping = vol->mftbmp_ino->i_mapping;
2051 filler_t *readpage = (filler_t*)mapping->a_ops->readpage; 2055 filler_t *readpage = (filler_t*)mapping->a_ops->readpage;
2052 struct page *page; 2056 struct page *page;
2053 unsigned long index, max_index; 2057 pgoff_t index;
2054 unsigned int max_size;
2055 2058
2056 ntfs_debug("Entering."); 2059 ntfs_debug("Entering.");
2057 /* Number of mft records in file system (at this point in time). */ 2060 /* Use multiples of 4 bytes, thus max_size is PAGE_CACHE_SIZE / 4. */
2058 nr_free = vol->mft_ino->i_size >> vol->mft_record_size_bits;
2059 /*
2060 * Convert the maximum number of set bits into bytes rounded up, then
2061 * convert into multiples of PAGE_CACHE_SIZE, rounding up so that if we
2062 * have one full and one partial page max_index = 2.
2063 */
2064 max_index = ((((NTFS_I(vol->mft_ino)->initialized_size >>
2065 vol->mft_record_size_bits) + 7) >> 3) +
2066 PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
2067 /* Use multiples of 4 bytes. */
2068 max_size = PAGE_CACHE_SIZE >> 2;
2069 ntfs_debug("Reading $MFT/$BITMAP, max_index = 0x%lx, max_size = " 2061 ntfs_debug("Reading $MFT/$BITMAP, max_index = 0x%lx, max_size = "
2070 "0x%x.", max_index, max_size); 2062 "0x%lx.", max_index, PAGE_CACHE_SIZE / 4);
2071 for (index = 0UL; index < max_index; index++) { 2063 for (index = 0; index < max_index; index++) {
2072 unsigned int i; 2064 unsigned int i;
2073 /* 2065 /*
2074 * Read the page from page cache, getting it from backing store 2066 * Read the page from page cache, getting it from backing store
@@ -2100,7 +2092,7 @@ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol)
2100 * the result as all out of range bytes are set to zero by 2092 * the result as all out of range bytes are set to zero by
2101 * ntfs_readpage(). 2093 * ntfs_readpage().
2102 */ 2094 */
2103 for (i = 0; i < max_size; i++) 2095 for (i = 0; i < PAGE_CACHE_SIZE / 4; i++)
2104 nr_free -= (s64)hweight32(kaddr[i]); 2096 nr_free -= (s64)hweight32(kaddr[i]);
2105 kunmap_atomic(kaddr, KM_USER0); 2097 kunmap_atomic(kaddr, KM_USER0);
2106 page_cache_release(page); 2098 page_cache_release(page);
@@ -2134,8 +2126,11 @@ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol)
2134 */ 2126 */
2135static int ntfs_statfs(struct super_block *sb, struct kstatfs *sfs) 2127static int ntfs_statfs(struct super_block *sb, struct kstatfs *sfs)
2136{ 2128{
2137 ntfs_volume *vol = NTFS_SB(sb);
2138 s64 size; 2129 s64 size;
2130 ntfs_volume *vol = NTFS_SB(sb);
2131 ntfs_inode *mft_ni = NTFS_I(vol->mft_ino);
2132 pgoff_t max_index;
2133 unsigned long flags;
2139 2134
2140 ntfs_debug("Entering."); 2135 ntfs_debug("Entering.");
2141 /* Type of filesystem. */ 2136 /* Type of filesystem. */
@@ -2158,10 +2153,20 @@ static int ntfs_statfs(struct super_block *sb, struct kstatfs *sfs)
2158 sfs->f_bavail = sfs->f_bfree = size; 2153 sfs->f_bavail = sfs->f_bfree = size;
2159 /* Serialize accesses to the inode bitmap. */ 2154 /* Serialize accesses to the inode bitmap. */
2160 down_read(&vol->mftbmp_lock); 2155 down_read(&vol->mftbmp_lock);
2156 read_lock_irqsave(&mft_ni->size_lock, flags);
2157 size = i_size_read(vol->mft_ino) >> vol->mft_record_size_bits;
2158 /*
2159 * Convert the maximum number of set bits into bytes rounded up, then
2160 * convert into multiples of PAGE_CACHE_SIZE, rounding up so that if we
2161 * have one full and one partial page max_index = 2.
2162 */
2163 max_index = ((((mft_ni->initialized_size >> vol->mft_record_size_bits)
2164 + 7) >> 3) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
2165 read_unlock_irqrestore(&mft_ni->size_lock, flags);
2161 /* Number of inodes in file system (at this point in time). */ 2166 /* Number of inodes in file system (at this point in time). */
2162 sfs->f_files = vol->mft_ino->i_size >> vol->mft_record_size_bits; 2167 sfs->f_files = size;
2163 /* Free inodes in fs (based on current total count). */ 2168 /* Free inodes in fs (based on current total count). */
2164 sfs->f_ffree = __get_nr_free_mft_records(vol); 2169 sfs->f_ffree = __get_nr_free_mft_records(vol, size, max_index);
2165 up_read(&vol->mftbmp_lock); 2170 up_read(&vol->mftbmp_lock);
2166 /* 2171 /*
2167 * File system id. This is extremely *nix flavour dependent and even 2172 * File system id. This is extremely *nix flavour dependent and even
@@ -2347,7 +2352,8 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
2347 } 2352 }
2348 2353
2349 /* Get the size of the device in units of NTFS_BLOCK_SIZE bytes. */ 2354 /* Get the size of the device in units of NTFS_BLOCK_SIZE bytes. */
2350 vol->nr_blocks = sb->s_bdev->bd_inode->i_size >> NTFS_BLOCK_SIZE_BITS; 2355 vol->nr_blocks = i_size_read(sb->s_bdev->bd_inode) >>
2356 NTFS_BLOCK_SIZE_BITS;
2351 2357
2352 /* Read the boot sector and return unlocked buffer head to it. */ 2358 /* Read the boot sector and return unlocked buffer head to it. */
2353 if (!(bh = read_ntfs_boot_sector(sb, silent))) { 2359 if (!(bh = read_ntfs_boot_sector(sb, silent))) {