frecord.c (78ab59fee07f22464f32eafebab2bd97ba94ff2d) frecord.c (d3624466b56dd5b1886c1dff500525b544c19c83)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 *
4 * Copyright (C) 2019-2021 Paragon Software GmbH, All rights reserved.
5 *
6 */
7
8#include <linux/blkdev.h>

--- 42 unchanged lines hidden (view full) ---

51 */
52static struct mft_inode *ni_find_mi(struct ntfs_inode *ni, CLST rno)
53{
54 return ni_ins_mi(ni, &ni->mi_tree, rno, NULL);
55}
56
57/*
58 * ni_add_mi - Add new mft_inode into ntfs_inode.
1// SPDX-License-Identifier: GPL-2.0
2/*
3 *
4 * Copyright (C) 2019-2021 Paragon Software GmbH, All rights reserved.
5 *
6 */
7
8#include <linux/blkdev.h>

--- 42 unchanged lines hidden (view full) ---

51 */
52static struct mft_inode *ni_find_mi(struct ntfs_inode *ni, CLST rno)
53{
54 return ni_ins_mi(ni, &ni->mi_tree, rno, NULL);
55}
56
57/*
58 * ni_add_mi - Add new mft_inode into ntfs_inode.
59*/
59 */
60static void ni_add_mi(struct ntfs_inode *ni, struct mft_inode *mi)
61{
62 ni_ins_mi(ni, &ni->mi_tree, mi->rno, &mi->node);
63}
64
65/*
66 * ni_remove_mi - Remove mft_inode from ntfs_inode.
67 */
68void ni_remove_mi(struct ntfs_inode *ni, struct mft_inode *mi)
69{
70 rb_erase(&mi->node, &ni->mi_tree);
71}
72
60static void ni_add_mi(struct ntfs_inode *ni, struct mft_inode *mi)
61{
62 ni_ins_mi(ni, &ni->mi_tree, mi->rno, &mi->node);
63}
64
65/*
66 * ni_remove_mi - Remove mft_inode from ntfs_inode.
67 */
68void ni_remove_mi(struct ntfs_inode *ni, struct mft_inode *mi)
69{
70 rb_erase(&mi->node, &ni->mi_tree);
71}
72
73/* ni_std
74 *
75 * Return: Pointer into std_info from primary record.
73/*
74 * ni_std - Return: Pointer into std_info from primary record.
76 */
77struct ATTR_STD_INFO *ni_std(struct ntfs_inode *ni)
78{
79 const struct ATTRIB *attr;
80
81 attr = mi_find_attr(&ni->mi, NULL, ATTR_STD, NULL, 0, NULL);
82 return attr ? resident_data_ex(attr, sizeof(struct ATTR_STD_INFO))
83 : NULL;

--- 296 unchanged lines hidden (view full) ---

380
381 ni_add_mi(ni, m);
382 *mi = m;
383 return true;
384}
385
386/*
387 * ni_remove_attr - Remove all attributes for the given type/name/id.
75 */
76struct ATTR_STD_INFO *ni_std(struct ntfs_inode *ni)
77{
78 const struct ATTRIB *attr;
79
80 attr = mi_find_attr(&ni->mi, NULL, ATTR_STD, NULL, 0, NULL);
81 return attr ? resident_data_ex(attr, sizeof(struct ATTR_STD_INFO))
82 : NULL;

--- 296 unchanged lines hidden (view full) ---

379
380 ni_add_mi(ni, m);
381 *mi = m;
382 return true;
383}
384
385/*
386 * ni_remove_attr - Remove all attributes for the given type/name/id.
388*/
387 */
389int ni_remove_attr(struct ntfs_inode *ni, enum ATTR_TYPE type,
390 const __le16 *name, size_t name_len, bool base_only,
391 const __le16 *id)
392{
393 int err;
394 struct ATTRIB *attr;
395 struct ATTR_LIST_ENTRY *le;
396 struct mft_inode *mi;

--- 338 unchanged lines hidden (view full) ---

735 ni->attr_list.le = NULL;
736 ni->attr_list.dirty = false;
737
738 return 0;
739}
740
741/*
742 * ni_create_attr_list - Generates an attribute list for this primary record.
388int ni_remove_attr(struct ntfs_inode *ni, enum ATTR_TYPE type,
389 const __le16 *name, size_t name_len, bool base_only,
390 const __le16 *id)
391{
392 int err;
393 struct ATTRIB *attr;
394 struct ATTR_LIST_ENTRY *le;
395 struct mft_inode *mi;

--- 338 unchanged lines hidden (view full) ---

734 ni->attr_list.le = NULL;
735 ni->attr_list.dirty = false;
736
737 return 0;
738}
739
740/*
741 * ni_create_attr_list - Generates an attribute list for this primary record.
743*/
742 */
744int ni_create_attr_list(struct ntfs_inode *ni)
745{
746 struct ntfs_sb_info *sbi = ni->mi.sbi;
747 int err;
748 u32 lsize;
749 struct ATTRIB *attr;
750 struct ATTRIB *arr_move[7];
751 struct ATTR_LIST_ENTRY *le, *le_b[7];

--- 182 unchanged lines hidden (view full) ---

934
935 /* Check each of loaded subrecord. */
936 for (node = rb_first(&ni->mi_tree); node; node = rb_next(node)) {
937 mi = rb_entry(node, struct mft_inode, node);
938
939 if (is_mft_data &&
940 (mi_enum_attr(mi, NULL) ||
941 vbo <= ((u64)mi->rno << sbi->record_bits))) {
743int ni_create_attr_list(struct ntfs_inode *ni)
744{
745 struct ntfs_sb_info *sbi = ni->mi.sbi;
746 int err;
747 u32 lsize;
748 struct ATTRIB *attr;
749 struct ATTRIB *arr_move[7];
750 struct ATTR_LIST_ENTRY *le, *le_b[7];

--- 182 unchanged lines hidden (view full) ---

933
934 /* Check each of loaded subrecord. */
935 for (node = rb_first(&ni->mi_tree); node; node = rb_next(node)) {
936 mi = rb_entry(node, struct mft_inode, node);
937
938 if (is_mft_data &&
939 (mi_enum_attr(mi, NULL) ||
940 vbo <= ((u64)mi->rno << sbi->record_bits))) {
942 /* We can't accept this record 'case MFT's bootstrapping. */
941 /* We can't accept this record 'cause MFT's bootstrapping. */
943 continue;
944 }
945 if (is_mft &&
946 mi_find_attr(mi, NULL, ATTR_DATA, NULL, 0, NULL)) {
947 /*
948 * This child record already has a ATTR_DATA.
949 * So it can't accept any other records.
950 */

--- 122 unchanged lines hidden (view full) ---

1073 /*
1074 * Here we have: "is_mft && type == ATTR_DATA && !svcn"
1075 *
1076 * The first chunk of the $MFT::Data ATTRIB must be the base record.
1077 * Evict as many other attributes as possible.
1078 */
1079 max_free = free;
1080
942 continue;
943 }
944 if (is_mft &&
945 mi_find_attr(mi, NULL, ATTR_DATA, NULL, 0, NULL)) {
946 /*
947 * This child record already has a ATTR_DATA.
948 * So it can't accept any other records.
949 */

--- 122 unchanged lines hidden (view full) ---

1072 /*
1073 * Here we have: "is_mft && type == ATTR_DATA && !svcn"
1074 *
1075 * The first chunk of the $MFT::Data ATTRIB must be the base record.
1076 * Evict as many other attributes as possible.
1077 */
1078 max_free = free;
1079
1081 /* Estimate the result of moving all possible attributes away.*/
1080 /* Estimate the result of moving all possible attributes away. */
1082 attr = NULL;
1083
1084 while ((attr = mi_enum_attr(&ni->mi, attr))) {
1085 if (attr->type == ATTR_STD)
1086 continue;
1087 if (attr->type == ATTR_LIST)
1088 continue;
1089 max_free += le32_to_cpu(attr->size);
1090 }
1091
1092 if (max_free < asize + list_reserve) {
1093 /* Impossible to insert this attribute into primary record. */
1094 err = -EINVAL;
1095 goto out;
1096 }
1097
1081 attr = NULL;
1082
1083 while ((attr = mi_enum_attr(&ni->mi, attr))) {
1084 if (attr->type == ATTR_STD)
1085 continue;
1086 if (attr->type == ATTR_LIST)
1087 continue;
1088 max_free += le32_to_cpu(attr->size);
1089 }
1090
1091 if (max_free < asize + list_reserve) {
1092 /* Impossible to insert this attribute into primary record. */
1093 err = -EINVAL;
1094 goto out;
1095 }
1096
1098 /* Start real attribute moving */
1097 /* Start real attribute moving. */
1099 attr = NULL;
1100
1101 for (;;) {
1102 attr = mi_enum_attr(&ni->mi, attr);
1103 if (!attr) {
1104 /* We should never be here 'cause we have already check this case. */
1105 err = -EINVAL;
1106 goto out;

--- 430 unchanged lines hidden (view full) ---

1537 mi_write(mi, 0);
1538
1539 ntfs_mark_rec_free(sbi, mi->rno);
1540 ni_remove_mi(ni, mi);
1541 mi_put(mi);
1542 node = next;
1543 }
1544
1098 attr = NULL;
1099
1100 for (;;) {
1101 attr = mi_enum_attr(&ni->mi, attr);
1102 if (!attr) {
1103 /* We should never be here 'cause we have already check this case. */
1104 err = -EINVAL;
1105 goto out;

--- 430 unchanged lines hidden (view full) ---

1536 mi_write(mi, 0);
1537
1538 ntfs_mark_rec_free(sbi, mi->rno);
1539 ni_remove_mi(ni, mi);
1540 mi_put(mi);
1541 node = next;
1542 }
1543
1545 /* Free base record */
1544 /* Free base record. */
1546 clear_rec_inuse(ni->mi.mrec);
1547 ni->mi.dirty = true;
1548 err = mi_write(&ni->mi, 0);
1549
1550 ntfs_mark_rec_free(sbi, ni->mi.rno);
1551
1552 return err;
1553}

--- 684 unchanged lines hidden (view full) ---

2238 */
2239 attr = ni_find_attr(ni, NULL, NULL, ATTR_DATA, NULL, 0, NULL, &mi);
2240 if (!attr) {
2241 err = -EINVAL;
2242 goto out;
2243 }
2244
2245 if (attr->non_res && is_attr_sparsed(attr)) {
1545 clear_rec_inuse(ni->mi.mrec);
1546 ni->mi.dirty = true;
1547 err = mi_write(&ni->mi, 0);
1548
1549 ntfs_mark_rec_free(sbi, ni->mi.rno);
1550
1551 return err;
1552}

--- 684 unchanged lines hidden (view full) ---

2237 */
2238 attr = ni_find_attr(ni, NULL, NULL, ATTR_DATA, NULL, 0, NULL, &mi);
2239 if (!attr) {
2240 err = -EINVAL;
2241 goto out;
2242 }
2243
2244 if (attr->non_res && is_attr_sparsed(attr)) {
2246 /* Sarsed attribute header is 8 bytes bigger than normal. */
2245 /* Sparsed attribute header is 8 bytes bigger than normal. */
2247 struct MFT_REC *rec = mi->mrec;
2248 u32 used = le32_to_cpu(rec->used);
2249 u32 asize = le32_to_cpu(attr->size);
2250 u16 roff = le16_to_cpu(attr->nres.run_off);
2251 char *rbuf = Add2Ptr(attr, roff);
2252
2253 memmove(rbuf - 8, rbuf, used - PtrOffset(rec, rbuf));
2254 attr->size = cpu_to_le32(asize - 8);

--- 64 unchanged lines hidden (view full) ---

2319 }
2320out1:
2321 mutex_unlock(&sbi->compress.mtx_lzx);
2322 } else {
2323 /* XPRESS: Frame compressed. */
2324 mutex_lock(&sbi->compress.mtx_xpress);
2325 ctx = sbi->compress.xpress;
2326 if (!ctx) {
2246 struct MFT_REC *rec = mi->mrec;
2247 u32 used = le32_to_cpu(rec->used);
2248 u32 asize = le32_to_cpu(attr->size);
2249 u16 roff = le16_to_cpu(attr->nres.run_off);
2250 char *rbuf = Add2Ptr(attr, roff);
2251
2252 memmove(rbuf - 8, rbuf, used - PtrOffset(rec, rbuf));
2253 attr->size = cpu_to_le32(asize - 8);

--- 64 unchanged lines hidden (view full) ---

2318 }
2319out1:
2320 mutex_unlock(&sbi->compress.mtx_lzx);
2321 } else {
2322 /* XPRESS: Frame compressed. */
2323 mutex_lock(&sbi->compress.mtx_xpress);
2324 ctx = sbi->compress.xpress;
2325 if (!ctx) {
2327 /* Lazy initialize Xpress decompress context */
2326 /* Lazy initialize Xpress decompress context. */
2328 ctx = xpress_allocate_decompressor();
2329 if (!ctx) {
2330 err = -ENOMEM;
2331 goto out2;
2332 }
2333
2334 sbi->compress.xpress = ctx;
2335 }

--- 7 unchanged lines hidden (view full) ---

2343 }
2344 return err;
2345}
2346#endif
2347
2348/*
2349 * ni_read_frame
2350 *
2327 ctx = xpress_allocate_decompressor();
2328 if (!ctx) {
2329 err = -ENOMEM;
2330 goto out2;
2331 }
2332
2333 sbi->compress.xpress = ctx;
2334 }

--- 7 unchanged lines hidden (view full) ---

2342 }
2343 return err;
2344}
2345#endif
2346
2347/*
2348 * ni_read_frame
2349 *
2351 * Pages - array of locked pages.
2350 * Pages - Array of locked pages.
2352 */
2353int ni_read_frame(struct ntfs_inode *ni, u64 frame_vbo, struct page **pages,
2354 u32 pages_per_frame)
2355{
2356 int err;
2357 struct ntfs_sb_info *sbi = ni->mi.sbi;
2358 u8 cluster_bits = sbi->cluster_bits;
2359 char *frame_ondisk = NULL;

--- 375 unchanged lines hidden (view full) ---

2735 err = -ENOMEM;
2736 goto out3;
2737 }
2738
2739 sbi->compress.lznt = lznt;
2740 lznt = NULL;
2741 }
2742
2351 */
2352int ni_read_frame(struct ntfs_inode *ni, u64 frame_vbo, struct page **pages,
2353 u32 pages_per_frame)
2354{
2355 int err;
2356 struct ntfs_sb_info *sbi = ni->mi.sbi;
2357 u8 cluster_bits = sbi->cluster_bits;
2358 char *frame_ondisk = NULL;

--- 375 unchanged lines hidden (view full) ---

2734 err = -ENOMEM;
2735 goto out3;
2736 }
2737
2738 sbi->compress.lznt = lznt;
2739 lznt = NULL;
2740 }
2741
2743 /* Compress: frame_mem -> frame_ondisk. */
2742 /* Compress: frame_mem -> frame_ondisk */
2744 compr_size = compress_lznt(frame_mem, frame_size, frame_ondisk,
2745 frame_size, sbi->compress.lznt);
2746 mutex_unlock(&sbi->compress.mtx_lznt);
2747 kfree(lznt);
2748
2749 if (compr_size + sbi->cluster_size > frame_size) {
2750 /* Frame is not compressed. */
2751 compr_size = frame_size;

--- 507 unchanged lines hidden ---
2743 compr_size = compress_lznt(frame_mem, frame_size, frame_ondisk,
2744 frame_size, sbi->compress.lznt);
2745 mutex_unlock(&sbi->compress.mtx_lznt);
2746 kfree(lznt);
2747
2748 if (compr_size + sbi->cluster_size > frame_size) {
2749 /* Frame is not compressed. */
2750 compr_size = frame_size;

--- 507 unchanged lines hidden ---