diff options
Diffstat (limited to 'fs/sysv/dir.c')
-rw-r--r-- | fs/sysv/dir.c | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c index 88e38cd8f5c9..16730795a621 100644 --- a/fs/sysv/dir.c +++ b/fs/sysv/dir.c @@ -34,21 +34,26 @@ static inline void dir_put_page(struct page *page) put_page(page); } -static int dir_commit_chunk(struct page *page, loff_t pos, unsigned len) +static void dir_commit_chunk(struct page *page, loff_t pos, unsigned len) { struct address_space *mapping = page->mapping; struct inode *dir = mapping->host; - int err = 0; 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); - else - unlock_page(page); + unlock_page(page); +} + +static int sysv_handle_dirsync(struct inode *dir) +{ + int err; + + err = filemap_write_and_wait(dir->i_mapping); + if (!err) + err = sync_inode_metadata(dir, 1); return err; } @@ -215,9 +220,10 @@ got_it: 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, pos, SYSV_DIRSIZE); + dir_commit_chunk(page, pos, SYSV_DIRSIZE); dir->i_mtime = dir->i_ctime = current_time(dir); mark_inode_dirty(dir); + err = sysv_handle_dirsync(dir); out_page: dir_put_page(page); out: @@ -238,11 +244,11 @@ int sysv_delete_entry(struct sysv_dir_entry *de, struct page *page) err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE); BUG_ON(err); de->inode = 0; - err = dir_commit_chunk(page, pos, SYSV_DIRSIZE); + dir_commit_chunk(page, pos, SYSV_DIRSIZE); dir_put_page(page); inode->i_ctime = inode->i_mtime = current_time(inode); mark_inode_dirty(inode); - return err; + return sysv_handle_dirsync(inode); } int sysv_make_empty(struct inode *inode, struct inode *dir) @@ -272,7 +278,8 @@ int sysv_make_empty(struct inode *inode, struct inode *dir) strcpy(de->name,".."); kunmap(page); - err = dir_commit_chunk(page, 0, 2 * SYSV_DIRSIZE); + dir_commit_chunk(page, 0, 2 * SYSV_DIRSIZE); + err = sysv_handle_dirsync(inode); fail: put_page(page); return err; @@ -336,10 +343,11 @@ void sysv_set_link(struct sysv_dir_entry *de, struct page *page, err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE); BUG_ON(err); de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); - err = dir_commit_chunk(page, pos, SYSV_DIRSIZE); + dir_commit_chunk(page, pos, SYSV_DIRSIZE); dir_put_page(page); dir->i_mtime = dir->i_ctime = current_time(dir); mark_inode_dirty(dir); + sysv_handle_dirsync(inode); } struct sysv_dir_entry * sysv_dotdot (struct inode *dir, struct page **p) |