OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [ntfs/] [inode.c] - Blame information for rev 1275

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * inode.c
3
 *
4
 * Copyright (C) 1995-1999 Martin von Löwis
5
 * Copyright (C) 1996 Albert D. Cahalan
6
 * Copyright (C) 1996-1997 Régis Duchesne
7
 * Copyright (C) 1998 Joseph Malicki
8
 * Copyright (C) 1999 Steve Dodd
9
 * Copyright (C) 2000-2001 Anton Altaparmakov (AIA)
10
 */
11
#include "ntfstypes.h"
12
#include "ntfsendian.h"
13
#include "struct.h"
14
#include "inode.h"
15
#include <linux/errno.h>
16
#include "macros.h"
17
#include "attr.h"
18
#include "super.h"
19
#include "dir.h"
20
#include "support.h"
21
#include "util.h"
22
#include <linux/ntfs_fs.h>
23
#include <linux/smp_lock.h>
24
 
25
typedef struct {
26
        int recno;
27
        unsigned char *record;
28
} ntfs_mft_record;
29
 
30
typedef struct {
31
        int size;
32
        int count;
33
        ntfs_mft_record *records;
34
} ntfs_disk_inode;
35
 
36
static void ntfs_fill_mft_header(ntfs_u8 *mft, int rec_size, int seq_no,
37
                int links, int flags)
38
{
39
        int fixup_ofs = 0x2a;
40
        int fixup_cnt = rec_size / NTFS_SECTOR_SIZE + 1;
41
        int attr_ofs = (fixup_ofs + 2 * fixup_cnt + 7) & ~7;
42
 
43
        NTFS_PUTU32(mft + 0x00, 0x454c4946);    /* FILE */
44
        NTFS_PUTU16(mft + 0x04, fixup_ofs);     /* Offset to fixup. */
45
        NTFS_PUTU16(mft + 0x06, fixup_cnt);     /* Number of fixups. */
46
        NTFS_PUTU64(mft + 0x08, 0);              /* Logical sequence number. */
47
        NTFS_PUTU16(mft + 0x10, seq_no);        /* Sequence number. */
48
        NTFS_PUTU16(mft + 0x12, links);         /* Hard link count. */
49
        NTFS_PUTU16(mft + 0x14, attr_ofs);      /* Offset to attributes. */
50
        NTFS_PUTU16(mft + 0x16, flags);         /* Flags: 1 = In use,
51
                                                          2 = Directory. */
52
        NTFS_PUTU32(mft + 0x18, attr_ofs + 8);  /* Bytes in use. */
53
        NTFS_PUTU32(mft + 0x1c, rec_size);      /* Total allocated size. */
54
        NTFS_PUTU64(mft + 0x20, 0);              /* Base mft record. */
55
        NTFS_PUTU16(mft + 0x28, 0);              /* Next attr instance. */
56
        NTFS_PUTU16(mft + fixup_ofs, 1);        /* Fixup word. */
57
        NTFS_PUTU32(mft + attr_ofs, (__u32)-1); /* End of attributes marker. */
58
}
59
 
60
/*
61
 * Search in an inode an attribute by type and name.
62
 * FIXME: Check that when attributes are inserted all attribute list
63
 * attributes are expanded otherwise need to modify this function to deal
64
 * with attribute lists. (AIA)
65
 */
66
ntfs_attribute *ntfs_find_attr(ntfs_inode *ino, int type, char *name)
67
{
68
        int i;
69
 
70
        if (!ino) {
71
                ntfs_error("ntfs_find_attr: NO INODE!\n");
72
                return 0;
73
        }
74
        for (i = 0; i < ino->attr_count; i++) {
75
                if (type < ino->attrs[i].type)
76
                        return 0;
77
                if (type == ino->attrs[i].type) {
78
                        if (!name) {
79
                                if (!ino->attrs[i].name)
80
                                        return ino->attrs + i;
81
                        } else if (ino->attrs[i].name &&
82
                                   !ntfs_ua_strncmp(ino->attrs[i].name, name,
83
                                                    strlen(name)))
84
                                return ino->attrs + i;
85
                }
86
        }
87
        return 0;
88
}
89
 
90
/*
91
 * Insert all attributes from the record mftno of the MFT in the inode ino.
92
 * If mftno is a base mft record we abort as soon as we find the attribute
93
 * list, but only on the first pass. We will get called later when the attribute
94
 * list attribute is being parsed so we need to distinguish the two cases.
95
 * FIXME: We should be performing structural consistency checks. (AIA)
96
 * Return 0 on success or -errno on error.
97
 */
98
static int ntfs_insert_mft_attributes(ntfs_inode* ino, char *mft, int mftno)
99
{
100
        int i, error, type, len, present = 0;
101
        char *it;
102
 
103
        /* Check for duplicate extension record. */
104
        for(i = 0; i < ino->record_count; i++)
105
                if (ino->records[i] == mftno) {
106
                        if (i)
107
                                return 0;
108
                        present = 1;
109
                        break;
110
                }
111
        if (!present) {
112
                /* (re-)allocate space if necessary. */
113
                if (ino->record_count % 8 == 0)  {
114
                        int *new;
115
 
116
                        new = ntfs_malloc((ino->record_count + 8) *
117
                                                                sizeof(int));
118
                        if (!new)
119
                                return -ENOMEM;
120
                        if (ino->records) {
121
                                for (i = 0; i < ino->record_count; i++)
122
                                        new[i] = ino->records[i];
123
                                ntfs_free(ino->records);
124
                        }
125
                        ino->records = new;
126
                }
127
                ino->records[ino->record_count] = mftno;
128
                ino->record_count++;
129
        }
130
        it = mft + NTFS_GETU16(mft + 0x14); /* mft->attrs_offset */
131
        do {
132
                type = NTFS_GETU32(it);
133
                len = NTFS_GETU32(it + 4);
134
                if (type != -1) {
135
                        error = ntfs_insert_attribute(ino, it);
136
                        if (error)
137
                                return error;
138
                }
139
                /* If we have just processed the attribute list and this is
140
                 * the first time we are parsing this (base) mft record then we
141
                 * are done so that the attribute list gets parsed before the
142
                 * entries in the base mft record. Otherwise we run into
143
                 * problems with encountering attributes out of order and when
144
                 * this happens with different attribute extents we die. )-:
145
                 * This way we are ok as the attribute list is always sorted
146
                 * fully and correctly. (-: */
147
                if (type == 0x20 && !present)
148
                        return 0;
149
                it += len;
150
        } while (type != -1); /* Attribute listing ends with type -1. */
151
        return 0;
152
}
153
 
154
/*
155
 * Insert a single specific attribute from the record mftno of the MFT in the
156
 * inode ino. We disregard the attribute list assuming we have already parsed
157
 * it.
158
 * FIXME: We should be performing structural consistency checks. (AIA)
159
 * Return 0 on success or -errno on error.
160
 */
161
static int ntfs_insert_mft_attribute(ntfs_inode* ino, int mftno,
162
                ntfs_u8 *attr)
163
{
164
        int i, error, present = 0;
165
 
166
        /* Check for duplicate extension record. */
167
        for(i = 0; i < ino->record_count; i++)
168
                if (ino->records[i] == mftno) {
169
                        present = 1;
170
                        break;
171
                }
172
        if (!present) {
173
                /* (re-)allocate space if necessary. */
174
                if (ino->record_count % 8 == 0)  {
175
                        int *new;
176
 
177
                        new = ntfs_malloc((ino->record_count + 8) *
178
                                                                sizeof(int));
179
                        if (!new)
180
                                return -ENOMEM;
181
                        if (ino->records) {
182
                                for (i = 0; i < ino->record_count; i++)
183
                                        new[i] = ino->records[i];
184
                                ntfs_free(ino->records);
185
                        }
186
                        ino->records = new;
187
                }
188
                ino->records[ino->record_count] = mftno;
189
                ino->record_count++;
190
        }
191
        if (NTFS_GETU32(attr) == -1) {
192
                ntfs_debug(DEBUG_FILE3, "ntfs_insert_mft_attribute: attribute "
193
                                "type is -1.\n");
194
                return 0;
195
        }
196
        error = ntfs_insert_attribute(ino, attr);
197
        if (error)
198
                return error;
199
        return 0;
200
}
201
 
202
/* Read and insert all the attributes of an 'attribute list' attribute.
203
 * Return the number of remaining bytes in *plen. */
204
static int parse_attributes(ntfs_inode *ino, ntfs_u8 *alist, int *plen)
205
{
206
        ntfs_u8 *mft, *attr;
207
        int mftno, l, error;
208
        int last_mft = -1;
209
        int len = *plen;
210
        int tries = 0;
211
 
212
        if (!ino->attr) {
213
                ntfs_error("parse_attributes: called on inode 0x%x without a "
214
                                "loaded base mft record.\n", ino->i_number);
215
                return -EINVAL;
216
        }
217
        mft = ntfs_malloc(ino->vol->mft_record_size);
218
        if (!mft)
219
                return -ENOMEM;
220
        while (len > 8) {
221
                l = NTFS_GETU16(alist + 4);
222
                if (l > len)
223
                        break;
224
                /* Process an attribute description. */
225
                mftno = NTFS_GETU32(alist + 0x10);
226
                        /* FIXME: The mft reference (alist + 0x10) is __s64.
227
                        * - Not a problem unless we encounter a huge partition.
228
                        * - Should be consistency checking the sequence numbers
229
                        *   though! This should maybe happen in
230
                        *   ntfs_read_mft_record() itself and a hotfix could
231
                        *   then occur there or the user notified to run
232
                        *   ntfsck. (AIA) */
233
                if (mftno != ino->i_number && mftno != last_mft) {
234
continue_after_loading_mft_data:
235
                        last_mft = mftno;
236
                        error = ntfs_read_mft_record(ino->vol, mftno, mft);
237
                        if (error) {
238
                                if (error == -EINVAL && !tries)
239
                                        goto force_load_mft_data;
240
failed_reading_mft_data:
241
                                ntfs_debug(DEBUG_FILE3, "parse_attributes: "
242
                                        "ntfs_read_mft_record(mftno = 0x%x) "
243
                                        "failed\n", mftno);
244
                                ntfs_free(mft);
245
                                return error;
246
                        }
247
                }
248
                attr = ntfs_find_attr_in_mft_rec(
249
                                ino->vol,               /* ntfs volume */
250
                                mftno == ino->i_number ?/* mft record is: */
251
                                        ino->attr:      /*   base record */
252
                                        mft,            /*   extension record */
253
                                NTFS_GETU32(alist + 0),  /* type */
254
                                (wchar_t*)(alist + alist[7]),   /* name */
255
                                alist[6],               /* name length */
256
                                1,                      /* ignore case */
257
                                NTFS_GETU16(alist + 24) /* instance number */
258
                                );
259
                if (!attr) {
260
                        ntfs_error("parse_attributes: mft records 0x%x and/or "
261
                                       "0x%x corrupt!\n", ino->i_number, mftno);
262
                        ntfs_free(mft);
263
                        return -EINVAL; /* FIXME: Better error code? (AIA) */
264
                }
265
                error = ntfs_insert_mft_attribute(ino, mftno, attr);
266
                if (error) {
267
                        ntfs_debug(DEBUG_FILE3, "parse_attributes: "
268
                                "ntfs_insert_mft_attribute(mftno 0x%x, "
269
                                "attribute type 0x%x) failed\n", mftno,
270
                                NTFS_GETU32(alist + 0));
271
                        ntfs_free(mft);
272
                        return error;
273
                }
274
                len -= l;
275
                alist += l;
276
        }
277
        ntfs_free(mft);
278
        *plen = len;
279
        return 0;
280
force_load_mft_data:
281
{
282
        ntfs_u8 *mft2, *attr2;
283
        int mftno2;
284
        int last_mft2 = last_mft;
285
        int len2 = len;
286
        int error2;
287
        int found2 = 0;
288
        ntfs_u8 *alist2 = alist;
289
        /*
290
         * We only get here if $DATA wasn't found in $MFT which only happens
291
         * on volume mount when $MFT has an attribute list and there are
292
         * attributes before $DATA which are inside extent mft records. So
293
         * we just skip forward to the $DATA attribute and read that. Then we
294
         * restart which is safe as an attribute will not be inserted twice.
295
         *
296
         * This still will not fix the case where the attribute list is non-
297
         * resident, larger than 1024 bytes, and the $DATA attribute list entry
298
         * is not in the first 1024 bytes. FIXME: This should be implemented
299
         * somehow! Perhaps by passing special error code up to
300
         * ntfs_load_attributes() so it keeps going trying to get to $DATA
301
         * regardless. Then it would have to restart just like we do here.
302
         */
303
        mft2 = ntfs_malloc(ino->vol->mft_record_size);
304
        if (!mft2) {
305
                ntfs_free(mft);
306
                return -ENOMEM;
307
        }
308
        ntfs_memcpy(mft2, mft, ino->vol->mft_record_size);
309
        while (len2 > 8) {
310
                l = NTFS_GETU16(alist2 + 4);
311
                if (l > len2)
312
                        break;
313
                if (NTFS_GETU32(alist2 + 0x0) < ino->vol->at_data) {
314
                        len2 -= l;
315
                        alist2 += l;
316
                        continue;
317
                }
318
                if (NTFS_GETU32(alist2 + 0x0) > ino->vol->at_data) {
319
                        if (found2)
320
                                break;
321
                        /* Uh-oh! It really isn't there! */
322
                        ntfs_error("Either the $MFT is corrupt or, equally "
323
                                        "likely, the $MFT is too complex for "
324
                                        "the current driver to handle. Please "
325
                                        "email the ntfs maintainer that you "
326
                                        "saw this message. Thank you.\n");
327
                        goto failed_reading_mft_data;
328
                }
329
                /* Process attribute description. */
330
                mftno2 = NTFS_GETU32(alist2 + 0x10);
331
                if (mftno2 != ino->i_number && mftno2 != last_mft2) {
332
                        last_mft2 = mftno2;
333
                        error2 = ntfs_read_mft_record(ino->vol, mftno2, mft2);
334
                        if (error2) {
335
                                ntfs_debug(DEBUG_FILE3, "parse_attributes: "
336
                                        "ntfs_read_mft_record(mftno2 = 0x%x) "
337
                                        "failed\n", mftno2);
338
                                ntfs_free(mft2);
339
                                goto failed_reading_mft_data;
340
                        }
341
                }
342
                attr2 = ntfs_find_attr_in_mft_rec(
343
                                ino->vol,                /* ntfs volume */
344
                                mftno2 == ino->i_number ?/* mft record is: */
345
                                        ino->attr:       /*  base record */
346
                                        mft2,            /*  extension record */
347
                                NTFS_GETU32(alist2 + 0), /* type */
348
                                (wchar_t*)(alist2 + alist2[7]), /* name */
349
                                alist2[6],               /* name length */
350
                                1,                       /* ignore case */
351
                                NTFS_GETU16(alist2 + 24) /* instance number */
352
                                );
353
                if (!attr2) {
354
                        ntfs_error("parse_attributes: mft records 0x%x and/or "
355
                                       "0x%x corrupt!\n", ino->i_number,
356
                                       mftno2);
357
                        ntfs_free(mft2);
358
                        goto failed_reading_mft_data;
359
                }
360
                error2 = ntfs_insert_mft_attribute(ino, mftno2, attr2);
361
                if (error2) {
362
                        ntfs_debug(DEBUG_FILE3, "parse_attributes: "
363
                                "ntfs_insert_mft_attribute(mftno2 0x%x, "
364
                                "attribute2 type 0x%x) failed\n", mftno2,
365
                                NTFS_GETU32(alist2 + 0));
366
                        ntfs_free(mft2);
367
                        goto failed_reading_mft_data;
368
                }
369
                len2 -= l;
370
                alist2 += l;
371
                found2 = 1;
372
        }
373
        ntfs_free(mft2);
374
        tries = 1;
375
        goto continue_after_loading_mft_data;
376
}
377
}
378
 
