X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Flvfs%2Ffsfilt_ext3.c;h=271f19429504df3c1dc26fb6ca2394517470b956;hb=1e9326917af52f3d01920411465476154b2807d0;hp=afae10d5c4dcb3eb11a52fbe58b5c74697835c7c;hpb=b25eb219a157dda49a57e14f7bbc400a52a10a9d;p=fs%2Flustre-release.git diff --git a/lustre/lvfs/fsfilt_ext3.c b/lustre/lvfs/fsfilt_ext3.c index afae10d..271f194 100644 --- a/lustre/lvfs/fsfilt_ext3.c +++ b/lustre/lvfs/fsfilt_ext3.c @@ -28,6 +28,9 @@ /* * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2011 Whamcloud, Inc. + * */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -60,19 +63,17 @@ #include #include #include -#ifdef HAVE_QUOTAIO_V1_H -# include +#ifdef HAVE_QUOTAIO_H # include -#elif defined(HAVE_FS_QUOTA_QUOTAIO_V1_H) -# include +#elif defined(HAVE_FS_QUOTA_QUOTAIO_H) # include # include # define V2_DQTREEOFF QT_TREEOFF -#else -# include +#elif defined(HAVE_FS_QUOTAIO_V1_H) # include # include # define V2_DQTREEOFF QT_TREEOFF +# define V2_INITQVERSIONS_R1 V2_INITQVERSIONS #endif #ifdef QFMT_VFS_V1 @@ -215,20 +216,12 @@ static char *fsfilt_ext3_uuid(struct super_block *sb) static __u64 get_i_version(struct inode *inode) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) && defined(HAVE_EXT4_LDISKFS) - return inode->i_version; -#else return EXT3_I(inode)->i_fs_version; -#endif } static void set_i_version(struct inode *inode, __u64 new_version) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) && defined(HAVE_EXT4_LDISKFS) - inode->i_version = new_version; -#else (EXT3_I(inode))->i_fs_version = new_version; -#endif } /* @@ -306,7 +299,7 @@ static void *fsfilt_ext3_start(struct inode *inode, int op, void *desc_private, cpu_to_le32(EXT3_EXTENTS_FL | EXT3_INDEX_FL))) { CWARN("extent-mapped directory found with " "ext3-based ldiskfs - contact " - "http://bugzilla.lustre.org/\n"); + "http://bugs.whamcloud.com/\n"); warned = 1; } } @@ -815,13 +808,6 @@ static int fsfilt_ext3_add_journal_cb(struct obd_device *obd, __u64 last_rcvd, return 0; } -/* - * We need to hack the return value for the free inode counts because - * the current EA code requires one filesystem block per inode with EAs, - * so it is possible to run out of blocks before we run out of inodes. - * - * This can be removed when the ext3 EA code is fixed. - */ static int fsfilt_ext3_statfs(struct super_block *sb, struct obd_statfs *osfs) { struct kstatfs sfs; @@ -829,11 +815,6 @@ static int fsfilt_ext3_statfs(struct super_block *sb, struct obd_statfs *osfs) memset(&sfs, 0, sizeof(sfs)); rc = ll_do_statfs(sb, &sfs); - if (!rc && sfs.f_bfree < sfs.f_ffree) { - sfs.f_files = (sfs.f_files - sfs.f_ffree) + sfs.f_bfree; - sfs.f_ffree = sfs.f_bfree; - } - statfs_pack(osfs, &sfs); return rc; } @@ -1010,13 +991,17 @@ static int ext3_ext_new_extent_cb(struct ext3_ext_base *base, #endif struct inode *inode = ext3_ext_base2inode(base); struct ext3_extent nex; +#if defined(HAVE_EXT4_LDISKFS) && defined(WALK_SPACE_HAS_DATA_SEM) + struct ext4_ext_path *tmppath = NULL; + struct ext4_extent *tmpex; +#endif unsigned long pblock; unsigned long tgen; - int err, i; + int err, i, depth; unsigned long count; handle_t *handle; - i = EXT_DEPTH(base); + i = depth = EXT_DEPTH(base); EXT_ASSERT(i == path->p_depth); EXT_ASSERT(path[i].p_hdr); @@ -1061,6 +1046,29 @@ static int ext3_ext_new_extent_cb(struct ext3_ext_base *base, return EXT_REPEAT; } +#if defined(HAVE_EXT4_LDISKFS) && defined(WALK_SPACE_HAS_DATA_SEM) + /* In 2.6.32 kernel, ext4_ext_walk_space()'s callback func is not + * protected by i_data_sem, we need revalidate extent to be created */ + down_write((&EXT4_I(inode)->i_data_sem)); + + /* validate extent, make sure the extent tree does not changed */ + tmppath = ext4_ext_find_extent(inode, cex->ec_block, NULL); + if (IS_ERR(tmppath)) { + up_write(&EXT4_I(inode)->i_data_sem); + ext3_journal_stop(handle); + return PTR_ERR(tmppath); + } + tmpex = tmppath[depth].p_ext; + if (tmpex != ex) { + /* cex is invalid, try again */ + ext4_ext_drop_refs(tmppath); + kfree(tmppath); + up_write(&EXT4_I(inode)->i_data_sem); + ext3_journal_stop(handle); + return EXT_REPEAT; + } +#endif + count = cex->ec_len; pblock = new_blocks(handle, base, path, cex->ec_block, &count, &err); if (!pblock) @@ -1095,6 +1103,11 @@ static int ext3_ext_new_extent_cb(struct ext3_ext_base *base, BUG_ON(le32_to_cpu(nex.ee_block) != cex->ec_block); out: +#if defined(HAVE_EXT4_LDISKFS) && defined(WALK_SPACE_HAS_DATA_SEM) + ext4_ext_drop_refs(tmppath); + kfree(tmppath); + up_write((&EXT4_I(inode)->i_data_sem)); +#endif ext3_journal_stop(handle); map: if (err >= 0) {