The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/ntfs/inode.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*
    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, __FUNCTION__ "(): %s 0x%x bytes at offset "
  675                         "0x%Lx %s inode 0x%x, attr type 0x%x.\n",
  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, __FUNCTION__ "(): EOPNOTSUPP: "
  750                         "inode = 0x%x, rnum = %i, offset = 0x%Lx, vcn = 0x%x, "
  751                         "s_vcn = 0x%x.\n", ino->i_number, rnum, offset, vcn,
  752                         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, __FUNCTION__ "(): attr 0x%x not found "
  797                                 "in inode 0x%x\n", 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, __FUNCTION__ "(): attr 0x%x not found "
  812                                 "in inode 0x%x\n", 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, __FUNCTION__ "(): rlen = %i.\n", 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, __FUNCTION__ "(): Entering with *r1len = %i, "
 1376                         "r2len = %i.\n", *r1len, r2len);
 1377         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Dumping 1st runlist.\n");
 1378         if (*rl1)
 1379                 dump_runlist(*rl1, *r1len);
 1380         else
 1381                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Not present.\n");
 1382         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Dumping 2nd runlist.\n");
 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, __FUNCTION__ "(): rlen = %i, rl_size = %i.\n",
 1388                         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, __FUNCTION__ "(): Have enough space "
 1395                                 "already.\n");
 1396         } else {
 1397                 /* Need more space. Reallocate. */
 1398                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Need more space.\n");
 1399                 rl = ntfs_vmalloc(rlen << sizeof(ntfs_runlist));
 1400                 if (!rl)
 1401                         return -ENOMEM;
 1402                 /* Copy over rl1. */
 1403                 ntfs_memcpy(rl, *rl1, *r1len * sizeof(ntfs_runlist));
 1404                 ntfs_vfree(*rl1);
 1405                 *rl1 = rl;
 1406         }
 1407         /* Reuse rl_size as the current position index into rl. */
 1408         rl_size = *r1len - 1;
 1409         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): rl_size = %i.\n");
 1410         /* Coalesce neighbouring elements, if present. */
 1411         rl2_pos = 0;
 1412         if (rl[rl_size].lcn + rl[rl_size].len == rl2[rl2_pos].lcn) {
 1413                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Coalescing adjacent "
 1414                                 "runs.\n");
 1415                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Before: "
 1416                                 "rl[rl_size].len = %i.\n", rl[rl_size].len);
 1417                 rl[rl_size].len += rl2[rl2_pos].len;
 1418                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After: "
 1419                                 "rl[rl_size].len = %i.\n", rl[rl_size].len);
 1420                 rl2_pos++;
 1421                 r2len--;
 1422                 rlen--;
 1423         }
 1424         rl_size++;
 1425         /* Copy over rl2. */
 1426         ntfs_memcpy(rl + rl_size, rl2 + rl2_pos, r2len * sizeof(ntfs_runlist));
 1427         rlen--;
 1428         rl[rlen].lcn = (ntfs_cluster_t)-1;
 1429         rl[rlen].len = (ntfs_cluster_t)0;
 1430         *r1len = rlen;
 1431         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Dumping result runlist.\n");
 1432         dump_runlist(*rl1, *r1len);
 1433         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Returning with *r1len = "
 1434                         "%i.\n", rlen);
 1435         return 0;
 1436 }
 1437 
 1438 /**
 1439  * ntfs_alloc_mft_record - allocate an mft record
 1440  * @vol:        volume to allocate an mft record on
 1441  * @result:     the mft record number allocated
 1442  *
 1443  * Allocate a new mft record on disk. Return 0 on success or -ERRNO on error.
 1444  * On success, *@result contains the allocated mft record number. On error,
 1445  * *@result is -1UL.
 1446  *
 1447  * Note, this function doesn't actually set the mft record to be in use. This
 1448  * is done by the caller, which at the moment is only ntfs_alloc_inode().
 1449  *
 1450  * To find a free mft record, we scan the mft bitmap for a zero bit. To
 1451  * optimize this we start scanning at the place where we last stopped and we
 1452  * perform wrap around when we reach the end. Note, we do not try to allocate
 1453  * mft records below number 24 because numbers 0 to 15 are the defined system
 1454  * files anyway and 16 to 24 are special in that they are used for storing
 1455  * extension mft records for $MFT's $DATA attribute. This is required to avoid
 1456  * the possibility of creating a run list with a circular dependence which once
 1457  * written to disk can never be read in again. Windows will only use records
 1458  * 16 to 24 for normal files if the volume is completely out of space. We never
 1459  * use them which means that when the volume is really out of space we cannot
 1460  * create any more files while Windows can still create up to 8 small files. We
 1461  * can start doing this at some later time, doesn't matter much for now.
 1462  *
 1463  * When scanning the mft bitmap, we only search up to the last allocated mft
 1464  * record. If there are no free records left in the range 24 to number of
 1465  * allocated mft records, then we extend the mft data in order to create free
 1466  * mft records. We extend the allocated size of $MFT/$DATA by 16 records at a
 1467  * time or one cluster, if cluster size is above 16kiB. If there isn't
 1468  * sufficient space to do this, we try to extend by a single mft record or one
 1469  * cluster, if cluster size is above mft record size, but we only do this if
 1470  * there is enough free space, which we know from the values returned by the
 1471  * failed cluster allocation function when we tried to do the first allocation.
 1472  *
 1473  * No matter how many mft records we allocate, we initialize only the first
 1474  * allocated mft record (incrementing mft data size and initialized size) and
 1475  * return its number to the caller in @*result, unless there are less than 24
 1476  * mft records, in which case we allocate and initialize mft records until we
 1477  * reach record 24 which we consider as the first free mft record for use by
 1478  * normal files.
 1479  *
 1480  * If during any stage we overflow the initialized data in the mft bitmap, we
 1481  * extend the initialized size (and data size) by 8 bytes, allocating another
 1482  * cluster if required. The bitmap data size has to be at least equal to the
 1483  * number of mft records in the mft, but it can be bigger, in which case the
 1484  * superflous bits are padded with zeroes.
 1485  *
 1486  * Thus, when we return successfully (return value 0), we will have:
 1487  *      - initialized / extended the mft bitmap if necessary,
 1488  *      - initialized / extended the mft data if necessary,
 1489  *      - set the bit corresponding to the mft record being allocated in the
 1490  *        mft bitmap, and we will
 1491  *      - return the mft record number in @*result.
 1492  *
 1493  * On error (return value below zero), nothing will have changed. If we had
 1494  * changed anything before the error occured, we will have reverted back to
 1495  * the starting state before returning to the caller. Thus, except for bugs,
 1496  * we should always leave the volume in a consitents state when returning from
 1497  * this function. NOTE: Small exception to this is that we set the bit in the
 1498  * mft bitmap but we do not mark the mft record in use, which is inconsistent.
 1499  * However, the caller will immediately add the wanted attributes to the mft
 1500  * record, set it in use and write it out to disk, so there should be no
 1501  * problem.
 1502  *
 1503  * Note, this function cannot make use of most of the normal functions, like
 1504  * for example for attribute resizing, etc, because when the run list overflows
 1505  * the base mft record and an attribute list is used, it is very important
 1506  * that the extension mft records used to store the $DATA attribute of $MFT
 1507  * can be reached without having to read the information contained inside
 1508  * them, as this would make it impossible to find them in the first place
 1509  * after the volume is dismounted. $MFT/$BITMAP probably doesn't need to
 1510  * follow this rule because the bitmap is not essential for finding the mft
 1511  * records, but on the other hand, handling the bitmap in this special way
 1512  * would make life easier because otherwise there might be circular invocations
 1513  * of functions when reading the bitmap but if we are careful, we should be
 1514  * able to avoid all problems.
 1515  *
 1516  * FIXME: Don't forget $MftMirr, though this probably belongs in
 1517  *        ntfs_update_inode() (or even deeper). (AIA)
 1518  *
 1519  * FIXME: Want finer grained locking. (AIA)
 1520  */
 1521 static int ntfs_alloc_mft_record(ntfs_volume *vol, unsigned long *result)
 1522 {
 1523         unsigned long nr_mft_records, buf_size, buf_pos, pass_start, pass_end;
 1524         unsigned long last_read_pos, mft_rec_size, bit, l;
 1525         ntfs_attribute *data, *bmp;
 1526         __u8 *buf, *byte, pass, b, have_allocated_mftbmp = 0;
 1527         int rlen, rl_size = 0, r2len, rl2_size, old_data_rlen, err = 0;
 1528         ntfs_runlist *rl, *rl2;
 1529         ntfs_cluster_t lcn = 0, old_data_len;
 1530         ntfs_io io;
 1531         __s64 ll, old_data_allocated, old_data_initialized, old_data_size;
 1532 
 1533         *result = -1UL;
 1534         /* Allocate a buffer and setup the io structure. */
 1535         buf = (__u8*)__get_free_page(GFP_NOFS);
 1536         if (!buf)
 1537                 return -ENOMEM;
 1538         lock_kernel();
 1539         /* Get the $DATA and $BITMAP attributes of $MFT. */
 1540         data = ntfs_find_attr(vol->mft_ino, vol->at_data, 0);
 1541         bmp = ntfs_find_attr(vol->mft_ino, vol->at_bitmap, 0);
 1542         if (!data || !bmp) {
 1543                 err = -EINVAL;
 1544                 goto err_ret;
 1545         }
 1546         /* Determine the number of allocated mft records in the mft. */
 1547         pass_end = nr_mft_records = data->allocated >>
 1548                         vol->mft_record_size_bits;
 1549         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): nr_mft_records = %lu.\n",
 1550                         nr_mft_records);
 1551         /* Make sure we don't overflow the bitmap. */
 1552         l = bmp->initialized << 3;
 1553         if (l < nr_mft_records)
 1554                 // FIXME: It might be a good idea to extend the bitmap instead.
 1555                 pass_end = l;
 1556         pass = 1;
 1557         buf_pos = vol->mft_data_pos;
 1558         if (buf_pos >= pass_end) {
 1559                 buf_pos = 24UL;
 1560                 pass = 2;
 1561         }
 1562         pass_start = buf_pos;
 1563         rl = bmp->d.r.runlist;
 1564         rlen = bmp->d.r.len - 1;
 1565         lcn = rl[rlen].lcn + rl[rlen].len;
 1566         io.fn_put = ntfs_put;
 1567         io.fn_get = ntfs_get;
 1568         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Starting bitmap search.\n");
 1569         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): pass = %i, pass_start = %lu, "
 1570                         "pass_end = %lu.\n", pass, pass_start, pass_end);
 1571         byte = NULL; // FIXME: For debugging only.
 1572         /* Loop until a free mft record is found. */
 1573         io.size = (nr_mft_records >> 3) & ~PAGE_MASK;
 1574         for (;; io.size = PAGE_SIZE) {
 1575                 io.param = buf;
 1576                 io.do_read = 1;
 1577                 last_read_pos = buf_pos >> 3;
 1578                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Before: "
 1579                                 "bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "
 1580                                 "bmp->initialized = 0x%Lx.\n", bmp->allocated,
 1581                                 bmp->size, bmp->initialized);
 1582                 err = ntfs_readwrite_attr(vol->mft_ino, bmp, last_read_pos,
 1583                                 &io);
 1584                 if (err)
 1585                         goto err_ret;
 1586                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Read %lu bytes.\n",
 1587                                 (unsigned long)io.size);
 1588                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After: "
 1589                                 "bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "
 1590                                 "bmp->initialized = 0x%Lx.\n", bmp->allocated,
 1591                                 bmp->size, bmp->initialized);
 1592                 if (!io.size)
 1593                         goto pass_done;
 1594                 buf_size = io.size << 3;
 1595                 bit = buf_pos & 7UL;
 1596                 buf_pos &= ~7UL;
 1597                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Before loop: "
 1598                                 "buf_size = %lu, buf_pos = %lu, bit = %lu, "
 1599                                 "*byte = 0x%x, b = %u.\n",
 1600                                 buf_size, buf_pos, bit, byte ? *byte : -1, b);
 1601                 for (; bit < buf_size && bit + buf_pos < pass_end;
 1602                                 bit &= ~7UL, bit += 8UL) {
 1603                         byte = buf + (bit >> 3);
 1604                         if (*byte == 0xff)
 1605                                 continue;
 1606                         b = ffz((unsigned long)*byte);
 1607                         if (b < (__u8)8 && b >= (bit & 7UL)) {
 1608                                 bit = b + (bit & ~7UL) + buf_pos;
 1609                                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "
 1610                                                 "Found free rec in for loop. "
 1611                                                 "bit = %lu\n", bit);
 1612                                 goto found_free_rec;
 1613                         }
 1614                 }
 1615                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After loop: "
 1616                                 "buf_size = %lu, buf_pos = %lu, bit = %lu, "
 1617                                 "*byte = 0x%x, b = %u.\n",
 1618                                 buf_size, buf_pos, bit, byte ? *byte : -1, b);
 1619                 buf_pos += buf_size;
 1620                 if (buf_pos < pass_end)
 1621                         continue;
 1622 pass_done:      /* Finished with the current pass. */
 1623                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At pass_done.\n");
 1624                 if (pass == 1) {
 1625                         /*
 1626                          * Now do pass 2, scanning the first part of the zone
 1627                          * we omitted in pass 1.
 1628                          */
 1629                         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Done pass "
 1630                                         "1.\n");
 1631                         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Pass = 2.\n");
 1632                         pass = 2;
 1633                         pass_end = pass_start;
 1634                         buf_pos = pass_start = 24UL;
 1635                         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): pass = %i, "
 1636                                         "pass_start = %lu, pass_end = %lu.\n",
 1637                                         pass, pass_start, pass_end);
 1638                         continue;
 1639                 } /* pass == 2 */
 1640                 /* No free records left. */
 1641                 if (bmp->initialized << 3 > nr_mft_records &&
 1642                                 bmp->initialized > 3) {
 1643                         /*
 1644                          * The mft bitmap is already bigger but the space is
 1645                          * not covered by mft records, this implies that the
 1646                          * next records are all free, so we already have found
 1647                          * a free record.
 1648                          */
 1649                         bit = nr_mft_records;
 1650                         if (bit < 24UL)
 1651                                 bit = 24UL;
 1652                         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Found free "
 1653                                         "record bit (#1) = 0x%lx.\n", bit);
 1654                         goto found_free_rec;
 1655                 }
 1656                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Done pass 2.\n");
 1657                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Before: "
 1658                                 "bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "
 1659                                 "bmp->initialized = 0x%Lx.\n", bmp->allocated,
 1660                                 bmp->size, bmp->initialized);
 1661                 /* Need to extend the mft bitmap. */
 1662                 if (bmp->initialized + 8LL > bmp->allocated) {
 1663                         ntfs_io io2;
 1664 
 1665                         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Initialized "
 1666                                         "> allocated.\n");
 1667                         /* Need to extend bitmap by one more cluster. */
 1668                         rl = bmp->d.r.runlist;
 1669                         rlen = bmp->d.r.len - 1;
 1670                         lcn = rl[rlen].lcn + rl[rlen].len;
 1671                         io2.fn_put = ntfs_put;
 1672                         io2.fn_get = ntfs_get;
 1673                         io2.param = &b;
 1674                         io2.size = 1;
 1675                         io2.do_read = 1;
 1676                         err = ntfs_readwrite_attr(vol->bitmap, data, lcn >> 3,
 1677                                         &io2);
 1678                         if (err)
 1679                                 goto err_ret;
 1680                         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Read %lu "
 1681                                         "bytes.\n", (unsigned long)io2.size);
 1682                         if (io2.size == 1 && b != 0xff) {
 1683                                 __u8 tb = 1 << (lcn & (ntfs_cluster_t)7);
 1684                                 if (!(b & tb)) {
 1685                                         /* Next cluster is free. Allocate it. */
 1686                                         b |= tb;
 1687                                         io2.param = &b;
 1688                                         io2.do_read = 0;
 1689                                         err = ntfs_readwrite_attr(vol->bitmap,
 1690                                                         data, lcn >> 3, &io2);
 1691                                         if (err || io.size != 1) {
 1692                                                 if (!err)
 1693                                                         err = -EIO;
 1694                                                 goto err_ret;
 1695                                         }
 1696 append_mftbmp_simple:                   rl[rlen].len++;
 1697                                         have_allocated_mftbmp |= 1;
 1698                                         ntfs_debug(DEBUG_OTHER, __FUNCTION__
 1699                                                         "(): Appending one "
 1700                                                         "cluster to mftbmp.\n");
 1701                                 }
 1702                         }
 1703                         if (!have_allocated_mftbmp) {
 1704                                 /* Allocate a cluster from the DATA_ZONE. */
 1705                                 ntfs_cluster_t lcn2 = lcn;
 1706                                 ntfs_cluster_t count = 1;
 1707                                 err = ntfs_allocate_clusters(vol, &lcn2,
 1708                                                 &count, &rl2, &r2len,
 1709                                                 DATA_ZONE);
 1710                                 if (err)
 1711                                         goto err_ret;
 1712                                 if (count != 1 || lcn2 <= 0) {
 1713                                         if (count > 0) {
 1714 rl2_dealloc_err_out:                            if (ntfs_deallocate_clusters(
 1715                                                         vol, rl2, r2len))
 1716                                                         ntfs_error(__FUNCTION__
 1717                                                         "(): Cluster "
 1718                                                         "deallocation in error "
 1719                                                         "code path failed! You "
 1720                                                         "should run chkdsk.\n");
 1721                                         }
 1722                                         ntfs_vfree(rl2);
 1723                                         if (!err)
 1724                                                 err = -EINVAL;
 1725                                         goto err_ret;
 1726                                 }
 1727                                 if (lcn2 == lcn) {
 1728                                         ntfs_vfree(rl2);
 1729                                         goto append_mftbmp_simple;
 1730                                 }
 1731                                 /* We need to append a new run. */
 1732                                 rl_size = (rlen * sizeof(ntfs_runlist) +
 1733                                                 PAGE_SIZE - 1) & PAGE_MASK;
 1734                                 /* Reallocate memory if necessary. */
 1735                                 if ((rlen + 2) * sizeof(ntfs_runlist) >=
 1736                                                 rl_size) {
 1737                                         ntfs_runlist *rlt;
 1738 
 1739                                         rl_size += PAGE_SIZE;
 1740                                         rlt = ntfs_vmalloc(rl_size);
 1741                                         if (!rlt) {
 1742                                                 err = -ENOMEM;
 1743                                                 goto rl2_dealloc_err_out;
 1744                                         }
 1745                                         ntfs_memcpy(rlt, rl, rl_size -
 1746                                                         PAGE_SIZE);
 1747                                         ntfs_vfree(rl);
 1748                                         bmp->d.r.runlist = rl = rlt;
 1749                                 }
 1750                                 ntfs_vfree(rl2);
 1751                                 rl[rlen].lcn = lcn = lcn2;
 1752                                 rl[rlen].len = count;
 1753                                 bmp->d.r.len = ++rlen;
 1754                                 have_allocated_mftbmp |= 2;
 1755                                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "
 1756                                                 "Adding run to mftbmp. "
 1757                                                 "LCN = %i, len = %i\n", lcn,
 1758                                                 count);
 1759                         }
 1760                         /*
 1761                          * We now have extended the mft bitmap allocated size
 1762                          * by one cluster. Reflect this in the attribute.
 1763                          */
 1764                         bmp->allocated += (__s64)vol->cluster_size;
 1765                 }
 1766                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After: "
 1767                                 "bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "
 1768                                 "bmp->initialized = 0x%Lx.\n", bmp->allocated,
 1769                                 bmp->size, bmp->initialized);
 1770                 /* We now have sufficient allocated space. */
 1771                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Now have sufficient "
 1772                                 "allocated space in mftbmp.\n");
 1773                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Before: "
 1774                                 "bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "
 1775                                 "bmp->initialized = 0x%Lx.\n", bmp->allocated,
 1776                                 bmp->size, bmp->initialized);
 1777                 buf_pos = bmp->initialized;
 1778                 bmp->initialized += 8LL;
 1779                 if (bmp->initialized > bmp->size)
 1780                         bmp->size = bmp->initialized;
 1781                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After: "
 1782                                 "bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "
 1783                                 "bmp->initialized = 0x%Lx.\n", bmp->allocated,
 1784                                 bmp->size, bmp->initialized);
 1785                 have_allocated_mftbmp |= 4;
 1786                 /* Update the mft bitmap attribute value. */
 1787                 memset(buf, 0, 8);
 1788                 io.param = buf;
 1789                 io.size = 8;
 1790                 io.do_read = 0;
 1791                 err = ntfs_readwrite_attr(vol->mft_ino, bmp, buf_pos, &io);
 1792                 if (err || io.size != 8) {
 1793                         if (!err)
 1794                                 err = -EIO;
 1795                         goto shrink_mftbmp_err_ret;
 1796                 }
 1797                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Wrote extended "
 1798                                 "mftbmp bytes %lu.\n", (unsigned long)io.size);
 1799                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After write: "
 1800                                 "bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "
 1801                                 "bmp->initialized = 0x%Lx.\n", bmp->allocated,
 1802                                 bmp->size, bmp->initialized);
 1803                 bit = buf_pos << 3;
 1804                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Found free record "
 1805                                 "bit (#2) = 0x%lx.\n", bit);
 1806                 goto found_free_rec;
 1807         }
 1808 found_free_rec:
 1809         /* bit is the found free mft record. Allocate it in the mft bitmap. */
 1810         vol->mft_data_pos = bit;
 1811         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At found_free_rec.\n");
 1812         io.param = buf;
 1813         io.size = 1;
 1814         io.do_read = 1;
 1815         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Before update: "
 1816                         "bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "
 1817                         "bmp->initialized = 0x%Lx.\n", bmp->allocated,
 1818                         bmp->size, bmp->initialized);
 1819         err = ntfs_readwrite_attr(vol->mft_ino, bmp, bit >> 3, &io);
 1820         if (err || io.size != 1) {
 1821                 if (!err)
 1822                         err = -EIO;
 1823                 goto shrink_mftbmp_err_ret;
 1824         }
 1825         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Read %lu bytes.\n",
 1826                         (unsigned long)io.size);
 1827 #ifdef DEBUG
 1828         /* Check our bit is really zero! */
 1829         if (*buf & (1 << (bit & 7)))
 1830                 BUG();
 1831 #endif
 1832         *buf |= 1 << (bit & 7);
 1833         io.param = buf;
 1834         io.do_read = 0;
 1835         err = ntfs_readwrite_attr(vol->mft_ino, bmp, bit >> 3, &io);
 1836         if (err || io.size != 1) {
 1837                 if (!err)
 1838                         err = -EIO;
 1839                 goto shrink_mftbmp_err_ret;
 1840         }
 1841         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Wrote %lu bytes.\n",
 1842                         (unsigned long)io.size);
 1843         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After update: "
 1844                         "bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "
 1845                         "bmp->initialized = 0x%Lx.\n", bmp->allocated,
 1846                         bmp->size, bmp->initialized);
 1847         /* The mft bitmap is now uptodate. Deal with mft data attribute now. */
 1848         ll = (__s64)(bit + 1) << vol->mft_record_size_bits;
 1849         if (ll <= data->initialized) {
 1850                 /* The allocated record is already initialized. We are done! */
 1851                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Allocated mft record "
 1852                                 "already initialized!\n");
 1853                 goto done_ret;
 1854         }
 1855         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Allocated mft record needs "
 1856                         "to be initialized.\n");
 1857         /* The mft record is outside the initialized data. */
 1858         mft_rec_size = (unsigned long)vol->mft_record_size;
 1859         /* Preserve old values for undo purposes. */
 1860         old_data_allocated = data->allocated;
 1861         old_data_rlen = data->d.r.len - 1;
 1862         old_data_len = data->d.r.runlist[old_data_rlen].len;
 1863         /*
 1864          * If necessary, extend the mft until it covers the allocated record.
 1865          * The loop is only actually used when a freshly formatted volume is
 1866          * first written to. But it optimizes away nicely in the common case.
 1867          */
 1868         while (ll > data->allocated) {
 1869                 ntfs_cluster_t lcn2, nr_lcn2, nr, min_nr;
 1870 
 1871                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Extending mft "
 1872                                 "data allocation, data->allocated = 0x%Lx, "
 1873                                 "data->size = 0x%Lx, data->initialized = "
 1874                                 "0x%Lx.\n", data->allocated, data->size,
 1875                                 data->initialized);
 1876                 /* Minimum allocation is one mft record worth of clusters. */
 1877                 if (mft_rec_size <= vol->cluster_size)
 1878                         min_nr = (ntfs_cluster_t)1;
 1879                 else
 1880                         min_nr = mft_rec_size >> vol->cluster_size_bits;
 1881                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): min_nr = %i.\n",
 1882                                 min_nr);
 1883                 /* Allocate 16 mft records worth of clusters. */
 1884                 nr = mft_rec_size << 4 >> vol->cluster_size_bits;
 1885                 if (!nr)
 1886                         nr = (ntfs_cluster_t)1;
 1887                 /* Determine the preferred allocation location. */
 1888                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): nr = %i.\n", nr);
 1889                 rl2 = data->d.r.runlist;
 1890                 r2len = data->d.r.len;
 1891                 lcn2 = rl2[r2len - 1].lcn + rl2[r2len - 1].len;
 1892                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): rl2[r2len - 1].lcn "
 1893                                 "= %i, .len = %i.\n", rl2[r2len - 1].lcn,
 1894                                 rl2[r2len - 1].len);
 1895                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): lcn2 = %i, r2len = "
 1896                                 "%i.\n", lcn2, r2len);
 1897 retry_mft_data_allocation:
 1898                 nr_lcn2 = nr;
 1899                 err = ntfs_allocate_clusters(vol, &lcn2, &nr_lcn2, &rl2,
 1900                                 &r2len, MFT_ZONE);
 1901 #ifdef DEBUG
 1902                 if (!err && nr_lcn2 < min_nr)
 1903                         /* Allocated less than minimum needed. Weird! */
 1904                         BUG();
 1905 #endif
 1906                 if (err) {
 1907                         /*
 1908                          * If there isn't enough space to do the wanted
 1909                          * allocation, but there is enough space to do a
 1910                          * minimal allocation, then try that, unless the wanted
 1911                          * allocation was already the minimal allocation.
 1912                          */
 1913                         if (err == -ENOSPC && nr > min_nr &&
 1914                                         nr_lcn2 >= min_nr) {
 1915                                 nr = min_nr;
 1916                                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "
 1917                                                 "Retrying mft data "
 1918                                                 "allocation, nr = min_nr = %i"
 1919                                                 ".\n", nr);
 1920                                 goto retry_mft_data_allocation;
 1921                         }
 1922                         goto undo_mftbmp_alloc_err_ret;
 1923                 }
 1924                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Allocated %i "
 1925                                 "clusters starting at LCN %i.\n", nr_lcn2,
 1926                                 lcn2);
 1927                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Allocated "
 1928                                 "runlist:\n");
 1929                 dump_runlist(rl2, r2len);
 1930                 /* Append rl2 to the mft data attribute's run list. */
 1931                 err = splice_runlists(&data->d.r.runlist, (int*)&data->d.r.len,
 1932                                 rl2, r2len);
 1933                 if (err) {
 1934                         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "
 1935                                         "splice_runlists failed with error "
 1936                                         "code %i.\n", -err);
 1937                         goto undo_partial_data_alloc_err_ret;
 1938                 }
 1939                 /* Reflect the allocated clusters in the mft allocated data. */
 1940                 data->allocated += nr_lcn2 << vol->cluster_size_bits;
 1941                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After extending mft "
 1942                                 "data allocation, data->allocated = 0x%Lx, "
 1943                                 "data->size = 0x%Lx, data->initialized = "
 1944                                 "0x%Lx.\n", data->allocated, data->size,
 1945                                 data->initialized);
 1946         }
 1947         /* Prepare a formatted (empty) mft record. */
 1948         memset(buf, 0, mft_rec_size);
 1949         ntfs_fill_mft_header(buf, mft_rec_size, 0, 0, 0);
 1950         err = ntfs_insert_fixups(buf, mft_rec_size);
 1951         if (err)
 1952                 goto undo_data_alloc_err_ret;
 1953         /*
 1954          * Extend mft data initialized size to reach the allocated mft record
 1955          * and write the formatted mft record buffer to each mft record being
 1956          * initialized. Note, that ntfs_readwrite_attr extends both
 1957          * data->initialized and data->size, so no need for us to touch them.
 1958          */
 1959         old_data_initialized = data->initialized;
 1960         old_data_size = data->size;
 1961         while (ll > data->initialized) {
 1962                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Initializing mft "
 1963                                 "record 0x%Lx.\n",
 1964                                 data->initialized >> vol->mft_record_size_bits);
 1965                 io.param = buf;
 1966                 io.size = mft_rec_size;
 1967                 io.do_read = 0;
 1968                 err = ntfs_readwrite_attr(vol->mft_ino, data,
 1969                                 data->initialized, &io);
 1970                 if (err || io.size != mft_rec_size) {
 1971                         if (!err)
 1972                                 err = -EIO;
 1973                         goto undo_data_init_err_ret;
 1974                 }
 1975                 ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Wrote %i bytes to "
 1976                                 "mft data.\n", io.size);
 1977         }
 1978         /* Update the VFS inode size as well. */
 1979         VFS_I(vol->mft_ino)->i_size = data->size;
 1980 #ifdef DEBUG
 1981         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After mft record "
 1982                         "initialization: data->allocated = 0x%Lx, data->size "
 1983                         "= 0x%Lx, data->initialized = 0x%Lx.\n",
 1984                         data->allocated, data->size, data->initialized);
 1985         /* Sanity checks. */
 1986         if (data->size > data->allocated || data->size < data->initialized ||
 1987                         data->initialized > data->allocated)
 1988                 BUG();
 1989 #endif
 1990 done_ret:
 1991         /* Return the number of the allocated mft record. */
 1992         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At done_ret. *result = bit = "
 1993                         "0x%lx.\n", bit);
 1994         *result = bit;
 1995         vol->mft_data_pos = bit + 1;
 1996 err_ret:
 1997         unlock_kernel();
 1998         free_page((unsigned long)buf);
 1999         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Syncing inode $MFT.\n");
 2000         if (ntfs_update_inode(vol->mft_ino))
 2001                 ntfs_error(__FUNCTION__ "(): Failed to sync inode $MFT. "
 2002                                 "Continuing anyway.\n");
 2003         if (!err) {
 2004                 ntfs_debug(DEBUG_FILE3, __FUNCTION__ "(): Done. Allocated mft "
 2005                                 "record number *result = 0x%lx.\n", *result);
 2006                 return 0;
 2007         }
 2008         if (err != -ENOSPC)
 2009                 ntfs_error(__FUNCTION__ "(): Failed to allocate an mft "
 2010                                 "record. Returning error code %i.\n", -err);
 2011         else
 2012                 ntfs_debug(DEBUG_FILE3, __FUNCTION__ "(): Failed to allocate "
 2013                                 "an mft record due to lack of free space.\n");
 2014         return err;
 2015 undo_data_init_err_ret:
 2016         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At "
 2017                         "undo_data_init_err_ret.\n");
 2018         data->initialized = old_data_initialized;
 2019         data->size = old_data_size;
 2020 undo_data_alloc_err_ret:
 2021         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At undo_data_alloc_err_ret."
 2022                         "\n");
 2023         data->allocated = old_data_allocated;
 2024 undo_partial_data_alloc_err_ret:
 2025         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At "
 2026                         "undo_partial_data_alloc_err_ret.\n");
 2027         /* Deallocate the clusters. */
 2028         if (ntfs_deallocate_clusters(vol, rl2, r2len))
 2029                 ntfs_error(__FUNCTION__ "(): Error deallocating clusters in "
 2030                                 "error code path. You should run chkdsk.\n");
 2031         ntfs_vfree(rl2);
 2032         /* Revert the run list back to what it was before. */
 2033         r2len = data->d.r.len;
 2034         rl2 = data->d.r.runlist;
 2035         rl2[old_data_rlen++].len = old_data_len;
 2036         rl2[old_data_rlen].lcn = (ntfs_cluster_t)-1;
 2037         rl2[old_data_rlen].len = (ntfs_cluster_t)0;
 2038         data->d.r.len = old_data_rlen;
 2039         rl2_size = ((old_data_rlen + 1) * sizeof(ntfs_runlist) + PAGE_SIZE -
 2040                         1) & PAGE_MASK;
 2041         /* Reallocate memory freeing any extra memory allocated. */
 2042         if (rl2_size < ((r2len * sizeof(ntfs_runlist) + PAGE_SIZE - 1) &
 2043                         PAGE_MASK)) {
 2044                 rl2 = ntfs_vmalloc(rl2_size);
 2045                 if (rl2) {
 2046                         ntfs_memcpy(rl2, data->d.r.runlist, rl2_size);
 2047                         ntfs_vfree(data->d.r.runlist);
 2048                         data->d.r.runlist = rl2;
 2049                 } else
 2050                         ntfs_error(__FUNCTION__ "(): Error reallocating "
 2051                                         "memory in error code path. This "
 2052                                         "should be harmless.\n");
 2053         }       
 2054 undo_mftbmp_alloc_err_ret:
 2055         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At "
 2056                         "undo_mftbmp_alloc_err_ret.\n");
 2057         /* Deallocate the allocated bit in the mft bitmap. */
 2058         io.param = buf;
 2059         io.size = 1;
 2060         io.do_read = 1;
 2061         err = ntfs_readwrite_attr(vol->mft_ino, bmp, bit >> 3, &io);
 2062         if (!err && io.size == 1) {
 2063                 *buf &= ~(1 << (bit & 7));
 2064                 io.param = buf;
 2065                 io.do_read = 0;
 2066                 err = ntfs_readwrite_attr(vol->mft_ino, bmp, bit >> 3, &io);
 2067         }
 2068         if (err || io.size != 1) {
 2069                 if (!err)
 2070                         err = -EIO;
 2071                 ntfs_error(__FUNCTION__ "(): Error deallocating mft record in "
 2072                                 "error code path. You should run chkdsk.\n");
 2073         }
 2074 shrink_mftbmp_err_ret:
 2075         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At shrink_mftbmp_err_ret.\n");
 2076         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): have_allocated_mftbmp = "
 2077                         "%i.\n", have_allocated_mftbmp);
 2078         if (!have_allocated_mftbmp)
 2079                 goto err_ret;
 2080         /* Shrink the mftbmp back to previous size. */
 2081         if (bmp->size == bmp->initialized)
 2082                 bmp->size -= 8LL;
 2083         bmp->initialized -= 8LL;
 2084         have_allocated_mftbmp &= ~4;
 2085         /* If no allocation occured then we are done. */
 2086         ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): have_allocated_mftbmp = "
 2087                         "%i.\n", have_allocated_mftbmp);
 2088         if (!have_allocated_mftbmp)
 2089                 goto err_ret;
 2090         /* Deallocate the allocated cluster. */
 2091         bmp->allocated -= (__s64)vol->cluster_size;
 2092         if (ntfs_deallocate_cluster_run(vol, lcn, (ntfs_cluster_t)1))
 2093                 ntfs_error(__FUNCTION__ "(): Error deallocating cluster in "
 2094                                 "error code path. You should run chkdsk.\n");
 2095         switch (have_allocated_mftbmp & 3) {
 2096         case 1:
 2097                 /* Delete the last lcn from the last run of mftbmp. */
 2098                 rl[rlen - 1].len--;
 2099                 break;
 2100         case 2:
 2101                 /* Delete the last run of mftbmp. */
 2102                 bmp->d.r.len = --rlen;
 2103                 /* Reallocate memory if necessary. */
 2104                 if ((rlen + 1) * sizeof(ntfs_runlist) <= rl_size - PAGE_SIZE) {
 2105                         ntfs_runlist *rlt;
 2106 
 2107                         rl_size -= PAGE_SIZE;
 2108                         rlt = ntfs_vmalloc(rl_size);
 2109                         if (rlt) {
 2110                                 ntfs_memcpy(rlt, rl, rl_size);
 2111                                 ntfs_vfree(rl);
 2112                                 bmp->d.r.runlist = rl = rlt;
 2113                         } else
 2114                                 ntfs_error(__FUNCTION__ "(): Error "
 2115                                                 "reallocating memory in error "
 2116                                                 "code path. This should be "
 2117                                                 "harmless.\n");
 2118                 }
 2119                 bmp->d.r.runlist[bmp->d.r.len].lcn = (ntfs_cluster_t)-1;
 2120                 bmp->d.r.runlist[bmp->d.r.len].len = (ntfs_cluster_t)0;
 2121                 break;
 2122         default:
 2123                 BUG();
 2124         }
 2125         goto err_ret;
 2126 }
 2127 
 2128 /* We need 0x48 bytes in total. */
 2129 static int add_standard_information(ntfs_inode *ino)
 2130 {
 2131         ntfs_time64_t now;
 2132         char data[0x30];
 2133         char *position = data;
 2134         ntfs_attribute *si;
 2135 
 2136         now = ntfs_now();
 2137         NTFS_PUTU64(position + 0x00, now);              /* File creation */
 2138         NTFS_PUTU64(position + 0x08, now);              /* Last modification */
 2139         NTFS_PUTU64(position + 0x10, now);              /* Last mod for MFT */
 2140         NTFS_PUTU64(position + 0x18, now);              /* Last access */
 2141         NTFS_PUTU64(position + 0x20, 0);                /* MSDOS file perms */
 2142         NTFS_PUTU64(position + 0x28, 0);                /* unknown */
 2143         return ntfs_create_attr(ino, ino->vol->at_standard_information, 0,
 2144                         data, sizeof(data), &si);
 2145 }
 2146 
 2147 static int add_filename(ntfs_inode *ino, ntfs_inode *dir, 
 2148                 const unsigned char *filename, int length, ntfs_u32 flags)
 2149 {
 2150         unsigned char *position;
 2151         unsigned int size;
 2152         ntfs_time64_t now;
 2153         int count, error;
 2154         unsigned char* data;
 2155         ntfs_attribute *fn;
 2156 
 2157         /* Work out the size. */
 2158         size = 0x42 + 2 * length;
 2159         data = ntfs_malloc(size);
 2160         if (!data)
 2161                 return -ENOMEM;
 2162         /* Search for a position. */
 2163         position = data;
 2164         NTFS_PUTINUM(position, dir);                    /* Inode num of dir */
 2165         now = ntfs_now();
 2166         NTFS_PUTU64(position + 0x08, now);              /* File creation */
 2167         NTFS_PUTU64(position + 0x10, now);              /* Last modification */
 2168         NTFS_PUTU64(position + 0x18, now);              /* Last mod for MFT */
 2169         NTFS_PUTU64(position + 0x20, now);              /* Last access */
 2170         /* FIXME: Get the following two sizes by finding the data attribute
 2171          * in ino->attr and copying the corresponding fields from there.
 2172          * If no data present then set to zero. In current implementation
 2173          * add_data is called after add_filename so zero is correct on
 2174          * creation. Need to change when we have hard links / support different
 2175          * filename namespaces. (AIA) */
 2176         NTFS_PUTS64(position + 0x28, 0);                /* Allocated size */
 2177         NTFS_PUTS64(position + 0x30, 0);                /* Data size */
 2178         NTFS_PUTU32(position + 0x38, flags);            /* File flags */
 2179         NTFS_PUTU32(position + 0x3c, 0);                /* We don't use these
 2180                                                          * features yet. */
 2181         NTFS_PUTU8(position + 0x40, length);            /* Filename length */
 2182         NTFS_PUTU8(position + 0x41, 0);                 /* Only long name */
 2183                 /* FIXME: This is madness. We are defining the POSIX namespace
 2184                  * for the filename here which can mean that the file will be
 2185                  * invisible when in Windows NT/2k! )-: (AIA) */
 2186         position += 0x42;
 2187         for (count = 0; count < length; count++) {
 2188                 NTFS_PUTU16(position + 2 * count, filename[count]);
 2189         }
 2190         error = ntfs_create_attr(ino, ino->vol->at_file_name, 0, data, size,
 2191                                  &fn);
 2192         if (!error)
 2193                 error = ntfs_dir_add(dir, ino, fn);
 2194         ntfs_free(data);
 2195         return error;
 2196 }
 2197 
 2198 int add_security(ntfs_inode* ino, ntfs_inode* dir)
 2199 {
 2200         int error;
 2201         char *buf;
 2202         int size;
 2203         ntfs_attribute* attr;
 2204         ntfs_io io;
 2205         ntfs_attribute *se;
 2206 
 2207         attr = ntfs_find_attr(dir, ino->vol->at_security_descriptor, 0);
 2208         if (!attr)
 2209                 return -EOPNOTSUPP; /* Need security in directory. */
 2210         size = attr->size;
 2211         if (size > 512)
 2212                 return -EOPNOTSUPP;
 2213         buf = ntfs_malloc(size);
 2214         if (!buf)
 2215                 return -ENOMEM;
 2216         io.fn_get = ntfs_get;
 2217         io.fn_put = ntfs_put;
 2218         io.param = buf;
 2219         io.size = size;
 2220         error = ntfs_read_attr(dir, ino->vol->at_security_descriptor, 0, 0,&io);
 2221         if (!error && io.size != size)
 2222                 ntfs_error("wrong size in add_security\n");
 2223         if (error) {
 2224                 ntfs_free(buf);
 2225                 return error;
 2226         }
 2227         /* FIXME: Consider ACL inheritance. */
 2228         error = ntfs_create_attr(ino, ino->vol->at_security_descriptor,
 2229                                  0, buf, size, &se);
 2230         ntfs_free(buf);
 2231         return error;
 2232 }
 2233 
 2234 static int add_data(ntfs_inode* ino, unsigned char *data, int length)
 2235 {
 2236         ntfs_attribute *da;
 2237         
 2238         return ntfs_create_attr(ino, ino->vol->at_data, 0, data, length, &da);
 2239 }
 2240 
 2241 /*
 2242  * We _could_ use 'dir' to help optimise inode allocation.
 2243  *
 2244  * FIXME: Need to undo what we do in ntfs_alloc_mft_record if we get an error
 2245  * further on in ntfs_alloc_inode. Either fold the two functions to allow
 2246  * proper undo or just deallocate the record from the mft bitmap. (AIA)
 2247  */
 2248 int ntfs_alloc_inode(ntfs_inode *dir, ntfs_inode *result, const char *filename,
 2249                 int namelen, ntfs_u32 flags)
 2250 {
 2251         ntfs_volume *vol = dir->vol;
 2252         int err;
 2253         ntfs_u8 buffer[2];
 2254         ntfs_io io;
 2255 
 2256         err = ntfs_alloc_mft_record(vol, &(result->i_number));
 2257         if (err) {
 2258                 if (err == -ENOSPC)
 2259                         ntfs_error(__FUNCTION__ "(): No free inodes.\n");
 2260                 return err;
 2261         }
 2262         /* Get the sequence number. */
 2263         io.fn_put = ntfs_put;
 2264         io.fn_get = ntfs_get;
 2265         io.param = buffer;
 2266         io.size = 2;
 2267         err = ntfs_read_attr(vol->mft_ino, vol->at_data, 0, 
 2268                         ((__s64)result->i_number << vol->mft_record_size_bits)
 2269                         + 0x10, &io);
 2270         // FIXME: We are leaving the MFT in inconsistent state! (AIA)
 2271         if (err)
 2272                 return err;
 2273         /* Increment the sequence number skipping zero. */
 2274         result->sequence_number = (NTFS_GETU16(buffer) + 1) & 0xffff;
 2275         if (!result->sequence_number)
 2276                 result->sequence_number++;
 2277         result->vol = vol;
 2278         result->attr_count = 0;
 2279         result->attrs = 0;
 2280         result->record_count = 1;
 2281         result->records = ntfs_calloc(8 * sizeof(int));
 2282         if (!result->records)
 2283                 goto mem_err_out;
 2284         result->records[0] = result->i_number;
 2285         result->attr = ntfs_calloc(vol->mft_record_size);
 2286         if (!result->attr) {
 2287                 ntfs_free(result->records);
 2288                 result->records = NULL;
 2289                 goto mem_err_out;
 2290         }
 2291         ntfs_fill_mft_header(result->attr, vol->mft_record_size,
 2292                         result->sequence_number, 1, 1);
 2293         err = add_standard_information(result);
 2294         if (!err)
 2295                 err = add_filename(result, dir, filename, namelen, flags);
 2296         if (!err)
 2297                 err = add_security(result, dir);
 2298         // FIXME: We are leaving the MFT in inconsistent state on error! (AIA)
 2299         return err;
 2300 mem_err_out:
 2301         // FIXME: We are leaving the MFT in inconsistent state! (AIA)
 2302         result->record_count = 0;
 2303         result->attr = NULL;
 2304         return -ENOMEM;
 2305 }
 2306 
 2307 int ntfs_alloc_file(ntfs_inode *dir, ntfs_inode *result, char *filename,
 2308                 int namelen)
 2309 {
 2310         int err;
 2311 
 2312         err = ntfs_alloc_inode(dir, result, filename, namelen, 0);
 2313         if (!err)
 2314                 err = add_data(result, 0, 0);
 2315         return err;
 2316 }
 2317 

Cache object: 5d4ea7402d3dbd9f8f3d863110f81646


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.