root/fs/fat/inode.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fat_put_inode
  2. fat_put_super
  3. parse_options
  4. fat_read_super
  5. fat_statfs
  6. fat_bmap
  7. is_exec
  8. fat_read_inode
  9. fat_write_inode
  10. fat_notify_change
  11. init_module
  12. cleanup_module

   1 /*
   2  *  linux/fs/fat/inode.c
   3  *
   4  *  Written 1992,1993 by Werner Almesberger
   5  *  VFAT extensions by Gordon Chaffee, merged with msdos fs by Henrik Storner
   6  */
   7 
   8 #define __NO_VERSION__
   9 #include <linux/module.h>
  10 
  11 #include <linux/msdos_fs.h>
  12 #include <linux/kernel.h>
  13 #include <linux/sched.h>
  14 #include <linux/errno.h>
  15 #include <linux/string.h>
  16 #include <linux/major.h>
  17 #include <linux/blkdev.h>
  18 #include <linux/fs.h>
  19 #include <linux/stat.h>
  20 #include <linux/locks.h>
  21 
  22 #include "msbuffer.h"
  23 #include "tables.h"
  24 
  25 #include <asm/segment.h>
  26 
  27 
  28 
  29 void fat_put_inode(struct inode *inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  30 {
  31         struct inode *depend, *linked;
  32         struct super_block *sb;
  33 
  34         depend = MSDOS_I(inode)->i_depend;
  35         linked = MSDOS_I(inode)->i_linked;
  36         sb = inode->i_sb;
  37         if (inode->i_nlink) {
  38                 if (depend) {
  39                         iput(depend);
  40                 }
  41                 if (linked) {
  42                         iput(linked);
  43                         MSDOS_I(inode)->i_linked = NULL;
  44                 }
  45                 if (MSDOS_I(inode)->i_busy) fat_cache_inval_inode(inode);
  46                 return;
  47         }
  48         inode->i_size = 0;
  49         fat_truncate(inode);
  50         clear_inode(inode);
  51         if (depend) {
  52                 if (MSDOS_I(depend)->i_old != inode) {
  53                         printk("Invalid link (0x%p): expected 0x%p, got 0x%p\n",
  54                             depend, inode, MSDOS_I(depend)->i_old);
  55                         fat_fs_panic(sb,"...");
  56                         return;
  57                 }
  58                 MSDOS_I(depend)->i_old = NULL;
  59                 iput(depend);
  60         }
  61         if (linked) {
  62                 if (MSDOS_I(linked)->i_oldlink != inode) {
  63                         printk("Invalid link (0x%p): expected 0x%p, got 0x%p\n",
  64                             linked, inode, MSDOS_I(linked)->i_oldlink);
  65                         fat_fs_panic(sb,"...");
  66                         return;
  67                 }
  68                 MSDOS_I(linked)->i_oldlink = NULL;
  69                 iput(linked);
  70         }
  71 }
  72 
  73 
  74 void fat_put_super(struct super_block *sb)
     /* [previous][next][first][last][top][bottom][index][help] */
  75 {
  76         fat_cache_inval_dev(sb->s_dev);
  77         set_blocksize (sb->s_dev,BLOCK_SIZE);
  78         lock_super(sb);
  79         sb->s_dev = 0;
  80         unlock_super(sb);
  81         MOD_DEC_USE_COUNT;
  82         return;
  83 }
  84 
  85 
  86 static int parse_options(char *options,int *fat, int *blksize, int *debug,
     /* [previous][next][first][last][top][bottom][index][help] */
  87                          struct fat_mount_options *opts)
  88 {
  89         char *this_char,*value;
  90 
  91         opts->name_check = 'n';
  92         opts->conversion = 'b';
  93         opts->fs_uid = current->uid;
  94         opts->fs_gid = current->gid;
  95         opts->fs_umask = current->fs->umask;
  96         opts->quiet = opts->sys_immutable = opts->dotsOK = opts->showexec = opts->isvfat = 0;
  97         *debug = *fat = 0;
  98 
  99         if (!options) return 1;
 100         for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {
 101                 if ((value = strchr(this_char,'=')) != NULL)
 102                         *value++ = 0;
 103                 if (!strcmp(this_char,"check") && value) {
 104                         if (value[0] && !value[1] && strchr("rns",*value))
 105                                 opts->name_check = *value;
 106                         else if (!strcmp(value,"relaxed")) opts->name_check = 'r';
 107                         else if (!strcmp(value,"normal")) opts->name_check = 'n';
 108                         else if (!strcmp(value,"strict")) opts->name_check = 's';
 109                         else return 0;
 110                 }
 111                 else if (!strcmp(this_char,"conv") && value) {
 112                         if (value[0] && !value[1] && strchr("bta",*value))
 113                                 opts->conversion = *value;
 114                         else if (!strcmp(value,"binary")) opts->conversion = 'b';
 115                         else if (!strcmp(value,"text")) opts->conversion = 't';
 116                         else if (!strcmp(value,"auto")) opts->conversion = 'a';
 117                         else return 0;
 118                 }
 119                 else if (!strcmp(this_char,"dots")) {
 120                         opts->dotsOK = 1;
 121                 }
 122                 else if (!strcmp(this_char,"nodots")) {
 123                         opts->dotsOK = 0;
 124                 }
 125                 else if (!strcmp(this_char,"showexec")) {
 126                         opts->showexec = 1;
 127                 }
 128                 else if (!strcmp(this_char,"dotsOK") && value) {
 129                         if (!strcmp(value,"yes")) opts->dotsOK = 1;
 130                         else if (!strcmp(value,"no")) opts->dotsOK = 0;
 131                         else return 0;
 132                 }
 133                 else if (!strcmp(this_char,"uid")) {
 134                         if (!value || !*value)
 135                                 return 0;
 136                         opts->fs_uid = simple_strtoul(value,&value,0);
 137                         if (*value)
 138                                 return 0;
 139                 }
 140                 else if (!strcmp(this_char,"gid")) {
 141                         if (!value || !*value)
 142                                 return 0;
 143                         opts->fs_gid = simple_strtoul(value,&value,0);
 144                         if (*value)
 145                                 return 0;
 146                 }
 147                 else if (!strcmp(this_char,"umask")) {
 148                         if (!value || !*value)
 149                                 return 0;
 150                         opts->fs_umask = simple_strtoul(value,&value,8);
 151                         if (*value)
 152                                 return 0;
 153                 }
 154                 else if (!strcmp(this_char,"debug")) {
 155                         if (value) return 0;
 156                         *debug = 1;
 157                 }
 158                 else if (!strcmp(this_char,"fat")) {
 159                         if (!value || !*value)
 160                                 return 0;
 161                         *fat = simple_strtoul(value,&value,0);
 162                         if (*value || (*fat != 12 && *fat != 16))
 163                                 return 0;
 164                 }
 165                 else if (!strcmp(this_char,"quiet")) {
 166                         if (value) return 0;
 167                         opts->quiet = 1;
 168                 }
 169                 else if (!strcmp(this_char,"blocksize")) {
 170                         *blksize = simple_strtoul(value,&value,0);
 171                         if (*value)
 172                                 return 0;
 173                         if (*blksize != 512 && *blksize != 1024){
 174                                 printk ("MSDOS FS: Invalid blocksize (512 or 1024)\n");
 175                         }
 176                 }
 177                 else if (!strcmp(this_char,"sys_immutable")) {
 178                         if (value)
 179                                 return 0;
 180                         opts->sys_immutable = 1;
 181                 }
 182         }
 183         return 1;
 184 }
 185 
 186 
 187 /* Read the super block of an MS-DOS FS. */
 188 
 189 struct super_block *fat_read_super(struct super_block *sb,void *data, int silent)
     /* [previous][next][first][last][top][bottom][index][help] */
 190 {
 191         struct buffer_head *bh;
 192         struct msdos_boot_sector *b;
 193         int data_sectors,logical_sector_size,sector_mult,fat_clusters=0;
 194         int debug,error,fat;
 195         int blksize = 512;
 196         struct fat_mount_options opts;
 197 
 198         MOD_INC_USE_COUNT;
 199         if (hardsect_size[MAJOR(sb->s_dev)] != NULL){
 200                 blksize = hardsect_size[MAJOR(sb->s_dev)][MINOR(sb->s_dev)];
 201                 if (blksize != 512){
 202                         printk ("MSDOS: Hardware sector size is %d\n",blksize);
 203                 }
 204         }
 205         if (!parse_options((char *) data, &fat, &blksize, &debug, &opts)
 206                 || (blksize != 512 && blksize != 1024)) {
 207                 sb->s_dev = 0;
 208                 MOD_DEC_USE_COUNT;
 209                 return NULL;
 210         }
 211         cache_init();
 212         lock_super(sb);
 213         /* The first read is always 1024 bytes */
 214         sb->s_blocksize = 1024;
 215         set_blocksize(sb->s_dev, 1024);
 216         bh = bread(sb->s_dev, 0, 1024);
 217         unlock_super(sb);
 218         if (bh == NULL || !fat_is_uptodate(sb,bh)) {
 219                 brelse (bh);
 220                 sb->s_dev = 0;
 221                 printk("FAT bread failed\n");
 222                 MOD_DEC_USE_COUNT;
 223                 return NULL;
 224         }
 225         b = (struct msdos_boot_sector *) bh->b_data;
 226         set_blocksize(sb->s_dev, blksize);
 227 /*
 228  * The DOS3 partition size limit is *not* 32M as many people think.  
 229  * Instead, it is 64K sectors (with the usual sector size being
 230  * 512 bytes, leading to a 32M limit).
 231  * 
 232  * DOS 3 partition managers got around this problem by faking a 
 233  * larger sector size, ie treating multiple physical sectors as 
 234  * a single logical sector.
 235  * 
 236  * We can accommodate this scheme by adjusting our cluster size,
 237  * fat_start, and data_start by an appropriate value.
 238  *
 239  * (by Drew Eckhardt)
 240  */
 241 
 242 #define ROUND_TO_MULTIPLE(n,m) ((n) && (m) ? (n)+(m)-1-((n)-1)%(m) : 0)
 243     /* don't divide by zero */
 244 
 245         logical_sector_size = CF_LE_W(*(unsigned short *) &b->sector_size);
 246         sector_mult = logical_sector_size >> SECTOR_BITS;
 247         MSDOS_SB(sb)->cluster_size = b->cluster_size*sector_mult;
 248         MSDOS_SB(sb)->fats = b->fats;
 249         MSDOS_SB(sb)->fat_start = CF_LE_W(b->reserved)*sector_mult;
 250         MSDOS_SB(sb)->fat_length = CF_LE_W(b->fat_length)*sector_mult;
 251         MSDOS_SB(sb)->dir_start = (CF_LE_W(b->reserved)+b->fats*CF_LE_W(
 252             b->fat_length))*sector_mult;
 253         MSDOS_SB(sb)->dir_entries = CF_LE_W(*((unsigned short *) &b->dir_entries
 254             ));
 255         MSDOS_SB(sb)->data_start = MSDOS_SB(sb)->dir_start+ROUND_TO_MULTIPLE((
 256             MSDOS_SB(sb)->dir_entries << MSDOS_DIR_BITS) >> SECTOR_BITS,
 257             sector_mult);
 258         data_sectors = (CF_LE_W(*((unsigned short *) &b->sectors)) ?
 259             CF_LE_W(*((unsigned short *) &b->sectors)) :
 260             CF_LE_L(b->total_sect))*sector_mult-MSDOS_SB(sb)->data_start;
 261         error = !b->cluster_size || !sector_mult;
 262         if (!error) {
 263                 MSDOS_SB(sb)->clusters = b->cluster_size ? data_sectors/
 264                     b->cluster_size/sector_mult : 0;
 265                 MSDOS_SB(sb)->fat_bits = fat ? fat : MSDOS_SB(sb)->clusters >
 266                     MSDOS_FAT12 ? 16 : 12;
 267                 fat_clusters = MSDOS_SB(sb)->fat_length*SECTOR_SIZE*8/
 268                     MSDOS_SB(sb)->fat_bits;
 269                 error = !MSDOS_SB(sb)->fats || (MSDOS_SB(sb)->dir_entries &
 270                     (MSDOS_DPS-1)) || MSDOS_SB(sb)->clusters+2 > fat_clusters+
 271                     MSDOS_MAX_EXTRA || (logical_sector_size & (SECTOR_SIZE-1))
 272                     || !b->secs_track || !b->heads;
 273         }
 274         brelse(bh);
 275         /*
 276                 This must be done after the brelse because the bh is a dummy
 277                 allocated by fat_bread (see buffer.c)
 278         */
 279         sb->s_blocksize = blksize;      /* Using this small block size solve the */
 280                                 /* the misfit with buffer cache and cluster */
 281                                 /* because cluster (DOS) are often aligned */
 282                                 /* on odd sector */
 283         sb->s_blocksize_bits = blksize == 512 ? 9 : 10;
 284         if (error || debug) {
 285                 /* The MSDOS_CAN_BMAP is obsolete, but left just to remember */
 286                 printk("[MS-DOS FS Rel. 12,FAT %d,check=%c,conv=%c,"
 287                        "uid=%d,gid=%d,umask=%03o%s]\n",
 288                        MSDOS_SB(sb)->fat_bits,opts.name_check,
 289                        opts.conversion,opts.fs_uid,opts.fs_gid,opts.fs_umask,
 290                        MSDOS_CAN_BMAP(MSDOS_SB(sb)) ? ",bmap" : "");
 291                 printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%d,ds=%d,de=%d,data=%d,"
 292                        "se=%d,ts=%ld,ls=%d]\n",b->media,MSDOS_SB(sb)->cluster_size,
 293                        MSDOS_SB(sb)->fats,MSDOS_SB(sb)->fat_start,MSDOS_SB(sb)->fat_length,
 294                        MSDOS_SB(sb)->dir_start,MSDOS_SB(sb)->dir_entries,
 295                        MSDOS_SB(sb)->data_start,
 296                        CF_LE_W(*(unsigned short *) &b->sectors),
 297                        (unsigned long)b->total_sect,logical_sector_size);
 298                 printk ("Transaction block size = %d\n",blksize);
 299         }
 300         if (MSDOS_SB(sb)->clusters+2 > fat_clusters)
 301                 MSDOS_SB(sb)->clusters = fat_clusters-2;
 302         if (error) {
 303                 if (!silent)
 304                         printk("VFS: Can't find a valid MSDOS filesystem on dev "
 305                                "%s.\n", kdevname(sb->s_dev));
 306                 sb->s_dev = 0;
 307                 MOD_DEC_USE_COUNT;
 308                 return NULL;
 309         }
 310         sb->s_magic = MSDOS_SUPER_MAGIC;
 311         /* set up enough so that it can read an inode */
 312         MSDOS_SB(sb)->free_clusters = -1; /* don't know yet */
 313         MSDOS_SB(sb)->fat_wait = NULL;
 314         MSDOS_SB(sb)->fat_lock = 0;
 315         MSDOS_SB(sb)->prev_free = 0;
 316         memcpy(&(MSDOS_SB(sb)->options), &opts, sizeof(struct fat_mount_options));
 317         if (!(sb->s_mounted = iget(sb,MSDOS_ROOT_INO))) {
 318                 sb->s_dev = 0;
 319                 printk("get root inode failed\n");
 320                 MOD_DEC_USE_COUNT;
 321                 return NULL;
 322         }
 323         return sb;
 324 }
 325 
 326 
 327 void fat_statfs(struct super_block *sb,struct statfs *buf, int bufsiz)
     /* [previous][next][first][last][top][bottom][index][help] */
 328 {
 329         int free,nr;
 330         struct statfs tmp;
 331 
 332         lock_fat(sb);
 333         if (MSDOS_SB(sb)->free_clusters != -1)
 334                 free = MSDOS_SB(sb)->free_clusters;
 335         else {
 336                 free = 0;
 337                 for (nr = 2; nr < MSDOS_SB(sb)->clusters+2; nr++)
 338                         if (!fat_access(sb,nr,-1)) free++;
 339                 MSDOS_SB(sb)->free_clusters = free;
 340         }
 341         unlock_fat(sb);
 342         tmp.f_type = sb->s_magic;
 343         tmp.f_bsize = MSDOS_SB(sb)->cluster_size*SECTOR_SIZE;
 344         tmp.f_blocks = MSDOS_SB(sb)->clusters;
 345         tmp.f_bfree = free;
 346         tmp.f_bavail = free;
 347         tmp.f_files = 0;
 348         tmp.f_ffree = 0;
 349         tmp.f_namelen = 12;
 350         memcpy_tofs(buf, &tmp, bufsiz);
 351 }
 352 
 353 
 354 int fat_bmap(struct inode *inode,int block)
     /* [previous][next][first][last][top][bottom][index][help] */
 355 {
 356         struct msdos_sb_info *sb;
 357         int cluster,offset;
 358 
 359         sb = MSDOS_SB(inode->i_sb);
 360         if (inode->i_ino == MSDOS_ROOT_INO) {
 361                 return sb->dir_start + block;
 362         }
 363         cluster = block/sb->cluster_size;
 364         offset = block % sb->cluster_size;
 365         if (!(cluster = get_cluster(inode,cluster))) return 0;
 366         return (cluster-2)*sb->cluster_size+sb->data_start+offset;
 367 }
 368 
 369 static int is_exec(char *extension)
     /* [previous][next][first][last][top][bottom][index][help] */
 370 {
 371         char *exe_extensions = "EXECOMBAT", *walk;
 372 
 373         for (walk = exe_extensions; *walk; walk += 3)
 374                 if (!strncmp(extension, walk, 3))
 375                         return 1;
 376         return 0;
 377 }
 378 
 379 void fat_read_inode(struct inode *inode, struct inode_operations *fs_dir_inode_ops)
     /* [previous][next][first][last][top][bottom][index][help] */
 380 {
 381         struct super_block *sb = inode->i_sb;
 382         struct buffer_head *bh;
 383         struct msdos_dir_entry *raw_entry;
 384         int nr;
 385 
 386 /* printk("read inode %d\n",inode->i_ino); */
 387         MSDOS_I(inode)->i_busy = 0;
 388         MSDOS_I(inode)->i_depend = MSDOS_I(inode)->i_old = NULL;
 389         MSDOS_I(inode)->i_linked = MSDOS_I(inode)->i_oldlink = NULL;
 390         MSDOS_I(inode)->i_binary = 1;
 391         inode->i_uid = MSDOS_SB(inode->i_sb)->options.fs_uid;
 392         inode->i_gid = MSDOS_SB(inode->i_sb)->options.fs_gid;
 393         inode->i_version = ++event;
 394         if (inode->i_ino == MSDOS_ROOT_INO) {
 395                 inode->i_mode = (S_IRWXUGO & ~MSDOS_SB(inode->i_sb)->options.fs_umask) |
 396                     S_IFDIR;
 397                 inode->i_op = fs_dir_inode_ops;
 398                 inode->i_nlink = fat_subdirs(inode)+2;
 399                     /* subdirs (neither . nor ..) plus . and "self" */
 400                 inode->i_size = MSDOS_SB(inode->i_sb)->dir_entries*
 401                     sizeof(struct msdos_dir_entry);
 402                 inode->i_blksize = MSDOS_SB(inode->i_sb)->cluster_size*
 403                     SECTOR_SIZE;
 404                 inode->i_blocks = (inode->i_size+inode->i_blksize-1)/
 405                     inode->i_blksize*MSDOS_SB(inode->i_sb)->cluster_size;
 406                 MSDOS_I(inode)->i_start = 0;
 407                 MSDOS_I(inode)->i_attrs = 0;
 408                 inode->i_mtime = inode->i_atime = inode->i_ctime = 0;
 409                 return;
 410         }
 411         if (!(bh = bread(inode->i_dev,inode->i_ino >> MSDOS_DPB_BITS,
 412             SECTOR_SIZE))) {
 413                 printk("dev = %s, ino = %ld\n",
 414                        kdevname(inode->i_dev), inode->i_ino);
 415                 panic("fat_read_inode: unable to read i-node block");
 416         }
 417         raw_entry = &((struct msdos_dir_entry *) (bh->b_data))
 418             [inode->i_ino & (MSDOS_DPB-1)];
 419         if ((raw_entry->attr & ATTR_DIR) && !IS_FREE(raw_entry->name)) {
 420                 inode->i_mode = MSDOS_MKMODE(raw_entry->attr,S_IRWXUGO &
 421                     ~MSDOS_SB(inode->i_sb)->options.fs_umask) | S_IFDIR;
 422                 inode->i_op = fs_dir_inode_ops;
 423 
 424                 MSDOS_I(inode)->i_start = CF_LE_W(raw_entry->start);
 425                 inode->i_nlink = fat_subdirs(inode);
 426                     /* includes .., compensating for "self" */
 427 #ifdef DEBUG
 428                 if (!inode->i_nlink) {
 429                         printk("directory %d: i_nlink == 0\n",inode->i_ino);
 430                         inode->i_nlink = 1;
 431                 }
 432 #endif
 433                 inode->i_size = 0;
 434                 if ((nr = CF_LE_W(raw_entry->start)) != 0)
 435                         while (nr != -1) {
 436                                 inode->i_size += SECTOR_SIZE*MSDOS_SB(inode->
 437                                     i_sb)->cluster_size;
 438                                 if (!(nr = fat_access(inode->i_sb,nr,-1))) {
 439                                         printk("Directory %ld: bad FAT\n",
 440                                             inode->i_ino);
 441                                         break;
 442                                 }
 443                         }
 444         } else { /* not a directory */
 445                 inode->i_mode = MSDOS_MKMODE(raw_entry->attr,
 446                     ((IS_NOEXEC(inode) || 
 447                       (MSDOS_SB(inode->i_sb)->options.showexec &&
 448                        !is_exec(raw_entry->ext)))
 449                         ? S_IRUGO|S_IWUGO : S_IRWXUGO)
 450                     & ~MSDOS_SB(inode->i_sb)->options.fs_umask) | S_IFREG;
 451                 inode->i_op = (sb->s_blocksize == 1024)
 452                         ? &fat_file_inode_operations_1024
 453                         : &fat_file_inode_operations;
 454                 MSDOS_I(inode)->i_start = CF_LE_W(raw_entry->start);
 455                 inode->i_nlink = 1;
 456                 inode->i_size = CF_LE_L(raw_entry->size);
 457         }
 458         if(raw_entry->attr & ATTR_SYS)
 459                 if (MSDOS_SB(inode->i_sb)->options.sys_immutable)
 460                         inode->i_flags |= S_IMMUTABLE;
 461         MSDOS_I(inode)->i_binary = is_binary(MSDOS_SB(inode->i_sb)->options.conversion,
 462             raw_entry->ext);
 463         MSDOS_I(inode)->i_attrs = raw_entry->attr & ATTR_UNUSED;
 464         /* this is as close to the truth as we can get ... */
 465         inode->i_blksize = MSDOS_SB(inode->i_sb)->cluster_size*SECTOR_SIZE;
 466         inode->i_blocks = (inode->i_size+inode->i_blksize-1)/
 467             inode->i_blksize*MSDOS_SB(inode->i_sb)->cluster_size;
 468         inode->i_mtime = inode->i_atime =
 469             date_dos2unix(CF_LE_W(raw_entry->time),CF_LE_W(raw_entry->date));
 470         inode->i_ctime =
 471                 MSDOS_SB(inode->i_sb)->options.isvfat
 472                 ? date_dos2unix(CF_LE_W(raw_entry->ctime),CF_LE_W(raw_entry->cdate))
 473                 : inode->i_mtime;
 474         brelse(bh);
 475 }
 476 
 477 
 478 void fat_write_inode(struct inode *inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 479 {
 480         struct super_block *sb = inode->i_sb;
 481         struct buffer_head *bh;
 482         struct msdos_dir_entry *raw_entry;
 483         struct inode *linked;
 484 
 485         linked = MSDOS_I(inode)->i_linked;
 486         if (linked) {
 487                 if (MSDOS_I(linked)->i_oldlink != inode) {
 488                         printk("Invalid link (0x%p): expected 0x%p, got 0x%p\n",
 489                                linked, inode, MSDOS_I(linked)->i_oldlink);
 490                         fat_fs_panic(sb,"...");
 491                         return;
 492                 }
 493                 linked->i_version = ++event;
 494                 linked->i_mode = inode->i_mode;
 495                 linked->i_uid = inode->i_uid;
 496                 linked->i_gid = inode->i_gid;
 497                 linked->i_size = inode->i_size;
 498                 linked->i_atime = inode->i_atime;
 499                 linked->i_mtime = inode->i_mtime;
 500                 linked->i_ctime = inode->i_ctime;
 501                 linked->i_blocks = inode->i_blocks;
 502                 linked->i_atime = inode->i_atime;
 503                 MSDOS_I(linked)->i_attrs = MSDOS_I(inode)->i_attrs;
 504                 linked->i_dirt = 1;
 505         }
 506 
 507         inode->i_dirt = 0;
 508         if (inode->i_ino == MSDOS_ROOT_INO || !inode->i_nlink) return;
 509         if (!(bh = bread(inode->i_dev,inode->i_ino >> MSDOS_DPB_BITS,
 510             SECTOR_SIZE))) {
 511                 printk("dev = %s, ino = %ld\n",
 512                        kdevname(inode->i_dev), inode->i_ino);
 513                 panic("msdos_write_inode: unable to read i-node block");
 514         }
 515         raw_entry = &((struct msdos_dir_entry *) (bh->b_data))
 516             [inode->i_ino & (MSDOS_DPB-1)];
 517         if (S_ISDIR(inode->i_mode)) {
 518                 raw_entry->attr = ATTR_DIR;
 519                 raw_entry->size = 0;
 520         }
 521         else {
 522                 raw_entry->attr = ATTR_NONE;
 523                 raw_entry->size = CT_LE_L(inode->i_size);
 524         }
 525         raw_entry->attr |= MSDOS_MKATTR(inode->i_mode) |
 526             MSDOS_I(inode)->i_attrs;
 527         raw_entry->start = CT_LE_W(MSDOS_I(inode)->i_start);
 528         fat_date_unix2dos(inode->i_mtime,&raw_entry->time,&raw_entry->date);
 529         raw_entry->time = CT_LE_W(raw_entry->time);
 530         raw_entry->date = CT_LE_W(raw_entry->date);
 531         if (MSDOS_SB(sb)->options.isvfat) {
 532                 fat_date_unix2dos(inode->i_ctime,&raw_entry->ctime,&raw_entry->cdate);
 533                 raw_entry->ctime = CT_LE_W(raw_entry->ctime);
 534                 raw_entry->cdate = CT_LE_W(raw_entry->cdate);
 535         }
 536         mark_buffer_dirty(bh, 1);
 537         brelse(bh);
 538 }
 539 
 540 
 541 int fat_notify_change(struct inode * inode,struct iattr * attr)
     /* [previous][next][first][last][top][bottom][index][help] */
 542 {
 543         int error;
 544 
 545         error = inode_change_ok(inode, attr);
 546         if (error)
 547                 return MSDOS_SB(inode->i_sb)->options.quiet ? 0 : error;
 548 
 549         if (((attr->ia_valid & ATTR_UID) && 
 550              (attr->ia_uid != MSDOS_SB(inode->i_sb)->options.fs_uid)) ||
 551             ((attr->ia_valid & ATTR_GID) && 
 552              (attr->ia_gid != MSDOS_SB(inode->i_sb)->options.fs_gid)) ||
 553             ((attr->ia_valid & ATTR_MODE) &&
 554              (attr->ia_mode & ~MSDOS_VALID_MODE)))
 555                 error = -EPERM;
 556 
 557         if (error)
 558                 return MSDOS_SB(inode->i_sb)->options.quiet ? 0 : error;
 559 
 560         inode_setattr(inode, attr);
 561 
 562         if (IS_NOEXEC(inode) && !S_ISDIR(inode->i_mode))
 563                 inode->i_mode &= S_IFMT | S_IRUGO | S_IWUGO;
 564         else
 565                 inode->i_mode |= S_IXUGO;
 566 
 567         inode->i_mode = ((inode->i_mode & S_IFMT) | ((((inode->i_mode & S_IRWXU
 568             & ~MSDOS_SB(inode->i_sb)->options.fs_umask) | S_IRUSR) >> 6)*S_IXUGO)) &
 569             ~MSDOS_SB(inode->i_sb)->options.fs_umask;
 570         return 0;
 571 }
 572 
 573 
 574 #ifdef MODULE
 575 int init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 576 {
 577         return init_fat_fs();
 578 }
 579 
 580 
 581 void cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 582 {
 583         /* Nothing to be done, really! */
 584         return;
 585 }
 586 #endif
 587 

/* [previous][next][first][last][top][bottom][index][help] */