X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=fs%2Fufs%2Fdir.c;h=df0bef18742dc63b6dee218e029b2e90d35b1c37;hb=9bde10a4b8c54804236d3d6b4b75e98825a921e7;hp=4890ddf1518e347a45ef00bc451b55891022ff10;hpb=5a84d159061d914c8dd4aa372ac6e9529c2be453;p=linux-2.6-omap-h63xx.git diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c index 4890ddf1518..df0bef18742 100644 --- a/fs/ufs/dir.c +++ b/fs/ufs/dir.c @@ -18,9 +18,10 @@ #include #include -#include -#include +#include +#include "ufs_fs.h" +#include "ufs.h" #include "swab.h" #include "util.h" @@ -39,12 +40,18 @@ static inline int ufs_match(struct super_block *sb, int len, return !memcmp(name, de->d_name, len); } -static int ufs_commit_chunk(struct page *page, unsigned from, unsigned to) +static int ufs_commit_chunk(struct page *page, loff_t pos, unsigned len) { - struct inode *dir = page->mapping->host; + struct address_space *mapping = page->mapping; + struct inode *dir = mapping->host; int err = 0; + dir->i_version++; - 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 @@ -82,16 +89,20 @@ ino_t ufs_inode_by_name(struct inode *dir, struct dentry *dentry) void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de, struct page *page, struct inode *inode) { - unsigned from = (char *) de - (char *) page_address(page); - unsigned to = from + fs16_to_cpu(dir->i_sb, de->d_reclen); + loff_t pos = page_offset(page) + + (char *) de - (char *) page_address(page); + unsigned len = fs16_to_cpu(dir->i_sb, de->d_reclen); int err; lock_page(page); - err = page->mapping->a_ops->prepare_write(NULL, page, from, to); + err = __ufs_write_begin(NULL, page->mapping, pos, len, + AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); BUG_ON(err); + de->d_ino = cpu_to_fs32(dir->i_sb, inode->i_ino); ufs_set_de_type(dir->i_sb, de, inode->i_mode); - err = ufs_commit_chunk(page, from, to); + + err = ufs_commit_chunk(page, pos, len); ufs_put_page(page); dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(dir); @@ -168,7 +179,7 @@ bad_entry: goto fail; Eend: p = (struct ufs_dir_entry *)(kaddr + offs); - ufs_error (sb, "ext2_check_page", + ufs_error(sb, __func__, "entry in directory #%lu spans the page boundary" "offset=%lu", dir->i_ino, (page->index<i_mapping; - struct page *page = read_cache_page(mapping, n, - (filler_t*)mapping->a_ops->readpage, NULL); + struct page *page = read_mapping_page(mapping, n, NULL); if (!IS_ERR(page)) { - wait_on_page_locked(page); kmap(page); - if (!PageUptodate(page)) - goto fail; if (!PageChecked(page)) ufs_check_page(page); if (PageError(page)) @@ -277,7 +284,7 @@ struct ufs_dir_entry *ufs_find_entry(struct inode *dir, struct dentry *dentry, kaddr += ufs_last_byte(dir, n) - reclen; while ((char *) de <= kaddr) { if (de->d_reclen == 0) { - ufs_error(dir->i_sb, __FUNCTION__, + ufs_error(dir->i_sb, __func__, "zero-length directory entry"); ufs_put_page(page); goto out; @@ -317,7 +324,7 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode) unsigned long npages = ufs_dir_pages(dir); unsigned long n; char *kaddr; - unsigned from, to; + loff_t pos; int err; UFSD("ENTER, name %s, namelen %u\n", name, namelen); @@ -349,7 +356,7 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode) goto got_it; } if (de->d_reclen == 0) { - ufs_error(dir->i_sb, __FUNCTION__, + ufs_error(dir->i_sb, __func__, "zero-length directory entry"); err = -EIO; goto out_unlock; @@ -372,9 +379,10 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode) return -EINVAL; got_it: - from = (char*)de - (char*)page_address(page); - to = from + rec_len; - err = page->mapping->a_ops->prepare_write(NULL, page, from, to); + pos = page_offset(page) + + (char*)de - (char*)page_address(page); + err = __ufs_write_begin(NULL, page->mapping, pos, rec_len, + AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); if (err) goto out_unlock; if (de->d_ino) { @@ -391,7 +399,7 @@ got_it: de->d_ino = cpu_to_fs32(sb, inode->i_ino); ufs_set_de_type(sb, de, inode->i_mode); - err = ufs_commit_chunk(page, from, to); + err = ufs_commit_chunk(page, pos, rec_len); dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(dir); @@ -448,7 +456,7 @@ ufs_readdir(struct file *filp, void *dirent, filldir_t filldir) struct page *page = ufs_get_page(inode, n); if (IS_ERR(page)) { - ufs_error(sb, __FUNCTION__, + ufs_error(sb, __func__, "bad page in #%lu", inode->i_ino); filp->f_pos += PAGE_CACHE_SIZE - offset; @@ -467,7 +475,7 @@ ufs_readdir(struct file *filp, void *dirent, filldir_t filldir) limit = kaddr + ufs_last_byte(inode, n) - UFS_DIR_REC_LEN(1); for ( ;(char*)de <= limit; de = ufs_next_entry(sb, de)) { if (de->d_reclen == 0) { - ufs_error(sb, __FUNCTION__, + ufs_error(sb, __func__, "zero-length directory entry"); ufs_put_page(page); return -EIO; @@ -514,6 +522,7 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir, char *kaddr = page_address(page); unsigned from = ((char*)dir - kaddr) & ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1); unsigned to = ((char*)dir - kaddr) + fs16_to_cpu(sb, dir->d_reclen); + loff_t pos; struct ufs_dir_entry *pde = NULL; struct ufs_dir_entry *de = (struct ufs_dir_entry *) (kaddr + from); int err; @@ -527,7 +536,7 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir, while ((char*)de < (char*)dir) { if (de->d_reclen == 0) { - ufs_error(inode->i_sb, __FUNCTION__, + ufs_error(inode->i_sb, __func__, "zero-length directory entry"); err = -EIO; goto out; @@ -537,13 +546,16 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir, } if (pde) from = (char*)pde - (char*)page_address(page); + + pos = page_offset(page) + from; lock_page(page); - err = mapping->a_ops->prepare_write(NULL, page, from, to); + err = __ufs_write_begin(NULL, mapping, pos, to - from, + AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); BUG_ON(err); if (pde) - pde->d_reclen = cpu_to_fs16(sb, to-from); + pde->d_reclen = cpu_to_fs16(sb, to - from); dir->d_ino = 0; - err = ufs_commit_chunk(page, from, to); + err = ufs_commit_chunk(page, pos, to - from); inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; mark_inode_dirty(inode); out: @@ -564,14 +576,15 @@ int ufs_make_empty(struct inode * inode, struct inode *dir) if (!page) return -ENOMEM; - kmap(page); - err = mapping->a_ops->prepare_write(NULL, page, 0, chunk_size); + + err = __ufs_write_begin(NULL, mapping, 0, chunk_size, + 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); @@ -589,10 +602,10 @@ int ufs_make_empty(struct inode * inode, struct inode *dir) de->d_reclen = cpu_to_fs16(sb, chunk_size - UFS_DIR_REC_LEN(1)); ufs_set_de_namlen(sb, de, 2); strcpy (de->d_name, ".."); + kunmap(page); err = ufs_commit_chunk(page, 0, chunk_size); fail: - kunmap(page); page_cache_release(page); return err; } @@ -620,7 +633,7 @@ int ufs_empty_dir(struct inode * inode) while ((char *)de <= kaddr) { if (de->d_reclen == 0) { - ufs_error(inode->i_sb, __FUNCTION__, + ufs_error(inode->i_sb, __func__, "zero-length directory entry: " "kaddr=%p, de=%p\n", kaddr, de); goto not_empty;