^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * attrib.c - NTFS attribute operations. Part of the Linux-NTFS project.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2001-2012 Anton Altaparmakov and Tuxera Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2002 Richard Russon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/buffer_head.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/swap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/writeback.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "attrib.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "layout.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "lcnalloc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "malloc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "mft.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "ntfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "types.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * ntfs_map_runlist_nolock - map (a part of) a runlist of an ntfs inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * @ni: ntfs inode for which to map (part of) a runlist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * @vcn: map runlist part containing this vcn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * @ctx: active attribute search context if present or NULL if not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * Map the part of a runlist containing the @vcn of the ntfs inode @ni.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * If @ctx is specified, it is an active search context of @ni and its base mft
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * record. This is needed when ntfs_map_runlist_nolock() encounters unmapped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * runlist fragments and allows their mapping. If you do not have the mft
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * record mapped, you can specify @ctx as NULL and ntfs_map_runlist_nolock()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * will perform the necessary mapping and unmapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * Note, ntfs_map_runlist_nolock() saves the state of @ctx on entry and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * restores it before returning. Thus, @ctx will be left pointing to the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * attribute on return as on entry. However, the actual pointers in @ctx may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * point to different memory locations on return, so you must remember to reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * any cached pointers from the @ctx, i.e. after the call to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * ntfs_map_runlist_nolock(), you will probably want to do:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * m = ctx->mrec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * a = ctx->attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * you cache ctx->mrec in a variable @m of type MFT_RECORD *.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Return 0 on success and -errno on error. There is one special error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * which is not an error as such. This is -ENOENT. It means that @vcn is out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * of bounds of the runlist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * Note the runlist can be NULL after this function returns if @vcn is zero and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * the attribute has zero allocated size, i.e. there simply is no runlist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * WARNING: If @ctx is supplied, regardless of whether success or failure is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * returned, you need to check IS_ERR(@ctx->mrec) and if 'true' the @ctx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * is no longer valid, i.e. you need to either call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * In that case PTR_ERR(@ctx->mrec) will give you the error code for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * why the mapping of the old inode failed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * Locking: - The runlist described by @ni must be locked for writing on entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * and is locked on return. Note the runlist will be modified.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * - If @ctx is NULL, the base mft record of @ni must not be mapped on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * entry and it will be left unmapped on return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * - If @ctx is not NULL, the base mft record must be mapped on entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * and it will be left mapped on return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, ntfs_attr_search_ctx *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) VCN end_vcn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ntfs_inode *base_ni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) MFT_RECORD *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) ATTR_RECORD *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) runlist_element *rl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct page *put_this_page = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) bool ctx_is_temporary, ctx_needs_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) ntfs_attr_search_ctx old_ctx = { NULL, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) ntfs_debug("Mapping runlist part containing vcn 0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) (unsigned long long)vcn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (!NInoAttr(ni))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) base_ni = ni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) base_ni = ni->ext.base_ntfs_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (!ctx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) ctx_is_temporary = ctx_needs_reset = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) m = map_mft_record(base_ni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (IS_ERR(m))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return PTR_ERR(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) ctx = ntfs_attr_get_search_ctx(base_ni, m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (unlikely(!ctx)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) VCN allocated_size_vcn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) BUG_ON(IS_ERR(ctx->mrec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) a = ctx->attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) BUG_ON(!a->non_resident);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ctx_is_temporary = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) read_lock_irqsave(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) allocated_size_vcn = ni->allocated_size >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) ni->vol->cluster_size_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) read_unlock_irqrestore(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (!a->data.non_resident.lowest_vcn && end_vcn <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) end_vcn = allocated_size_vcn - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * If we already have the attribute extent containing @vcn in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * @ctx, no need to look it up again. We slightly cheat in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * that if vcn exceeds the allocated size, we will refuse to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * map the runlist below, so there is definitely no need to get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * the right attribute extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (vcn >= allocated_size_vcn || (a->type == ni->type &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) a->name_length == ni->name_len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) !memcmp((u8*)a + le16_to_cpu(a->name_offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) ni->name, ni->name_len) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) sle64_to_cpu(a->data.non_resident.lowest_vcn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) <= vcn && end_vcn >= vcn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) ctx_needs_reset = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* Save the old search context. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) old_ctx = *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * If the currently mapped (extent) inode is not the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * base inode we will unmap it when we reinitialize the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * search context which means we need to get a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * reference to the page containing the mapped mft
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * record so we do not accidentally drop changes to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * mft record when it has not been marked dirty yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (old_ctx.base_ntfs_ino && old_ctx.ntfs_ino !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) old_ctx.base_ntfs_ino) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) put_this_page = old_ctx.ntfs_ino->page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) get_page(put_this_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * Reinitialize the search context so we can lookup the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * needed attribute extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ntfs_attr_reinit_search_ctx(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) ctx_needs_reset = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (ctx_needs_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) CASE_SENSITIVE, vcn, NULL, 0, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (err == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) BUG_ON(!ctx->attr->non_resident);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) a = ctx->attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * Only decompress the mapping pairs if @vcn is inside it. Otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * we get into problems when we try to map an out of bounds vcn because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * we then try to map the already mapped runlist fragment and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * ntfs_mapping_pairs_decompress() fails.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (unlikely(vcn && vcn >= end_vcn)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) err = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) rl = ntfs_mapping_pairs_decompress(ni->vol, a, ni->runlist.rl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (IS_ERR(rl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) err = PTR_ERR(rl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) ni->runlist.rl = rl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (ctx_is_temporary) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (likely(ctx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) ntfs_attr_put_search_ctx(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) unmap_mft_record(base_ni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) } else if (ctx_needs_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * If there is no attribute list, restoring the search context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * is accomplished simply by copying the saved context back over
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * the caller supplied context. If there is an attribute list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * things are more complicated as we need to deal with mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * of mft records and resulting potential changes in pointers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (NInoAttrList(base_ni)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * If the currently mapped (extent) inode is not the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * one we had before, we need to unmap it and map the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * old one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (ctx->ntfs_ino != old_ctx.ntfs_ino) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * If the currently mapped inode is not the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * base inode, unmap it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (ctx->base_ntfs_ino && ctx->ntfs_ino !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ctx->base_ntfs_ino) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) unmap_extent_mft_record(ctx->ntfs_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) ctx->mrec = ctx->base_mrec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) BUG_ON(!ctx->mrec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * If the old mapped inode is not the base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * inode, map it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (old_ctx.base_ntfs_ino &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) old_ctx.ntfs_ino !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) old_ctx.base_ntfs_ino) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) retry_map:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ctx->mrec = map_mft_record(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) old_ctx.ntfs_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * Something bad has happened. If out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * of memory retry till it succeeds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * Any other errors are fatal and we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * return the error code in ctx->mrec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * Let the caller deal with it... We
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * just need to fudge things so the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * caller can reinit and/or put the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * search context safely.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (IS_ERR(ctx->mrec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (PTR_ERR(ctx->mrec) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) -ENOMEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) goto retry_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) old_ctx.ntfs_ino =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) old_ctx.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) base_ntfs_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /* Update the changed pointers in the saved context. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (ctx->mrec != old_ctx.mrec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (!IS_ERR(ctx->mrec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) old_ctx.attr = (ATTR_RECORD*)(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) (u8*)ctx->mrec +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) ((u8*)old_ctx.attr -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) (u8*)old_ctx.mrec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) old_ctx.mrec = ctx->mrec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* Restore the search context to the saved one. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) *ctx = old_ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * We drop the reference on the page we took earlier. In the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * case that IS_ERR(ctx->mrec) is true this means we might lose
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * some changes to the mft record that had been made between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * the last time it was marked dirty/written out and now. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * at this stage is not a problem as the mapping error is fatal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * enough that the mft record cannot be written out anyway and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * the caller is very likely to shutdown the whole inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * immediately and mark the volume dirty for chkdsk to pick up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * the pieces anyway.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (put_this_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) put_page(put_this_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * ntfs_map_runlist - map (a part of) a runlist of an ntfs inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * @ni: ntfs inode for which to map (part of) a runlist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * @vcn: map runlist part containing this vcn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * Map the part of a runlist containing the @vcn of the ntfs inode @ni.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * Return 0 on success and -errno on error. There is one special error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * which is not an error as such. This is -ENOENT. It means that @vcn is out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * of bounds of the runlist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * Locking: - The runlist must be unlocked on entry and is unlocked on return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * - This function takes the runlist lock for writing and may modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * the runlist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) int ntfs_map_runlist(ntfs_inode *ni, VCN vcn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) down_write(&ni->runlist.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /* Make sure someone else didn't do the work while we were sleeping. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (likely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) <=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) LCN_RL_NOT_MAPPED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) err = ntfs_map_runlist_nolock(ni, vcn, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) up_write(&ni->runlist.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * ntfs_attr_vcn_to_lcn_nolock - convert a vcn into a lcn given an ntfs inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) * @ni: ntfs inode of the attribute whose runlist to search
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * @vcn: vcn to convert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * @write_locked: true if the runlist is locked for writing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * Find the virtual cluster number @vcn in the runlist of the ntfs attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * described by the ntfs inode @ni and return the corresponding logical cluster
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * number (lcn).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * If the @vcn is not mapped yet, the attempt is made to map the attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * extent containing the @vcn and the vcn to lcn conversion is retried.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * If @write_locked is true the caller has locked the runlist for writing and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * if false for reading.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * Since lcns must be >= 0, we use negative return codes with special meaning:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * Return code Meaning / Description
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * ==========================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * LCN_HOLE Hole / not allocated on disk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * LCN_ENOENT There is no such vcn in the runlist, i.e. @vcn is out of bounds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * LCN_ENOMEM Not enough memory to map runlist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * LCN_EIO Critical error (runlist/file is corrupt, i/o error, etc).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * Locking: - The runlist must be locked on entry and is left locked on return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * - If @write_locked is 'false', i.e. the runlist is locked for reading,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * the lock may be dropped inside the function so you cannot rely on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * the runlist still being the same when this function returns.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) const bool write_locked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) LCN lcn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) bool is_retry = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) BUG_ON(!ni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ni->mft_no, (unsigned long long)vcn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) write_locked ? "write" : "read");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) BUG_ON(!NInoNonResident(ni));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) BUG_ON(vcn < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (!ni->runlist.rl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) read_lock_irqsave(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (!ni->allocated_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) read_unlock_irqrestore(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return LCN_ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) read_unlock_irqrestore(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) retry_remap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /* Convert vcn to lcn. If that fails map the runlist and retry once. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) lcn = ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (likely(lcn >= LCN_HOLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) ntfs_debug("Done, lcn 0x%llx.", (long long)lcn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return lcn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (lcn != LCN_RL_NOT_MAPPED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (lcn != LCN_ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) lcn = LCN_EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) } else if (!is_retry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (!write_locked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) up_read(&ni->runlist.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) down_write(&ni->runlist.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (unlikely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) LCN_RL_NOT_MAPPED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) up_write(&ni->runlist.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) down_read(&ni->runlist.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) goto retry_remap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) err = ntfs_map_runlist_nolock(ni, vcn, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (!write_locked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) up_write(&ni->runlist.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) down_read(&ni->runlist.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (likely(!err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) is_retry = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) goto retry_remap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (err == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) lcn = LCN_ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) else if (err == -ENOMEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) lcn = LCN_ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) lcn = LCN_EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (lcn != LCN_ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) ntfs_error(ni->vol->sb, "Failed with error code %lli.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) (long long)lcn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return lcn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * ntfs_attr_find_vcn_nolock - find a vcn in the runlist of an ntfs inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * @ni: ntfs inode describing the runlist to search
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * @vcn: vcn to find
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * @ctx: active attribute search context if present or NULL if not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * Find the virtual cluster number @vcn in the runlist described by the ntfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * inode @ni and return the address of the runlist element containing the @vcn.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * If the @vcn is not mapped yet, the attempt is made to map the attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * extent containing the @vcn and the vcn to lcn conversion is retried.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * If @ctx is specified, it is an active search context of @ni and its base mft
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * record. This is needed when ntfs_attr_find_vcn_nolock() encounters unmapped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * runlist fragments and allows their mapping. If you do not have the mft
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * record mapped, you can specify @ctx as NULL and ntfs_attr_find_vcn_nolock()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * will perform the necessary mapping and unmapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * Note, ntfs_attr_find_vcn_nolock() saves the state of @ctx on entry and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * restores it before returning. Thus, @ctx will be left pointing to the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * attribute on return as on entry. However, the actual pointers in @ctx may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * point to different memory locations on return, so you must remember to reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) * any cached pointers from the @ctx, i.e. after the call to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * ntfs_attr_find_vcn_nolock(), you will probably want to do:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * m = ctx->mrec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * a = ctx->attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * you cache ctx->mrec in a variable @m of type MFT_RECORD *.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * Note you need to distinguish between the lcn of the returned runlist element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * being >= 0 and LCN_HOLE. In the later case you have to return zeroes on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * read and allocate clusters on write.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * Return the runlist element containing the @vcn on success and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) * ERR_PTR(-errno) on error. You need to test the return value with IS_ERR()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) * to decide if the return is success or failure and PTR_ERR() to get to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * error code if IS_ERR() is true.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * The possible error return codes are:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * -ENOENT - No such vcn in the runlist, i.e. @vcn is out of bounds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * -ENOMEM - Not enough memory to map runlist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * -EIO - Critical error (runlist/file is corrupt, i/o error, etc).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * WARNING: If @ctx is supplied, regardless of whether success or failure is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * returned, you need to check IS_ERR(@ctx->mrec) and if 'true' the @ctx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * is no longer valid, i.e. you need to either call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) * In that case PTR_ERR(@ctx->mrec) will give you the error code for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) * why the mapping of the old inode failed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) * Locking: - The runlist described by @ni must be locked for writing on entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * and is locked on return. Note the runlist may be modified when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * needed runlist fragments need to be mapped.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * - If @ctx is NULL, the base mft record of @ni must not be mapped on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * entry and it will be left unmapped on return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * - If @ctx is not NULL, the base mft record must be mapped on entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) * and it will be left mapped on return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) ntfs_attr_search_ctx *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) runlist_element *rl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) bool is_retry = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) BUG_ON(!ni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, with%s ctx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) ni->mft_no, (unsigned long long)vcn, ctx ? "" : "out");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) BUG_ON(!NInoNonResident(ni));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) BUG_ON(vcn < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (!ni->runlist.rl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) read_lock_irqsave(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (!ni->allocated_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) read_unlock_irqrestore(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return ERR_PTR(-ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) read_unlock_irqrestore(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) retry_remap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) rl = ni->runlist.rl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (likely(rl && vcn >= rl[0].vcn)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) while (likely(rl->length)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (unlikely(vcn < rl[1].vcn)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (likely(rl->lcn >= LCN_HOLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) ntfs_debug("Done.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return rl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) rl++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (likely(rl->lcn != LCN_RL_NOT_MAPPED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (likely(rl->lcn == LCN_ENOENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) err = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (!err && !is_retry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) * If the search context is invalid we cannot map the unmapped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * region.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (IS_ERR(ctx->mrec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) err = PTR_ERR(ctx->mrec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) * The @vcn is in an unmapped region, map the runlist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) * and retry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) err = ntfs_map_runlist_nolock(ni, vcn, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (likely(!err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) is_retry = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) goto retry_remap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (err == -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) } else if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (err != -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) ntfs_error(ni->vol->sb, "Failed with error code %i.", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * ntfs_attr_find - find (next) attribute in mft record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * @type: attribute type to find
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) * @name: attribute name to find (optional, i.e. NULL means don't care)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * @name_len: attribute name length (only needed if @name present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * @ic: IGNORE_CASE or CASE_SENSITIVE (ignored if @name not present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) * @val: attribute value to find (optional, resident attributes only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) * @val_len: attribute value length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) * @ctx: search context with mft record and attribute to search from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) * You should not need to call this function directly. Use ntfs_attr_lookup()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) * instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * ntfs_attr_find() takes a search context @ctx as parameter and searches the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) * mft record specified by @ctx->mrec, beginning at @ctx->attr, for an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) * attribute of @type, optionally @name and @val.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * If the attribute is found, ntfs_attr_find() returns 0 and @ctx->attr will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * point to the found attribute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * If the attribute is not found, ntfs_attr_find() returns -ENOENT and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * @ctx->attr will point to the attribute before which the attribute being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * searched for would need to be inserted if such an action were to be desired.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * On actual error, ntfs_attr_find() returns -EIO. In this case @ctx->attr is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * undefined and in particular do not rely on it not changing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) * If @ctx->is_first is 'true', the search begins with @ctx->attr itself. If it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) * is 'false', the search begins after @ctx->attr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) * If @ic is IGNORE_CASE, the @name comparisson is not case sensitive and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * @ctx->ntfs_ino must be set to the ntfs inode to which the mft record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * @ctx->mrec belongs. This is so we can get at the ntfs volume and hence at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * the upcase table. If @ic is CASE_SENSITIVE, the comparison is case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * sensitive. When @name is present, @name_len is the @name length in Unicode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) * characters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * If @name is not present (NULL), we assume that the unnamed attribute is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * being searched for.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) * Finally, the resident attribute value @val is looked for, if present. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * @val is not present (NULL), @val_len is ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * ntfs_attr_find() only searches the specified mft record and it ignores the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * presence of an attribute list attribute (unless it is the one being searched
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) * for, obviously). If you need to take attribute lists into consideration,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * use ntfs_attr_lookup() instead (see below). This also means that you cannot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * use ntfs_attr_find() to search for extent records of non-resident
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) * attributes, as extents with lowest_vcn != 0 are usually described by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) * attribute list attribute only. - Note that it is possible that the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) * extent is only in the attribute list while the last extent is in the base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) * mft record, so do not rely on being able to find the first extent in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) * base mft record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) * Warning: Never use @val when looking for attribute types which can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) * non-resident as this most likely will result in a crash!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) static int ntfs_attr_find(const ATTR_TYPE type, const ntfschar *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) const u32 name_len, const IGNORE_CASE_BOOL ic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) const u8 *val, const u32 val_len, ntfs_attr_search_ctx *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) ATTR_RECORD *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) ntfs_volume *vol = ctx->ntfs_ino->vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) ntfschar *upcase = vol->upcase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) u32 upcase_len = vol->upcase_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) * Iterate over attributes in mft record starting at @ctx->attr, or the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * attribute following that, if @ctx->is_first is 'true'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (ctx->is_first) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) a = ctx->attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) ctx->is_first = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) a = (ATTR_RECORD*)((u8*)ctx->attr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) le32_to_cpu(ctx->attr->length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) for (;; a = (ATTR_RECORD*)((u8*)a + le32_to_cpu(a->length))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if ((u8*)a < (u8*)ctx->mrec || (u8*)a > (u8*)ctx->mrec +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) le32_to_cpu(ctx->mrec->bytes_allocated))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) ctx->attr = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (unlikely(le32_to_cpu(a->type) > le32_to_cpu(type) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) a->type == AT_END))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (unlikely(!a->length))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (a->type != type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) * If @name is present, compare the two names. If @name is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) * missing, assume we want an unnamed attribute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (!name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /* The search failed if the found attribute is named. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (a->name_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) } else if (!ntfs_are_names_equal(name, name_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) (ntfschar*)((u8*)a + le16_to_cpu(a->name_offset)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) a->name_length, ic, upcase, upcase_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) register int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) rc = ntfs_collate_names(name, name_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) (ntfschar*)((u8*)a +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) le16_to_cpu(a->name_offset)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) a->name_length, 1, IGNORE_CASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) upcase, upcase_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) * If @name collates before a->name, there is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) * matching attribute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (rc == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) /* If the strings are not equal, continue search. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) rc = ntfs_collate_names(name, name_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) (ntfschar*)((u8*)a +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) le16_to_cpu(a->name_offset)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) a->name_length, 1, CASE_SENSITIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) upcase, upcase_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if (rc == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * The names match or @name not present and attribute is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * unnamed. If no @val specified, we have found the attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * and are done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) /* @val is present; compare values. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) register int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) rc = memcmp(val, (u8*)a + le16_to_cpu(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) a->data.resident.value_offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) min_t(u32, val_len, le32_to_cpu(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) a->data.resident.value_length)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) * If @val collates before the current attribute's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * value, there is no matching attribute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) register u32 avl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) avl = le32_to_cpu(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) a->data.resident.value_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (val_len == avl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (val_len < avl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) } else if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) ntfs_error(vol->sb, "Inode is corrupt. Run chkdsk.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) NVolSetErrors(vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * load_attribute_list - load an attribute list into memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) * @vol: ntfs volume from which to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) * @runlist: runlist of the attribute list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) * @al_start: destination buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) * @size: size of the destination buffer in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) * @initialized_size: initialized size of the attribute list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) * Walk the runlist @runlist and load all clusters from it copying them into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) * the linear buffer @al. The maximum number of bytes copied to @al is @size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) * bytes. Note, @size does not need to be a multiple of the cluster size. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) * @initialized_size is less than @size, the region in @al between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) * @initialized_size and @size will be zeroed and not read from disk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * Return 0 on success or -errno on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) int load_attribute_list(ntfs_volume *vol, runlist *runlist, u8 *al_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) const s64 size, const s64 initialized_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) LCN lcn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) u8 *al = al_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) u8 *al_end = al + initialized_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) runlist_element *rl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct super_block *sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) unsigned long block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) unsigned long block, max_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) unsigned char block_size_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) ntfs_debug("Entering.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) if (!vol || !runlist || !al || size <= 0 || initialized_size < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) initialized_size > size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (!initialized_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) memset(al, 0, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) sb = vol->sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) block_size = sb->s_blocksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) block_size_bits = sb->s_blocksize_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) down_read(&runlist->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) rl = runlist->rl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (!rl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) ntfs_error(sb, "Cannot read attribute list since runlist is "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) "missing.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) /* Read all clusters specified by the runlist one run at a time. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) while (rl->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) lcn = ntfs_rl_vcn_to_lcn(rl, rl->vcn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) ntfs_debug("Reading vcn = 0x%llx, lcn = 0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) (unsigned long long)rl->vcn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) (unsigned long long)lcn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) /* The attribute list cannot be sparse. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (lcn < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) ntfs_error(sb, "ntfs_rl_vcn_to_lcn() failed. Cannot "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) "read attribute list.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) block = lcn << vol->cluster_size_bits >> block_size_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) /* Read the run from device in chunks of block_size bytes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) max_block = block + (rl->length << vol->cluster_size_bits >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) block_size_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) ntfs_debug("max_block = 0x%lx.", max_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) ntfs_debug("Reading block = 0x%lx.", block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) bh = sb_bread(sb, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) if (!bh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) ntfs_error(sb, "sb_bread() failed. Cannot "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) "read attribute list.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (al + block_size >= al_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) goto do_final;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) memcpy(al, bh->b_data, block_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) al += block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) } while (++block < max_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) rl++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (initialized_size < size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) initialize:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) memset(al_start + initialized_size, 0, size - initialized_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) up_read(&runlist->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) do_final:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (al < al_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * Partial block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) * Note: The attribute list can be smaller than its allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) * by multiple clusters. This has been encountered by at least
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) * two people running Windows XP, thus we cannot do any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) * truncation sanity checking here. (AIA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) memcpy(al, bh->b_data, al_end - al);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (initialized_size < size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) goto initialize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) /* Real overflow! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) ntfs_error(sb, "Attribute list buffer overflow. Read attribute list "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) "is truncated.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) * ntfs_external_attr_find - find an attribute in the attribute list of an inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) * @type: attribute type to find
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) * @name: attribute name to find (optional, i.e. NULL means don't care)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) * @name_len: attribute name length (only needed if @name present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) * @ic: IGNORE_CASE or CASE_SENSITIVE (ignored if @name not present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) * @lowest_vcn: lowest vcn to find (optional, non-resident attributes only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) * @val: attribute value to find (optional, resident attributes only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) * @val_len: attribute value length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) * @ctx: search context with mft record and attribute to search from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) * You should not need to call this function directly. Use ntfs_attr_lookup()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) * Find an attribute by searching the attribute list for the corresponding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) * attribute list entry. Having found the entry, map the mft record if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) * attribute is in a different mft record/inode, ntfs_attr_find() the attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) * in there and return it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) * On first search @ctx->ntfs_ino must be the base mft record and @ctx must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) * have been obtained from a call to ntfs_attr_get_search_ctx(). On subsequent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) * calls @ctx->ntfs_ino can be any extent inode, too (@ctx->base_ntfs_ino is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) * then the base inode).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) * After finishing with the attribute/mft record you need to call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) * ntfs_attr_put_search_ctx() to cleanup the search context (unmapping any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) * mapped inodes, etc).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) * If the attribute is found, ntfs_external_attr_find() returns 0 and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) * @ctx->attr will point to the found attribute. @ctx->mrec will point to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) * mft record in which @ctx->attr is located and @ctx->al_entry will point to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) * the attribute list entry for the attribute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) * If the attribute is not found, ntfs_external_attr_find() returns -ENOENT and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) * @ctx->attr will point to the attribute in the base mft record before which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) * the attribute being searched for would need to be inserted if such an action
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) * were to be desired. @ctx->mrec will point to the mft record in which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) * @ctx->attr is located and @ctx->al_entry will point to the attribute list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) * entry of the attribute before which the attribute being searched for would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) * need to be inserted if such an action were to be desired.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * Thus to insert the not found attribute, one wants to add the attribute to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) * @ctx->mrec (the base mft record) and if there is not enough space, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) * attribute should be placed in a newly allocated extent mft record. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) * attribute list entry for the inserted attribute should be inserted in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) * attribute list attribute at @ctx->al_entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) * On actual error, ntfs_external_attr_find() returns -EIO. In this case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) * @ctx->attr is undefined and in particular do not rely on it not changing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) static int ntfs_external_attr_find(const ATTR_TYPE type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) const ntfschar *name, const u32 name_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) const IGNORE_CASE_BOOL ic, const VCN lowest_vcn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) const u8 *val, const u32 val_len, ntfs_attr_search_ctx *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) ntfs_inode *base_ni, *ni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) ntfs_volume *vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) ATTR_LIST_ENTRY *al_entry, *next_al_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) u8 *al_start, *al_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) ATTR_RECORD *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) ntfschar *al_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) u32 al_name_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) static const char *es = " Unmount and run chkdsk.";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) ni = ctx->ntfs_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) base_ni = ctx->base_ntfs_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) ntfs_debug("Entering for inode 0x%lx, type 0x%x.", ni->mft_no, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (!base_ni) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) /* First call happens with the base mft record. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) base_ni = ctx->base_ntfs_ino = ctx->ntfs_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) ctx->base_mrec = ctx->mrec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (ni == base_ni)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) ctx->base_attr = ctx->attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (type == AT_END)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) goto not_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) vol = base_ni->vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) al_start = base_ni->attr_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) al_end = al_start + base_ni->attr_list_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) if (!ctx->al_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) ctx->al_entry = (ATTR_LIST_ENTRY*)al_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) * Iterate over entries in attribute list starting at @ctx->al_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) * or the entry following that, if @ctx->is_first is 'true'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (ctx->is_first) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) al_entry = ctx->al_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) ctx->is_first = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) al_entry = (ATTR_LIST_ENTRY*)((u8*)ctx->al_entry +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) le16_to_cpu(ctx->al_entry->length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) for (;; al_entry = next_al_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) /* Out of bounds check. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if ((u8*)al_entry < base_ni->attr_list ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) (u8*)al_entry > al_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) break; /* Inode is corrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) ctx->al_entry = al_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) /* Catch the end of the attribute list. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) if ((u8*)al_entry == al_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) goto not_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) if (!al_entry->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) if ((u8*)al_entry + 6 > al_end || (u8*)al_entry +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) le16_to_cpu(al_entry->length) > al_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) next_al_entry = (ATTR_LIST_ENTRY*)((u8*)al_entry +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) le16_to_cpu(al_entry->length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) if (le32_to_cpu(al_entry->type) > le32_to_cpu(type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) goto not_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if (type != al_entry->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) * If @name is present, compare the two names. If @name is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) * missing, assume we want an unnamed attribute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) al_name_len = al_entry->name_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) al_name = (ntfschar*)((u8*)al_entry + al_entry->name_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (!name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) if (al_name_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) goto not_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) } else if (!ntfs_are_names_equal(al_name, al_name_len, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) name_len, ic, vol->upcase, vol->upcase_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) register int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) rc = ntfs_collate_names(name, name_len, al_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) al_name_len, 1, IGNORE_CASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) vol->upcase, vol->upcase_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) * If @name collates before al_name, there is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) * matching attribute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) if (rc == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) goto not_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) /* If the strings are not equal, continue search. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) * FIXME: Reverse engineering showed 0, IGNORE_CASE but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) * that is inconsistent with ntfs_attr_find(). The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) * subsequent rc checks were also different. Perhaps I
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) * made a mistake in one of the two. Need to recheck
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) * which is correct or at least see what is going on...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) * (AIA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) rc = ntfs_collate_names(name, name_len, al_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) al_name_len, 1, CASE_SENSITIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) vol->upcase, vol->upcase_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (rc == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) goto not_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) * The names match or @name not present and attribute is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) * unnamed. Now check @lowest_vcn. Continue search if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) * next attribute list entry still fits @lowest_vcn. Otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) * we have reached the right one or the search has failed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (lowest_vcn && (u8*)next_al_entry >= al_start &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) (u8*)next_al_entry + 6 < al_end &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) (u8*)next_al_entry + le16_to_cpu(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) next_al_entry->length) <= al_end &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) sle64_to_cpu(next_al_entry->lowest_vcn) <=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) lowest_vcn &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) next_al_entry->type == al_entry->type &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) next_al_entry->name_length == al_name_len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) ntfs_are_names_equal((ntfschar*)((u8*)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) next_al_entry +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) next_al_entry->name_offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) next_al_entry->name_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) al_name, al_name_len, CASE_SENSITIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) vol->upcase, vol->upcase_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (MREF_LE(al_entry->mft_reference) == ni->mft_no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (MSEQNO_LE(al_entry->mft_reference) != ni->seq_no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) ntfs_error(vol->sb, "Found stale mft "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) "reference in attribute list "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) "of base inode 0x%lx.%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) base_ni->mft_no, es);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) } else { /* Mft references do not match. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) /* If there is a mapped record unmap it first. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) if (ni != base_ni)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) unmap_extent_mft_record(ni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) /* Do we want the base record back? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) if (MREF_LE(al_entry->mft_reference) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) base_ni->mft_no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) ni = ctx->ntfs_ino = base_ni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) ctx->mrec = ctx->base_mrec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) /* We want an extent record. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) ctx->mrec = map_extent_mft_record(base_ni,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) le64_to_cpu(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) al_entry->mft_reference), &ni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) if (IS_ERR(ctx->mrec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) ntfs_error(vol->sb, "Failed to map "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) "extent mft record "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) "0x%lx of base inode "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) "0x%lx.%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) MREF_LE(al_entry->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) mft_reference),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) base_ni->mft_no, es);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) err = PTR_ERR(ctx->mrec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) if (err == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) /* Cause @ctx to be sanitized below. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) ni = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) ctx->ntfs_ino = ni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) le16_to_cpu(ctx->mrec->attrs_offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) * ctx->vfs_ino, ctx->mrec, and ctx->attr now point to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) * mft record containing the attribute represented by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) * current al_entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) * We could call into ntfs_attr_find() to find the right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) * attribute in this mft record but this would be less
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) * efficient and not quite accurate as ntfs_attr_find() ignores
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) * the attribute instance numbers for example which become
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) * important when one plays with attribute lists. Also,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) * because a proper match has been found in the attribute list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) * entry above, the comparison can now be optimized. So it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) * worth re-implementing a simplified ntfs_attr_find() here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) a = ctx->attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) * Use a manual loop so we can still use break and continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) * with the same meanings as above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) do_next_attr_loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if ((u8*)a < (u8*)ctx->mrec || (u8*)a > (u8*)ctx->mrec +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) le32_to_cpu(ctx->mrec->bytes_allocated))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) if (a->type == AT_END)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (!a->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (al_entry->instance != a->instance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) goto do_next_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) * If the type and/or the name are mismatched between the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) * attribute list entry and the attribute record, there is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) * corruption so we break and return error EIO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (al_entry->type != a->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (!ntfs_are_names_equal((ntfschar*)((u8*)a +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) le16_to_cpu(a->name_offset)), a->name_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) al_name, al_name_len, CASE_SENSITIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) vol->upcase, vol->upcase_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) ctx->attr = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) * If no @val specified or @val specified and it matches, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) * have found it!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (!val || (!a->non_resident && le32_to_cpu(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) a->data.resident.value_length) == val_len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) !memcmp((u8*)a +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) le16_to_cpu(a->data.resident.value_offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) val, val_len))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) ntfs_debug("Done, found.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) do_next_attr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) /* Proceed to the next attribute in the current mft record. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) a = (ATTR_RECORD*)((u8*)a + le32_to_cpu(a->length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) goto do_next_attr_loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) ntfs_error(vol->sb, "Base inode 0x%lx contains corrupt "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) "attribute list attribute.%s", base_ni->mft_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) es);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (ni != base_ni) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) if (ni)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) unmap_extent_mft_record(ni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) ctx->ntfs_ino = base_ni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) ctx->mrec = ctx->base_mrec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) ctx->attr = ctx->base_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) if (err != -ENOMEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) NVolSetErrors(vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) not_found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) * If we were looking for AT_END, we reset the search context @ctx and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) * use ntfs_attr_find() to seek to the end of the base mft record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (type == AT_END) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) ntfs_attr_reinit_search_ctx(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) return ntfs_attr_find(AT_END, name, name_len, ic, val, val_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) * The attribute was not found. Before we return, we want to ensure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) * @ctx->mrec and @ctx->attr indicate the position at which the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) * attribute should be inserted in the base mft record. Since we also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) * want to preserve @ctx->al_entry we cannot reinitialize the search
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) * context using ntfs_attr_reinit_search_ctx() as this would set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) * @ctx->al_entry to NULL. Thus we do the necessary bits manually (see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) * ntfs_attr_init_search_ctx() below). Note, we _only_ preserve
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) * @ctx->al_entry as the remaining fields (base_*) are identical to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) * their non base_ counterparts and we cannot set @ctx->base_attr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) * correctly yet as we do not know what @ctx->attr will be set to by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) * the call to ntfs_attr_find() below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (ni != base_ni)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) unmap_extent_mft_record(ni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) ctx->mrec = ctx->base_mrec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) le16_to_cpu(ctx->mrec->attrs_offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) ctx->is_first = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) ctx->ntfs_ino = base_ni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) ctx->base_ntfs_ino = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) ctx->base_mrec = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) ctx->base_attr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) * In case there are multiple matches in the base mft record, need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) * keep enumerating until we get an attribute not found response (or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) * another error), otherwise we would keep returning the same attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) * over and over again and all programs using us for enumeration would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) * lock up in a tight loop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) err = ntfs_attr_find(type, name, name_len, ic, val, val_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) } while (!err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) ntfs_debug("Done, not found.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) * ntfs_attr_lookup - find an attribute in an ntfs inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) * @type: attribute type to find
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) * @name: attribute name to find (optional, i.e. NULL means don't care)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) * @name_len: attribute name length (only needed if @name present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) * @ic: IGNORE_CASE or CASE_SENSITIVE (ignored if @name not present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) * @lowest_vcn: lowest vcn to find (optional, non-resident attributes only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) * @val: attribute value to find (optional, resident attributes only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) * @val_len: attribute value length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) * @ctx: search context with mft record and attribute to search from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) * Find an attribute in an ntfs inode. On first search @ctx->ntfs_ino must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) * be the base mft record and @ctx must have been obtained from a call to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) * ntfs_attr_get_search_ctx().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) * This function transparently handles attribute lists and @ctx is used to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) * continue searches where they were left off at.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) * After finishing with the attribute/mft record you need to call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) * ntfs_attr_put_search_ctx() to cleanup the search context (unmapping any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) * mapped inodes, etc).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) * Return 0 if the search was successful and -errno if not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) * When 0, @ctx->attr is the found attribute and it is in mft record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) * @ctx->mrec. If an attribute list attribute is present, @ctx->al_entry is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) * the attribute list entry of the found attribute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) * When -ENOENT, @ctx->attr is the attribute which collates just after the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) * attribute being searched for, i.e. if one wants to add the attribute to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) * mft record this is the correct place to insert it into. If an attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) * list attribute is present, @ctx->al_entry is the attribute list entry which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) * collates just after the attribute list entry of the attribute being searched
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) * for, i.e. if one wants to add the attribute to the mft record this is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) * correct place to insert its attribute list entry into.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) * When -errno != -ENOENT, an error occurred during the lookup. @ctx->attr is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) * then undefined and in particular you should not rely on it not changing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) int ntfs_attr_lookup(const ATTR_TYPE type, const ntfschar *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) const u32 name_len, const IGNORE_CASE_BOOL ic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) const VCN lowest_vcn, const u8 *val, const u32 val_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) ntfs_attr_search_ctx *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) ntfs_inode *base_ni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) ntfs_debug("Entering.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) BUG_ON(IS_ERR(ctx->mrec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) if (ctx->base_ntfs_ino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) base_ni = ctx->base_ntfs_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) base_ni = ctx->ntfs_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) /* Sanity check, just for debugging really. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) BUG_ON(!base_ni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) if (!NInoAttrList(base_ni) || type == AT_ATTRIBUTE_LIST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) return ntfs_attr_find(type, name, name_len, ic, val, val_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) return ntfs_external_attr_find(type, name, name_len, ic, lowest_vcn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) val, val_len, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) * ntfs_attr_init_search_ctx - initialize an attribute search context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) * @ctx: attribute search context to initialize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) * @ni: ntfs inode with which to initialize the search context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) * @mrec: mft record with which to initialize the search context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) * Initialize the attribute search context @ctx with @ni and @mrec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) static inline void ntfs_attr_init_search_ctx(ntfs_attr_search_ctx *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) ntfs_inode *ni, MFT_RECORD *mrec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) *ctx = (ntfs_attr_search_ctx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) .mrec = mrec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) /* Sanity checks are performed elsewhere. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) .attr = (ATTR_RECORD*)((u8*)mrec +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) le16_to_cpu(mrec->attrs_offset)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) .is_first = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) .ntfs_ino = ni,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) * ntfs_attr_reinit_search_ctx - reinitialize an attribute search context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) * @ctx: attribute search context to reinitialize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) * Reinitialize the attribute search context @ctx, unmapping an associated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) * extent mft record if present, and initialize the search context again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) * This is used when a search for a new attribute is being started to reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) * the search context to the beginning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) void ntfs_attr_reinit_search_ctx(ntfs_attr_search_ctx *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) if (likely(!ctx->base_ntfs_ino)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) /* No attribute list. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) ctx->is_first = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) /* Sanity checks are performed elsewhere. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) le16_to_cpu(ctx->mrec->attrs_offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) * This needs resetting due to ntfs_external_attr_find() which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) * can leave it set despite having zeroed ctx->base_ntfs_ino.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) ctx->al_entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) } /* Attribute list. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) if (ctx->ntfs_ino != ctx->base_ntfs_ino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) unmap_extent_mft_record(ctx->ntfs_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) ntfs_attr_init_search_ctx(ctx, ctx->base_ntfs_ino, ctx->base_mrec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) * ntfs_attr_get_search_ctx - allocate/initialize a new attribute search context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) * @ni: ntfs inode with which to initialize the search context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) * @mrec: mft record with which to initialize the search context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) * Allocate a new attribute search context, initialize it with @ni and @mrec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) * and return it. Return NULL if allocation failed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) ntfs_attr_search_ctx *ntfs_attr_get_search_ctx(ntfs_inode *ni, MFT_RECORD *mrec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) ntfs_attr_search_ctx *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) ctx = kmem_cache_alloc(ntfs_attr_ctx_cache, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) if (ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) ntfs_attr_init_search_ctx(ctx, ni, mrec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) return ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) * ntfs_attr_put_search_ctx - release an attribute search context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) * @ctx: attribute search context to free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) * Release the attribute search context @ctx, unmapping an associated extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) * mft record if present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) void ntfs_attr_put_search_ctx(ntfs_attr_search_ctx *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) if (ctx->base_ntfs_ino && ctx->ntfs_ino != ctx->base_ntfs_ino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) unmap_extent_mft_record(ctx->ntfs_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) kmem_cache_free(ntfs_attr_ctx_cache, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) #ifdef NTFS_RW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) * ntfs_attr_find_in_attrdef - find an attribute in the $AttrDef system file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) * @vol: ntfs volume to which the attribute belongs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) * @type: attribute type which to find
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) * Search for the attribute definition record corresponding to the attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) * @type in the $AttrDef system file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) * Return the attribute type definition record if found and NULL if not found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) static ATTR_DEF *ntfs_attr_find_in_attrdef(const ntfs_volume *vol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) const ATTR_TYPE type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) ATTR_DEF *ad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) BUG_ON(!vol->attrdef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) BUG_ON(!type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) for (ad = vol->attrdef; (u8*)ad - (u8*)vol->attrdef <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) vol->attrdef_size && ad->type; ++ad) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) /* We have not found it yet, carry on searching. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) if (likely(le32_to_cpu(ad->type) < le32_to_cpu(type)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) /* We found the attribute; return it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) if (likely(ad->type == type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) return ad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) /* We have gone too far already. No point in continuing. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) /* Attribute not found. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) ntfs_debug("Attribute type 0x%x not found in $AttrDef.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) le32_to_cpu(type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) * ntfs_attr_size_bounds_check - check a size of an attribute type for validity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) * @vol: ntfs volume to which the attribute belongs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) * @type: attribute type which to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) * @size: size which to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) * Check whether the @size in bytes is valid for an attribute of @type on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) * ntfs volume @vol. This information is obtained from $AttrDef system file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) * Return 0 if valid, -ERANGE if not valid, or -ENOENT if the attribute is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) * listed in $AttrDef.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) int ntfs_attr_size_bounds_check(const ntfs_volume *vol, const ATTR_TYPE type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) const s64 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) ATTR_DEF *ad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) BUG_ON(size < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) * $ATTRIBUTE_LIST has a maximum size of 256kiB, but this is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) * listed in $AttrDef.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) if (unlikely(type == AT_ATTRIBUTE_LIST && size > 256 * 1024))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) /* Get the $AttrDef entry for the attribute @type. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) ad = ntfs_attr_find_in_attrdef(vol, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) if (unlikely(!ad))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) /* Do the bounds check. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) if (((sle64_to_cpu(ad->min_size) > 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) size < sle64_to_cpu(ad->min_size)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) ((sle64_to_cpu(ad->max_size) > 0) && size >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) sle64_to_cpu(ad->max_size)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) * ntfs_attr_can_be_non_resident - check if an attribute can be non-resident
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) * @vol: ntfs volume to which the attribute belongs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) * @type: attribute type which to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) * Check whether the attribute of @type on the ntfs volume @vol is allowed to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) * be non-resident. This information is obtained from $AttrDef system file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) * Return 0 if the attribute is allowed to be non-resident, -EPERM if not, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) * -ENOENT if the attribute is not listed in $AttrDef.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) int ntfs_attr_can_be_non_resident(const ntfs_volume *vol, const ATTR_TYPE type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) ATTR_DEF *ad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) /* Find the attribute definition record in $AttrDef. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) ad = ntfs_attr_find_in_attrdef(vol, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) if (unlikely(!ad))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) /* Check the flags and return the result. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) if (ad->flags & ATTR_DEF_RESIDENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) * ntfs_attr_can_be_resident - check if an attribute can be resident
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) * @vol: ntfs volume to which the attribute belongs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) * @type: attribute type which to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) * Check whether the attribute of @type on the ntfs volume @vol is allowed to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) * be resident. This information is derived from our ntfs knowledge and may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) * not be completely accurate, especially when user defined attributes are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) * present. Basically we allow everything to be resident except for index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) * allocation and $EA attributes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) * Return 0 if the attribute is allowed to be non-resident and -EPERM if not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) * Warning: In the system file $MFT the attribute $Bitmap must be non-resident
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) * otherwise windows will not boot (blue screen of death)! We cannot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) * check for this here as we do not know which inode's $Bitmap is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) * being asked about so the caller needs to special case this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) int ntfs_attr_can_be_resident(const ntfs_volume *vol, const ATTR_TYPE type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) if (type == AT_INDEX_ALLOCATION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) * ntfs_attr_record_resize - resize an attribute record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) * @m: mft record containing attribute record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) * @a: attribute record to resize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) * @new_size: new size in bytes to which to resize the attribute record @a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) * Resize the attribute record @a, i.e. the resident part of the attribute, in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) * the mft record @m to @new_size bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) * Return 0 on success and -errno on error. The following error codes are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) * defined:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) * -ENOSPC - Not enough space in the mft record @m to perform the resize.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) * Note: On error, no modifications have been performed whatsoever.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) * Warning: If you make a record smaller without having copied all the data you
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) * are interested in the data may be overwritten.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) ntfs_debug("Entering for new_size %u.", new_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) /* Align to 8 bytes if it is not already done. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) if (new_size & 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) new_size = (new_size + 7) & ~7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) /* If the actual attribute length has changed, move things around. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) if (new_size != le32_to_cpu(a->length)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) u32 new_muse = le32_to_cpu(m->bytes_in_use) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) le32_to_cpu(a->length) + new_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) /* Not enough space in this mft record. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) if (new_muse > le32_to_cpu(m->bytes_allocated))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) /* Move attributes following @a to their new location. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) memmove((u8*)a + new_size, (u8*)a + le32_to_cpu(a->length),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) le32_to_cpu(m->bytes_in_use) - ((u8*)a -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) (u8*)m) - le32_to_cpu(a->length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) /* Adjust @m to reflect the change in used space. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) m->bytes_in_use = cpu_to_le32(new_muse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) /* Adjust @a to reflect the new size. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) if (new_size >= offsetof(ATTR_REC, length) + sizeof(a->length))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) a->length = cpu_to_le32(new_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) * ntfs_resident_attr_value_resize - resize the value of a resident attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) * @m: mft record containing attribute record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) * @a: attribute record whose value to resize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) * @new_size: new size in bytes to which to resize the attribute value of @a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) * Resize the value of the attribute @a in the mft record @m to @new_size bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) * If the value is made bigger, the newly allocated space is cleared.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) * Return 0 on success and -errno on error. The following error codes are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) * defined:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) * -ENOSPC - Not enough space in the mft record @m to perform the resize.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) * Note: On error, no modifications have been performed whatsoever.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) * Warning: If you make a record smaller without having copied all the data you
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) * are interested in the data may be overwritten.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) const u32 new_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) u32 old_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) /* Resize the resident part of the attribute record. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) if (ntfs_attr_record_resize(m, a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) le16_to_cpu(a->data.resident.value_offset) + new_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) * The resize succeeded! If we made the attribute value bigger, clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) * the area between the old size and @new_size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) old_size = le32_to_cpu(a->data.resident.value_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) if (new_size > old_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) memset((u8*)a + le16_to_cpu(a->data.resident.value_offset) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) old_size, 0, new_size - old_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) /* Finally update the length of the attribute value. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) a->data.resident.value_length = cpu_to_le32(new_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) * ntfs_attr_make_non_resident - convert a resident to a non-resident attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) * @ni: ntfs inode describing the attribute to convert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) * @data_size: size of the resident data to copy to the non-resident attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) * Convert the resident ntfs attribute described by the ntfs inode @ni to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) * non-resident one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) * @data_size must be equal to the attribute value size. This is needed since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) * we need to know the size before we can map the mft record and our callers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) * always know it. The reason we cannot simply read the size from the vfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) * inode i_size is that this is not necessarily uptodate. This happens when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) * ntfs_attr_make_non_resident() is called in the ->truncate call path(s).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) * Return 0 on success and -errno on error. The following error return codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) * are defined:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) * -EPERM - The attribute is not allowed to be non-resident.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) * -ENOMEM - Not enough memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) * -ENOSPC - Not enough disk space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) * -EINVAL - Attribute not defined on the volume.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) * -EIO - I/o error or other error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) * Note that -ENOSPC is also returned in the case that there is not enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) * space in the mft record to do the conversion. This can happen when the mft
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) * record is already very full. The caller is responsible for trying to make
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) * space in the mft record and trying again. FIXME: Do we need a separate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) * error return code for this kind of -ENOSPC or is it always worth trying
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) * again in case the attribute may then fit in a resident state so no need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) * make it non-resident at all? Ho-hum... (AIA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) * NOTE to self: No changes in the attribute list are required to move from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) * a resident to a non-resident attribute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) * Locking: - The caller must hold i_mutex on the inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) s64 new_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) struct inode *vi = VFS_I(ni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) ntfs_volume *vol = ni->vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) ntfs_inode *base_ni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) MFT_RECORD *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) ATTR_RECORD *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) ntfs_attr_search_ctx *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) runlist_element *rl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) u8 *kaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) int mp_size, mp_ofs, name_ofs, arec_size, err, err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) u32 attr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) u8 old_res_attr_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) /* Check that the attribute is allowed to be non-resident. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) err = ntfs_attr_can_be_non_resident(vol, ni->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) if (err == -EPERM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) ntfs_debug("Attribute is not allowed to be "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) "non-resident.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) ntfs_debug("Attribute not defined on the NTFS "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) "volume!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) * FIXME: Compressed and encrypted attributes are not supported when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) * writing and we should never have gotten here for them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) BUG_ON(NInoCompressed(ni));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) BUG_ON(NInoEncrypted(ni));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) * The size needs to be aligned to a cluster boundary for allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) * purposes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) new_size = (data_size + vol->cluster_size - 1) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) ~(vol->cluster_size - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) if (new_size > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) * Will need the page later and since the page lock nests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) * outside all ntfs locks, we need to get the page now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) page = find_or_create_page(vi->i_mapping, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) mapping_gfp_mask(vi->i_mapping));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) if (unlikely(!page))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) /* Start by allocating clusters to hold the attribute value. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) rl = ntfs_cluster_alloc(vol, 0, new_size >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) vol->cluster_size_bits, -1, DATA_ZONE, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) if (IS_ERR(rl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) err = PTR_ERR(rl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) ntfs_debug("Failed to allocate cluster%s, error code "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) "%i.", (new_size >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) vol->cluster_size_bits) > 1 ? "s" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) goto page_err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) rl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) page = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) /* Determine the size of the mapping pairs array. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) mp_size = ntfs_get_size_for_mapping_pairs(vol, rl, 0, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) if (unlikely(mp_size < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) err = mp_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) ntfs_debug("Failed to get size for mapping pairs array, error "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) "code %i.", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) goto rl_err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) down_write(&ni->runlist.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) if (!NInoAttr(ni))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) base_ni = ni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) base_ni = ni->ext.base_ntfs_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) m = map_mft_record(base_ni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) if (IS_ERR(m)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) err = PTR_ERR(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) m = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) ctx = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) ctx = ntfs_attr_get_search_ctx(base_ni, m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) if (unlikely(!ctx)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) CASE_SENSITIVE, 0, NULL, 0, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) if (err == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) m = ctx->mrec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) a = ctx->attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) BUG_ON(NInoNonResident(ni));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) BUG_ON(a->non_resident);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) * Calculate new offsets for the name and the mapping pairs array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) if (NInoSparse(ni) || NInoCompressed(ni))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) name_ofs = (offsetof(ATTR_REC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) data.non_resident.compressed_size) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) sizeof(a->data.non_resident.compressed_size) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 7) & ~7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) name_ofs = (offsetof(ATTR_REC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) data.non_resident.compressed_size) + 7) & ~7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) mp_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) * Determine the size of the resident part of the now non-resident
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) * attribute record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) arec_size = (mp_ofs + mp_size + 7) & ~7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) * If the page is not uptodate bring it uptodate by copying from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) * attribute value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) attr_size = le32_to_cpu(a->data.resident.value_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) BUG_ON(attr_size != data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) if (page && !PageUptodate(page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) kaddr = kmap_atomic(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) memcpy(kaddr, (u8*)a +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) le16_to_cpu(a->data.resident.value_offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) attr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) memset(kaddr + attr_size, 0, PAGE_SIZE - attr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) kunmap_atomic(kaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) flush_dcache_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) SetPageUptodate(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) /* Backup the attribute flag. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) old_res_attr_flags = a->data.resident.flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) /* Resize the resident part of the attribute record. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) err = ntfs_attr_record_resize(m, a, arec_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) if (unlikely(err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) * Convert the resident part of the attribute record to describe a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) * non-resident attribute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) a->non_resident = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) /* Move the attribute name if it exists and update the offset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) if (a->name_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) a->name_length * sizeof(ntfschar));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) a->name_offset = cpu_to_le16(name_ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) /* Setup the fields specific to non-resident attributes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) a->data.non_resident.lowest_vcn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) a->data.non_resident.highest_vcn = cpu_to_sle64((new_size - 1) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) vol->cluster_size_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) a->data.non_resident.mapping_pairs_offset = cpu_to_le16(mp_ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) memset(&a->data.non_resident.reserved, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) sizeof(a->data.non_resident.reserved));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) a->data.non_resident.allocated_size = cpu_to_sle64(new_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) a->data.non_resident.data_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) a->data.non_resident.initialized_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) cpu_to_sle64(attr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) if (NInoSparse(ni) || NInoCompressed(ni)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) a->data.non_resident.compression_unit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) if (NInoCompressed(ni) || vol->major_ver < 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) a->data.non_resident.compression_unit = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) a->data.non_resident.compressed_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) a->data.non_resident.allocated_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) a->data.non_resident.compression_unit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) /* Generate the mapping pairs array into the attribute record. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) err = ntfs_mapping_pairs_build(vol, (u8*)a + mp_ofs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) arec_size - mp_ofs, rl, 0, -1, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) ntfs_debug("Failed to build mapping pairs, error code %i.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) goto undo_err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) /* Setup the in-memory attribute structure to be non-resident. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) ni->runlist.rl = rl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) write_lock_irqsave(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) ni->allocated_size = new_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) if (NInoSparse(ni) || NInoCompressed(ni)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) ni->itype.compressed.size = ni->allocated_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) if (a->data.non_resident.compression_unit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) ni->itype.compressed.block_size = 1U << (a->data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) non_resident.compression_unit +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) vol->cluster_size_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) ni->itype.compressed.block_size_bits =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) ffs(ni->itype.compressed.block_size) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) ni->itype.compressed.block_clusters = 1U <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) a->data.non_resident.compression_unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) ni->itype.compressed.block_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) ni->itype.compressed.block_size_bits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) ni->itype.compressed.block_clusters = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) vi->i_blocks = ni->itype.compressed.size >> 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) vi->i_blocks = ni->allocated_size >> 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) write_unlock_irqrestore(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) * This needs to be last since the address space operations ->readpage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) * and ->writepage can run concurrently with us as they are not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) * serialized on i_mutex. Note, we are not allowed to fail once we flip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) * this switch, which is another reason to do this last.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) NInoSetNonResident(ni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) /* Mark the mft record dirty, so it gets written back. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) flush_dcache_mft_record_page(ctx->ntfs_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) mark_mft_record_dirty(ctx->ntfs_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) ntfs_attr_put_search_ctx(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) unmap_mft_record(base_ni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) up_write(&ni->runlist.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) if (page) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) set_page_dirty(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) put_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) ntfs_debug("Done.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) undo_err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) /* Convert the attribute back into a resident attribute. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) a->non_resident = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) /* Move the attribute name if it exists and update the offset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) name_ofs = (offsetof(ATTR_RECORD, data.resident.reserved) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) sizeof(a->data.resident.reserved) + 7) & ~7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) if (a->name_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) a->name_length * sizeof(ntfschar));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) mp_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) a->name_offset = cpu_to_le16(name_ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) arec_size = (mp_ofs + attr_size + 7) & ~7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) /* Resize the resident part of the attribute record. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) err2 = ntfs_attr_record_resize(m, a, arec_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) if (unlikely(err2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) * This cannot happen (well if memory corruption is at work it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) * could happen in theory), but deal with it as well as we can.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) * If the old size is too small, truncate the attribute,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) * otherwise simply give it a larger allocated size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) * FIXME: Should check whether chkdsk complains when the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) * allocated size is much bigger than the resident value size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) arec_size = le32_to_cpu(a->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) if ((mp_ofs + attr_size) > arec_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) err2 = attr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) attr_size = arec_size - mp_ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) ntfs_error(vol->sb, "Failed to undo partial resident "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) "to non-resident attribute "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) "conversion. Truncating inode 0x%lx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) "attribute type 0x%x from %i bytes to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) "%i bytes to maintain metadata "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) "consistency. THIS MEANS YOU ARE "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) "LOSING %i BYTES DATA FROM THIS %s.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) vi->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) (unsigned)le32_to_cpu(ni->type),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) err2, attr_size, err2 - attr_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) ((ni->type == AT_DATA) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) !ni->name_len) ? "FILE": "ATTRIBUTE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) write_lock_irqsave(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) ni->initialized_size = attr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) i_size_write(vi, attr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) write_unlock_irqrestore(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) /* Setup the fields specific to resident attributes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) a->data.resident.value_length = cpu_to_le32(attr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) a->data.resident.value_offset = cpu_to_le16(mp_ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) a->data.resident.flags = old_res_attr_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) memset(&a->data.resident.reserved, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) sizeof(a->data.resident.reserved));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) /* Copy the data from the page back to the attribute value. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) if (page) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) kaddr = kmap_atomic(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) memcpy((u8*)a + mp_ofs, kaddr, attr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) kunmap_atomic(kaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) /* Setup the allocated size in the ntfs inode in case it changed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) write_lock_irqsave(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) ni->allocated_size = arec_size - mp_ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) write_unlock_irqrestore(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) /* Mark the mft record dirty, so it gets written back. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) flush_dcache_mft_record_page(ctx->ntfs_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) mark_mft_record_dirty(ctx->ntfs_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) if (ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) ntfs_attr_put_search_ctx(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) if (m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) unmap_mft_record(base_ni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) ni->runlist.rl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) up_write(&ni->runlist.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) rl_err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) if (rl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) if (ntfs_cluster_free_from_rl(vol, rl) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) ntfs_error(vol->sb, "Failed to release allocated "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) "cluster(s) in error code path. Run "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) "chkdsk to recover the lost "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) "cluster(s).");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) NVolSetErrors(vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) ntfs_free(rl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) page_err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) put_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) if (err == -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) * ntfs_attr_extend_allocation - extend the allocated space of an attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) * @ni: ntfs inode of the attribute whose allocation to extend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) * @new_alloc_size: new size in bytes to which to extend the allocation to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) * @new_data_size: new size in bytes to which to extend the data to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) * @data_start: beginning of region which is required to be non-sparse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) * Extend the allocated space of an attribute described by the ntfs inode @ni
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) * to @new_alloc_size bytes. If @data_start is -1, the whole extension may be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) * implemented as a hole in the file (as long as both the volume and the ntfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) * inode @ni have sparse support enabled). If @data_start is >= 0, then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) * region between the old allocated size and @data_start - 1 may be made sparse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) * but the regions between @data_start and @new_alloc_size must be backed by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) * actual clusters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) * If @new_data_size is -1, it is ignored. If it is >= 0, then the data size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) * of the attribute is extended to @new_data_size. Note that the i_size of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) * vfs inode is not updated. Only the data size in the base attribute record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) * is updated. The caller has to update i_size separately if this is required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) * WARNING: It is a BUG() for @new_data_size to be smaller than the old data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) * size as well as for @new_data_size to be greater than @new_alloc_size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) * For resident attributes this involves resizing the attribute record and if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) * necessary moving it and/or other attributes into extent mft records and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) * converting the attribute to a non-resident attribute which in turn involves
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) * extending the allocation of a non-resident attribute as described below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) * For non-resident attributes this involves allocating clusters in the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) * zone on the volume (except for regions that are being made sparse) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) * extending the run list to describe the allocated clusters as well as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) * updating the mapping pairs array of the attribute. This in turn involves
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) * resizing the attribute record and if necessary moving it and/or other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) * attributes into extent mft records and/or splitting the attribute record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) * into multiple extent attribute records.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) * Also, the attribute list attribute is updated if present and in some of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) * above cases (the ones where extent mft records/attributes come into play),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) * an attribute list attribute is created if not already present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) * Return the new allocated size on success and -errno on error. In the case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) * that an error is encountered but a partial extension at least up to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) * @data_start (if present) is possible, the allocation is partially extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) * and this is returned. This means the caller must check the returned size to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) * determine if the extension was partial. If @data_start is -1 then partial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) * allocations are not performed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) * WARNING: Do not call ntfs_attr_extend_allocation() for $MFT/$DATA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) * Locking: This function takes the runlist lock of @ni for writing as well as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) * locking the mft record of the base ntfs inode. These locks are maintained
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) * throughout execution of the function. These locks are required so that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) * attribute can be resized safely and so that it can for example be converted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) * from resident to non-resident safely.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) * TODO: At present attribute list attribute handling is not implemented.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) * TODO: At present it is not safe to call this function for anything other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) * than the $DATA attribute(s) of an uncompressed and unencrypted file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) s64 ntfs_attr_extend_allocation(ntfs_inode *ni, s64 new_alloc_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) const s64 new_data_size, const s64 data_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) VCN vcn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) s64 ll, allocated_size, start = data_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) struct inode *vi = VFS_I(ni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) ntfs_volume *vol = ni->vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) ntfs_inode *base_ni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) MFT_RECORD *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) ATTR_RECORD *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) ntfs_attr_search_ctx *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) runlist_element *rl, *rl2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) int err, mp_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) u32 attr_len = 0; /* Silence stupid gcc warning. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) bool mp_rebuilt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) read_lock_irqsave(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) allocated_size = ni->allocated_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) read_unlock_irqrestore(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) ntfs_debug("Entering for i_ino 0x%lx, attribute type 0x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) "old_allocated_size 0x%llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) "new_allocated_size 0x%llx, new_data_size 0x%llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) "data_start 0x%llx.", vi->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) (unsigned)le32_to_cpu(ni->type),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) (unsigned long long)allocated_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) (unsigned long long)new_alloc_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) (unsigned long long)new_data_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) (unsigned long long)start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) retry_extend:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) * For non-resident attributes, @start and @new_size need to be aligned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) * to cluster boundaries for allocation purposes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) if (NInoNonResident(ni)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) if (start > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) start &= ~(s64)vol->cluster_size_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) new_alloc_size = (new_alloc_size + vol->cluster_size - 1) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) ~(s64)vol->cluster_size_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) BUG_ON(new_data_size >= 0 && new_data_size > new_alloc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) /* Check if new size is allowed in $AttrDef. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) err = ntfs_attr_size_bounds_check(vol, ni->type, new_alloc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) /* Only emit errors when the write will fail completely. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) read_lock_irqsave(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) allocated_size = ni->allocated_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) read_unlock_irqrestore(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) if (start < 0 || start >= allocated_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) if (err == -ERANGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) ntfs_error(vol->sb, "Cannot extend allocation "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) "of inode 0x%lx, attribute "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) "type 0x%x, because the new "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) "allocation would exceed the "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) "maximum allowed size for "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) "this attribute type.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) vi->i_ino, (unsigned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) le32_to_cpu(ni->type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) ntfs_error(vol->sb, "Cannot extend allocation "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) "of inode 0x%lx, attribute "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) "type 0x%x, because this "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) "attribute type is not "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) "defined on the NTFS volume. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) "Possible corruption! You "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) "should run chkdsk!",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) vi->i_ino, (unsigned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) le32_to_cpu(ni->type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) /* Translate error code to be POSIX conformant for write(2). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) if (err == -ERANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) err = -EFBIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) if (!NInoAttr(ni))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) base_ni = ni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) base_ni = ni->ext.base_ntfs_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) * We will be modifying both the runlist (if non-resident) and the mft
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) * record so lock them both down.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) down_write(&ni->runlist.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) m = map_mft_record(base_ni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) if (IS_ERR(m)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) err = PTR_ERR(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) m = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) ctx = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) ctx = ntfs_attr_get_search_ctx(base_ni, m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) if (unlikely(!ctx)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) read_lock_irqsave(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) allocated_size = ni->allocated_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) read_unlock_irqrestore(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) * If non-resident, seek to the last extent. If resident, there is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) * only one extent, so seek to that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) vcn = NInoNonResident(ni) ? allocated_size >> vol->cluster_size_bits :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) * Abort if someone did the work whilst we waited for the locks. If we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) * just converted the attribute from resident to non-resident it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) * likely that exactly this has happened already. We cannot quite
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) * abort if we need to update the data size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) if (unlikely(new_alloc_size <= allocated_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) ntfs_debug("Allocated size already exceeds requested size.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) new_alloc_size = allocated_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) if (new_data_size < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) * We want the first attribute extent so that we can update the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) * data size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) vcn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) CASE_SENSITIVE, vcn, NULL, 0, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) if (err == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) m = ctx->mrec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) a = ctx->attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) /* Use goto to reduce indentation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) if (a->non_resident)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) goto do_non_resident_extend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) BUG_ON(NInoNonResident(ni));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) /* The total length of the attribute value. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) attr_len = le32_to_cpu(a->data.resident.value_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) * Extend the attribute record to be able to store the new attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) * size. ntfs_attr_record_resize() will not do anything if the size is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) * not changing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) if (new_alloc_size < vol->mft_record_size &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) !ntfs_attr_record_resize(m, a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) le16_to_cpu(a->data.resident.value_offset) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) new_alloc_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) /* The resize succeeded! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) write_lock_irqsave(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) ni->allocated_size = le32_to_cpu(a->length) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) le16_to_cpu(a->data.resident.value_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) write_unlock_irqrestore(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) if (new_data_size >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) BUG_ON(new_data_size < attr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) a->data.resident.value_length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) cpu_to_le32((u32)new_data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) goto flush_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) * We have to drop all the locks so we can call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) * ntfs_attr_make_non_resident(). This could be optimised by try-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) * locking the first page cache page and only if that fails dropping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) * the locks, locking the page, and redoing all the locking and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) * lookups. While this would be a huge optimisation, it is not worth
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) * it as this is definitely a slow code path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) ntfs_attr_put_search_ctx(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) unmap_mft_record(base_ni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) up_write(&ni->runlist.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) * Not enough space in the mft record, try to make the attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) * non-resident and if successful restart the extension process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) err = ntfs_attr_make_non_resident(ni, attr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) if (likely(!err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) goto retry_extend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) * Could not make non-resident. If this is due to this not being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) * permitted for this attribute type or there not being enough space,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) * try to make other attributes non-resident. Otherwise fail.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) if (unlikely(err != -EPERM && err != -ENOSPC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) /* Only emit errors when the write will fail completely. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) read_lock_irqsave(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) allocated_size = ni->allocated_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) read_unlock_irqrestore(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) if (start < 0 || start >= allocated_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) ntfs_error(vol->sb, "Cannot extend allocation of "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) "inode 0x%lx, attribute type 0x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) "because the conversion from resident "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) "to non-resident attribute failed "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) "with error code %i.", vi->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) (unsigned)le32_to_cpu(ni->type), err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) if (err != -ENOMEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) goto conv_err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) /* TODO: Not implemented from here, abort. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) read_lock_irqsave(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) allocated_size = ni->allocated_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) read_unlock_irqrestore(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) if (start < 0 || start >= allocated_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) if (err == -ENOSPC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) ntfs_error(vol->sb, "Not enough space in the mft "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) "record/on disk for the non-resident "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) "attribute value. This case is not "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) "implemented yet.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) else /* if (err == -EPERM) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) ntfs_error(vol->sb, "This attribute type may not be "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) "non-resident. This case is not "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) "implemented yet.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) goto conv_err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) // TODO: Attempt to make other attributes non-resident.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) goto do_resident_extend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) * Both the attribute list attribute and the standard information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) * attribute must remain in the base inode. Thus, if this is one of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) * these attributes, we have to try to move other attributes out into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) * extent mft records instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) if (ni->type == AT_ATTRIBUTE_LIST ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) ni->type == AT_STANDARD_INFORMATION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) // TODO: Attempt to move other attributes into extent mft
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) // records.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) goto do_resident_extend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) // TODO: Attempt to move this attribute to an extent mft record, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) // only if it is not already the only attribute in an mft record in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) // which case there would be nothing to gain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) goto do_resident_extend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) /* There is nothing we can do to make enough space. )-: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) do_non_resident_extend:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) BUG_ON(!NInoNonResident(ni));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) if (new_alloc_size == allocated_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) BUG_ON(vcn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) goto alloc_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) * If the data starts after the end of the old allocation, this is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) * $DATA attribute and sparse attributes are enabled on the volume and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) * for this inode, then create a sparse region between the old
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) * allocated size and the start of the data. Otherwise simply proceed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) * with filling the whole space between the old allocated size and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) * new allocated size with clusters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) if ((start >= 0 && start <= allocated_size) || ni->type != AT_DATA ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) !NVolSparseEnabled(vol) || NInoSparseDisabled(ni))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) goto skip_sparse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) // TODO: This is not implemented yet. We just fill in with real
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) // clusters for now...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) ntfs_debug("Inserting holes is not-implemented yet. Falling back to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) "allocating real clusters instead.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) skip_sparse:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) rl = ni->runlist.rl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) if (likely(rl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) /* Seek to the end of the runlist. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) while (rl->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) rl++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) /* If this attribute extent is not mapped, map it now. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) if (unlikely(!rl || rl->lcn == LCN_RL_NOT_MAPPED ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) (rl->lcn == LCN_ENOENT && rl > ni->runlist.rl &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) (rl-1)->lcn == LCN_RL_NOT_MAPPED))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) if (!rl && !allocated_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) goto first_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) rl = ntfs_mapping_pairs_decompress(vol, a, ni->runlist.rl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) if (IS_ERR(rl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) err = PTR_ERR(rl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) if (start < 0 || start >= allocated_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) ntfs_error(vol->sb, "Cannot extend allocation "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) "of inode 0x%lx, attribute "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) "type 0x%x, because the "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) "mapping of a runlist "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) "fragment failed with error "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) "code %i.", vi->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) (unsigned)le32_to_cpu(ni->type),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) if (err != -ENOMEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) ni->runlist.rl = rl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) /* Seek to the end of the runlist. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) while (rl->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) rl++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) * We now know the runlist of the last extent is mapped and @rl is at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) * the end of the runlist. We want to begin allocating clusters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) * starting at the last allocated cluster to reduce fragmentation. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) * there are no valid LCNs in the attribute we let the cluster
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) * allocator choose the starting cluster.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) /* If the last LCN is a hole or simillar seek back to last real LCN. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) while (rl->lcn < 0 && rl > ni->runlist.rl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) rl--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) first_alloc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) // FIXME: Need to implement partial allocations so at least part of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) // write can be performed when start >= 0. (Needed for POSIX write(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) // conformance.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) rl2 = ntfs_cluster_alloc(vol, allocated_size >> vol->cluster_size_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) (new_alloc_size - allocated_size) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) vol->cluster_size_bits, (rl && (rl->lcn >= 0)) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) rl->lcn + rl->length : -1, DATA_ZONE, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) if (IS_ERR(rl2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) err = PTR_ERR(rl2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) if (start < 0 || start >= allocated_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) ntfs_error(vol->sb, "Cannot extend allocation of "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) "inode 0x%lx, attribute type 0x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) "because the allocation of clusters "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) "failed with error code %i.", vi->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) (unsigned)le32_to_cpu(ni->type), err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) if (err != -ENOMEM && err != -ENOSPC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) rl = ntfs_runlists_merge(ni->runlist.rl, rl2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) if (IS_ERR(rl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) err = PTR_ERR(rl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) if (start < 0 || start >= allocated_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) ntfs_error(vol->sb, "Cannot extend allocation of "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) "inode 0x%lx, attribute type 0x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) "because the runlist merge failed "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) "with error code %i.", vi->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) (unsigned)le32_to_cpu(ni->type), err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) if (err != -ENOMEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) if (ntfs_cluster_free_from_rl(vol, rl2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) ntfs_error(vol->sb, "Failed to release allocated "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) "cluster(s) in error code path. Run "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) "chkdsk to recover the lost "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) "cluster(s).");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) NVolSetErrors(vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) ntfs_free(rl2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) ni->runlist.rl = rl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) ntfs_debug("Allocated 0x%llx clusters.", (long long)(new_alloc_size -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) allocated_size) >> vol->cluster_size_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) /* Find the runlist element with which the attribute extent starts. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) ll = sle64_to_cpu(a->data.non_resident.lowest_vcn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) rl2 = ntfs_rl_find_vcn_nolock(rl, ll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) BUG_ON(!rl2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) BUG_ON(!rl2->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) BUG_ON(rl2->lcn < LCN_HOLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) mp_rebuilt = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) /* Get the size for the new mapping pairs array for this extent. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) if (unlikely(mp_size <= 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) err = mp_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) if (start < 0 || start >= allocated_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) ntfs_error(vol->sb, "Cannot extend allocation of "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) "inode 0x%lx, attribute type 0x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) "because determining the size for the "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) "mapping pairs failed with error code "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) "%i.", vi->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) (unsigned)le32_to_cpu(ni->type), err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) goto undo_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) /* Extend the attribute record to fit the bigger mapping pairs array. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) attr_len = le32_to_cpu(a->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) err = ntfs_attr_record_resize(m, a, mp_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) le16_to_cpu(a->data.non_resident.mapping_pairs_offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) BUG_ON(err != -ENOSPC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) // TODO: Deal with this by moving this extent to a new mft
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) // record or by starting a new extent in a new mft record,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) // possibly by extending this extent partially and filling it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) // and creating a new extent for the remainder, or by making
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) // other attributes non-resident and/or by moving other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) // attributes out of this mft record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) if (start < 0 || start >= allocated_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) ntfs_error(vol->sb, "Not enough space in the mft "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) "record for the extended attribute "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) "record. This case is not "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) "implemented yet.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) goto undo_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) mp_rebuilt = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) /* Generate the mapping pairs array directly into the attr record. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) err = ntfs_mapping_pairs_build(vol, (u8*)a +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) le16_to_cpu(a->data.non_resident.mapping_pairs_offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) mp_size, rl2, ll, -1, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) if (start < 0 || start >= allocated_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) ntfs_error(vol->sb, "Cannot extend allocation of "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) "inode 0x%lx, attribute type 0x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) "because building the mapping pairs "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) "failed with error code %i.", vi->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) (unsigned)le32_to_cpu(ni->type), err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) goto undo_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) /* Update the highest_vcn. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) a->data.non_resident.highest_vcn = cpu_to_sle64((new_alloc_size >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) vol->cluster_size_bits) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) * We now have extended the allocated size of the attribute. Reflect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) * this in the ntfs_inode structure and the attribute record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) if (a->data.non_resident.lowest_vcn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) * We are not in the first attribute extent, switch to it, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) * first ensure the changes will make it to disk later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) flush_dcache_mft_record_page(ctx->ntfs_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) mark_mft_record_dirty(ctx->ntfs_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) ntfs_attr_reinit_search_ctx(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) CASE_SENSITIVE, 0, NULL, 0, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) if (unlikely(err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) goto restore_undo_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) /* @m is not used any more so no need to set it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) a = ctx->attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) write_lock_irqsave(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) ni->allocated_size = new_alloc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) a->data.non_resident.allocated_size = cpu_to_sle64(new_alloc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) * FIXME: This would fail if @ni is a directory, $MFT, or an index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) * since those can have sparse/compressed set. For example can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) * set compressed even though it is not compressed itself and in that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) * case the bit means that files are to be created compressed in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) * directory... At present this is ok as this code is only called for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) * regular files, and only for their $DATA attribute(s).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) * FIXME: The calculation is wrong if we created a hole above. For now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) * it does not matter as we never create holes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) if (NInoSparse(ni) || NInoCompressed(ni)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) ni->itype.compressed.size += new_alloc_size - allocated_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) a->data.non_resident.compressed_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) cpu_to_sle64(ni->itype.compressed.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) vi->i_blocks = ni->itype.compressed.size >> 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) vi->i_blocks = new_alloc_size >> 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) write_unlock_irqrestore(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) alloc_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) if (new_data_size >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) BUG_ON(new_data_size <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) sle64_to_cpu(a->data.non_resident.data_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) a->data.non_resident.data_size = cpu_to_sle64(new_data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) flush_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) /* Ensure the changes make it to disk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) flush_dcache_mft_record_page(ctx->ntfs_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) mark_mft_record_dirty(ctx->ntfs_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) ntfs_attr_put_search_ctx(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) unmap_mft_record(base_ni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) up_write(&ni->runlist.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) ntfs_debug("Done, new_allocated_size 0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) (unsigned long long)new_alloc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) return new_alloc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) restore_undo_alloc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) if (start < 0 || start >= allocated_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) ntfs_error(vol->sb, "Cannot complete extension of allocation "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) "of inode 0x%lx, attribute type 0x%x, because "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) "lookup of first attribute extent failed with "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) "error code %i.", vi->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) (unsigned)le32_to_cpu(ni->type), err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) if (err == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) ntfs_attr_reinit_search_ctx(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) if (ntfs_attr_lookup(ni->type, ni->name, ni->name_len, CASE_SENSITIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) allocated_size >> vol->cluster_size_bits, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) ctx)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) ntfs_error(vol->sb, "Failed to find last attribute extent of "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) "attribute in error code path. Run chkdsk to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) "recover.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) write_lock_irqsave(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) ni->allocated_size = new_alloc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) * FIXME: This would fail if @ni is a directory... See above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) * FIXME: The calculation is wrong if we created a hole above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) * For now it does not matter as we never create holes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) if (NInoSparse(ni) || NInoCompressed(ni)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) ni->itype.compressed.size += new_alloc_size -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) allocated_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) vi->i_blocks = ni->itype.compressed.size >> 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) vi->i_blocks = new_alloc_size >> 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) write_unlock_irqrestore(&ni->size_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) ntfs_attr_put_search_ctx(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) unmap_mft_record(base_ni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) up_write(&ni->runlist.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) * The only thing that is now wrong is the allocated size of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) * base attribute extent which chkdsk should be able to fix.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) NVolSetErrors(vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) ctx->attr->data.non_resident.highest_vcn = cpu_to_sle64(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) (allocated_size >> vol->cluster_size_bits) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) undo_alloc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) ll = allocated_size >> vol->cluster_size_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) if (ntfs_cluster_free(ni, ll, -1, ctx) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) ntfs_error(vol->sb, "Failed to release allocated cluster(s) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) "in error code path. Run chkdsk to recover "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) "the lost cluster(s).");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) NVolSetErrors(vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) m = ctx->mrec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) a = ctx->attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) * If the runlist truncation fails and/or the search context is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) * longer valid, we cannot resize the attribute record or build the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) * mapping pairs array thus we mark the inode bad so that no access to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) * the freed clusters can happen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) if (ntfs_rl_truncate_nolock(vol, &ni->runlist, ll) || IS_ERR(m)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) ntfs_error(vol->sb, "Failed to %s in error code path. Run "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) "chkdsk to recover.", IS_ERR(m) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) "restore attribute search context" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) "truncate attribute runlist");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) NVolSetErrors(vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) } else if (mp_rebuilt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) if (ntfs_attr_record_resize(m, a, attr_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) ntfs_error(vol->sb, "Failed to restore attribute "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) "record in error code path. Run "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) "chkdsk to recover.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) NVolSetErrors(vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) } else /* if (success) */ {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) if (ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) a->data.non_resident.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) mapping_pairs_offset), attr_len -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) le16_to_cpu(a->data.non_resident.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) mapping_pairs_offset), rl2, ll, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) ntfs_error(vol->sb, "Failed to restore "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) "mapping pairs array in error "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) "code path. Run chkdsk to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) "recover.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) NVolSetErrors(vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) flush_dcache_mft_record_page(ctx->ntfs_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) mark_mft_record_dirty(ctx->ntfs_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) if (ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) ntfs_attr_put_search_ctx(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) if (m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) unmap_mft_record(base_ni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) up_write(&ni->runlist.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) conv_err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) ntfs_debug("Failed. Returning error code %i.", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) * ntfs_attr_set - fill (a part of) an attribute with a byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) * @ni: ntfs inode describing the attribute to fill
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) * @ofs: offset inside the attribute at which to start to fill
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) * @cnt: number of bytes to fill
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) * @val: the unsigned 8-bit value with which to fill the attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) * Fill @cnt bytes of the attribute described by the ntfs inode @ni starting at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) * byte offset @ofs inside the attribute with the constant byte @val.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) * This function is effectively like memset() applied to an ntfs attribute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) * Note thie function actually only operates on the page cache pages belonging
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) * to the ntfs attribute and it marks them dirty after doing the memset().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) * Thus it relies on the vm dirty page write code paths to cause the modified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) * pages to be written to the mft record/disk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) * Return 0 on success and -errno on error. An error code of -ESPIPE means
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) * that @ofs + @cnt were outside the end of the attribute and no write was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) * performed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) ntfs_volume *vol = ni->vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) struct address_space *mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) u8 *kaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) pgoff_t idx, end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) unsigned start_ofs, end_ofs, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) ntfs_debug("Entering for ofs 0x%llx, cnt 0x%llx, val 0x%hx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) (long long)ofs, (long long)cnt, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) BUG_ON(ofs < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) BUG_ON(cnt < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) if (!cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) * FIXME: Compressed and encrypted attributes are not supported when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) * writing and we should never have gotten here for them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) BUG_ON(NInoCompressed(ni));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) BUG_ON(NInoEncrypted(ni));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) mapping = VFS_I(ni)->i_mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) /* Work out the starting index and page offset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) idx = ofs >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) start_ofs = ofs & ~PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) /* Work out the ending index and page offset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) end = ofs + cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) end_ofs = end & ~PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) /* If the end is outside the inode size return -ESPIPE. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) if (unlikely(end > i_size_read(VFS_I(ni)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) ntfs_error(vol->sb, "Request exceeds end of attribute.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) return -ESPIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) end >>= PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) /* If there is a first partial page, need to do it the slow way. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) if (start_ofs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) page = read_mapping_page(mapping, idx, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) if (IS_ERR(page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) ntfs_error(vol->sb, "Failed to read first partial "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) "page (error, index 0x%lx).", idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) return PTR_ERR(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) * If the last page is the same as the first page, need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) * limit the write to the end offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) size = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) if (idx == end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) size = end_ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) kaddr = kmap_atomic(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) memset(kaddr + start_ofs, val, size - start_ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) flush_dcache_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) kunmap_atomic(kaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) set_page_dirty(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) put_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) balance_dirty_pages_ratelimited(mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) if (idx == end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) /* Do the whole pages the fast way. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) for (; idx < end; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) /* Find or create the current page. (The page is locked.) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) page = grab_cache_page(mapping, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) if (unlikely(!page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) ntfs_error(vol->sb, "Insufficient memory to grab "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) "page (index 0x%lx).", idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) kaddr = kmap_atomic(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) memset(kaddr, val, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) flush_dcache_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) kunmap_atomic(kaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) * If the page has buffers, mark them uptodate since buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) * state and not page state is definitive in 2.6 kernels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) if (page_has_buffers(page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) struct buffer_head *bh, *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) bh = head = page_buffers(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) set_buffer_uptodate(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) } while ((bh = bh->b_this_page) != head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) /* Now that buffers are uptodate, set the page uptodate, too. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) SetPageUptodate(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) * Set the page and all its buffers dirty and mark the inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) * dirty, too. The VM will write the page later on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) set_page_dirty(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) /* Finally unlock and release the page. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) put_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) balance_dirty_pages_ratelimited(mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) /* If there is a last partial page, need to do it the slow way. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) if (end_ofs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) page = read_mapping_page(mapping, idx, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) if (IS_ERR(page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) ntfs_error(vol->sb, "Failed to read last partial page "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) "(error, index 0x%lx).", idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) return PTR_ERR(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) kaddr = kmap_atomic(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) memset(kaddr, val, end_ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) flush_dcache_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) kunmap_atomic(kaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) set_page_dirty(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) put_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) balance_dirty_pages_ratelimited(mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) ntfs_debug("Done.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) #endif /* NTFS_RW */