])
#
+# 3.1.1 has ext4_blocks_for_truncate
+#
+AC_DEFUN([LC_BLOCKS_FOR_TRUNCATE],
+[AC_MSG_CHECKING([if kernel has ext4_blocks_for_truncate])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+ #include "$LINUX/fs/ext4/ext4_jbd2.h"
+ #include "$LINUX/fs/ext4/truncate.h"
+],[
+ ext4_blocks_for_truncate(NULL);
+],[
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_BLOCKS_FOR_TRUNCATE, 1,
+ [kernel has ext4_blocks_for_truncate])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+#
# LC_PROG_LINUX
#
# Lustre linux kernel checks
LC_HAVE_MIGRATE_HEADER
LC_MIGRATEPAGE_4ARGS
+ # 3.1.1
+ LC_BLOCKS_FOR_TRUNCATE
+
#
if test x$enable_server = xyes ; then
AC_DEFINE(HAVE_SERVER_SUPPORT, 1, [support server])
#endif
+/* kernel has ext4_blocks_for_truncate since linux-3.1.1 */
+#ifdef HAVE_BLOCKS_FOR_TRUNCATE
+# include <ext4/truncate.h>
+#else
+static inline unsigned long ext4_blocks_for_truncate(struct inode *inode)
+{
+ ext4_lblk_t needed;
+
+ needed = inode->i_blocks >> (inode->i_sb->s_blocksize_bits - 9);
+ if (needed < 2)
+ needed = 2;
+ if (needed > EXT4_MAX_TRANS_DATA)
+ needed = EXT4_MAX_TRANS_DATA;
+ return EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + needed;
+}
+#endif
+
/*
* We don't currently need any additional blocks for rmdir and
* unlink transactions because we are storing the OST oa_id inside
FSFILT_SINGLEDATA_TRANS_BLOCKS(inode->i_sb)) * logs;
break;
case FSFILT_OP_CANCEL_UNLINK:
- /* blocks for log header bitmap update OR
- * blocks for catalog header bitmap update + unlink of logs */
+ LASSERT(logs == 1);
+
+ /* blocks for log header bitmap update OR
+ * blocks for catalog header bitmap update + unlink of logs +
+ * blocks for delete the inode (include blocks truncating). */
nblocks = (LLOG_CHUNK_SIZE >> inode->i_blkbits) +
- EXT3_DELETE_TRANS_BLOCKS(inode->i_sb) * logs;
+ EXT3_DELETE_TRANS_BLOCKS(inode->i_sb) +
+ ext4_blocks_for_truncate(inode) + 3;
break;
default: CERROR("unknown transaction start op %d\n", op);
LBUG();