@@ -231,7 +231,7 @@ int attr_make_nonresident(struct ntfs_inode *ni, struct ATTRIB *attr,
231
231
struct ntfs_sb_info * sbi ;
232
232
struct ATTRIB * attr_s ;
233
233
struct MFT_REC * rec ;
234
- u32 used , asize , rsize , aoff , align ;
234
+ u32 used , asize , rsize , aoff ;
235
235
bool is_data ;
236
236
CLST len , alen ;
237
237
char * next ;
@@ -252,10 +252,13 @@ int attr_make_nonresident(struct ntfs_inode *ni, struct ATTRIB *attr,
252
252
rsize = le32_to_cpu (attr -> res .data_size );
253
253
is_data = attr -> type == ATTR_DATA && !attr -> name_len ;
254
254
255
- align = sbi -> cluster_size ;
256
- if (is_attr_compressed (attr ))
257
- align <<= COMPRESSION_UNIT ;
258
- len = (rsize + align - 1 ) >> sbi -> cluster_bits ;
255
+ /* len - how many clusters required to store 'rsize' bytes */
256
+ if (is_attr_compressed (attr )) {
257
+ u8 shift = sbi -> cluster_bits + NTFS_LZNT_CUNIT ;
258
+ len = ((rsize + (1u << shift ) - 1 ) >> shift ) << NTFS_LZNT_CUNIT ;
259
+ } else {
260
+ len = bytes_to_cluster (sbi , rsize );
261
+ }
259
262
260
263
run_init (run );
261
264
@@ -285,22 +288,21 @@ int attr_make_nonresident(struct ntfs_inode *ni, struct ATTRIB *attr,
285
288
if (err )
286
289
goto out2 ;
287
290
} else if (!page ) {
288
- char * kaddr ;
289
-
290
- page = grab_cache_page (ni -> vfs_inode .i_mapping , 0 );
291
- if (!page ) {
292
- err = - ENOMEM ;
291
+ struct address_space * mapping = ni -> vfs_inode .i_mapping ;
292
+ struct folio * folio ;
293
+
294
+ folio = __filemap_get_folio (
295
+ mapping , 0 , FGP_LOCK | FGP_ACCESSED | FGP_CREAT ,
296
+ mapping_gfp_mask (mapping ));
297
+ if (IS_ERR (folio )) {
298
+ err = PTR_ERR (folio );
293
299
goto out2 ;
294
300
}
295
- kaddr = kmap_atomic (page );
296
- memcpy (kaddr , data , rsize );
297
- memset (kaddr + rsize , 0 , PAGE_SIZE - rsize );
298
- kunmap_atomic (kaddr );
299
- flush_dcache_page (page );
300
- SetPageUptodate (page );
301
- set_page_dirty (page );
302
- unlock_page (page );
303
- put_page (page );
301
+ folio_fill_tail (folio , 0 , data , rsize );
302
+ folio_mark_uptodate (folio );
303
+ folio_mark_dirty (folio );
304
+ folio_unlock (folio );
305
+ folio_put (folio );
304
306
}
305
307
}
306
308
@@ -670,7 +672,8 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type,
670
672
goto undo_2 ;
671
673
}
672
674
673
- if (!is_mft )
675
+ /* keep runs for $MFT::$ATTR_DATA and $MFT::$ATTR_BITMAP. */
676
+ if (ni -> mi .rno != MFT_REC_MFT )
674
677
run_truncate_head (run , evcn + 1 );
675
678
676
679
svcn = le64_to_cpu (attr -> nres .svcn );
@@ -972,6 +975,19 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn,
972
975
if (err )
973
976
goto out ;
974
977
978
+ /* Check for compressed frame. */
979
+ err = attr_is_frame_compressed (ni , attr , vcn >> NTFS_LZNT_CUNIT , & hint );
980
+ if (err )
981
+ goto out ;
982
+
983
+ if (hint ) {
984
+ /* if frame is compressed - don't touch it. */
985
+ * lcn = COMPRESSED_LCN ;
986
+ * len = hint ;
987
+ err = - EOPNOTSUPP ;
988
+ goto out ;
989
+ }
990
+
975
991
if (!* len ) {
976
992
if (run_lookup_entry (run , vcn , lcn , len , NULL )) {
977
993
if (* lcn != SPARSE_LCN || !new )
@@ -1223,11 +1239,12 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn,
1223
1239
goto out ;
1224
1240
}
1225
1241
1226
- int attr_data_read_resident (struct ntfs_inode * ni , struct page * page )
1242
+ int attr_data_read_resident (struct ntfs_inode * ni , struct folio * folio )
1227
1243
{
1228
1244
u64 vbo ;
1229
1245
struct ATTRIB * attr ;
1230
1246
u32 data_size ;
1247
+ size_t len ;
1231
1248
1232
1249
attr = ni_find_attr (ni , NULL , NULL , ATTR_DATA , NULL , 0 , NULL , NULL );
1233
1250
if (!attr )
@@ -1236,30 +1253,20 @@ int attr_data_read_resident(struct ntfs_inode *ni, struct page *page)
1236
1253
if (attr -> non_res )
1237
1254
return E_NTFS_NONRESIDENT ;
1238
1255
1239
- vbo = page -> index << PAGE_SHIFT ;
1256
+ vbo = folio -> index << PAGE_SHIFT ;
1240
1257
data_size = le32_to_cpu (attr -> res .data_size );
1241
- if (vbo < data_size ) {
1242
- const char * data = resident_data (attr );
1243
- char * kaddr = kmap_atomic (page );
1244
- u32 use = data_size - vbo ;
1245
-
1246
- if (use > PAGE_SIZE )
1247
- use = PAGE_SIZE ;
1258
+ if (vbo > data_size )
1259
+ len = 0 ;
1260
+ else
1261
+ len = min (data_size - vbo , folio_size (folio ));
1248
1262
1249
- memcpy (kaddr , data + vbo , use );
1250
- memset (kaddr + use , 0 , PAGE_SIZE - use );
1251
- kunmap_atomic (kaddr );
1252
- flush_dcache_page (page );
1253
- SetPageUptodate (page );
1254
- } else if (!PageUptodate (page )) {
1255
- zero_user_segment (page , 0 , PAGE_SIZE );
1256
- SetPageUptodate (page );
1257
- }
1263
+ folio_fill_tail (folio , 0 , resident_data (attr ) + vbo , len );
1264
+ folio_mark_uptodate (folio );
1258
1265
1259
1266
return 0 ;
1260
1267
}
1261
1268
1262
- int attr_data_write_resident (struct ntfs_inode * ni , struct page * page )
1269
+ int attr_data_write_resident (struct ntfs_inode * ni , struct folio * folio )
1263
1270
{
1264
1271
u64 vbo ;
1265
1272
struct mft_inode * mi ;
@@ -1275,17 +1282,13 @@ int attr_data_write_resident(struct ntfs_inode *ni, struct page *page)
1275
1282
return E_NTFS_NONRESIDENT ;
1276
1283
}
1277
1284
1278
- vbo = page -> index << PAGE_SHIFT ;
1285
+ vbo = folio -> index << PAGE_SHIFT ;
1279
1286
data_size = le32_to_cpu (attr -> res .data_size );
1280
1287
if (vbo < data_size ) {
1281
1288
char * data = resident_data (attr );
1282
- char * kaddr = kmap_atomic (page );
1283
- u32 use = data_size - vbo ;
1289
+ size_t len = min (data_size - vbo , folio_size (folio ));
1284
1290
1285
- if (use > PAGE_SIZE )
1286
- use = PAGE_SIZE ;
1287
- memcpy (data + vbo , kaddr , use );
1288
- kunmap_atomic (kaddr );
1291
+ memcpy_from_folio (data + vbo , folio , 0 , len );
1289
1292
mi -> dirty = true;
1290
1293
}
1291
1294
ni -> i_valid = data_size ;
@@ -1378,7 +1381,7 @@ int attr_wof_frame_info(struct ntfs_inode *ni, struct ATTRIB *attr,
1378
1381
u32 voff ;
1379
1382
u8 bytes_per_off ;
1380
1383
char * addr ;
1381
- struct page * page ;
1384
+ struct folio * folio ;
1382
1385
int i , err ;
1383
1386
__le32 * off32 ;
1384
1387
__le64 * off64 ;
@@ -1423,18 +1426,18 @@ int attr_wof_frame_info(struct ntfs_inode *ni, struct ATTRIB *attr,
1423
1426
1424
1427
wof_size = le64_to_cpu (attr -> nres .data_size );
1425
1428
down_write (& ni -> file .run_lock );
1426
- page = ni -> file .offs_page ;
1427
- if (!page ) {
1428
- page = alloc_page (GFP_KERNEL );
1429
- if (!page ) {
1429
+ folio = ni -> file .offs_folio ;
1430
+ if (!folio ) {
1431
+ folio = folio_alloc (GFP_KERNEL , 0 );
1432
+ if (!folio ) {
1430
1433
err = - ENOMEM ;
1431
1434
goto out ;
1432
1435
}
1433
- page -> index = -1 ;
1434
- ni -> file .offs_page = page ;
1436
+ folio -> index = -1 ;
1437
+ ni -> file .offs_folio = folio ;
1435
1438
}
1436
- lock_page ( page );
1437
- addr = page_address ( page );
1439
+ folio_lock ( folio );
1440
+ addr = folio_address ( folio );
1438
1441
1439
1442
if (vbo [1 ]) {
1440
1443
voff = vbo [1 ] & (PAGE_SIZE - 1 );
@@ -1450,7 +1453,8 @@ int attr_wof_frame_info(struct ntfs_inode *ni, struct ATTRIB *attr,
1450
1453
do {
1451
1454
pgoff_t index = vbo [i ] >> PAGE_SHIFT ;
1452
1455
1453
- if (index != page -> index ) {
1456
+ if (index != folio -> index ) {
1457
+ struct page * page = & folio -> page ;
1454
1458
u64 from = vbo [i ] & ~(u64 )(PAGE_SIZE - 1 );
1455
1459
u64 to = min (from + PAGE_SIZE , wof_size );
1456
1460
@@ -1463,10 +1467,10 @@ int attr_wof_frame_info(struct ntfs_inode *ni, struct ATTRIB *attr,
1463
1467
err = ntfs_bio_pages (sbi , run , & page , 1 , from ,
1464
1468
to - from , REQ_OP_READ );
1465
1469
if (err ) {
1466
- page -> index = -1 ;
1470
+ folio -> index = -1 ;
1467
1471
goto out1 ;
1468
1472
}
1469
- page -> index = index ;
1473
+ folio -> index = index ;
1470
1474
}
1471
1475
1472
1476
if (i ) {
@@ -1504,7 +1508,7 @@ int attr_wof_frame_info(struct ntfs_inode *ni, struct ATTRIB *attr,
1504
1508
* ondisk_size = off [1 ] - off [0 ];
1505
1509
1506
1510
out1 :
1507
- unlock_page ( page );
1511
+ folio_unlock ( folio );
1508
1512
out :
1509
1513
up_write (& ni -> file .run_lock );
1510
1514
return err ;
@@ -1722,6 +1726,7 @@ int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size,
1722
1726
1723
1727
attr_b -> nres .total_size = cpu_to_le64 (total_size );
1724
1728
inode_set_bytes (& ni -> vfs_inode , total_size );
1729
+ ni -> ni_flags |= NI_FLAG_UPDATE_PARENT ;
1725
1730
1726
1731
mi_b -> dirty = true;
1727
1732
mark_inode_dirty (& ni -> vfs_inode );
@@ -2356,8 +2361,13 @@ int attr_insert_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
2356
2361
mask = (sbi -> cluster_size << attr_b -> nres .c_unit ) - 1 ;
2357
2362
}
2358
2363
2359
- if (vbo > data_size ) {
2360
- /* Insert range after the file size is not allowed. */
2364
+ if (vbo >= data_size ) {
2365
+ /*
2366
+ * Insert range after the file size is not allowed.
2367
+ * If the offset is equal to or greater than the end of
2368
+ * file, an error is returned. For such operations (i.e., inserting
2369
+ * a hole at the end of file), ftruncate(2) should be used.
2370
+ */
2361
2371
return - EINVAL ;
2362
2372
}
2363
2373
0 commit comments