379
static void ntfs_load_attributes(ntfs_inode *ino)
380
{
381
        ntfs_attribute *alist;
382
        int datasize;
383
        int offset, len, delta;
384
        char *buf;
385
        ntfs_volume *vol = ino->vol;
386
 
387
        ntfs_debug(DEBUG_FILE2, "load_attributes 0x%x 1\n", ino->i_number);
388
        if (ntfs_insert_mft_attributes(ino, ino->attr, ino->i_number))
389
                return;
390
        ntfs_debug(DEBUG_FILE2, "load_attributes 0x%x 2\n", ino->i_number);
391
        alist = ntfs_find_attr(ino, vol->at_attribute_list, 0);
392
        ntfs_debug(DEBUG_FILE2, "load_attributes 0x%x 3\n", ino->i_number);
393
        if (!alist)
394
                return;
395
        ntfs_debug(DEBUG_FILE2, "load_attributes 0x%x 4\n", ino->i_number);
396
        datasize = alist->size;
397
        ntfs_debug(DEBUG_FILE2, "load_attributes 0x%x: alist->size = 0x%x\n",
398
                        ino->i_number, alist->size);
399
        if (alist->resident) {
400
                parse_attributes(ino, alist->d.data, &datasize);
401
                return;
402
        }
403
        ntfs_debug(DEBUG_FILE2, "load_attributes 0x%x 5\n", ino->i_number);
404
        buf = ntfs_malloc(1024);
405
        if (!buf)    /* FIXME: Should be passing error code to caller. (AIA) */
406
                return;
407
        delta = 0;
408
        for (offset = 0; datasize; datasize -= len, offset += len) {
409
                ntfs_io io;
410
 
411
                io.fn_put = ntfs_put;
412
                io.fn_get = 0;
413
                io.param = buf + delta;
414
                len = 1024 - delta;
415
                if (len > datasize)
416
                        len = datasize;
417
                ntfs_debug(DEBUG_FILE2, "load_attributes 0x%x: len = %i\n",
418
                                                ino->i_number, len);
419
                ntfs_debug(DEBUG_FILE2, "load_attributes 0x%x: delta = %i\n",
420
                                                ino->i_number, delta);
421
                io.size = len;
422
                if (ntfs_read_attr(ino, vol->at_attribute_list, 0, offset,
423
                                   &io))
424
                        ntfs_error("error in load_attributes\n");
425
                delta += len;
426
                ntfs_debug(DEBUG_FILE2, "load_attributes 0x%x: after += len, "
427
                                "delta = %i\n", ino->i_number, delta);
428
                parse_attributes(ino, buf, &delta);
429
                ntfs_debug(DEBUG_FILE2, "load_attributes 0x%x: after "
430
                                "parse_attr, delta = %i\n", ino->i_number,
431
                                delta);
432
                if (delta)
433
                        /* Move remaining bytes to buffer start. */
434
                        ntfs_memmove(buf, buf + len - delta, delta);
435
        }
436
        ntfs_debug(DEBUG_FILE2, "load_attributes 0x%x 6\n", ino->i_number);
437
        ntfs_free(buf);
438
}
439
 
440
int ntfs_init_inode(ntfs_inode *ino, ntfs_volume *vol, int inum)
441
{
442
        char *buf;
443
        int error;
444
 
445
        ntfs_debug(DEBUG_FILE1, "Initializing inode 0x%x\n", inum);
446
        ino->i_number = inum;
447
        ino->vol = vol;
448
        ino->attr = buf = ntfs_malloc(vol->mft_record_size);
449
        if (!buf)
450
                return -ENOMEM;
451
        error = ntfs_read_mft_record(vol, inum, ino->attr);
452
        if (error) {
453
                ntfs_debug(DEBUG_OTHER, "Init inode: 0x%x failed\n", inum);
454
                return error;
455
        }
456
        ntfs_debug(DEBUG_FILE2, "Init inode: got mft 0x%x\n", inum);
457
        ino->sequence_number = NTFS_GETU16(buf + 0x10);
458
        ino->attr_count = 0;
459
        ino->record_count = 0;
460
        ino->records = 0;
461
        ino->attrs = 0;
462
        ntfs_load_attributes(ino);
463
        ntfs_debug(DEBUG_FILE2, "Init inode: done 0x%x\n", inum);
464
        return 0;
465
}
466
 
467
void ntfs_clear_inode(ntfs_inode *ino)
468
{
469
        int i;
470
        if (!ino->attr) {
471
                ntfs_error("ntfs_clear_inode: double free\n");
472
                return;
473
        }
474
        ntfs_free(ino->attr);
475
        ino->attr = 0;
476
        ntfs_free(ino->records);
477
        ino->records = 0;
478
        for (i = 0; i < ino->attr_count; i++) {
479
                if (ino->attrs[i].name)
480
                        ntfs_free(ino->attrs[i].name);
481
                if (ino->attrs[i].resident) {
482
                        if (ino->attrs[i].d.data)
483
                                ntfs_free(ino->attrs[i].d.data);
484
                } else {
485
                        if (ino->attrs[i].d.r.runlist)
486
                                ntfs_vfree(ino->attrs[i].d.r.runlist);
487
                }
488
        }
489
        ntfs_free(ino->attrs);
490
        ino->attrs = 0;
491
}
492
 
493
/* Check and fixup a MFT record. */
494
int ntfs_check_mft_record(ntfs_volume *vol, char *record)
495
{
496
        return ntfs_fixup_record(record, "FILE", vol->mft_record_size);
497
}
498
 
499
/* Return (in result) the value indicating the next available attribute
500
 * chunk number. Works for inodes w/o extension records only. */
501
int ntfs_allocate_attr_number(ntfs_inode *ino, int *result)
502
{
503
        if (ino->record_count != 1)
504
                return -EOPNOTSUPP;
505
        *result = NTFS_GETU16(ino->attr + 0x28);
506
        NTFS_PUTU16(ino->attr + 0x28, (*result) + 1);
507
        return 0;
508
}
509
 
510
/* Find the location of an attribute in the inode. A name of NULL indicates
511
 * unnamed attributes. Return pointer to attribute or NULL if not found. */
512
char *ntfs_get_attr(ntfs_inode *ino, int attr, char *name)
513
{
514
        /* Location of first attribute. */
515
        char *it = ino->attr + NTFS_GETU16(ino->attr + 0x14);
516
        int type;
517
        int len;
518
 
519
        /* Only check for magic DWORD here, fixup should have happened before.*/
520
        if (!IS_MFT_RECORD(ino->attr))
521
                return 0;
522
        do {
523
                type = NTFS_GETU32(it);
524
                len = NTFS_GETU16(it + 4);
525
                /* We found the attribute type. Is the name correct, too? */
526
                if (type == attr) {
527
                        int namelen = NTFS_GETU8(it + 9);
528
                        char *name_it, *n = name;
529
                        /* Match given name and attribute name if present.
530
                           Make sure attribute name is Unicode. */
531
                        if (!name) {
532
                                goto check_namelen;
533
                        } else if (namelen) {
534
                                for (name_it = it + NTFS_GETU16(it + 10);
535
                                     namelen; n++, name_it += 2, namelen--)
536
                                        if (*name_it != *n || name_it[1])
537
                                                break;
538
check_namelen:
539
                                if (!namelen)
540
                                        break;
541
                        }
542
                }
543
                it += len;
544
        } while (type != -1); /* List of attributes ends with type -1. */
545
        if (type == -1)
546
                return 0;
547
        return it;
548
}
549
 
550
__s64 ntfs_get_attr_size(ntfs_inode *ino, int type, char *name)
551
{
552
        ntfs_attribute *attr = ntfs_find_attr(ino, type, name);
553
        if (!attr)
554
                return 0;
555
        return
556
                attr->size;
557
}
558
 
559
int ntfs_attr_is_resident(ntfs_inode *ino, int type, char *name)
560
{
561
        ntfs_attribute *attr = ntfs_find_attr(ino, type, name);
562
        if (!attr)
563
                return 0;
564
        return attr->resident;
565
}
566
 
567
/*
568
 * A run is coded as a type indicator, an unsigned length, and a signed cluster
569
 * offset.
570
 * . To save space, length and offset are fields of variable length. The low
571
 *   nibble of the type indicates the width of the length :), the high nibble
572
 *   the width of the offset.
573
 * . The first offset is relative to cluster 0, later offsets are relative to
574
 *   the previous cluster.
575
 *
576
 * This function decodes a run. Length is an output parameter, data and cluster
577
 * are in/out parameters.
578
 */
579
int ntfs_decompress_run(unsigned char **data, int *length,
580
                        ntfs_cluster_t *cluster, int *ctype)
581
{
582
        unsigned char type = *(*data)++;
583
        *ctype = 0;
584
        switch (type & 0xF) {
585
        case 1:
586
                *length = NTFS_GETS8(*data);
587
                break;
588
        case 2:
589
                *length = NTFS_GETS16(*data);
590
                break;
591
        case 3:
592
                *length = NTFS_GETS24(*data);
593
                break;
594
        case 4:
595
                *length = NTFS_GETS32(*data);
596
                break;
597
                /* Note: cases 5-8 are probably pointless to code, since how
598
                 * many runs > 4GB of length are there? At the most, cases 5
599
                 * and 6 are probably necessary, and would also require making
600
                 * length 64-bit throughout. */
601
        default:
602
                ntfs_error("Can't decode run type field 0x%x\n", type);
603
                return -1;
604
        }
605
//      ntfs_debug(DEBUG_FILE3, "ntfs_decompress_run: length = 0x%x\n",*length);
606
        if (*length < 0)
607
        {
608
                ntfs_error("Negative run length decoded\n");
609
                return -1;
610
        }
611
        *data += (type & 0xF);
612
        switch (type & 0xF0) {
613
        case 0:
614
                *ctype = 2;
615
                break;
616
        case 0x10:
617
                *cluster += NTFS_GETS8(*data);
618
                break;
619
        case 0x20:
620
                *cluster += NTFS_GETS16(*data);
621
                break;
622
        case 0x30:
623
                *cluster += NTFS_GETS24(*data);
624
                break;
625
        case 0x40:
626
                *cluster += NTFS_GETS32(*data);
627
                break;
628
#if 0 /* Keep for future, in case ntfs_cluster_t ever becomes 64bit. */
629
        case 0x50:
630
                *cluster += NTFS_GETS40(*data);
631
                break;
632
        case 0x60:
633
                *cluster += NTFS_GETS48(*data);
634
                break;
635
        case 0x70:
636
                *cluster += NTFS_GETS56(*data);
637
                break;
638
        case 0x80:
639
                *cluster += NTFS_GETS64(*data);
640
                break;
641
#endif
642
        default:
643
                ntfs_error("Can't decode run type field 0x%x\n", type);
644
                return -1;
645
        }
646
//      ntfs_debug(DEBUG_FILE3, "ntfs_decompress_run: cluster = 0x%x\n",
647
//                                                              *cluster);
648
        *data += (type >> 4);
649
        return 0;
650
}
651
 
652
static void dump_runlist(const ntfs_runlist *rl, const int rlen);
653
 
654
/*
655
 * FIXME: ntfs_readwrite_attr() has the effect of writing @dest to @offset of
656
 * the attribute value of the attribute @attr in the in memory inode @ino.
657
 * If the attribute value of @attr is non-resident the value's contents at
658
 * @offset are actually written to disk (from @dest). The on disk mft record
659
 * describing the non-resident attribute value is not updated!
660
 * If the attribute value is resident then the value is written only in
661
 * memory. The on disk mft record containing the value is not written to disk.
662
 * A possible fix would be to call ntfs_update_inode() before returning. (AIA)
663
 */
