Unverified Commit e8b8e97f authored by Kari Argillander's avatar Kari Argillander Committed by Konstantin Komarov
Browse files

fs/ntfs3: Restyle comments to better align with kernel-doc



Capitalize comments and end with period for better reading.

Also function comments are now little more kernel-doc style. This way we
can easily convert them to kernel-doc style if we want. Note that these
are not yet complete with this style. Example function comments start
with /* and in kernel-doc style they start /**.

Use imperative mood in function descriptions.

Change words like ntfs -> NTFS, linux -> Linux.

Use "we" not "I" when commenting code.

Signed-off-by: default avatarKari Argillander <kari.argillander@gmail.com>
Signed-off-by: default avatarKonstantin Komarov <almaz.alexandrovich@paragon-software.com>
parent b8155e95
Loading
Loading
Loading
Loading
+111 −119
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
 *
 * Copyright (C) 2019-2021 Paragon Software GmbH, All rights reserved.
 *
 * TODO: merge attr_set_size/attr_data_get_block/attr_allocate_frame?
 * TODO: Merge attr_set_size/attr_data_get_block/attr_allocate_frame?
 */

#include <linux/blkdev.h>
@@ -20,7 +20,7 @@

/*
 * You can set external NTFS_MIN_LOG2_OF_CLUMP/NTFS_MAX_LOG2_OF_CLUMP to manage
 * preallocate algorithm
 * preallocate algorithm.
 */
#ifndef NTFS_MIN_LOG2_OF_CLUMP
#define NTFS_MIN_LOG2_OF_CLUMP 16
@@ -35,10 +35,6 @@
// 16G
#define NTFS_CLUMP_MAX (1ull << (NTFS_MAX_LOG2_OF_CLUMP + 8))

/*
 * get_pre_allocated
 *
 */
