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/blkdev.h> 17 18 int fat_generic_ioctl(struct inode *inode, struct file *filp, 19 unsigned int cmd, unsigned long arg) 20 { 21 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); 22 u32 __user *user_attr = (u32 __user *)arg; 23 24 switch (cmd) { 25 case FAT_IOCTL_GET_ATTRIBUTES: 26 { 27 u32 attr; 28 29 if (inode->i_ino == MSDOS_ROOT_INO) 30 attr = ATTR_DIR; 31 else 32 attr = fat_attr(inode); 33 34 return put_user(attr, user_attr); 35 } 36 case FAT_IOCTL_SET_ATTRIBUTES: 37 { 38 u32 attr, oldattr; 39 int err, is_dir = S_ISDIR(inode->i_mode); 40 struct iattr ia; 41 42 err = get_user(attr, user_attr); 43 if (err) 44 return err; 45 46 mutex_lock(&inode->i_mutex); 47 48 if (IS_RDONLY(inode)) { 49 err = -EROFS; 50 goto up; 51 } 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_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 mutex_unlock(&inode->i_mutex); 109 return err; 110 } 111 default: 112 return -ENOTTY; /* Inappropriate ioctl for device */ 113 } 114 } 115 116 static int fat_file_release(struct inode *inode, struct file *filp) 117 { 118 if ((filp->f_mode & FMODE_WRITE) && 119 MSDOS_SB(inode->i_sb)->options.flush) { 120 fat_flush_inodes(inode->i_sb, inode, NULL); 121 blk_congestion_wait(WRITE, HZ/10); 122 } 123 return 0; 124 } 125 126 const struct file_operations fat_file_operations = { 127 .llseek = generic_file_llseek, 128 .read = do_sync_read, 129 .write = do_sync_write, 130 .aio_read = generic_file_aio_read, 131 .aio_write = generic_file_aio_write, 132 .mmap = generic_file_mmap, 133 .release = fat_file_release, 134 .ioctl = fat_generic_ioctl, 135 .fsync = file_fsync, 136 .sendfile = generic_file_sendfile, 137 }; 138 139 static int fat_cont_expand(struct inode *inode, loff_t size) 140 { 141 struct address_space *mapping = inode->i_mapping; 142 loff_t start = inode->i_size, count = size - inode->i_size; 143 int err; 144 145 err = generic_cont_expand_simple(inode, size); 146 if (err) 147 goto out; 148 149 inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; 150 mark_inode_dirty(inode); 151 if (IS_SYNC(inode)) 152 err = sync_page_range_nolock(inode, mapping, start, count); 153 out: 154 return err; 155 } 156 157 int fat_notify_change(struct dentry *dentry, struct iattr *attr) 158 { 159 struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); 160 struct inode *inode = dentry->d_inode; 161 int mask, error = 0; 162 163 lock_kernel(); 164 165 /* 166 * Expand the file. Since inode_setattr() updates ->i_size 167 * before calling the ->truncate(), but FAT needs to fill the 168 * hole before it. 169 */ 170 if (attr->ia_valid & ATTR_SIZE) { 171 if (attr->ia_size > inode->i_size) { 172 error = fat_cont_expand(inode, attr->ia_size); 173 if (error || attr->ia_valid == ATTR_SIZE) 174 goto out; 175 attr->ia_valid &= ~ATTR_SIZE; 176 } 177 } 178 179 error = inode_change_ok(inode, attr); 180 if (error) { 181 if (sbi->options.quiet) 182 error = 0; 183 goto out; 184 } 185 if (((attr->ia_valid & ATTR_UID) && 186 (attr->ia_uid != sbi->options.fs_uid)) || 187 ((attr->ia_valid & ATTR_GID) && 188 (attr->ia_gid != sbi->options.fs_gid)) || 189 ((attr->ia_valid & ATTR_MODE) && 190 (attr->ia_mode & ~MSDOS_VALID_MODE))) 191 error = -EPERM; 192 193 if (error) { 194 if (sbi->options.quiet) 195 error = 0; 196 goto out; 197 } 198 error = inode_setattr(inode, attr); 199 if (error) 200 goto out; 201 202 if (S_ISDIR(inode->i_mode)) 203 mask = sbi->options.fs_dmask; 204 else 205 mask = sbi->options.fs_fmask; 206 inode->i_mode &= S_IFMT | (S_IRWXUGO & ~mask); 207 out: 208 unlock_kernel(); 209 return error; 210 } 211 212 EXPORT_SYMBOL_GPL(fat_notify_change); 213 214 /* Free all clusters after the skip'th cluster. */ 215 static int fat_free(struct inode *inode, int skip) 216 { 217 struct super_block *sb = inode->i_sb; 218 int err, wait, free_start, i_start, i_logstart; 219 220 if (MSDOS_I(inode)->i_start == 0) 221 return 0; 222 223 fat_cache_inval_inode(inode); 224 225 wait = IS_DIRSYNC(inode); 226 i_start = free_start = MSDOS_I(inode)->i_start; 227 i_logstart = MSDOS_I(inode)->i_logstart; 228 229 /* First, we write the new file size. */ 230 if (!skip) { 231 MSDOS_I(inode)->i_start = 0; 232 MSDOS_I(inode)->i_logstart = 0; 233 } 234 MSDOS_I(inode)->i_attrs |= ATTR_ARCH; 235 inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; 236 if (wait) { 237 err = fat_sync_inode(inode); 238 if (err) { 239 MSDOS_I(inode)->i_start = i_start; 240 MSDOS_I(inode)->i_logstart = i_logstart; 241 return err; 242 } 243 } else 244 mark_inode_dirty(inode); 245 246 /* Write a new EOF, and get the remaining cluster chain for freeing. */ 247 if (skip) { 248 struct fat_entry fatent; 249 int ret, fclus, dclus; 250 251 ret = fat_get_cluster(inode, skip - 1, &fclus, &dclus); 252 if (ret < 0) 253 return ret; 254 else if (ret == FAT_ENT_EOF) 255 return 0; 256 257 fatent_init(&fatent); 258 ret = fat_ent_read(inode, &fatent, dclus); 259 if (ret == FAT_ENT_EOF) { 260 fatent_brelse(&fatent); 261 return 0; 262 } else if (ret == FAT_ENT_FREE) { 263 fat_fs_panic(sb, 264 "%s: invalid cluster chain (i_pos %lld)", 265 __FUNCTION__, MSDOS_I(inode)->i_pos); 266 ret = -EIO; 267 } else if (ret > 0) { 268 err = fat_ent_write(inode, &fatent, FAT_ENT_EOF, wait); 269 if (err) 270 ret = err; 271 } 272 fatent_brelse(&fatent); 273 if (ret < 0) 274 return ret; 275 276 free_start = ret; 277 } 278 inode->i_blocks = skip << (MSDOS_SB(sb)->cluster_bits - 9); 279 280 /* Freeing the remained cluster chain */ 281 return fat_free_clusters(inode, free_start); 282 } 283 284 void fat_truncate(struct inode *inode) 285 { 286 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); 287 const unsigned int cluster_size = sbi->cluster_size; 288 int nr_clusters; 289 290 /* 291 * This protects against truncating a file bigger than it was then 292 * trying to write into the hole. 293 */ 294 if (MSDOS_I(inode)->mmu_private > inode->i_size) 295 MSDOS_I(inode)->mmu_private = inode->i_size; 296 297 nr_clusters = (inode->i_size + (cluster_size - 1)) >> sbi->cluster_bits; 298 299 lock_kernel(); 300 fat_free(inode, nr_clusters); 301 unlock_kernel(); 302 fat_flush_inodes(inode->i_sb, inode, NULL); 303 } 304 305 struct inode_operations fat_file_inode_operations = { 306 .truncate = fat_truncate, 307 .setattr = fat_notify_change, 308 }; 309