From 642be6ec218b956fbae88304449720f76ba0d578 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 25 Feb 2008 17:20:46 -0500 Subject: Remove incorrect BKL comments in ext4 Signed-off-by: Andi Kleen Signed-off-by: "Theodore Ts'o" --- fs/ext4/dir.c | 2 +- fs/ext4/inode.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'fs') diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index 33888bb5814..2c23bade9aa 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c @@ -46,7 +46,7 @@ const struct file_operations ext4_dir_operations = { #ifdef CONFIG_COMPAT .compat_ioctl = ext4_compat_ioctl, #endif - .fsync = ext4_sync_file, /* BKL held */ + .fsync = ext4_sync_file, .release = ext4_release_dir, }; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 7dd9b50d5eb..d3c6f58a9de 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -768,7 +768,6 @@ err_out: * * `handle' can be NULL if create == 0. * - * The BKL may not be held on entry here. Be sure to take it early. * return > 0, # of blocks mapped or allocated. * return = 0, if plain lookup failed. * return < 0, error case. -- cgit v1.2.3 From 55bd725aa3a83b3935988f37275b5a80e10d4169 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 15 Feb 2008 12:47:21 -0500 Subject: ext4: Fix locking hierarchy violation in ext4_fallocate() ext4_fallocate() was trying to acquire i_data_sem outside of jbd2_start_transaction/jbd2_journal_stop, which violates ext4's locking hierarchy. So we take i_mutex to prevent writes and truncates during the complete fallocate operation, and use ext4_get_block_wrap() which acquires and releases i_data_sem for each block allocation. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'fs') diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index bc7081f1fbe..e856f660fc3 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2623,7 +2623,7 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len) * modify 1 super block, 1 block bitmap and 1 group descriptor. */ credits = EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + 3; - down_write((&EXT4_I(inode)->i_data_sem)); + mutex_lock(&inode->i_mutex); retry: while (ret >= 0 && ret < max_blocks) { block = block + ret; @@ -2634,7 +2634,7 @@ retry: break; } - ret = ext4_ext_get_blocks(handle, inode, block, + ret = ext4_get_blocks_wrap(handle, inode, block, max_blocks, &map_bh, EXT4_CREATE_UNINITIALIZED_EXT, 0); WARN_ON(ret <= 0); @@ -2680,7 +2680,6 @@ retry: if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) goto retry; - up_write((&EXT4_I(inode)->i_data_sem)); /* * Time to update the file size. * Update only when preallocation was requested beyond the file size. @@ -2692,21 +2691,18 @@ retry: * if no error, we assume preallocation succeeded * completely */ - mutex_lock(&inode->i_mutex); i_size_write(inode, offset + len); EXT4_I(inode)->i_disksize = i_size_read(inode); - mutex_unlock(&inode->i_mutex); } else if (ret < 0 && nblocks) { /* Handle partial allocation scenario */ loff_t newsize; - mutex_lock(&inode->i_mutex); newsize = (nblocks << blkbits) + i_size_read(inode); i_size_write(inode, EXT4_BLOCK_ALIGN(newsize, blkbits)); EXT4_I(inode)->i_disksize = i_size_read(inode); - mutex_unlock(&inode->i_mutex); } } + mutex_unlock(&inode->i_mutex); return ret > 0 ? ret2 : ret; } -- cgit v1.2.3 From b73fce69ecb091a178ef9286027c370a63eb25aa Mon Sep 17 00:00:00 2001 From: Valerie Clement Date: Fri, 15 Feb 2008 13:48:51 -0500 Subject: ext4: Fix kernel BUG at fs/ext4/mballoc.c:910! With the flex_bg feature enabled, a large file creation oopses the kernel. The BUG_ON is: BUG_ON(len >= EXT4_BLOCKS_PER_GROUP(sb)); As the allocation of the bitmaps and the inode table can be done outside the block group with flex_bg, this allows to allocate up to EXT4_BLOCKS_PER_GROUP blocks in a group. This patch fixes the oops. Signed-off-by: Valerie Clement Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" --- fs/ext4/mballoc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index dd0fcfcb35c..2121184a3fa 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -906,7 +906,7 @@ static void ext4_mb_mark_free_simple(struct super_block *sb, unsigned short chunk; unsigned short border; - BUG_ON(len >= EXT4_BLOCKS_PER_GROUP(sb)); + BUG_ON(len > EXT4_BLOCKS_PER_GROUP(sb)); border = 2 << sb->s_blocksize_bits; -- cgit v1.2.3 From 4cdeed861b5f797b3fa661eb331a6bd6ad669c6a Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 22 Feb 2008 06:17:31 -0500 Subject: ext4: Don't leave behind a half-created inode if ext4_mkdir() fails If ext4_mkdir() fails to allocate the initial block for the directory, don't leave behind a half-created directory inode with the link count left at one. This was caused by an inappropriate call to ext4_dec_count(). Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" --- fs/ext4/namei.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'fs') diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index a9347fb43bc..fffd0807a01 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1804,12 +1804,8 @@ retry: inode->i_fop = &ext4_dir_operations; inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize; dir_block = ext4_bread (handle, inode, 0, 1, &err); - if (!dir_block) { - ext4_dec_count(handle, inode); /* is this nlink == 0? */ - ext4_mark_inode_dirty(handle, inode); - iput (inode); - goto out_stop; - } + if (!dir_block) + goto out_clear_inode; BUFFER_TRACE(dir_block, "get_write_access"); ext4_journal_get_write_access(handle, dir_block); de = (struct ext4_dir_entry_2 *) dir_block->b_data; @@ -1832,7 +1828,8 @@ retry: ext4_mark_inode_dirty(handle, inode); err = ext4_add_entry (handle, dentry, inode); if (err) { - inode->i_nlink = 0; +out_clear_inode: + clear_nlink(inode); ext4_mark_inode_dirty(handle, inode); iput (inode); goto out_stop; -- cgit v1.2.3 From b35905c16ad6428551eb9e49525011bd2700cf56 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Mon, 25 Feb 2008 16:54:37 -0500 Subject: ext4: Fix memory and buffer head leak in callers to ext4_ext_find_extent() The path variable returned via ext4_ext_find_extent is a kmalloc variable and needs to be freeded. It also contains a reference to buffer_head which needs to be dropped. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 6 +++--- fs/ext4/migrate.c | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index e856f660fc3..995ac16102a 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -349,7 +349,7 @@ static void ext4_ext_show_leaf(struct inode *inode, struct ext4_ext_path *path) #define ext4_ext_show_leaf(inode,path) #endif -static void ext4_ext_drop_refs(struct ext4_ext_path *path) +void ext4_ext_drop_refs(struct ext4_ext_path *path) { int depth = path->p_depth; int i; @@ -2200,10 +2200,10 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, newdepth = ext_depth(inode); if (newdepth != depth) { depth = newdepth; - path = ext4_ext_find_extent(inode, iblock, NULL); + ext4_ext_drop_refs(path); + path = ext4_ext_find_extent(inode, iblock, path); if (IS_ERR(path)) { err = PTR_ERR(path); - path = NULL; goto out; } eh = path[depth].p_hdr; diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c index 8c6c685b9d2..5c1e27de775 100644 --- a/fs/ext4/migrate.c +++ b/fs/ext4/migrate.c @@ -43,6 +43,7 @@ static int finish_range(handle_t *handle, struct inode *inode, if (IS_ERR(path)) { retval = PTR_ERR(path); + path = NULL; goto err_out; } @@ -74,6 +75,10 @@ static int finish_range(handle_t *handle, struct inode *inode, } retval = ext4_ext_insert_extent(handle, inode, path, &newext); err_out: + if (path) { + ext4_ext_drop_refs(path); + kfree(path); + } lb->first_pblock = 0; return retval; } -- cgit v1.2.3 From 9df5643ad135c7f8c02d3b69020de4ec910f9fc0 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 22 Feb 2008 06:17:31 -0500 Subject: ext4: Get journal write access before modifying the extent tree When the user was writing into an unitialized extent, ext4_ext_convert_to_initialize() was not requesting journal write access before it started to modify the extent tree. Fix this oversight. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 995ac16102a..c4d6f19faf3 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2168,6 +2168,10 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, newblock = iblock - ee_block + ext_pblock(ex); ex2 = ex; + err = ext4_ext_get_access(handle, inode, path + depth); + if (err) + goto out; + /* ex1: ee_block to iblock - 1 : uninitialized */ if (iblock > ee_block) { ex1 = ex; @@ -2210,6 +2214,10 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, ex = path[depth].p_ext; if (ex2 != &newex) ex2 = ex; + + err = ext4_ext_get_access(handle, inode, path + depth); + if (err) + goto out; } allocated = max_blocks; } @@ -2230,9 +2238,6 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, ex2->ee_len = cpu_to_le16(allocated); if (ex2 != ex) goto insert; - err = ext4_ext_get_access(handle, inode, path + depth); - if (err) - goto out; /* * New (initialized) extent starts from the first block * in the current extent. i.e., ex2 == ex -- cgit v1.2.3 From e56eb6590693a5a340e8f596db2768a6e1b9e236 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 15 Feb 2008 13:48:21 -0500 Subject: ext4: Don't claim block from group which has corrupt bitmap In ext4_mb_complex_scan_group, if the extent length of the newly found extentet is greater than than the total free blocks counted in group info, break without claiming the block. Document different ext4_error usage, explaining the state with which we continue if we mount with errors=continue Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" --- fs/ext4/mballoc.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 2121184a3fa..6968c53e62a 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -967,6 +967,10 @@ static void ext4_mb_generate_buddy(struct super_block *sb, ext4_error(sb, __FUNCTION__, "EXT4-fs: group %lu: %u blocks in bitmap, %u in gd\n", group, free, grp->bb_free); + /* + * If we intent to continue, we consider group descritor + * corrupt and update bb_free using bitmap value + */ grp->bb_free = free; } @@ -1822,7 +1826,7 @@ static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, EXT4_BLOCKS_PER_GROUP(sb), i); if (i >= EXT4_BLOCKS_PER_GROUP(sb)) { /* - * IF we corrupt the bitmap we won't find any + * IF we have corrupt bitmap, we won't find any * free blocks even though group info says we * we have free blocks */ @@ -1838,6 +1842,12 @@ static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, ext4_error(sb, __FUNCTION__, "%d free blocks as per " "group info. But got %d blocks\n", free, ex.fe_len); + /* + * The number of free blocks differs. This mostly + * indicate that the bitmap is corrupt. So exit + * without claiming the space. + */ + break; } ext4_mb_measure_extent(ac, &ex, e4b); @@ -3771,6 +3781,10 @@ static int ext4_mb_release_inode_pa(struct ext4_buddy *e4b, (unsigned long) pa->pa_len); ext4_error(sb, __FUNCTION__, "free %u, pa_free %u\n", free, pa->pa_free); + /* + * pa is already deleted so we use the value obtained + * from the bitmap and continue. + */ } atomic_add(free, &sbi->s_mb_discarded); if (ac) -- cgit v1.2.3 From 74d3487fc8aa58cec16dff7239dea1ca59bdab0e Mon Sep 17 00:00:00 2001 From: Valerie Clement Date: Fri, 15 Feb 2008 13:43:07 -0500 Subject: ext4: modify block allocation algorithm for the last group When a directory inode is allocated in the last group and the last group contains less than s_blocks_per_group blocks, the initial block allocated for the directory is not always allocated in the same group as the directory inode, but in one of the first groups of the filesystem (group 1 for example). Depending on the current process's pid, ext4_find_near() and ext4_ext_find_goal() can return a block number greater than the maximum blocks count in the filesystem and in that case the block will be not allocated in the same group as the inode. The following patch fixes the problem. Should the modification also be done in ext2/3 code? Signed-off-by: Valerie Clement Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 8 +++++++- fs/ext4/inode.c | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'fs') diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index c4d6f19faf3..8a59f7ba30e 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -148,6 +148,7 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode, { struct ext4_inode_info *ei = EXT4_I(inode); ext4_fsblk_t bg_start; + ext4_fsblk_t last_block; ext4_grpblk_t colour; int depth; @@ -169,8 +170,13 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode, /* OK. use inode's group */ bg_start = (ei->i_block_group * EXT4_BLOCKS_PER_GROUP(inode->i_sb)) + le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_first_data_block); - colour = (current->pid % 16) * + last_block = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es) - 1; + + if (bg_start + EXT4_BLOCKS_PER_GROUP(inode->i_sb) <= last_block) + colour = (current->pid % 16) * (EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16); + else + colour = (current->pid % 16) * ((last_block - bg_start) / 16); return bg_start + colour + block; } diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index d3c6f58a9de..34f3eb615fd 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -403,6 +403,7 @@ static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind) __le32 *start = ind->bh ? (__le32*) ind->bh->b_data : ei->i_data; __le32 *p; ext4_fsblk_t bg_start; + ext4_fsblk_t last_block; ext4_grpblk_t colour; /* Try to find previous block */ @@ -420,8 +421,13 @@ static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind) * into the same cylinder group then. */ bg_start = ext4_group_first_block_no(inode->i_sb, ei->i_block_group); - colour = (current->pid % 16) * + last_block = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es) - 1; + + if (bg_start + EXT4_BLOCKS_PER_GROUP(inode->i_sb) <= last_block) + colour = (current->pid % 16) * (EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16); + else + colour = (current->pid % 16) * ((last_block - bg_start) / 16); return bg_start + colour; } -- cgit v1.2.3 From 825f1481ead4ce40671089bae7412ac3519e8caa Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 15 Feb 2008 15:00:38 -0500 Subject: ext4: Don't use ext4_dec_count() if not needed The ext4_dec_count() function is only needed when dropping the i_nlink count on inodes which are (or which could be) directories. If we *know* that the inode in question can't possibly be a directory, use drop_nlink or clear_nlink() if we know i_nlink is 1. Signed-off-by: "Theodore Ts'o" --- fs/ext4/namei.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index fffd0807a01..5a79c6b6dc6 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -2161,7 +2161,7 @@ static int ext4_unlink(struct inode * dir, struct dentry *dentry) dir->i_ctime = dir->i_mtime = ext4_current_time(dir); ext4_update_dx_flag(dir); ext4_mark_inode_dirty(handle, dir); - ext4_dec_count(handle, inode); + drop_nlink(inode); if (!inode->i_nlink) ext4_orphan_add(handle, inode); inode->i_ctime = ext4_current_time(inode); @@ -2211,7 +2211,7 @@ retry: err = __page_symlink(inode, symname, l, mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); if (err) { - ext4_dec_count(handle, inode); + clear_nlink(inode); ext4_mark_inode_dirty(handle, inode); iput (inode); goto out_stop; @@ -2404,7 +2404,7 @@ static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry, ext4_dec_count(handle, old_dir); if (new_inode) { /* checked empty_dir above, can't have another parent, - * ext3_dec_count() won't work for many-linked dirs */ + * ext4_dec_count() won't work for many-linked dirs */ new_inode->i_nlink = 0; } else { ext4_inc_count(handle, new_dir); -- cgit v1.2.3 From 58b7983d15a422d9616bdc4e245d5c31dfaefbe2 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 27 Nov 2007 16:53:47 +1100 Subject: [XFS] Remove Makefile wrappers in XFS Makefile (and Kbuild) would include Makefile-linux-26 I doubt XFS will really still compile on 2.4; so drop that. This moves Makefile-linux-26 into Makefile and drops Kbuild. Also having wrappers as both Kbuild and Makefile seemed redundant anyways. The patch is relatively large because it renames a file, but no functional changes. SGI-PV: 971050 SGI-Modid: xfs-linux-melb:xfs-kern:29781a Signed-off-by: Andi Kleen Signed-off-by: Donald Douwsma Signed-off-by: Tim Shimmin Signed-off-by: Lachlan McIlroy --- fs/xfs/Kbuild | 6 --- fs/xfs/Makefile | 123 +++++++++++++++++++++++++++++++++++++++++++++- fs/xfs/Makefile-linux-2.6 | 117 ------------------------------------------- 3 files changed, 122 insertions(+), 124 deletions(-) delete mode 100644 fs/xfs/Kbuild (limited to 'fs') diff --git a/fs/xfs/Kbuild b/fs/xfs/Kbuild deleted file mode 100644 index 2566e96706f..00000000000 --- a/fs/xfs/Kbuild +++ /dev/null @@ -1,6 +0,0 @@ -# -# The xfs people like to share Makefile with 2.6 and 2.4. -# Utilise file named Kbuild file which has precedence over Makefile. -# - -include $(srctree)/$(obj)/Makefile-linux-2.6 diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 49e3e7e5e3d..6bf3ee2bea5 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -1 +1,122 @@ -include $(TOPDIR)/fs/xfs/Makefile-linux-$(VERSION).$(PATCHLEVEL) +# +# Copyright (c) 2000-2005 Silicon Graphics, Inc. +# All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +EXTRA_CFLAGS += -Ifs/xfs -Ifs/xfs/linux-2.6 -funsigned-char + +XFS_LINUX := linux-2.6 + +ifeq ($(CONFIG_XFS_DEBUG),y) + EXTRA_CFLAGS += -g +endif + +obj-$(CONFIG_XFS_FS) += xfs.o +obj-$(CONFIG_XFS_QUOTA) += quota/ +obj-$(CONFIG_XFS_DMAPI) += dmapi/ + +xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o +xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o +xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o +xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o +xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o + + +xfs-y += xfs_alloc.o \ + xfs_alloc_btree.o \ + xfs_attr.o \ + xfs_attr_leaf.o \ + xfs_bit.o \ + xfs_bmap.o \ + xfs_bmap_btree.o \ + xfs_btree.o \ + xfs_buf_item.o \ + xfs_da_btree.o \ + xfs_dir2.o \ + xfs_dir2_block.o \ + xfs_dir2_data.o \ + xfs_dir2_leaf.o \ + xfs_dir2_node.o \ + xfs_dir2_sf.o \ + xfs_error.o \ + xfs_extfree_item.o \ + xfs_filestream.o \ + xfs_fsops.o \ + xfs_ialloc.o \ + xfs_ialloc_btree.o \ + xfs_iget.o \ + xfs_inode.o \ + xfs_inode_item.o \ + xfs_iomap.o \ + xfs_itable.o \ + xfs_dfrag.o \ + xfs_log.o \ + xfs_log_recover.o \ + xfs_mount.o \ + xfs_mru_cache.o \ + xfs_rename.o \ + xfs_trans.o \ + xfs_trans_ail.o \ + xfs_trans_buf.o \ + xfs_trans_extfree.o \ + xfs_trans_inode.o \ + xfs_trans_item.o \ + xfs_utils.o \ + xfs_vfsops.o \ + xfs_vnodeops.o \ + xfs_rw.o \ + xfs_dmops.o \ + xfs_qmops.o + +xfs-$(CONFIG_XFS_TRACE) += xfs_dir2_trace.o + +# Objects in linux/ +xfs-y += $(addprefix $(XFS_LINUX)/, \ + kmem.o \ + xfs_aops.o \ + xfs_buf.o \ + xfs_export.o \ + xfs_file.o \ + xfs_fs_subr.o \ + xfs_globals.o \ + xfs_ioctl.o \ + xfs_iops.o \ + xfs_lrw.o \ + xfs_super.o \ + xfs_vnode.o \ + xfs_ksyms.o) + +# Objects in support/ +xfs-y += $(addprefix support/, \ + debug.o \ + uuid.o) + +xfs-$(CONFIG_XFS_TRACE) += support/ktrace.o + +# If both xfs and kdb modules are built in then xfsidbg is built in. If xfs is +# a module and kdb modules are being compiled then xfsidbg must be a module, to +# follow xfs. If xfs is built in then xfsidbg tracks the kdb module state. +# This must come after the main xfs code so xfs initialises before xfsidbg. +# KAO +ifneq ($(CONFIG_KDB_MODULES),) + ifeq ($(CONFIG_XFS_FS),y) + obj-$(CONFIG_KDB_MODULES) += xfsidbg.o + else + obj-$(CONFIG_XFS_FS) += xfsidbg.o + endif +endif + +CFLAGS_xfsidbg.o += -Iarch/$(ARCH)/kdb diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6 index 97316451fc6..e69de29bb2d 100644 --- a/fs/xfs/Makefile-linux-2.6 +++ b/fs/xfs/Makefile-linux-2.6 @@ -1,117 +0,0 @@ -# -# Copyright (c) 2000-2005 Silicon Graphics, Inc. -# All Rights Reserved. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it would be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# - -EXTRA_CFLAGS += -Ifs/xfs -Ifs/xfs/linux-2.6 -funsigned-char - -XFS_LINUX := linux-2.6 - -ifeq ($(CONFIG_XFS_DEBUG),y) - EXTRA_CFLAGS += -g -endif - -obj-$(CONFIG_XFS_FS) += xfs.o - -xfs-$(CONFIG_XFS_QUOTA) += $(addprefix quota/, \ - xfs_dquot.o \ - xfs_dquot_item.o \ - xfs_trans_dquot.o \ - xfs_qm_syscalls.o \ - xfs_qm_bhv.o \ - xfs_qm.o) - -ifeq ($(CONFIG_XFS_QUOTA),y) -xfs-$(CONFIG_PROC_FS) += quota/xfs_qm_stats.o -endif - -xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o -xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o -xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o -xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o -xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o - - -xfs-y += xfs_alloc.o \ - xfs_alloc_btree.o \ - xfs_attr.o \ - xfs_attr_leaf.o \ - xfs_bit.o \ - xfs_bmap.o \ - xfs_bmap_btree.o \ - xfs_btree.o \ - xfs_buf_item.o \ - xfs_da_btree.o \ - xfs_dir2.o \ - xfs_dir2_block.o \ - xfs_dir2_data.o \ - xfs_dir2_leaf.o \ - xfs_dir2_node.o \ - xfs_dir2_sf.o \ - xfs_error.o \ - xfs_extfree_item.o \ - xfs_filestream.o \ - xfs_fsops.o \ - xfs_ialloc.o \ - xfs_ialloc_btree.o \ - xfs_iget.o \ - xfs_inode.o \ - xfs_inode_item.o \ - xfs_iomap.o \ - xfs_itable.o \ - xfs_dfrag.o \ - xfs_log.o \ - xfs_log_recover.o \ - xfs_mount.o \ - xfs_mru_cache.o \ - xfs_rename.o \ - xfs_trans.o \ - xfs_trans_ail.o \ - xfs_trans_buf.o \ - xfs_trans_extfree.o \ - xfs_trans_inode.o \ - xfs_trans_item.o \ - xfs_utils.o \ - xfs_vfsops.o \ - xfs_vnodeops.o \ - xfs_rw.o \ - xfs_dmops.o \ - xfs_qmops.o - -xfs-$(CONFIG_XFS_TRACE) += xfs_dir2_trace.o - -# Objects in linux/ -xfs-y += $(addprefix $(XFS_LINUX)/, \ - kmem.o \ - xfs_aops.o \ - xfs_buf.o \ - xfs_export.o \ - xfs_file.o \ - xfs_fs_subr.o \ - xfs_globals.o \ - xfs_ioctl.o \ - xfs_iops.o \ - xfs_lrw.o \ - xfs_super.o \ - xfs_vnode.o) - -# Objects in support/ -xfs-y += $(addprefix support/, \ - debug.o \ - uuid.o) - -xfs-$(CONFIG_XFS_TRACE) += support/ktrace.o - -- cgit v1.2.3 From 794f744b225aaf35742aac9e7b9dda96a9943413 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Tue, 27 Nov 2007 16:59:56 +1100 Subject: [XFS] Fix up xfs out-of-tree builds. (a.k.a. external modules) Change -I include directives to find headers in the out-of-tree spot. This allows a directory containing only xfs files to be built as: SGI-PV: 971186 SGI-Modid: xfs-linux-melb:xfs-kern:29878a Signed-off-by: Eric Sandeen Signed-off-by: Donald Douwsma Signed-off-by: Lachlan McIlroy --- fs/xfs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 6bf3ee2bea5..57c923212d7 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -16,7 +16,7 @@ # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # -EXTRA_CFLAGS += -Ifs/xfs -Ifs/xfs/linux-2.6 -funsigned-char +EXTRA_CFLAGS += -I$(src) -I$(src)/linux-2.6 -funsigned-char XFS_LINUX := linux-2.6 -- cgit v1.2.3 From 269cdfaf769f5cd831284cc831790c7c5038040f Mon Sep 17 00:00:00 2001 From: Lachlan McIlroy Date: Wed, 28 Nov 2007 18:28:09 +1100 Subject: [XFS] Added quota targets and removed dmapi directory Fixes build failures introduced by bad merge to mainline. --- fs/xfs/Makefile | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) (limited to 'fs') diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 57c923212d7..36ec614e699 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -25,8 +25,18 @@ ifeq ($(CONFIG_XFS_DEBUG),y) endif obj-$(CONFIG_XFS_FS) += xfs.o -obj-$(CONFIG_XFS_QUOTA) += quota/ -obj-$(CONFIG_XFS_DMAPI) += dmapi/ + +xfs-$(CONFIG_XFS_QUOTA) += $(addprefix quota/, \ + xfs_dquot.o \ + xfs_dquot_item.o \ + xfs_trans_dquot.o \ + xfs_qm_syscalls.o \ + xfs_qm_bhv.o \ + xfs_qm.o) + +ifeq ($(CONFIG_XFS_QUOTA),y) +xfs-$(CONFIG_PROC_FS) += quota/xfs_qm_stats.o +endif xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o @@ -96,8 +106,7 @@ xfs-y += $(addprefix $(XFS_LINUX)/, \ xfs_iops.o \ xfs_lrw.o \ xfs_super.o \ - xfs_vnode.o \ - xfs_ksyms.o) + xfs_vnode.o) # Objects in support/ xfs-y += $(addprefix support/, \ @@ -106,17 +115,3 @@ xfs-y += $(addprefix support/, \ xfs-$(CONFIG_XFS_TRACE) += support/ktrace.o -# If both xfs and kdb modules are built in then xfsidbg is built in. If xfs is -# a module and kdb modules are being compiled then xfsidbg must be a module, to -# follow xfs. If xfs is built in then xfsidbg tracks the kdb module state. -# This must come after the main xfs code so xfs initialises before xfsidbg. -# KAO -ifneq ($(CONFIG_KDB_MODULES),) - ifeq ($(CONFIG_XFS_FS),y) - obj-$(CONFIG_KDB_MODULES) += xfsidbg.o - else - obj-$(CONFIG_XFS_FS) += xfsidbg.o - endif -endif - -CFLAGS_xfsidbg.o += -Iarch/$(ARCH)/kdb -- cgit v1.2.3 From 4c54ac62dceecedd82d4a865017bba0b738e2897 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 18 Feb 2008 13:48:31 +0100 Subject: make struct def_blk_aops static This patch makes the needlessly global struct def_blk_aops static. Signed-off-by: Adrian Bunk Signed-off-by: Jens Axboe --- fs/block_dev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/block_dev.c b/fs/block_dev.c index 67fe72ce6ac..8335f0e1b0f 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -31,6 +31,8 @@ struct bdev_inode { struct inode vfs_inode; }; +static const struct address_space_operations def_blk_aops; + static inline struct bdev_inode *BDEV_I(struct inode *inode) { return container_of(inode, struct bdev_inode, vfs_inode); @@ -1334,7 +1336,7 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg) return blkdev_ioctl(file->f_mapping->host, file, cmd, arg); } -const struct address_space_operations def_blk_aops = { +static const struct address_space_operations def_blk_aops = { .readpage = blkdev_readpage, .writepage = blkdev_writepage, .sync_page = block_sync_page, -- cgit v1.2.3 From 86b6c7a7f78feca58d2d8615e53aee4d59ab9dc6 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 18 Feb 2008 13:48:32 +0100 Subject: fs/block_dev.c: remove #if 0'ed code Commit b2e895dbd80c420bfc0937c3729b4afe073b3848 #if 0'ed this code stating: <-- snip --> [PATCH] revert blockdev direct io back to 2.6.19 version Andrew Vasquez is reporting as-iosched oopses and a 65% throughput slowdown due to the recent special-casing of direct-io against blockdevs. We don't know why either of these things are occurring. The patch minimally reverts us back to the 2.6.19 code for a 2.6.20 release. <-- snip --> It has since been dead code, and unless someone wants to revive it now it's time to remove it. This patch also makes bio_release_pages() static again and removes the ki_bio_count member from struct kiocb, reverting changes that had been done for this dead code. Signed-off-by: Adrian Bunk Signed-off-by: Jens Axboe --- fs/bio.c | 2 +- fs/block_dev.c | 197 --------------------------------------------------------- 2 files changed, 1 insertion(+), 198 deletions(-) (limited to 'fs') diff --git a/fs/bio.c b/fs/bio.c index 242e409dab4..3312fcc3c09 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -903,7 +903,7 @@ void bio_set_pages_dirty(struct bio *bio) } } -void bio_release_pages(struct bio *bio) +static void bio_release_pages(struct bio *bio) { struct bio_vec *bvec = bio->bi_io_vec; int i; diff --git a/fs/block_dev.c b/fs/block_dev.c index 8335f0e1b0f..7d822fae776 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -173,203 +173,6 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, iov, offset, nr_segs, blkdev_get_blocks, NULL); } -#if 0 -static void blk_end_aio(struct bio *bio, int error) -{ - struct kiocb *iocb = bio->bi_private; - atomic_t *bio_count = &iocb->ki_bio_count; - - if (bio_data_dir(bio) == READ) - bio_check_pages_dirty(bio); - else { - bio_release_pages(bio); - bio_put(bio); - } - - /* iocb->ki_nbytes stores error code from LLDD */ - if (error) - iocb->ki_nbytes = -EIO; - - if (atomic_dec_and_test(bio_count)) { - if ((long)iocb->ki_nbytes < 0) - aio_complete(iocb, iocb->ki_nbytes, 0); - else - aio_complete(iocb, iocb->ki_left, 0); - } - - return 0; -} - -#define VEC_SIZE 16 -struct pvec { - unsigned short nr; - unsigned short idx; - struct page *page[VEC_SIZE]; -}; - -#define PAGES_SPANNED(addr, len) \ - (DIV_ROUND_UP((addr) + (len), PAGE_SIZE) - (addr) / PAGE_SIZE); - -/* - * get page pointer for user addr, we internally cache struct page array for - * (addr, count) range in pvec to avoid frequent call to get_user_pages. If - * internal page list is exhausted, a batch count of up to VEC_SIZE is used - * to get next set of page struct. - */ -static struct page *blk_get_page(unsigned long addr, size_t count, int rw, - struct pvec *pvec) -{ - int ret, nr_pages; - if (pvec->idx == pvec->nr) { - nr_pages = PAGES_SPANNED(addr, count); - nr_pages = min(nr_pages, VEC_SIZE); - down_read(¤t->mm->mmap_sem); - ret = get_user_pages(current, current->mm, addr, nr_pages, - rw == READ, 0, pvec->page, NULL); - up_read(¤t->mm->mmap_sem); - if (ret < 0) - return ERR_PTR(ret); - pvec->nr = ret; - pvec->idx = 0; - } - return pvec->page[pvec->idx++]; -} - -/* return a page back to pvec array */ -static void blk_unget_page(struct page *page, struct pvec *pvec) -{ - pvec->page[--pvec->idx] = page; -} - -static ssize_t -blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, - loff_t pos, unsigned long nr_segs) -{ - struct inode *inode = iocb->ki_filp->f_mapping->host; - unsigned blkbits = blksize_bits(bdev_hardsect_size(I_BDEV(inode))); - unsigned blocksize_mask = (1 << blkbits) - 1; - unsigned long seg = 0; /* iov segment iterator */ - unsigned long nvec; /* number of bio vec needed */ - unsigned long cur_off; /* offset into current page */ - unsigned long cur_len; /* I/O len of current page, up to PAGE_SIZE */ - - unsigned long addr; /* user iovec address */ - size_t count; /* user iovec len */ - size_t nbytes = iocb->ki_nbytes = iocb->ki_left; /* total xfer size */ - loff_t size; /* size of block device */ - struct bio *bio; - atomic_t *bio_count = &iocb->ki_bio_count; - struct page *page; - struct pvec pvec; - - pvec.nr = 0; - pvec.idx = 0; - - if (pos & blocksize_mask) - return -EINVAL; - - size = i_size_read(inode); - if (pos + nbytes > size) { - nbytes = size - pos; - iocb->ki_left = nbytes; - } - - /* - * check first non-zero iov alignment, the remaining - * iov alignment is checked inside bio loop below. - */ - do { - addr = (unsigned long) iov[seg].iov_base; - count = min(iov[seg].iov_len, nbytes); - if (addr & blocksize_mask || count & blocksize_mask) - return -EINVAL; - } while (!count && ++seg < nr_segs); - atomic_set(bio_count, 1); - - while (nbytes) { - /* roughly estimate number of bio vec needed */ - nvec = (nbytes + PAGE_SIZE - 1) / PAGE_SIZE; - nvec = max(nvec, nr_segs - seg); - nvec = min(nvec, (unsigned long) BIO_MAX_PAGES); - - /* bio_alloc should not fail with GFP_KERNEL flag */ - bio = bio_alloc(GFP_KERNEL, nvec); - bio->bi_bdev = I_BDEV(inode); - bio->bi_end_io = blk_end_aio; - bio->bi_private = iocb; - bio->bi_sector = pos >> blkbits; -same_bio: - cur_off = addr & ~PAGE_MASK; - cur_len = PAGE_SIZE - cur_off; - if (count < cur_len) - cur_len = count; - - page = blk_get_page(addr, count, rw, &pvec); - if (unlikely(IS_ERR(page))) - goto backout; - - if (bio_add_page(bio, page, cur_len, cur_off)) { - pos += cur_len; - addr += cur_len; - count -= cur_len; - nbytes -= cur_len; - - if (count) - goto same_bio; - while (++seg < nr_segs) { - addr = (unsigned long) iov[seg].iov_base; - count = iov[seg].iov_len; - if (!count) - continue; - if (unlikely(addr & blocksize_mask || - count & blocksize_mask)) { - page = ERR_PTR(-EINVAL); - goto backout; - } - count = min(count, nbytes); - goto same_bio; - } - } else { - blk_unget_page(page, &pvec); - } - - /* bio is ready, submit it */ - if (rw == READ) - bio_set_pages_dirty(bio); - atomic_inc(bio_count); - submit_bio(rw, bio); - } - -completion: - iocb->ki_left -= nbytes; - nbytes = iocb->ki_left; - iocb->ki_pos += nbytes; - - blk_run_address_space(inode->i_mapping); - if (atomic_dec_and_test(bio_count)) - aio_complete(iocb, nbytes, 0); - - return -EIOCBQUEUED; - -backout: - /* - * back out nbytes count constructed so far for this bio, - * we will throw away current bio. - */ - nbytes += bio->bi_size; - bio_release_pages(bio); - bio_put(bio); - - /* - * if no bio was submmitted, return the error code. - * otherwise, proceed with pending I/O completion. - */ - if (atomic_read(bio_count) == 1) - return PTR_ERR(page); - goto completion; -} -#endif - static int blkdev_writepage(struct page *page, struct writeback_control *wbc) { return block_write_full_page(page, blkdev_get_block, wbc); -- cgit v1.2.3 From 1227a74e2e0217a4ca155d1677bdbf5f69e32bed Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 19 Feb 2008 12:51:35 -0500 Subject: NFS: flush signals before taking down callback thread Now that the reference counting on the callback thread is working as expected, it uncovers another problem. Peter Staubach noticed while testing that patch on an older kernel that he would occasionally see this printk in rpc_register fire: "RPC: failed to contact portmap (errno -512). The NFSv4 callback thread is signaled by nfs_callback_down(), but never flushes that signal. All of the shutdown processing is done with that signal pending. This makes it fail the call to unregister the port with the portmapper. In actuality, this rpc_register call isn't necessary at all since the port isn't actually registered with the portmapper anymore. Regardless, there doesn't seem to be any reason to leave the signal pending while the thread is being shut down and flushing it should generally silence that printk. Signed-off-by: Jeff Layton Signed-off-by: Trond Myklebust --- fs/nfs/callback.c | 1 + 1 file changed, 1 insertion(+) (limited to 'fs') diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index ecc06c61949..0d784f6f609 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -93,6 +93,7 @@ static void nfs_callback_svc(struct svc_rqst *rqstp) svc_process(rqstp); } + flush_signals(current); svc_exit_thread(rqstp); nfs_callback_info.pid = 0; complete(&nfs_callback_info.stopped); -- cgit v1.2.3 From 90dc7d2796edf94a9eaa838321a9734c8513e717 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 20 Feb 2008 13:03:05 -0800 Subject: nfs: fix sparse warnings fs/nfs/nfs4state.c:788:34: warning: Using plain integer as NULL pointer fs/nfs/delegation.c:52:34: warning: Using plain integer as NULL pointer fs/nfs/idmap.c:312:12: warning: Using plain integer as NULL pointer fs/nfs/callback_xdr.c:257:6: warning: Using plain integer as NULL pointer fs/nfs/callback_xdr.c:270:6: warning: Using plain integer as NULL pointer fs/nfs/callback_xdr.c:281:6: warning: Using plain integer as NULL pointer Signed-off-by: Harvey Harrison Signed-off-by: Trond Myklebust --- fs/nfs/callback_xdr.c | 6 +++--- fs/nfs/delegation.c | 2 +- fs/nfs/idmap.c | 2 +- fs/nfs/nfs4state.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'fs') diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index c63eb720b68..13619d24f02 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c @@ -254,7 +254,7 @@ static __be32 encode_attr_change(struct xdr_stream *xdr, const uint32_t *bitmap, if (!(bitmap[0] & FATTR4_WORD0_CHANGE)) return 0; p = xdr_reserve_space(xdr, 8); - if (unlikely(p == 0)) + if (unlikely(!p)) return htonl(NFS4ERR_RESOURCE); p = xdr_encode_hyper(p, change); return 0; @@ -267,7 +267,7 @@ static __be32 encode_attr_size(struct xdr_stream *xdr, const uint32_t *bitmap, u if (!(bitmap[0] & FATTR4_WORD0_SIZE)) return 0; p = xdr_reserve_space(xdr, 8); - if (unlikely(p == 0)) + if (unlikely(!p)) return htonl(NFS4ERR_RESOURCE); p = xdr_encode_hyper(p, size); return 0; @@ -278,7 +278,7 @@ static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec *ti __be32 *p; p = xdr_reserve_space(xdr, 12); - if (unlikely(p == 0)) + if (unlikely(!p)) return htonl(NFS4ERR_RESOURCE); p = xdr_encode_hyper(p, time->tv_sec); *p = htonl(time->tv_nsec); diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index b9eadd18ba7..00a5e4405e1 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -49,7 +49,7 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_ struct file_lock *fl; int status; - for (fl = inode->i_flock; fl != 0; fl = fl->fl_next) { + for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) continue; if (nfs_file_open_context(fl->fl_file) != ctx) diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index 8ae5dba2d4e..86147b0ab2c 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c @@ -309,7 +309,7 @@ nfs_idmap_name(struct idmap *idmap, struct idmap_hashtable *h, mutex_lock(&idmap->idmap_im_lock); he = idmap_lookup_id(h, id); - if (he != 0) { + if (he) { memcpy(name, he->ih_name, he->ih_namelen); ret = he->ih_namelen; goto out; diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 6233eb5e98c..b962397004c 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -785,7 +785,7 @@ static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_s struct file_lock *fl; int status = 0; - for (fl = inode->i_flock; fl != 0; fl = fl->fl_next) { + for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) continue; if (nfs_file_open_context(fl->fl_file)->state != state) -- cgit v1.2.3 From 1803f3389b7ac9ed33ea561b3b94e22e2864a95d Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 20 Feb 2008 19:55:09 -0800 Subject: Remove empty file remnants that were left in the tree by mistake Noted by various people (Sam, Jeff, Roland..) Commit 58b7983d15a422d9616bdc4e245d5c31dfaefbe2 intended to remove the xfs "Makefile-linux-2.6" file, but it was mistakenly still left in the tree as a empty file, and would cause git to correctly complain about a tracked file being removed after a "make distclean" (which removes empty files as garbage). And the asm-x86/desc_64.h file was supposed to be removed by commit c81c6ca45a69478c7877b729af1942d2b80ef582, but instead stayed around containing just a single newline. Get rid of them both properly. Signed-off-by: Linus Torvalds --- fs/xfs/Makefile-linux-2.6 | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 fs/xfs/Makefile-linux-2.6 (limited to 'fs') diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6 deleted file mode 100644 index e69de29bb2d..00000000000 -- cgit v1.2.3 From 599e0f584de8ff16b1428e2e16118757619f1d1b Mon Sep 17 00:00:00 2001 From: David Teigland Date: Thu, 21 Feb 2008 13:39:57 -0600 Subject: dlm: fix rcom_names message to self The recent patch to validate data lengths in rcom_names messages failed to account for fake messages a node directs to itself before ever sending it. In this case we need to fill in the message length in the header for the validation code to use. Signed-off-by: David Teigland --- fs/dlm/rcom.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'fs') diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c index 035e6f9990b..67522c268c1 100644 --- a/fs/dlm/rcom.c +++ b/fs/dlm/rcom.c @@ -215,6 +215,8 @@ int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len) ls->ls_recover_nodeid = nodeid; if (nodeid == dlm_our_nodeid()) { + ls->ls_recover_buf->rc_header.h_length = + dlm_config.ci_buffer_size; dlm_copy_master_names(ls, last_name, last_len, ls->ls_recover_buf->rc_buf, max_size, nodeid); -- cgit v1.2.3 From 5216a8e70e25b01cbd2915cd0442fb96deb2c262 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Thu, 21 Feb 2008 10:57:45 +0300 Subject: Wrap buffers used for rpc debug printks into RPC_IFDEBUG Sorry for the noise, but here's the v3 of this compilation fix :) There are some places, which declare the char buf[...] on the stack to push it later into dprintk(). Since the dprintk sometimes (if the CONFIG_SYSCTL=n) becomes an empty do { } while (0) stub, these buffers cause gcc to produce appropriate warnings. Wrap these buffers with RPC_IFDEBUG macro, as Trond proposed, to compile them out when not needed. Signed-off-by: Pavel Emelyanov Acked-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/lockd/svc.c | 2 +- fs/nfs/callback.c | 2 +- fs/nfsd/nfsfh.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 08226464e56..1ed8bd4de94 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -153,7 +153,7 @@ lockd(struct svc_rqst *rqstp) */ while ((nlmsvc_users || !signalled()) && nlmsvc_pid == current->pid) { long timeout = MAX_SCHEDULE_TIMEOUT; - char buf[RPC_MAX_ADDRBUFLEN]; + RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); if (signalled()) { flush_signals(current); diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 0d784f6f609..66648dd92d9 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -172,7 +172,7 @@ void nfs_callback_down(void) static int nfs_callback_authenticate(struct svc_rqst *rqstp) { struct nfs_client *clp; - char buf[RPC_MAX_ADDRBUFLEN]; + RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); /* Don't talk to strangers */ clp = nfs_find_client(svc_addr(rqstp), 4); diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 0130b345234..1eb771d79cc 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -101,7 +101,7 @@ static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp, { /* Check if the request originated from a secure port. */ if (!rqstp->rq_secure && EX_SECURE(exp)) { - char buf[RPC_MAX_ADDRBUFLEN]; + RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); dprintk(KERN_WARNING "nfsd: request from insecure port %s!\n", svc_print_addr(rqstp, buf, sizeof(buf))); -- cgit v1.2.3 From f5ab0d1f8f7df937778c60c3da6f4ef939a54a7b Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Mon, 25 Feb 2008 15:29:55 -0500 Subject: ext4: Fix BUG when writing to an unitialized extent This patch fixes a bug when writing to preallocated but uninitialized blocks, which resulted in a BUG in fs/buffer.c saying that the buffer is not mapped. When writing to a file, ext4_get_block_wrap() is called with create=1 in order to request that blocks be allocated if necessary. It currently calls ext4_get_blocks() with create=0 in order to do a lookup first. If the inode contains an unitialized data block, the buffer head is left unampped, which ext4_get_blocks_wrap() returns, causing the BUG. We fix this by checking to see if the buffer head is unmapped, and if so, we make sure the the buffer head is mapped by calling ext4_ext_get_blocks with create=1. Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 13 +++++++++++++ fs/ext4/inode.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 57 insertions(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 8a59f7ba30e..bcf5d040e32 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2287,9 +2287,22 @@ out: } /* + * Block allocation/map/preallocation routine for extents based files + * + * * Need to be called with * down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system block * (ie, create is zero). Otherwise down_write(&EXT4_I(inode)->i_data_sem) + * + * return > 0, number of of blocks already mapped/allocated + * if create == 0 and these are pre-allocated blocks + * buffer head is unmapped + * otherwise blocks are mapped + * + * return = 0, if plain look up failed (blocks have not been allocated) + * buffer head is unmapped + * + * return < 0, error case. */ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, ext4_lblk_t iblock, diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 34f3eb615fd..945cbf6cb1f 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -908,11 +908,38 @@ out: */ #define DIO_CREDITS 25 + +/* + * + * + * ext4_ext4 get_block() wrapper function + * It will do a look up first, and returns if the blocks already mapped. + * Otherwise it takes the write lock of the i_data_sem and allocate blocks + * and store the allocated blocks in the result buffer head and mark it + * mapped. + * + * If file type is extents based, it will call ext4_ext_get_blocks(), + * Otherwise, call with ext4_get_blocks_handle() to handle indirect mapping + * based files + * + * On success, it returns the number of blocks being mapped or allocate. + * if create==0 and the blocks are pre-allocated and uninitialized block, + * the result buffer head is unmapped. If the create ==1, it will make sure + * the buffer head is mapped. + * + * It returns 0 if plain look up failed (blocks have not been allocated), in + * that casem, buffer head is unmapped + * + * It returns the error in case of allocation failure. + */ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, unsigned long max_blocks, struct buffer_head *bh, int create, int extend_disksize) { int retval; + + clear_buffer_mapped(bh); + /* * Try to see if we can get the block without requesting * for new file system block. @@ -926,12 +953,26 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, inode, block, max_blocks, bh, 0, 0); } up_read((&EXT4_I(inode)->i_data_sem)); - if (!create || (retval > 0)) + + /* If it is only a block(s) look up */ + if (!create) + return retval; + + /* + * Returns if the blocks have already allocated + * + * Note that if blocks have been preallocated + * ext4_ext_get_block() returns th create = 0 + * with buffer head unmapped. + */ + if (retval > 0 && buffer_mapped(bh)) return retval; /* - * We need to allocate new blocks which will result - * in i_data update + * New blocks allocate and/or writing to uninitialized extent + * will possibly result in updating i_data, so we take + * the write lock of i_data_sem, and call get_blocks() + * with create == 1 flag. */ down_write((&EXT4_I(inode)->i_data_sem)); /* -- cgit v1.2.3 From 2c98615d3b64ce7888cd46cc668023f456daf287 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Mon, 25 Feb 2008 15:41:35 -0500 Subject: ext4: Don't mark filesystem error if fallocate fails If we fail to allocate blocks don't call ext4_error. Also don't hide errors from ext4_get_blocks_wrap Signed-off-by: Aneesh Kumar K.V Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'fs') diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index bcf5d040e32..9ae6e67090c 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2661,13 +2661,14 @@ retry: ret = ext4_get_blocks_wrap(handle, inode, block, max_blocks, &map_bh, EXT4_CREATE_UNINITIALIZED_EXT, 0); - WARN_ON(ret <= 0); if (ret <= 0) { - ext4_error(inode->i_sb, "ext4_fallocate", - "ext4_ext_get_blocks returned error: " - "inode#%lu, block=%u, max_blocks=%lu", +#ifdef EXT4FS_DEBUG + WARN_ON(ret <= 0); + printk(KERN_ERR "%s: ext4_ext_get_blocks " + "returned error inode#%lu, block=%u, " + "max_blocks=%lu", __func__, inode->i_ino, block, max_blocks); - ret = -EIO; +#endif ext4_mark_inode_dirty(handle, inode); ret2 = ext4_journal_stop(handle); break; -- cgit v1.2.3 From 42bf0383d1e09dd1b38f3debb13a76b2f87634b3 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Mon, 25 Feb 2008 16:38:03 -0500 Subject: ext4: set EXT4_EXTENTS_FL only for directory and regular files In addition, don't inherit EXT4_EXTENTS_FL from parent directory. If we have a directory with extent flag set and later mount the file system with -o noextents, the files created in that directory will also have extent flag set but we would not have called ext4_ext_tree_init for them. This will cause error later when we are verifying the extent header Signed-off-by: Aneesh Kumar K.V Acked-off-by: Eric Sandeen Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" --- fs/ext4/ialloc.c | 22 +++++++++++++++------- fs/ext4/namei.c | 1 - 2 files changed, 15 insertions(+), 8 deletions(-) (limited to 'fs') diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index da18a74b966..8036b9b5376 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -702,7 +702,12 @@ got: ei->i_dir_start_lookup = 0; ei->i_disksize = 0; - ei->i_flags = EXT4_I(dir)->i_flags & ~EXT4_INDEX_FL; + /* + * Don't inherit extent flag from directory. We set extent flag on + * newly created directory and file only if -o extent mount option is + * specified + */ + ei->i_flags = EXT4_I(dir)->i_flags & ~(EXT4_INDEX_FL|EXT4_EXTENTS_FL); if (S_ISLNK(mode)) ei->i_flags &= ~(EXT4_IMMUTABLE_FL|EXT4_APPEND_FL); /* dirsync only applies to directories */ @@ -745,12 +750,15 @@ got: goto fail_free_drop; } if (test_opt(sb, EXTENTS)) { - EXT4_I(inode)->i_flags |= EXT4_EXTENTS_FL; - ext4_ext_tree_init(handle, inode); - err = ext4_update_incompat_feature(handle, sb, - EXT4_FEATURE_INCOMPAT_EXTENTS); - if (err) - goto fail; + /* set extent flag only for directory and file */ + if (S_ISDIR(mode) || S_ISREG(mode)) { + EXT4_I(inode)->i_flags |= EXT4_EXTENTS_FL; + ext4_ext_tree_init(handle, inode); + err = ext4_update_incompat_feature(handle, sb, + EXT4_FEATURE_INCOMPAT_EXTENTS); + if (err) + goto fail; + } } ext4_debug("allocating inode %lu\n", inode->i_ino); diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 5a79c6b6dc6..28aa2ed4297 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -2220,7 +2220,6 @@ retry: inode->i_op = &ext4_fast_symlink_inode_operations; memcpy((char*)&EXT4_I(inode)->i_data,symname,l); inode->i_size = l-1; - EXT4_I(inode)->i_flags &= ~EXT4_EXTENTS_FL; } EXT4_I(inode)->i_disksize = inode->i_size; err = ext4_add_nondir(handle, dentry, inode); -- cgit v1.2.3 From ffad0a44b7216d0f079dcf95a351082099d1e5fb Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Sat, 23 Feb 2008 01:38:34 -0500 Subject: ext4: ext4_find_next_zero_bit needs an aligned address on some arch ext4_find_next_zero_bit and ext4_find_next_bit needs a long aligned address on x8_64. Add mb_find_next_zero_bit and mb_find_next_bit and use them in the mballoc. Fix: https://bugzilla.redhat.com/show_bug.cgi?id=433286 Eric Sandeen debugged the problem and suggested the fix. Signed-off-by: Aneesh Kumar K.V Acked-by: Eric Sandeen Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" --- fs/ext4/mballoc.c | 62 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 22 deletions(-) (limited to 'fs') diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 6968c53e62a..ef97f19c2f9 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -627,21 +627,19 @@ static ext4_fsblk_t ext4_grp_offs_to_block(struct super_block *sb, return block; } +static inline void *mb_correct_addr_and_bit(int *bit, void *addr) +{ #if BITS_PER_LONG == 64 -#define mb_correct_addr_and_bit(bit, addr) \ -{ \ - bit += ((unsigned long) addr & 7UL) << 3; \ - addr = (void *) ((unsigned long) addr & ~7UL); \ -} + *bit += ((unsigned long) addr & 7UL) << 3; + addr = (void *) ((unsigned long) addr & ~7UL); #elif BITS_PER_LONG == 32 -#define mb_correct_addr_and_bit(bit, addr) \ -{ \ - bit += ((unsigned long) addr & 3UL) << 3; \ - addr = (void *) ((unsigned long) addr & ~3UL); \ -} + *bit += ((unsigned long) addr & 3UL) << 3; + addr = (void *) ((unsigned long) addr & ~3UL); #else #error "how many bits you are?!" #endif + return addr; +} static inline int mb_test_bit(int bit, void *addr) { @@ -649,34 +647,54 @@ static inline int mb_test_bit(int bit, void *addr) * ext4_test_bit on architecture like powerpc * needs unsigned long aligned address */ - mb_correct_addr_and_bit(bit, addr); + addr = mb_correct_addr_and_bit(&bit, addr); return ext4_test_bit(bit, addr); } static inline void mb_set_bit(int bit, void *addr) { - mb_correct_addr_and_bit(bit, addr); + addr = mb_correct_addr_and_bit(&bit, addr); ext4_set_bit(bit, addr); } static inline void mb_set_bit_atomic(spinlock_t *lock, int bit, void *addr) { - mb_correct_addr_and_bit(bit, addr); + addr = mb_correct_addr_and_bit(&bit, addr); ext4_set_bit_atomic(lock, bit, addr); } static inline void mb_clear_bit(int bit, void *addr) { - mb_correct_addr_and_bit(bit, addr); + addr = mb_correct_addr_and_bit(&bit, addr); ext4_clear_bit(bit, addr); } static inline void mb_clear_bit_atomic(spinlock_t *lock, int bit, void *addr) { - mb_correct_addr_and_bit(bit, addr); + addr = mb_correct_addr_and_bit(&bit, addr); ext4_clear_bit_atomic(lock, bit, addr); } +static inline int mb_find_next_zero_bit(void *addr, int max, int start) +{ + int fix = 0; + addr = mb_correct_addr_and_bit(&fix, addr); + max += fix; + start += fix; + + return ext4_find_next_zero_bit(addr, max, start) - fix; +} + +static inline int mb_find_next_bit(void *addr, int max, int start) +{ + int fix = 0; + addr = mb_correct_addr_and_bit(&fix, addr); + max += fix; + start += fix; + + return ext4_find_next_bit(addr, max, start) - fix; +} + static void *mb_find_buddy(struct ext4_buddy *e4b, int order, int *max) { char *bb; @@ -946,12 +964,12 @@ static void ext4_mb_generate_buddy(struct super_block *sb, /* initialize buddy from bitmap which is aggregation * of on-disk bitmap and preallocations */ - i = ext4_find_next_zero_bit(bitmap, max, 0); + i = mb_find_next_zero_bit(bitmap, max, 0); grp->bb_first_free = i; while (i < max) { fragments++; first = i; - i = ext4_find_next_bit(bitmap, max, i); + i = mb_find_next_bit(bitmap, max, i); len = i - first; free += len; if (len > 1) @@ -959,7 +977,7 @@ static void ext4_mb_generate_buddy(struct super_block *sb, else grp->bb_counters[0]++; if (i < max) - i = ext4_find_next_zero_bit(bitmap, max, i); + i = mb_find_next_zero_bit(bitmap, max, i); } grp->bb_fragments = fragments; @@ -1782,7 +1800,7 @@ static void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac, buddy = mb_find_buddy(e4b, i, &max); BUG_ON(buddy == NULL); - k = ext4_find_next_zero_bit(buddy, max, 0); + k = mb_find_next_zero_bit(buddy, max, 0); BUG_ON(k >= max); ac->ac_found++; @@ -1822,7 +1840,7 @@ static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, i = e4b->bd_info->bb_first_free; while (free && ac->ac_status == AC_STATUS_CONTINUE) { - i = ext4_find_next_zero_bit(bitmap, + i = mb_find_next_zero_bit(bitmap, EXT4_BLOCKS_PER_GROUP(sb), i); if (i >= EXT4_BLOCKS_PER_GROUP(sb)) { /* @@ -3750,10 +3768,10 @@ static int ext4_mb_release_inode_pa(struct ext4_buddy *e4b, } while (bit < end) { - bit = ext4_find_next_zero_bit(bitmap_bh->b_data, end, bit); + bit = mb_find_next_zero_bit(bitmap_bh->b_data, end, bit); if (bit >= end) break; - next = ext4_find_next_bit(bitmap_bh->b_data, end, bit); + next = mb_find_next_bit(bitmap_bh->b_data, end, bit); if (next > end) next = end; start = group * EXT4_BLOCKS_PER_GROUP(sb) + bit + -- cgit v1.2.3 From 1a823ac9ff09cbdf39201df37b7ede1f9395de83 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Sat, 23 Feb 2008 15:23:27 -0800 Subject: fuse: fix permission checking I added a nasty local variable shadowing bug to fuse in 2.6.24, with the result, that the 'default_permissions' mount option is basically ignored. How did this happen? - old err declaration in inner scope - new err getting declared in outer scope - 'return err' from inner scope getting removed - old declaration not being noticed -Wshadow would have saved us, but it doesn't seem practical for the kernel :( More testing would have also saved us :(( Signed-off-by: Miklos Szeredi Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/fuse/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 7fb514b6d85..c4807b3fc8a 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -906,7 +906,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) } if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { - int err = generic_permission(inode, mask, NULL); + err = generic_permission(inode, mask, NULL); /* If permission is denied, try to refresh file attributes. This is also needed, because the root -- cgit v1.2.3 From f81e8a43871f44f98dd14e83a83bf9ca0b3b46c5 Mon Sep 17 00:00:00 2001 From: Roel Kluin <12o3l@tiscali.nl> Date: Sat, 23 Feb 2008 15:23:29 -0800 Subject: ufs: fix parenthesisation in ufs_set_fs_state() This bug snuck in with commit 252e211e90ce56bf005cb533ad5a297c18c19407 Author: Mark Fortescue Date: Tue Oct 16 23:26:31 2007 -0700 Add in SunOS 4.1.x compatible mode for UFS Signed-off-by: Roel Kluin <12o3l@tiscali.nl> Acked-by: Evgeniy Dushistov Cc: Mark Fortescue Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ufs/util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/ufs/util.h b/fs/ufs/util.h index b26fc4dec1e..23ceed8c8fb 100644 --- a/fs/ufs/util.h +++ b/fs/ufs/util.h @@ -58,7 +58,7 @@ ufs_set_fs_state(struct super_block *sb, struct ufs_super_block_first *usb1, { switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { case UFS_ST_SUNOS: - if (fs32_to_cpu(sb, usb3->fs_postblformat == UFS_42POSTBLFMT)) { + if (fs32_to_cpu(sb, usb3->fs_postblformat) == UFS_42POSTBLFMT) { usb1->fs_u0.fs_sun.fs_state = cpu_to_fs32(sb, value); break; } -- cgit v1.2.3 From 745329c4a2a25efbf5ba6cd7842e07840e4e9775 Mon Sep 17 00:00:00 2001 From: Hans Rosenfeld Date: Sat, 23 Feb 2008 15:23:31 -0800 Subject: /proc/pid/pagemap: fix PM_SPECIAL macro There seems to be a bug in the PM_SPECIAL macro for /proc/pid/pagemap. I think masking out those other bits makes more sense then setting all those mask bits. Signed-off-by: Hans Rosenfeld Acked-by: Matt Mackall Cc: Dave Hansen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/task_mmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 49958cffbd8..6dc0334815f 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -531,7 +531,7 @@ struct pagemapread { #define PM_RESERVED_BITS 3 #define PM_RESERVED_OFFSET (64 - PM_RESERVED_BITS) #define PM_RESERVED_MASK (((1LL< Date: Sat, 23 Feb 2008 15:23:51 -0800 Subject: efs: move headers out of include/linux/ Merge include/linux/efs_fs{_i,_dir}.h into fs/efs/efs.h. efs_vh.h remains there because this is the IRIX volume header and shouldn't really be handled by efs but by the partitioning code. efs_sb.h remains there for now because it's exported to userspace. Of course this wrong and aboot should have a copy of it's own, but I'll leave that to a separate patch to avoid any contention. Signed-off-by: Christoph Hellwig Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/efs/dir.c | 2 +- fs/efs/efs.h | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/efs/file.c | 2 +- fs/efs/inode.c | 4 +- fs/efs/namei.c | 2 +- fs/efs/super.c | 7 +-- fs/efs/symlink.c | 2 +- 7 files changed, 150 insertions(+), 9 deletions(-) create mode 100644 fs/efs/efs.h (limited to 'fs') diff --git a/fs/efs/dir.c b/fs/efs/dir.c index dfb5cb40021..49308a29798 100644 --- a/fs/efs/dir.c +++ b/fs/efs/dir.c @@ -5,8 +5,8 @@ */ #include -#include #include +#include "efs.h" static int efs_readdir(struct file *, void *, filldir_t); diff --git a/fs/efs/efs.h b/fs/efs/efs.h new file mode 100644 index 00000000000..d8305b582ab --- /dev/null +++ b/fs/efs/efs.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 1999 Al Smith + * + * Portions derived from work (c) 1995,1996 Christian Vogelgsang. + * Portions derived from IRIX header files (c) 1988 Silicon Graphics + */ +#ifndef _EFS_EFS_H_ +#define _EFS_EFS_H_ + +#include +#include + +#define EFS_VERSION "1.0a" + +static const char cprt[] = "EFS: "EFS_VERSION" - (c) 1999 Al Smith "; + + +/* 1 block is 512 bytes */ +#define EFS_BLOCKSIZE_BITS 9 +#define EFS_BLOCKSIZE (1 << EFS_BLOCKSIZE_BITS) + +typedef int32_t efs_block_t; +typedef uint32_t efs_ino_t; + +#define EFS_DIRECTEXTENTS 12 + +/* + * layout of an extent, in memory and on disk. 8 bytes exactly. + */ +typedef union extent_u { + unsigned char raw[8]; + struct extent_s { + unsigned int ex_magic:8; /* magic # (zero) */ + unsigned int ex_bn:24; /* basic block */ + unsigned int ex_length:8; /* numblocks in this extent */ + unsigned int ex_offset:24; /* logical offset into file */ + } cooked; +} efs_extent; + +typedef struct edevs { + __be16 odev; + __be32 ndev; +} efs_devs; + +/* + * extent based filesystem inode as it appears on disk. The efs inode + * is exactly 128 bytes long. + */ +struct efs_dinode { + __be16 di_mode; /* mode and type of file */ + __be16 di_nlink; /* number of links to file */ + __be16 di_uid; /* owner's user id */ + __be16 di_gid; /* owner's group id */ + __be32 di_size; /* number of bytes in file */ + __be32 di_atime; /* time last accessed */ + __be32 di_mtime; /* time last modified */ + __be32 di_ctime; /* time created */ + __be32 di_gen; /* generation number */ + __be16 di_numextents; /* # of extents */ + u_char di_version; /* version of inode */ + u_char di_spare; /* spare - used by AFS */ + union di_addr { + efs_extent di_extents[EFS_DIRECTEXTENTS]; + efs_devs di_dev; /* device for IFCHR/IFBLK */ + } di_u; +}; + +/* efs inode storage in memory */ +struct efs_inode_info { + int numextents; + int lastextent; + + efs_extent extents[EFS_DIRECTEXTENTS]; + struct inode vfs_inode; +}; + +#include + +#define EFS_DIRBSIZE_BITS EFS_BLOCKSIZE_BITS +#define EFS_DIRBSIZE (1 << EFS_DIRBSIZE_BITS) + +struct efs_dentry { + __be32 inode; + unsigned char namelen; + char name[3]; +}; + +#define EFS_DENTSIZE (sizeof(struct efs_dentry) - 3 + 1) +#define EFS_MAXNAMELEN ((1 << (sizeof(char) * 8)) - 1) + +#define EFS_DIRBLK_HEADERSIZE 4 +#define EFS_DIRBLK_MAGIC 0xbeef /* moo */ + +struct efs_dir { + __be16 magic; + unsigned char firstused; + unsigned char slots; + + unsigned char space[EFS_DIRBSIZE - EFS_DIRBLK_HEADERSIZE]; +}; + +#define EFS_MAXENTS \ + ((EFS_DIRBSIZE - EFS_DIRBLK_HEADERSIZE) / \ + (EFS_DENTSIZE + sizeof(char))) + +#define EFS_SLOTAT(dir, slot) EFS_REALOFF((dir)->space[slot]) + +#define EFS_REALOFF(offset) ((offset << 1)) + + +static inline struct efs_inode_info *INODE_INFO(struct inode *inode) +{ + return container_of(inode, struct efs_inode_info, vfs_inode); +} + +static inline struct efs_sb_info *SUPER_INFO(struct super_block *sb) +{ + return sb->s_fs_info; +} + +struct statfs; +struct fid; + +extern const struct inode_operations efs_dir_inode_operations; +extern const struct file_operations efs_dir_operations; +extern const struct address_space_operations efs_symlink_aops; + +extern struct inode *efs_iget(struct super_block *, unsigned long); +extern efs_block_t efs_map_block(struct inode *, efs_block_t); +extern int efs_get_block(struct inode *, sector_t, struct buffer_head *, int); + +extern struct dentry *efs_lookup(struct inode *, struct dentry *, struct nameidata *); +extern struct dentry *efs_fh_to_dentry(struct super_block *sb, struct fid *fid, + int fh_len, int fh_type); +extern struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid, + int fh_len, int fh_type); +extern struct dentry *efs_get_parent(struct dentry *); +extern int efs_bmap(struct inode *, int); + +#endif /* _EFS_EFS_H_ */ diff --git a/fs/efs/file.c b/fs/efs/file.c index 5db20129681..1ccb364ffa6 100644 --- a/fs/efs/file.c +++ b/fs/efs/file.c @@ -7,7 +7,7 @@ */ #include -#include +#include "efs.h" int efs_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) diff --git a/fs/efs/inode.c b/fs/efs/inode.c index 627c3026946..79e19e5958e 100644 --- a/fs/efs/inode.c +++ b/fs/efs/inode.c @@ -7,11 +7,11 @@ * and from work (c) 1998 Mike Shaver. */ -#include -#include #include #include #include +#include "efs.h" +#include static int efs_readpage(struct file *file, struct page *page) { diff --git a/fs/efs/namei.c b/fs/efs/namei.c index e26704742d4..3a404e7fad5 100644 --- a/fs/efs/namei.c +++ b/fs/efs/namei.c @@ -8,9 +8,9 @@ #include #include -#include #include #include +#include "efs.h" static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) { diff --git a/fs/efs/super.c b/fs/efs/super.c index 14082405cdd..d733531b55e 100644 --- a/fs/efs/super.c +++ b/fs/efs/super.c @@ -8,14 +8,15 @@ #include #include -#include -#include -#include #include #include #include #include +#include "efs.h" +#include +#include + static int efs_statfs(struct dentry *dentry, struct kstatfs *buf); static int efs_fill_super(struct super_block *s, void *d, int silent); diff --git a/fs/efs/symlink.c b/fs/efs/symlink.c index 1d30d2ff440..41911ec83aa 100644 --- a/fs/efs/symlink.c +++ b/fs/efs/symlink.c @@ -7,10 +7,10 @@ */ #include -#include #include #include #include +#include "efs.h" static int efs_symlink_readpage(struct file *file, struct page *page) { -- cgit v1.2.3 From 8808117ca571fd63e188a2306baae86cca9fce7a Mon Sep 17 00:00:00 2001 From: Eugene Teo Date: Sat, 23 Feb 2008 15:23:52 -0800 Subject: proc: add RLIMIT_RTTIME to /proc//limits RLIMIT_RTTIME was introduced to allow the user to set a runtime timeout on real-time tasks: http://lkml.org/lkml/2007/12/18/218. This patch updates /proc//limits with the new rlimit. Signed-off-by: Eugene Teo Acked-by: Peter Zijlstra Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/base.c | 1 + 1 file changed, 1 insertion(+) (limited to 'fs') diff --git a/fs/proc/base.c b/fs/proc/base.c index 88f8edf1825..96ee899d650 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -416,6 +416,7 @@ static const struct limit_names lnames[RLIM_NLIMITS] = { [RLIMIT_MSGQUEUE] = {"Max msgqueue size", "bytes"}, [RLIMIT_NICE] = {"Max nice priority", NULL}, [RLIMIT_RTPRIO] = {"Max realtime priority", NULL}, + [RLIMIT_RTTIME] = {"Max realtime timeout", "us"}, }; /* Display limits for a process */ -- cgit v1.2.3 From ae0027869db7d28563cd783865fab04ffd18419c Mon Sep 17 00:00:00 2001 From: Hiroshi Shimamoto Date: Thu, 14 Feb 2008 10:26:24 -0800 Subject: latencytop: fix kernel panic while reading latency proc file Reading /proc//latency or /proc//task//latency could cause NULL pointer dereference. In lstats_open(), get_proc_task() can return NULL, in which case the kernel will oops at lstats_show_proc() because m->private is NULL. When get_proc_task() returns NULL, the kernel should return -ENOENT. This can be reproduced by the following script. while : do date bash -c 'ls > ls.$$' & pid=$! cat /proc/$pid/latency & cat /proc/$pid/latency & cat /proc/$pid/latency & cat /proc/$pid/latency done Signed-off-by: Hiroshi Shimamoto Signed-off-by: Ingo Molnar --- fs/proc/base.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'fs') diff --git a/fs/proc/base.c b/fs/proc/base.c index 96ee899d650..989e3078d7a 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -350,6 +350,8 @@ static int lstats_open(struct inode *inode, struct file *file) struct seq_file *m; struct task_struct *task = get_proc_task(inode); + if (!task) + return -ENOENT; ret = single_open(file, lstats_show_proc, NULL); if (!ret) { m = file->private_data; -- cgit v1.2.3 From d6643d12cb0885d06a1491b16c1476abcbd53d40 Mon Sep 17 00:00:00 2001 From: Hiroshi Shimamoto Date: Thu, 14 Feb 2008 10:27:00 -0800 Subject: latencytop: fix memory leak on latency proc file At lstats_open(), calling get_proc_task() gets task struct, but it never put. put_task_struct() should be called when releasing. Signed-off-by: Hiroshi Shimamoto Signed-off-by: Ingo Molnar --- fs/proc/base.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/proc/base.c b/fs/proc/base.c index 989e3078d7a..85e06e49807 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -360,6 +360,15 @@ static int lstats_open(struct inode *inode, struct file *file) return ret; } +static int lstats_release(struct inode *inode, struct file *file) +{ + struct seq_file *m = file->private_data; + struct task_struct *task = m->private; + + put_task_struct(task); + return single_release(inode, file); +} + static ssize_t lstats_write(struct file *file, const char __user *buf, size_t count, loff_t *offs) { @@ -378,7 +387,7 @@ static const struct file_operations proc_lstats_operations = { .read = seq_read, .write = lstats_write, .llseek = seq_lseek, - .release = single_release, + .release = lstats_release, }; #endif -- cgit v1.2.3 From 13d77c37cab2bb906022309e1e7182c327e49916 Mon Sep 17 00:00:00 2001 From: Hiroshi Shimamoto Date: Wed, 20 Feb 2008 16:53:29 -0800 Subject: latencytop: change /proc task_struct access method Change getting task_struct by get_proc_task() at read or write time, and returns -ESRCH if get_proc_task() returns NULL. This is same behavior as other /proc files. Signed-off-by: Hiroshi Shimamoto Signed-off-by: Ingo Molnar --- fs/proc/base.c | 40 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 28 deletions(-) (limited to 'fs') diff --git a/fs/proc/base.c b/fs/proc/base.c index 85e06e49807..91a1bd67ac1 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -314,9 +314,12 @@ static int proc_pid_schedstat(struct task_struct *task, char *buffer) static int lstats_show_proc(struct seq_file *m, void *v) { int i; - struct task_struct *task = m->private; - seq_puts(m, "Latency Top version : v0.1\n"); + struct inode *inode = m->private; + struct task_struct *task = get_proc_task(inode); + if (!task) + return -ESRCH; + seq_puts(m, "Latency Top version : v0.1\n"); for (i = 0; i < 32; i++) { if (task->latency_record[i].backtrace[0]) { int q; @@ -341,43 +344,24 @@ static int lstats_show_proc(struct seq_file *m, void *v) } } + put_task_struct(task); return 0; } static int lstats_open(struct inode *inode, struct file *file) { - int ret; - struct seq_file *m; - struct task_struct *task = get_proc_task(inode); - - if (!task) - return -ENOENT; - ret = single_open(file, lstats_show_proc, NULL); - if (!ret) { - m = file->private_data; - m->private = task; - } - return ret; -} - -static int lstats_release(struct inode *inode, struct file *file) -{ - struct seq_file *m = file->private_data; - struct task_struct *task = m->private; - - put_task_struct(task); - return single_release(inode, file); + return single_open(file, lstats_show_proc, inode); } static ssize_t lstats_write(struct file *file, const char __user *buf, size_t count, loff_t *offs) { - struct seq_file *m; - struct task_struct *task; + struct task_struct *task = get_proc_task(file->f_dentry->d_inode); - m = file->private_data; - task = m->private; + if (!task) + return -ESRCH; clear_all_latency_tracing(task); + put_task_struct(task); return count; } @@ -387,7 +371,7 @@ static const struct file_operations proc_lstats_operations = { .read = seq_read, .write = lstats_write, .llseek = seq_lseek, - .release = lstats_release, + .release = single_release, }; #endif -- cgit v1.2.3 From 5606bf5d0cbfbc3dfa78793a3793c43dd045fb1b Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Mon, 25 Feb 2008 15:37:42 -0500 Subject: ext4: add missing ext4_journal_stop() Add missing ext4_journal_stop() in error handling. Signed-off-by: Akinobu Mita Signed-off-by: "Theodore Ts'o" Cc: Stephen Tweedie Cc: adilger@clusterfs.com Cc: Andrew Morton Cc: Mingming Cao --- fs/ext4/resize.c | 1 + 1 file changed, 1 insertion(+) (limited to 'fs') diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 9477a2bd6ff..e29efa0f9d6 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -1037,6 +1037,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, ext4_warning(sb, __FUNCTION__, "multiple resizers run on filesystem!"); unlock_super(sb); + ext4_journal_stop(handle); err = -EBUSY; goto exit_put; } -- cgit v1.2.3 From db69c915e67705daac25cad06d816c09be634de0 Mon Sep 17 00:00:00 2001 From: Lachlan McIlroy Date: Tue, 26 Feb 2008 17:00:14 +1100 Subject: [XFS] Undo bit ops cleanup mod due to regression on 32-bit powermac platform. SGI-PV: 974005 SGI-Modid: xfs-linux-melb:xfs-kern:30558a Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_bit.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_bit.h b/fs/xfs/xfs_bit.h index 325a007dec9..0f9fc9a3c41 100644 --- a/fs/xfs/xfs_bit.h +++ b/fs/xfs/xfs_bit.h @@ -61,15 +61,15 @@ static inline int xfs_highbit64(__uint64_t v) /* Get low bit set out of 32-bit argument, -1 if none set */ static inline int xfs_lowbit32(__uint32_t v) { - __uint32_t t = v; - return (t) ? find_first_bit((unsigned long *)&t, 32) : -1; + unsigned long t = v; + return (v) ? find_first_bit(&t, 32) : -1; } /* Get low bit set out of 64-bit argument, -1 if none set */ static inline int xfs_lowbit64(__uint64_t v) { - __uint64_t t = v; - return (t) ? find_first_bit((unsigned long *)&t, 64) : -1; + unsigned long t = v; + return (v) ? find_first_bit(&t, 64) : -1; } /* Return whether bitmap is empty (1 == empty) */ -- cgit v1.2.3 From ef8ece55d9b6825c28a5c1a4bd89b94040cb7b32 Mon Sep 17 00:00:00 2001 From: Lachlan McIlroy Date: Tue, 26 Feb 2008 17:00:22 +1100 Subject: [XFS] Undo bit ops cleanup mod due to regression on 32-bit powermac platform. SGI-PV: 971186 SGI-Modid: xfs-linux-melb:xfs-kern:30559a Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_bit.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_bit.h | 27 +++----------- fs/xfs/xfs_rtalloc.c | 19 ++++++---- 3 files changed, 120 insertions(+), 29 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_bit.c b/fs/xfs/xfs_bit.c index 48228848f5a..fab0b6d5a41 100644 --- a/fs/xfs/xfs_bit.c +++ b/fs/xfs/xfs_bit.c @@ -25,6 +25,109 @@ * XFS bit manipulation routines, used in non-realtime code. */ +#ifndef HAVE_ARCH_HIGHBIT +/* + * Index of high bit number in byte, -1 for none set, 0..7 otherwise. + */ +static const char xfs_highbit[256] = { + -1, 0, 1, 1, 2, 2, 2, 2, /* 00 .. 07 */ + 3, 3, 3, 3, 3, 3, 3, 3, /* 08 .. 0f */ + 4, 4, 4, 4, 4, 4, 4, 4, /* 10 .. 17 */ + 4, 4, 4, 4, 4, 4, 4, 4, /* 18 .. 1f */ + 5, 5, 5, 5, 5, 5, 5, 5, /* 20 .. 27 */ + 5, 5, 5, 5, 5, 5, 5, 5, /* 28 .. 2f */ + 5, 5, 5, 5, 5, 5, 5, 5, /* 30 .. 37 */ + 5, 5, 5, 5, 5, 5, 5, 5, /* 38 .. 3f */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 40 .. 47 */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 48 .. 4f */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 50 .. 57 */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 58 .. 5f */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 60 .. 67 */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 68 .. 6f */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 70 .. 77 */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 78 .. 7f */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 80 .. 87 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 88 .. 8f */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 90 .. 97 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 98 .. 9f */ + 7, 7, 7, 7, 7, 7, 7, 7, /* a0 .. a7 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* a8 .. af */ + 7, 7, 7, 7, 7, 7, 7, 7, /* b0 .. b7 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* b8 .. bf */ + 7, 7, 7, 7, 7, 7, 7, 7, /* c0 .. c7 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* c8 .. cf */ + 7, 7, 7, 7, 7, 7, 7, 7, /* d0 .. d7 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* d8 .. df */ + 7, 7, 7, 7, 7, 7, 7, 7, /* e0 .. e7 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* e8 .. ef */ + 7, 7, 7, 7, 7, 7, 7, 7, /* f0 .. f7 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* f8 .. ff */ +}; +#endif + +/* + * xfs_highbit32: get high bit set out of 32-bit argument, -1 if none set. + */ +inline int +xfs_highbit32( + __uint32_t v) +{ +#ifdef HAVE_ARCH_HIGHBIT + return highbit32(v); +#else + int i; + + if (v & 0xffff0000) + if (v & 0xff000000) + i = 24; + else + i = 16; + else if (v & 0x0000ffff) + if (v & 0x0000ff00) + i = 8; + else + i = 0; + else + return -1; + return i + xfs_highbit[(v >> i) & 0xff]; +#endif +} + +/* + * xfs_lowbit64: get low bit set out of 64-bit argument, -1 if none set. + */ +int +xfs_lowbit64( + __uint64_t v) +{ + __uint32_t w = (__uint32_t)v; + int n = 0; + + if (w) { /* lower bits */ + n = ffs(w); + } else { /* upper bits */ + w = (__uint32_t)(v >> 32); + if (w && (n = ffs(w))) + n += 32; + } + return n - 1; +} + +/* + * xfs_highbit64: get high bit set out of 64-bit argument, -1 if none set. + */ +int +xfs_highbit64( + __uint64_t v) +{ + __uint32_t h = (__uint32_t)(v >> 32); + + if (h) + return xfs_highbit32(h) + 32; + return xfs_highbit32((__uint32_t)v); +} + + /* * Return whether bitmap is empty. * Size is number of words in the bitmap, which is padded to word boundary diff --git a/fs/xfs/xfs_bit.h b/fs/xfs/xfs_bit.h index 0f9fc9a3c41..082641a9782 100644 --- a/fs/xfs/xfs_bit.h +++ b/fs/xfs/xfs_bit.h @@ -47,30 +47,13 @@ static inline __uint64_t xfs_mask64lo(int n) } /* Get high bit set out of 32-bit argument, -1 if none set */ -static inline int xfs_highbit32(__uint32_t v) -{ - return fls(v) - 1; -} - -/* Get high bit set out of 64-bit argument, -1 if none set */ -static inline int xfs_highbit64(__uint64_t v) -{ - return fls64(v) - 1; -} - -/* Get low bit set out of 32-bit argument, -1 if none set */ -static inline int xfs_lowbit32(__uint32_t v) -{ - unsigned long t = v; - return (v) ? find_first_bit(&t, 32) : -1; -} +extern int xfs_highbit32(__uint32_t v); /* Get low bit set out of 64-bit argument, -1 if none set */ -static inline int xfs_lowbit64(__uint64_t v) -{ - unsigned long t = v; - return (v) ? find_first_bit(&t, 64) : -1; -} +extern int xfs_lowbit64(__uint64_t v); + +/* Get high bit set out of 64-bit argument, -1 if none set */ +extern int xfs_highbit64(__uint64_t); /* Return whether bitmap is empty (1 == empty) */ extern int xfs_bitmap_empty(uint *map, uint size); diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index ca83ddf72af..47082c01872 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -72,6 +72,18 @@ STATIC int xfs_rtmodify_summary(xfs_mount_t *, xfs_trans_t *, int, * Internal functions. */ +/* + * xfs_lowbit32: get low bit set out of 32-bit argument, -1 if none set. + */ +STATIC int +xfs_lowbit32( + __uint32_t v) +{ + if (v) + return ffs(v) - 1; + return -1; +} + /* * Allocate space to the bitmap or summary file, and zero it, for growfs. */ @@ -432,7 +444,6 @@ xfs_rtallocate_extent_near( } bbno = XFS_BITTOBLOCK(mp, bno); i = 0; - ASSERT(minlen != 0); log2len = xfs_highbit32(minlen); /* * Loop over all bitmap blocks (bbno + i is current block). @@ -601,8 +612,6 @@ xfs_rtallocate_extent_size( xfs_suminfo_t sum; /* summary information for extents */ ASSERT(minlen % prod == 0 && maxlen % prod == 0); - ASSERT(maxlen != 0); - /* * Loop over all the levels starting with maxlen. * At each level, look at all the bitmap blocks, to see if there @@ -660,9 +669,6 @@ xfs_rtallocate_extent_size( *rtblock = NULLRTBLOCK; return 0; } - ASSERT(minlen != 0); - ASSERT(maxlen != 0); - /* * Loop over sizes, from maxlen down to minlen. * This time, when we do the allocations, allow smaller ones @@ -1948,7 +1954,6 @@ xfs_growfs_rt( nsbp->sb_blocksize * nsbp->sb_rextsize); nsbp->sb_rextents = nsbp->sb_rblocks; do_div(nsbp->sb_rextents, nsbp->sb_rextsize); - ASSERT(nsbp->sb_rextents != 0); nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents); nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1; nrsumsize = -- cgit v1.2.3 From 1bd960ee2b1231759bd485aad0fa483c2f793a3b Mon Sep 17 00:00:00 2001 From: Josef Jeff Sipek Date: Fri, 29 Feb 2008 13:58:40 +1100 Subject: [XFS] If you mount an XFS filesystem with no mount options at all, then the "ikeep" option is set rather than "noikeep". This regression was introduced in 970451. With no mount options specified, xfs_parseargs() does the following: int ikeep = 0; args->flags |= XFSMNT_BARRIER; args->flags2 |= XFSMNT2_COMPAT_IOSIZE; if (!options) goto done; It only sets the above two options by default and before, it also used to set XFSMNT_IDELETE by default. If options are specified, then if (!(args->flags & XFSMNT_DMAPI) && !ikeep) args->flags |= XFSMNT_IDELETE; is executed later on which is skipped by the "goto done;" above. The solution is to invert the logic. SGI-PV: 977771 SGI-Modid: xfs-linux-melb:xfs-kern:30590a Signed-off-by: Niv Sardi Signed-off-by: Barry Naujok Signed-off-by: Josef 'Jeff' Sipek Signed-off-by: Lachlan McIlroy --- fs/xfs/linux-2.6/xfs_super.c | 14 +++++++------- fs/xfs/xfs_clnt.h | 2 +- fs/xfs/xfs_ialloc.c | 2 +- fs/xfs/xfs_mount.h | 2 +- fs/xfs/xfs_vfsops.c | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 21dfc9da235..8831d951879 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -171,7 +171,7 @@ xfs_parseargs( char *this_char, *value, *eov; int dsunit, dswidth, vol_dsunit, vol_dswidth; int iosize; - int ikeep = 0; + int dmapi_implies_ikeep = 1; args->flags |= XFSMNT_BARRIER; args->flags2 |= XFSMNT2_COMPAT_IOSIZE; @@ -302,10 +302,10 @@ xfs_parseargs( } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) { args->flags &= ~XFSMNT_BARRIER; } else if (!strcmp(this_char, MNTOPT_IKEEP)) { - ikeep = 1; - args->flags &= ~XFSMNT_IDELETE; + args->flags |= XFSMNT_IKEEP; } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { - args->flags |= XFSMNT_IDELETE; + dmapi_implies_ikeep = 0; + args->flags &= ~XFSMNT_IKEEP; } else if (!strcmp(this_char, MNTOPT_LARGEIO)) { args->flags2 &= ~XFSMNT2_COMPAT_IOSIZE; } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) { @@ -410,8 +410,8 @@ xfs_parseargs( * Note that if "ikeep" or "noikeep" mount options are * supplied, then they are honored. */ - if (!(args->flags & XFSMNT_DMAPI) && !ikeep) - args->flags |= XFSMNT_IDELETE; + if ((args->flags & XFSMNT_DMAPI) && dmapi_implies_ikeep) + args->flags |= XFSMNT_IKEEP; if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) { if (dsunit) { @@ -446,6 +446,7 @@ xfs_showargs( { static struct proc_xfs_info xfs_info_set[] = { /* the few simple ones we can get from the mount struct */ + { XFS_MOUNT_IKEEP, "," MNTOPT_IKEEP }, { XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC }, { XFS_MOUNT_INO64, "," MNTOPT_INO64 }, { XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN }, @@ -461,7 +462,6 @@ xfs_showargs( }; static struct proc_xfs_info xfs_info_unset[] = { /* the few simple ones we can get from the mount struct */ - { XFS_MOUNT_IDELETE, "," MNTOPT_IKEEP }, { XFS_MOUNT_COMPAT_IOSIZE, "," MNTOPT_LARGEIO }, { XFS_MOUNT_BARRIER, "," MNTOPT_NOBARRIER }, { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_64BITINODE }, diff --git a/fs/xfs/xfs_clnt.h b/fs/xfs/xfs_clnt.h index d16c1b97107..d5d1e60ee22 100644 --- a/fs/xfs/xfs_clnt.h +++ b/fs/xfs/xfs_clnt.h @@ -86,7 +86,7 @@ struct xfs_mount_args { #define XFSMNT_NOUUID 0x01000000 /* Ignore fs uuid */ #define XFSMNT_DMAPI 0x02000000 /* enable dmapi/xdsm */ #define XFSMNT_BARRIER 0x04000000 /* use write barriers */ -#define XFSMNT_IDELETE 0x08000000 /* inode cluster delete */ +#define XFSMNT_IKEEP 0x08000000 /* inode cluster delete */ #define XFSMNT_SWALLOC 0x10000000 /* turn on stripe width * allocation */ #define XFSMNT_DIRSYNC 0x40000000 /* sync creat,link,unlink,rename diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index c5836b951d0..db9d5fa600a 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c @@ -1053,7 +1053,7 @@ xfs_difree( /* * When an inode cluster is free, it becomes eligible for removal */ - if ((mp->m_flags & XFS_MOUNT_IDELETE) && + if (!(mp->m_flags & XFS_MOUNT_IKEEP) && (rec.ir_freecount == XFS_IALLOC_INODES(mp))) { *delete = 1; diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index f7c620ec6e6..1d8a4728d84 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -366,7 +366,7 @@ typedef struct xfs_mount { #define XFS_MOUNT_SMALL_INUMS (1ULL << 15) /* users wants 32bit inodes */ #define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */ #define XFS_MOUNT_BARRIER (1ULL << 17) -#define XFS_MOUNT_IDELETE (1ULL << 18) /* delete empty inode clusters*/ +#define XFS_MOUNT_IKEEP (1ULL << 18) /* keep empty inode clusters*/ #define XFS_MOUNT_SWALLOC (1ULL << 19) /* turn on stripe width * allocation */ #define XFS_MOUNT_RDONLY (1ULL << 20) /* read-only fs */ diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index 413587f0215..7321304a69c 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c @@ -281,8 +281,8 @@ xfs_start_flags( mp->m_readio_log = mp->m_writeio_log = ap->iosizelog; } - if (ap->flags & XFSMNT_IDELETE) - mp->m_flags |= XFS_MOUNT_IDELETE; + if (ap->flags & XFSMNT_IKEEP) + mp->m_flags |= XFS_MOUNT_IKEEP; if (ap->flags & XFSMNT_DIRSYNC) mp->m_flags |= XFS_MOUNT_DIRSYNC; if (ap->flags & XFSMNT_ATTR2) -- cgit v1.2.3