static inline u64 get_pre_allocated(u64 size)
{
	u32 clump;
@@ -65,7 +61,7 @@ static inline u64 get_pre_allocated(u64 size)
/*
 * attr_must_be_resident
 *
 * returns true if attribute must be resident
 * Return: True if attribute must be resident.
 */
static inline bool attr_must_be_resident(struct ntfs_sb_info *sbi,
					 enum ATTR_TYPE type)
@@ -90,9 +86,7 @@ static inline bool attr_must_be_resident(struct ntfs_sb_info *sbi,
}

/*
 * attr_load_runs
 *
 * load all runs stored in 'attr'
 * attr_load_runs - Load all runs stored in @attr.
 */
int attr_load_runs(struct ATTRIB *attr, struct ntfs_inode *ni,
		   struct runs_tree *run, const CLST *vcn)
@@ -121,9 +115,7 @@ int attr_load_runs(struct ATTRIB *attr, struct ntfs_inode *ni,
}

/*
 * int run_deallocate_ex
 *
 * Deallocate clusters
 * run_deallocate_ex - Deallocate clusters.
 */
static int run_deallocate_ex(struct ntfs_sb_info *sbi, struct runs_tree *run,
			     CLST vcn, CLST len, CLST *done, bool trim)
@@ -163,7 +155,7 @@ static int run_deallocate_ex(struct ntfs_sb_info *sbi, struct runs_tree *run,
		vcn_next = vcn + clen;
		if (!run_get_entry(run, ++idx, &vcn, &lcn, &clen) ||
		    vcn != vcn_next) {
			// save memory - don't load entire run
			/* Save memory - don't load entire run. */
			goto failed;
		}
	}
@@ -176,9 +168,7 @@ static int run_deallocate_ex(struct ntfs_sb_info *sbi, struct runs_tree *run,
}

/*
 * attr_allocate_clusters
 *
 * find free space, mark it as used and store in 'run'
 * attr_allocate_clusters - Find free space, mark it as used and store in @run.
 */
int attr_allocate_clusters(struct ntfs_sb_info *sbi, struct runs_tree *run,
			   CLST vcn, CLST lcn, CLST len, CLST *pre_alloc,
@@ -207,7 +197,7 @@ int attr_allocate_clusters(struct ntfs_sb_info *sbi, struct runs_tree *run,
		if (new_lcn && vcn == vcn0)
			*new_lcn = lcn;

		/* Add new fragment into run storage */
		/* Add new fragment into run storage. */
		if (!run_add_entry(run, vcn, lcn, flen, opt == ALLOCATE_MFT)) {
			down_write_nested(&wnd->rw_lock, BITMAP_MUTEX_CLUSTERS);
			wnd_set_free(wnd, lcn, flen);
@@ -228,7 +218,7 @@ int attr_allocate_clusters(struct ntfs_sb_info *sbi, struct runs_tree *run,
	}

out:
	/* undo */
	/* Undo. */
	run_deallocate_ex(sbi, run, vcn0, vcn - vcn0, NULL, false);
	run_truncate(run, vcn0);

@@ -236,8 +226,10 @@ int attr_allocate_clusters(struct ntfs_sb_info *sbi, struct runs_tree *run,
}

/*
 * if page is not NULL - it is already contains resident data
 * and locked (called from ni_write_frame)
 * attr_make_nonresident
 *
 * If page is not NULL - it is already contains resident data
 * and locked (called from ni_write_frame()).
 */
int attr_make_nonresident(struct ntfs_inode *ni, struct ATTRIB *attr,
			  struct ATTR_LIST_ENTRY *le, struct mft_inode *mi,
@@ -275,7 +267,7 @@ int attr_make_nonresident(struct ntfs_inode *ni, struct ATTRIB *attr,

	run_init(run);

	/* make a copy of original attribute */
	/* Make a copy of original attribute. */
	attr_s = kmemdup(attr, asize, GFP_NOFS);
	if (!attr_s) {
		err = -ENOMEM;
@@ -283,7 +275,7 @@ int attr_make_nonresident(struct ntfs_inode *ni, struct ATTRIB *attr,
	}

	if (!len) {
		/* empty resident -> empty nonresident */
		/* Empty resident -> Empty nonresident. */
		alen = 0;
	} else {
		const char *data = resident_data(attr);
@@ -294,7 +286,7 @@ int attr_make_nonresident(struct ntfs_inode *ni, struct ATTRIB *attr,
			goto out1;

		if (!rsize) {
			/* empty resident -> non empty nonresident */
			/* Empty resident -> Non empty nonresident. */
		} else if (!is_data) {
			err = ntfs_sb_write_run(sbi, run, 0, data, rsize);
			if (err)
@@ -319,7 +311,7 @@ int attr_make_nonresident(struct ntfs_inode *ni, struct ATTRIB *attr,
		}
	}

	/* remove original attribute */
	/* Remove original attribute. */
	used -= asize;
	memmove(attr, Add2Ptr(attr, asize), used - aoff);
	rec->used = cpu_to_le32(used);
@@ -342,7 +334,7 @@ int attr_make_nonresident(struct ntfs_inode *ni, struct ATTRIB *attr,
	if (is_data)
		ni->ni_flags &= ~NI_FLAG_RESIDENT;

	/* Resident attribute becomes non resident */
	/* Resident attribute becomes non resident. */
	return 0;

out3:
@@ -352,20 +344,18 @@ int attr_make_nonresident(struct ntfs_inode *ni, struct ATTRIB *attr,
	rec->used = cpu_to_le32(used + asize);
	mi->dirty = true;
out2:
	/* undo: do not trim new allocated clusters */
	/* Undo: do not trim new allocated clusters. */
	run_deallocate(sbi, run, false);
	run_close(run);
out1:
	kfree(attr_s);
	/*reinsert le*/
	/* Reinsert le. */
out:
	return err;
}

/*
 * attr_set_size_res
 *
 * helper for attr_set_size
 * attr_set_size_res - Helper for attr_set_size().
 */
static int attr_set_size_res(struct ntfs_inode *ni, struct ATTRIB *attr,
			     struct ATTR_LIST_ENTRY *le, struct mft_inode *mi,
@@ -407,14 +397,13 @@ static int attr_set_size_res(struct ntfs_inode *ni, struct ATTRIB *attr,
}

/*
 * attr_set_size
 * attr_set_size - Change the size of attribute.
 *
 * change the size of attribute
 * Extend:
 *   - sparse/compressed: no allocated clusters
 *   - normal: append allocated and preallocated new clusters
 *   - Sparse/compressed: No allocated clusters.
 *   - Normal: Append allocated and preallocated new clusters.
 * Shrink:
 *   - no deallocate if keep_prealloc is set
 *   - No deallocate if @keep_prealloc is set.
 */
int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type,
		  const __le16 *name, u8 name_len, struct runs_tree *run,
@@ -451,7 +440,7 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type,
		if (err || !attr_b->non_res)
			goto out;

		/* layout of records may be changed, so do a full search */
		/* Layout of records may be changed, so do a full search. */
		goto again;
	}

@@ -530,10 +519,10 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type,
add_alloc_in_same_attr_seg:
		lcn = 0;
		if (is_mft) {
			/* mft allocates clusters from mftzone */
			/* MFT allocates clusters from MFT zone. */
			pre_alloc = 0;
		} else if (is_ext) {
			/* no preallocate for sparse/compress */
			/* No preallocate for sparse/compress. */
			pre_alloc = 0;
		} else if (pre_alloc == -1) {
			pre_alloc = 0;
@@ -544,7 +533,7 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type,
				pre_alloc = new_alen2 - new_alen;
			}

			/* Get the last lcn to allocate from */
			/* Get the last LCN to allocate from. */
			if (old_alen &&
			    !run_lookup_entry(run, vcn, &lcn, NULL, NULL)) {
				lcn = SPARSE_LCN;
@@ -575,7 +564,7 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type,
			}
			alen = to_allocate;
		} else {
			/* ~3 bytes per fragment */
			/* ~3 bytes per fragment. */
			err = attr_allocate_clusters(
				sbi, run, vcn, lcn, to_allocate, &pre_alloc,
				is_mft ? ALLOCATE_MFT : 0, &alen,
@@ -607,12 +596,12 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type,
		mi_b->dirty = true;

		if (next_svcn >= vcn && !to_allocate) {
			/* Normal way. update attribute and exit */
			/* Normal way. Update attribute and exit. */
			attr_b->nres.data_size = cpu_to_le64(new_size);
			goto ok;
		}

		/* at least two mft to avoid recursive loop*/
		/* At least two MFT to avoid recursive loop. */
		if (is_mft && next_svcn == vcn &&
		    ((u64)done << sbi->cluster_bits) >= 2 * sbi->record_size) {
			new_size = new_alloc_tmp;
@@ -637,7 +626,7 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type,
			if (next_svcn < vcn)
				goto pack_runs;

			/* layout of records is changed */
			/* Layout of records is changed. */
			goto again;
		}

@@ -645,15 +634,15 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type,
			err = ni_create_attr_list(ni);
			if (err)
				goto out;
			/* layout of records is changed */
			/* Layout of records is changed. */
		}

		if (next_svcn >= vcn) {
			/* this is mft data, repeat */
			/* This is MFT data, repeat. */
			goto again;
		}

		/* insert new attribute segment */
		/* Insert new attribute segment. */
		err = ni_insert_nonresident(ni, type, name, name_len, run,
					    next_svcn, vcn - next_svcn,
					    attr_b->flags, &attr, &mi);
@@ -667,8 +656,10 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type,
		evcn = le64_to_cpu(attr->nres.evcn);

		le_b = NULL;
		/* layout of records maybe changed */
		/* find base attribute to update*/
		/*
		 * Layout of records maybe changed.
		 * Find base attribute to update.
		 */
		attr_b = ni_find_attr(ni, NULL, &le_b, type, name, name_len,
				      NULL, &mi_b);
		if (!attr_b) {
@@ -704,11 +695,11 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type,
			u16 le_sz = le16_to_cpu(le->size);

			/*
			 * NOTE: list entries for one attribute are always
			 * NOTE: List entries for one attribute are always
			 * the same size. We deal with last entry (vcn==0)
			 * and it is not first in entries array
			 * (list entry for std attribute always first)
			 * So it is safe to step back
			 * (list entry for std attribute always first).
			 * So it is safe to step back.
			 */
			mi_remove_attr(mi, attr);

@@ -793,7 +784,7 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type,
	if (!err && attr_b && ret)
		*ret = attr_b;

	/* update inode_set_bytes*/
	/* Update inode_set_bytes. */
	if (!err && ((type == ATTR_DATA && !name_len) ||
		     (type == ATTR_ALLOC && name == I30_NAME))) {
		bool dirty = false;
@@ -843,7 +834,7 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn,
	up_read(&ni->file.run_lock);

	if (ok && (*lcn != SPARSE_LCN || !new)) {
		/* normal way */
		/* Normal way. */
		return 0;
	}

@@ -909,7 +900,7 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn,
	if (!ok) {
		ok = run_lookup_entry(run, vcn, lcn, len, NULL);
		if (ok && (*lcn != SPARSE_LCN || !new)) {
			/* normal way */
			/* Normal way. */
			err = 0;
			goto ok;
		}
@@ -932,7 +923,7 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn,
		goto out;
	}

	/* Get the last lcn to allocate from */
	/* Get the last LCN to allocate from. */
	hint = 0;

	if (vcn > evcn1) {
@@ -970,20 +961,20 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn,
	mi_b->dirty = true;
	mark_inode_dirty(&ni->vfs_inode);

	/* stored [vcn : next_svcn) from [vcn : end) */
	/* Stored [vcn : next_svcn) from [vcn : end). */
	next_svcn = le64_to_cpu(attr->nres.evcn) + 1;

	if (end <= evcn1) {
		if (next_svcn == evcn1) {
			/* Normal way. update attribute and exit */
			/* Normal way. Update attribute and exit. */
			goto ok;
		}
		/* add new segment [next_svcn : evcn1 - next_svcn )*/
		/* Add new segment [next_svcn : evcn1 - next_svcn). */
		if (!ni->attr_list.size) {
			err = ni_create_attr_list(ni);
			if (err)
				goto out;
			/* layout of records is changed */
			/* Layout of records is changed. */
			le_b = NULL;
			attr_b = ni_find_attr(ni, NULL, &le_b, ATTR_DATA, NULL,
					      0, NULL, &mi_b);
@@ -1001,7 +992,7 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn,

	svcn = evcn1;

	/* Estimate next attribute */
	/* Estimate next attribute. */
	attr = ni_find_attr(ni, attr, &le, ATTR_DATA, NULL, 0, &svcn, &mi);

	if (attr) {
@@ -1012,7 +1003,7 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn,
		if (end < next_svcn)
			end = next_svcn;
		while (end > evcn) {
			/* remove segment [svcn : evcn)*/
			/* Remove segment [svcn : evcn). */
			mi_remove_attr(mi, attr);

			if (!al_remove_le(ni, le)) {
@@ -1021,7 +1012,7 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn,
			}

			if (evcn + 1 >= alloc) {
				/* last attribute segment */
				/* Last attribute segment. */
				evcn1 = evcn + 1;
				goto ins_ext;
			}
@@ -1125,7 +1116,7 @@ int attr_data_write_resident(struct ntfs_inode *ni, struct page *page)
		return -EINVAL;

	if (attr->non_res) {
		/*return special error code to check this case*/
		/* Return special error code to check this case. */
		return E_NTFS_NONRESIDENT;
	}

@@ -1148,9 +1139,7 @@ int attr_data_write_resident(struct ntfs_inode *ni, struct page *page)
}

/*
 * attr_load_runs_vcn
 *
 * load runs with vcn
 * attr_load_runs_vcn - Load runs with VCN.
 */
int attr_load_runs_vcn(struct ntfs_inode *ni, enum ATTR_TYPE type,
		       const __le16 *name, u8 name_len, struct runs_tree *run,
@@ -1180,7 +1169,7 @@ int attr_load_runs_vcn(struct ntfs_inode *ni, enum ATTR_TYPE type,
}

/*
 * load runs for given range [from to)
 * attr_wof_load_runs_range - Load runs for given range [from to).
 */
int attr_load_runs_range(struct ntfs_inode *ni, enum ATTR_TYPE type,
			 const __le16 *name, u8 name_len, struct runs_tree *run,
@@ -1199,7 +1188,7 @@ int attr_load_runs_range(struct ntfs_inode *ni, enum ATTR_TYPE type,
						 vcn);
			if (err)
				return err;
			clen = 0; /*next run_lookup_entry(vcn) must be success*/
			clen = 0; /* Next run_lookup_entry(vcn) must be success. */
		}
	}

@@ -1210,7 +1199,7 @@ int attr_load_runs_range(struct ntfs_inode *ni, enum ATTR_TYPE type,
/*
 * attr_wof_frame_info
 *
 * read header of xpress/lzx file to get info about frame
 * Read header of Xpress/LZX file to get info about frame.
 */
int attr_wof_frame_info(struct ntfs_inode *ni, struct ATTRIB *attr,
			struct runs_tree *run, u64 frame, u64 frames,
@@ -1227,20 +1216,20 @@ int attr_wof_frame_info(struct ntfs_inode *ni, struct ATTRIB *attr,
	__le64 *off64;

	if (ni->vfs_inode.i_size < 0x100000000ull) {
		/* file starts with array of 32 bit offsets */
		/* File starts with array of 32 bit offsets. */
		bytes_per_off = sizeof(__le32);
		vbo[1] = frame << 2;
		*vbo_data = frames << 2;
	} else {
		/* file starts with array of 64 bit offsets */
		/* File starts with array of 64 bit offsets. */
		bytes_per_off = sizeof(__le64);
		vbo[1] = frame << 3;
		*vbo_data = frames << 3;
	}

	/*
	 * read 4/8 bytes at [vbo - 4(8)] == offset where compressed frame starts
	 * read 4/8 bytes at [vbo] == offset where compressed frame ends
	 * Read 4/8 bytes at [vbo - 4(8)] == offset where compressed frame starts.
	 * Read 4/8 bytes at [vbo] == offset where compressed frame ends.
	 */
	if (!attr->non_res) {
		if (vbo[1] + bytes_per_off > le32_to_cpu(attr->res.data_size)) {
@@ -1329,7 +1318,7 @@ int attr_wof_frame_info(struct ntfs_inode *ni, struct ATTRIB *attr,
				off[0] = le64_to_cpu(*off64);
			}
		} else {
			/* two values in one page*/
			/* Two values in one page. */
			if (bytes_per_off == sizeof(__le32)) {
				off32 = Add2Ptr(addr, voff);
				off[0] = le32_to_cpu(off32[-1]);
@@ -1355,9 +1344,7 @@ int attr_wof_frame_info(struct ntfs_inode *ni, struct ATTRIB *attr,
#endif

/*
 * attr_is_frame_compressed
 *
 * This function is used to detect compressed frame
 * attr_is_frame_compressed - Used to detect compressed frame.
 */
int attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr,
			     CLST frame, CLST *clst_data)
@@ -1391,14 +1378,14 @@ int attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr,
	}

	if (lcn == SPARSE_LCN) {
		/* sparsed frame */
		/* Sparsed frame. */
		return 0;
	}

	if (clen >= clst_frame) {
		/*
		 * The frame is not compressed 'cause
		 * it does not contain any sparse clusters
		 * it does not contain any sparse clusters.
		 */
		*clst_data = clst_frame;
		return 0;
@@ -1409,8 +1396,8 @@ int attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr,
	*clst_data = clen;

	/*
	 * The frame is compressed if *clst_data + slen >= clst_frame
	 * Check next fragments
	 * The frame is compressed if *clst_data + slen >= clst_frame.
	 * Check next fragments.
	 */
	while ((vcn += clen) < alen) {
		vcn_next = vcn;
@@ -1433,8 +1420,8 @@ int attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr,
		} else {
			if (slen) {
				/*
				 * data_clusters + sparse_clusters =
				 * not enough for frame
				 * Data_clusters + sparse_clusters =
				 * not enough for frame.
				 */
				return -EINVAL;
			}
@@ -1445,11 +1432,11 @@ int attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr,
			if (!slen) {
				/*
				 * There is no sparsed clusters in this frame
				 * So it is not compressed
				 * so it is not compressed.
				 */
				*clst_data = clst_frame;
			} else {
				/*frame is compressed*/
				/* Frame is compressed. */
			}
			break;
		}
@@ -1459,10 +1446,9 @@ int attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr,
}

/*
 * attr_allocate_frame
 * attr_allocate_frame - Allocate/free clusters for @frame.
 *
 * allocate/free clusters for 'frame'
 * assumed: down_write(&ni->file.run_lock);
 * Assumed: down_write(&ni->file.run_lock);
 */
int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size,
			u64 new_valid)
@@ -1538,10 +1524,10 @@ int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size,
			goto out;
		}
		end = vcn + clst_data;
		/* run contains updated range [vcn + len : end) */
		/* Run contains updated range [vcn + len : end). */
	} else {
		CLST alen, hint = 0;
		/* Get the last lcn to allocate from */
		/* Get the last LCN to allocate from. */
		if (vcn + clst_data &&
		    !run_lookup_entry(run, vcn + clst_data - 1, &hint, NULL,
				      NULL)) {
@@ -1555,7 +1541,7 @@ int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size,
			goto out;

		end = vcn + len;
		/* run contains updated range [vcn + clst_data : end) */
		/* Run contains updated range [vcn + clst_data : end). */
	}

	total_size += (u64)len << sbi->cluster_bits;
@@ -1571,20 +1557,20 @@ int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size,
	mi_b->dirty = true;
	mark_inode_dirty(&ni->vfs_inode);

	/* stored [vcn : next_svcn) from [vcn : end) */
	/* Stored [vcn : next_svcn) from [vcn : end). */
	next_svcn = le64_to_cpu(attr->nres.evcn) + 1;

	if (end <= evcn1) {
		if (next_svcn == evcn1) {
			/* Normal way. update attribute and exit */
			/* Normal way. Update attribute and exit. */
			goto ok;
		}
		/* add new segment [next_svcn : evcn1 - next_svcn )*/
		/* Add new segment [next_svcn : evcn1 - next_svcn). */
		if (!ni->attr_list.size) {
			err = ni_create_attr_list(ni);
			if (err)
				goto out;
			/* layout of records is changed */
			/* Layout of records is changed. */
			le_b = NULL;
			attr_b = ni_find_attr(ni, NULL, &le_b, ATTR_DATA, NULL,
					      0, NULL, &mi_b);
@@ -1602,7 +1588,7 @@ int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size,

	svcn = evcn1;

	/* Estimate next attribute */
	/* Estimate next attribute. */
	attr = ni_find_attr(ni, attr, &le, ATTR_DATA, NULL, 0, &svcn, &mi);

	if (attr) {
@@ -1613,7 +1599,7 @@ int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size,
		if (end < next_svcn)
			end = next_svcn;
		while (end > evcn) {
			/* remove segment [svcn : evcn)*/
			/* Remove segment [svcn : evcn). */
			mi_remove_attr(mi, attr);

			if (!al_remove_le(ni, le)) {
@@ -1622,7 +1608,7 @@ int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size,
			}

			if (evcn + 1 >= alloc) {
				/* last attribute segment */
				/* Last attribute segment. */
				evcn1 = evcn + 1;
				goto ins_ext;
			}
@@ -1684,7 +1670,9 @@ int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size,
	return err;
}

/* Collapse range in file */
/*
 * attr_collapse_range - Collapse range in file.
 */
int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
{
	int err = 0;
@@ -1725,7 +1713,7 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
	}

	if ((vbo & mask) || (bytes & mask)) {
		/* allow to collapse only cluster aligned ranges */
		/* Allow to collapse only cluster aligned ranges. */
		return -EINVAL;
	}

@@ -1737,7 +1725,7 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
	if (vbo + bytes >= data_size) {
		u64 new_valid = min(ni->i_valid, vbo);

		/* Simple truncate file at 'vbo' */
		/* Simple truncate file at 'vbo'. */
		truncate_setsize(&ni->vfs_inode, vbo);
		err = attr_set_size(ni, ATTR_DATA, NULL, 0, &ni->file.run, vbo,
				    &new_valid, true, NULL);
@@ -1749,7 +1737,7 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
	}

	/*
	 * Enumerate all attribute segments and collapse
	 * Enumerate all attribute segments and collapse.
	 */
	alen = alloc_size >> sbi->cluster_bits;
	vcn = vbo >> sbi->cluster_bits;
@@ -1782,7 +1770,7 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)

	for (;;) {
		if (svcn >= end) {
			/* shift vcn */
			/* Shift VCN- */
			attr->nres.svcn = cpu_to_le64(svcn - len);
			attr->nres.evcn = cpu_to_le64(evcn1 - 1 - len);
			if (le) {
@@ -1793,7 +1781,7 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
		} else if (svcn < vcn || end < evcn1) {
			CLST vcn1, eat, next_svcn;

			/* collapse a part of this attribute segment */
			/* Collapse a part of this attribute segment. */
			err = attr_load_runs(attr, ni, run, &svcn);
			if (err)
				goto out;
@@ -1811,7 +1799,7 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
			}

			if (svcn >= vcn) {
				/* shift vcn */
				/* Shift VCN */
				attr->nres.svcn = cpu_to_le64(vcn);
				if (le) {
					le->vcn = attr->nres.svcn;
@@ -1832,7 +1820,7 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
				if (err)
					goto out;

				/* layout of records maybe changed */
				/* Layout of records maybe changed. */
				attr_b = NULL;
				le = al_find_ex(ni, NULL, ATTR_DATA, NULL, 0,
						&next_svcn);
@@ -1842,18 +1830,18 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
				}
			}

			/* free all allocated memory */
			/* Free all allocated memory. */
			run_truncate(run, 0);
		} else {
			u16 le_sz;
			u16 roff = le16_to_cpu(attr->nres.run_off);

			/*run==1 means unpack and deallocate*/
			/* run==1 means unpack and deallocate. */
			run_unpack_ex(RUN_DEALLOCATE, sbi, ni->mi.rno, svcn,
				      evcn1 - 1, svcn, Add2Ptr(attr, roff),
				      le32_to_cpu(attr->size) - roff);

			/* delete this attribute segment */
			/* Delete this attribute segment. */
			mi_remove_attr(mi, attr);
			if (!le)
				break;
@@ -1868,13 +1856,13 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
				break;

			if (!svcn) {
				/* Load next record that contains this attribute */
				/* Load next record that contains this attribute. */
				if (ni_load_mi(ni, le, &mi)) {
					err = -EINVAL;
					goto out;
				}

				/* Look for required attribute */
				/* Look for required attribute. */
				attr = mi_find_attr(mi, NULL, ATTR_DATA, NULL,
						    0, &le->id);
				if (!attr) {
@@ -1925,7 +1913,7 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
		attr_b->nres.total_size = cpu_to_le64(total_size);
	mi_b->dirty = true;

	/*update inode size*/
	/* Update inode size. */
	ni->i_valid = valid_size;
	ni->vfs_inode.i_size = data_size;
	inode_set_bytes(&ni->vfs_inode, total_size);
@@ -1940,7 +1928,11 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
	return err;
}

/* not for normal files */
/*
 * attr_punch_hole
 *
 * Not for normal files.
 */
int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size)
{
	int err = 0;
@@ -1981,7 +1973,7 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size)
	total_size = le64_to_cpu(attr_b->nres.total_size);

	if (vbo >= alloc_size) {
		// NOTE: it is allowed
		// NOTE: It is allowed.
		return 0;
	}

@@ -2004,7 +1996,7 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size)

	down_write(&ni->file.run_lock);
	/*
	 * Enumerate all attribute segments and punch hole where necessary
	 * Enumerate all attribute segments and punch hole where necessary.
	 */
	alen = alloc_size >> sbi->cluster_bits;
	vcn = vbo >> sbi->cluster_bits;
@@ -2050,7 +2042,7 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size)
			goto out;

		if (dealloc2 == dealloc) {
			/* looks like  the required range is already sparsed */
			/* Looks like the required range is already sparsed. */
		} else {
			if (!run_add_entry(run, vcn1, SPARSE_LCN, zero,
					   false)) {
@@ -2062,7 +2054,7 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size)
			if (err)
				goto out;
		}
		/* free all allocated memory */
		/* Free all allocated memory. */
		run_truncate(run, 0);

		if (evcn1 >= alen)
@@ -2082,7 +2074,7 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size)
	attr_b->nres.total_size = cpu_to_le64(total_size);
	mi_b->dirty = true;

	/*update inode size*/
	/* Update inode size. */
	inode_set_bytes(&ni->vfs_inode, total_size);
	ni->ni_flags |= NI_FLAG_UPDATE_PARENT;
	mark_inode_dirty(&ni->vfs_inode);
+31 −31
Original line number Diff line number Diff line
@@ -14,7 +14,11 @@
#include "ntfs.h"
#include "ntfs_fs.h"

/* Returns true if le is valid */
/*
 * al_is_valid_le
 *
 * Return: True if @le is valid.
 */
static inline bool al_is_valid_le(const struct ntfs_inode *ni,
				  struct ATTR_LIST_ENTRY *le)
{
@@ -101,8 +105,9 @@ int ntfs_load_attr_list(struct ntfs_inode *ni, struct ATTRIB *attr)
/*
 * al_enumerate
 *
 * Returns the next list 'le'
 * if 'le' is NULL then returns the first 'le'
 * Return:
 * * The next list le.
 * * If @le is NULL then return the first le.
 */
struct ATTR_LIST_ENTRY *al_enumerate(struct ntfs_inode *ni,
				     struct ATTR_LIST_ENTRY *le)
@@ -115,22 +120,22 @@ struct ATTR_LIST_ENTRY *al_enumerate(struct ntfs_inode *ni,
	} else {
		sz = le16_to_cpu(le->size);
		if (sz < sizeof(struct ATTR_LIST_ENTRY)) {
			/* Impossible 'cause we should not return such 'le' */
			/* Impossible 'cause we should not return such le. */
			return NULL;
		}
		le = Add2Ptr(le, sz);
	}

	/* Check boundary */
	/* Check boundary. */
	off = PtrOffset(ni->attr_list.le, le);
	if (off + sizeof(struct ATTR_LIST_ENTRY) > ni->attr_list.size) {
		// The regular end of list
		/* The regular end of list. */
		return NULL;
	}

	sz = le16_to_cpu(le->size);

	/* Check 'le' for errors */
	/* Check le for errors. */
	if (sz < sizeof(struct ATTR_LIST_ENTRY) ||
	    off + sz > ni->attr_list.size ||
	    sz < le->name_off + le->name_len * sizeof(short)) {
@@ -143,8 +148,9 @@ struct ATTR_LIST_ENTRY *al_enumerate(struct ntfs_inode *ni,
/*
 * al_find_le
 *
 * finds the first 'le' in the list which matches type, name and vcn
 * Returns NULL if not found
 * Find the first le in the list which matches type, name and VCN.
 *
 * Return: NULL if not found.
 */
struct ATTR_LIST_ENTRY *al_find_le(struct ntfs_inode *ni,
				   struct ATTR_LIST_ENTRY *le,
@@ -159,8 +165,9 @@ struct ATTR_LIST_ENTRY *al_find_le(struct ntfs_inode *ni,
/*
 * al_find_ex
 *
 * finds the first 'le' in the list which matches type, name and vcn
 * Returns NULL if not found
 * Find the first le in the list which matches type, name and VCN.
 *
 * Return: NULL if not found.
 */
struct ATTR_LIST_ENTRY *al_find_ex(struct ntfs_inode *ni,
				   struct ATTR_LIST_ENTRY *le,
@@ -174,7 +181,7 @@ struct ATTR_LIST_ENTRY *al_find_ex(struct ntfs_inode *ni,
		u64 le_vcn;
		int diff = le32_to_cpu(le->type) - type_in;

		/* List entries are sorted by type, name and vcn */
		/* List entries are sorted by type, name and VCN. */
		if (diff < 0)
			continue;

@@ -187,7 +194,7 @@ struct ATTR_LIST_ENTRY *al_find_ex(struct ntfs_inode *ni,
		le_vcn = le64_to_cpu(le->vcn);
		if (!le_vcn) {
			/*
			 * compare entry names only for entry with vcn == 0
			 * Compare entry names only for entry with vcn == 0.
			 */
			diff = ntfs_cmp_names(le_name(le), name_len, name,
					      name_len, ni->mi.sbi->upcase,
@@ -217,7 +224,7 @@ struct ATTR_LIST_ENTRY *al_find_ex(struct ntfs_inode *ni,
/*
 * al_find_le_to_insert
 *
 * finds the first list entry which matches type, name and vcn
 * Find the first list entry which matches type, name and VCN.
 */
static struct ATTR_LIST_ENTRY *al_find_le_to_insert(struct ntfs_inode *ni,
						    enum ATTR_TYPE type,
@@ -227,7 +234,7 @@ static struct ATTR_LIST_ENTRY *al_find_le_to_insert(struct ntfs_inode *ni,
	struct ATTR_LIST_ENTRY *le = NULL, *prev;
	u32 type_in = le32_to_cpu(type);

	/* List entries are sorted by type, name, vcn */
	/* List entries are sorted by type, name and VCN. */
	while ((le = al_enumerate(ni, prev = le))) {
		int diff = le32_to_cpu(le->type) - type_in;

@@ -239,7 +246,7 @@ static struct ATTR_LIST_ENTRY *al_find_le_to_insert(struct ntfs_inode *ni,

		if (!le->vcn) {
			/*
			 * compare entry names only for entry with vcn == 0
			 * Compare entry names only for entry with vcn == 0.
			 */
			diff = ntfs_cmp_names(le_name(le), le->name_len, name,
					      name_len, ni->mi.sbi->upcase,
@@ -261,7 +268,7 @@ static struct ATTR_LIST_ENTRY *al_find_le_to_insert(struct ntfs_inode *ni,
/*
 * al_add_le
 *
 * adds an "attribute list entry" to the list.
 * Add an "attribute list entry" to the list.
 */
int al_add_le(struct ntfs_inode *ni, enum ATTR_TYPE type, const __le16 *name,
	      u8 name_len, CLST svcn, __le16 id, const struct MFT_REF *ref,
@@ -335,9 +342,7 @@ int al_add_le(struct ntfs_inode *ni, enum ATTR_TYPE type, const __le16 *name,
}

/*
 * al_remove_le
 *
 * removes 'le' from attribute list
 * al_remove_le - Remove @le from attribute list.
 */
bool al_remove_le(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le)
{
@@ -361,9 +366,7 @@ bool al_remove_le(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le)
}

/*
 * al_delete_le
 *
 * deletes from the list the first 'le' which matches its parameters.
 * al_delete_le - Delete first le from the list which matches its parameters.
 */
bool al_delete_le(struct ntfs_inode *ni, enum ATTR_TYPE type, CLST vcn,
		  const __le16 *name, size_t name_len,
@@ -374,7 +377,7 @@ bool al_delete_le(struct ntfs_inode *ni, enum ATTR_TYPE type, CLST vcn,
	size_t off;
	typeof(ni->attr_list) *al = &ni->attr_list;

	/* Scan forward to the first 'le' that matches the input */
	/* Scan forward to the first le that matches the input. */
	le = al_find_ex(ni, NULL, type, name, name_len, &vcn);
	if (!le)
		return false;
@@ -405,9 +408,9 @@ bool al_delete_le(struct ntfs_inode *ni, enum ATTR_TYPE type, CLST vcn,
		goto next;
	}

	/* Save on stack the size of 'le' */
	/* Save on stack the size of 'le'. */
	size = le16_to_cpu(le->size);
	/* Delete 'le'. */
	/* Delete the le. */
	memmove(le, Add2Ptr(le, size), al->size - (off + size));

	al->size -= size;
@@ -416,9 +419,6 @@ bool al_delete_le(struct ntfs_inode *ni, enum ATTR_TYPE type, CLST vcn,
	return true;
}

/*
 * al_update
 */
int al_update(struct ntfs_inode *ni)
{
	int err;
@@ -429,8 +429,8 @@ int al_update(struct ntfs_inode *ni)
		return 0;

	/*
	 * attribute list increased on demand in al_add_le
	 * attribute list decreased here
	 * Attribute list increased on demand in al_add_le.
	 * Attribute list decreased here.
	 */
	err = attr_set_size(ni, ATTR_LIST, NULL, 0, &al->run, al->size, NULL,
			    false, &attr);
+3 −4
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
 * Copyright (C) 2019-2021 Paragon Software GmbH, All rights reserved.
 *
 */

#include <linux/blkdev.h>
#include <linux/buffer_head.h>
#include <linux/fs.h>
@@ -32,7 +33,7 @@ static const u8 zero_mask[] = { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0,
/*
 * are_bits_clear
 *
 * Returns true if all bits [bit, bit+nbits) are zeros "0"
 * Return: True if all bits [bit, bit+nbits) are zeros "0".
 */
bool are_bits_clear(const ulong *lmap, size_t bit, size_t nbits)
{
@@ -74,14 +75,13 @@ bool are_bits_clear(const ulong *lmap, size_t bit, size_t nbits)
	if (pos && (*map & fill_mask[pos]))
		return false;

	// All bits are zero
	return true;
}

/*
 * are_bits_set
 *
 * Returns true if all bits [bit, bit+nbits) are ones "1"
 * Return: True if all bits [bit, bit+nbits) are ones "1".
 */
bool are_bits_set(const ulong *lmap, size_t bit, size_t nbits)
{
@@ -130,6 +130,5 @@ bool are_bits_set(const ulong *lmap, size_t bit, size_t nbits)
			return false;
	}

	// All bits are ones
	return true;
}
+88 −113

File changed.

Preview size limit exceeded, changes collapsed.

+3 −2
Original line number Diff line number Diff line
@@ -3,7 +3,8 @@
 *
 * Copyright (C) 2019-2021 Paragon Software GmbH, All rights reserved.
 *
 * useful functions for debugging
 * Useful functions for debugging.
 *
 */

// clang-format off
@@ -33,7 +34,7 @@ void ntfs_inode_printk(struct inode *inode, const char *fmt, ...)
#endif

/*
 * Logging macros ( thanks Joe Perches <joe@perches.com> for implementation )
 * Logging macros. Thanks Joe Perches <joe@perches.com> for implementation.
 */

#define ntfs_err(sb, fmt, ...)  ntfs_printk(sb, KERN_ERR fmt, ##__VA_ARGS__)
Loading