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