diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/Kconfig | 2 | ||||
-rw-r--r-- | fs/binfmt_aout.c | 1 | ||||
-rw-r--r-- | fs/dquot.c | 4 | ||||
-rw-r--r-- | fs/ecryptfs/keystore.c | 2 | ||||
-rw-r--r-- | fs/ecryptfs/main.c | 1 | ||||
-rw-r--r-- | fs/ecryptfs/mmap.c | 31 | ||||
-rw-r--r-- | fs/ecryptfs/read_write.c | 27 | ||||
-rw-r--r-- | fs/ext3/super.c | 2 | ||||
-rw-r--r-- | fs/ext4/super.c | 2 | ||||
-rw-r--r-- | fs/nfs/client.c | 6 | ||||
-rw-r--r-- | fs/nfs/direct.c | 2 | ||||
-rw-r--r-- | fs/nfs/getroot.c | 11 | ||||
-rw-r--r-- | fs/nfs/super.c | 2 | ||||
-rw-r--r-- | fs/ocfs2/alloc.c | 68 | ||||
-rw-r--r-- | fs/ocfs2/journal.c | 13 | ||||
-rw-r--r-- | fs/proc/generic.c | 7 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_file.c | 5 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_iops.c | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2_block.c | 6 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2_leaf.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2_sf.c | 9 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.c | 6 |
22 files changed, 134 insertions, 79 deletions
diff --git a/fs/Kconfig b/fs/Kconfig index 635f3e286ad8..487236c65837 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -1305,7 +1305,7 @@ config JFFS2_COMPRESSION_OPTIONS help Enabling this option allows you to explicitly choose which compression modules, if any, are enabled in JFFS2. Removing - compressors and mean you cannot read existing file systems, + compressors can mean you cannot read existing file systems, and enabling experimental compressors can mean that you write a file system which cannot be read by a standard kernel. diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index e176d195e7e5..7596e1e94cde 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c @@ -319,7 +319,6 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) current->mm->free_area_cache = current->mm->mmap_base; current->mm->cached_hole_size = 0; - current->mm->mmap = NULL; compute_creds(bprm); current->flags &= ~PF_FORKNOEXEC; #ifdef __sparc__ diff --git a/fs/dquot.c b/fs/dquot.c index 2809768d9c41..686ab63a7c6c 100644 --- a/fs/dquot.c +++ b/fs/dquot.c @@ -965,7 +965,7 @@ err_out: } #endif -static inline void flush_warnings(struct dquot **dquots, char *warntype) +static inline void flush_warnings(struct dquot * const *dquots, char *warntype) { int i; @@ -1216,7 +1216,7 @@ warn_put_all: for (cnt = 0; cnt < MAXQUOTAS; cnt++) if (inode->i_dquot[cnt]) mark_dquot_dirty(inode->i_dquot[cnt]); - flush_warnings((struct dquot **)inode->i_dquot, warntype); + flush_warnings(inode->i_dquot, warntype); up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); return ret; } diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index 263fed88c0ca..f458c1f35565 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c @@ -1860,7 +1860,7 @@ ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, struct ecryptfs_global_auth_tok *new_auth_tok; int rc = 0; - new_auth_tok = kmem_cache_alloc(ecryptfs_global_auth_tok_cache, + new_auth_tok = kmem_cache_zalloc(ecryptfs_global_auth_tok_cache, GFP_KERNEL); if (!new_auth_tok) { rc = -ENOMEM; diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index b83a512b7e08..a277754da171 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c @@ -523,6 +523,7 @@ static int ecryptfs_read_super(struct super_block *sb, const char *dev_name) lower_mnt = nd.mnt; ecryptfs_set_superblock_lower(sb, lower_root->d_sb); sb->s_maxbytes = lower_root->d_sb->s_maxbytes; + sb->s_blocksize = lower_root->d_sb->s_blocksize; ecryptfs_set_dentry_lower(sb->s_root, lower_root); ecryptfs_set_dentry_lower_mnt(sb->s_root, lower_mnt); rc = ecryptfs_interpose(lower_root, sb->s_root, sb, 0); diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 16a7a555f392..32c5711d79a3 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c @@ -263,14 +263,13 @@ out: return 0; } +/* This function must zero any hole we create */ static int ecryptfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) { int rc = 0; + loff_t prev_page_end_size; - if (from == 0 && to == PAGE_CACHE_SIZE) - goto out; /* If we are writing a full page, it will be - up to date. */ if (!PageUptodate(page)) { rc = ecryptfs_read_lower_page_segment(page, page->index, 0, PAGE_CACHE_SIZE, @@ -283,22 +282,32 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page, } else SetPageUptodate(page); } - if (page->index != 0) { - loff_t end_of_prev_pg_pos = - (((loff_t)page->index << PAGE_CACHE_SHIFT) - 1); - if (end_of_prev_pg_pos > i_size_read(page->mapping->host)) { + prev_page_end_size = ((loff_t)page->index << PAGE_CACHE_SHIFT); + + /* + * If creating a page or more of holes, zero them out via truncate. + * Note, this will increase i_size. + */ + if (page->index != 0) { + if (prev_page_end_size > i_size_read(page->mapping->host)) { rc = ecryptfs_truncate(file->f_path.dentry, - end_of_prev_pg_pos); + prev_page_end_size); if (rc) { printk(KERN_ERR "Error on attempt to " "truncate to (higher) offset [%lld];" - " rc = [%d]\n", end_of_prev_pg_pos, rc); + " rc = [%d]\n", prev_page_end_size, rc); goto out; } } - if (end_of_prev_pg_pos + 1 > i_size_read(page->mapping->host)) - zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); + } + /* + * Writing to a new page, and creating a small hole from start of page? + * Zero it out. + */ + if ((i_size_read(page->mapping->host) == prev_page_end_size) && + (from != 0)) { + zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); } out: return rc; diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c index 6b7474a4336a..948f57624c05 100644 --- a/fs/ecryptfs/read_write.c +++ b/fs/ecryptfs/read_write.c @@ -124,6 +124,10 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset, loff_t pos; int rc = 0; + /* + * if we are writing beyond current size, then start pos + * at the current size - we'll fill in zeros from there. + */ if (offset > ecryptfs_file_size) pos = ecryptfs_file_size; else @@ -137,6 +141,7 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset, if (num_bytes > total_remaining_bytes) num_bytes = total_remaining_bytes; if (pos < offset) { + /* remaining zeros to write, up to destination offset */ size_t total_remaining_zeros = (offset - pos); if (num_bytes > total_remaining_zeros) @@ -167,17 +172,27 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset, } } ecryptfs_page_virt = kmap_atomic(ecryptfs_page, KM_USER0); + + /* + * pos: where we're now writing, offset: where the request was + * If current pos is before request, we are filling zeros + * If we are at or beyond request, we are writing the *data* + * If we're in a fresh page beyond eof, zero it in either case + */ + if (pos < offset || !start_offset_in_page) { + /* We are extending past the previous end of the file. + * Fill in zero values to the end of the page */ + memset(((char *)ecryptfs_page_virt + + start_offset_in_page), 0, + PAGE_CACHE_SIZE - start_offset_in_page); + } + + /* pos >= offset, we are now writing the data request */ if (pos >= offset) { memcpy(((char *)ecryptfs_page_virt + start_offset_in_page), (data + data_offset), num_bytes); data_offset += num_bytes; - } else { - /* We are extending past the previous end of the file. - * Fill in zero values up to the start of where we - * will be writing data. */ - memset(((char *)ecryptfs_page_virt - + start_offset_in_page), 0, num_bytes); } kunmap_atomic(ecryptfs_page_virt, KM_USER0); flush_dcache_page(ecryptfs_page); diff --git a/fs/ext3/super.c b/fs/ext3/super.c index de55da9e28ba..cb14de1502c3 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -1676,7 +1676,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group); sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group); sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group); - if (EXT3_INODE_SIZE(sb) == 0) + if (EXT3_INODE_SIZE(sb) == 0 || EXT3_INODES_PER_GROUP(sb) == 0) goto cantfind_ext3; sbi->s_inodes_per_block = blocksize / EXT3_INODE_SIZE(sb); if (sbi->s_inodes_per_block == 0) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 8031dc0e24e5..1ca0f546c466 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1797,7 +1797,7 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) sbi->s_desc_size = EXT4_MIN_DESC_SIZE; sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group); sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group); - if (EXT4_INODE_SIZE(sb) == 0) + if (EXT4_INODE_SIZE(sb) == 0 || EXT4_INODES_PER_GROUP(sb) == 0) goto cantfind_ext4; sbi->s_inodes_per_block = blocksize / EXT4_INODE_SIZE(sb); if (sbi->s_inodes_per_block == 0) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 70587f383f10..a6f625497612 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -410,9 +410,6 @@ static int nfs_create_rpc_client(struct nfs_client *clp, int proto, */ static void nfs_destroy_server(struct nfs_server *server) { - if (!IS_ERR(server->client_acl)) - rpc_shutdown_client(server->client_acl); - if (!(server->flags & NFS_MOUNT_NONLM)) lockd_down(); /* release rpc.lockd */ } @@ -755,6 +752,9 @@ void nfs_free_server(struct nfs_server *server) if (server->destroy != NULL) server->destroy(server); + + if (!IS_ERR(server->client_acl)) + rpc_shutdown_client(server->client_acl); if (!IS_ERR(server->client)) rpc_shutdown_client(server->client); diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 5e8d82f6666b..3c9d16b4f80c 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -894,8 +894,6 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov, retval = generic_write_checks(file, &pos, &count, 0); if (retval) goto out; - if (!count) - goto out; /* return 0 */ retval = -EINVAL; if ((ssize_t) count < 0) diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c index 0ee43843f4ec..e6242cdbaf91 100644 --- a/fs/nfs/getroot.c +++ b/fs/nfs/getroot.c @@ -57,6 +57,17 @@ static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *i } /* Circumvent igrab(): we know the inode is not being freed */ atomic_inc(&inode->i_count); + /* + * Ensure that this dentry is invisible to d_find_alias(). + * Otherwise, it may be spliced into the tree by + * d_materialise_unique if a parent directory from the same + * filesystem gets mounted at a later time. + * This again causes shrink_dcache_for_umount_subtree() to + * Oops, since the test for IS_ROOT() will fail. + */ + spin_lock(&dcache_lock); + list_del_init(&sb->s_root->d_alias); + spin_unlock(&dcache_lock); } return 0; } diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 2426e713b77f..ea929207f274 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1475,7 +1475,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags, error = PTR_ERR(mntroot); goto error_splat_super; } - if (mntroot->d_inode->i_op != &nfs_dir_inode_operations) { + if (mntroot->d_inode->i_op != server->nfs_client->rpc_ops->dir_inode_ops) { dput(mntroot); error = -ESTALE; goto error_splat_super; diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index ce62c152823d..23c8cda43f19 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c @@ -2389,6 +2389,18 @@ static int __ocfs2_rotate_tree_left(struct inode *inode, goto out; } + /* + * Caller might still want to make changes to the + * tree root, so re-add it to the journal here. + */ + ret = ocfs2_journal_access(handle, inode, + path_root_bh(left_path), + OCFS2_JOURNAL_ACCESS_WRITE); + if (ret) { + mlog_errno(ret); + goto out; + } + ret = ocfs2_rotate_subtree_left(inode, handle, left_path, right_path, subtree_root, dealloc, &deleted); @@ -3289,16 +3301,6 @@ static int ocfs2_insert_path(struct inode *inode, int ret, subtree_index; struct buffer_head *leaf_bh = path_leaf_bh(right_path); - /* - * Pass both paths to the journal. The majority of inserts - * will be touching all components anyway. - */ - ret = ocfs2_journal_access_path(inode, handle, right_path); - if (ret < 0) { - mlog_errno(ret); - goto out; - } - if (left_path) { int credits = handle->h_buffer_credits; @@ -3323,6 +3325,16 @@ static int ocfs2_insert_path(struct inode *inode, } } + /* + * Pass both paths to the journal. The majority of inserts + * will be touching all components anyway. + */ + ret = ocfs2_journal_access_path(inode, handle, right_path); + if (ret < 0) { + mlog_errno(ret); + goto out; + } + if (insert->ins_split != SPLIT_NONE) { /* * We could call ocfs2_insert_at_leaf() for some types @@ -3331,6 +3343,17 @@ static int ocfs2_insert_path(struct inode *inode, */ ocfs2_split_record(inode, left_path, right_path, insert_rec, insert->ins_split); + + /* + * Split might have modified either leaf and we don't + * have a guarantee that the later edge insert will + * dirty this for us. + */ + if (left_path) + ret = ocfs2_journal_dirty(handle, + path_leaf_bh(left_path)); + if (ret) + mlog_errno(ret); } else ocfs2_insert_at_leaf(insert_rec, path_leaf_el(right_path), insert, inode); @@ -3430,6 +3453,17 @@ static int ocfs2_do_insert_extent(struct inode *inode, mlog_errno(ret); goto out; } + + /* + * ocfs2_rotate_tree_right() might have extended the + * transaction without re-journaling our tree root. + */ + ret = ocfs2_journal_access(handle, inode, di_bh, + OCFS2_JOURNAL_ACCESS_WRITE); + if (ret) { + mlog_errno(ret); + goto out; + } } else if (type->ins_appending == APPEND_TAIL && type->ins_contig != CONTIG_LEFT) { ret = ocfs2_append_rec_to_path(inode, handle, insert_rec, @@ -3941,7 +3975,7 @@ static int __ocfs2_mark_extent_written(struct inode *inode, { int ret = 0; struct ocfs2_extent_list *el = path_leaf_el(path); - struct buffer_head *eb_bh, *last_eb_bh = NULL; + struct buffer_head *last_eb_bh = NULL; struct ocfs2_extent_rec *rec = &el->l_recs[split_index]; struct ocfs2_merge_ctxt ctxt; struct ocfs2_extent_list *rightmost_el; @@ -3960,14 +3994,6 @@ static int __ocfs2_mark_extent_written(struct inode *inode, goto out; } - eb_bh = path_leaf_bh(path); - ret = ocfs2_journal_access(handle, inode, eb_bh, - OCFS2_JOURNAL_ACCESS_WRITE); - if (ret) { - mlog_errno(ret); - goto out; - } - ctxt.c_contig_type = ocfs2_figure_merge_contig_type(inode, el, split_index, split_rec); @@ -4029,8 +4055,6 @@ static int __ocfs2_mark_extent_written(struct inode *inode, mlog_errno(ret); } - ocfs2_journal_dirty(handle, eb_bh); - out: brelse(last_eb_bh); return ret; @@ -6093,8 +6117,6 @@ start: mlog(0, "clusters_to_del = %u in this pass, tail blk=%llu\n", clusters_to_del, (unsigned long long)path_leaf_bh(path)->b_blocknr); - BUG_ON(clusters_to_del == 0); - mutex_lock(&tl_inode->i_mutex); tl_sem = 1; /* ocfs2_truncate_log_needs_flush guarantees us at least one diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index f9d01e25298d..8d81f6c1b877 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c @@ -174,6 +174,12 @@ int ocfs2_commit_trans(struct ocfs2_super *osb, * transaction. extend_trans will either extend the current handle by * nblocks, or commit it and start a new one with nblocks credits. * + * This might call journal_restart() which will commit dirty buffers + * and then restart the transaction. Before calling + * ocfs2_extend_trans(), any changed blocks should have been + * dirtied. After calling it, all blocks which need to be changed must + * go through another set of journal_access/journal_dirty calls. + * * WARNING: This will not release any semaphores or disk locks taken * during the transaction, so make sure they were taken *before* * start_trans or we'll have ordering deadlocks. @@ -193,11 +199,15 @@ int ocfs2_extend_trans(handle_t *handle, int nblocks) mlog(0, "Trying to extend transaction by %d blocks\n", nblocks); +#ifdef OCFS2_DEBUG_FS + status = 1; +#else status = journal_extend(handle, nblocks); if (status < 0) { mlog_errno(status); goto bail; } +#endif if (status > 0) { mlog(0, "journal_extend failed, trying journal_restart\n"); @@ -1277,11 +1287,12 @@ static int ocfs2_queue_orphans(struct ocfs2_super *osb, ocfs2_orphan_filldir); if (status) { mlog_errno(status); - goto out; + goto out_cluster; } *head = priv.head; +out_cluster: ocfs2_meta_unlock(orphan_dir_inode, 0); out: mutex_unlock(&orphan_dir_inode->i_mutex); diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 8d49838e5554..6a2fe5187b62 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -374,16 +374,9 @@ static int proc_delete_dentry(struct dentry * dentry) return 1; } -static int proc_revalidate_dentry(struct dentry *dentry, struct nameidata *nd) -{ - d_drop(dentry); - return 0; -} - static struct dentry_operations proc_dentry_operations = { .d_delete = proc_delete_dentry, - .d_revalidate = proc_revalidate_dentry, }; /* diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 54c564693d93..4847eb83fc18 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c @@ -347,6 +347,7 @@ xfs_file_readdir( size = buf.used; de = (struct hack_dirent *)buf.dirent; + curr_offset = de->offset /* & 0x7fffffff */; while (size > 0) { if (filldir(dirent, de->name, de->namlen, curr_offset & 0x7fffffff, @@ -356,13 +357,13 @@ xfs_file_readdir( reclen = sizeof(struct hack_dirent) + de->namlen; size -= reclen; - curr_offset = de->offset /* & 0x7fffffff */; de = (struct hack_dirent *)((char *)de + reclen); + curr_offset = de->offset /* & 0x7fffffff */; } } done: - if (!error) { + if (!error) { if (size == 0) filp->f_pos = offset & 0x7fffffff; else if (de) diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 37e116779eb1..5e8bb7f71b5a 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c @@ -332,9 +332,7 @@ xfs_vn_mknod( ASSERT(vp); ip = vn_to_inode(vp); - if (S_ISCHR(mode) || S_ISBLK(mode)) - ip->i_rdev = rdev; - else if (S_ISDIR(mode)) + if (S_ISDIR(mode)) xfs_validate_fields(ip); d_instantiate(dentry, ip); xfs_validate_fields(dir); diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c index c171767e242a..a5f4f4fb8868 100644 --- a/fs/xfs/xfs_dir2_block.c +++ b/fs/xfs/xfs_dir2_block.c @@ -508,7 +508,7 @@ xfs_dir2_block_getdents( continue; cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, - ptr - (char *)block); + (char *)dep - (char *)block); ino = be64_to_cpu(dep->inumber); #if XFS_BIG_INUMS ino += mp->m_inoadd; @@ -519,9 +519,7 @@ xfs_dir2_block_getdents( */ if (filldir(dirent, dep->name, dep->namelen, cook, ino, DT_UNKNOWN)) { - *offset = xfs_dir2_db_off_to_dataptr(mp, - mp->m_dirdatablk, - (char *)dep - (char *)block); + *offset = cook; xfs_da_brelse(NULL, bp); return 0; } diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c index e7c12fa1303e..0ca0020ba09f 100644 --- a/fs/xfs/xfs_dir2_leaf.c +++ b/fs/xfs/xfs_dir2_leaf.c @@ -1091,7 +1091,7 @@ xfs_dir2_leaf_getdents( * Won't fit. Return to caller. */ if (filldir(dirent, dep->name, dep->namelen, - xfs_dir2_byte_to_dataptr(mp, curoff + length), + xfs_dir2_byte_to_dataptr(mp, curoff), ino, DT_UNKNOWN)) break; diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c index 182c70315ad1..919d275a1cef 100644 --- a/fs/xfs/xfs_dir2_sf.c +++ b/fs/xfs/xfs_dir2_sf.c @@ -752,7 +752,7 @@ xfs_dir2_sf_getdents( #if XFS_BIG_INUMS ino += mp->m_inoadd; #endif - if (filldir(dirent, ".", 1, dotdot_offset, ino, DT_DIR)) { + if (filldir(dirent, ".", 1, dot_offset, ino, DT_DIR)) { *offset = dot_offset; return 0; } @@ -762,13 +762,11 @@ xfs_dir2_sf_getdents( * Put .. entry unless we're starting past it. */ if (*offset <= dotdot_offset) { - off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, - XFS_DIR2_DATA_FIRST_OFFSET); ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); #if XFS_BIG_INUMS ino += mp->m_inoadd; #endif - if (filldir(dirent, "..", 2, off, ino, DT_DIR)) { + if (filldir(dirent, "..", 2, dotdot_offset, ino, DT_DIR)) { *offset = dotdot_offset; return 0; } @@ -793,8 +791,7 @@ xfs_dir2_sf_getdents( #endif if (filldir(dirent, sfep->name, sfep->namelen, - off + xfs_dir2_data_entsize(sfep->namelen), - ino, DT_UNKNOWN)) { + off, ino, DT_UNKNOWN)) { *offset = off; return 0; } diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index abf509a88915..344948082819 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1459,8 +1459,10 @@ xfs_itruncate_start( mp = ip->i_mount; vp = XFS_ITOV(ip); - vn_iowait(ip); /* wait for the completion of any pending DIOs */ - + /* wait for the completion of any pending DIOs */ + if (new_size < ip->i_size) + vn_iowait(ip); + /* * Call toss_pages or flushinval_pages to get rid of pages * overlapping the region being removed. We have to use |