664
/* Reads l bytes of the attribute (attr, name) of ino starting at offset on
665
 * vol into buf. Returns the number of bytes read in the ntfs_io struct.
666
 * Returns 0 on success, errno on failure */
667
int ntfs_readwrite_attr(ntfs_inode *ino, ntfs_attribute *attr, __s64 offset,
668
                ntfs_io *dest)
669
{
670
        int rnum, s_vcn, error, clustersizebits;
671
        ntfs_cluster_t cluster, s_cluster, vcn, len;
672
        __s64 l, chunk, copied;
673
 
674
        ntfs_debug(DEBUG_FILE3, "%s(): %s 0x%x bytes at offset "
675
                        "0x%Lx %s inode 0x%x, attr type 0x%x.\n", __FUNCTION__,
676
                        dest->do_read ? "Read" : "Write", dest->size, offset,
677
                        dest->do_read ? "from" : "to", ino->i_number,
678
                        attr->type);
679
        l = dest->size;
680
        if (l == 0)
681
                return 0;
682
        if (dest->do_read) {
683
                /* If read _starts_ beyond end of stream, return nothing. */
684
                if (offset >= attr->size) {
685
                        dest->size = 0;
686
                        return 0;
687
                }
688
                /* If read _extends_ beyond end of stream, return as much
689
                 * initialised data as we have. */
690
                if (offset + l >= attr->size)
691
                        l = dest->size = attr->size - offset;
692
        } else {
693
                /*
694
                 * If write extends beyond _allocated_ size, extend attribute,
695
                 * updating attr->allocated and attr->size in the process. (AIA)
696
                 */
697
                if ((!attr->resident && offset + l > attr->allocated) ||
698
                                (attr->resident && offset + l > attr->size)) {
699
                        error = ntfs_resize_attr(ino, attr, offset + l);
700
                        if (error)
701
                                return error;
702
                }
703
                if (!attr->resident) {
704
                        /* Has amount of data increased? */
705
                        if (offset + l > attr->size)
706
                                attr->size = offset + l;
707
                        /* Has amount of initialised data increased? */
708
                        if (offset + l > attr->initialized) {
709
                                /* FIXME: Clear the section between the old
710
                                 * initialised length and the write start.
711
                                 * (AIA) */
712
                                attr->initialized = offset + l;
713
                        }
714
                }
715
        }
716
        if (attr->resident) {
717
                if (dest->do_read)
718
                        dest->fn_put(dest, (ntfs_u8*)attr->d.data + offset, l);
719
                else
720
                        dest->fn_get((ntfs_u8*)attr->d.data + offset, dest, l);
721
                dest->size = l;
722
                return 0;
723
        }
724
        if (dest->do_read) {
725
                /* Read uninitialized data. */
726
                if (offset >= attr->initialized)
727
                        return ntfs_read_zero(dest, l);
728
                if (offset + l > attr->initialized) {
729
                        dest->size = chunk = attr->initialized - offset;
730
                        error = ntfs_readwrite_attr(ino, attr, offset, dest);
731
                        if (error || (dest->size != chunk && (error = -EIO, 1)))
732
                                return error;
733
                        dest->size += l - chunk;
734
                        return ntfs_read_zero(dest, l - chunk);
735
                }
736
                if (attr->flags & ATTR_IS_COMPRESSED)
737
                        return ntfs_read_compressed(ino, attr, offset, dest);
738
        } else {
739
                if (attr->flags & ATTR_IS_COMPRESSED)
740
                        return ntfs_write_compressed(ino, attr, offset, dest);
741
        }
742
        vcn = 0;
743
        clustersizebits = ino->vol->cluster_size_bits;
744
        s_vcn = offset >> clustersizebits;
745
        for (rnum = 0; rnum < attr->d.r.len &&
746
                        vcn + attr->d.r.runlist[rnum].len <= s_vcn; rnum++)
747
                vcn += attr->d.r.runlist[rnum].len;
748
        if (rnum == attr->d.r.len) {
749
                ntfs_debug(DEBUG_FILE3, "%s(): EOPNOTSUPP: "
750
                        "inode = 0x%x, rnum = %i, offset = 0x%Lx, vcn = 0x%x, "
751
                        "s_vcn = 0x%x.\n", __FUNCTION__, ino->i_number, rnum,
752
                        offset, vcn, s_vcn);
753
                dump_runlist(attr->d.r.runlist, attr->d.r.len);
754
                /*FIXME: Should extend runlist. */
755
                return -EOPNOTSUPP;
756
        }
757
        copied = 0;
758
        while (l) {
759
                s_vcn = offset >> clustersizebits;
760
                cluster = attr->d.r.runlist[rnum].lcn;
761
                len = attr->d.r.runlist[rnum].len;
762
                s_cluster = cluster + s_vcn - vcn;
763
                chunk = ((__s64)(vcn + len) << clustersizebits) - offset;
764
                if (chunk > l)
765
                        chunk = l;
766
                dest->size = chunk;
767
                error = ntfs_getput_clusters(ino->vol, s_cluster, offset -
768
                                ((__s64)s_vcn << clustersizebits), dest);
769
                if (error) {
770
                        ntfs_error("Read/write error.\n");
771
                        dest->size = copied;
772
                        return error;
773
                }
774
                l -= chunk;
775
                copied += chunk;
776
                offset += chunk;
777
                if (l && offset >= ((__s64)(vcn + len) << clustersizebits)) {
778
                        rnum++;
779
                        vcn += len;
780
                        cluster = attr->d.r.runlist[rnum].lcn;
781
                        len = attr->d.r.runlist[rnum].len;
782
                }
783
        }
784
        dest->size = copied;
785
        return 0;
786
}
787
 
788
int ntfs_read_attr(ntfs_inode *ino, int type, char *name, __s64 offset,
789
                   ntfs_io *buf)
790
{
791
        ntfs_attribute *attr;
792
 
793
        buf->do_read = 1;
794
        attr = ntfs_find_attr(ino, type, name);
795
        if (!attr) {
796
                ntfs_debug(DEBUG_FILE3, "%s(): attr 0x%x not found in inode "
797
                                "0x%x\n", __FUNCTION__, type, ino->i_number);
798
                return -EINVAL;
799
        }
800
        return ntfs_readwrite_attr(ino, attr, offset, buf);
801
}
802
 
803
int ntfs_write_attr(ntfs_inode *ino, int type, char *name, __s64 offset,
804
                    ntfs_io *buf)
805
{
806
        ntfs_attribute *attr;
807
 
808
        buf->do_read = 0;
809
        attr = ntfs_find_attr(ino, type, name);
810
        if (!attr) {
811
                ntfs_debug(DEBUG_FILE3, "%s(): attr 0x%x not found in inode "
812
                                "0x%x\n", __FUNCTION__, type, ino->i_number);
813
                return -EINVAL;
814
        }
815
        return ntfs_readwrite_attr(ino, attr, offset, buf);
816
}
817
 
818
/* -2 = error, -1 = hole, >= 0 means real disk cluster (lcn). */
819
int ntfs_vcn_to_lcn(ntfs_inode *ino, int vcn)
820
{
821
        int rnum;
822
        ntfs_attribute *data;
823
 
824
        data = ntfs_find_attr(ino, ino->vol->at_data, 0);
825
        if (!data || data->resident || data->flags & (ATTR_IS_COMPRESSED |
826
                        ATTR_IS_ENCRYPTED))
827
                return -2;
828
        if (data->size <= (__s64)vcn << ino->vol->cluster_size_bits)
829
                return -2;
830
        if (data->initialized <= (__s64)vcn << ino->vol->cluster_size_bits)
831
                return -1;
832
        for (rnum = 0; rnum < data->d.r.len &&
833
                        vcn >= data->d.r.runlist[rnum].len; rnum++)
834
                vcn -= data->d.r.runlist[rnum].len;
835
        if (data->d.r.runlist[rnum].lcn >= 0)
836
                return data->d.r.runlist[rnum].lcn + vcn;
837
        return data->d.r.runlist[rnum].lcn + vcn;
838
}
839
 
840
static int allocate_store(ntfs_volume *vol, ntfs_disk_inode *store, int count)
841
{
842
        int i;
843
 
844
        if (store->count > count)
845
                return 0;
846
        if (store->size < count) {
847
                ntfs_mft_record *n = ntfs_malloc((count + 4) *
848
                                                 sizeof(ntfs_mft_record));
849
                if (!n)
850
                        return -ENOMEM;
851
                if (store->size) {
852
                        for (i = 0; i < store->size; i++)
853
                                n[i] = store->records[i];
854
                        ntfs_free(store->records);
855
                }
856
                store->size = count + 4;
857
                store->records = n;
858
        }
859
        for (i = store->count; i < count; i++) {
860
                store->records[i].record = ntfs_malloc(vol->mft_record_size);
861
                if (!store->records[i].record)
862
                        return -ENOMEM;
863
                store->count++;
864
        }
865
        return 0;
866
}
867
 
868
static void deallocate_store(ntfs_disk_inode* store)
869
{
870
        int i;
871
 
872
        for (i = 0; i < store->count; i++)
873
                ntfs_free(store->records[i].record);
874
        ntfs_free(store->records);
875
        store->count = store->size = 0;
876
        store->records = 0;
877
}
878
 
879
/**
880
 * layout_runs - compress runlist into mapping pairs array
881
 * @attr:       attribute containing the runlist to compress
882
 * @rec:        destination buffer to hold the mapping pairs array
883
 * @offs:       current position in @rec (in/out variable)
884
 * @size:       size of the buffer @rec
885
 *
886
 * layout_runs walks the runlist in @attr, compresses it and writes it out the
887
 * resulting mapping pairs array into @rec (up to a maximum of @size bytes are
888
 * written). On entry @offs is the offset in @rec at which to begin writing the
889
 * mapping pairs array. On exit, it contains the offset in @rec of the first
890
 * byte after the end of the mapping pairs array.
891
 */
892
static int layout_runs(ntfs_attribute *attr, char *rec, int *offs, int size)
893
{
894
        int i, len, offset, coffs;
895
        /* ntfs_cluster_t MUST be signed! (AIA) */
896
        ntfs_cluster_t cluster, rclus;
897
        ntfs_runlist *rl = attr->d.r.runlist;
898
        cluster = 0;
899
        offset = *offs;
900
        for (i = 0; i < attr->d.r.len; i++) {
901
                /*
902
                 * We cheat with this check on the basis that lcn will never
903
                 * be less than -1 and the lcn delta will fit in signed
904
                 * 32-bits (ntfs_cluster_t). (AIA)
905
                 */
906
                if (rl[i].lcn < (ntfs_cluster_t)-1) {
907
                        ntfs_error("layout_runs() encountered an out of bounds "
908
                                        "cluster delta, lcn = %i.\n",
909
                                        rl[i].lcn);
910
                        return -ERANGE;
911
                }
912
                rclus = rl[i].lcn - cluster;
913
                len = rl[i].len;
914
                rec[offset] = 0;
915
                if (offset + 9 > size)
916
                        return -E2BIG; /* It might still fit, but this
917
                                        * simplifies testing. */
918
                /*
919
                 * Run length is stored as signed number, so deal with it
920
                 * properly, i.e. observe that a negative number will have all
921
                 * its most significant bits set to 1 but we don't store that
922
                 * in the mapping pairs array. We store the smallest type of
923
                 * negative number required, thus in the first if we check
924
                 * whether len fits inside a signed byte and if so we store it
925
                 * as such, the next ifs check for a signed short, then a signed
926
                 * 24-bit and finally the full blown signed 32-bit. Same goes
927
                 * for rlus below. (AIA)
928
                 */
929
                if (len >= -0x80 && len <= 0x7f) {
930
                        NTFS_PUTU8(rec + offset + 1, len & 0xff);
931
                        coffs = 1;
932
                } else if (len >= -0x8000 && len <= 0x7fff) {
933
                        NTFS_PUTU16(rec + offset + 1, len & 0xffff);
934
                        coffs = 2;
935
                } else if (len >= -0x800000 && len <= 0x7fffff) {
936
                        NTFS_PUTU24(rec + offset + 1, len & 0xffffff);
937
                        coffs = 3;
938
                } else /* if (len >= -0x80000000LL && len <= 0x7fffffff */ {
939
                        NTFS_PUTU32(rec + offset + 1, len);
940
                        coffs = 4;
941
                } /* else ... FIXME: When len becomes 64-bit we need to extend
942
                   *                 the else if () statements. (AIA) */
943
                *(rec + offset) |= coffs++;
944
                if (rl[i].lcn == (ntfs_cluster_t)-1) /* Compressed run. */
945
                        /* Nothing */;
946
                else if (rclus >= -0x80 && rclus <= 0x7f) {
947
                        *(rec + offset) |= 0x10;
948
                        NTFS_PUTS8(rec + offset + coffs, rclus & 0xff);
949
                        coffs += 1;
950
                } else if (rclus >= -0x8000 && rclus <= 0x7fff) {
951
                        *(rec + offset) |= 0x20;
952
                        NTFS_PUTS16(rec + offset + coffs, rclus & 0xffff);
953
                        coffs += 2;
954
                } else if (rclus >= -0x800000 && rclus <= 0x7fffff) {
955
                        *(rec + offset) |= 0x30;
956
                        NTFS_PUTS24(rec + offset + coffs, rclus & 0xffffff);
957
                        coffs += 3;
958
                } else /* if (rclus >= -0x80000000LL && rclus <= 0x7fffffff)*/ {
959
                        *(rec + offset) |= 0x40;
960
                        NTFS_PUTS32(rec + offset + coffs, rclus
961
                                                        /* & 0xffffffffLL */);
962
                        coffs += 4;
963
                } /* FIXME: When rclus becomes 64-bit.
964
                else if (rclus >= -0x8000000000 && rclus <= 0x7FFFFFFFFF) {
965
                        *(rec + offset) |= 0x50;
966
                        NTFS_PUTS40(rec + offset + coffs, rclus &
967
                                                        0xffffffffffLL);
968
                        coffs += 5;
969
                } else if (rclus >= -0x800000000000 &&
970
                                                rclus <= 0x7FFFFFFFFFFF) {
971
                        *(rec + offset) |= 0x60;
972
                        NTFS_PUTS48(rec + offset + coffs, rclus &
973
                                                        0xffffffffffffLL);
974
                        coffs += 6;
975
                } else if (rclus >= -0x80000000000000 &&
976
                                                rclus <= 0x7FFFFFFFFFFFFF) {
977
                        *(rec + offset) |= 0x70;
978
                        NTFS_PUTS56(rec + offset + coffs, rclus &
979
                                                        0xffffffffffffffLL);
980
                        coffs += 7;
981
                } else {
982
                        *(rec + offset) |= 0x80;
983
                        NTFS_PUTS64(rec + offset + coffs, rclus);
984
                        coffs += 8;
985
                } */
986
                offset += coffs;
987
                if (rl[i].lcn)
988
                        cluster = rl[i].lcn;
989
        }
990
        if (offset >= size)
991
                return -E2BIG;
992
        /* Terminating null. */
993
        *(rec + offset++) = 0;
994
        *offs = offset;
995
        return 0;
996
}
997
 
