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/hpfs/super.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  *  linux/fs/hpfs/super.c
    3  *
    4  *  Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
    5  *
    6  *  mounting, unmounting, error handling
    7  */
    8 
    9 #include <linux/string.h>
   10 #include "hpfs_fn.h"
   11 #include <linux/module.h>
   12 #include <linux/init.h>
   13 
   14 /* Mark the filesystem dirty, so that chkdsk checks it when os/2 booted */
   15 
   16 static void mark_dirty(struct super_block *s)
   17 {
   18         if (s->s_hpfs_chkdsk && !(s->s_flags & MS_RDONLY)) {
   19                 struct buffer_head *bh;
   20                 struct hpfs_spare_block *sb;
   21                 if ((sb = hpfs_map_sector(s, 17, &bh, 0))) {
   22                         sb->dirty = 1;
   23                         sb->old_wrote = 0;
   24                         mark_buffer_dirty(bh);
   25                         brelse(bh);
   26                 }
   27         }
   28 }
   29 
   30 /* Mark the filesystem clean (mark it dirty for chkdsk if chkdsk==2 or if there
   31    were errors) */
   32 
   33 static void unmark_dirty(struct super_block *s)
   34 {
   35         struct buffer_head *bh;
   36         struct hpfs_spare_block *sb;
   37         if (s->s_flags & MS_RDONLY) return;
   38         if ((sb = hpfs_map_sector(s, 17, &bh, 0))) {
   39                 sb->dirty = s->s_hpfs_chkdsk > 1 - s->s_hpfs_was_error;
   40                 sb->old_wrote = s->s_hpfs_chkdsk >= 2 && !s->s_hpfs_was_error;
   41                 mark_buffer_dirty(bh);
   42                 brelse(bh);
   43         }
   44 }
   45 
   46 /* Filesystem error... */
   47 
   48 #define ERR_BUF_SIZE 1024
   49 
   50 void hpfs_error(struct super_block *s, char *m,...)
   51 {
   52         char *buf;
   53         va_list l;
   54         va_start(l, m);
   55         if (!(buf = kmalloc(ERR_BUF_SIZE, GFP_KERNEL)))
   56                 printk("HPFS: No memory for error message '%s'\n",m);
   57         else if (vsprintf(buf, m, l) >= ERR_BUF_SIZE)
   58                 printk("HPFS: Grrrr... Kernel memory corrupted ... going on, but it'll crash very soon :-(\n");
   59         printk("HPFS: filesystem error: ");
   60         if (buf) printk("%s", buf);
   61         else printk("%s\n",m);
   62         if (!s->s_hpfs_was_error) {
   63                 if (s->s_hpfs_err == 2) {
   64                         printk("; crashing the system because you wanted it\n");
   65                         mark_dirty(s);
   66                         panic("HPFS panic");
   67                 } else if (s->s_hpfs_err == 1) {
   68                         if (s->s_flags & MS_RDONLY) printk("; already mounted read-only\n");
   69                         else {
   70                                 printk("; remounting read-only\n");
   71                                 mark_dirty(s);
   72                                 s->s_flags |= MS_RDONLY;
   73                         }
   74                 } else if (s->s_flags & MS_RDONLY) printk("; going on - but anything won't be destroyed because it's read-only\n");
   75                 else printk("; corrupted filesystem mounted read/write - your computer will explode within 20 seconds ... but you wanted it so!\n");
   76         } else printk("\n");
   77         if (buf) kfree(buf);
   78         s->s_hpfs_was_error = 1;
   79 }
   80 
   81 /* 
   82  * A little trick to detect cycles in many hpfs structures and don't let the
   83  * kernel crash on corrupted filesystem. When first called, set c2 to 0.
   84  *
   85  * BTW. chkdsk doesn't detect cycles correctly. When I had 2 lost directories
   86  * nested each in other, chkdsk locked up happilly.
   87  */
   88 
   89 int hpfs_stop_cycles(struct super_block *s, int key, int *c1, int *c2,
   90                 char *msg)
   91 {
   92         if (*c2 && *c1 == key) {
   93                 hpfs_error(s, "cycle detected on key %08x in %s", key, msg);
   94                 return 1;
   95         }
   96         (*c2)++;
   97         if (!((*c2 - 1) & *c2)) *c1 = key;
   98         return 0;
   99 }
  100 
  101 void hpfs_put_super(struct super_block *s)
  102 {
  103         if (s->s_hpfs_cp_table) kfree(s->s_hpfs_cp_table);
  104         if (s->s_hpfs_bmp_dir) kfree(s->s_hpfs_bmp_dir);
  105         unmark_dirty(s);
  106 }
  107 
  108 unsigned hpfs_count_one_bitmap(struct super_block *s, secno secno)
  109 {
  110         struct quad_buffer_head qbh;
  111         unsigned *bits;
  112         unsigned i, count;
  113         if (!(bits = hpfs_map_4sectors(s, secno, &qbh, 4))) return 0;
  114         count = 0;
  115         for (i = 0; i < 2048 / sizeof(unsigned); i++) {
  116                 unsigned b; 
  117                 if (!bits[i]) continue;
  118                 for (b = bits[i]; b; b>>=1) count += b & 1;
  119         }
  120         hpfs_brelse4(&qbh);
  121         return count;
  122 }
  123 
  124 static unsigned count_bitmaps(struct super_block *s)
  125 {
  126         unsigned n, count, n_bands;
  127         n_bands = (s->s_hpfs_fs_size + 0x3fff) >> 14;
  128         count = 0;
  129         for (n = 0; n < n_bands; n++)
  130                 count += hpfs_count_one_bitmap(s, s->s_hpfs_bmp_dir[n]);
  131         return count;
  132 }
  133 
  134 int hpfs_statfs(struct super_block *s, struct statfs *buf)
  135 {
  136         /*if (s->s_hpfs_n_free == -1) {*/
  137                 s->s_hpfs_n_free = count_bitmaps(s);
  138                 s->s_hpfs_n_free_dnodes = hpfs_count_one_bitmap(s, s->s_hpfs_dmap);
  139         /*}*/
  140         buf->f_type = s->s_magic;
  141         buf->f_bsize = 512;
  142         buf->f_blocks = s->s_hpfs_fs_size;
  143         buf->f_bfree = s->s_hpfs_n_free;
  144         buf->f_bavail = s->s_hpfs_n_free;
  145         buf->f_files = s->s_hpfs_dirband_size / 4;
  146         buf->f_ffree = s->s_hpfs_n_free_dnodes;
  147         buf->f_namelen = 254;
  148         return 0;
  149 }
  150 
  151 /* Super operations */
  152 
  153 static struct super_operations hpfs_sops =
  154 {
  155         read_inode:     hpfs_read_inode,
  156         delete_inode:   hpfs_delete_inode,
  157         put_super:      hpfs_put_super,
  158         statfs:         hpfs_statfs,
  159         remount_fs:     hpfs_remount_fs,
  160 };
  161 
  162 /*
  163  * A tiny parser for option strings, stolen from dosfs.
  164  *
  165  * Stolen again from read-only hpfs.
  166  */
  167 
  168 int parse_opts(char *opts, uid_t *uid, gid_t *gid, umode_t *umask,
  169                int *lowercase, int *conv, int *eas, int *chk, int *errs,
  170                int *chkdsk, int *timeshift)
  171 {
  172         char *p, *rhs;
  173 
  174         if (!opts)
  175                 return 1;
  176 
  177         /*printk("Parsing opts: '%s'\n",opts);*/
  178 
  179         for (p = strtok(opts, ","); p != 0; p = strtok(0, ",")) {
  180                 if ((rhs = strchr(p, '=')) != 0)
  181                         *rhs++ = '\0';
  182                 if (!strcmp(p, "help")) return 2;
  183                 if (!strcmp(p, "uid")) {
  184                         if (!rhs || !*rhs)
  185                                 return 0;
  186                         *uid = simple_strtoul(rhs, &rhs, 0);
  187                         if (*rhs)
  188                                 return 0;
  189                 }
  190                 else if (!strcmp(p, "gid")) {
  191                         if (!rhs || !*rhs)
  192                                 return 0;
  193                         *gid = simple_strtoul(rhs, &rhs, 0);
  194                         if (*rhs)
  195                                 return 0;
  196                 }
  197                 else if (!strcmp(p, "umask")) {
  198                         if (!rhs || !*rhs)
  199                                 return 0;
  200                         *umask = simple_strtoul(rhs, &rhs, 8);
  201                         if (*rhs)
  202                                 return 0;
  203                 }
  204                 else if (!strcmp(p, "timeshift")) {
  205                         int m = 1;
  206                         if (!rhs || !*rhs)
  207                                 return 0;
  208                         if (*rhs == '-') m = -1;
  209                         if (*rhs == '+' || *rhs == '-') rhs++;
  210                         *timeshift = simple_strtoul(rhs, &rhs, 0) * m;
  211                         if (*rhs)
  212                                 return 0;
  213                 }
  214                 else if (!strcmp(p, "case")) {
  215                         if (!rhs || !*rhs)
  216                                 return 0;
  217                         if (!strcmp(rhs, "lower"))
  218                                 *lowercase = 1;
  219                         else if (!strcmp(rhs, "asis"))
  220                                 *lowercase = 0;
  221                         else
  222                                 return 0;
  223                 }
  224                 else if (!strcmp(p, "conv")) {
  225                         if (!rhs || !*rhs)
  226                                 return 0;
  227                         if (!strcmp(rhs, "binary"))
  228                                 *conv = CONV_BINARY;
  229                         else if (!strcmp(rhs, "text"))
  230                                 *conv = CONV_TEXT;
  231                         else if (!strcmp(rhs, "auto"))
  232                                 *conv = CONV_AUTO;
  233                         else
  234                                 return 0;
  235                 }
  236                 else if (!strcmp(p, "check")) {
  237                         if (!rhs || !*rhs)
  238                                 return 0;
  239                         if (!strcmp(rhs, "none"))
  240                                 *chk = 0;
  241                         else if (!strcmp(rhs, "normal"))
  242                                 *chk = 1;
  243                         else if (!strcmp(rhs, "strict"))
  244                                 *chk = 2;
  245                         else
  246                                 return 0;
  247                 }
  248                 else if (!strcmp(p, "errors")) {
  249                         if (!rhs || !*rhs)
  250                                 return 0;
  251                         if (!strcmp(rhs, "continue"))
  252                                 *errs = 0;
  253                         else if (!strcmp(rhs, "remount-ro"))
  254                                 *errs = 1;
  255                         else if (!strcmp(rhs, "panic"))
  256                                 *errs = 2;
  257                         else
  258                                 return 0;
  259                 }
  260                 else if (!strcmp(p, "eas")) {
  261                         if (!rhs || !*rhs)
  262                                 return 0;
  263                         if (!strcmp(rhs, "no"))
  264                                 *eas = 0;
  265                         else if (!strcmp(rhs, "ro"))
  266                                 *eas = 1;
  267                         else if (!strcmp(rhs, "rw"))
  268                                 *eas = 2;
  269                         else
  270                                 return 0;
  271                 }
  272                 else if (!strcmp(p, "chkdsk")) {
  273                         if (!rhs || !*rhs)
  274                                 return 0;
  275                         if (!strcmp(rhs, "no"))
  276                                 *chkdsk = 0;
  277                         else if (!strcmp(rhs, "errors"))
  278                                 *chkdsk = 1;
  279                         else if (!strcmp(rhs, "always"))
  280                                 *chkdsk = 2;
  281                         else
  282                                 return 0;
  283                 }
  284                 else
  285                         return 0;
  286         }
  287         return 1;
  288 }
  289 
  290 static inline void hpfs_help(void)
  291 {
  292         printk("\n\
  293 HPFS filesystem options:\n\
  294       help              do not mount and display this text\n\
  295       uid=xxx           set uid of files that don't have uid specified in eas\n\
  296       gid=xxx           set gid of files that don't have gid specified in eas\n\
  297       umask=xxx         set mode of files that don't have mode specified in eas\n\
  298       case=lower        lowercase all files\n\
  299       case=asis         do not lowercase files (default)\n\
  300       conv=binary       do not convert CR/LF -> LF (default)\n\
  301       conv=auto         convert only files with known text extensions\n\
  302       conv=text         convert all files\n\
  303       check=none        no fs checks - kernel may crash on corrupted filesystem\n\
  304       check=normal      do some checks - it should not crash (default)\n\
  305       check=strict      do extra time-consuming checks, used for debugging\n\
  306       errors=continue   continue on errors\n\
  307       errors=remount-ro remount read-only if errors found (default)\n\
  308       errors=panic      panic on errors\n\
  309       chkdsk=no         do not mark fs for chkdsking even if there were errors\n\
  310       chkdsk=errors     mark fs dirty if errors found (default)\n\
  311       chkdsk=always     always mark fs dirty - used for debugging\n\
  312       eas=no            ignore extended attributes\n\
  313       eas=ro            read but do not write extended attributes\n\
  314       eas=rw            r/w eas => enables chmod, chown, mknod, ln -s (default)\n\
  315       timeshift=nnn     add nnn seconds to file times\n\
  316 \n");
  317 }
  318 
  319 int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
  320 {
  321         uid_t uid;
  322         gid_t gid;
  323         umode_t umask;
  324         int lowercase, conv, eas, chk, errs, chkdsk, timeshift;
  325         int o;
  326         
  327         *flags |= MS_NOATIME;
  328         
  329         uid = s->s_hpfs_uid; gid = s->s_hpfs_gid;
  330         umask = 0777 & ~s->s_hpfs_mode;
  331         lowercase = s->s_hpfs_lowercase; conv = s->s_hpfs_conv;
  332         eas = s->s_hpfs_eas; chk = s->s_hpfs_chk; chkdsk = s->s_hpfs_chkdsk;
  333         errs = s->s_hpfs_err; timeshift = s->s_hpfs_timeshift;
  334 
  335         if (!(o = parse_opts(data, &uid, &gid, &umask, &lowercase, &conv,
  336             &eas, &chk, &errs, &chkdsk, &timeshift))) {
  337                 printk("HPFS: bad mount options.\n");
  338                 return 1;
  339         }
  340         if (o == 2) {
  341                 hpfs_help();
  342                 return 1;
  343         }
  344         if (timeshift != s->s_hpfs_timeshift) {
  345                 printk("HPFS: timeshift can't be changed using remount.\n");
  346                 return 1;
  347         }
  348 
  349         unmark_dirty(s);
  350 
  351         s->s_hpfs_uid = uid; s->s_hpfs_gid = gid;
  352         s->s_hpfs_mode = 0777 & ~umask;
  353         s->s_hpfs_lowercase = lowercase; s->s_hpfs_conv = conv;
  354         s->s_hpfs_eas = eas; s->s_hpfs_chk = chk; s->s_hpfs_chkdsk = chkdsk;
  355         s->s_hpfs_err = errs; s->s_hpfs_timeshift = timeshift;
  356 
  357         if (!(*flags & MS_RDONLY)) mark_dirty(s);
  358 
  359         return 0;
  360 }
  361 
  362 struct super_block *hpfs_read_super(struct super_block *s, void *options,
  363                                     int silent)
  364 {
  365         kdev_t dev;
  366         struct buffer_head *bh0, *bh1, *bh2;
  367         struct hpfs_boot_block *bootblock;
  368         struct hpfs_super_block *superblock;
  369         struct hpfs_spare_block *spareblock;
  370 
  371         uid_t uid;
  372         gid_t gid;
  373         umode_t umask;
  374         int lowercase, conv, eas, chk, errs, chkdsk, timeshift;
  375 
  376         dnode_secno root_dno;
  377         struct hpfs_dirent *de = NULL;
  378         struct quad_buffer_head qbh;
  379 
  380         int o;
  381 
  382         s->s_hpfs_bmp_dir = NULL;
  383         s->s_hpfs_cp_table = NULL;
  384 
  385         s->s_hpfs_creation_de_lock = s->s_hpfs_rd_inode = 0;
  386         init_waitqueue_head(&s->s_hpfs_creation_de);
  387         init_waitqueue_head(&s->s_hpfs_iget_q);
  388 
  389         uid = current->uid;
  390         gid = current->gid;
  391         umask = current->fs->umask;
  392         lowercase = 0;
  393         conv = CONV_BINARY;
  394         eas = 2;
  395         chk = 1;
  396         errs = 1;
  397         chkdsk = 1;
  398         timeshift = 0;
  399 
  400         if (!(o = parse_opts(options, &uid, &gid, &umask, &lowercase, &conv,
  401             &eas, &chk, &errs, &chkdsk, &timeshift))) {
  402                 printk("HPFS: bad mount options.\n");
  403                 goto bail0;
  404         }
  405         if (o==2) {
  406                 hpfs_help();
  407                 goto bail0;
  408         }
  409 
  410         /*s->s_hpfs_mounting = 1;*/
  411         dev = s->s_dev;
  412         set_blocksize(dev, 512);
  413         s->s_blocksize = 512;
  414         s->s_blocksize_bits = 9;
  415         s->s_hpfs_fs_size = -1;
  416         if (!(bootblock = hpfs_map_sector(s, 0, &bh0, 0))) goto bail1;
  417         if (!(superblock = hpfs_map_sector(s, 16, &bh1, 1))) goto bail2;
  418         if (!(spareblock = hpfs_map_sector(s, 17, &bh2, 0))) goto bail3;
  419 
  420         /* Check magics */
  421         if (/*bootblock->magic != BB_MAGIC
  422             ||*/ superblock->magic != SB_MAGIC
  423             || spareblock->magic != SP_MAGIC) {
  424                 if (!silent) printk("HPFS: Bad magic ... probably not HPFS\n");
  425                 goto bail4;
  426         }
  427 
  428         /* Check version */
  429         if (!(s->s_flags & MS_RDONLY) &&
  430               superblock->funcversion != 2 && superblock->funcversion != 3) {
  431                 printk("HPFS: Bad version %d,%d. Mount readonly to go around\n",
  432                         (int)superblock->version, (int)superblock->funcversion);
  433                 printk("HPFS: please try recent version of HPFS driver at http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi and if it still can't understand this format, contact author - mikulas@artax.karlin.mff.cuni.cz\n");
  434                 goto bail4;
  435         }
  436 
  437         s->s_flags |= MS_NOATIME;
  438 
  439         /* Fill superblock stuff */
  440         s->s_magic = HPFS_SUPER_MAGIC;
  441         s->s_op = &hpfs_sops;
  442 
  443         s->s_hpfs_root = superblock->root;
  444         s->s_hpfs_fs_size = superblock->n_sectors;
  445         s->s_hpfs_bitmaps = superblock->bitmaps;
  446         s->s_hpfs_dirband_start = superblock->dir_band_start;
  447         s->s_hpfs_dirband_size = superblock->n_dir_band;
  448         s->s_hpfs_dmap = superblock->dir_band_bitmap;
  449         s->s_hpfs_uid = uid;
  450         s->s_hpfs_gid = gid;
  451         s->s_hpfs_mode = 0777 & ~umask;
  452         s->s_hpfs_n_free = -1;
  453         s->s_hpfs_n_free_dnodes = -1;
  454         s->s_hpfs_lowercase = lowercase;
  455         s->s_hpfs_conv = conv;
  456         s->s_hpfs_eas = eas;
  457         s->s_hpfs_chk = chk;
  458         s->s_hpfs_chkdsk = chkdsk;
  459         s->s_hpfs_err = errs;
  460         s->s_hpfs_timeshift = timeshift;
  461         s->s_hpfs_was_error = 0;
  462         s->s_hpfs_cp_table = NULL;
  463         s->s_hpfs_c_bitmap = -1;
  464         
  465         /* Load bitmap directory */
  466         if (!(s->s_hpfs_bmp_dir = hpfs_load_bitmap_directory(s, superblock->bitmaps)))
  467                 goto bail4;
  468         
  469         /* Check for general fs errors*/
  470         if (spareblock->dirty && !spareblock->old_wrote) {
  471                 if (errs == 2) {
  472                         printk("HPFS: Improperly stopped, not mounted\n");
  473                         goto bail4;
  474                 }
  475                 hpfs_error(s, "improperly stopped");
  476         }
  477 
  478         if (!(s->s_flags & MS_RDONLY)) {
  479                 spareblock->dirty = 1;
  480                 spareblock->old_wrote = 0;
  481                 mark_buffer_dirty(bh2);
  482         }
  483 
  484         if (spareblock->hotfixes_used || spareblock->n_spares_used) {
  485                 if (errs >= 2) {
  486                         printk("HPFS: Hotfixes not supported here, try chkdsk\n");
  487                         mark_dirty(s);
  488                         goto bail4;
  489                 }
  490                 hpfs_error(s, "hotfixes not supported here, try chkdsk");
  491                 if (errs == 0) printk("HPFS: Proceeding, but your filesystem will be probably corrupted by this driver...\n");
  492                 else printk("HPFS: This driver may read bad files or crash when operating on disk with hotfixes.\n");
  493         }
  494         if (spareblock->n_dnode_spares != spareblock->n_dnode_spares_free) {
  495                 if (errs >= 2) {
  496                         printk("HPFS: Spare dnodes used, try chkdsk\n");
  497                         mark_dirty(s);
  498                         goto bail4;
  499                 }
  500                 hpfs_error(s, "warning: spare dnodes used, try chkdsk");
  501                 if (errs == 0) printk("HPFS: Proceeding, but your filesystem could be corrupted if you delete files or directories\n");
  502         }
  503         if (chk) {
  504                 unsigned a;
  505                 if (superblock->dir_band_end - superblock->dir_band_start + 1 != superblock->n_dir_band ||
  506                     superblock->dir_band_end < superblock->dir_band_start || superblock->n_dir_band > 0x4000) {
  507                         hpfs_error(s, "dir band size mismatch: dir_band_start==%08x, dir_band_end==%08x, n_dir_band==%08x",
  508                                 superblock->dir_band_start, superblock->dir_band_end, superblock->n_dir_band);
  509                         goto bail4;
  510                 }
  511                 a = s->s_hpfs_dirband_size;
  512                 s->s_hpfs_dirband_size = 0;
  513                 if (hpfs_chk_sectors(s, superblock->dir_band_start, superblock->n_dir_band, "dir_band") ||
  514                     hpfs_chk_sectors(s, superblock->dir_band_bitmap, 4, "dir_band_bitmap") ||
  515                     hpfs_chk_sectors(s, superblock->bitmaps, 4, "bitmaps")) {
  516                         mark_dirty(s);
  517                         goto bail4;
  518                 }
  519                 s->s_hpfs_dirband_size = a;
  520         } else printk("HPFS: You really don't want any checks? You are crazy...\n");
  521 
  522         /* Load code page table */
  523         if (spareblock->n_code_pages)
  524                 if (!(s->s_hpfs_cp_table = hpfs_load_code_page(s, spareblock->code_page_dir)))
  525                         printk("HPFS: Warning: code page support is disabled\n");
  526 
  527         brelse(bh2);
  528         brelse(bh1);
  529         brelse(bh0);
  530 
  531         hpfs_lock_iget(s, 1);
  532         s->s_root = d_alloc_root(iget(s, s->s_hpfs_root));
  533         hpfs_unlock_iget(s);
  534         if (!s->s_root || !s->s_root->d_inode) {
  535                 printk("HPFS: iget failed. Why???\n");
  536                 goto bail0;
  537         }
  538         hpfs_set_dentry_operations(s->s_root);
  539 
  540         /*
  541          * find the root directory's . pointer & finish filling in the inode
  542          */
  543 
  544         root_dno = hpfs_fnode_dno(s, s->s_hpfs_root);
  545         if (root_dno)
  546                 de = map_dirent(s->s_root->d_inode, root_dno, "\001\001", 2, NULL, &qbh);
  547         if (!root_dno || !de) hpfs_error(s, "unable to find root dir");
  548         else {
  549                 s->s_root->d_inode->i_atime = local_to_gmt(s, de->read_date);
  550                 s->s_root->d_inode->i_mtime = local_to_gmt(s, de->write_date);
  551                 s->s_root->d_inode->i_ctime = local_to_gmt(s, de->creation_date);
  552                 s->s_root->d_inode->i_hpfs_ea_size = de->ea_size;
  553                 s->s_root->d_inode->i_hpfs_parent_dir = s->s_root->d_inode->i_ino;
  554                 if (s->s_root->d_inode->i_size == -1) s->s_root->d_inode->i_size = 2048;
  555                 if (s->s_root->d_inode->i_blocks == -1) s->s_root->d_inode->i_blocks = 5;
  556         }
  557         if (de) hpfs_brelse4(&qbh);
  558 
  559         return s;
  560 
  561 bail4:  brelse(bh2);
  562 bail3:  brelse(bh1);
  563 bail2:  brelse(bh0);
  564 bail1:
  565 bail0:
  566         if (s->s_hpfs_bmp_dir) kfree(s->s_hpfs_bmp_dir);
  567         if (s->s_hpfs_cp_table) kfree(s->s_hpfs_cp_table);
  568         return NULL;
  569 }
  570 
  571 DECLARE_FSTYPE_DEV(hpfs_fs_type, "hpfs", hpfs_read_super);
  572 
  573 static int __init init_hpfs_fs(void)
  574 {
  575         return register_filesystem(&hpfs_fs_type);
  576 }
  577 
  578 static void __exit exit_hpfs_fs(void)
  579 {
  580         unregister_filesystem(&hpfs_fs_type);
  581 }
  582 
  583 EXPORT_NO_SYMBOLS;
  584 
  585 module_init(init_hpfs_fs)
  586 module_exit(exit_hpfs_fs)
  587 MODULE_LICENSE("GPL");

Cache object: ebe8c6fe596946ad8f02750315734dd5


[ 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.