Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 53d59aad authored by Anton Altaparmakov's avatar Anton Altaparmakov
Browse files

NTFS: Fix compilation when configured read-only.



- Add ifdef NTFS_RW around write specific code if fs/ntfs/runlist.[hc] and
  fs/ntfs/attrib.[hc].
- Minor bugfix to fs/ntfs/attrib.c::ntfs_attr_make_non_resident() where the
  runlist was not freed in all error cases.
- Add fs/ntfs/runlist.[hc]::ntfs_rl_find_vcn_nolock().

Signed-off-by: default avatarAnton Altaparmakov <aia21@cantab.net>
parent 1ef334d3
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -1057,6 +1057,8 @@ void ntfs_attr_put_search_ctx(ntfs_attr_search_ctx *ctx)
	return;
}

#ifdef NTFS_RW

/**
 * ntfs_attr_find_in_attrdef - find an attribute in the $AttrDef system file
 * @vol:	ntfs volume to which the attribute belongs
@@ -1243,6 +1245,13 @@ int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size)
 *	-ENOSPC	- Not enough disk space.
 *	-EINVAL	- Attribute not defined on the volume.
 *	-EIO	- I/o error or other error.
 * Note that -ENOSPC is also returned in the case that there is not enough
 * space in the mft record to do the conversion.  This can happen when the mft
 * record is already very full.  The caller is responsible for trying to make
 * space in the mft record and trying again.  FIXME: Do we need a separate
 * error return code for this kind of -ENOSPC or is it always worth trying
 * again in case the attribute may then fit in a resident state so no need to
 * make it non-resident at all?  Ho-hum...  (AIA)
 *
 * NOTE to self: No changes in the attribute list are required to move from
 *		 a resident to a non-resident attribute.
@@ -1520,13 +1529,13 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
rl_err_out:
	if (rl) {
		if (ntfs_cluster_free_from_rl(vol, rl) < 0) {
			ntfs_free(rl);
			ntfs_error(vol->sb, "Failed to release allocated "
					"cluster(s) in error code path.  Run "
					"chkdsk to recover the lost "
					"cluster(s).");
			NVolSetErrors(vol);
		}
		ntfs_free(rl);
page_err_out:
		unlock_page(page);
		page_cache_release(page);
@@ -1680,3 +1689,5 @@ int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val)
	ntfs_debug("Done.");
	return 0;
}

#endif /* NTFS_RW */
+4 −0
Original line number Diff line number Diff line
@@ -89,6 +89,8 @@ extern ntfs_attr_search_ctx *ntfs_attr_get_search_ctx(ntfs_inode *ni,
		MFT_RECORD *mrec);
extern void ntfs_attr_put_search_ctx(ntfs_attr_search_ctx *ctx);

#ifdef NTFS_RW

extern int ntfs_attr_size_bounds_check(const ntfs_volume *vol,
		const ATTR_TYPE type, const s64 size);
extern int ntfs_attr_can_be_non_resident(const ntfs_volume *vol,
@@ -103,4 +105,6 @@ extern int ntfs_attr_make_non_resident(ntfs_inode *ni);
extern int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt,
		const u8 val);

#endif /* NTFS_RW */

#endif /* _LINUX_NTFS_ATTRIB_H */
+0 −1
Original line number Diff line number Diff line
@@ -848,7 +848,6 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count,

	total_freed = real_freed = 0;

	/* This returns with ni->runlist locked for reading on success. */
	down_read(&ni->runlist.lock);
	rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, FALSE);
	if (IS_ERR(rl)) {
+35 −0
Original line number Diff line number Diff line
@@ -980,6 +980,39 @@ LCN ntfs_rl_vcn_to_lcn(const runlist_element *rl, const VCN vcn)
	return LCN_ENOENT;
}

#ifdef NTFS_RW

/**
 * ntfs_rl_find_vcn_nolock - find a vcn in a runlist
 * @rl:		runlist to search
 * @vcn:	vcn to find
 *
 * Find the virtual cluster number @vcn in the runlist @rl and return the
 * address of the runlist element containing the @vcn on success.
 *
 * Return NULL if @rl is NULL or @vcn is in an unmapped part/out of bounds of
 * the runlist.
 *
 * Locking: The runlist must be locked on entry.
 */
runlist_element *ntfs_rl_find_vcn_nolock(runlist_element *rl, const VCN vcn)
{
	BUG_ON(vcn < 0);
	if (unlikely(!rl || vcn < rl[0].vcn))
		return NULL;
	while (likely(rl->length)) {
		if (unlikely(vcn < rl[1].vcn)) {
			if (likely(rl->lcn >= LCN_HOLE))
				return rl;
			return NULL;
		}
		rl++;
	}
	if (likely(rl->lcn == LCN_ENOENT))
		return rl;
	return NULL;
}

/**
 * ntfs_get_nr_significant_bytes - get number of bytes needed to store a number
 * @n:		number for which to get the number of bytes for
@@ -1452,3 +1485,5 @@ int ntfs_rl_truncate_nolock(const ntfs_volume *vol, runlist *const runlist,
	ntfs_debug("Done.");
	return 0;
}

#endif /* NTFS_RW */
+8 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
 * runlist.h - Defines for runlist handling in NTFS Linux kernel driver.
 *	       Part of the Linux-NTFS project.
 *
 * Copyright (c) 2001-2004 Anton Altaparmakov
 * Copyright (c) 2001-2005 Anton Altaparmakov
 * Copyright (c) 2002 Richard Russon
 *
 * This program/include file is free software; you can redistribute it and/or
@@ -78,6 +78,11 @@ extern runlist_element *ntfs_mapping_pairs_decompress(const ntfs_volume *vol,

extern LCN ntfs_rl_vcn_to_lcn(const runlist_element *rl, const VCN vcn);

#ifdef NTFS_RW

extern runlist_element *ntfs_rl_find_vcn_nolock(runlist_element *rl,
		const VCN vcn);

extern int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol,
		const runlist_element *rl, const VCN start_vcn);

@@ -88,4 +93,6 @@ extern int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst,
extern int ntfs_rl_truncate_nolock(const ntfs_volume *vol,
		runlist *const runlist, const s64 new_length);

#endif /* NTFS_RW */

#endif /* _LINUX_NTFS_RUNLIST_H */