998
static void count_runs(ntfs_attribute *attr, char *buf)
999
{
1000
        ntfs_u32 first, count, last, i;
1001
 
1002
        first = 0;
1003
        for (i = 0, count = 0; i < attr->d.r.len; i++)
1004
                count += attr->d.r.runlist[i].len;
1005
        last = first + count - 1;
1006
        NTFS_PUTU64(buf + 0x10, first);
1007
        NTFS_PUTU64(buf + 0x18, last);
1008
}
1009
 
1010
/**
1011
 * layout_attr - convert in memory attribute to on disk attribute record
1012
 * @attr:       in memory attribute to convert
1013
 * @buf:        destination buffer for on disk attribute record
1014
 * @size:       size of the destination buffer
1015
 * @psize:      size of converted on disk attribute record (out variable)
1016
 *
1017
 * layout_attr() takes the attribute @attr and converts it into the appropriate
1018
 * on disk structure, writing it into @buf (up to @size bytes are written).
1019
 *
1020
 * On success we return 0 and set @*psize to the actual byte size of the on-
1021
 * disk attribute that was written into @buf.
1022
 */
1023
static int layout_attr(ntfs_attribute *attr, char *buf, int size, int *psize)
1024
{
1025
        int nameoff, hdrsize, asize;
1026
 
1027
        if (attr->resident) {
1028
                nameoff = 0x18;
1029
                hdrsize = (nameoff + 2 * attr->namelen + 7) & ~7;
1030
                asize = (hdrsize + attr->size + 7) & ~7;
1031
                if (size < asize)
1032
                        return -E2BIG;
1033
                NTFS_PUTU32(buf + 0x10, attr->size);
1034
                NTFS_PUTU8(buf + 0x16, attr->indexed);
1035
                NTFS_PUTU16(buf + 0x14, hdrsize);
1036
                if (attr->size)
1037
                        ntfs_memcpy(buf + hdrsize, attr->d.data, attr->size);
1038
        } else {
1039
                int error;
1040
 
1041
                if (attr->flags & ATTR_IS_COMPRESSED)
1042
                        nameoff = 0x48;
1043
                else
1044
                        nameoff = 0x40;
1045
                hdrsize = (nameoff + 2 * attr->namelen + 7) & ~7;
1046
                if (size < hdrsize)
1047
                        return -E2BIG;
1048
                /* Make asize point at the end of the attribute record header,
1049
                   i.e. at the beginning of the mapping pairs array. */
1050
                asize = hdrsize;
1051
                error = layout_runs(attr, buf, &asize, size);
1052
                /* Now, asize points one byte beyond the end of the mapping
1053
                   pairs array. */
1054
                if (error)
1055
                        return error;
1056
                /* The next attribute has to begin on 8-byte boundary. */
1057
                asize = (asize + 7) & ~7;
1058
                /* FIXME: fragments */
1059
                count_runs(attr, buf);
1060
                NTFS_PUTU16(buf + 0x20, hdrsize);
1061
                NTFS_PUTU16(buf + 0x22, attr->cengine);
1062
                NTFS_PUTU32(buf + 0x24, 0);
1063
                NTFS_PUTS64(buf + 0x28, attr->allocated);
1064
                NTFS_PUTS64(buf + 0x30, attr->size);
1065
                NTFS_PUTS64(buf + 0x38, attr->initialized);
1066
                if (attr->flags & ATTR_IS_COMPRESSED)
1067
                        NTFS_PUTS64(buf + 0x40, attr->compsize);
1068
        }
1069
        NTFS_PUTU32(buf, attr->type);
1070
        NTFS_PUTU32(buf + 4, asize);
1071
        NTFS_PUTU8(buf + 8, attr->resident ? 0 : 1);
1072
        NTFS_PUTU8(buf + 9, attr->namelen);
1073
        NTFS_PUTU16(buf + 0xa, nameoff);
1074
        NTFS_PUTU16(buf + 0xc, attr->flags);
1075
        NTFS_PUTU16(buf + 0xe, attr->attrno);
1076
        if (attr->namelen)
1077
                ntfs_memcpy(buf + nameoff, attr->name, 2 * attr->namelen);
1078
        *psize = asize;
1079
        return 0;
1080
}
1081
 
1082
/**
1083
 * layout_inode - convert an in-memory inode into on disk mft record(s)
1084
 * @ino:        in memory inode to convert
1085
 * @store:      on disk inode, contain buffers for the on disk mft record(s)
1086
 *
1087
 * layout_inode takes the in memory inode @ino, converts it into a (sequence of)
1088
 * mft record(s) and writes them to the appropriate buffers in the @store.
1089
 *
1090
 * Return 0 on success,
1091
 * the required mft record count (>0) if the inode does not fit,
1092
 * -ENOMEM if memory allocation problem, or
1093
 * -EOPNOTSUP if beyond our capabilities.
1094
 *
1095
 * TODO: We at the moment do not support extension mft records. (AIA)
1096
 */
1097
int layout_inode(ntfs_inode *ino, ntfs_disk_inode *store)
1098
{
1099
        int offset, i, size, psize, error, count, recno;
1100
        ntfs_attribute *attr;
1101
        unsigned char *rec;
1102
 
1103
        error = allocate_store(ino->vol, store, ino->record_count);
1104
        if (error)
1105
                return error;
1106
        size = ino->vol->mft_record_size;
1107
        count = i = 0;
1108
        do {
1109
                if (count < ino->record_count) {
1110
                        recno = ino->records[count];
1111
                } else {
1112
                        error = allocate_store(ino->vol, store, count + 1);
1113
                        if (error)
1114
                                return error;
1115
                        recno = -1;
1116
                }
1117
                /*
1118
                 * FIXME: We need to support extension records properly.
1119
                 * At the moment they wouldn't work. Probably would "just" get
1120
                 * corrupted if we write to them... (AIA)
1121
                 */
1122
                store->records[count].recno = recno;
1123
                rec = store->records[count].record;
1124
                count++;
1125
                /* Copy mft record header. */
1126
                offset = NTFS_GETU16(ino->attr + 0x14); /* attrs_offset */
1127
                ntfs_memcpy(rec, ino->attr, offset);
1128
                /* Copy attributes. */
1129
                while (i < ino->attr_count) {
1130
                        attr = ino->attrs + i;
1131
                        error = layout_attr(attr, rec + offset,
1132
                                        size - offset - 8, &psize);
1133
                        if (error == -E2BIG && offset != NTFS_GETU16(ino->attr
1134
                                        + 0x14))
1135
                                break;
1136
                        if (error)
1137
                                return error;
1138
                        offset += psize;
1139
                        i++;
1140
                }
1141
                /* Terminating attribute. */
1142
                NTFS_PUTU32(rec + offset, 0xFFFFFFFF);
1143
                offset += 4;
1144
                NTFS_PUTU32(rec + offset, 0);
1145
                offset += 4;
1146
                NTFS_PUTU32(rec + 0x18, offset);
1147
        } while (i < ino->attr_count || count < ino->record_count);
1148
        return count - ino->record_count;
1149
}
1150
 
1151
/*
1152
 * FIXME: ntfs_update_inode() calls layout_inode() to create the mft record on
1153
 * disk structure corresponding to the inode @ino. After that, ntfs_write_attr()
1154
 * is called to write out the created mft record to disk.
1155
 * We shouldn't need to re-layout every single time we are updating an mft
1156
 * record. No wonder the ntfs driver is slow like hell. (AIA)
1157
 */
1158
int ntfs_update_inode(ntfs_inode *ino)
1159
{
1160
        int error, i;
1161
        ntfs_disk_inode store;
1162
        ntfs_io io;
1163
 
1164
        ntfs_bzero(&store, sizeof(store));
1165
        error = layout_inode(ino, &store);
1166
        if (error == -E2BIG) {
1167
                i = ntfs_split_indexroot(ino);
1168
                if (i != -ENOTDIR) {
1169
                        if (!i)
1170
                                i = layout_inode(ino, &store);
1171
                        error = i;
1172
                }
1173
        }
1174
        if (error == -E2BIG) {
1175
                error = ntfs_attr_allnonresident(ino);
1176
                if (!error)
1177
                        error = layout_inode(ino, &store);
1178
        }
1179
        if (error > 0) {
1180
                /* FIXME: Introduce extension records. */
1181
                error = -E2BIG;
1182
        }
1183
        if (error) {
1184
                if (error == -E2BIG)
1185
                        ntfs_error("Cannot handle saving inode 0x%x.\n",
1186
                                   ino->i_number);
1187
                deallocate_store(&store);
1188
                return error;
1189
        }
1190
        io.fn_get = ntfs_get;
1191
        io.fn_put = 0;
1192
        for (i = 0; i < store.count; i++) {
1193
                error = ntfs_insert_fixups(store.records[i].record,
1194
                                ino->vol->mft_record_size);
1195
                if (error) {
1196
                        printk(KERN_ALERT "NTFS: ntfs_update_inode() caught "
1197
                                        "corrupt %s mtf record ntfs record "
1198
                                        "header. Refusing to write corrupt "
1199
                                        "data to disk. Unmount and run chkdsk "
1200
                                        "immediately!\n", i ? "extension":
1201
                                        "base");
1202
                        deallocate_store(&store);
1203
                        return -EIO;
1204
                }
1205
                io.param = store.records[i].record;
1206
                io.size = ino->vol->mft_record_size;
1207
                error = ntfs_write_attr(ino->vol->mft_ino, ino->vol->at_data,
1208
                                0, (__s64)store.records[i].recno <<
1209
                                ino->vol->mft_record_size_bits, &io);
1210
                if (error || io.size != ino->vol->mft_record_size) {
1211
                        /* Big trouble, partially written file. */
1212
                        ntfs_error("Please unmount: Write error in inode "
1213
                                        "0x%x\n", ino->i_number);
1214
                        deallocate_store(&store);
1215
                        return error ? error : -EIO;
1216
                }
1217
        }
1218
        deallocate_store(&store);
1219
        return 0;
1220
}
1221
 
1222
void ntfs_decompress(unsigned char *dest, unsigned char *src, ntfs_size_t l)
1223
{
1224
        int head, comp;
1225
        int copied = 0;
1226
        unsigned char *stop;
1227
        int bits;
1228
        int tag = 0;
1229
        int clear_pos;
1230
 
1231
        while (1) {
1232
                head = NTFS_GETU16(src) & 0xFFF;
1233
                /* High bit indicates that compression was performed. */
1234
                comp = NTFS_GETU16(src) & 0x8000;
1235
                src += 2;
1236
                stop = src + head;
1237
                bits = 0;
1238
                clear_pos = 0;
1239
                if (head == 0)
1240
                        /* Block is not used. */
1241
                        return;/* FIXME: copied */
1242
                if (!comp) { /* uncompressible */
1243
                        ntfs_memcpy(dest, src, 0x1000);
1244
                        dest += 0x1000;
1245
                        copied += 0x1000;
1246
                        src += 0x1000;
1247
                        if (l == copied)
1248
                                return;
1249
                        continue;
1250
                }
1251
                while (src <= stop) {
1252
                        if (clear_pos > 4096) {
1253
                                ntfs_error("Error 1 in decompress\n");
1254
                                return;
1255
                        }
1256
                        if (!bits) {
1257
                                tag = NTFS_GETU8(src);
1258
                                bits = 8;
1259
                                src++;
1260
                                if (src > stop)
1261
                                        break;
1262
                        }
1263
                        if (tag & 1) {
1264
                                int i, len, delta, code, lmask, dshift;
1265
                                code = NTFS_GETU16(src);
1266
                                src += 2;
1267
                                if (!clear_pos) {
1268
                                        ntfs_error("Error 2 in decompress\n");
1269
                                        return;
1270
                                }
1271
                                for (i = clear_pos - 1, lmask = 0xFFF,
1272
                                     dshift = 12; i >= 0x10; i >>= 1) {
1273
                                        lmask >>= 1;
1274
                                        dshift--;
1275
                                }
1276
                                delta = code >> dshift;
1277
                                len = (code & lmask) + 3;
1278
                                for (i = 0; i < len; i++) {
1279
                                        dest[clear_pos] = dest[clear_pos -
1280
                                                                    delta - 1];
1281
                                        clear_pos++;
1282
                                        copied++;
1283
                                        if (copied==l)
1284
                                                return;
1285
                                }
1286
                        } else {
1287
                                dest[clear_pos++] = NTFS_GETU8(src);
1288
                                src++;
1289
                                copied++;
1290
                                if (copied==l)
1291
                                        return;
1292
                        }
1293
                        tag >>= 1;
1294
                        bits--;
1295
                }
1296
                dest += clear_pos;
1297
        }
1298
}
1299
 
