aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysv/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/sysv/dir.c')
-rw-r--r--fs/sysv/dir.c50
1 files changed, 30 insertions, 20 deletions
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c
index e566b387fcf9..56f655254bfe 100644
--- a/fs/sysv/dir.c
+++ b/fs/sysv/dir.c
@@ -16,6 +16,7 @@
16#include <linux/pagemap.h> 16#include <linux/pagemap.h>
17#include <linux/highmem.h> 17#include <linux/highmem.h>
18#include <linux/smp_lock.h> 18#include <linux/smp_lock.h>
19#include <linux/swap.h>
19#include "sysv.h" 20#include "sysv.h"
20 21
21static int sysv_readdir(struct file *, void *, filldir_t); 22static int sysv_readdir(struct file *, void *, filldir_t);
@@ -37,12 +38,17 @@ static inline unsigned long dir_pages(struct inode *inode)
37 return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT; 38 return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT;
38} 39}
39 40
40static int dir_commit_chunk(struct page *page, unsigned from, unsigned to) 41static int dir_commit_chunk(struct page *page, loff_t pos, unsigned len)
41{ 42{
42 struct inode *dir = (struct inode *)page->mapping->host; 43 struct address_space *mapping = page->mapping;
44 struct inode *dir = mapping->host;
43 int err = 0; 45 int err = 0;
44 46
45 page->mapping->a_ops->commit_write(NULL, page, from, to); 47 block_write_end(NULL, mapping, pos, len, len, page, NULL);
48 if (pos+len > dir->i_size) {
49 i_size_write(dir, pos+len);
50 mark_inode_dirty(dir);
51 }
46 if (IS_DIRSYNC(dir)) 52 if (IS_DIRSYNC(dir))
47 err = write_one_page(page, 1); 53 err = write_one_page(page, 1);
48 else 54 else
@@ -186,7 +192,7 @@ int sysv_add_link(struct dentry *dentry, struct inode *inode)
186 unsigned long npages = dir_pages(dir); 192 unsigned long npages = dir_pages(dir);
187 unsigned long n; 193 unsigned long n;
188 char *kaddr; 194 char *kaddr;
189 unsigned from, to; 195 loff_t pos;
190 int err; 196 int err;
191 197
192 /* We take care of directory expansion in the same loop */ 198 /* We take care of directory expansion in the same loop */
@@ -212,16 +218,17 @@ int sysv_add_link(struct dentry *dentry, struct inode *inode)
212 return -EINVAL; 218 return -EINVAL;
213 219
214got_it: 220got_it:
215 from = (char*)de - (char*)page_address(page); 221 pos = page_offset(page) +
216 to = from + SYSV_DIRSIZE; 222 (char*)de - (char*)page_address(page);
217 lock_page(page); 223 lock_page(page);
218 err = page->mapping->a_ops->prepare_write(NULL, page, from, to); 224 err = __sysv_write_begin(NULL, page->mapping, pos, SYSV_DIRSIZE,
225 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
219 if (err) 226 if (err)
220 goto out_unlock; 227 goto out_unlock;
221 memcpy (de->name, name, namelen); 228 memcpy (de->name, name, namelen);
222 memset (de->name + namelen, 0, SYSV_DIRSIZE - namelen - 2); 229 memset (de->name + namelen, 0, SYSV_DIRSIZE - namelen - 2);
223 de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); 230 de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
224 err = dir_commit_chunk(page, from, to); 231 err = dir_commit_chunk(page, pos, SYSV_DIRSIZE);
225 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; 232 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
226 mark_inode_dirty(dir); 233 mark_inode_dirty(dir);
227out_page: 234out_page:
@@ -238,15 +245,15 @@ int sysv_delete_entry(struct sysv_dir_entry *de, struct page *page)
238 struct address_space *mapping = page->mapping; 245 struct address_space *mapping = page->mapping;
239 struct inode *inode = (struct inode*)mapping->host; 246 struct inode *inode = (struct inode*)mapping->host;
240 char *kaddr = (char*)page_address(page); 247 char *kaddr = (char*)page_address(page);
241 unsigned from = (char*)de - kaddr; 248 loff_t pos = page_offset(page) + (char *)de - kaddr;
242 unsigned to = from + SYSV_DIRSIZE;
243 int err; 249 int err;
244 250
245 lock_page(page); 251 lock_page(page);
246 err = mapping->a_ops->prepare_write(NULL, page, from, to); 252 err = __sysv_write_begin(NULL, mapping, pos, SYSV_DIRSIZE,
253 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
247 BUG_ON(err); 254 BUG_ON(err);
248 de->inode = 0; 255 de->inode = 0;
249 err = dir_commit_chunk(page, from, to); 256 err = dir_commit_chunk(page, pos, SYSV_DIRSIZE);
250 dir_put_page(page); 257 dir_put_page(page);
251 inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; 258 inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
252 mark_inode_dirty(inode); 259 mark_inode_dirty(inode);
@@ -263,12 +270,13 @@ int sysv_make_empty(struct inode *inode, struct inode *dir)
263 270
264 if (!page) 271 if (!page)
265 return -ENOMEM; 272 return -ENOMEM;
266 kmap(page); 273 err = __sysv_write_begin(NULL, mapping, 0, 2 * SYSV_DIRSIZE,
267 err = mapping->a_ops->prepare_write(NULL, page, 0, 2 * SYSV_DIRSIZE); 274 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
268 if (err) { 275 if (err) {
269 unlock_page(page); 276 unlock_page(page);
270 goto fail; 277 goto fail;
271 } 278 }
279 kmap(page);
272 280
273 base = (char*)page_address(page); 281 base = (char*)page_address(page);
274 memset(base, 0, PAGE_CACHE_SIZE); 282 memset(base, 0, PAGE_CACHE_SIZE);
@@ -280,9 +288,9 @@ int sysv_make_empty(struct inode *inode, struct inode *dir)
280 de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), dir->i_ino); 288 de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), dir->i_ino);
281 strcpy(de->name,".."); 289 strcpy(de->name,"..");
282 290
291 kunmap(page);
283 err = dir_commit_chunk(page, 0, 2 * SYSV_DIRSIZE); 292 err = dir_commit_chunk(page, 0, 2 * SYSV_DIRSIZE);
284fail: 293fail:
285 kunmap(page);
286 page_cache_release(page); 294 page_cache_release(page);
287 return err; 295 return err;
288} 296}
@@ -336,16 +344,18 @@ not_empty:
336void sysv_set_link(struct sysv_dir_entry *de, struct page *page, 344void sysv_set_link(struct sysv_dir_entry *de, struct page *page,
337 struct inode *inode) 345 struct inode *inode)
338{ 346{
339 struct inode *dir = (struct inode*)page->mapping->host; 347 struct address_space *mapping = page->mapping;
340 unsigned from = (char *)de-(char*)page_address(page); 348 struct inode *dir = mapping->host;
341 unsigned to = from + SYSV_DIRSIZE; 349 loff_t pos = page_offset(page) +
350 (char *)de-(char*)page_address(page);
342 int err; 351 int err;
343 352
344 lock_page(page); 353 lock_page(page);
345 err = page->mapping->a_ops->prepare_write(NULL, page, from, to); 354 err = __sysv_write_begin(NULL, mapping, pos, SYSV_DIRSIZE,
355 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
346 BUG_ON(err); 356 BUG_ON(err);
347 de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); 357 de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
348 err = dir_commit_chunk(page, from, to); 358 err = dir_commit_chunk(page, pos, SYSV_DIRSIZE);
349 dir_put_page(page); 359 dir_put_page(page);
350 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; 360 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
351 mark_inode_dirty(dir); 361 mark_inode_dirty(dir);