diff options
author | npiggin@suse.de <npiggin@suse.de> | 2010-05-26 11:05:38 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-05-27 22:16:02 -0400 |
commit | 459f6ed3b8c74cedeb64e5a854394c0d40eda9cd (patch) | |
tree | 296049a8ea7aa7ee6753c1fdc0e539739c257301 /fs/fat/inode.c | |
parent | 737f2e93b9724a3554f9d0b248c22cd407313f86 (diff) |
fat: convert to use the new truncate convention.
Cc: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nick Piggin <npiggin@suse.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/fat/inode.c')
-rw-r--r-- | fs/fat/inode.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index ed33904926ee..7bf45aee56d7 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -142,14 +142,29 @@ static int fat_readpages(struct file *file, struct address_space *mapping, | |||
142 | return mpage_readpages(mapping, pages, nr_pages, fat_get_block); | 142 | return mpage_readpages(mapping, pages, nr_pages, fat_get_block); |
143 | } | 143 | } |
144 | 144 | ||
145 | static void fat_write_failed(struct address_space *mapping, loff_t to) | ||
146 | { | ||
147 | struct inode *inode = mapping->host; | ||
148 | |||
149 | if (to > inode->i_size) { | ||
150 | truncate_pagecache(inode, to, inode->i_size); | ||
151 | fat_truncate_blocks(inode, inode->i_size); | ||
152 | } | ||
153 | } | ||
154 | |||
145 | static int fat_write_begin(struct file *file, struct address_space *mapping, | 155 | static int fat_write_begin(struct file *file, struct address_space *mapping, |
146 | loff_t pos, unsigned len, unsigned flags, | 156 | loff_t pos, unsigned len, unsigned flags, |
147 | struct page **pagep, void **fsdata) | 157 | struct page **pagep, void **fsdata) |
148 | { | 158 | { |
159 | int err; | ||
160 | |||
149 | *pagep = NULL; | 161 | *pagep = NULL; |
150 | return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | 162 | err = cont_write_begin_newtrunc(file, mapping, pos, len, flags, |
151 | fat_get_block, | 163 | pagep, fsdata, fat_get_block, |
152 | &MSDOS_I(mapping->host)->mmu_private); | 164 | &MSDOS_I(mapping->host)->mmu_private); |
165 | if (err < 0) | ||
166 | fat_write_failed(mapping, pos + len); | ||
167 | return err; | ||
153 | } | 168 | } |
154 | 169 | ||
155 | static int fat_write_end(struct file *file, struct address_space *mapping, | 170 | static int fat_write_end(struct file *file, struct address_space *mapping, |
@@ -159,6 +174,8 @@ static int fat_write_end(struct file *file, struct address_space *mapping, | |||
159 | struct inode *inode = mapping->host; | 174 | struct inode *inode = mapping->host; |
160 | int err; | 175 | int err; |
161 | err = generic_write_end(file, mapping, pos, len, copied, pagep, fsdata); | 176 | err = generic_write_end(file, mapping, pos, len, copied, pagep, fsdata); |
177 | if (err < len) | ||
178 | fat_write_failed(mapping, pos + len); | ||
162 | if (!(err < 0) && !(MSDOS_I(inode)->i_attrs & ATTR_ARCH)) { | 179 | if (!(err < 0) && !(MSDOS_I(inode)->i_attrs & ATTR_ARCH)) { |
163 | inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; | 180 | inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; |
164 | MSDOS_I(inode)->i_attrs |= ATTR_ARCH; | 181 | MSDOS_I(inode)->i_attrs |= ATTR_ARCH; |
@@ -172,7 +189,9 @@ static ssize_t fat_direct_IO(int rw, struct kiocb *iocb, | |||
172 | loff_t offset, unsigned long nr_segs) | 189 | loff_t offset, unsigned long nr_segs) |
173 | { | 190 | { |
174 | struct file *file = iocb->ki_filp; | 191 | struct file *file = iocb->ki_filp; |
175 | struct inode *inode = file->f_mapping->host; | 192 | struct address_space *mapping = file->f_mapping; |
193 | struct inode *inode = mapping->host; | ||
194 | ssize_t ret; | ||
176 | 195 | ||
177 | if (rw == WRITE) { | 196 | if (rw == WRITE) { |
178 | /* | 197 | /* |
@@ -193,8 +212,12 @@ static ssize_t fat_direct_IO(int rw, struct kiocb *iocb, | |||
193 | * FAT need to use the DIO_LOCKING for avoiding the race | 212 | * FAT need to use the DIO_LOCKING for avoiding the race |
194 | * condition of fat_get_block() and ->truncate(). | 213 | * condition of fat_get_block() and ->truncate(). |
195 | */ | 214 | */ |
196 | return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, | 215 | ret = blockdev_direct_IO_newtrunc(rw, iocb, inode, inode->i_sb->s_bdev, |
197 | offset, nr_segs, fat_get_block, NULL); | 216 | iov, offset, nr_segs, fat_get_block, NULL); |
217 | if (ret < 0 && (rw & WRITE)) | ||
218 | fat_write_failed(mapping, offset + iov_length(iov, nr_segs)); | ||
219 | |||
220 | return ret; | ||
198 | } | 221 | } |
199 | 222 | ||
200 | static sector_t _fat_bmap(struct address_space *mapping, sector_t block) | 223 | static sector_t _fat_bmap(struct address_space *mapping, sector_t block) |
@@ -429,7 +452,7 @@ static void fat_delete_inode(struct inode *inode) | |||
429 | { | 452 | { |
430 | truncate_inode_pages(&inode->i_data, 0); | 453 | truncate_inode_pages(&inode->i_data, 0); |
431 | inode->i_size = 0; | 454 | inode->i_size = 0; |
432 | fat_truncate(inode); | 455 | fat_truncate_blocks(inode, 0); |
433 | clear_inode(inode); | 456 | clear_inode(inode); |
434 | } | 457 | } |
435 | 458 | ||