1300
/*
1301
 * NOTE: Neither of the ntfs_*_bit functions are atomic! But we don't need
1302
 * them atomic at present as we never operate on shared/cached bitmaps.
1303
 */
1304
static __inline__ int ntfs_test_bit(unsigned char *byte, const int bit)
1305
{
1306
        return byte[bit >> 3] & (1 << (bit & 7)) ? 1 : 0;
1307
}
1308
 
1309
static __inline__ void ntfs_set_bit(unsigned char *byte, const int bit)
1310
{
1311
        byte[bit >> 3] |= 1 << (bit & 7);
1312
}
1313
 
1314
static __inline__ void ntfs_clear_bit(unsigned char *byte, const int bit)
1315
{
1316
        byte[bit >> 3] &= ~(1 << (bit & 7));
1317
}
1318
 
1319
static __inline__ int ntfs_test_and_clear_bit(unsigned char *byte,
1320
                const int bit)
1321
{
1322
        unsigned char *ptr = byte + (bit >> 3);
1323
        int b = 1 << (bit & 7);
1324
        int oldbit = *ptr & b ? 1 : 0;
1325
        *ptr &= ~b;
1326
        return oldbit;
1327
}
1328
 
1329
static void dump_runlist(const ntfs_runlist *rl, const int rlen)
1330
{
1331
#ifdef DEBUG
1332
        int i;
1333
        ntfs_cluster_t ct;
1334
 
1335
        ntfs_debug(DEBUG_OTHER, "%s(): rlen = %i.\n", __FUNCTION__, rlen);
1336
        ntfs_debug(DEBUG_OTHER, "VCN        LCN        Run length\n");
1337
        for (i = 0, ct = 0; i < rlen; ct += rl[i++].len) {
1338
                if (rl[i].lcn == (ntfs_cluster_t)-1)
1339
                        ntfs_debug(DEBUG_OTHER, "0x%-8x LCN_HOLE   0x%-8x "
1340
                                        "(%s)\n", ct, rl[i].len, rl[i].len ?
1341
                                        "sparse run" : "run list end");
1342
                else
1343
                        ntfs_debug(DEBUG_OTHER, "0x%-8x 0x%-8x 0x%-8x%s\n", ct,
1344
                                        rl[i].lcn, rl[i].len, rl[i].len &&
1345
                                        i + 1 < rlen ? "" : " (run list end)");
1346
                if (!rl[i].len)
1347
                        break;
1348
        }
1349
#endif
1350
}
1351
 
1352
/**
1353
 * splice_runlists - splice two run lists into one
1354
 * @rl1:        pointer to address of first run list
1355
 * @r1len:      number of elementfs in first run list
1356
 * @rl2:        pointer to second run list
1357
 * @r2len:      number of elements in second run list
1358
 *
1359
 * Append the run list @rl2 to the run list *@rl1 and return the result in
1360
 * *@rl1 and *@r1len.
1361
 *
1362
 * Return 0 on success or -errno on error, in which case *@rl1 and *@r1len are
1363
 * left untouched.
1364
 *
1365
 * The only possible error code at the moment is -ENOMEM and only happens if
1366
 * there is insufficient memory to allocate the new run list (only happens
1367
 * when size of (rl1 + rl2) > allocated size of rl1).
1368
 */
1369
int splice_runlists(ntfs_runlist **rl1, int *r1len, const ntfs_runlist *rl2,
1370
                int r2len)
1371
{
1372
        ntfs_runlist *rl;
1373
        int rlen, rl_size, rl2_pos;
1374
 
1375
        ntfs_debug(DEBUG_OTHER, "%s(): Entering with *r1len = %i, "
1376
                        "r2len = %i.\n", __FUNCTION__, *r1len, r2len);
1377
        ntfs_debug(DEBUG_OTHER, "%s(): Dumping 1st runlist.\n", __FUNCTION__);
1378
        if (*rl1)
1379
                dump_runlist(*rl1, *r1len);
1380
        else
1381
                ntfs_debug(DEBUG_OTHER, "%s(): Not present.\n", __FUNCTION__);
1382
        ntfs_debug(DEBUG_OTHER, "%s(): Dumping 2nd runlist.\n", __FUNCTION__);
1383
        dump_runlist(rl2, r2len);
1384
        rlen = *r1len + r2len + 1;
1385
        rl_size = (rlen * sizeof(ntfs_runlist) + PAGE_SIZE - 1) &
1386
                        PAGE_MASK;
1387
        ntfs_debug(DEBUG_OTHER, "%s(): rlen = %i, rl_size = %i.\n",
1388
                        __FUNCTION__, rlen, rl_size);
1389
        /* Do we have enough space? */
1390
        if (rl_size <= ((*r1len * sizeof(ntfs_runlist) + PAGE_SIZE - 1) &
1391
                        PAGE_MASK)) {
1392
                /* Have enough space already. */
1393
                rl = *rl1;
1394
                ntfs_debug(DEBUG_OTHER, "%s(): Have enough space already.\n",
1395
                                __FUNCTION__);
1396
        } else {
1397
                /* Need more space. Reallocate. */
1398
                ntfs_debug(DEBUG_OTHER, "%s(): Need more space.\n",
1399
                                __FUNCTION__);
1400
                rl = ntfs_vmalloc(rlen << sizeof(ntfs_runlist));
1401
                if (!rl)
1402
                        return -ENOMEM;
1403
                /* Copy over rl1. */
1404
                ntfs_memcpy(rl, *rl1, *r1len * sizeof(ntfs_runlist));
1405
                ntfs_vfree(*rl1);
1406
                *rl1 = rl;
1407
        }
1408
        /* Reuse rl_size as the current position index into rl. */
1409
        rl_size = *r1len - 1;
1410
        ntfs_debug(DEBUG_OTHER, "%s(): rl_size = %i.\n", __FUNCTION__,rl_size);
1411
        /* Coalesce neighbouring elements, if present. */
1412
        rl2_pos = 0;
1413
        if (rl[rl_size].lcn + rl[rl_size].len == rl2[rl2_pos].lcn) {
1414
                ntfs_debug(DEBUG_OTHER, "%s(): Coalescing adjacent runs.\n",
1415
                                __FUNCTION__);
1416
                ntfs_debug(DEBUG_OTHER, "%s(): Before: rl[rl_size].len = %i.\n",
1417
                                __FUNCTION__, rl[rl_size].len);
1418
                rl[rl_size].len += rl2[rl2_pos].len;
1419
                ntfs_debug(DEBUG_OTHER, "%s(): After: rl[rl_size].len = %i.\n",
1420
                                __FUNCTION__, rl[rl_size].len);
1421
                rl2_pos++;
1422
                r2len--;
1423
                rlen--;
1424
        }
1425
        rl_size++;
1426
        /* Copy over rl2. */
1427
        ntfs_memcpy(rl + rl_size, rl2 + rl2_pos, r2len * sizeof(ntfs_runlist));
1428
        rlen--;
1429
        rl[rlen].lcn = (ntfs_cluster_t)-1;
1430
        rl[rlen].len = (ntfs_cluster_t)0;
1431
        *r1len = rlen;
1432
        ntfs_debug(DEBUG_OTHER, "%s(): Dumping result runlist.\n",
1433
                        __FUNCTION__);
1434
        dump_runlist(*rl1, *r1len);
1435
        ntfs_debug(DEBUG_OTHER, "%s(): Returning with *r1len = %i.\n",
1436
                        __FUNCTION__, rlen);
1437
        return 0;
1438
}
1439
 
1440
/**
1441
 * ntfs_alloc_mft_record - allocate an mft record
1442
 * @vol:        volume to allocate an mft record on
1443
 * @result:     the mft record number allocated
1444
 *
1445
 * Allocate a new mft record on disk. Return 0 on success or -ERRNO on error.
1446
 * On success, *@result contains the allocated mft record number. On error,
1447
 * *@result is -1UL.
1448
 *
1449
 * Note, this function doesn't actually set the mft record to be in use. This
1450
 * is done by the caller, which at the moment is only ntfs_alloc_inode().
1451
 *
1452
 * To find a free mft record, we scan the mft bitmap for a zero bit. To
1453
 * optimize this we start scanning at the place where we last stopped and we
1454
 * perform wrap around when we reach the end. Note, we do not try to allocate
1455
 * mft records below number 24 because numbers 0 to 15 are the defined system
1456
 * files anyway and 16 to 24 are special in that they are used for storing
1457
 * extension mft records for $MFT's $DATA attribute. This is required to avoid
1458
 * the possibility of creating a run list with a circular dependence which once
1459
 * written to disk can never be read in again. Windows will only use records
1460
 * 16 to 24 for normal files if the volume is completely out of space. We never
1461
 * use them which means that when the volume is really out of space we cannot
1462
 * create any more files while Windows can still create up to 8 small files. We
1463
 * can start doing this at some later time, doesn't matter much for now.
1464
 *
1465
 * When scanning the mft bitmap, we only search up to the last allocated mft
1466
 * record. If there are no free records left in the range 24 to number of
1467
 * allocated mft records, then we extend the mft data in order to create free
1468
 * mft records. We extend the allocated size of $MFT/$DATA by 16 records at a
1469
 * time or one cluster, if cluster size is above 16kiB. If there isn't
1470
 * sufficient space to do this, we try to extend by a single mft record or one
1471
 * cluster, if cluster size is above mft record size, but we only do this if
1472
 * there is enough free space, which we know from the values returned by the
1473
 * failed cluster allocation function when we tried to do the first allocation.
1474
 *
1475
 * No matter how many mft records we allocate, we initialize only the first
1476
 * allocated mft record (incrementing mft data size and initialized size) and
1477
 * return its number to the caller in @*result, unless there are less than 24
1478
 * mft records, in which case we allocate and initialize mft records until we
1479
 * reach record 24 which we consider as the first free mft record for use by
1480
 * normal files.
1481
 *
1482
 * If during any stage we overflow the initialized data in the mft bitmap, we
1483
 * extend the initialized size (and data size) by 8 bytes, allocating another
1484
 * cluster if required. The bitmap data size has to be at least equal to the
1485
 * number of mft records in the mft, but it can be bigger, in which case the
1486
 * superflous bits are padded with zeroes.
1487
 *
1488
 * Thus, when we return successfully (return value 0), we will have:
1489
 *      - initialized / extended the mft bitmap if necessary,
1490
 *      - initialized / extended the mft data if necessary,
1491
 *      - set the bit corresponding to the mft record being allocated in the
1492
 *        mft bitmap, and we will
1493
 *      - return the mft record number in @*result.
1494
 *
1495
 * On error (return value below zero), nothing will have changed. If we had
1496
 * changed anything before the error occured, we will have reverted back to
1497
 * the starting state before returning to the caller. Thus, except for bugs,
1498
 * we should always leave the volume in a consitents state when returning from
1499
 * this function. NOTE: Small exception to this is that we set the bit in the
1500
 * mft bitmap but we do not mark the mft record in use, which is inconsistent.
1501
 * However, the caller will immediately add the wanted attributes to the mft
1502
 * record, set it in use and write it out to disk, so there should be no
1503
 * problem.
1504
 *
1505
 * Note, this function cannot make use of most of the normal functions, like
1506
 * for example for attribute resizing, etc, because when the run list overflows
1507
 * the base mft record and an attribute list is used, it is very important
1508
 * that the extension mft records used to store the $DATA attribute of $MFT
1509
 * can be reached without having to read the information contained inside
1510
 * them, as this would make it impossible to find them in the first place
1511
 * after the volume is dismounted. $MFT/$BITMAP probably doesn't need to
1512
 * follow this rule because the bitmap is not essential for finding the mft
1513
 * records, but on the other hand, handling the bitmap in this special way
1514
 * would make life easier because otherwise there might be circular invocations
1515
 * of functions when reading the bitmap but if we are careful, we should be
1516
 * able to avoid all problems.
1517
 *
1518
 * FIXME: Don't forget $MftMirr, though this probably belongs in
1519
 *        ntfs_update_inode() (or even deeper). (AIA)
1520
 *
1521
 * FIXME: Want finer grained locking. (AIA)
1522
 */
