LCOV - code coverage report
Current view: top level - fs/fat - file.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 178 0.0 %
Date: 2014-02-18 Functions: 0 13 0.0 %
Branches: 0 136 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  *  linux/fs/fat/file.c
       3                 :            :  *
       4                 :            :  *  Written 1992,1993 by Werner Almesberger
       5                 :            :  *
       6                 :            :  *  regular file handling primitives for fat-based filesystems
       7                 :            :  */
       8                 :            : 
       9                 :            : #include <linux/capability.h>
      10                 :            : #include <linux/module.h>
      11                 :            : #include <linux/compat.h>
      12                 :            : #include <linux/mount.h>
      13                 :            : #include <linux/time.h>
      14                 :            : #include <linux/buffer_head.h>
      15                 :            : #include <linux/writeback.h>
      16                 :            : #include <linux/backing-dev.h>
      17                 :            : #include <linux/blkdev.h>
      18                 :            : #include <linux/fsnotify.h>
      19                 :            : #include <linux/security.h>
      20                 :            : #include "fat.h"
      21                 :            : 
      22                 :          0 : static int fat_ioctl_get_attributes(struct inode *inode, u32 __user *user_attr)
      23                 :            : {
      24                 :            :         u32 attr;
      25                 :            : 
      26                 :          0 :         mutex_lock(&inode->i_mutex);
      27                 :          0 :         attr = fat_make_attrs(inode);
      28                 :          0 :         mutex_unlock(&inode->i_mutex);
      29                 :            : 
      30                 :          0 :         return put_user(attr, user_attr);
      31                 :            : }
      32                 :            : 
      33                 :          0 : static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr)
      34                 :            : {
      35                 :            :         struct inode *inode = file_inode(file);
      36                 :          0 :         struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
      37                 :          0 :         int is_dir = S_ISDIR(inode->i_mode);
      38                 :            :         u32 attr, oldattr;
      39                 :            :         struct iattr ia;
      40                 :            :         int err;
      41                 :            : 
      42                 :          0 :         err = get_user(attr, user_attr);
      43         [ #  # ]:          0 :         if (err)
      44                 :            :                 goto out;
      45                 :            : 
      46                 :          0 :         err = mnt_want_write_file(file);
      47         [ #  # ]:          0 :         if (err)
      48                 :            :                 goto out;
      49                 :          0 :         mutex_lock(&inode->i_mutex);
      50                 :            : 
      51                 :            :         /*
      52                 :            :          * ATTR_VOLUME and ATTR_DIR cannot be changed; this also
      53                 :            :          * prevents the user from turning us into a VFAT
      54                 :            :          * longname entry.  Also, we obviously can't set
      55                 :            :          * any of the NTFS attributes in the high 24 bits.
      56                 :            :          */
      57                 :          0 :         attr &= 0xff & ~(ATTR_VOLUME | ATTR_DIR);
      58                 :            :         /* Merge in ATTR_VOLUME and ATTR_DIR */
      59                 :          0 :         attr |= (MSDOS_I(inode)->i_attrs & ATTR_VOLUME) |
      60         [ #  # ]:          0 :                 (is_dir ? ATTR_DIR : 0);
      61                 :          0 :         oldattr = fat_make_attrs(inode);
      62                 :            : 
      63                 :            :         /* Equivalent to a chmod() */
      64                 :          0 :         ia.ia_valid = ATTR_MODE | ATTR_CTIME;
      65                 :          0 :         ia.ia_ctime = current_fs_time(inode->i_sb);
      66         [ #  # ]:          0 :         if (is_dir)
      67                 :          0 :                 ia.ia_mode = fat_make_mode(sbi, attr, S_IRWXUGO);
      68                 :            :         else {
      69                 :          0 :                 ia.ia_mode = fat_make_mode(sbi, attr,
      70                 :          0 :                         S_IRUGO | S_IWUGO | (inode->i_mode & S_IXUGO));
      71                 :            :         }
      72                 :            : 
      73                 :            :         /* The root directory has no attributes */
      74 [ #  # ][ #  # ]:          0 :         if (inode->i_ino == MSDOS_ROOT_INO && attr != ATTR_DIR) {
      75                 :            :                 err = -EINVAL;
      76                 :            :                 goto out_unlock_inode;
      77                 :            :         }
      78                 :            : 
      79 [ #  # ][ #  # ]:          0 :         if (sbi->options.sys_immutable &&
      80         [ #  # ]:          0 :             ((attr | oldattr) & ATTR_SYS) &&
      81                 :          0 :             !capable(CAP_LINUX_IMMUTABLE)) {
      82                 :            :                 err = -EPERM;
      83                 :            :                 goto out_unlock_inode;
      84                 :            :         }
      85                 :            : 
      86                 :            :         /*
      87                 :            :          * The security check is questionable...  We single
      88                 :            :          * out the RO attribute for checking by the security
      89                 :            :          * module, just because it maps to a file mode.
      90                 :            :          */
      91                 :          0 :         err = security_inode_setattr(file->f_path.dentry, &ia);
      92         [ #  # ]:          0 :         if (err)
      93                 :            :                 goto out_unlock_inode;
      94                 :            : 
      95                 :            :         /* This MUST be done before doing anything irreversible... */
      96                 :          0 :         err = fat_setattr(file->f_path.dentry, &ia);
      97         [ #  # ]:          0 :         if (err)
      98                 :            :                 goto out_unlock_inode;
      99                 :            : 
     100                 :          0 :         fsnotify_change(file->f_path.dentry, ia.ia_valid);
     101         [ #  # ]:          0 :         if (sbi->options.sys_immutable) {
     102         [ #  # ]:          0 :                 if (attr & ATTR_SYS)
     103                 :          0 :                         inode->i_flags |= S_IMMUTABLE;
     104                 :            :                 else
     105                 :          0 :                         inode->i_flags &= ~S_IMMUTABLE;
     106                 :            :         }
     107                 :            : 
     108                 :          0 :         fat_save_attrs(inode, attr);
     109                 :            :         mark_inode_dirty(inode);
     110                 :            : out_unlock_inode:
     111                 :          0 :         mutex_unlock(&inode->i_mutex);
     112                 :          0 :         mnt_drop_write_file(file);
     113                 :            : out:
     114                 :          0 :         return err;
     115                 :            : }
     116                 :            : 
     117                 :          0 : static int fat_ioctl_get_volume_id(struct inode *inode, u32 __user *user_attr)
     118                 :            : {
     119                 :          0 :         struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
     120                 :          0 :         return put_user(sbi->vol_id, user_attr);
     121                 :            : }
     122                 :            : 
     123                 :          0 : long fat_generic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
     124                 :            : {
     125                 :          0 :         struct inode *inode = file_inode(filp);
     126                 :          0 :         u32 __user *user_attr = (u32 __user *)arg;
     127                 :            : 
     128   [ #  #  #  # ]:          0 :         switch (cmd) {
     129                 :            :         case FAT_IOCTL_GET_ATTRIBUTES:
     130                 :          0 :                 return fat_ioctl_get_attributes(inode, user_attr);
     131                 :            :         case FAT_IOCTL_SET_ATTRIBUTES:
     132                 :          0 :                 return fat_ioctl_set_attributes(filp, user_attr);
     133                 :            :         case FAT_IOCTL_GET_VOLUME_ID:
     134                 :          0 :                 return fat_ioctl_get_volume_id(inode, user_attr);
     135                 :            :         default:
     136                 :            :                 return -ENOTTY; /* Inappropriate ioctl for device */
     137                 :            :         }
     138                 :            : }
     139                 :            : 
     140                 :            : #ifdef CONFIG_COMPAT
     141                 :            : static long fat_generic_compat_ioctl(struct file *filp, unsigned int cmd,
     142                 :            :                                       unsigned long arg)
     143                 :            : 
     144                 :            : {
     145                 :            :         return fat_generic_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
     146                 :            : }
     147                 :            : #endif
     148                 :            : 
     149                 :          0 : static int fat_file_release(struct inode *inode, struct file *filp)
     150                 :            : {
     151 [ #  # ][ #  # ]:          0 :         if ((filp->f_mode & FMODE_WRITE) &&
     152                 :          0 :              MSDOS_SB(inode->i_sb)->options.flush) {
     153                 :          0 :                 fat_flush_inodes(inode->i_sb, inode, NULL);
     154                 :          0 :                 congestion_wait(BLK_RW_ASYNC, HZ/10);
     155                 :            :         }
     156                 :          0 :         return 0;
     157                 :            : }
     158                 :            : 
     159                 :          0 : int fat_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
     160                 :            : {
     161                 :          0 :         struct inode *inode = filp->f_mapping->host;
     162                 :            :         int res, err;
     163                 :            : 
     164                 :          0 :         res = generic_file_fsync(filp, start, end, datasync);
     165                 :          0 :         err = sync_mapping_buffers(MSDOS_SB(inode->i_sb)->fat_inode->i_mapping);
     166                 :            : 
     167         [ #  # ]:          0 :         return res ? res : err;
     168                 :            : }
     169                 :            : 
     170                 :            : 
     171                 :            : const struct file_operations fat_file_operations = {
     172                 :            :         .llseek         = generic_file_llseek,
     173                 :            :         .read           = do_sync_read,
     174                 :            :         .write          = do_sync_write,
     175                 :            :         .aio_read       = generic_file_aio_read,
     176                 :            :         .aio_write      = generic_file_aio_write,
     177                 :            :         .mmap           = generic_file_mmap,
     178                 :            :         .release        = fat_file_release,
     179                 :            :         .unlocked_ioctl = fat_generic_ioctl,
     180                 :            : #ifdef CONFIG_COMPAT
     181                 :            :         .compat_ioctl   = fat_generic_compat_ioctl,
     182                 :            : #endif
     183                 :            :         .fsync          = fat_file_fsync,
     184                 :            :         .splice_read    = generic_file_splice_read,
     185                 :            : };
     186                 :            : 
     187                 :          0 : static int fat_cont_expand(struct inode *inode, loff_t size)
     188                 :            : {
     189                 :          0 :         struct address_space *mapping = inode->i_mapping;
     190                 :          0 :         loff_t start = inode->i_size, count = size - inode->i_size;
     191                 :            :         int err;
     192                 :            : 
     193                 :          0 :         err = generic_cont_expand_simple(inode, size);
     194         [ #  # ]:          0 :         if (err)
     195                 :            :                 goto out;
     196                 :            : 
     197                 :          0 :         inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
     198                 :            :         mark_inode_dirty(inode);
     199 [ #  # ][ #  # ]:          0 :         if (IS_SYNC(inode)) {
     200                 :            :                 int err2;
     201                 :            : 
     202                 :            :                 /*
     203                 :            :                  * Opencode syncing since we don't have a file open to use
     204                 :            :                  * standard fsync path.
     205                 :            :                  */
     206                 :          0 :                 err = filemap_fdatawrite_range(mapping, start,
     207                 :          0 :                                                start + count - 1);
     208                 :          0 :                 err2 = sync_mapping_buffers(mapping);
     209         [ #  # ]:          0 :                 if (!err)
     210                 :            :                         err = err2;
     211                 :          0 :                 err2 = write_inode_now(inode, 1);
     212         [ #  # ]:          0 :                 if (!err)
     213                 :            :                         err = err2;
     214         [ #  # ]:          0 :                 if (!err) {
     215                 :          0 :                         err =  filemap_fdatawait_range(mapping, start,
     216                 :            :                                                        start + count - 1);
     217                 :            :                 }
     218                 :            :         }
     219                 :            : out:
     220                 :          0 :         return err;
     221                 :            : }
     222                 :            : 
     223                 :            : /* Free all clusters after the skip'th cluster. */
     224                 :          0 : static int fat_free(struct inode *inode, int skip)
     225                 :            : {
     226                 :          0 :         struct super_block *sb = inode->i_sb;
     227                 :            :         int err, wait, free_start, i_start, i_logstart;
     228                 :            : 
     229         [ #  # ]:          0 :         if (MSDOS_I(inode)->i_start == 0)
     230                 :            :                 return 0;
     231                 :            : 
     232                 :          0 :         fat_cache_inval_inode(inode);
     233                 :            : 
     234 [ #  # ][ #  # ]:          0 :         wait = IS_DIRSYNC(inode);
     235                 :          0 :         i_start = free_start = MSDOS_I(inode)->i_start;
     236                 :          0 :         i_logstart = MSDOS_I(inode)->i_logstart;
     237                 :            : 
     238                 :            :         /* First, we write the new file size. */
     239         [ #  # ]:          0 :         if (!skip) {
     240                 :          0 :                 MSDOS_I(inode)->i_start = 0;
     241                 :          0 :                 MSDOS_I(inode)->i_logstart = 0;
     242                 :            :         }
     243                 :          0 :         MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
     244                 :          0 :         inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
     245         [ #  # ]:          0 :         if (wait) {
     246                 :          0 :                 err = fat_sync_inode(inode);
     247         [ #  # ]:          0 :                 if (err) {
     248                 :          0 :                         MSDOS_I(inode)->i_start = i_start;
     249                 :          0 :                         MSDOS_I(inode)->i_logstart = i_logstart;
     250                 :          0 :                         return err;
     251                 :            :                 }
     252                 :            :         } else
     253                 :            :                 mark_inode_dirty(inode);
     254                 :            : 
     255                 :            :         /* Write a new EOF, and get the remaining cluster chain for freeing. */
     256         [ #  # ]:          0 :         if (skip) {
     257                 :            :                 struct fat_entry fatent;
     258                 :            :                 int ret, fclus, dclus;
     259                 :            : 
     260                 :          0 :                 ret = fat_get_cluster(inode, skip - 1, &fclus, &dclus);
     261         [ #  # ]:          0 :                 if (ret < 0)
     262                 :          0 :                         return ret;
     263         [ #  # ]:          0 :                 else if (ret == FAT_ENT_EOF)
     264                 :            :                         return 0;
     265                 :            : 
     266                 :            :                 fatent_init(&fatent);
     267                 :          0 :                 ret = fat_ent_read(inode, &fatent, dclus);
     268         [ #  # ]:          0 :                 if (ret == FAT_ENT_EOF) {
     269                 :            :                         fatent_brelse(&fatent);
     270                 :            :                         return 0;
     271         [ #  # ]:          0 :                 } else if (ret == FAT_ENT_FREE) {
     272                 :          0 :                         fat_fs_error(sb,
     273                 :            :                                      "%s: invalid cluster chain (i_pos %lld)",
     274                 :            :                                      __func__, MSDOS_I(inode)->i_pos);
     275                 :            :                         ret = -EIO;
     276         [ #  # ]:          0 :                 } else if (ret > 0) {
     277                 :          0 :                         err = fat_ent_write(inode, &fatent, FAT_ENT_EOF, wait);
     278         [ #  # ]:          0 :                         if (err)
     279                 :            :                                 ret = err;
     280                 :            :                 }
     281                 :            :                 fatent_brelse(&fatent);
     282         [ #  # ]:          0 :                 if (ret < 0)
     283                 :            :                         return ret;
     284                 :            : 
     285                 :            :                 free_start = ret;
     286                 :            :         }
     287                 :          0 :         inode->i_blocks = skip << (MSDOS_SB(sb)->cluster_bits - 9);
     288                 :            : 
     289                 :            :         /* Freeing the remained cluster chain */
     290                 :          0 :         return fat_free_clusters(inode, free_start);
     291                 :            : }
     292                 :            : 
     293                 :          0 : void fat_truncate_blocks(struct inode *inode, loff_t offset)
     294                 :            : {
     295                 :          0 :         struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
     296                 :          0 :         const unsigned int cluster_size = sbi->cluster_size;
     297                 :            :         int nr_clusters;
     298                 :            : 
     299                 :            :         /*
     300                 :            :          * This protects against truncating a file bigger than it was then
     301                 :            :          * trying to write into the hole.
     302                 :            :          */
     303         [ #  # ]:          0 :         if (MSDOS_I(inode)->mmu_private > offset)
     304                 :          0 :                 MSDOS_I(inode)->mmu_private = offset;
     305                 :            : 
     306                 :          0 :         nr_clusters = (offset + (cluster_size - 1)) >> sbi->cluster_bits;
     307                 :            : 
     308                 :          0 :         fat_free(inode, nr_clusters);
     309                 :          0 :         fat_flush_inodes(inode->i_sb, inode, NULL);
     310                 :          0 : }
     311                 :            : 
     312                 :          0 : int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
     313                 :            : {
     314                 :          0 :         struct inode *inode = dentry->d_inode;
     315                 :          0 :         generic_fillattr(inode, stat);
     316                 :          0 :         stat->blksize = MSDOS_SB(inode->i_sb)->cluster_size;
     317                 :            : 
     318         [ #  # ]:          0 :         if (MSDOS_SB(inode->i_sb)->options.nfs == FAT_NFS_NOSTALE_RO) {
     319                 :            :                 /* Use i_pos for ino. This is used as fileid of nfs. */
     320                 :          0 :                 stat->ino = fat_i_pos_read(MSDOS_SB(inode->i_sb), inode);
     321                 :            :         }
     322                 :          0 :         return 0;
     323                 :            : }
     324                 :            : EXPORT_SYMBOL_GPL(fat_getattr);
     325                 :            : 
     326                 :          0 : static int fat_sanitize_mode(const struct msdos_sb_info *sbi,
     327                 :          0 :                              struct inode *inode, umode_t *mode_ptr)
     328                 :            : {
     329                 :            :         umode_t mask, perm;
     330                 :            : 
     331                 :            :         /*
     332                 :            :          * Note, the basic check is already done by a caller of
     333                 :            :          * (attr->ia_mode & ~FAT_VALID_MODE)
     334                 :            :          */
     335                 :            : 
     336         [ #  # ]:          0 :         if (S_ISREG(inode->i_mode))
     337                 :          0 :                 mask = sbi->options.fs_fmask;
     338                 :            :         else
     339                 :          0 :                 mask = sbi->options.fs_dmask;
     340                 :            : 
     341                 :          0 :         perm = *mode_ptr & ~(S_IFMT | mask);
     342                 :            : 
     343                 :            :         /*
     344                 :            :          * Of the r and x bits, all (subject to umask) must be present. Of the
     345                 :            :          * w bits, either all (subject to umask) or none must be present.
     346                 :            :          *
     347                 :            :          * If fat_mode_can_hold_ro(inode) is false, can't change w bits.
     348                 :            :          */
     349         [ #  # ]:          0 :         if ((perm & (S_IRUGO | S_IXUGO)) != (inode->i_mode & (S_IRUGO|S_IXUGO)))
     350                 :            :                 return -EPERM;
     351         [ #  # ]:          0 :         if (fat_mode_can_hold_ro(inode)) {
     352 [ #  # ][ #  # ]:          0 :                 if ((perm & S_IWUGO) && ((perm & S_IWUGO) != (S_IWUGO & ~mask)))
     353                 :            :                         return -EPERM;
     354                 :            :         } else {
     355         [ #  # ]:          0 :                 if ((perm & S_IWUGO) != (S_IWUGO & ~mask))
     356                 :            :                         return -EPERM;
     357                 :            :         }
     358                 :            : 
     359                 :          0 :         *mode_ptr &= S_IFMT | perm;
     360                 :            : 
     361                 :            :         return 0;
     362                 :            : }
     363                 :            : 
     364                 :          0 : static int fat_allow_set_time(struct msdos_sb_info *sbi, struct inode *inode)
     365                 :            : {
     366                 :          0 :         umode_t allow_utime = sbi->options.allow_utime;
     367                 :            : 
     368         [ #  # ]:          0 :         if (!uid_eq(current_fsuid(), inode->i_uid)) {
     369         [ #  # ]:          0 :                 if (in_group_p(inode->i_gid))
     370                 :          0 :                         allow_utime >>= 3;
     371         [ #  # ]:          0 :                 if (allow_utime & MAY_WRITE)
     372                 :            :                         return 1;
     373                 :            :         }
     374                 :            : 
     375                 :            :         /* use a default check */
     376                 :            :         return 0;
     377                 :            : }
     378                 :            : 
     379                 :            : #define TIMES_SET_FLAGS (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)
     380                 :            : /* valid file mode bits */
     381                 :            : #define FAT_VALID_MODE  (S_IFREG | S_IFDIR | S_IRWXUGO)
     382                 :            : 
     383                 :          0 : int fat_setattr(struct dentry *dentry, struct iattr *attr)
     384                 :            : {
     385                 :          0 :         struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb);
     386                 :          0 :         struct inode *inode = dentry->d_inode;
     387                 :            :         unsigned int ia_valid;
     388                 :            :         int error;
     389                 :            : 
     390                 :            :         /* Check for setting the inode time. */
     391                 :          0 :         ia_valid = attr->ia_valid;
     392         [ #  # ]:          0 :         if (ia_valid & TIMES_SET_FLAGS) {
     393         [ #  # ]:          0 :                 if (fat_allow_set_time(sbi, inode))
     394                 :          0 :                         attr->ia_valid &= ~TIMES_SET_FLAGS;
     395                 :            :         }
     396                 :            : 
     397                 :          0 :         error = inode_change_ok(inode, attr);
     398                 :          0 :         attr->ia_valid = ia_valid;
     399         [ #  # ]:          0 :         if (error) {
     400         [ #  # ]:          0 :                 if (sbi->options.quiet)
     401                 :            :                         error = 0;
     402                 :            :                 goto out;
     403                 :            :         }
     404                 :            : 
     405                 :            :         /*
     406                 :            :          * Expand the file. Since inode_setattr() updates ->i_size
     407                 :            :          * before calling the ->truncate(), but FAT needs to fill the
     408                 :            :          * hole before it. XXX: this is no longer true with new truncate
     409                 :            :          * sequence.
     410                 :            :          */
     411         [ #  # ]:          0 :         if (attr->ia_valid & ATTR_SIZE) {
     412                 :          0 :                 inode_dio_wait(inode);
     413                 :            : 
     414         [ #  # ]:          0 :                 if (attr->ia_size > inode->i_size) {
     415                 :          0 :                         error = fat_cont_expand(inode, attr->ia_size);
     416 [ #  # ][ #  # ]:          0 :                         if (error || attr->ia_valid == ATTR_SIZE)
     417                 :            :                                 goto out;
     418                 :          0 :                         attr->ia_valid &= ~ATTR_SIZE;
     419                 :            :                 }
     420                 :            :         }
     421                 :            : 
     422 [ #  # ][ #  # ]:          0 :         if (((attr->ia_valid & ATTR_UID) &&
     423         [ #  # ]:          0 :              (!uid_eq(attr->ia_uid, sbi->options.fs_uid))) ||
     424         [ #  # ]:          0 :             ((attr->ia_valid & ATTR_GID) &&
     425         [ #  # ]:          0 :              (!gid_eq(attr->ia_gid, sbi->options.fs_gid))) ||
     426         [ #  # ]:          0 :             ((attr->ia_valid & ATTR_MODE) &&
     427                 :          0 :              (attr->ia_mode & ~FAT_VALID_MODE)))
     428                 :            :                 error = -EPERM;
     429                 :            : 
     430         [ #  # ]:          0 :         if (error) {
     431         [ #  # ]:          0 :                 if (sbi->options.quiet)
     432                 :            :                         error = 0;
     433                 :            :                 goto out;
     434                 :            :         }
     435                 :            : 
     436                 :            :         /*
     437                 :            :          * We don't return -EPERM here. Yes, strange, but this is too
     438                 :            :          * old behavior.
     439                 :            :          */
     440         [ #  # ]:          0 :         if (attr->ia_valid & ATTR_MODE) {
     441         [ #  # ]:          0 :                 if (fat_sanitize_mode(sbi, inode, &attr->ia_mode) < 0)
     442                 :          0 :                         attr->ia_valid &= ~ATTR_MODE;
     443                 :            :         }
     444                 :            : 
     445         [ #  # ]:          0 :         if (attr->ia_valid & ATTR_SIZE) {
     446                 :          0 :                 down_write(&MSDOS_I(inode)->truncate_lock);
     447                 :          0 :                 truncate_setsize(inode, attr->ia_size);
     448                 :          0 :                 fat_truncate_blocks(inode, attr->ia_size);
     449                 :          0 :                 up_write(&MSDOS_I(inode)->truncate_lock);
     450                 :            :         }
     451                 :            : 
     452                 :          0 :         setattr_copy(inode, attr);
     453                 :            :         mark_inode_dirty(inode);
     454                 :            : out:
     455                 :          0 :         return error;
     456                 :            : }
     457                 :            : EXPORT_SYMBOL_GPL(fat_setattr);
     458                 :            : 
     459                 :            : const struct inode_operations fat_file_inode_operations = {
     460                 :            :         .setattr        = fat_setattr,
     461                 :            :         .getattr        = fat_getattr,
     462                 :            : };

Generated by: LCOV version 1.9