Blame view
fs/fat/file.c
13.1 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 |
/* * linux/fs/fat/file.c * * Written 1992,1993 by Werner Almesberger * * regular file handling primitives for fat-based filesystems */ |
16f7e0fe2 [PATCH] capable/c... |
8 |
#include <linux/capability.h> |
1da177e4c Linux-2.6.12-rc2 |
9 |
#include <linux/module.h> |
7845bc3e1 fat: convert to u... |
10 |
#include <linux/compat.h> |
42a74f206 [PATCH] r/o bind ... |
11 |
#include <linux/mount.h> |
ae78bf9c4 [PATCH] add -o fl... |
12 |
#include <linux/blkdev.h> |
66114cad6 writeback: separa... |
13 |
#include <linux/backing-dev.h> |
b1da47e29 [patch 3/4] fat: ... |
14 15 |
#include <linux/fsnotify.h> #include <linux/security.h> |
b13bb33ea fat: add fat_fall... |
16 |
#include <linux/falloc.h> |
9e975dae2 fat: split includ... |
17 |
#include "fat.h" |
1da177e4c Linux-2.6.12-rc2 |
18 |
|
b13bb33ea fat: add fat_fall... |
19 20 |
static long fat_fallocate(struct file *file, int mode, loff_t offset, loff_t len); |
21bea4959 fat: split fat_ge... |
21 22 23 |
static int fat_ioctl_get_attributes(struct inode *inode, u32 __user *user_attr) { u32 attr; |
5955102c9 wrappers for ->i_... |
24 |
inode_lock(inode); |
21bea4959 fat: split fat_ge... |
25 |
attr = fat_make_attrs(inode); |
5955102c9 wrappers for ->i_... |
26 |
inode_unlock(inode); |
21bea4959 fat: split fat_ge... |
27 28 29 30 31 |
return put_user(attr, user_attr); } static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr) |
1da177e4c Linux-2.6.12-rc2 |
32 |
{ |
496ad9aa8 new helper: file_... |
33 |
struct inode *inode = file_inode(file); |
1da177e4c Linux-2.6.12-rc2 |
34 |
struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); |
21bea4959 fat: split fat_ge... |
35 36 37 38 |
int is_dir = S_ISDIR(inode->i_mode); u32 attr, oldattr; struct iattr ia; int err; |
1da177e4c Linux-2.6.12-rc2 |
39 |
|
21bea4959 fat: split fat_ge... |
40 41 42 |
err = get_user(attr, user_attr); if (err) goto out; |
1da177e4c Linux-2.6.12-rc2 |
43 |
|
a561be710 switch a bunch of... |
44 |
err = mnt_want_write_file(file); |
21bea4959 fat: split fat_ge... |
45 |
if (err) |
e24f17da3 fat: Push mnt_wan... |
46 |
goto out; |
5955102c9 wrappers for ->i_... |
47 |
inode_lock(inode); |
21bea4959 fat: split fat_ge... |
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
/* * ATTR_VOLUME and ATTR_DIR cannot be changed; this also * prevents the user from turning us into a VFAT * longname entry. Also, we obviously can't set * any of the NTFS attributes in the high 24 bits. */ attr &= 0xff & ~(ATTR_VOLUME | ATTR_DIR); /* Merge in ATTR_VOLUME and ATTR_DIR */ attr |= (MSDOS_I(inode)->i_attrs & ATTR_VOLUME) | (is_dir ? ATTR_DIR : 0); oldattr = fat_make_attrs(inode); /* Equivalent to a chmod() */ ia.ia_valid = ATTR_MODE | ATTR_CTIME; |
c2050a454 fs: Replace curre... |
63 |
ia.ia_ctime = current_time(inode); |
21bea4959 fat: split fat_ge... |
64 65 66 67 68 69 |
if (is_dir) ia.ia_mode = fat_make_mode(sbi, attr, S_IRWXUGO); else { ia.ia_mode = fat_make_mode(sbi, attr, S_IRUGO | S_IWUGO | (inode->i_mode & S_IXUGO)); } |
1da177e4c Linux-2.6.12-rc2 |
70 |
|
21bea4959 fat: split fat_ge... |
71 72 73 |
/* The root directory has no attributes */ if (inode->i_ino == MSDOS_ROOT_INO && attr != ATTR_DIR) { err = -EINVAL; |
e24f17da3 fat: Push mnt_wan... |
74 |
goto out_unlock_inode; |
1da177e4c Linux-2.6.12-rc2 |
75 |
} |
1da177e4c Linux-2.6.12-rc2 |
76 |
|
21bea4959 fat: split fat_ge... |
77 78 79 80 |
if (sbi->options.sys_immutable && ((attr | oldattr) & ATTR_SYS) && !capable(CAP_LINUX_IMMUTABLE)) { err = -EPERM; |
e24f17da3 fat: Push mnt_wan... |
81 |
goto out_unlock_inode; |
21bea4959 fat: split fat_ge... |
82 |
} |
1da177e4c Linux-2.6.12-rc2 |
83 |
|
21bea4959 fat: split fat_ge... |
84 85 86 87 88 89 90 |
/* * The security check is questionable... We single * out the RO attribute for checking by the security * module, just because it maps to a file mode. */ err = security_inode_setattr(file->f_path.dentry, &ia); if (err) |
e24f17da3 fat: Push mnt_wan... |
91 |
goto out_unlock_inode; |
1da177e4c Linux-2.6.12-rc2 |
92 |
|
21bea4959 fat: split fat_ge... |
93 94 95 |
/* This MUST be done before doing anything irreversible... */ err = fat_setattr(file->f_path.dentry, &ia); if (err) |
e24f17da3 fat: Push mnt_wan... |
96 |
goto out_unlock_inode; |
21bea4959 fat: split fat_ge... |
97 98 99 100 101 102 |
fsnotify_change(file->f_path.dentry, ia.ia_valid); if (sbi->options.sys_immutable) { if (attr & ATTR_SYS) inode->i_flags |= S_IMMUTABLE; else |
1adffbae2 fat: Fix corrupt ... |
103 |
inode->i_flags &= ~S_IMMUTABLE; |
21bea4959 fat: split fat_ge... |
104 |
} |
1da177e4c Linux-2.6.12-rc2 |
105 |
|
21bea4959 fat: split fat_ge... |
106 107 |
fat_save_attrs(inode, attr); mark_inode_dirty(inode); |
21bea4959 fat: split fat_ge... |
108 |
out_unlock_inode: |
5955102c9 wrappers for ->i_... |
109 |
inode_unlock(inode); |
e24f17da3 fat: Push mnt_wan... |
110 |
mnt_drop_write_file(file); |
21bea4959 fat: split fat_ge... |
111 112 113 |
out: return err; } |
1da177e4c Linux-2.6.12-rc2 |
114 |
|
6e5b93ee5 fatfs: add FAT_IO... |
115 116 117 118 119 |
static int fat_ioctl_get_volume_id(struct inode *inode, u32 __user *user_attr) { struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); return put_user(sbi->vol_id, user_attr); } |
7845bc3e1 fat: convert to u... |
120 |
long fat_generic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
1da177e4c Linux-2.6.12-rc2 |
121 |
{ |
496ad9aa8 new helper: file_... |
122 |
struct inode *inode = file_inode(filp); |
1da177e4c Linux-2.6.12-rc2 |
123 |
u32 __user *user_attr = (u32 __user *)arg; |
1da177e4c Linux-2.6.12-rc2 |
124 |
|
1da177e4c Linux-2.6.12-rc2 |
125 126 |
switch (cmd) { case FAT_IOCTL_GET_ATTRIBUTES: |
21bea4959 fat: split fat_ge... |
127 |
return fat_ioctl_get_attributes(inode, user_attr); |
1da177e4c Linux-2.6.12-rc2 |
128 |
case FAT_IOCTL_SET_ATTRIBUTES: |
21bea4959 fat: split fat_ge... |
129 |
return fat_ioctl_set_attributes(filp, user_attr); |
6e5b93ee5 fatfs: add FAT_IO... |
130 131 |
case FAT_IOCTL_GET_VOLUME_ID: return fat_ioctl_get_volume_id(inode, user_attr); |
1da177e4c Linux-2.6.12-rc2 |
132 133 134 135 |
default: return -ENOTTY; /* Inappropriate ioctl for device */ } } |
7845bc3e1 fat: convert to u... |
136 137 138 139 140 141 142 143 |
#ifdef CONFIG_COMPAT static long fat_generic_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { return fat_generic_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); } #endif |
ae78bf9c4 [PATCH] add -o fl... |
144 145 146 147 148 |
static int fat_file_release(struct inode *inode, struct file *filp) { if ((filp->f_mode & FMODE_WRITE) && MSDOS_SB(inode->i_sb)->options.flush) { fat_flush_inodes(inode->i_sb, inode, NULL); |
8aa7e847d Fix congestion_wa... |
149 |
congestion_wait(BLK_RW_ASYNC, HZ/10); |
ae78bf9c4 [PATCH] add -o fl... |
150 151 152 |
} return 0; } |
02c24a821 fs: push i_mutex ... |
153 |
int fat_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync) |
b522412ae Sanitize ->fsync(... |
154 |
{ |
7ea808591 drop unused dentr... |
155 |
struct inode *inode = filp->f_mapping->host; |
b522412ae Sanitize ->fsync(... |
156 |
int res, err; |
02c24a821 fs: push i_mutex ... |
157 |
res = generic_file_fsync(filp, start, end, datasync); |
b522412ae Sanitize ->fsync(... |
158 159 160 161 |
err = sync_mapping_buffers(MSDOS_SB(inode->i_sb)->fat_inode->i_mapping); return res ? res : err; } |
4b6f5d20b [PATCH] Make most... |
162 |
const struct file_operations fat_file_operations = { |
1da177e4c Linux-2.6.12-rc2 |
163 |
.llseek = generic_file_llseek, |
aad4f8bb4 switch simple gen... |
164 |
.read_iter = generic_file_read_iter, |
8174202b3 write_iter varian... |
165 |
.write_iter = generic_file_write_iter, |
1da177e4c Linux-2.6.12-rc2 |
166 |
.mmap = generic_file_mmap, |
ae78bf9c4 [PATCH] add -o fl... |
167 |
.release = fat_file_release, |
7845bc3e1 fat: convert to u... |
168 169 170 171 |
.unlocked_ioctl = fat_generic_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = fat_generic_compat_ioctl, #endif |
b522412ae Sanitize ->fsync(... |
172 |
.fsync = fat_file_fsync, |
5ffc4ef45 sendfile: remove ... |
173 |
.splice_read = generic_file_splice_read, |
b13bb33ea fat: add fat_fall... |
174 |
.fallocate = fat_fallocate, |
1da177e4c Linux-2.6.12-rc2 |
175 |
}; |
05eb0b51f [PATCH] fat: supp... |
176 177 178 179 180 181 182 183 184 |
static int fat_cont_expand(struct inode *inode, loff_t size) { struct address_space *mapping = inode->i_mapping; loff_t start = inode->i_size, count = size - inode->i_size; int err; err = generic_cont_expand_simple(inode, size); if (err) goto out; |
02027d42c fs: Replace CURRE... |
185 |
inode->i_ctime = inode->i_mtime = current_time(inode); |
05eb0b51f [PATCH] fat: supp... |
186 |
mark_inode_dirty(inode); |
2f3d675bc fat: Opencode syn... |
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
if (IS_SYNC(inode)) { int err2; /* * Opencode syncing since we don't have a file open to use * standard fsync path. */ err = filemap_fdatawrite_range(mapping, start, start + count - 1); err2 = sync_mapping_buffers(mapping); if (!err) err = err2; err2 = write_inode_now(inode, 1); if (!err) err = err2; if (!err) { err = filemap_fdatawait_range(mapping, start, start + count - 1); } } |
05eb0b51f [PATCH] fat: supp... |
207 208 209 |
out: return err; } |
b13bb33ea fat: add fat_fall... |
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
/* * Preallocate space for a file. This implements fat's fallocate file * operation, which gets called from sys_fallocate system call. User * space requests len bytes at offset. If FALLOC_FL_KEEP_SIZE is set * we just allocate clusters without zeroing them out. Otherwise we * allocate and zero out clusters via an expanding truncate. */ static long fat_fallocate(struct file *file, int mode, loff_t offset, loff_t len) { int nr_cluster; /* Number of clusters to be allocated */ loff_t mm_bytes; /* Number of bytes to be allocated for file */ loff_t ondisksize; /* block aligned on-disk size in bytes*/ struct inode *inode = file->f_mapping->host; struct super_block *sb = inode->i_sb; struct msdos_sb_info *sbi = MSDOS_SB(sb); int err = 0; /* No support for hole punch or other fallocate flags. */ if (mode & ~FALLOC_FL_KEEP_SIZE) return -EOPNOTSUPP; /* No support for dir */ if (!S_ISREG(inode->i_mode)) return -EOPNOTSUPP; |
5955102c9 wrappers for ->i_... |
235 |
inode_lock(inode); |
b13bb33ea fat: add fat_fall... |
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 |
if (mode & FALLOC_FL_KEEP_SIZE) { ondisksize = inode->i_blocks << 9; if ((offset + len) <= ondisksize) goto error; /* First compute the number of clusters to be allocated */ mm_bytes = offset + len - ondisksize; nr_cluster = (mm_bytes + (sbi->cluster_size - 1)) >> sbi->cluster_bits; /* Start the allocation.We are not zeroing out the clusters */ while (nr_cluster-- > 0) { err = fat_add_cluster(inode); if (err) goto error; } } else { if ((offset + len) <= i_size_read(inode)) goto error; /* This is just an expanding truncate */ err = fat_cont_expand(inode, (offset + len)); } error: |
5955102c9 wrappers for ->i_... |
261 |
inode_unlock(inode); |
b13bb33ea fat: add fat_fall... |
262 263 |
return err; } |
1da177e4c Linux-2.6.12-rc2 |
264 265 266 267 268 269 270 271 |
/* Free all clusters after the skip'th cluster. */ static int fat_free(struct inode *inode, int skip) { struct super_block *sb = inode->i_sb; int err, wait, free_start, i_start, i_logstart; if (MSDOS_I(inode)->i_start == 0) return 0; |
3b641407a [PATCH] fat: Fix ... |
272 |
fat_cache_inval_inode(inode); |
1da177e4c Linux-2.6.12-rc2 |
273 |
wait = IS_DIRSYNC(inode); |
3b641407a [PATCH] fat: Fix ... |
274 275 276 277 278 279 280 281 282 |
i_start = free_start = MSDOS_I(inode)->i_start; i_logstart = MSDOS_I(inode)->i_logstart; /* First, we write the new file size. */ if (!skip) { MSDOS_I(inode)->i_start = 0; MSDOS_I(inode)->i_logstart = 0; } MSDOS_I(inode)->i_attrs |= ATTR_ARCH; |
02027d42c fs: Replace CURRE... |
283 |
inode->i_ctime = inode->i_mtime = current_time(inode); |
3b641407a [PATCH] fat: Fix ... |
284 285 286 287 288 289 290 291 292 293 294 |
if (wait) { err = fat_sync_inode(inode); if (err) { MSDOS_I(inode)->i_start = i_start; MSDOS_I(inode)->i_logstart = i_logstart; return err; } } else mark_inode_dirty(inode); /* Write a new EOF, and get the remaining cluster chain for freeing. */ |
1da177e4c Linux-2.6.12-rc2 |
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
if (skip) { struct fat_entry fatent; int ret, fclus, dclus; ret = fat_get_cluster(inode, skip - 1, &fclus, &dclus); if (ret < 0) return ret; else if (ret == FAT_ENT_EOF) return 0; fatent_init(&fatent); ret = fat_ent_read(inode, &fatent, dclus); if (ret == FAT_ENT_EOF) { fatent_brelse(&fatent); return 0; } else if (ret == FAT_ENT_FREE) { |
85c785919 FAT: add 'errors'... |
311 |
fat_fs_error(sb, |
1da177e4c Linux-2.6.12-rc2 |
312 |
"%s: invalid cluster chain (i_pos %lld)", |
8e24eea72 fs: replace remai... |
313 |
__func__, MSDOS_I(inode)->i_pos); |
1da177e4c Linux-2.6.12-rc2 |
314 315 316 317 318 319 320 321 322 323 324 |
ret = -EIO; } else if (ret > 0) { err = fat_ent_write(inode, &fatent, FAT_ENT_EOF, wait); if (err) ret = err; } fatent_brelse(&fatent); if (ret < 0) return ret; free_start = ret; |
1da177e4c Linux-2.6.12-rc2 |
325 |
} |
1da177e4c Linux-2.6.12-rc2 |
326 327 328 329 |
inode->i_blocks = skip << (MSDOS_SB(sb)->cluster_bits - 9); /* Freeing the remained cluster chain */ return fat_free_clusters(inode, free_start); |
1da177e4c Linux-2.6.12-rc2 |
330 |
} |
459f6ed3b fat: convert to u... |
331 |
void fat_truncate_blocks(struct inode *inode, loff_t offset) |
1da177e4c Linux-2.6.12-rc2 |
332 |
{ |
9c20616c3 Make FAT users ha... |
333 |
struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
334 335 336 337 338 339 340 |
const unsigned int cluster_size = sbi->cluster_size; int nr_clusters; /* * This protects against truncating a file bigger than it was then * trying to write into the hole. */ |
459f6ed3b fat: convert to u... |
341 342 |
if (MSDOS_I(inode)->mmu_private > offset) MSDOS_I(inode)->mmu_private = offset; |
1da177e4c Linux-2.6.12-rc2 |
343 |
|
459f6ed3b fat: convert to u... |
344 |
nr_clusters = (offset + (cluster_size - 1)) >> sbi->cluster_bits; |
1da177e4c Linux-2.6.12-rc2 |
345 |
|
1da177e4c Linux-2.6.12-rc2 |
346 |
fat_free(inode, nr_clusters); |
ae78bf9c4 [PATCH] add -o fl... |
347 |
fat_flush_inodes(inode->i_sb, inode, NULL); |
1da177e4c Linux-2.6.12-rc2 |
348 |
} |
a528d35e8 statx: Add a syst... |
349 350 |
int fat_getattr(const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags) |
da63fc7ce [PATCH] fat: add ... |
351 |
{ |
a528d35e8 statx: Add a syst... |
352 |
struct inode *inode = d_inode(path->dentry); |
da63fc7ce [PATCH] fat: add ... |
353 354 |
generic_fillattr(inode, stat); stat->blksize = MSDOS_SB(inode->i_sb)->cluster_size; |
ea3983ace fat: restructure ... |
355 356 357 358 359 |
if (MSDOS_SB(inode->i_sb)->options.nfs == FAT_NFS_NOSTALE_RO) { /* Use i_pos for ino. This is used as fileid of nfs. */ stat->ino = fat_i_pos_read(MSDOS_SB(inode->i_sb), inode); } |
da63fc7ce [PATCH] fat: add ... |
360 361 362 |
return 0; } EXPORT_SYMBOL_GPL(fat_getattr); |
2d518f84e fat: relax the pe... |
363 364 |
static int fat_sanitize_mode(const struct msdos_sb_info *sbi, struct inode *inode, umode_t *mode_ptr) |
1278fdd34 fat: fat_notify_c... |
365 |
{ |
dacd0e7b3 fat: propagate um... |
366 |
umode_t mask, perm; |
1278fdd34 fat: fat_notify_c... |
367 |
|
2d518f84e fat: relax the pe... |
368 369 |
/* * Note, the basic check is already done by a caller of |
9c0aa1b87 fat: Cleanup FAT ... |
370 |
* (attr->ia_mode & ~FAT_VALID_MODE) |
2d518f84e fat: relax the pe... |
371 372 373 |
*/ if (S_ISREG(inode->i_mode)) |
1278fdd34 fat: fat_notify_c... |
374 375 376 |
mask = sbi->options.fs_fmask; else mask = sbi->options.fs_dmask; |
2d518f84e fat: relax the pe... |
377 |
perm = *mode_ptr & ~(S_IFMT | mask); |
1278fdd34 fat: fat_notify_c... |
378 379 380 |
/* * Of the r and x bits, all (subject to umask) must be present. Of the * w bits, either all (subject to umask) or none must be present. |
dfc209c00 fat: Fix ATTR_RO ... |
381 382 |
* * If fat_mode_can_hold_ro(inode) is false, can't change w bits. |
1278fdd34 fat: fat_notify_c... |
383 |
*/ |
2d518f84e fat: relax the pe... |
384 |
if ((perm & (S_IRUGO | S_IXUGO)) != (inode->i_mode & (S_IRUGO|S_IXUGO))) |
1278fdd34 fat: fat_notify_c... |
385 |
return -EPERM; |
dfc209c00 fat: Fix ATTR_RO ... |
386 387 388 389 390 391 392 |
if (fat_mode_can_hold_ro(inode)) { if ((perm & S_IWUGO) && ((perm & S_IWUGO) != (S_IWUGO & ~mask))) return -EPERM; } else { if ((perm & S_IWUGO) != (S_IWUGO & ~mask)) return -EPERM; } |
1278fdd34 fat: fat_notify_c... |
393 |
|
2d518f84e fat: relax the pe... |
394 |
*mode_ptr &= S_IFMT | perm; |
1278fdd34 fat: fat_notify_c... |
395 396 |
return 0; } |
1ae43f826 fat: Add allow_ut... |
397 398 |
static int fat_allow_set_time(struct msdos_sb_info *sbi, struct inode *inode) { |
dacd0e7b3 fat: propagate um... |
399 |
umode_t allow_utime = sbi->options.allow_utime; |
1ae43f826 fat: Add allow_ut... |
400 |
|
170782eb8 userns: Convert f... |
401 |
if (!uid_eq(current_fsuid(), inode->i_uid)) { |
1ae43f826 fat: Add allow_ut... |
402 403 404 405 406 407 408 409 410 |
if (in_group_p(inode->i_gid)) allow_utime >>= 3; if (allow_utime & MAY_WRITE) return 1; } /* use a default check */ return 0; } |
17263849c fat: Fix allow_ut... |
411 |
#define TIMES_SET_FLAGS (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET) |
9c0aa1b87 fat: Cleanup FAT ... |
412 413 |
/* valid file mode bits */ #define FAT_VALID_MODE (S_IFREG | S_IFDIR | S_IRWXUGO) |
17263849c fat: Fix allow_ut... |
414 |
|
1278fdd34 fat: fat_notify_c... |
415 416 417 |
int fat_setattr(struct dentry *dentry, struct iattr *attr) { struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); |
2b0143b5c VFS: normal files... |
418 |
struct inode *inode = d_inode(dentry); |
1ae43f826 fat: Add allow_ut... |
419 |
unsigned int ia_valid; |
dfc209c00 fat: Fix ATTR_RO ... |
420 |
int error; |
1278fdd34 fat: fat_notify_c... |
421 |
|
1ae43f826 fat: Add allow_ut... |
422 423 |
/* Check for setting the inode time. */ ia_valid = attr->ia_valid; |
17263849c fat: Fix allow_ut... |
424 |
if (ia_valid & TIMES_SET_FLAGS) { |
1ae43f826 fat: Add allow_ut... |
425 |
if (fat_allow_set_time(sbi, inode)) |
17263849c fat: Fix allow_ut... |
426 |
attr->ia_valid &= ~TIMES_SET_FLAGS; |
1ae43f826 fat: Add allow_ut... |
427 |
} |
31051c85b fs: Give dentry t... |
428 |
error = setattr_prepare(dentry, attr); |
1ae43f826 fat: Add allow_ut... |
429 |
attr->ia_valid = ia_valid; |
1278fdd34 fat: fat_notify_c... |
430 431 432 433 434 |
if (error) { if (sbi->options.quiet) error = 0; goto out; } |
2d518f84e fat: relax the pe... |
435 |
|
db78b877f always call inode... |
436 437 438 439 440 441 442 |
/* * Expand the file. Since inode_setattr() updates ->i_size * before calling the ->truncate(), but FAT needs to fill the * hole before it. XXX: this is no longer true with new truncate * sequence. */ if (attr->ia_valid & ATTR_SIZE) { |
562c72aa5 fs: move inode_di... |
443 |
inode_dio_wait(inode); |
db78b877f always call inode... |
444 445 446 447 448 449 450 |
if (attr->ia_size > inode->i_size) { error = fat_cont_expand(inode, attr->ia_size); if (error || attr->ia_valid == ATTR_SIZE) goto out; attr->ia_valid &= ~ATTR_SIZE; } } |
1278fdd34 fat: fat_notify_c... |
451 |
if (((attr->ia_valid & ATTR_UID) && |
170782eb8 userns: Convert f... |
452 |
(!uid_eq(attr->ia_uid, sbi->options.fs_uid))) || |
1278fdd34 fat: fat_notify_c... |
453 |
((attr->ia_valid & ATTR_GID) && |
170782eb8 userns: Convert f... |
454 |
(!gid_eq(attr->ia_gid, sbi->options.fs_gid))) || |
e97e8de38 fat: fat_setattr(... |
455 |
((attr->ia_valid & ATTR_MODE) && |
9c0aa1b87 fat: Cleanup FAT ... |
456 |
(attr->ia_mode & ~FAT_VALID_MODE))) |
1278fdd34 fat: fat_notify_c... |
457 458 459 460 461 462 463 |
error = -EPERM; if (error) { if (sbi->options.quiet) error = 0; goto out; } |
2d518f84e fat: relax the pe... |
464 465 466 467 468 469 470 471 |
/* * We don't return -EPERM here. Yes, strange, but this is too * old behavior. */ if (attr->ia_valid & ATTR_MODE) { if (fat_sanitize_mode(sbi, inode, &attr->ia_mode) < 0) attr->ia_valid &= ~ATTR_MODE; } |
1278fdd34 fat: fat_notify_c... |
472 |
|
459f6ed3b fat: convert to u... |
473 |
if (attr->ia_valid & ATTR_SIZE) { |
c0ef0cc9d fat: fix data pas... |
474 475 476 |
error = fat_block_truncate_page(inode, attr->ia_size); if (error) goto out; |
582686915 fat: remove i_all... |
477 |
down_write(&MSDOS_I(inode)->truncate_lock); |
2c27c65ed check ATTR_SIZE c... |
478 479 |
truncate_setsize(inode, attr->ia_size); fat_truncate_blocks(inode, attr->ia_size); |
582686915 fat: remove i_all... |
480 |
up_write(&MSDOS_I(inode)->truncate_lock); |
459f6ed3b fat: convert to u... |
481 |
} |
6a1a90ad1 rename generic_se... |
482 |
setattr_copy(inode, attr); |
459f6ed3b fat: convert to u... |
483 |
mark_inode_dirty(inode); |
1278fdd34 fat: fat_notify_c... |
484 |
out: |
1278fdd34 fat: fat_notify_c... |
485 486 487 |
return error; } EXPORT_SYMBOL_GPL(fat_setattr); |
754661f14 [PATCH] mark stru... |
488 |
const struct inode_operations fat_file_inode_operations = { |
1278fdd34 fat: fat_notify_c... |
489 |
.setattr = fat_setattr, |
da63fc7ce [PATCH] fat: add ... |
490 |
.getattr = fat_getattr, |
1da177e4c Linux-2.6.12-rc2 |
491 |
}; |