1523
static int ntfs_alloc_mft_record(ntfs_volume *vol, unsigned long *result)
1524
{
1525
        unsigned long nr_mft_records, buf_size, buf_pos, pass_start, pass_end;
1526
        unsigned long last_read_pos, mft_rec_size, bit, l;
1527
        ntfs_attribute *data, *bmp;
1528
        __u8 *buf, *byte, pass, b, have_allocated_mftbmp = 0;
1529
        int rlen, rl_size = 0, r2len, rl2_size, old_data_rlen, err = 0;
1530
        ntfs_runlist *rl, *rl2;
1531
        ntfs_cluster_t lcn = 0, old_data_len;
1532
        ntfs_io io;
1533
        __s64 ll, old_data_allocated, old_data_initialized, old_data_size;
1534
 
1535
        *result = -1UL;
1536
        /* Allocate a buffer and setup the io structure. */
1537
        buf = (__u8*)__get_free_page(GFP_NOFS);
1538
        if (!buf)
1539
                return -ENOMEM;
1540
        lock_kernel();
1541
        /* Get the $DATA and $BITMAP attributes of $MFT. */
1542
        data = ntfs_find_attr(vol->mft_ino, vol->at_data, 0);
1543
        bmp = ntfs_find_attr(vol->mft_ino, vol->at_bitmap, 0);
1544
        if (!data || !bmp) {
1545
                err = -EINVAL;
1546
                goto err_ret;
1547
        }
1548
        /* Determine the number of allocated mft records in the mft. */
1549
        pass_end = nr_mft_records = data->allocated >>
1550
                        vol->mft_record_size_bits;
1551
        ntfs_debug(DEBUG_OTHER, "%s(): nr_mft_records = %lu.\n", __FUNCTION__,
1552
                        nr_mft_records);
1553
        /* Make sure we don't overflow the bitmap. */
1554
        l = bmp->initialized << 3;
1555
        if (l < nr_mft_records)
1556
                // FIXME: It might be a good idea to extend the bitmap instead.
1557
                pass_end = l;
1558
        pass = 1;
1559
        buf_pos = vol->mft_data_pos;
1560
        if (buf_pos >= pass_end) {
1561
                buf_pos = 24UL;
1562
                pass = 2;
1563
        }
1564
        pass_start = buf_pos;
1565
        rl = bmp->d.r.runlist;
1566
        rlen = bmp->d.r.len - 1;
1567
        lcn = rl[rlen].lcn + rl[rlen].len;
1568
        io.fn_put = ntfs_put;
1569
        io.fn_get = ntfs_get;
1570
        ntfs_debug(DEBUG_OTHER, "%s(): Starting bitmap search.\n",
1571
                        __FUNCTION__);
1572
        ntfs_debug(DEBUG_OTHER, "%s(): pass = %i, pass_start = %lu, pass_end = "
1573
                        "%lu.\n", __FUNCTION__, pass, pass_start, pass_end);
1574
        byte = NULL; // FIXME: For debugging only.
1575
        /* Loop until a free mft record is found. */
1576
        io.size = (nr_mft_records >> 3) & ~PAGE_MASK;
1577
        for (;; io.size = PAGE_SIZE) {
1578
                io.param = buf;
1579
                io.do_read = 1;
1580
                last_read_pos = buf_pos >> 3;
1581
                ntfs_debug(DEBUG_OTHER, "%s(): Before: bmp->allocated = 0x%Lx, "
1582
                                "bmp->size = 0x%Lx, bmp->initialized = "
1583
                                "0x%Lx.\n", __FUNCTION__, bmp->allocated,
1584
                                bmp->size, bmp->initialized);
1585
                err = ntfs_readwrite_attr(vol->mft_ino, bmp, last_read_pos,
1586
                                &io);
1587
                if (err)
1588
                        goto err_ret;
1589
                ntfs_debug(DEBUG_OTHER, "%s(): Read %lu bytes.\n", __FUNCTION__,
1590
                                (unsigned long)io.size);
1591
                ntfs_debug(DEBUG_OTHER, "%s(): After: bmp->allocated = 0x%Lx, "
1592
                                "bmp->size = 0x%Lx, bmp->initialized = "
1593
                                "0x%Lx.\n", __FUNCTION__, bmp->allocated,
1594
                                bmp->size, bmp->initialized);
1595
                if (!io.size)
1596
                        goto pass_done;
1597
                buf_size = io.size << 3;
1598
                bit = buf_pos & 7UL;
1599
                buf_pos &= ~7UL;
1600
                ntfs_debug(DEBUG_OTHER, "%s(): Before loop: buf_size = %lu, "
1601
                                "buf_pos = %lu, bit = %lu, *byte = 0x%x, b = "
1602
                                "%u.\n", __FUNCTION__, buf_size, buf_pos, bit,
1603
                                byte ? *byte : -1, b);
1604
                for (; bit < buf_size && bit + buf_pos < pass_end;
1605
                                bit &= ~7UL, bit += 8UL) {
1606
                        byte = buf + (bit >> 3);
1607
                        if (*byte == 0xff)
1608
                                continue;
1609
                        b = ffz((unsigned long)*byte);
1610
                        if (b < (__u8)8 && b >= (bit & 7UL)) {
1611
                                bit = b + (bit & ~7UL) + buf_pos;
1612
                                ntfs_debug(DEBUG_OTHER, "%s(): Found free rec "
1613
                                                "in for loop. bit = %lu\n",
1614
                                                __FUNCTION__, bit);
1615
                                goto found_free_rec;
1616
                        }
1617
                }
1618
                ntfs_debug(DEBUG_OTHER, "%s(): After loop: buf_size = %lu, "
1619
                                "buf_pos = %lu, bit = %lu, *byte = 0x%x, b = "
1620
                                "%u.\n", __FUNCTION__, buf_size, buf_pos, bit,
1621
                                byte ? *byte : -1, b);
1622
                buf_pos += buf_size;
1623
                if (buf_pos < pass_end)
1624
                        continue;
1625
pass_done:      /* Finished with the current pass. */
1626
                ntfs_debug(DEBUG_OTHER, "%s(): At pass_done.\n", __FUNCTION__);
1627
                if (pass == 1) {
1628
                        /*
1629
                         * Now do pass 2, scanning the first part of the zone
1630
                         * we omitted in pass 1.
1631
                         */
1632
                        ntfs_debug(DEBUG_OTHER, "%s(): Done pass 1.\n",
1633
                                        __FUNCTION__);
1634
                        ntfs_debug(DEBUG_OTHER, "%s(): Pass = 2.\n",
1635
                                        __FUNCTION__);
1636
                        pass = 2;
1637
                        pass_end = pass_start;
1638
                        buf_pos = pass_start = 24UL;
1639
                        ntfs_debug(DEBUG_OTHER, "%s(): pass = %i, pass_start = "
1640
                                        "%lu, pass_end = %lu.\n", __FUNCTION__,
1641
                                        pass, pass_start, pass_end);
1642
                        continue;
1643
                } /* pass == 2 */
1644
                /* No free records left. */
1645
                if (bmp->initialized << 3 > nr_mft_records &&
1646
                                bmp->initialized > 3) {
1647
                        /*
1648
                         * The mft bitmap is already bigger but the space is
1649
                         * not covered by mft records, this implies that the
1650
                         * next records are all free, so we already have found
1651
                         * a free record.
1652
                         */
1653
                        bit = nr_mft_records;
1654
                        if (bit < 24UL)
1655
                                bit = 24UL;
1656
                        ntfs_debug(DEBUG_OTHER, "%s(): Found free record bit "
1657
                                        "(#1) = 0x%lx.\n", __FUNCTION__, bit);
1658
                        goto found_free_rec;
1659
                }
1660
                ntfs_debug(DEBUG_OTHER, "%s(): Done pass 2.\n", __FUNCTION__);
1661
                ntfs_debug(DEBUG_OTHER, "%s(): Before: bmp->allocated = 0x%Lx, "
1662
                                "bmp->size = 0x%Lx, bmp->initialized = "
1663
                                "0x%Lx.\n", __FUNCTION__, bmp->allocated,
1664
                                bmp->size, bmp->initialized);
1665
                /* Need to extend the mft bitmap. */
1666
                if (bmp->initialized + 8LL > bmp->allocated) {
1667
                        ntfs_io io2;
1668
 
1669
                        ntfs_debug(DEBUG_OTHER, "%s(): Initialized "
1670
                                        "> allocated.\n", __FUNCTION__);
1671
                        /* Need to extend bitmap by one more cluster. */
1672
                        rl = bmp->d.r.runlist;
1673
                        rlen = bmp->d.r.len - 1;
1674
                        lcn = rl[rlen].lcn + rl[rlen].len;
1675
                        io2.fn_put = ntfs_put;
1676
                        io2.fn_get = ntfs_get;
1677
                        io2.param = &b;
1678
                        io2.size = 1;
1679
                        io2.do_read = 1;
1680
                        err = ntfs_readwrite_attr(vol->bitmap, data, lcn >> 3,
1681
                                        &io2);
1682
                        if (err)
1683
                                goto err_ret;
1684
                        ntfs_debug(DEBUG_OTHER, "%s(): Read %lu bytes.\n",
1685
                                        __FUNCTION__, (unsigned long)io2.size);
1686
                        if (io2.size == 1 && b != 0xff) {
1687
                                __u8 tb = 1 << (lcn & (ntfs_cluster_t)7);
1688
                                if (!(b & tb)) {
1689
                                        /* Next cluster is free. Allocate it. */
1690
                                        b |= tb;
1691
                                        io2.param = &b;
1692
                                        io2.do_read = 0;
1693
                                        err = ntfs_readwrite_attr(vol->bitmap,
1694
                                                        data, lcn >> 3, &io2);
1695
                                        if (err || io.size != 1) {
1696
                                                if (!err)
1697
                                                        err = -EIO;
1698
                                                goto err_ret;
1699
                                        }
1700
append_mftbmp_simple:                   rl[rlen].len++;
1701
                                        have_allocated_mftbmp |= 1;
1702
                                        ntfs_debug(DEBUG_OTHER, "%s(): "
1703
                                                        "Appending one cluster "
1704
                                                        "to mftbmp.\n",
1705
                                                        __FUNCTION__);
1706
                                }
1707
                        }
1708
                        if (!have_allocated_mftbmp) {
1709
                                /* Allocate a cluster from the DATA_ZONE. */
1710
                                ntfs_cluster_t lcn2 = lcn;
1711
                                ntfs_cluster_t count = 1;
1712
                                err = ntfs_allocate_clusters(vol, &lcn2,
1713
                                                &count, &rl2, &r2len,
1714
                                                DATA_ZONE);
1715
                                if (err)
1716
                                        goto err_ret;
1717
                                if (count != 1 || lcn2 <= 0) {
1718
                                        if (count > 0) {
1719
rl2_dealloc_err_out:                            if (ntfs_deallocate_clusters(
1720
                                                        vol, rl2, r2len))
1721
                                                        ntfs_error("%s(): "
1722
                                                        "Cluster "
1723
                                                        "deallocation in error "
1724
                                                        "code path failed! You "
1725
                                                        "should run chkdsk.\n",
1726
                                                        __FUNCTION__);
1727
                                        }
1728
                                        ntfs_vfree(rl2);
1729
                                        if (!err)
1730
                                                err = -EINVAL;
1731
                                        goto err_ret;
1732
                                }
1733
                                if (lcn2 == lcn) {
1734
                                        ntfs_vfree(rl2);
1735
                                        goto append_mftbmp_simple;
1736
                                }
1737
                                /* We need to append a new run. */
1738
                                rl_size = (rlen * sizeof(ntfs_runlist) +
1739
                                                PAGE_SIZE - 1) & PAGE_MASK;
1740
                                /* Reallocate memory if necessary. */
1741
                                if ((rlen + 2) * sizeof(ntfs_runlist) >=
1742
                                                rl_size) {
1743
                                        ntfs_runlist *rlt;
1744
 
1745
                                        rl_size += PAGE_SIZE;
1746
                                        rlt = ntfs_vmalloc(rl_size);
1747
                                        if (!rlt) {
1748
                                                err = -ENOMEM;
1749
                                                goto rl2_dealloc_err_out;
1750
                                        }
1751
                                        ntfs_memcpy(rlt, rl, rl_size -
1752
                                                        PAGE_SIZE);
1753
                                        ntfs_vfree(rl);
1754
                                        bmp->d.r.runlist = rl = rlt;
1755
                                }
1756
                                ntfs_vfree(rl2);
1757
                                rl[rlen].lcn = lcn = lcn2;
1758
                                rl[rlen].len = count;
1759
                                bmp->d.r.len = ++rlen;
1760
                                have_allocated_mftbmp |= 2;
1761
                                ntfs_debug(DEBUG_OTHER, "%s(): Adding run to "
1762
                                                "mftbmp. LCN = %i, len = %i\n",
1763
                                                __FUNCTION__, lcn, count);
1764
                        }
1765
                        /*
1766
                         * We now have extended the mft bitmap allocated size
1767
                         * by one cluster. Reflect this in the attribute.
1768
                         */
1769
                        bmp->allocated += (__s64)vol->cluster_size;
1770
                }
1771
                ntfs_debug(DEBUG_OTHER, "%s(): After: bmp->allocated = 0x%Lx, "
1772
                                "bmp->size = 0x%Lx, bmp->initialized = "
1773
                                "0x%Lx.\n", __FUNCTION__, bmp->allocated,
1774
                                bmp->size, bmp->initialized);
1775
                /* We now have sufficient allocated space. */
1776
                ntfs_debug(DEBUG_OTHER, "%s(): Now have sufficient allocated "
1777
                                "space in mftbmp.\n", __FUNCTION__);
1778
                ntfs_debug(DEBUG_OTHER, "%s(): Before: bmp->allocated = 0x%Lx, "
1779
                                "bmp->size = 0x%Lx, bmp->initialized = "
1780
                                "0x%Lx.\n", __FUNCTION__, bmp->allocated,
1781
                                bmp->size, bmp->initialized);
1782
                buf_pos = bmp->initialized;
1783
                bmp->initialized += 8LL;
1784
                if (bmp->initialized > bmp->size)
1785
                        bmp->size = bmp->initialized;
1786
                ntfs_debug(DEBUG_OTHER, "%s(): After: bmp->allocated = 0x%Lx, "
1787
                                "bmp->size = 0x%Lx, bmp->initialized = "
1788
                                "0x%Lx.\n", __FUNCTION__, bmp->allocated,
1789
                                bmp->size, bmp->initialized);
1790
                have_allocated_mftbmp |= 4;
1791
                /* Update the mft bitmap attribute value. */
1792
                memset(buf, 0, 8);
1793
                io.param = buf;
1794
                io.size = 8;
1795
                io.do_read = 0;
1796
                err = ntfs_readwrite_attr(vol->mft_ino, bmp, buf_pos, &io);
1797
                if (err || io.size != 8) {
1798
                        if (!err)
1799
                                err = -EIO;
1800
                        goto shrink_mftbmp_err_ret;
1801
                }
1802
                ntfs_debug(DEBUG_OTHER, "%s(): Wrote extended mftbmp bytes "
1803
                                "%lu.\n", __FUNCTION__, (unsigned long)io.size);
1804
                ntfs_debug(DEBUG_OTHER, "%s(): After write: bmp->allocated = "
1805
                                "0x%Lx, bmp->size = 0x%Lx, bmp->initialized = "
1806
                                "0x%Lx.\n", __FUNCTION__, bmp->allocated,
1807
                                bmp->size, bmp->initialized);
1808
                bit = buf_pos << 3;
1809
                ntfs_debug(DEBUG_OTHER, "%s(): Found free record bit (#2) = "
1810
                                "0x%lx.\n", __FUNCTION__, bit);
1811
                goto found_free_rec;
1812
        }
1813
found_free_rec:
1814
        /* bit is the found free mft record. Allocate it in the mft bitmap. */
1815
        vol->mft_data_pos = bit;
1816
        ntfs_debug(DEBUG_OTHER, "%s(): At found_free_rec.\n", __FUNCTION__);
1817
        io.param = buf;
1818
        io.size = 1;
1819
        io.do_read = 1;
1820
        ntfs_debug(DEBUG_OTHER, "%s(): Before update: bmp->allocated = 0x%Lx, "
1821
                        "bmp->size = 0x%Lx, bmp->initialized = 0x%Lx.\n",
1822
                        __FUNCTION__, bmp->allocated,
1823
                        bmp->size, bmp->initialized);
1824
        err = ntfs_readwrite_attr(vol->mft_ino, bmp, bit >> 3, &io);
1825
        if (err || io.size != 1) {
1826
                if (!err)
1827
                        err = -EIO;
1828
                goto shrink_mftbmp_err_ret;
1829
        }
1830
        ntfs_debug(DEBUG_OTHER, "%s(): Read %lu bytes.\n", __FUNCTION__,
1831
                        (unsigned long)io.size);
1832
#ifdef DEBUG
1833
        /* Check our bit is really zero! */
1834
        if (*buf & (1 << (bit & 7)))
1835
                BUG();
1836
#endif
1837
        *buf |= 1 << (bit & 7);
1838
        io.param = buf;
1839
        io.do_read = 0;
1840
        err = ntfs_readwrite_attr(vol->mft_ino, bmp, bit >> 3, &io);
1841
        if (err || io.size != 1) {
1842
                if (!err)
1843
                        err = -EIO;
1844
                goto shrink_mftbmp_err_ret;
1845
        }
1846
        ntfs_debug(DEBUG_OTHER, "%s(): Wrote %lu bytes.\n", __FUNCTION__,
1847
                        (unsigned long)io.size);
1848
        ntfs_debug(DEBUG_OTHER, "%s(): After update: bmp->allocated = 0x%Lx, "
1849
                        "bmp->size = 0x%Lx, bmp->initialized = 0x%Lx.\n",
1850
                        __FUNCTION__, bmp->allocated,
1851
                        bmp->size, bmp->initialized);
1852
        /* The mft bitmap is now uptodate. Deal with mft data attribute now. */
1853
        ll = (__s64)(bit + 1) << vol->mft_record_size_bits;
1854
        if (ll <= data->initialized) {
1855
                /* The allocated record is already initialized. We are done! */
1856
                ntfs_debug(DEBUG_OTHER, "%s(): Allocated mft record "
1857
                                "already initialized!\n", __FUNCTION__);
1858
                goto done_ret;
1859
        }
1860
        ntfs_debug(DEBUG_OTHER, "%s(): Allocated mft record needs "
1861
                        "to be initialized.\n", __FUNCTION__);
1862
        /* The mft record is outside the initialized data. */
1863
        mft_rec_size = (unsigned long)vol->mft_record_size;
1864
        /* Preserve old values for undo purposes. */
1865
        old_data_allocated = data->allocated;
1866
        old_data_rlen = data->d.r.len - 1;
1867
        old_data_len = data->d.r.runlist[old_data_rlen].len;
1868
        /*
1869
         * If necessary, extend the mft until it covers the allocated record.
1870
         * The loop is only actually used when a freshly formatted volume is
1871
         * first written to. But it optimizes away nicely in the common case.
1872
         */
1873
        while (ll > data->allocated) {
1874
                ntfs_cluster_t lcn2, nr_lcn2, nr, min_nr;
1875
 
1876
                ntfs_debug(DEBUG_OTHER, "%s(): Extending mft data allocation, "
1877
                                "data->allocated = 0x%Lx, data->size = 0x%Lx, "
1878
                                "data->initialized = 0x%Lx.\n", __FUNCTION__,
1879
                                data->allocated, data->size, data->initialized);
1880
                /* Minimum allocation is one mft record worth of clusters. */
1881
                if (mft_rec_size <= vol->cluster_size)
1882
                        min_nr = (ntfs_cluster_t)1;
1883
                else
1884
                        min_nr = mft_rec_size >> vol->cluster_size_bits;
1885
                ntfs_debug(DEBUG_OTHER, "%s(): min_nr = %i.\n", __FUNCTION__,
1886
                                min_nr);
1887
                /* Allocate 16 mft records worth of clusters. */
1888
                nr = mft_rec_size << 4 >> vol->cluster_size_bits;
1889
                if (!nr)
1890
                        nr = (ntfs_cluster_t)1;
1891
                /* Determine the preferred allocation location. */
1892
                ntfs_debug(DEBUG_OTHER, "%s(): nr = %i.\n", __FUNCTION__, nr);
1893
                rl2 = data->d.r.runlist;
1894
                r2len = data->d.r.len;
1895
                lcn2 = rl2[r2len - 1].lcn + rl2[r2len - 1].len;
1896
                ntfs_debug(DEBUG_OTHER, "%s(): rl2[r2len - 1].lcn = %i, .len = "
1897
                                "%i.\n", __FUNCTION__, rl2[r2len - 1].lcn,
1898
                                rl2[r2len - 1].len);
1899
                ntfs_debug(DEBUG_OTHER, "%s(): lcn2 = %i, r2len = %i.\n",
1900
                                __FUNCTION__, lcn2, r2len);
1901
retry_mft_data_allocation:
1902
                nr_lcn2 = nr;
1903
                err = ntfs_allocate_clusters(vol, &lcn2, &nr_lcn2, &rl2,
1904
                                &r2len, MFT_ZONE);
1905
#ifdef DEBUG
1906
                if (!err && nr_lcn2 < min_nr)
1907
                        /* Allocated less than minimum needed. Weird! */
1908
                        BUG();
1909
#endif
1910
                if (err) {
1911
                        /*
1912
                         * If there isn't enough space to do the wanted
1913
                         * allocation, but there is enough space to do a
1914
                         * minimal allocation, then try that, unless the wanted
1915
                         * allocation was already the minimal allocation.
1916
                         */
1917
                        if (err == -ENOSPC && nr > min_nr &&
1918
                                        nr_lcn2 >= min_nr) {
1919
                                nr = min_nr;
1920
                                ntfs_debug(DEBUG_OTHER, "%s(): Retrying mft "
1921
                                                "data allocation, nr = min_nr "
1922
                                                "= %i.\n", __FUNCTION__, nr);
1923
                                goto retry_mft_data_allocation;
1924
                        }
1925
                        goto undo_mftbmp_alloc_err_ret;
1926
                }
1927
                ntfs_debug(DEBUG_OTHER, "%s(): Allocated %i clusters starting "
1928
                                "at LCN %i.\n", __FUNCTION__, nr_lcn2, lcn2);
1929
                ntfs_debug(DEBUG_OTHER, "%s(): Allocated runlist:\n",
1930
                                __FUNCTION__);
1931
                dump_runlist(rl2, r2len);
1932
                /* Append rl2 to the mft data attribute's run list. */
1933
                err = splice_runlists(&data->d.r.runlist, (int*)&data->d.r.len,
1934
                                rl2, r2len);
1935
                if (err) {
1936
                        ntfs_debug(DEBUG_OTHER, "%s(): splice_runlists failed "
1937
                                        "with error code %i.\n", __FUNCTION__,
1938
                                        -err);
1939
                        goto undo_partial_data_alloc_err_ret;
1940
                }
1941
                /* Reflect the allocated clusters in the mft allocated data. */
1942
                data->allocated += nr_lcn2 << vol->cluster_size_bits;
1943
                ntfs_debug(DEBUG_OTHER, "%s(): After extending mft data "
1944
                                "allocation, data->allocated = 0x%Lx, "
1945
                                "data->size = 0x%Lx, data->initialized = "
1946
                                "0x%Lx.\n", __FUNCTION__, data->allocated,
1947
                                data->size, data->initialized);
1948
        }
1949
        /* Prepare a formatted (empty) mft record. */
1950
        memset(buf, 0, mft_rec_size);
1951
        ntfs_fill_mft_header(buf, mft_rec_size, 0, 0, 0);
1952
        err = ntfs_insert_fixups(buf, mft_rec_size);
1953
        if (err)
1954
                goto undo_data_alloc_err_ret;
1955
        /*
1956
         * Extend mft data initialized size to reach the allocated mft record
1957
         * and write the formatted mft record buffer to each mft record being
1958
         * initialized. Note, that ntfs_readwrite_attr extends both
1959
         * data->initialized and data->size, so no need for us to touch them.
1960
         */
1961
        old_data_initialized = data->initialized;
1962
        old_data_size = data->size;
1963
        while (ll > data->initialized) {
1964
                ntfs_debug(DEBUG_OTHER, "%s(): Initializing mft record "
1965
                                "0x%Lx.\n", __FUNCTION__,
1966
                                data->initialized >> vol->mft_record_size_bits);
1967
                io.param = buf;
1968
                io.size = mft_rec_size;
1969
                io.do_read = 0;
1970
                err = ntfs_readwrite_attr(vol->mft_ino, data,
1971
                                data->initialized, &io);
1972
                if (err || io.size != mft_rec_size) {
1973
                        if (!err)
1974
                                err = -EIO;
1975
                        goto undo_data_init_err_ret;
1976
                }
1977
                ntfs_debug(DEBUG_OTHER, "%s(): Wrote %i bytes to mft data.\n",
1978
                                __FUNCTION__, io.size);
1979
        }
1980
        /* Update the VFS inode size as well. */
1981
        VFS_I(vol->mft_ino)->i_size = data->size;
1982
#ifdef DEBUG
1983
        ntfs_debug(DEBUG_OTHER, "%s(): After mft record "
1984
                        "initialization: data->allocated = 0x%Lx, data->size "
1985
                        "= 0x%Lx, data->initialized = 0x%Lx.\n", __FUNCTION__,
1986
                        data->allocated, data->size, data->initialized);
1987
        /* Sanity checks. */
1988
        if (data->size > data->allocated || data->size < data->initialized ||
1989
                        data->initialized > data->allocated)
1990
                BUG();
1991
#endif
1992
done_ret:
1993
        /* Return the number of the allocated mft record. */
1994
        ntfs_debug(DEBUG_OTHER, "%s(): At done_ret. *result = bit = 0x%lx.\n",
1995
                        __FUNCTION__, bit);
1996
        *result = bit;
1997
        vol->mft_data_pos = bit + 1;
1998
err_ret:
1999
        unlock_kernel();
2000
        free_page((unsigned long)buf);
2001
        ntfs_debug(DEBUG_OTHER, "%s(): Syncing inode $MFT.\n", __FUNCTION__);
2002
        if (ntfs_update_inode(vol->mft_ino))
2003
                ntfs_error("%s(): Failed to sync inode $MFT. "
2004
                                "Continuing anyway.\n",__FUNCTION__);
2005
        if (!err) {
2006
                ntfs_debug(DEBUG_FILE3, "%s(): Done. Allocated mft record "
2007
                                "number *result = 0x%lx.\n", __FUNCTION__,
2008
                                *result);
2009
                return 0;
2010
        }
2011
        if (err != -ENOSPC)
2012
                ntfs_error("%s(): Failed to allocate an mft record. Returning "
2013
                                "error code %i.\n", __FUNCTION__, -err);
2014
        else
2015
                ntfs_debug(DEBUG_FILE3, "%s(): Failed to allocate an mft "
2016
                                "record due to lack of free space.\n",
2017
                                __FUNCTION__);
2018
        return err;
2019
undo_data_init_err_ret:
2020
        ntfs_debug(DEBUG_OTHER, "%s(): At undo_data_init_err_ret.\n",
2021
                        __FUNCTION__);
2022
        data->initialized = old_data_initialized;
2023
        data->size = old_data_size;
2024
undo_data_alloc_err_ret:
2025
        ntfs_debug(DEBUG_OTHER, "%s(): At undo_data_alloc_err_ret.\n",
2026
                        __FUNCTION__);
2027
        data->allocated = old_data_allocated;
2028
undo_partial_data_alloc_err_ret:
2029
        ntfs_debug(DEBUG_OTHER, "%s(): At undo_partial_data_alloc_err_ret.\n",
2030
                        __FUNCTION__);
2031
        /* Deallocate the clusters. */
2032
        if (ntfs_deallocate_clusters(vol, rl2, r2len))
2033
                ntfs_error("%s(): Error deallocating clusters in error code "
2034
                        "path. You should run chkdsk.\n", __FUNCTION__);
2035
        ntfs_vfree(rl2);
2036
        /* Revert the run list back to what it was before. */
2037
        r2len = data->d.r.len;
2038
        rl2 = data->d.r.runlist;
2039
        rl2[old_data_rlen++].len = old_data_len;
2040
        rl2[old_data_rlen].lcn = (ntfs_cluster_t)-1;
2041
        rl2[old_data_rlen].len = (ntfs_cluster_t)0;
2042
        data->d.r.len = old_data_rlen;
2043
        rl2_size = ((old_data_rlen + 1) * sizeof(ntfs_runlist) + PAGE_SIZE -
2044
                        1) & PAGE_MASK;
2045
        /* Reallocate memory freeing any extra memory allocated. */
2046
        if (rl2_size < ((r2len * sizeof(ntfs_runlist) + PAGE_SIZE - 1) &
2047
                        PAGE_MASK)) {
2048
                rl2 = ntfs_vmalloc(rl2_size);
2049
                if (rl2) {
2050
                        ntfs_memcpy(rl2, data->d.r.runlist, rl2_size);
2051
                        ntfs_vfree(data->d.r.runlist);
2052
                        data->d.r.runlist = rl2;
2053
                } else
2054
                        ntfs_error("%s(): Error reallocating "
2055
                                        "memory in error code path. This "
2056
                                        "should be harmless.\n", __FUNCTION__);
2057
        }
2058
undo_mftbmp_alloc_err_ret:
2059
        ntfs_debug(DEBUG_OTHER, "%s(): At undo_mftbmp_alloc_err_ret.\n",
2060
                        __FUNCTION__);
2061
        /* Deallocate the allocated bit in the mft bitmap. */
2062
        io.param = buf;
2063
        io.size = 1;
2064
        io.do_read = 1;
2065
        err = ntfs_readwrite_attr(vol->mft_ino, bmp, bit >> 3, &io);
2066
        if (!err && io.size == 1) {
2067
                *buf &= ~(1 << (bit & 7));
2068
                io.param = buf;
2069
                io.do_read = 0;
2070
                err = ntfs_readwrite_attr(vol->mft_ino, bmp, bit >> 3, &io);
2071
        }
2072
        if (err || io.size != 1) {
2073
                if (!err)
2074
                        err = -EIO;
2075
                ntfs_error("%s(): Error deallocating mft record in error code "
2076
                        "path. You should run chkdsk.\n", __FUNCTION__);
2077
        }
2078
shrink_mftbmp_err_ret:
2079
        ntfs_debug(DEBUG_OTHER, "%s(): At shrink_mftbmp_err_ret.\n",
2080
                        __FUNCTION__);
2081
        ntfs_debug(DEBUG_OTHER, "%s(): have_allocated_mftbmp = %i.\n",
2082
                        __FUNCTION__, have_allocated_mftbmp);
2083
        if (!have_allocated_mftbmp)
2084
                goto err_ret;
2085
        /* Shrink the mftbmp back to previous size. */
2086
        if (bmp->size == bmp->initialized)
2087
                bmp->size -= 8LL;
2088
        bmp->initialized -= 8LL;
2089
        have_allocated_mftbmp &= ~4;
2090
        /* If no allocation occured then we are done. */
2091
        ntfs_debug(DEBUG_OTHER, "%s(): have_allocated_mftbmp = %i.\n",
2092
                        __FUNCTION__, have_allocated_mftbmp);
2093
        if (!have_allocated_mftbmp)
2094
                goto err_ret;
2095
        /* Deallocate the allocated cluster. */
2096
        bmp->allocated -= (__s64)vol->cluster_size;
2097
        if (ntfs_deallocate_cluster_run(vol, lcn, (ntfs_cluster_t)1))
2098
                ntfs_error("%s(): Error deallocating cluster in error code "
2099
                        "path. You should run chkdsk.\n", __FUNCTION__);
2100
        switch (have_allocated_mftbmp & 3) {
2101
        case 1:
2102
                /* Delete the last lcn from the last run of mftbmp. */
2103
                rl[rlen - 1].len--;
2104
                break;
2105
        case 2:
2106
                /* Delete the last run of mftbmp. */
2107
                bmp->d.r.len = --rlen;
2108
                /* Reallocate memory if necessary. */
2109
                if ((rlen + 1) * sizeof(ntfs_runlist) <= rl_size - PAGE_SIZE) {
2110
                        ntfs_runlist *rlt;
2111
 
2112
                        rl_size -= PAGE_SIZE;
2113
                        rlt = ntfs_vmalloc(rl_size);
2114
                        if (rlt) {
2115
                                ntfs_memcpy(rlt, rl, rl_size);
2116
                                ntfs_vfree(rl);
2117
                                bmp->d.r.runlist = rl = rlt;
2118
                        } else
2119
                                ntfs_error("%s(): Error "
2120
                                                "reallocating memory in error "
2121
                                                "code path. This should be "
2122
                                                "harmless.\n", __FUNCTION__);
2123
                }
2124
                bmp->d.r.runlist[bmp->d.r.len].lcn = (ntfs_cluster_t)-1;
2125
                bmp->d.r.runlist[bmp->d.r.len].len = (ntfs_cluster_t)0;
2126
                break;
2127
        default:
2128
                BUG();
2129
        }
2130
        goto err_ret;
2131
}
2132
 
