aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ntfs/attrib.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ntfs/attrib.c')
-rw-r--r--fs/ntfs/attrib.c61
1 files changed, 42 insertions, 19 deletions
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index c6b2bb64d651..543d47fa5fc9 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -39,15 +39,19 @@
39 * 39 *
40 * Map the part of a runlist containing the @vcn of the ntfs inode @ni. 40 * Map the part of a runlist containing the @vcn of the ntfs inode @ni.
41 * 41 *
42 * Return 0 on success and -errno on error. 42 * Return 0 on success and -errno on error. There is one special error code
43 * which is not an error as such. This is -ENOENT. It means that @vcn is out
44 * of bounds of the runlist.
43 * 45 *
44 * Locking: - The runlist must be locked for writing. 46 * Locking: - The runlist must be locked for writing.
45 * - This function modifies the runlist. 47 * - This function modifies the runlist.
46 */ 48 */
47int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn) 49int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
48{ 50{
51 VCN end_vcn;
49 ntfs_inode *base_ni; 52 ntfs_inode *base_ni;
50 MFT_RECORD *mrec; 53 MFT_RECORD *m;
54 ATTR_RECORD *a;
51 ntfs_attr_search_ctx *ctx; 55 ntfs_attr_search_ctx *ctx;
52 runlist_element *rl; 56 runlist_element *rl;
53 int err = 0; 57 int err = 0;
@@ -58,26 +62,43 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
58 base_ni = ni; 62 base_ni = ni;
59 else 63 else
60 base_ni = ni->ext.base_ntfs_ino; 64 base_ni = ni->ext.base_ntfs_ino;
61 mrec = map_mft_record(base_ni); 65 m = map_mft_record(base_ni);
62 if (IS_ERR(mrec)) 66 if (IS_ERR(m))
63 return PTR_ERR(mrec); 67 return PTR_ERR(m);
64 ctx = ntfs_attr_get_search_ctx(base_ni, mrec); 68 ctx = ntfs_attr_get_search_ctx(base_ni, m);
65 if (unlikely(!ctx)) { 69 if (unlikely(!ctx)) {
66 err = -ENOMEM; 70 err = -ENOMEM;
67 goto err_out; 71 goto err_out;
68 } 72 }
69 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, 73 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
70 CASE_SENSITIVE, vcn, NULL, 0, ctx); 74 CASE_SENSITIVE, vcn, NULL, 0, ctx);
71 if (likely(!err)) { 75 if (unlikely(err)) {
72 rl = ntfs_mapping_pairs_decompress(ni->vol, ctx->attr, 76 if (err == -ENOENT)
73 ni->runlist.rl); 77 err = -EIO;
74 if (IS_ERR(rl)) 78 goto err_out;
75 err = PTR_ERR(rl);
76 else
77 ni->runlist.rl = rl;
78 } 79 }
79 ntfs_attr_put_search_ctx(ctx); 80 a = ctx->attr;
81 /*
82 * Only decompress the mapping pairs if @vcn is inside it. Otherwise
83 * we get into problems when we try to map an out of bounds vcn because
84 * we then try to map the already mapped runlist fragment and
85 * ntfs_mapping_pairs_decompress() fails.
86 */
87 end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn) + 1;
88 if (unlikely(!a->data.non_resident.lowest_vcn && end_vcn <= 1))
89 end_vcn = ni->allocated_size >> ni->vol->cluster_size_bits;
90 if (unlikely(vcn >= end_vcn)) {
91 err = -ENOENT;
92 goto err_out;
93 }
94 rl = ntfs_mapping_pairs_decompress(ni->vol, a, ni->runlist.rl);
95 if (IS_ERR(rl))
96 err = PTR_ERR(rl);
97 else
98 ni->runlist.rl = rl;
80err_out: 99err_out:
100 if (likely(ctx))
101 ntfs_attr_put_search_ctx(ctx);
81 unmap_mft_record(base_ni); 102 unmap_mft_record(base_ni);
82 return err; 103 return err;
83} 104}
@@ -89,7 +110,9 @@ err_out:
89 * 110 *
90 * Map the part of a runlist containing the @vcn of the ntfs inode @ni. 111 * Map the part of a runlist containing the @vcn of the ntfs inode @ni.
91 * 112 *
92 * Return 0 on success and -errno on error. 113 * Return 0 on success and -errno on error. There is one special error code
114 * which is not an error as such. This is -ENOENT. It means that @vcn is out
115 * of bounds of the runlist.
93 * 116 *
94 * Locking: - The runlist must be unlocked on entry and is unlocked on return. 117 * Locking: - The runlist must be unlocked on entry and is unlocked on return.
95 * - This function takes the runlist lock for writing and modifies the 118 * - This function takes the runlist lock for writing and modifies the
@@ -287,11 +310,11 @@ retry_remap:
287 goto retry_remap; 310 goto retry_remap;
288 } 311 }
289 /* 312 /*
290 * -EINVAL and -ENOENT coming from a failed mapping attempt are 313 * -EINVAL coming from a failed mapping attempt is equivalent
291 * equivalent to i/o errors for us as they should not happen in 314 * to i/o error for us as it should not happen in our code
292 * our code paths. 315 * paths.
293 */ 316 */
294 if (err == -EINVAL || err == -ENOENT) 317 if (err == -EINVAL)
295 err = -EIO; 318 err = -EIO;
296 } else if (!err) 319 } else if (!err)
297 err = -EIO; 320 err = -EIO;