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/mount.h> 12 #include <linux/time.h> 13 #include <linux/msdos_fs.h> 14 #include <linux/buffer_head.h> 15 #include <linux/writeback.h> 16 #include <linux/backing-dev.h> 17 #include <linux/blkdev.h> 18 19 int fat_generic_ioctl(struct inode *inode, struct file *filp, 20 unsigned int cmd, unsigned long arg) 21 { 22 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); 23 u32 __user *user_attr = (u32 __user *)arg; 24 25 switch (cmd) { 26 case FAT_IOCTL_GET_ATTRIBUTES: 27 { 28 u32 attr; 29 30 if (inode->i_ino == MSDOS_ROOT_INO) 31 attr = ATTR_DIR; 32 else 33 attr = fat_attr(inode); 34 35 return put_user(attr, user_attr); 36 } 37 case FAT_IOCTL_SET_ATTRIBUTES: 38 { 39 u32 attr, oldattr; 40 int err, is_dir = S_ISDIR(inode->i_mode); 41 struct iattr ia; 42 43 err = get_user(attr, user_attr); 44 if (err) 45 return err; 46 47 mutex_lock(&inode->i_mutex); 48 49 err = mnt_want_write(filp->f_path.mnt); 50 if (err) 51 goto up_no_drop_write; 52 53 /* 54 * ATTR_VOLUME and ATTR_DIR cannot be changed; this also 55 * prevents the user from turning us into a VFAT 56 * longname entry. Also, we obviously can't set 57 * any of the NTFS attributes in the high 24 bits. 58 */ 59 attr &= 0xff & ~(ATTR_VOLUME | ATTR_DIR); 60 /* Merge in ATTR_VOLUME and ATTR_DIR */ 61 attr |= (MSDOS_I(inode)->i_attrs & ATTR_VOLUME) | 62 (is_dir ? ATTR_DIR : 0); 63 oldattr = fat_attr(inode); 64 65 /* Equivalent to a chmod() */ 66 ia.ia_valid = ATTR_MODE | ATTR_CTIME; 67 if (is_dir) { 68 ia.ia_mode = MSDOS_MKMODE(attr, 69 S_IRWXUGO & ~sbi->options.fs_dmask) 70 | S_IFDIR; 71 } else { 72 ia.ia_mode = MSDOS_MKMODE(attr, 73 (S_IRUGO | S_IWUGO | (inode->i_mode & S_IXUGO)) 74 & ~sbi->options.fs_fmask) 75 | S_IFREG; 76 } 77 78 /* The root directory has no attributes */ 79 if (inode->i_ino == MSDOS_ROOT_INO && attr != ATTR_DIR) { 80 err = -EINVAL; 81 goto up; 82 } 83 84 if (sbi->options.sys_immutable) { 85 if ((attr | oldattr) & ATTR_SYS) { 86 if (!capable(CAP_LINUX_IMMUTABLE)) { 87 err = -EPERM; 88 goto up; 89 } 90 } 91 } 92 93 /* This MUST be done before doing anything irreversible... */ 94 err = notify_change(filp->f_path.dentry, &ia); 95 if (err) 96 goto up; 97 98 if (sbi->options.sys_immutable) { 99 if (attr & ATTR_SYS) 100 inode->i_flags |= S_IMMUTABLE; 101 else 102 inode->i_flags &= S_IMMUTABLE; 103 } 104 105 MSDOS_I(inode)->i_attrs = attr & ATTR_UNUSED; 106 mark_inode_dirty(inode); 107 up: 108 mnt_drop_write(filp->f_path.mnt); 109 up_no_drop_write: 110 mutex_unlock(&inode->i_mutex); 111 return err; 112 } 113 default: 114 return -ENOTTY; /* Inappropriate ioctl for device */ 115 } 116 } 117 118 static int fat_file_release(struct inode *inode, struct file *filp) 119 { 120 if ((filp->f_mode & FMODE_WRITE) && 121 MSDOS_SB(inode->i_sb)->options.flush) { 122 fat_flush_inodes(inode->i_sb, inode, NULL); 123 congestion_wait(WRITE, HZ/10); 124 } 125 return 0; 126 } 127 128 const struct file_operations fat_file_operations = { 129 .llseek = generic_file_llseek, 130 .read = do_sync_read, 131 .write = do_sync_write, 132 .aio_read = generic_file_aio_read, 133 .aio_write = generic_file_aio_write, 134 .mmap = generic_file_mmap, 135 .release = fat_file_release, 136 .ioctl = fat_generic_ioctl, 137 .fsync = file_fsync, 138 .splice_read = generic_file_splice_read, 139 }; 140 141 static int fat_cont_expand(struct inode *inode, loff_t size) 142 { 143 struct address_space *mapping = inode->i_mapping; 144 loff_t start = inode->i_size, count = size - inode->i_size; 145 int err; 146 147 err = generic_cont_expand_simple(inode, size); 148 if (err) 149 goto out; 150 151 inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; 152 mark_inode_dirty(inode); 153 if (IS_SYNC(inode)) 154 err = sync_page_range_nolock(inode, mapping, start, count); 155 out: 156 return err; 157 } 158 159 /* Free all clusters after the skip'th cluster. */ 160 static int fat_free(struct inode *inode, int skip) 161 { 162 struct super_block *sb = inode->i_sb; 163 int err, wait, free_start, i_start, i_logstart; 164 165 if (MSDOS_I(inode)->i_start == 0) 166 return 0; 167 168 fat_cache_inval_inode(inode); 169 170 wait = IS_DIRSYNC(inode); 171 i_start = free_start = MSDOS_I(inode)->i_start; 172 i_logstart = MSDOS_I(inode)->i_logstart; 173 174 /* First, we write the new file size. */ 175 if (!skip) { 176 MSDOS_I(inode)->i_start = 0; 177 MSDOS_I(inode)->i_logstart = 0; 178 } 179 MSDOS_I(inode)->i_attrs |= ATTR_ARCH; 180 inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; 181 if (wait) { 182 err = fat_sync_inode(inode); 183 if (err) { 184 MSDOS_I(inode)->i_start = i_start; 185 MSDOS_I(inode)->i_logstart = i_logstart; 186 return err; 187 } 188 } else 189 mark_inode_dirty(inode); 190 191 /* Write a new EOF, and get the remaining cluster chain for freeing. */ 192 if (skip) { 193 struct fat_entry fatent; 194 int ret, fclus, dclus; 195 196 ret = fat_get_cluster(inode, skip - 1, &fclus, &dclus); 197 if (ret < 0) 198 return ret; 199 else if (ret == FAT_ENT_EOF) 200 return 0; 201 202 fatent_init(&fatent); 203 ret = fat_ent_read(inode, &fatent, dclus); 204 if (ret == FAT_ENT_EOF) { 205 fatent_brelse(&fatent); 206 return 0; 207 } else if (ret == FAT_ENT_FREE) { 208 fat_fs_panic(sb, 209 "%s: invalid cluster chain (i_pos %lld)", 210 __func__, MSDOS_I(inode)->i_pos); 211 ret = -EIO; 212 } else if (ret > 0) { 213 err = fat_ent_write(inode, &fatent, FAT_ENT_EOF, wait); 214 if (err) 215 ret = err; 216 } 217 fatent_brelse(&fatent); 218 if (ret < 0) 219 return ret; 220 221 free_start = ret; 222 } 223 inode->i_blocks = skip << (MSDOS_SB(sb)->cluster_bits - 9); 224 225 /* Freeing the remained cluster chain */ 226 return fat_free_clusters(inode, free_start); 227 } 228 229 void fat_truncate(struct inode *inode) 230 { 231 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); 232 const unsigned int cluster_size = sbi->cluster_size; 233 int nr_clusters; 234 235 /* 236 * This protects against truncating a file bigger than it was then 237 * trying to write into the hole. 238 */ 239 if (MSDOS_I(inode)->mmu_private > inode->i_size) 240 MSDOS_I(inode)->mmu_private = inode->i_size; 241 242 nr_clusters = (inode->i_size + (cluster_size - 1)) >> sbi->cluster_bits; 243 244 fat_free(inode, nr_clusters); 245 fat_flush_inodes(inode->i_sb, inode, NULL); 246 } 247 248 int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) 249 { 250 struct inode *inode = dentry->d_inode; 251 generic_fillattr(inode, stat); 252 stat->blksize = MSDOS_SB(inode->i_sb)->cluster_size; 253 return 0; 254 } 255 EXPORT_SYMBOL_GPL(fat_getattr); 256 257 static int fat_sanitize_mode(const struct msdos_sb_info *sbi, 258 struct inode *inode, umode_t *mode_ptr) 259 { 260 mode_t mask, perm; 261 262 /* 263 * Note, the basic check is already done by a caller of 264 * (attr->ia_mode & ~MSDOS_VALID_MODE) 265 */ 266 267 if (S_ISREG(inode->i_mode)) 268 mask = sbi->options.fs_fmask; 269 else 270 mask = sbi->options.fs_dmask; 271 272 perm = *mode_ptr & ~(S_IFMT | mask); 273 274 /* 275 * Of the r and x bits, all (subject to umask) must be present. Of the 276 * w bits, either all (subject to umask) or none must be present. 277 */ 278 if ((perm & (S_IRUGO | S_IXUGO)) != (inode->i_mode & (S_IRUGO|S_IXUGO))) 279 return -EPERM; 280 if ((perm & S_IWUGO) && ((perm & S_IWUGO) != (S_IWUGO & ~mask))) 281 return -EPERM; 282 283 *mode_ptr &= S_IFMT | perm; 284 285 return 0; 286 } 287 288 static int fat_allow_set_time(struct msdos_sb_info *sbi, struct inode *inode) 289 { 290 mode_t allow_utime = sbi->options.allow_utime; 291 292 if (current->fsuid != inode->i_uid) { 293 if (in_group_p(inode->i_gid)) 294 allow_utime >>= 3; 295 if (allow_utime & MAY_WRITE) 296 return 1; 297 } 298 299 /* use a default check */ 300 return 0; 301 } 302 303 int fat_setattr(struct dentry *dentry, struct iattr *attr) 304 { 305 struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); 306 struct inode *inode = dentry->d_inode; 307 int error = 0; 308 unsigned int ia_valid; 309 310 /* 311 * Expand the file. Since inode_setattr() updates ->i_size 312 * before calling the ->truncate(), but FAT needs to fill the 313 * hole before it. 314 */ 315 if (attr->ia_valid & ATTR_SIZE) { 316 if (attr->ia_size > inode->i_size) { 317 error = fat_cont_expand(inode, attr->ia_size); 318 if (error || attr->ia_valid == ATTR_SIZE) 319 goto out; 320 attr->ia_valid &= ~ATTR_SIZE; 321 } 322 } 323 324 /* Check for setting the inode time. */ 325 ia_valid = attr->ia_valid; 326 if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET)) { 327 if (fat_allow_set_time(sbi, inode)) 328 attr->ia_valid &= ~(ATTR_MTIME_SET | ATTR_ATIME_SET); 329 } 330 331 error = inode_change_ok(inode, attr); 332 attr->ia_valid = ia_valid; 333 if (error) { 334 if (sbi->options.quiet) 335 error = 0; 336 goto out; 337 } 338 339 if (((attr->ia_valid & ATTR_UID) && 340 (attr->ia_uid != sbi->options.fs_uid)) || 341 ((attr->ia_valid & ATTR_GID) && 342 (attr->ia_gid != sbi->options.fs_gid)) || 343 ((attr->ia_valid & ATTR_MODE) && 344 (attr->ia_mode & ~MSDOS_VALID_MODE))) 345 error = -EPERM; 346 347 if (error) { 348 if (sbi->options.quiet) 349 error = 0; 350 goto out; 351 } 352 353 /* 354 * We don't return -EPERM here. Yes, strange, but this is too 355 * old behavior. 356 */ 357 if (attr->ia_valid & ATTR_MODE) { 358 if (fat_sanitize_mode(sbi, inode, &attr->ia_mode) < 0) 359 attr->ia_valid &= ~ATTR_MODE; 360 } 361 362 error = inode_setattr(inode, attr); 363 out: 364 return error; 365 } 366 EXPORT_SYMBOL_GPL(fat_setattr); 367 368 const struct inode_operations fat_file_inode_operations = { 369 .truncate = fat_truncate, 370 .setattr = fat_setattr, 371 .getattr = fat_getattr, 372 }; 373