Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c271c5c2 authored by Sunil Mushran's avatar Sunil Mushran Committed by Mark Fasheh
Browse files

ocfs2: local mounts



This allows users to format an ocfs2 file system with a special flag,
OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT. When the file system sees this flag, it
will not use any cluster services, nor will it require a cluster
configuration, thus acting like a 'local' file system.

Signed-off-by: default avatarSunil Mushran <sunil.mushran@oracle.com>
Signed-off-by: default avatarMark Fasheh <mark.fasheh@oracle.com>
parent c9976797
Loading
Loading
Loading
Loading
+59 −20
Original line number Diff line number Diff line
@@ -770,7 +770,7 @@ static int ocfs2_lock_create(struct ocfs2_super *osb,
			     int dlm_flags)
{
	int ret = 0;
	enum dlm_status status;
	enum dlm_status status = DLM_NORMAL;
	unsigned long flags;

	mlog_entry_void();
@@ -1138,6 +1138,7 @@ int ocfs2_rw_lock(struct inode *inode, int write)
{
	int status, level;
	struct ocfs2_lock_res *lockres;
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);

	BUG_ON(!inode);

@@ -1147,6 +1148,9 @@ int ocfs2_rw_lock(struct inode *inode, int write)
	     (unsigned long long)OCFS2_I(inode)->ip_blkno,
	     write ? "EXMODE" : "PRMODE");

	if (ocfs2_mount_local(osb))
		return 0;

	lockres = &OCFS2_I(inode)->ip_rw_lockres;

	level = write ? LKM_EXMODE : LKM_PRMODE;
@@ -1164,6 +1168,7 @@ void ocfs2_rw_unlock(struct inode *inode, int write)
{
	int level = write ? LKM_EXMODE : LKM_PRMODE;
	struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_rw_lockres;
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);

	mlog_entry_void();

@@ -1171,6 +1176,7 @@ void ocfs2_rw_unlock(struct inode *inode, int write)
	     (unsigned long long)OCFS2_I(inode)->ip_blkno,
	     write ? "EXMODE" : "PRMODE");

	if (!ocfs2_mount_local(osb))
		ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level);

	mlog_exit_void();