2133
/* We need 0x48 bytes in total. */
2134
static int add_standard_information(ntfs_inode *ino)
2135
{
2136
        ntfs_time64_t now;
2137
        char data[0x30];
2138
        char *position = data;
2139
        ntfs_attribute *si;
2140
 
2141
        now = ntfs_now();
2142
        NTFS_PUTU64(position + 0x00, now);              /* File creation */
2143
        NTFS_PUTU64(position + 0x08, now);              /* Last modification */
2144
        NTFS_PUTU64(position + 0x10, now);              /* Last mod for MFT */
2145
        NTFS_PUTU64(position + 0x18, now);              /* Last access */
2146
        NTFS_PUTU64(position + 0x20, 0);         /* MSDOS file perms */
2147
        NTFS_PUTU64(position + 0x28, 0);         /* unknown */
2148
        return ntfs_create_attr(ino, ino->vol->at_standard_information, 0,
2149
                        data, sizeof(data), &si);
2150
}
2151
 
2152
static int add_filename(ntfs_inode *ino, ntfs_inode *dir,
2153
                const unsigned char *filename, int length, ntfs_u32 flags)
2154
{
2155
        unsigned char *position;
2156
        unsigned int size;
2157
        ntfs_time64_t now;
2158
        int count, error;
2159
        unsigned char* data;
2160
        ntfs_attribute *fn;
2161
 
2162
        /* Work out the size. */
2163
        size = 0x42 + 2 * length;
2164
        data = ntfs_malloc(size);
2165
        if (!data)
2166
                return -ENOMEM;
2167
        /* Search for a position. */
2168
        position = data;
2169
        NTFS_PUTINUM(position, dir);                    /* Inode num of dir */
2170
        now = ntfs_now();
2171
        NTFS_PUTU64(position + 0x08, now);              /* File creation */
2172
        NTFS_PUTU64(position + 0x10, now);              /* Last modification */
2173
        NTFS_PUTU64(position + 0x18, now);              /* Last mod for MFT */
2174
        NTFS_PUTU64(position + 0x20, now);              /* Last access */
2175
        /* FIXME: Get the following two sizes by finding the data attribute
2176
         * in ino->attr and copying the corresponding fields from there.
2177
         * If no data present then set to zero. In current implementation
2178
         * add_data is called after add_filename so zero is correct on
2179
         * creation. Need to change when we have hard links / support different
2180
         * filename namespaces. (AIA) */
2181
        NTFS_PUTS64(position + 0x28, 0);         /* Allocated size */
2182
        NTFS_PUTS64(position + 0x30, 0);         /* Data size */
2183
        NTFS_PUTU32(position + 0x38, flags);            /* File flags */
2184
        NTFS_PUTU32(position + 0x3c, 0);         /* We don't use these
2185
                                                         * features yet. */
2186
        NTFS_PUTU8(position + 0x40, length);            /* Filename length */
2187
        NTFS_PUTU8(position + 0x41, 0);                  /* Only long name */
2188
                /* FIXME: This is madness. We are defining the POSIX namespace
2189
                 * for the filename here which can mean that the file will be
2190
                 * invisible when in Windows NT/2k! )-: (AIA) */
2191
        position += 0x42;
2192
        for (count = 0; count < length; count++) {
2193
                NTFS_PUTU16(position + 2 * count, filename[count]);
2194
        }
2195
        error = ntfs_create_attr(ino, ino->vol->at_file_name, 0, data, size,
2196
                                 &fn);
2197
        if (!error)
2198
                error = ntfs_dir_add(dir, ino, fn);
2199
        ntfs_free(data);
2200
        return error;
2201
}
2202
 
