Cc: [EMAIL PROTECTED] Cc: Linux Filesystems <linux-fsdevel@vger.kernel.org> Signed-off-by: Nick Piggin <[EMAIL PROTECTED]>
fs/sysv/dir.c | 45 +++++++++++++++++++++++++-------------------- fs/sysv/itree.c | 23 +++++++++++++++++++---- 2 files changed, 44 insertions(+), 24 deletions(-) Index: linux-2.6/fs/sysv/itree.c =================================================================== --- linux-2.6.orig/fs/sysv/itree.c +++ linux-2.6/fs/sysv/itree.c @@ -453,23 +453,38 @@ static int sysv_writepage(struct page *p { return block_write_full_page(page,get_block,wbc); } + static int sysv_readpage(struct file *file, struct page *page) { return block_read_full_page(page,get_block); } -static int sysv_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) + +int __sysv_write_begin(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned flags, + struct page **pagep, void **fsdata) { - return block_prepare_write(page,from,to,get_block); + return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, + get_block); } + +static int sysv_write_begin(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned flags, + struct page **pagep, void **fsdata) +{ + *pagep = NULL; + return __sysv_write_begin(file, mapping, pos, len, flags, pagep, fsdata); +} + static sector_t sysv_bmap(struct address_space *mapping, sector_t block) { return generic_block_bmap(mapping,block,get_block); } + const struct address_space_operations sysv_aops = { .readpage = sysv_readpage, .writepage = sysv_writepage, .sync_page = block_sync_page, - .prepare_write = sysv_prepare_write, - .commit_write = generic_commit_write, + .write_begin = sysv_write_begin, + .write_end = generic_write_end, .bmap = sysv_bmap }; Index: linux-2.6/fs/sysv/dir.c =================================================================== --- linux-2.6.orig/fs/sysv/dir.c +++ linux-2.6/fs/sysv/dir.c @@ -37,12 +37,13 @@ static inline unsigned long dir_pages(st return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT; } -static int dir_commit_chunk(struct page *page, unsigned from, unsigned to) +static int dir_commit_chunk(struct page *page, loff_t pos, unsigned len) { - struct inode *dir = (struct inode *)page->mapping->host; + struct address_space *mapping = page->mapping; + struct inode *dir = mapping->host; int err = 0; - page->mapping->a_ops->commit_write(NULL, page, from, to); + block_write_end(NULL, mapping, pos, len, len, page, NULL); if (IS_DIRSYNC(dir)) err = write_one_page(page, 1); else @@ -186,7 +187,7 @@ int sysv_add_link(struct dentry *dentry, unsigned long npages = dir_pages(dir); unsigned long n; char *kaddr; - unsigned from, to; + loff_t pos; int err; /* We take care of directory expansion in the same loop */ @@ -212,16 +213,17 @@ int sysv_add_link(struct dentry *dentry, return -EINVAL; got_it: - from = (char*)de - (char*)page_address(page); - to = from + SYSV_DIRSIZE; + pos = (page->index << PAGE_CACHE_SHIFT) + + (char*)de - (char*)page_address(page); lock_page(page); - err = page->mapping->a_ops->prepare_write(NULL, page, from, to); + err = __sysv_write_begin(NULL, page->mapping, pos, SYSV_DIRSIZE, + AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); if (err) goto out_unlock; memcpy (de->name, name, namelen); memset (de->name + namelen, 0, SYSV_DIRSIZE - namelen - 2); de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); - err = dir_commit_chunk(page, from, to); + err = dir_commit_chunk(page, pos, SYSV_DIRSIZE); dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(dir); out_page: @@ -238,15 +240,15 @@ int sysv_delete_entry(struct sysv_dir_en struct address_space *mapping = page->mapping; struct inode *inode = (struct inode*)mapping->host; char *kaddr = (char*)page_address(page); - unsigned from = (char*)de - kaddr; - unsigned to = from + SYSV_DIRSIZE; + loff_t pos = (page->index << PAGE_CACHE_SHIFT) + (char *)de - kaddr; int err; lock_page(page); - err = mapping->a_ops->prepare_write(NULL, page, from, to); + err = __sysv_write_begin(NULL, mapping, pos, SYSV_DIRSIZE, + AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); BUG_ON(err); de->inode = 0; - err = dir_commit_chunk(page, from, to); + err = dir_commit_chunk(page, pos, SYSV_DIRSIZE); dir_put_page(page); inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; mark_inode_dirty(inode); @@ -263,12 +265,13 @@ int sysv_make_empty(struct inode *inode, if (!page) return -ENOMEM; - kmap(page); - err = mapping->a_ops->prepare_write(NULL, page, 0, 2 * SYSV_DIRSIZE); + err = __sysv_write_begin(NULL, mapping, 0, 2 * SYSV_DIRSIZE, + AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); if (err) { unlock_page(page); goto fail; } + kmap(page); base = (char*)page_address(page); memset(base, 0, PAGE_CACHE_SIZE); @@ -280,9 +283,9 @@ int sysv_make_empty(struct inode *inode, de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), dir->i_ino); strcpy(de->name,".."); + kunmap(page); err = dir_commit_chunk(page, 0, 2 * SYSV_DIRSIZE); fail: - kunmap(page); page_cache_release(page); return err; } @@ -336,16 +339,18 @@ not_empty: void sysv_set_link(struct sysv_dir_entry *de, struct page *page, struct inode *inode) { - struct inode *dir = (struct inode*)page->mapping->host; - unsigned from = (char *)de-(char*)page_address(page); - unsigned to = from + SYSV_DIRSIZE; + struct address_space *mapping = page->mapping; + struct inode *dir = mapping->host; + loff_t pos = (page->index << PAGE_CACHE_SHIFT) + + (char *)de-(char*)page_address(page); int err; lock_page(page); - err = page->mapping->a_ops->prepare_write(NULL, page, from, to); + err = __sysv_write_begin(NULL, mapping, pos, SYSV_DIRSIZE, + AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); BUG_ON(err); de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); - err = dir_commit_chunk(page, from, to); + err = dir_commit_chunk(page, pos, SYSV_DIRSIZE); dir_put_page(page); dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(dir); -- - To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html