diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ntfs/attrib.c | 13 | ||||
-rw-r--r-- | fs/ntfs/attrib.h | 4 | ||||
-rw-r--r-- | fs/ntfs/lcnalloc.c | 1 | ||||
-rw-r--r-- | fs/ntfs/runlist.c | 35 | ||||
-rw-r--r-- | fs/ntfs/runlist.h | 9 |
5 files changed, 59 insertions, 3 deletions
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index 97e6fb047aa0..1b95f39234a3 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c @@ -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 @@ err_out: 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 @@ done: ntfs_debug("Done."); return 0; } + +#endif /* NTFS_RW */ diff --git a/fs/ntfs/attrib.h b/fs/ntfs/attrib.h index d73385198336..0e4ac6d3c0e7 100644 --- a/fs/ntfs/attrib.h +++ b/fs/ntfs/attrib.h @@ -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 */ diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c index 71bf08730b05..7087b5b0e6ce 100644 --- a/fs/ntfs/lcnalloc.c +++ b/fs/ntfs/lcnalloc.c @@ -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)) { diff --git a/fs/ntfs/runlist.c b/fs/ntfs/runlist.c index 3f479f176610..396d767c2cab 100644 --- a/fs/ntfs/runlist.c +++ b/fs/ntfs/runlist.c @@ -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 */ diff --git a/fs/ntfs/runlist.h b/fs/ntfs/runlist.h index 60c42f3a3fc4..cf5c1b44bea8 100644 --- a/fs/ntfs/runlist.h +++ b/fs/ntfs/runlist.h @@ -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 */ |