1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
6 #include <linux/slab.h>
7 #include <linux/cred.h>
8 #include <linux/buffer_head.h>
10 #include "exfat_raw.h"
13 static int exfat_cont_expand(struct inode *inode, loff_t size)
15 struct address_space *mapping = inode->i_mapping;
16 loff_t start = i_size_read(inode), count = size - i_size_read(inode);
19 err = generic_cont_expand_simple(inode, size);
23 inode->i_ctime = inode->i_mtime = current_time(inode);
24 mark_inode_dirty(inode);
29 err = filemap_fdatawrite_range(mapping, start, start + count - 1);
30 err2 = sync_mapping_buffers(mapping);
33 err2 = write_inode_now(inode, 1);
39 return filemap_fdatawait_range(mapping, start, start + count - 1);
42 static bool exfat_allow_set_time(struct exfat_sb_info *sbi, struct inode *inode)
44 mode_t allow_utime = sbi->options.allow_utime;
46 if (!uid_eq(current_fsuid(), inode->i_uid)) {
47 if (in_group_p(inode->i_gid))
49 if (allow_utime & MAY_WRITE)
53 /* use a default check */
57 static int exfat_sanitize_mode(const struct exfat_sb_info *sbi,
58 struct inode *inode, umode_t *mode_ptr)
60 mode_t i_mode, mask, perm;
62 i_mode = inode->i_mode;
64 mask = (S_ISREG(i_mode) || S_ISLNK(i_mode)) ?
65 sbi->options.fs_fmask : sbi->options.fs_dmask;
66 perm = *mode_ptr & ~(S_IFMT | mask);
68 /* Of the r and x bits, all (subject to umask) must be present.*/
69 if ((perm & 0555) != (i_mode & 0555))
72 if (exfat_mode_can_hold_ro(inode)) {
74 * Of the w bits, either all (subject to umask) or none must
77 if ((perm & 0222) && ((perm & 0222) != (0222 & ~mask)))
81 * If exfat_mode_can_hold_ro(inode) is false, can't change
84 if ((perm & 0222) != (0222 & ~mask))
88 *mode_ptr &= S_IFMT | perm;
93 /* resize the file length */
94 int __exfat_truncate(struct inode *inode, loff_t new_size)
96 unsigned int num_clusters_new, num_clusters_phys;
97 unsigned int last_clu = EXFAT_FREE_CLUSTER;
98 struct exfat_chain clu;
99 struct super_block *sb = inode->i_sb;
100 struct exfat_sb_info *sbi = EXFAT_SB(sb);
101 struct exfat_inode_info *ei = EXFAT_I(inode);
102 int evict = (ei->dir.dir == DIR_DELETED) ? 1 : 0;
104 /* check if the given file ID is opened */
105 if (ei->type != TYPE_FILE && ei->type != TYPE_DIR)
108 exfat_set_vol_flags(sb, VOL_DIRTY);
110 num_clusters_new = EXFAT_B_TO_CLU_ROUND_UP(i_size_read(inode), sbi);
112 EXFAT_B_TO_CLU_ROUND_UP(EXFAT_I(inode)->i_size_ondisk, sbi);
114 exfat_chain_set(&clu, ei->start_clu, num_clusters_phys, ei->flags);
118 * Truncate FAT chain num_clusters after the first cluster
119 * num_clusters = min(new, phys);
121 unsigned int num_clusters =
122 min(num_clusters_new, num_clusters_phys);
126 * (defensive coding - works fine even with corrupted FAT table
128 if (clu.flags == ALLOC_NO_FAT_CHAIN) {
129 clu.dir += num_clusters;
130 clu.size -= num_clusters;
132 while (num_clusters > 0) {
134 if (exfat_get_next_cluster(sb, &(clu.dir)))
142 ei->flags = ALLOC_NO_FAT_CHAIN;
143 ei->start_clu = EXFAT_EOF_CLUSTER;
146 i_size_write(inode, new_size);
148 if (ei->type == TYPE_FILE)
149 ei->attr |= ATTR_ARCHIVE;
151 /* update the directory entry */
153 struct timespec64 ts;
154 struct exfat_dentry *ep, *ep2;
155 struct exfat_entry_set_cache *es;
157 es = exfat_get_dentry_set(sb, &(ei->dir), ei->entry,
161 ep = exfat_get_dentry_cached(es, 0);
162 ep2 = exfat_get_dentry_cached(es, 1);
164 ts = current_time(inode);
165 exfat_set_entry_time(sbi, &ts,
166 &ep->dentry.file.modify_tz,
167 &ep->dentry.file.modify_time,
168 &ep->dentry.file.modify_date,
169 &ep->dentry.file.modify_time_cs);
170 ep->dentry.file.attr = cpu_to_le16(ei->attr);
172 /* File size should be zero if there is no cluster allocated */
173 if (ei->start_clu == EXFAT_EOF_CLUSTER) {
174 ep2->dentry.stream.valid_size = 0;
175 ep2->dentry.stream.size = 0;
177 ep2->dentry.stream.valid_size = cpu_to_le64(new_size);
178 ep2->dentry.stream.size = ep->dentry.stream.valid_size;
182 /* Any directory can not be truncated to zero */
183 WARN_ON(ei->type != TYPE_FILE);
185 ep2->dentry.stream.flags = ALLOC_FAT_CHAIN;
186 ep2->dentry.stream.start_clu = EXFAT_FREE_CLUSTER;
189 exfat_update_dir_chksum_with_entry_set(es);
190 exfat_free_dentry_set(es, inode_needs_sync(inode));
193 /* cut off from the FAT chain */
194 if (ei->flags == ALLOC_FAT_CHAIN && last_clu != EXFAT_FREE_CLUSTER &&
195 last_clu != EXFAT_EOF_CLUSTER) {
196 if (exfat_ent_set(sb, last_clu, EXFAT_EOF_CLUSTER))
200 /* invalidate cache and free the clusters */
201 /* clear exfat cache */
202 exfat_cache_inval_inode(inode);
204 /* hint information */
205 ei->hint_bmap.off = EXFAT_EOF_CLUSTER;
206 ei->hint_bmap.clu = EXFAT_EOF_CLUSTER;
207 if (ei->rwoffset > new_size)
208 ei->rwoffset = new_size;
210 /* hint_stat will be used if this is directory. */
211 ei->hint_stat.eidx = 0;
212 ei->hint_stat.clu = ei->start_clu;
213 ei->hint_femp.eidx = EXFAT_HINT_NONE;
215 /* free the clusters */
216 if (exfat_free_cluster(inode, &clu))
219 exfat_set_vol_flags(sb, VOL_CLEAN);
224 void exfat_truncate(struct inode *inode, loff_t size)
226 struct super_block *sb = inode->i_sb;
227 struct exfat_sb_info *sbi = EXFAT_SB(sb);
228 unsigned int blocksize = 1 << inode->i_blkbits;
232 mutex_lock(&sbi->s_lock);
233 if (EXFAT_I(inode)->start_clu == 0) {
235 * Empty start_clu != ~0 (not allocated)
237 exfat_fs_error(sb, "tried to truncate zeroed cluster.");
241 err = __exfat_truncate(inode, i_size_read(inode));
245 inode->i_ctime = inode->i_mtime = current_time(inode);
246 if (IS_DIRSYNC(inode))
247 exfat_sync_inode(inode);
249 mark_inode_dirty(inode);
251 inode->i_blocks = ((i_size_read(inode) + (sbi->cluster_size - 1)) &
252 ~(sbi->cluster_size - 1)) >> inode->i_blkbits;
254 aligned_size = i_size_read(inode);
255 if (aligned_size & (blocksize - 1)) {
256 aligned_size |= (blocksize - 1);
260 if (EXFAT_I(inode)->i_size_ondisk > i_size_read(inode))
261 EXFAT_I(inode)->i_size_ondisk = aligned_size;
263 if (EXFAT_I(inode)->i_size_aligned > i_size_read(inode))
264 EXFAT_I(inode)->i_size_aligned = aligned_size;
265 mutex_unlock(&sbi->s_lock);
268 int exfat_getattr(const struct path *path, struct kstat *stat,
269 unsigned int request_mask, unsigned int query_flags)
271 struct inode *inode = d_backing_inode(path->dentry);
272 struct exfat_inode_info *ei = EXFAT_I(inode);
274 generic_fillattr(inode, stat);
275 exfat_truncate_atime(&stat->atime);
276 stat->result_mask |= STATX_BTIME;
277 stat->btime.tv_sec = ei->i_crtime.tv_sec;
278 stat->btime.tv_nsec = ei->i_crtime.tv_nsec;
279 stat->blksize = EXFAT_SB(inode->i_sb)->cluster_size;
283 int exfat_setattr(struct dentry *dentry, struct iattr *attr)
285 struct exfat_sb_info *sbi = EXFAT_SB(dentry->d_sb);
286 struct inode *inode = dentry->d_inode;
287 unsigned int ia_valid;
290 if ((attr->ia_valid & ATTR_SIZE) &&
291 attr->ia_size > i_size_read(inode)) {
292 error = exfat_cont_expand(inode, attr->ia_size);
293 if (error || attr->ia_valid == ATTR_SIZE)
295 attr->ia_valid &= ~ATTR_SIZE;
298 /* Check for setting the inode time. */
299 ia_valid = attr->ia_valid;
300 if ((ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) &&
301 exfat_allow_set_time(sbi, inode)) {
302 attr->ia_valid &= ~(ATTR_MTIME_SET | ATTR_ATIME_SET |
306 error = setattr_prepare(dentry, attr);
307 attr->ia_valid = ia_valid;
311 if (((attr->ia_valid & ATTR_UID) &&
312 !uid_eq(attr->ia_uid, sbi->options.fs_uid)) ||
313 ((attr->ia_valid & ATTR_GID) &&
314 !gid_eq(attr->ia_gid, sbi->options.fs_gid)) ||
315 ((attr->ia_valid & ATTR_MODE) &&
316 (attr->ia_mode & ~(S_IFREG | S_IFLNK | S_IFDIR | 0777)))) {
322 * We don't return -EPERM here. Yes, strange, but this is too
325 if (attr->ia_valid & ATTR_MODE) {
326 if (exfat_sanitize_mode(sbi, inode, &attr->ia_mode) < 0)
327 attr->ia_valid &= ~ATTR_MODE;
330 if (attr->ia_valid & ATTR_SIZE) {
331 error = exfat_block_truncate_page(inode, attr->ia_size);
335 down_write(&EXFAT_I(inode)->truncate_lock);
336 truncate_setsize(inode, attr->ia_size);
337 exfat_truncate(inode, attr->ia_size);
338 up_write(&EXFAT_I(inode)->truncate_lock);
341 setattr_copy(inode, attr);
342 exfat_truncate_atime(&inode->i_atime);
343 mark_inode_dirty(inode);
349 const struct file_operations exfat_file_operations = {
350 .llseek = generic_file_llseek,
351 .read_iter = generic_file_read_iter,
352 .write_iter = generic_file_write_iter,
353 .mmap = generic_file_mmap,
354 .fsync = generic_file_fsync,
355 .splice_read = generic_file_splice_read,
356 .splice_write = iter_file_splice_write,
359 const struct inode_operations exfat_file_inode_operations = {
360 .setattr = exfat_setattr,
361 .getattr = exfat_getattr,