@@ -1182,6 +1188,7 @@ int ocfs2_data_lock_full(struct inode *inode,
{
	int status = 0, level;
	struct ocfs2_lock_res *lockres;
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);

	BUG_ON(!inode);

@@ -1201,6 +1208,9 @@ int ocfs2_data_lock_full(struct inode *inode,
		goto out;
	}

	if (ocfs2_mount_local(osb))
		goto out;

	lockres = &OCFS2_I(inode)->ip_data_lockres;

	level = write ? LKM_EXMODE : LKM_PRMODE;
@@ -1269,6 +1279,7 @@ void ocfs2_data_unlock(struct inode *inode,
{
	int level = write ? LKM_EXMODE : LKM_PRMODE;
	struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_data_lockres;
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);

	mlog_entry_void();

@@ -1276,7 +1287,8 @@ void ocfs2_data_unlock(struct inode *inode,
	     (unsigned long long)OCFS2_I(inode)->ip_blkno,
	     write ? "EXMODE" : "PRMODE");

	if (!ocfs2_is_hard_readonly(OCFS2_SB(inode->i_sb)))
	if (!ocfs2_is_hard_readonly(OCFS2_SB(inode->i_sb)) &&
	    !ocfs2_mount_local(osb))
		ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level);

	mlog_exit_void();
@@ -1467,8 +1479,9 @@ static int ocfs2_meta_lock_update(struct inode *inode,
{
	int status = 0;
	struct ocfs2_inode_info *oi = OCFS2_I(inode);
	struct ocfs2_lock_res *lockres;
	struct ocfs2_lock_res *lockres = NULL;
	struct ocfs2_dinode *fe;
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);

	mlog_entry_void();

@@ -1483,10 +1496,12 @@ static int ocfs2_meta_lock_update(struct inode *inode,
	}
	spin_unlock(&oi->ip_lock);

	if (!ocfs2_mount_local(osb)) {
		lockres = &oi->ip_meta_lockres;

		if (!ocfs2_should_refresh_lock_res(lockres))
			goto bail;
	}

	/* This will discard any caching information we might have had
	 * for the inode metadata. */
@@ -1496,7 +1511,7 @@ static int ocfs2_meta_lock_update(struct inode *inode,
	 * map (directories, bitmap files, etc) */
	ocfs2_extent_map_trunc(inode, 0);

	if (ocfs2_meta_lvb_is_trustable(inode, lockres)) {
	if (lockres && ocfs2_meta_lvb_is_trustable(inode, lockres)) {
		mlog(0, "Trusting LVB on inode %llu\n",
		     (unsigned long long)oi->ip_blkno);
		ocfs2_refresh_inode_from_lvb(inode);
@@ -1543,6 +1558,7 @@ static int ocfs2_meta_lock_update(struct inode *inode,

	status = 0;
bail_refresh:
	if (lockres)
		ocfs2_complete_lock_res_refresh(lockres, status);
bail:
	mlog_exit(status);
@@ -1585,7 +1601,7 @@ int ocfs2_meta_lock_full(struct inode *inode,
			 int arg_flags)
{
	int status, level, dlm_flags, acquired;
	struct ocfs2_lock_res *lockres;
	struct ocfs2_lock_res *lockres = NULL;
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
	struct buffer_head *local_bh = NULL;

@@ -1607,6 +1623,9 @@ int ocfs2_meta_lock_full(struct inode *inode,
		goto bail;
	}

	if (ocfs2_mount_local(osb))
		goto local;

	if (!(arg_flags & OCFS2_META_LOCK_RECOVERY))
		wait_event(osb->recovery_event,
			   ocfs2_node_map_is_empty(osb, &osb->recovery_map));
@@ -1636,6 +1655,7 @@ int ocfs2_meta_lock_full(struct inode *inode,
		wait_event(osb->recovery_event,
			   ocfs2_node_map_is_empty(osb, &osb->recovery_map));

local:
	/*
	 * We only see this flag if we're being called from
	 * ocfs2_read_locked_inode(). It means we're locking an inode
@@ -1644,6 +1664,7 @@ int ocfs2_meta_lock_full(struct inode *inode,
	 */
	if (inode->i_state & I_NEW) {
		status = 0;
		if (lockres)
			ocfs2_complete_lock_res_refresh(lockres, 0);
		goto bail;
	}
@@ -1767,6 +1788,7 @@ void ocfs2_meta_unlock(struct inode *inode,
{
	int level = ex ? LKM_EXMODE : LKM_PRMODE;
	struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_meta_lockres;
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);

	mlog_entry_void();

@@ -1774,7 +1796,8 @@ void ocfs2_meta_unlock(struct inode *inode,
	     (unsigned long long)OCFS2_I(inode)->ip_blkno,
	     ex ? "EXMODE" : "PRMODE");

	if (!ocfs2_is_hard_readonly(OCFS2_SB(inode->i_sb)))
	if (!ocfs2_is_hard_readonly(OCFS2_SB(inode->i_sb)) &&
	    !ocfs2_mount_local(osb))
		ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level);

	mlog_exit_void();
@@ -1783,7 +1806,7 @@ void ocfs2_meta_unlock(struct inode *inode,
int ocfs2_super_lock(struct ocfs2_super *osb,
		     int ex)
{
	int status;
	int status = 0;
	int level = ex ? LKM_EXMODE : LKM_PRMODE;
	struct ocfs2_lock_res *lockres = &osb->osb_super_lockres;
	struct buffer_head *bh;
@@ -1794,6 +1817,9 @@ int ocfs2_super_lock(struct ocfs2_super *osb,
	if (ocfs2_is_hard_readonly(osb))
		return -EROFS;

	if (ocfs2_mount_local(osb))
		goto bail;

	status = ocfs2_cluster_lock(osb, lockres, level, 0, 0);
	if (status < 0) {
		mlog_errno(status);
@@ -1832,6 +1858,7 @@ void ocfs2_super_unlock(struct ocfs2_super *osb,
	int level = ex ? LKM_EXMODE : LKM_PRMODE;
	struct ocfs2_lock_res *lockres = &osb->osb_super_lockres;

	if (!ocfs2_mount_local(osb))
		ocfs2_cluster_unlock(osb, lockres, level);
}

@@ -1843,6 +1870,9 @@ int ocfs2_rename_lock(struct ocfs2_super *osb)
	if (ocfs2_is_hard_readonly(osb))
		return -EROFS;

	if (ocfs2_mount_local(osb))
		return 0;

	status = ocfs2_cluster_lock(osb, lockres, LKM_EXMODE, 0, 0);
	if (status < 0)
		mlog_errno(status);
@@ -1854,6 +1884,7 @@ void ocfs2_rename_unlock(struct ocfs2_super *osb)
{
	struct ocfs2_lock_res *lockres = &osb->osb_rename_lockres;

	if (!ocfs2_mount_local(osb))
		ocfs2_cluster_unlock(osb, lockres, LKM_EXMODE);
}

@@ -1869,6 +1900,9 @@ int ocfs2_dentry_lock(struct dentry *dentry, int ex)
	if (ocfs2_is_hard_readonly(osb))
		return -EROFS;

	if (ocfs2_mount_local(osb))
		return 0;

	ret = ocfs2_cluster_lock(osb, &dl->dl_lockres, level, 0, 0);
	if (ret < 0)
		mlog_errno(ret);
@@ -1882,6 +1916,7 @@ void ocfs2_dentry_unlock(struct dentry *dentry, int ex)
	struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
	struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);

	if (!ocfs2_mount_local(osb))
		ocfs2_cluster_unlock(osb, &dl->dl_lockres, level);
}

@@ -2145,12 +2180,15 @@ static void ocfs2_dlm_shutdown_debug(struct ocfs2_super *osb)

int ocfs2_dlm_init(struct ocfs2_super *osb)
{
	int status;
	int status = 0;
	u32 dlm_key;
	struct dlm_ctxt *dlm;
	struct dlm_ctxt *dlm = NULL;

	mlog_entry_void();

	if (ocfs2_mount_local(osb))
		goto local;

	status = ocfs2_dlm_init_debug(osb);
	if (status < 0) {
		mlog_errno(status);
@@ -2178,11 +2216,12 @@ int ocfs2_dlm_init(struct ocfs2_super *osb)
		goto bail;
	}

	dlm_register_eviction_cb(dlm, &osb->osb_eviction_cb);

local:
	ocfs2_super_lock_res_init(&osb->osb_super_lockres, osb);
	ocfs2_rename_lock_res_init(&osb->osb_rename_lockres, osb);

	dlm_register_eviction_cb(dlm, &osb->osb_eviction_cb);

	osb->dlm = dlm;

	status = 0;
+9 −0
Original line number Diff line number Diff line
@@ -154,6 +154,9 @@ int ocfs2_register_hb_callbacks(struct ocfs2_super *osb)
{
	int status;

	if (ocfs2_mount_local(osb))
		return 0;

	status = o2hb_register_callback(&osb->osb_hb_down);
	if (status < 0) {
		mlog_errno(status);
@@ -172,6 +175,9 @@ void ocfs2_clear_hb_callbacks(struct ocfs2_super *osb)
{
	int status;

	if (ocfs2_mount_local(osb))
		return;

	status = o2hb_unregister_callback(&osb->osb_hb_down);
	if (status < 0)
		mlog_errno(status);
@@ -186,6 +192,9 @@ void ocfs2_stop_heartbeat(struct ocfs2_super *osb)
	int ret;
	char *argv[5], *envp[3];

	if (ocfs2_mount_local(osb))
		return;

	if (!osb->uuid_str) {
		/* This can happen if we don't get far enough in mount... */
		mlog(0, "No UUID with which to stop heartbeat!\n\n");
+2 −1
Original line number Diff line number Diff line
@@ -423,7 +423,8 @@ static int ocfs2_read_locked_inode(struct inode *inode,
	 * cluster lock before trusting anything anyway.
	 */
	can_lock = !(args->fi_flags & OCFS2_FI_FLAG_SYSFILE)
		&& !(args->fi_flags & OCFS2_FI_FLAG_NOLOCK);
		&& !(args->fi_flags & OCFS2_FI_FLAG_NOLOCK)
		&& !ocfs2_mount_local(osb);

	/*
	 * To maintain backwards compatibility with older versions of
+33 −13
Original line number Diff line number Diff line
@@ -144,8 +144,10 @@ handle_t *ocfs2_start_trans(struct ocfs2_super *osb, int max_buffs)
			ocfs2_abort(osb->sb, "Detected aborted journal");
			handle = ERR_PTR(-EROFS);
		}
	} else
	} else {
		if (!ocfs2_mount_local(osb))
			atomic_inc(&(osb->journal->j_num_trans));
	}

	return handle;
}
@@ -507,9 +509,23 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb)

	BUG_ON(atomic_read(&(osb->journal->j_num_trans)) != 0);

	if (ocfs2_mount_local(osb)) {
		journal_lock_updates(journal->j_journal);
		status = journal_flush(journal->j_journal);
		journal_unlock_updates(journal->j_journal);
		if (status < 0)
			mlog_errno(status);
	}

	if (status == 0) {
		/*
		 * Do not toggle if flush was unsuccessful otherwise
		 * will leave dirty metadata in a "clean" journal
		 */
		status = ocfs2_journal_toggle_dirty(osb, 0);
		if (status < 0)
			mlog_errno(status);
	}

	/* Shutdown the kernel journal system */
	journal_destroy(journal->j_journal);
@@ -549,7 +565,7 @@ static void ocfs2_clear_journal_error(struct super_block *sb,
	}
}

int ocfs2_journal_load(struct ocfs2_journal *journal)
int ocfs2_journal_load(struct ocfs2_journal *journal, int local)
{
	int status = 0;
	struct ocfs2_super *osb;
@@ -576,14 +592,18 @@ int ocfs2_journal_load(struct ocfs2_journal *journal)
	}

	/* Launch the commit thread */
	osb->commit_task = kthread_run(ocfs2_commit_thread, osb, "ocfs2cmt");
	if (!local) {
		osb->commit_task = kthread_run(ocfs2_commit_thread, osb,
					       "ocfs2cmt");
		if (IS_ERR(osb->commit_task)) {
			status = PTR_ERR(osb->commit_task);
			osb->commit_task = NULL;
		mlog(ML_ERROR, "unable to launch ocfs2commit thread, error=%d",
		     status);
			mlog(ML_ERROR, "unable to launch ocfs2commit thread, "
			     "error=%d", status);
			goto done;
		}
	} else
		osb->commit_task = NULL;

done:
	mlog_exit(status);
+4 −1
Original line number Diff line number Diff line
@@ -157,7 +157,7 @@ int ocfs2_journal_init(struct ocfs2_journal *journal,
void   ocfs2_journal_shutdown(struct ocfs2_super *osb);
int    ocfs2_journal_wipe(struct ocfs2_journal *journal,
			  int full);
int    ocfs2_journal_load(struct ocfs2_journal *journal);
int    ocfs2_journal_load(struct ocfs2_journal *journal, int local);
int    ocfs2_check_journals_nolocks(struct ocfs2_super *osb);
void   ocfs2_recovery_thread(struct ocfs2_super *osb,
			     int node_num);
@@ -174,6 +174,9 @@ static inline void ocfs2_checkpoint_inode(struct inode *inode)
{
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);

	if (ocfs2_mount_local(osb))
		return;

	if (!ocfs2_inode_fully_checkpointed(inode)) {
		/* WARNING: This only kicks off a single
		 * checkpoint. If someone races you and adds more
Loading