Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
0004  */
0005 
0006 #include <linux/slab.h>
0007 #include <linux/compat.h>
0008 #include <linux/cred.h>
0009 #include <linux/buffer_head.h>
0010 #include <linux/blkdev.h>
0011 
0012 #include "exfat_raw.h"
0013 #include "exfat_fs.h"
0014 
0015 static int exfat_cont_expand(struct inode *inode, loff_t size)
0016 {
0017     struct address_space *mapping = inode->i_mapping;
0018     loff_t start = i_size_read(inode), count = size - i_size_read(inode);
0019     int err, err2;
0020 
0021     err = generic_cont_expand_simple(inode, size);
0022     if (err)
0023         return err;
0024 
0025     inode->i_ctime = inode->i_mtime = current_time(inode);
0026     mark_inode_dirty(inode);
0027 
0028     if (!IS_SYNC(inode))
0029         return 0;
0030 
0031     err = filemap_fdatawrite_range(mapping, start, start + count - 1);
0032     err2 = sync_mapping_buffers(mapping);
0033     if (!err)
0034         err = err2;
0035     err2 = write_inode_now(inode, 1);
0036     if (!err)
0037         err = err2;
0038     if (err)
0039         return err;
0040 
0041     return filemap_fdatawait_range(mapping, start, start + count - 1);
0042 }
0043 
0044 static bool exfat_allow_set_time(struct exfat_sb_info *sbi, struct inode *inode)
0045 {
0046     mode_t allow_utime = sbi->options.allow_utime;
0047 
0048     if (!uid_eq(current_fsuid(), inode->i_uid)) {
0049         if (in_group_p(inode->i_gid))
0050             allow_utime >>= 3;
0051         if (allow_utime & MAY_WRITE)
0052             return true;
0053     }
0054 
0055     /* use a default check */
0056     return false;
0057 }
0058 
0059 static int exfat_sanitize_mode(const struct exfat_sb_info *sbi,
0060         struct inode *inode, umode_t *mode_ptr)
0061 {
0062     mode_t i_mode, mask, perm;
0063 
0064     i_mode = inode->i_mode;
0065 
0066     mask = (S_ISREG(i_mode) || S_ISLNK(i_mode)) ?
0067         sbi->options.fs_fmask : sbi->options.fs_dmask;
0068     perm = *mode_ptr & ~(S_IFMT | mask);
0069 
0070     /* Of the r and x bits, all (subject to umask) must be present.*/
0071     if ((perm & 0555) != (i_mode & 0555))
0072         return -EPERM;
0073 
0074     if (exfat_mode_can_hold_ro(inode)) {
0075         /*
0076          * Of the w bits, either all (subject to umask) or none must
0077          * be present.
0078          */
0079         if ((perm & 0222) && ((perm & 0222) != (0222 & ~mask)))
0080             return -EPERM;
0081     } else {
0082         /*
0083          * If exfat_mode_can_hold_ro(inode) is false, can't change
0084          * w bits.
0085          */
0086         if ((perm & 0222) != (0222 & ~mask))
0087             return -EPERM;
0088     }
0089 
0090     *mode_ptr &= S_IFMT | perm;
0091 
0092     return 0;
0093 }
0094 
0095 /* resize the file length */
0096 int __exfat_truncate(struct inode *inode, loff_t new_size)
0097 {
0098     unsigned int num_clusters_new, num_clusters_phys;
0099     unsigned int last_clu = EXFAT_FREE_CLUSTER;
0100     struct exfat_chain clu;
0101     struct super_block *sb = inode->i_sb;
0102     struct exfat_sb_info *sbi = EXFAT_SB(sb);
0103     struct exfat_inode_info *ei = EXFAT_I(inode);
0104 
0105     /* check if the given file ID is opened */
0106     if (ei->type != TYPE_FILE && ei->type != TYPE_DIR)
0107         return -EPERM;
0108 
0109     exfat_set_volume_dirty(sb);
0110 
0111     num_clusters_new = EXFAT_B_TO_CLU_ROUND_UP(i_size_read(inode), sbi);
0112     num_clusters_phys = EXFAT_B_TO_CLU_ROUND_UP(ei->i_size_ondisk, sbi);
0113 
0114     exfat_chain_set(&clu, ei->start_clu, num_clusters_phys, ei->flags);
0115 
0116     if (new_size > 0) {
0117         /*
0118          * Truncate FAT chain num_clusters after the first cluster
0119          * num_clusters = min(new, phys);
0120          */
0121         unsigned int num_clusters =
0122             min(num_clusters_new, num_clusters_phys);
0123 
0124         /*
0125          * Follow FAT chain
0126          * (defensive coding - works fine even with corrupted FAT table
0127          */
0128         if (clu.flags == ALLOC_NO_FAT_CHAIN) {
0129             clu.dir += num_clusters;
0130             clu.size -= num_clusters;
0131         } else {
0132             while (num_clusters > 0) {
0133                 last_clu = clu.dir;
0134                 if (exfat_get_next_cluster(sb, &(clu.dir)))
0135                     return -EIO;
0136 
0137                 num_clusters--;
0138                 clu.size--;
0139             }
0140         }
0141     } else {
0142         ei->flags = ALLOC_NO_FAT_CHAIN;
0143         ei->start_clu = EXFAT_EOF_CLUSTER;
0144     }
0145 
0146     i_size_write(inode, new_size);
0147 
0148     if (ei->type == TYPE_FILE)
0149         ei->attr |= ATTR_ARCHIVE;
0150 
0151     /*
0152      * update the directory entry
0153      *
0154      * If the directory entry is updated by mark_inode_dirty(), the
0155      * directory entry will be written after a writeback cycle of
0156      * updating the bitmap/FAT, which may result in clusters being
0157      * freed but referenced by the directory entry in the event of a
0158      * sudden power failure.
0159      * __exfat_write_inode() is called for directory entry, bitmap
0160      * and FAT to be written in a same writeback.
0161      */
0162     if (__exfat_write_inode(inode, inode_needs_sync(inode)))
0163         return -EIO;
0164 
0165     /* cut off from the FAT chain */
0166     if (ei->flags == ALLOC_FAT_CHAIN && last_clu != EXFAT_FREE_CLUSTER &&
0167             last_clu != EXFAT_EOF_CLUSTER) {
0168         if (exfat_ent_set(sb, last_clu, EXFAT_EOF_CLUSTER))
0169             return -EIO;
0170     }
0171 
0172     /* invalidate cache and free the clusters */
0173     /* clear exfat cache */
0174     exfat_cache_inval_inode(inode);
0175 
0176     /* hint information */
0177     ei->hint_bmap.off = EXFAT_EOF_CLUSTER;
0178     ei->hint_bmap.clu = EXFAT_EOF_CLUSTER;
0179 
0180     /* hint_stat will be used if this is directory. */
0181     ei->hint_stat.eidx = 0;
0182     ei->hint_stat.clu = ei->start_clu;
0183     ei->hint_femp.eidx = EXFAT_HINT_NONE;
0184 
0185     /* free the clusters */
0186     if (exfat_free_cluster(inode, &clu))
0187         return -EIO;
0188 
0189     return 0;
0190 }
0191 
0192 void exfat_truncate(struct inode *inode, loff_t size)
0193 {
0194     struct super_block *sb = inode->i_sb;
0195     struct exfat_sb_info *sbi = EXFAT_SB(sb);
0196     struct exfat_inode_info *ei = EXFAT_I(inode);
0197     unsigned int blocksize = i_blocksize(inode);
0198     loff_t aligned_size;
0199     int err;
0200 
0201     mutex_lock(&sbi->s_lock);
0202     if (ei->start_clu == 0) {
0203         /*
0204          * Empty start_clu != ~0 (not allocated)
0205          */
0206         exfat_fs_error(sb, "tried to truncate zeroed cluster.");
0207         goto write_size;
0208     }
0209 
0210     err = __exfat_truncate(inode, i_size_read(inode));
0211     if (err)
0212         goto write_size;
0213 
0214     inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >>
0215                 inode->i_blkbits;
0216 write_size:
0217     aligned_size = i_size_read(inode);
0218     if (aligned_size & (blocksize - 1)) {
0219         aligned_size |= (blocksize - 1);
0220         aligned_size++;
0221     }
0222 
0223     if (ei->i_size_ondisk > i_size_read(inode))
0224         ei->i_size_ondisk = aligned_size;
0225 
0226     if (ei->i_size_aligned > i_size_read(inode))
0227         ei->i_size_aligned = aligned_size;
0228     mutex_unlock(&sbi->s_lock);
0229 }
0230 
0231 int exfat_getattr(struct user_namespace *mnt_uerns, const struct path *path,
0232           struct kstat *stat, unsigned int request_mask,
0233           unsigned int query_flags)
0234 {
0235     struct inode *inode = d_backing_inode(path->dentry);
0236     struct exfat_inode_info *ei = EXFAT_I(inode);
0237 
0238     generic_fillattr(&init_user_ns, inode, stat);
0239     exfat_truncate_atime(&stat->atime);
0240     stat->result_mask |= STATX_BTIME;
0241     stat->btime.tv_sec = ei->i_crtime.tv_sec;
0242     stat->btime.tv_nsec = ei->i_crtime.tv_nsec;
0243     stat->blksize = EXFAT_SB(inode->i_sb)->cluster_size;
0244     return 0;
0245 }
0246 
0247 int exfat_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
0248           struct iattr *attr)
0249 {
0250     struct exfat_sb_info *sbi = EXFAT_SB(dentry->d_sb);
0251     struct inode *inode = dentry->d_inode;
0252     unsigned int ia_valid;
0253     int error;
0254 
0255     if ((attr->ia_valid & ATTR_SIZE) &&
0256         attr->ia_size > i_size_read(inode)) {
0257         error = exfat_cont_expand(inode, attr->ia_size);
0258         if (error || attr->ia_valid == ATTR_SIZE)
0259             return error;
0260         attr->ia_valid &= ~ATTR_SIZE;
0261     }
0262 
0263     /* Check for setting the inode time. */
0264     ia_valid = attr->ia_valid;
0265     if ((ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) &&
0266         exfat_allow_set_time(sbi, inode)) {
0267         attr->ia_valid &= ~(ATTR_MTIME_SET | ATTR_ATIME_SET |
0268                 ATTR_TIMES_SET);
0269     }
0270 
0271     error = setattr_prepare(&init_user_ns, dentry, attr);
0272     attr->ia_valid = ia_valid;
0273     if (error)
0274         goto out;
0275 
0276     if (((attr->ia_valid & ATTR_UID) &&
0277          !uid_eq(attr->ia_uid, sbi->options.fs_uid)) ||
0278         ((attr->ia_valid & ATTR_GID) &&
0279          !gid_eq(attr->ia_gid, sbi->options.fs_gid)) ||
0280         ((attr->ia_valid & ATTR_MODE) &&
0281          (attr->ia_mode & ~(S_IFREG | S_IFLNK | S_IFDIR | 0777)))) {
0282         error = -EPERM;
0283         goto out;
0284     }
0285 
0286     /*
0287      * We don't return -EPERM here. Yes, strange, but this is too
0288      * old behavior.
0289      */
0290     if (attr->ia_valid & ATTR_MODE) {
0291         if (exfat_sanitize_mode(sbi, inode, &attr->ia_mode) < 0)
0292             attr->ia_valid &= ~ATTR_MODE;
0293     }
0294 
0295     if (attr->ia_valid & ATTR_SIZE)
0296         inode->i_mtime = inode->i_ctime = current_time(inode);
0297 
0298     setattr_copy(&init_user_ns, inode, attr);
0299     exfat_truncate_atime(&inode->i_atime);
0300 
0301     if (attr->ia_valid & ATTR_SIZE) {
0302         error = exfat_block_truncate_page(inode, attr->ia_size);
0303         if (error)
0304             goto out;
0305 
0306         down_write(&EXFAT_I(inode)->truncate_lock);
0307         truncate_setsize(inode, attr->ia_size);
0308 
0309         /*
0310          * __exfat_write_inode() is called from exfat_truncate(), inode
0311          * is already written by it, so mark_inode_dirty() is unneeded.
0312          */
0313         exfat_truncate(inode, attr->ia_size);
0314         up_write(&EXFAT_I(inode)->truncate_lock);
0315     } else
0316         mark_inode_dirty(inode);
0317 
0318 out:
0319     return error;
0320 }
0321 
0322 static int exfat_ioctl_fitrim(struct inode *inode, unsigned long arg)
0323 {
0324     struct fstrim_range range;
0325     int ret = 0;
0326 
0327     if (!capable(CAP_SYS_ADMIN))
0328         return -EPERM;
0329 
0330     if (!bdev_max_discard_sectors(inode->i_sb->s_bdev))
0331         return -EOPNOTSUPP;
0332 
0333     if (copy_from_user(&range, (struct fstrim_range __user *)arg, sizeof(range)))
0334         return -EFAULT;
0335 
0336     range.minlen = max_t(unsigned int, range.minlen,
0337                 bdev_discard_granularity(inode->i_sb->s_bdev));
0338 
0339     ret = exfat_trim_fs(inode, &range);
0340     if (ret < 0)
0341         return ret;
0342 
0343     if (copy_to_user((struct fstrim_range __user *)arg, &range, sizeof(range)))
0344         return -EFAULT;
0345 
0346     return 0;
0347 }
0348 
0349 long exfat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
0350 {
0351     struct inode *inode = file_inode(filp);
0352 
0353     switch (cmd) {
0354     case FITRIM:
0355         return exfat_ioctl_fitrim(inode, arg);
0356     default:
0357         return -ENOTTY;
0358     }
0359 }
0360 
0361 #ifdef CONFIG_COMPAT
0362 long exfat_compat_ioctl(struct file *filp, unsigned int cmd,
0363                 unsigned long arg)
0364 {
0365     return exfat_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
0366 }
0367 #endif
0368 
0369 int exfat_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
0370 {
0371     struct inode *inode = filp->f_mapping->host;
0372     int err;
0373 
0374     err = __generic_file_fsync(filp, start, end, datasync);
0375     if (err)
0376         return err;
0377 
0378     err = sync_blockdev(inode->i_sb->s_bdev);
0379     if (err)
0380         return err;
0381 
0382     return blkdev_issue_flush(inode->i_sb->s_bdev);
0383 }
0384 
0385 const struct file_operations exfat_file_operations = {
0386     .llseek     = generic_file_llseek,
0387     .read_iter  = generic_file_read_iter,
0388     .write_iter = generic_file_write_iter,
0389     .unlocked_ioctl = exfat_ioctl,
0390 #ifdef CONFIG_COMPAT
0391     .compat_ioctl = exfat_compat_ioctl,
0392 #endif
0393     .mmap       = generic_file_mmap,
0394     .fsync      = exfat_file_fsync,
0395     .splice_read    = generic_file_splice_read,
0396     .splice_write   = iter_file_splice_write,
0397 };
0398 
0399 const struct inode_operations exfat_file_inode_operations = {
0400     .setattr     = exfat_setattr,
0401     .getattr     = exfat_getattr,
0402 };