' \
-e '/^%prep$/,/^# END OF PATCH APPLICATIONS$/s/kernel-%{kversion}/%{name}-%{kversion}/g' \
-e '/find $RPM_BUILD_ROOT\/lib\/modules\/$KernelVer/a\
- cp -a fs/ext3/* $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/fs/ext3' \
+ cp -a fs/ext3/* $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/fs/ext3 \
+ cp -a fs/ext4/* $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/fs/ext4' \
SPECS/kernel-2.6.spec
if $KERNEL_LUSTRE_NAMING; then
return rc;
}
-static inline int fsfilt_iocontrol(struct obd_device *obd, struct inode *inode,
- struct file *file, unsigned int cmd,
- unsigned long arg)
+static inline int fsfilt_iocontrol(struct obd_device *obd, struct dentry *dentry,
+ unsigned int cmd, unsigned long arg)
{
- return obd->obd_fsops->fs_iocontrol(inode, file, cmd, arg);
+ struct file *dummy_file = NULL;
+ int ret;
+
+ OBD_ALLOC_PTR(dummy_file);
+ if (!dummy_file)
+ return(-ENOMEM);
+
+ dummy_file->f_dentry = dentry;
+ dummy_file->f_vfsmnt = obd->u.obt.obt_vfsmnt;
+
+ ret = obd->obd_fsops->fs_iocontrol(dentry->d_inode, dummy_file, cmd,
+ arg);
+
+ OBD_FREE_PTR(dummy_file);
+ return ret;
}
static inline int fsfilt_set_md(struct obd_device *obd, struct inode *inode,
/* for statfs() */
#define LL_SUPER_MAGIC 0x0BD00BD0
-#ifndef EXT3_IOC_GETFLAGS
-#define EXT3_IOC_GETFLAGS _IOR('f', 1, long)
-#define EXT3_IOC_SETFLAGS _IOW('f', 2, long)
-#define EXT3_IOC_GETVERSION _IOR('f', 3, long)
-#define EXT3_IOC_SETVERSION _IOW('f', 4, long)
-#define EXT3_IOC_GETVERSION_OLD _IOR('v', 1, long)
-#define EXT3_IOC_SETVERSION_OLD _IOW('v', 2, long)
-#define EXT3_IOC_FIEMAP _IOWR('f', 11, struct ll_user_fiemap)
+#ifndef FSFILT_IOC_GETFLAGS
+#define FSFILT_IOC_GETFLAGS _IOR('f', 1, long)
+#define FSFILT_IOC_SETFLAGS _IOW('f', 2, long)
+#define FSFILT_IOC_GETVERSION _IOR('f', 3, long)
+#define FSFILT_IOC_SETVERSION _IOW('f', 4, long)
+#define FSFILT_IOC_GETVERSION_OLD _IOR('v', 1, long)
+#define FSFILT_IOC_SETVERSION_OLD _IOW('v', 2, long)
+#define FSFILT_IOC_FIEMAP _IOWR('f', 11, struct ll_user_fiemap)
#endif
/* FIEMAP flags supported by Lustre */
struct lustre_quota_ctxt obt_qctxt;
lustre_quota_version_t obt_qfmt;
struct rw_semaphore obt_rwsem;
+ struct vfsmount *obt_vfsmnt;
+ struct file *obt_health_check_filp;
};
/* llog contexts */
struct obd_device_target fo_obt;
struct lu_target fo_lut;
const char *fo_fstype;
- struct vfsmount *fo_vfsmnt;
int fo_group_count;
cfs_dentry_t *fo_dentry_O;
spinlock_t fo_objidlock; /* protect fo_lastobjid */
- struct file *fo_health_check_filp;
unsigned long fo_destroys_in_progress;
struct semaphore fo_create_locks[FILTER_SUBDIR_COUNT];
#define fo_fsd fo_obt.obt_lsd
#define fo_last_rcvd_slots fo_obt.obt_client_bitmap
#define fo_mount_count fo_obt.obt_mount_count
+#define fo_vfsmnt fo_obt.obt_vfsmnt
struct timeout_item {
enum timeout_event ti_event;
struct ptlrpc_service *mds_service;
struct ptlrpc_service *mds_setattr_service;
struct ptlrpc_service *mds_readpage_service;
- struct vfsmount *mds_vfsmnt;
cfs_dentry_t *mds_fid_de;
int mds_max_mdsize;
int mds_max_cookiesize;
__u32 mds_lov_objid_lastpage;
__u32 mds_lov_objid_lastidx;
- struct file *mds_health_check_filp;
struct lustre_quota_info mds_quota_info;
struct semaphore mds_qonoff_sem;
#define mds_client_bitmap mds_obt.obt_client_bitmap
#define mds_mount_count mds_obt.obt_mount_count
#define mds_last_transno mds_obt.obt_last_transno
+#define mds_vfsmnt mds_obt.obt_vfsmnt
/* lov objid */
extern __u32 mds_max_ost_index;
--- /dev/null
+Index: linux-2.6.18-128.1.6/include/linux/jbd2.h
+===================================================================
+--- linux-2.6.18-128.1.6.orig/include/linux/jbd2.h 2009-04-15 08:35:28.000000000 +0530
++++ linux-2.6.18-128.1.6/include/linux/jbd2.h 2009-05-28 15:10:18.000000000 +0530
+@@ -381,6 +381,27 @@
+ bit_spin_unlock(BH_JournalHead, &bh->b_state);
+ }
+
++#define HAVE_JOURNAL_CALLBACK_STATUS
++/**
++ * struct journal_callback - Base structure for callback information.
++ * @jcb_list: list information for other callbacks attached to the same handle.
++ * @jcb_func: Function to call with this callback structure.
++ *
++ * This struct is a 'seed' structure for a using with your own callback
++ * structs. If you are using callbacks you must allocate one of these
++ * or another struct of your own definition which has this struct
++ * as it's first element and pass it to journal_callback_set().
++ *
++ * This is used internally by jbd2 to maintain callback information.
++ *
++ * See journal_callback_set for more information.
++ **/
++struct journal_callback {
++ struct list_head jcb_list; /* t_jcb_lock */
++ void (*jcb_func)(struct journal_callback *jcb, int error);
++ /* user data goes here */
++};
++
+ struct jbd2_revoke_table_s;
+
+ /**
+@@ -389,6 +410,7 @@
+ * @h_transaction: Which compound transaction is this update a part of?
+ * @h_buffer_credits: Number of remaining buffers we are allowed to dirty.
+ * @h_ref: Reference count on this handle
++ * @h_jcb: List of application registered callbacks for this handle.
+ * @h_err: Field for caller's use to track errors through large fs operations
+ * @h_sync: flag for sync-on-close
+ * @h_jdata: flag to force data journaling
+@@ -414,6 +436,13 @@
+ /* operations */
+ int h_err;
+
++ /*
++ * List of application registered callbacks for this handle. The
++ * function(s) will be called after the transaction that this handle is
++ * part of has been committed to disk. [t_jcb_lock]
++ */
++ struct list_head h_jcb;
++
+ /* Flags [no locking] */
+ unsigned int h_sync: 1; /* sync-on-close */
+ unsigned int h_jdata: 1; /* force data journaling */
+@@ -469,6 +498,8 @@
+ * j_state_lock
+ * ->j_list_lock (journal_unmap_buffer)
+ *
++ * t_handle_lock
++ * ->t_jcb_lock
+ */
+
+ struct transaction_s
+@@ -615,6 +646,15 @@
+ */
+ int t_handle_count;
+
++ /*
++ * Protects the callback list
++ */
++ spinlock_t t_jcb_lock;
++ /*
++ * List of registered callback functions for this transaction.
++ * Called when the transaction is committed. [t_jcb_lock]
++ */
++ struct list_head t_jcb;
+ };
+
+ struct transaction_run_stats_s {
+@@ -1018,6 +1058,9 @@
+ extern int jbd2_journal_flush (journal_t *);
+ extern void jbd2_journal_lock_updates (journal_t *);
+ extern void jbd2_journal_unlock_updates (journal_t *);
++extern void jbd2_journal_callback_set(handle_t *handle,
++ void (*fn)(struct journal_callback *,int),
++ struct journal_callback *jcb);
+
+ extern journal_t * jbd2_journal_init_dev(struct block_device *bdev,
+ struct block_device *fs_dev,
+Index: linux-2.6.18-128.1.6/fs/jbd2/checkpoint.c
+===================================================================
+--- linux-2.6.18-128.1.6.orig/fs/jbd2/checkpoint.c 2009-04-15 08:35:28.000000000 +0530
++++ linux-2.6.18-128.1.6/fs/jbd2/checkpoint.c 2009-05-28 15:10:18.000000000 +0530
+@@ -695,6 +695,7 @@
+ J_ASSERT(transaction->t_checkpoint_list == NULL);
+ J_ASSERT(transaction->t_checkpoint_io_list == NULL);
+ J_ASSERT(transaction->t_updates == 0);
++ J_ASSERT(list_empty(&transaction->t_jcb));
+ J_ASSERT(journal->j_committing_transaction != transaction);
+ J_ASSERT(journal->j_running_transaction != transaction);
+
+Index: linux-2.6.18-128.1.6/fs/jbd2/commit.c
+===================================================================
+--- linux-2.6.18-128.1.6.orig/fs/jbd2/commit.c 2009-04-15 08:35:28.000000000 +0530
++++ linux-2.6.18-128.1.6/fs/jbd2/commit.c 2009-05-28 15:12:45.000000000 +0530
+@@ -898,6 +898,30 @@
+ transaction can be removed from any checkpoint list it was on
+ before. */
+
++ /*
++ * Call any callbacks that had been registered for handles in this
++ * transaction. It is up to the callback to free any allocated
++ * memory.
++ *
++ * The spinlocking (t_jcb_lock) here is surely unnecessary...
++ */
++ spin_lock(&commit_transaction->t_jcb_lock);
++ if (!list_empty(&commit_transaction->t_jcb)) {
++ struct list_head *p, *n;
++ int error = is_journal_aborted(journal);
++
++ list_for_each_safe(p, n, &commit_transaction->t_jcb) {
++ struct journal_callback *jcb;
++
++ jcb = list_entry(p, struct journal_callback, jcb_list);
++ list_del(p);
++ spin_unlock(&commit_transaction->t_jcb_lock);
++ jcb->jcb_func(jcb, error);
++ spin_lock(&commit_transaction->t_jcb_lock);
++ }
++ }
++ spin_unlock(&commit_transaction->t_jcb_lock);
++
+ jbd_debug(3, "JBD: commit phase 7\n");
+
+ J_ASSERT(commit_transaction->t_sync_datalist == NULL);
+Index: linux-2.6.18-128.1.6/fs/jbd2/journal.c
+===================================================================
+--- linux-2.6.18-128.1.6.orig/fs/jbd2/journal.c 2009-04-15 08:35:28.000000000 +0530
++++ linux-2.6.18-128.1.6/fs/jbd2/journal.c 2009-05-28 17:13:35.000000000 +0530
+@@ -80,6 +80,9 @@
+ EXPORT_SYMBOL(jbd2_journal_invalidatepage);
+ EXPORT_SYMBOL(jbd2_journal_try_to_free_buffers);
+ EXPORT_SYMBOL(jbd2_journal_force_commit);
++EXPORT_SYMBOL(jbd2_journal_callback_set);
++EXPORT_SYMBOL(jbd2_journal_bmap);
++EXPORT_SYMBOL(jbd2_log_start_commit);
+
+ static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);
+ static void __journal_abort_soft (journal_t *journal, int errno);
+Index: linux-2.6.18-128.1.6/fs/jbd2/transaction.c
+===================================================================
+--- linux-2.6.18-128.1.6.orig/fs/jbd2/transaction.c 2009-04-15 08:35:28.000000000 +0530
++++ linux-2.6.18-128.1.6/fs/jbd2/transaction.c 2009-05-28 15:11:28.000000000 +0530
+@@ -51,6 +51,9 @@
+ transaction->t_tid = journal->j_transaction_sequence++;
+ transaction->t_expires = jiffies + journal->j_commit_interval;
+ spin_lock_init(&transaction->t_handle_lock);
++ INIT_LIST_HEAD(&transaction->t_jcb);
++ spin_lock_init(&transaction->t_jcb_lock);
++
+
+ /* Set up the commit timer for the new transaction. */
+ journal->j_commit_timer.expires = round_jiffies(transaction->t_expires);
+@@ -251,6 +254,7 @@
+ memset(handle, 0, sizeof(*handle));
+ handle->h_buffer_credits = nblocks;
+ handle->h_ref = 1;
++ INIT_LIST_HEAD(&handle->h_jcb);
+
+ lockdep_init_map(&handle->h_lockdep_map, "jbd2_handle",
+ &jbd2_handle_key, 0);
+@@ -1349,6 +1353,36 @@
+ }
+
+ /**
++ * void jbd2_journal_callback_set() - Register a callback function for this handle.
++ * @handle: handle to attach the callback to.
++ * @func: function to callback.
++ * @jcb: structure with additional information required by func() , and
++ * some space for jbd2 internal information.
++ *
++ * The function will be
++ * called when the transaction that this handle is part of has been
++ * committed to disk with the original callback data struct and the
++ * error status of the journal as parameters. There is no guarantee of
++ * ordering between handles within a single transaction, nor between
++ * callbacks registered on the same handle.
++ *
++ * The caller is responsible for allocating the journal_callback struct.
++ * This is to allow the caller to add as much extra data to the callback
++ * as needed, but reduce the overhead of multiple allocations. The caller
++ * allocated struct must start with a struct journal_callback at offset 0,
++ * and has the caller-specific data afterwards.
++ */
++void jbd2_journal_callback_set(handle_t *handle,
++ void (*func)(struct journal_callback *jcb, int error),
++ struct journal_callback *jcb)
++{
++ spin_lock(&handle->h_transaction->t_jcb_lock);
++ list_add_tail(&jcb->jcb_list, &handle->h_jcb);
++ spin_unlock(&handle->h_transaction->t_jcb_lock);
++ jcb->jcb_func = func;
++}
++
++/**
+ * int jbd2_journal_stop() - complete a transaction
+ * @handle: tranaction to complete.
+ *
+@@ -1422,6 +1456,11 @@
+ wake_up(&journal->j_wait_transaction_locked);
+ }
+
++ /* Move callbacks from the handle to the transaction. */
++ spin_lock(&transaction->t_jcb_lock);
++ list_splice(&handle->h_jcb, &transaction->t_jcb);
++ spin_unlock(&transaction->t_jcb_lock);
++
+ /*
+ * If the handle is marked SYNC, we need to set another commit
+ * going! We also want to force a commit if the current
jbd-slab-race-2.6-rhel5.patch
mpt-fusion-max-sge.patch
prune-icache-use-trylock-rhel5.patch
+jbd2-jcberr-2.6-rhel5.patch
+jbd2-commit-timer-no-jiffies-rounding.diff
ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_IOCTL, 1);
switch(cmd) {
- case EXT3_IOC_GETFLAGS:
- case EXT3_IOC_SETFLAGS:
+ case FSFILT_IOC_GETFLAGS:
+ case FSFILT_IOC_SETFLAGS:
RETURN(ll_iocontrol(inode, file, cmd, arg));
- case EXT3_IOC_GETVERSION_OLD:
- case EXT3_IOC_GETVERSION:
+ case FSFILT_IOC_GETVERSION_OLD:
+ case FSFILT_IOC_GETVERSION:
RETURN(put_user(inode->i_generation, (int *)arg));
/* We need to special case any other ioctls we want to handle,
* to send them to the MDS/OST as appropriate and to properly
* network encode the arg field.
- case EXT3_IOC_SETVERSION_OLD:
- case EXT3_IOC_SETVERSION:
+ case FSFILT_IOC_SETVERSION_OLD:
+ case FSFILT_IOC_SETVERSION:
*/
case IOC_MDC_LOOKUP: {
struct ptlrpc_request *request = NULL;
RETURN(ll_lov_getstripe(inode, arg));
case LL_IOC_RECREATE_OBJ:
RETURN(ll_lov_recreate_obj(inode, file, arg));
- case EXT3_IOC_FIEMAP: {
+ case FSFILT_IOC_FIEMAP: {
struct ll_user_fiemap *fiemap_s;
size_t num_bytes, ret_bytes;
unsigned int extent_count;
OBD_VFREE(fiemap_s, num_bytes);
RETURN(rc);
}
- case EXT3_IOC_GETFLAGS:
- case EXT3_IOC_SETFLAGS:
+ case FSFILT_IOC_GETFLAGS:
+ case FSFILT_IOC_SETFLAGS:
RETURN(ll_iocontrol(inode, file, cmd, arg));
- case EXT3_IOC_GETVERSION_OLD:
- case EXT3_IOC_GETVERSION:
+ case FSFILT_IOC_GETVERSION_OLD:
+ case FSFILT_IOC_GETVERSION:
RETURN(put_user(inode->i_generation, (int *)arg));
case LL_IOC_JOIN: {
#if LUSTRE_FIX >= 50
/* We need to special case any other ioctls we want to handle,
* to send them to the MDS/OST as appropriate and to properly
* network encode the arg field.
- case EXT3_IOC_SETVERSION_OLD:
- case EXT3_IOC_SETVERSION:
+ case FSFILT_IOC_SETVERSION_OLD:
+ case FSFILT_IOC_SETVERSION:
*/
case LL_IOC_FLUSHCTX:
RETURN(ll_flush_ctx(inode));
ENTRY;
switch(cmd) {
- case EXT3_IOC_GETFLAGS: {
+ case FSFILT_IOC_GETFLAGS: {
struct mdt_body *body;
struct obd_capa *oc;
RETURN(put_user(flags, (int *)arg));
}
- case EXT3_IOC_SETFLAGS: {
+ case FSFILT_IOC_SETFLAGS: {
struct lov_stripe_md *lsm = ll_i2info(inode)->lli_smd;
struct obd_info oinfo = { { { 0 } } };
struct md_op_data *op_data;
-e "s/DX_HASH/EXT3_DX_HASH/g" \
-e "s/reserve_window/ext3_reserve_window/g" \
-e "s/rsv_window_add/ext3_rsv_window_add/g" \
- -e "s/EXT3/LDISKFS/g" -e "s/ext3/ldiskfs/g"
+ -e "s/EXT3/LDISKFS/g" -e "s/ext3/ldiskfs/g" \
+ -e "s/EXT4/LDISKFS/g" -e "s/ext4/ldiskfs/g" \
+ -e "s/HAVE_LDISKFS_LDISKFS/HAVE_EXT4_LDISKFS/g"
fsfilt_ldiskfs.c: fsfilt_ext3.c
sed $(strip $(ldiskfs_sed_flags)) $< > $@
+ if grep -q '^#define\(.*\)HAVE_EXT4_LDISKFS' @LDISKFS_DIR@/config.h ; then \
+ sed -i -e "/DEBUG_SUBSYSTEM\(.*\)S_FILTER/a\#define HAVE_EXT4_LDISKFS 1" $@ ;\
+ fi
fsfilt_ldiskfs_quota.h: fsfilt_ext3_quota.h
sed $(strip $(ldiskfs_sed_flags)) $< > $@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
-#include <linux/jbd.h>
#include <linux/slab.h>
#include <linux/pagemap.h>
#include <linux/quotaops.h>
+#ifdef HAVE_EXT4_LDISKFS
+#include <ext4/ext4.h>
+#include <ext4/ext4_jbd2.h>
+#else
+#include <linux/jbd.h>
#include <linux/ext3_fs.h>
#include <linux/ext3_jbd.h>
+#endif
#include <linux/version.h>
#include <linux/bitops.h>
#include <linux/quota.h>
#include <linux/lprocfs_status.h>
#ifdef EXT3_MULTIBLOCK_ALLOCATOR
+#ifdef HAVE_EXT4_LDISKFS
+#include <ext4/ext4_extents.h>
+#else
#include <linux/ext3_extents.h>
#endif
+#endif
#include "lustre_quota_fmt.h"
#define EXT3_XATTR_INDEX_TRUSTED 4
#endif
+#ifdef HAVE_EXT4_LDISKFS
+#define fsfilt_log_start_commit(journal, tid) jbd2_log_start_commit(journal, tid)
+#define fsfilt_log_wait_commit(journal, tid) jbd2_log_wait_commit(journal, tid)
+#define fsfilt_journal_callback_set(handle, func, jcb) jbd2_journal_callback_set(handle, func, jcb)
+#else
+#define fsfilt_log_start_commit(journal, tid) log_start_commit(journal, tid)
+#define fsfilt_log_wait_commit(journal, tid) log_wait_commit(journal, tid)
+#define fsfilt_journal_callback_set(handle, func, jcb) journal_callback_set(handle, func, jcb)
+#define ext_pblock(ex) le32_to_cpu((ex)->ee_start)
+#define ext3_ext_store_pblock(ex, pblock) ((ex)->ee_start = cpu_to_le32(pblock))
+#define ext3_inode_bitmap(sb,desc) le32_to_cpu((desc)->bg_inode_bitmap)
+#endif
+
static char *fsfilt_ext3_get_label(struct super_block *sb)
{
return EXT3_SB(sb)->s_es->s_volume_name;
int err;
journal = EXT3_SB(sb)->s_journal;
- handle = journal_start(journal, 1);
+ handle = ext3_journal_start_sb(sb, 1);
if (IS_ERR(handle)) {
CERROR("can't start transaction\n");
return(PTR_ERR(handle));
err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
out:
- journal_stop(handle);
+ ext3_journal_stop(handle);
return(err);
}
nblocks += 3;
/* no break */
case FSFILT_OP_CREATE: {
-#if defined(EXT3_EXTENTS_FL) && defined(EXT3_INDEX_FL)
+#if defined(EXT3_EXTENTS_FL) && defined(EXT3_INDEX_FL) && !defined(HAVE_EXT4_LDISKFS)
static int warned;
if (!warned) {
if (!test_opt(inode->i_sb, EXTENTS)) {
} else if (((EXT3_I(inode)->i_flags &
cpu_to_le32(EXT3_EXTENTS_FL | EXT3_INDEX_FL)) ==
cpu_to_le32(EXT3_EXTENTS_FL | EXT3_INDEX_FL))) {
- CWARN("extent-mapped directory found - contact "
+ CWARN("extent-mapped directory found with "
+ "ext3-based ldiskfs - contact "
"http://bugzilla.lustre.org/\n");
warned = 1;
}
if (handle->h_buffer_credits > nblocks)
return 0;
- if (journal_extend(handle, nblocks) == 0)
+ if (ext3_journal_extend(handle, nblocks) == 0)
return 0;
ext3_mark_inode_dirty(handle, inode);
- return journal_restart(handle, nblocks);
+ return ext3_journal_restart(handle, nblocks);
}
static int fsfilt_ext3_commit(struct inode *inode, void *h, int force_sync)
CERROR("error while stopping transaction: %d\n", rc);
return rc;
}
- log_start_commit(journal, tid);
+ fsfilt_log_start_commit(journal, tid);
*wait_handle = (void *) tid;
CDEBUG(D_INODE, "commit async: %lu\n", (unsigned long) tid);
if (unlikely(is_journal_aborted(journal)))
return -EIO;
- log_wait_commit(EXT3_JOURNAL(inode), tid);
+ fsfilt_log_wait_commit(EXT3_JOURNAL(inode), tid);
if (unlikely(is_journal_aborted(journal)))
return -EIO;
RETURN(rc);
}
-static int fsfilt_ext3_iocontrol(struct inode * inode, struct file *file,
+static int fsfilt_ext3_iocontrol(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
int rc = 0;
RETURN(-EPERM);
}
+#ifdef HAVE_EXT4_LDISKFS
+ /* ext4_ioctl does not have a inode argument */
+ if (inode->i_fop->unlocked_ioctl)
+ rc = inode->i_fop->unlocked_ioctl(file, cmd, arg);
+#else
if (inode->i_fop->ioctl)
rc = inode->i_fop->ioctl(inode, file, cmd, arg);
+#endif
else
RETURN(-ENOTTY);
fcb->cb_data = cb_data;
CDEBUG(D_EXT2, "set callback for last_rcvd: "LPD64"\n", last_rcvd);
- journal_callback_set(handle, fsfilt_ext3_cb_func,
- (struct journal_callback *)fcb);
+ fsfilt_journal_callback_set(handle, fsfilt_ext3_cb_func,
+ (struct journal_callback *)fcb);
return 0;
}
#ifdef EXT3_MULTIBLOCK_ALLOCATOR
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17))
-#define ext3_up_truncate_sem(inode) up(&EXT3_I(inode)->truncate_sem);
-#define ext3_down_truncate_sem(inode) down(&EXT3_I(inode)->truncate_sem);
+#define fsfilt_up_truncate_sem(inode) up(&EXT3_I(inode)->truncate_sem);
+#define fsfilt_down_truncate_sem(inode) down(&EXT3_I(inode)->truncate_sem);
+#else
+#ifdef HAVE_EXT4_LDISKFS
+#define fsfilt_up_truncate_sem(inode) up_write((&EXT4_I(inode)->i_data_sem));
+#define fsfilt_down_truncate_sem(inode) down_write((&EXT4_I(inode)->i_data_sem));
#else
-#define ext3_up_truncate_sem(inode) mutex_unlock(&EXT3_I(inode)->truncate_mutex);
-#define ext3_down_truncate_sem(inode) mutex_lock(&EXT3_I(inode)->truncate_mutex);
+#define fsfilt_up_truncate_sem(inode) mutex_unlock(&EXT3_I(inode)->truncate_mutex);
+#define fsfilt_down_truncate_sem(inode) mutex_lock(&EXT3_I(inode)->truncate_mutex);
+#endif
#endif
#ifndef EXT_ASSERT
#ifdef EXT3_EXT_HAS_NO_TREE
/* for kernels 2.6.18 and later */
+#ifdef HAVE_EXT4_LDISKFS
+#define EXT_GENERATION(inode) (EXT4_I(inode)->i_ext_generation)
+#else
+#define EXT_GENERATION(inode) ext_generation(inode)
+#endif
#define ext3_ext_base inode
#define ext3_ext_base2inode(inode) (inode)
#define EXT_DEPTH(inode) ext_depth(inode)
-#define EXT_GENERATION(inode) ext_generation(inode)
#define fsfilt_ext3_ext_walk_space(inode, block, num, cb, cbdata) \
ext3_ext_walk_space(inode, block, num, cb, cbdata);
#else
#endif
#include <linux/lustre_version.h>
-#if EXT3_EXT_MAGIC == 0xf301
-#define ee_start e_start
-#define ee_block e_block
-#define ee_len e_num
-#endif
-#ifndef EXT3_BB_MAX_BLOCKS
-#define ext3_mb_new_blocks(handle, inode, goal, count, aflags, err) \
- ext3_new_blocks(handle, inode, count, goal, err)
-#endif
struct bpointers {
unsigned long *blocks;
depth = path->p_depth;
/* try to predict block placement */
- if ((ex = path[depth].p_ext)) {
-#if 0
- /* This prefers to eat into a contiguous extent
- * rather than find an extent that the whole
- * request will fit into. This can fragment data
- * block allocation and prevents our lovely 1M I/Os
- * from reaching the disk intact. */
- if (ex->ee_block + ex->ee_len == block)
- *aflags |= 1;
-#endif
- return ex->ee_start + (block - ex->ee_block);
- }
+ if ((ex = path[depth].p_ext))
+ return ext_pblock(ex) + (block - le32_to_cpu(ex->ee_block));
/* it looks index is empty
* try to find starting from index itself */
tgen = EXT_GENERATION(base);
count = ext3_ext_calc_credits_for_insert(base, path);
- ext3_up_truncate_sem(inode);
+ fsfilt_up_truncate_sem(inode);
handle = fsfilt_ext3_journal_start(inode, count+EXT3_ALLOC_NEEDED+1);
if (IS_ERR(handle)) {
- ext3_down_truncate_sem(inode);
+ fsfilt_down_truncate_sem(inode);
return PTR_ERR(handle);
}
- ext3_down_truncate_sem(inode);
+ fsfilt_down_truncate_sem(inode);
if (tgen != EXT_GENERATION(base)) {
/* the tree has changed. so path can be invalid at moment */
fsfilt_ext3_journal_stop(handle);
EXT_ASSERT(count <= cex->ec_len);
/* insert new extent */
- nex.ee_block = cex->ec_block;
- nex.ee_start = pblock;
- nex.ee_len = count;
+ nex.ee_block = cpu_to_le32(cex->ec_block);
+ ext3_ext_store_pblock(&nex, pblock);
+ nex.ee_len = cpu_to_le16(count);
err = ext3_ext_insert_extent(handle, base, path, &nex);
if (err) {
/* free data blocks we just allocated */
#ifdef EXT3_MB_HINT_GROUP_ALLOC
ext3_mb_discard_inode_preallocations(inode);
#endif
- ext3_free_blocks(handle, inode, nex.ee_start, nex.ee_len, 0);
+ ext3_free_blocks(handle, inode, ext_pblock(&nex),
+ cpu_to_le16(nex.ee_len), 0);
goto out;
}
* we are asking ext3_ext_walk_space() to continue
* scaning after that block
*/
- cex->ec_len = nex.ee_len;
- cex->ec_start = nex.ee_start;
- BUG_ON(nex.ee_len == 0);
- BUG_ON(nex.ee_block != cex->ec_block);
+ cex->ec_len = le16_to_cpu(nex.ee_len);
+ cex->ec_start = ext_pblock(&nex);
+ BUG_ON(le16_to_cpu(nex.ee_len) == 0);
+ BUG_ON(le32_to_cpu(nex.ee_block) != cex->ec_block);
out:
fsfilt_ext3_journal_stop(handle);
CERROR("hmm. why do we find this extent?\n");
CERROR("initial space: %lu:%u\n",
bp->start, bp->init_num);
- CERROR("current extent: %u/%u/%u %d\n",
+ CERROR("current extent: %u/%u/%llu %d\n",
cex->ec_block, cex->ec_len,
- cex->ec_start, cex->ec_type);
+ (unsigned long long)cex->ec_start,
+ cex->ec_type);
}
i = 0;
if (cex->ec_block < bp->start)
bp.init_num = bp.num = num;
bp.create = create;
- ext3_down_truncate_sem(inode);
+ fsfilt_down_truncate_sem(inode);
err = fsfilt_ext3_ext_walk_space(base, block, num,
ext3_ext_new_extent_cb, &bp);
ext3_ext_invalidate_cache(base);
- ext3_up_truncate_sem(inode);
+ fsfilt_up_truncate_sem(inode);
return err;
}
return gdp + desc;
}
+
+#ifndef HAVE_EXT4_LDISKFS
static inline struct buffer_head *
-read_inode_bitmap(struct super_block *sb, unsigned long group)
+ext3_read_inode_bitmap(struct super_block *sb, unsigned long group)
{
struct ext3_group_desc *desc;
struct buffer_head *bh;
desc = get_group_desc(sb, group);
- bh = sb_bread(sb, le32_to_cpu(desc->bg_inode_bitmap));
-
+ bh = sb_bread(sb, ext3_inode_bitmap(sb, desc));
return bh;
}
+#endif
static inline struct inode *ext3_iget_inuse(struct super_block *sb,
struct buffer_head *bitmap_bh,
{
struct inode *inode = NULL;
+
if (ext3_test_bit(index, bitmap_bh->b_data))
+#ifdef HAVE_EXT4_LDISKFS
+ inode = ext4_iget(sb, ino);
+ if (IS_ERR(inode))
+ /* Newer kernels return an error instead of a NULL pointer */
+ inode = NULL;
+#else
inode = iget(sb, ino);
-
- if (IS_ERR(inode))
- /* Newer kernels return an error instead of a NULL pointer */
- inode = NULL;
+#endif
return inode;
}
/* check quota and update in hash */
for (group = 0; group < sbi->s_groups_count; group++) {
ino = group * sbi->s_inodes_per_group + 1;
- bitmap_bh = read_inode_bitmap(sb, group);
+ bitmap_bh = ext3_read_inode_bitmap(sb, group);
if (!bitmap_bh) {
- CERROR("read_inode_bitmap group %d failed", group);
+ CERROR("ext3_read_inode_bitmap group %d failed", group);
GOTO(out, rc = -EIO);
}
#define DEBUG_SUBSYSTEM S_MDS
#include <linux/module.h>
+#ifdef HAVE_EXT4_LDISKFS
+#include <ldiskfs/ldiskfs_jbd2.h>
+#else
#include <linux/jbd.h>
+#endif
#include <obd.h>
#include <obd_class.h>
#include <lustre_ver.h>
#include <lustre_disk.h>
#include <lustre_fid.h>
+#ifdef HAVE_EXT4_LDISKFS
+#include <ldiskfs/ldiskfs.h>
+#else
#include <linux/ldiskfs_fs.h>
+#endif
#include <lustre_mds.h>
#include <lustre/lustre_idl.h>
#include <lustre_disk.h> /* for changelogs */
#define DEBUG_SUBSYSTEM S_MDS
#include <linux/module.h>
+#ifdef HAVE_EXT4_LDISKFS
+#include <ldiskfs/ldiskfs_jbd2.h>
+#else
#include <linux/jbd.h>
+#endif
#include <obd.h>
#include <obd_class.h>
#include <lustre_ver.h>
#include <obd_support.h>
#include <lprocfs_status.h>
-
+#ifdef HAVE_EXT4_LDISKFS
+#include <ldiskfs/ldiskfs.h>
+#else
#include <linux/ldiskfs_fs.h>
+#endif
#include <lustre_mds.h>
#include <lustre/lustre_idl.h>
#include <lustre_fid.h>
#define DEBUG_SUBSYSTEM S_MDS
#include <linux/module.h>
+#ifdef HAVE_EXT4_LDISKFS
+#include <ldiskfs/ldiskfs_jbd2.h>
+#else
#include <linux/jbd.h>
+#endif
#include <obd.h>
#include <obd_class.h>
#include <obd_support.h>
#include <lustre_fid.h>
#include <lustre_param.h>
+#ifdef HAVE_EXT4_LDISKFS
+#include <ldiskfs/ldiskfs.h>
+#else
#include <linux/ldiskfs_fs.h>
+#endif
#include <lustre_mds.h>
#include <lustre/lustre_idl.h>
#define DEBUG_SUBSYSTEM S_MDS
#include <linux/module.h>
+#ifdef HAVE_EXT4_LDISKFS
+#include <ldiskfs/ldiskfs_jbd2.h>
+#else
#include <linux/jbd.h>
+#endif
#include <obd.h>
#include <obd_class.h>
#include <lustre_ver.h>
#include <obd_support.h>
#include <lprocfs_status.h>
+#ifdef HAVE_EXT4_LDISKFS
+#include <ldiskfs/ldiskfs.h>
+#else
#include <linux/ldiskfs_fs.h>
+#endif
#include <lustre_mds.h>
#include <lustre/lustre_idl.h>
#define DEBUG_SUBSYSTEM S_MDS
#include <linux/module.h>
+#ifdef HAVE_EXT4_LDISKFS
+#include <ldiskfs/ldiskfs_jbd2.h>
+#else
#include <linux/jbd.h>
+#endif
#include <obd.h>
#include <obd_class.h>
#include <lustre_ver.h>
#include <obd_support.h>
#include <lprocfs_status.h>
+#ifdef HAVE_EXT4_LDISKFS
+#include <ldiskfs/ldiskfs.h>
+#else
#include <linux/ldiskfs_fs.h>
+#endif
#include <lustre_mds.h>
#include <lustre/lustre_idl.h>
*/
#include <linux/fs.h>
+
+#ifdef HAVE_EXT4_LDISKFS
+#include <ldiskfs/ldiskfs_jbd2.h>
+#else
#include <linux/jbd.h>
+#endif
+
#include <linux/sched.h>
#ifdef HAVE_SERVER_SUPPORT
-# include <linux/ldiskfs_fs.h>
+
+#ifdef HAVE_EXT4_LDISKFS
+#include <ldiskfs/ldiskfs.h>
+#else
+#include <linux/ldiskfs_fs.h>
+#endif
+
#else
# include <obd_class.h>
#endif
#define DELTA 0x9E3779B9
-#define DX_HASH_R5 98
-#define DX_HASH_SAME 99
static void TEA_transform(__u32 buf[4], __u32 const in[])
return (hash0 << 1);
}
-static __u32 dx_r5_hash(const signed char *msg, int len)
-{
- __u32 a = 0;
- while (len--) {
- a += *msg << 4;
- a += *msg >> 4;
- a *= 11;
- msg++;
- }
- return a;
-}
-
-static __u32 dx_same_hash(const signed char *msg, int len)
-{
- return 0xcafebabeUL;
-}
-
static void str2hashbuf(const char *msg, int len, __u32 *buf, int num)
{
__u32 pad, val;
hash = buf[0];
minor_hash = buf[1];
break;
- case LDISKFS_DX_HASH_R5:
- hash = dx_r5_hash(name, len);
- break;
- case LDISKFS_DX_HASH_SAME:
- hash = dx_same_hash(name, len);
- break;
default:
hinfo->hash = 0;
return -1;
#include <lustre/lustre_idl.h>
#ifdef __KERNEL__
+
+#ifdef HAVE_EXT4_LDISKFS
+#include <ldiskfs/ldiskfs_jbd2.h>
+#else
#include <linux/jbd.h>
+#endif
+
#ifdef HAVE_SERVER_SUPPORT
/* LDISKFS_SB() */
+
+#ifdef HAVE_EXT4_LDISKFS
+#include <ldiskfs/ldiskfs.h>
+#else
#include <linux/ldiskfs_fs.h>
#endif
+
+#endif
#endif
static int mea_last_char_hash(int count, char *name, int namelen)
{
/* This hash calculate method must be same as the lvar hash method */
#define LVAR_HASH_SANDWICH (0)
-#define LVAR_HASH_TEA (1)
-#define LVAR_HASH_R5 (0)
#define LVAR_HASH_PREFIX (0)
static __u32 hash_build0(const char *name, int namelen)
} else {
struct ldiskfs_dx_hash_info hinfo;
- if (LVAR_HASH_TEA)
- hinfo.hash_version = LDISKFS_DX_HASH_TEA;
- else
- hinfo.hash_version = LDISKFS_DX_HASH_R5;
+ hinfo.hash_version = LDISKFS_DX_HASH_TEA;
hinfo.seed = 0;
ldiskfsfs_dirhash(name, namelen, &hinfo);
result = hinfo.hash;
HEALTH_CHECK, rc);
GOTO(err_server_data, rc);
}
- filter->fo_health_check_filp = file;
+ filter->fo_obt.obt_health_check_filp = file;
if (!S_ISREG(file->f_dentry->d_inode->i_mode)) {
CERROR("%s is not a regular file!: mode = %o\n", HEALTH_CHECK,
file->f_dentry->d_inode->i_mode);
return(rc);
err_health_check:
- if (filp_close(filter->fo_health_check_filp, 0))
+ if (filp_close(filter->fo_obt.obt_health_check_filp, 0))
CERROR("can't close %s after error\n", HEALTH_CHECK);
- filter->fo_health_check_filp = NULL;
+ filter->fo_obt.obt_health_check_filp = NULL;
err_server_data:
target_recovery_fini(obd);
filter_free_server_data(filter);
if (rc)
CERROR("error closing %s: rc = %d\n", LAST_RCVD, rc);
- rc = filp_close(filter->fo_health_check_filp, 0);
- filter->fo_health_check_filp = NULL;
+ rc = filp_close(filter->fo_obt.obt_health_check_filp, 0);
+ filter->fo_obt.obt_health_check_filp = NULL;
if (rc)
CERROR("error closing %s: rc = %d\n", HEALTH_CHECK, rc);
GOTO(out_unlock, rc = PTR_ERR(handle));
}
if (oa->o_valid & OBD_MD_FLFLAGS) {
- rc = fsfilt_iocontrol(exp->exp_obd, inode, NULL,
- EXT3_IOC_SETFLAGS, (long)&oa->o_flags);
+ rc = fsfilt_iocontrol(exp->exp_obd, dentry,
+ FSFILT_IOC_SETFLAGS, (long)&oa->o_flags);
} else {
rc = fsfilt_setattr(exp->exp_obd, dentry, handle, &iattr, 1);
if (fcc != NULL)
memcpy(fiemap, &fm_key->fiemap, sizeof(*fiemap));
push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
- rc = fsfilt_iocontrol(obd, dentry->d_inode, NULL,
- EXT3_IOC_FIEMAP, (long)fiemap);
+ rc = fsfilt_iocontrol(obd, dentry, FSFILT_IOC_FIEMAP,
+ (long)fiemap);
pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
f_dput(dentry);
rc = 1;
#ifdef USE_HEALTH_CHECK_WRITE
- LASSERT(filter->fo_health_check_filp != NULL);
- rc |= !!lvfs_check_io_health(obd, filter->fo_health_check_filp);
+ LASSERT(filter->fo_obt.obt_health_check_filp != NULL);
+ rc |= !!lvfs_check_io_health(obd, filter->fo_obt.obt_health_check_filp);
#endif
return rc;
}
#include <linux/fs.h>
/* XATTR_{REPLACE,CREATE} */
#include <linux/xattr.h>
-/*
- * XXX temporary stuff: direct access to ldiskfs/jdb. Interface between osd
- * and file system is not yet specified.
- */
-/* handle_t, journal_start(), journal_stop() */
-#include <linux/jbd.h>
-/* LDISKFS_SB() */
-#include <linux/ldiskfs_fs.h>
-#include <linux/ldiskfs_jbd.h>
/* simple_mkdir() */
#include <lvfs.h>
struct osd_device *dev,
const struct osd_inode_id *id)
{
- struct inode *inode;
+ struct inode *inode = NULL;
+#ifdef HAVE_EXT4_LDISKFS
+ inode = ldiskfs_iget(osd_sb(dev), id->oii_ino);
+ if (IS_ERR(inode))
+ /* Newer kernels return an error instead of a NULL pointer */
+ inode = NULL;
+#else
inode = iget(osd_sb(dev), id->oii_ino);
+#endif
if (inode == NULL) {
CERROR("no inode\n");
inode = ERR_PTR(-EACCES);
* be used.
*/
- jh = journal_start(osd_journal(dev), p->tp_credits);
+ jh = ldiskfs_journal_start_sb(osd_sb(dev), p->tp_credits);
if (!IS_ERR(jh)) {
oh->ot_handle = jh;
th = &oh->ot_super;
/* add commit callback */
lu_context_init(&th->th_ctx, LCT_TX_HANDLE);
lu_context_enter(&th->th_ctx);
- journal_callback_set(jh, osd_trans_commit_cb,
- (struct journal_callback *)&oh->ot_jcb);
+ osd_journal_callback_set(jh, osd_trans_commit_cb,
+ (struct journal_callback *)&oh->ot_jcb);
LASSERT(oti->oti_txns == 0);
LASSERT(oti->oti_r_locks == 0);
LASSERT(oti->oti_w_locks == 0);
if (result != 0)
CERROR("Failure in transaction hook: %d\n", result);
oh->ot_handle = NULL;
- result = journal_stop(hdl);
+ result = ldiskfs_journal_stop(hdl);
if (result != 0)
CERROR("Failure to stop transaction: %d\n", result);
}
struct lustre_sb_info *lsi;
ENTRY;
-
if (o->od_mount != NULL) {
CERROR("Already mounted (%s)\n", dev);
RETURN(-EEXIST);
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
-#include <linux/jbd.h>
#include <linux/time.h>
-#include <linux/ldiskfs_fs.h>
-#include <linux/ldiskfs_jbd.h>
#include <linux/fcntl.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/module.h>
#include <asm/unaligned.h>
#include <linux/dynlocks.h>
-
/*
* linux/include/linux/osd_iam.h
*/
};
#ifdef __KERNEL__
-/* handle_t, journal_start(), journal_stop() */
-#include <linux/jbd.h>
/*
* Debugging.
return path->ip_data->ipd_key_scratch[nr];
}
+
static inline struct dynlock *path_dynlock(struct iam_path *path)
{
return &LDISKFS_I(iam_path_obj(path))->i_htree_lock;
int iam_node_read(struct iam_container *c, iam_ptr_t ptr,
handle_t *handle, struct buffer_head **bh);
-int iam_lvar_create(struct inode *obj, int keysize, int ptrsize,
- int recsize, handle_t *handle);
-int iam_lfix_create(struct inode *obj, int keysize, int ptrsize,
- int recsize, handle_t *handle);
+int iam_lvar_create(struct inode *obj,
+ int keysize, int ptrsize, int recsize, handle_t *handle);
#ifndef swap
#define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0)
void iam_lvar_format_init(void);
void iam_htree_format_init(void);
+int iam_lfix_create(struct inode *obj,
+ int keysize, int ptrsize, int recsize, handle_t *handle);
struct iam_private_info;
void ldiskfs_iam_release(struct file *filp, struct inode *inode);
*/
#include <linux/types.h>
-#include <linux/jbd.h>
-/* ldiskfs_error() */
-#include <linux/ldiskfs_fs.h>
#include "osd_internal.h"
/*
memcpy(dst, &__val, sizeof(*(dst))); \
})
-#include <linux/jbd.h>
-#include <linux/ldiskfs_fs.h>
-#include <linux/ldiskfs_jbd.h>
-
static void lfix_root(void *buf,
int blocksize, int keysize, int ptrsize, int recsize)
{
*/
#include <linux/types.h>
-#include <linux/jbd.h>
-/* ldiskfs_error() */
-#include <linux/ldiskfs_fs.h>
#include "osd_internal.h"
/*
} else {
struct ldiskfs_dx_hash_info hinfo;
- if (LVAR_HASH_TEA)
- hinfo.hash_version = LDISKFS_DX_HASH_TEA;
- else
- hinfo.hash_version = LDISKFS_DX_HASH_R5;
+ hinfo.hash_version = LDISKFS_DX_HASH_TEA;
hinfo.seed = 0;
ldiskfsfs_dirhash(name, namelen, &hinfo);
result = hinfo.hash;
*(char *)e_rec(entry) = recsize;
}
-#include <linux/jbd.h>
-#include <linux/ldiskfs_fs.h>
-#include <linux/ldiskfs_jbd.h>
-
int iam_lvar_create(struct inode *obj,
int keysize, int ptrsize, int recsize, handle_t *handle)
{
/* struct rw_semaphore */
#include <linux/rwsem.h>
-/* handle_t, journal_start(), journal_stop() */
-#include <linux/jbd.h>
-/* struct dx_hash_info */
-#include <linux/ldiskfs_fs.h>
/* struct dentry */
#include <linux/dcache.h>
/* struct dirent64 */
#include <linux/dirent.h>
+#ifdef HAVE_EXT4_LDISKFS
+#include <ldiskfs/ldiskfs.h>
+#include <ldiskfs/ldiskfs_jbd2.h>
+#define osd_journal_callback_set(handle, func, jcb) jbd2_journal_callback_set(handle, func, jcb)
+#else
+#include <linux/jbd.h>
+#include <linux/ldiskfs_fs.h>
+#include <linux/ldiskfs_jbd.h>
+#define osd_journal_callback_set(handle, func, jcb) journal_callback_set(handle, func, jcb)
+#endif
+
+
/* LUSTRE_OSD_NAME */
#include <obd.h>
/* class_register_type(), class_unregister_type(), class_get_type() */
[ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
mkdir -p $DIR/d52a
touch $DIR/d52a/foo
- chattr =a $DIR/d52a/foo || error "chattr =a failed"
+ chattr +a $DIR/d52a/foo || error "chattr +a failed"
echo bar >> $DIR/d52a/foo || error "append bar failed"
cp /etc/hosts $DIR/d52a/foo && error "cp worked"
rm -f $DIR/d52a/foo 2>/dev/null && error "rm worked"
link $DIR/d52a/foo $DIR/d52a/foo_link 2>/dev/null && error "link worked"
echo foo >> $DIR/d52a/foo || error "append foo failed"
mrename $DIR/d52a/foo $DIR/d52a/foo_ren && error "rename worked"
- lsattr $DIR/d52a/foo | egrep -q "^-+a-+ $DIR/d52a/foo" || error "lsattr"
+ lsattr $DIR/d52a/foo | egrep -q "^-+[ae]-+ $DIR/d52a/foo" || error "lsattr"
chattr -a $DIR/d52a/foo || error "chattr -a failed"
-
+ cp -r $DIR/d52a /tmp/
rm -fr $DIR/d52a || error "cleanup rm failed"
}
run_test 52a "append-only flag test (should return errors) ====="
[ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
mkdir -p $DIR/d52b
touch $DIR/d52b/foo
- chattr =i $DIR/d52b/foo || error
- cat test > $DIR/d52b/foo && error
- cp /etc/hosts $DIR/d52b/foo && error
- rm -f $DIR/d52b/foo 2>/dev/null && error
- link $DIR/d52b/foo $DIR/d52b/foo_link 2>/dev/null && error
- echo foo >> $DIR/d52b/foo && error
- mrename $DIR/d52b/foo $DIR/d52b/foo_ren && error
+ chattr +i $DIR/d52b/foo || error "chattr +i failed"
+ cat test > $DIR/d52b/foo && error "cat test worked"
+ cp /etc/hosts $DIR/d52b/foo && error "cp worked"
+ rm -f $DIR/d52b/foo 2>/dev/null && error "rm worked"
+ link $DIR/d52b/foo $DIR/d52b/foo_link 2>/dev/null && error "link worked"
+ echo foo >> $DIR/d52b/foo && error "echo worked"
+ mrename $DIR/d52b/foo $DIR/d52b/foo_ren && error "rename worked"
[ -f $DIR/d52b/foo ] || error
[ -f $DIR/d52b/foo_ren ] && error
- lsattr $DIR/d52b/foo | egrep -q "^-+i-+ $DIR/d52b/foo" || error
- chattr -i $DIR/d52b/foo || error
+ lsattr $DIR/d52b/foo | egrep -q "^-+[ie]-+ $DIR/d52b/foo" || error "lsattr"
+ chattr -i $DIR/d52b/foo || error "chattr failed"
rm -fr $DIR/d52b || error
}
int maj_high, maj_low, min;
int ret;
- strscat(mop->mo_mkfsopts, " -O dir_index", sizeof(mop->mo_mkfsopts));
+ strscat(mop->mo_mkfsopts, " -O dir_index,extents", sizeof(mop->mo_mkfsopts));
/* Upstream e2fsprogs called our uninit_groups feature uninit_bg,
* check for both of them when testing e2fsprogs features. */