X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=fs%2Fsysv%2Fdir.c;h=56f655254bfedbb81a03b05f530b54a66ccab448;hb=59af1584bf33810639cb98d79856021253e2177c;hp=8c66e9270dd64995f95ac6504a61998bec5c31dd;hpb=d62e54abca1146981fc9f98f85ff398a113a22c2;p=linux-2.6-omap-h63xx.git diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c index 8c66e9270dd..56f655254bf 100644 --- a/fs/sysv/dir.c +++ b/fs/sysv/dir.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "sysv.h" static int sysv_readdir(struct file *, void *, filldir_t); @@ -37,12 +38,17 @@ static inline unsigned long dir_pages(struct inode *inode) 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 (pos+len > dir->i_size) { + i_size_write(dir, pos+len); + mark_inode_dirty(dir); + } if (IS_DIRSYNC(dir)) err = write_one_page(page, 1); else @@ -53,25 +59,16 @@ static int dir_commit_chunk(struct page *page, unsigned from, unsigned to) static struct page * dir_get_page(struct inode *dir, unsigned long n) { struct address_space *mapping = dir->i_mapping; - struct page *page = read_cache_page(mapping, n, - (filler_t*)mapping->a_ops->readpage, NULL); - if (!IS_ERR(page)) { - wait_on_page_locked(page); + struct page *page = read_mapping_page(mapping, n, NULL); + if (!IS_ERR(page)) kmap(page); - if (!PageUptodate(page)) - goto fail; - } return page; - -fail: - dir_put_page(page); - return ERR_PTR(-EIO); } static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir) { unsigned long pos = filp->f_pos; - struct inode *inode = filp->f_dentry->d_inode; + struct inode *inode = filp->f_path.dentry->d_inode; struct super_block *sb = inode->i_sb; unsigned offset = pos & ~PAGE_CACHE_MASK; unsigned long n = pos >> PAGE_CACHE_SHIFT; @@ -195,7 +192,7 @@ int sysv_add_link(struct dentry *dentry, struct inode *inode) 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 */ @@ -221,16 +218,17 @@ int sysv_add_link(struct dentry *dentry, struct inode *inode) return -EINVAL; got_it: - from = (char*)de - (char*)page_address(page); - to = from + SYSV_DIRSIZE; + pos = page_offset(page) + + (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: @@ -247,16 +245,15 @@ int sysv_delete_entry(struct sysv_dir_entry *de, struct page *page) 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_offset(page) + (char *)de - kaddr; int err; lock_page(page); - err = mapping->a_ops->prepare_write(NULL, page, from, to); - if (err) - BUG(); + 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); @@ -273,12 +270,13 @@ int sysv_make_empty(struct inode *inode, struct inode *dir) 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); @@ -290,9 +288,9 @@ int sysv_make_empty(struct inode *inode, struct inode *dir) 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; } @@ -346,17 +344,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_offset(page) + + (char *)de-(char*)page_address(page); int err; lock_page(page); - err = page->mapping->a_ops->prepare_write(NULL, page, from, to); - if (err) - BUG(); + 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);