diff options
Diffstat (limited to 'fs/fat/file.c')
| -rw-r--r-- | fs/fat/file.c | 50 |
1 files changed, 23 insertions, 27 deletions
diff --git a/fs/fat/file.c b/fs/fat/file.c index e99c5a73b39e..88aa1ae13f9f 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c | |||
| @@ -210,10 +210,30 @@ static int fat_free(struct inode *inode, int skip) | |||
| 210 | if (MSDOS_I(inode)->i_start == 0) | 210 | if (MSDOS_I(inode)->i_start == 0) |
| 211 | return 0; | 211 | return 0; |
| 212 | 212 | ||
| 213 | /* | 213 | fat_cache_inval_inode(inode); |
| 214 | * Write a new EOF, and get the remaining cluster chain for freeing. | 214 | |
| 215 | */ | ||
| 216 | wait = IS_DIRSYNC(inode); | 215 | wait = IS_DIRSYNC(inode); |
| 216 | i_start = free_start = MSDOS_I(inode)->i_start; | ||
| 217 | i_logstart = MSDOS_I(inode)->i_logstart; | ||
| 218 | |||
| 219 | /* First, we write the new file size. */ | ||
| 220 | if (!skip) { | ||
| 221 | MSDOS_I(inode)->i_start = 0; | ||
| 222 | MSDOS_I(inode)->i_logstart = 0; | ||
| 223 | } | ||
| 224 | MSDOS_I(inode)->i_attrs |= ATTR_ARCH; | ||
| 225 | inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; | ||
| 226 | if (wait) { | ||
| 227 | err = fat_sync_inode(inode); | ||
| 228 | if (err) { | ||
| 229 | MSDOS_I(inode)->i_start = i_start; | ||
| 230 | MSDOS_I(inode)->i_logstart = i_logstart; | ||
| 231 | return err; | ||
| 232 | } | ||
| 233 | } else | ||
| 234 | mark_inode_dirty(inode); | ||
| 235 | |||
| 236 | /* Write a new EOF, and get the remaining cluster chain for freeing. */ | ||
| 217 | if (skip) { | 237 | if (skip) { |
| 218 | struct fat_entry fatent; | 238 | struct fat_entry fatent; |
| 219 | int ret, fclus, dclus; | 239 | int ret, fclus, dclus; |
| @@ -244,35 +264,11 @@ static int fat_free(struct inode *inode, int skip) | |||
| 244 | return ret; | 264 | return ret; |
| 245 | 265 | ||
| 246 | free_start = ret; | 266 | free_start = ret; |
| 247 | i_start = i_logstart = 0; | ||
| 248 | fat_cache_inval_inode(inode); | ||
| 249 | } else { | ||
| 250 | fat_cache_inval_inode(inode); | ||
| 251 | |||
| 252 | i_start = free_start = MSDOS_I(inode)->i_start; | ||
| 253 | i_logstart = MSDOS_I(inode)->i_logstart; | ||
| 254 | MSDOS_I(inode)->i_start = 0; | ||
| 255 | MSDOS_I(inode)->i_logstart = 0; | ||
| 256 | } | 267 | } |
| 257 | MSDOS_I(inode)->i_attrs |= ATTR_ARCH; | ||
| 258 | inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; | ||
| 259 | if (wait) { | ||
| 260 | err = fat_sync_inode(inode); | ||
| 261 | if (err) | ||
| 262 | goto error; | ||
| 263 | } else | ||
| 264 | mark_inode_dirty(inode); | ||
| 265 | inode->i_blocks = skip << (MSDOS_SB(sb)->cluster_bits - 9); | 268 | inode->i_blocks = skip << (MSDOS_SB(sb)->cluster_bits - 9); |
| 266 | 269 | ||
| 267 | /* Freeing the remained cluster chain */ | 270 | /* Freeing the remained cluster chain */ |
| 268 | return fat_free_clusters(inode, free_start); | 271 | return fat_free_clusters(inode, free_start); |
| 269 | |||
| 270 | error: | ||
| 271 | if (i_start) { | ||
| 272 | MSDOS_I(inode)->i_start = i_start; | ||
| 273 | MSDOS_I(inode)->i_logstart = i_logstart; | ||
| 274 | } | ||
| 275 | return err; | ||
| 276 | } | 272 | } |
| 277 | 273 | ||
| 278 | void fat_truncate(struct inode *inode) | 274 | void fat_truncate(struct inode *inode) |