2203
int add_security(ntfs_inode* ino, ntfs_inode* dir)
2204
{
2205
        int error;
2206
        char *buf;
2207
        int size;
2208
        ntfs_attribute* attr;
2209
        ntfs_io io;
2210
        ntfs_attribute *se;
2211
 
2212
        attr = ntfs_find_attr(dir, ino->vol->at_security_descriptor, 0);
2213
        if (!attr)
2214
                return -EOPNOTSUPP; /* Need security in directory. */
2215
        size = attr->size;
2216
        if (size > 512)
2217
                return -EOPNOTSUPP;
2218
        buf = ntfs_malloc(size);
2219
        if (!buf)
2220
                return -ENOMEM;
2221
        io.fn_get = ntfs_get;
2222
        io.fn_put = ntfs_put;
2223
        io.param = buf;
2224
        io.size = size;
2225
        error = ntfs_read_attr(dir, ino->vol->at_security_descriptor, 0, 0,&io);
2226
        if (!error && io.size != size)
2227
                ntfs_error("wrong size in add_security\n");
2228
        if (error) {
2229
                ntfs_free(buf);
2230
                return error;
2231
        }
2232
        /* FIXME: Consider ACL inheritance. */
2233
        error = ntfs_create_attr(ino, ino->vol->at_security_descriptor,
2234
                                 0, buf, size, &se);
2235
        ntfs_free(buf);
2236
        return error;
2237
}
2238
 
2239
static int add_data(ntfs_inode* ino, unsigned char *data, int length)
2240
{
2241
        ntfs_attribute *da;
2242
 
2243
        return ntfs_create_attr(ino, ino->vol->at_data, 0, data, length, &da);
2244
}
2245
 
2246
/*
2247
 * We _could_ use 'dir' to help optimise inode allocation.
2248
 *
2249
 * FIXME: Need to undo what we do in ntfs_alloc_mft_record if we get an error
2250
 * further on in ntfs_alloc_inode. Either fold the two functions to allow
2251
 * proper undo or just deallocate the record from the mft bitmap. (AIA)
2252
 */
2253
int ntfs_alloc_inode(ntfs_inode *dir, ntfs_inode *result, const char *filename,
2254
                int namelen, ntfs_u32 flags)
2255
{
2256
        ntfs_volume *vol = dir->vol;
2257
        int err;
2258
        ntfs_u8 buffer[2];
2259
        ntfs_io io;
2260
 
2261
        err = ntfs_alloc_mft_record(vol, &(result->i_number));
2262
        if (err) {
2263
                if (err == -ENOSPC)
2264
                        ntfs_error("%s(): No free inodes.\n", __FUNCTION__);
2265
                return err;
2266
        }
2267
        /* Get the sequence number. */
2268
        io.fn_put = ntfs_put;
2269
        io.fn_get = ntfs_get;
2270
        io.param = buffer;
2271
        io.size = 2;
2272
        err = ntfs_read_attr(vol->mft_ino, vol->at_data, 0,
2273
                        ((__s64)result->i_number << vol->mft_record_size_bits)
2274
                        + 0x10, &io);
2275
        // FIXME: We are leaving the MFT in inconsistent state! (AIA)
2276
        if (err)
2277
                return err;
2278
        /* Increment the sequence number skipping zero. */
2279
        result->sequence_number = (NTFS_GETU16(buffer) + 1) & 0xffff;
2280
        if (!result->sequence_number)
2281
                result->sequence_number++;
2282
        result->vol = vol;
2283
        result->attr_count = 0;
2284
        result->attrs = 0;
2285
        result->record_count = 1;
2286
        result->records = ntfs_calloc(8 * sizeof(int));
2287
        if (!result->records)
2288
                goto mem_err_out;
2289
        result->records[0] = result->i_number;
2290
        result->attr = ntfs_calloc(vol->mft_record_size);
2291
        if (!result->attr) {
2292
                ntfs_free(result->records);
2293
                result->records = NULL;
2294
                goto mem_err_out;
2295
        }
2296
        ntfs_fill_mft_header(result->attr, vol->mft_record_size,
2297
                        result->sequence_number, 1, 1);
2298
        err = add_standard_information(result);
2299
        if (!err)
2300
                err = add_filename(result, dir, filename, namelen, flags);
2301
        if (!err)
2302
                err = add_security(result, dir);
2303
        // FIXME: We are leaving the MFT in inconsistent state on error! (AIA)
2304
        return err;
2305
mem_err_out:
2306
        // FIXME: We are leaving the MFT in inconsistent state! (AIA)
2307
        result->record_count = 0;
2308
        result->attr = NULL;
2309
        return -ENOMEM;
2310
}
2311
 
2312
int ntfs_alloc_file(ntfs_inode *dir, ntfs_inode *result, char *filename,
2313
                int namelen)
2314
{
2315
        int err;
2316
 
2317
        err = ntfs_alloc_inode(dir, result, filename, namelen, 0);
2318
        if (!err)
2319
                err = add_data(result, 0, 0);
2320
        return err;
2321
}
2322
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.