X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=fs%2Fext2%2Fdir.c;h=05d9342bb64ee271586f0a9f136e36f599b8cf83;hb=4ba9b9d0ba0a49d91fa6417c7510ee36f48cf957;hp=2bf49d7ef841423d03c44527e1578f7f8c4a2f38;hpb=02a93208edec0d655c9f18613d830dc6afeda7d4;p=karo-tx-linux.git diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index 2bf49d7ef841..05d9342bb64e 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c @@ -22,7 +22,9 @@ */ #include "ext2.h" +#include #include +#include typedef struct ext2_dir_entry_2 ext2_dirent; @@ -61,16 +63,25 @@ ext2_last_byte(struct inode *inode, unsigned long page_nr) return last_byte; } -static int ext2_commit_chunk(struct page *page, unsigned from, unsigned to) +static int ext2_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 unlock_page(page); + return err; } @@ -412,16 +423,18 @@ ino_t ext2_inode_by_name(struct inode * dir, struct dentry *dentry) void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, struct page *page, struct inode *inode) { - unsigned from = (char *) de - (char *) page_address(page); - unsigned to = from + le16_to_cpu(de->rec_len); + loff_t pos = page_offset(page) + + (char *) de - (char *) page_address(page); + unsigned len = le16_to_cpu(de->rec_len); int err; lock_page(page); - err = page->mapping->a_ops->prepare_write(NULL, page, from, to); + err = __ext2_write_begin(NULL, page->mapping, pos, len, + AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); BUG_ON(err); de->inode = cpu_to_le32(inode->i_ino); - ext2_set_de_type (de, inode); - err = ext2_commit_chunk(page, from, to); + ext2_set_de_type(de, inode); + err = ext2_commit_chunk(page, pos, len); ext2_put_page(page); dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL; @@ -444,7 +457,7 @@ int ext2_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; /* @@ -497,9 +510,10 @@ int ext2_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 = __ext2_write_begin(NULL, page->mapping, pos, rec_len, 0, + &page, NULL); if (err) goto out_unlock; if (de->inode) { @@ -509,10 +523,10 @@ got_it: de = de1; } de->name_len = namelen; - memcpy (de->name, name, namelen); + memcpy(de->name, name, namelen); de->inode = cpu_to_le32(inode->i_ino); ext2_set_de_type (de, inode); - err = ext2_commit_chunk(page, from, to); + err = ext2_commit_chunk(page, pos, rec_len); dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL; mark_inode_dirty(dir); @@ -537,6 +551,7 @@ int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ) char *kaddr = page_address(page); unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1); unsigned to = ((char*)dir - kaddr) + le16_to_cpu(dir->rec_len); + loff_t pos; ext2_dirent * pde = NULL; ext2_dirent * de = (ext2_dirent *) (kaddr + from); int err; @@ -553,13 +568,15 @@ int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ) } 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 = __ext2_write_begin(NULL, page->mapping, pos, to - from, 0, + &page, NULL); BUG_ON(err); if (pde) - pde->rec_len = cpu_to_le16(to-from); + pde->rec_len = cpu_to_le16(to - from); dir->inode = 0; - err = ext2_commit_chunk(page, from, to); + err = ext2_commit_chunk(page, pos, to - from); inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; EXT2_I(inode)->i_flags &= ~EXT2_BTREE_FL; mark_inode_dirty(inode); @@ -582,7 +599,9 @@ int ext2_make_empty(struct inode *inode, struct inode *parent) if (!page) return -ENOMEM; - err = mapping->a_ops->prepare_write(NULL, page, 0, chunk_size); + + err = __ext2_write_begin(NULL, page->mapping, 0, chunk_size, 0, + &page, NULL); if (err) { unlock_page(page); goto fail;