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

Commit 9623e5a2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2:
  ocfs2: Fix a race in o2dlm lockres mastery
  Ocfs2: Handle deletion of reflinked oprhan inodes correctly.
  Ocfs2: Journaling i_flags and i_orphaned_slot when adding inode to orphan dir.
  ocfs2: Clear undo bits when local alloc is freed
  ocfs2: Init meta_ac properly in ocfs2_create_empty_xattr_block.
  ocfs2: Fix the update of name_offset when removing xattrs
  ocfs2: Always try for maximum bits with new local alloc windows
  ocfs2: set i_mode on disk during acl operations
  ocfs2: Update i_blocks in reflink operations.
  ocfs2: Change bg_chain check for ocfs2_validate_gd_parent.
  [PATCH] Skip check for mandatory locks when unlocking
parents 9f321603 14741472
Loading
Loading
Loading
Loading
+72 −5
Original line number Original line Diff line number Diff line
@@ -30,6 +30,8 @@
#include "alloc.h"
#include "alloc.h"
#include "dlmglue.h"
#include "dlmglue.h"
#include "file.h"
#include "file.h"
#include "inode.h"
#include "journal.h"
#include "ocfs2_fs.h"
#include "ocfs2_fs.h"


#include "xattr.h"
#include "xattr.h"
@@ -165,6 +167,60 @@ static struct posix_acl *ocfs2_get_acl(struct inode *inode, int type)
	return acl;
	return acl;
}
}


/*
 * Helper function to set i_mode in memory and disk. Some call paths
 * will not have di_bh or a journal handle to pass, in which case it
 * will create it's own.
 */
static int ocfs2_acl_set_mode(struct inode *inode, struct buffer_head *di_bh,
			      handle_t *handle, umode_t new_mode)
{
	int ret, commit_handle = 0;
	struct ocfs2_dinode *di;

	if (di_bh == NULL) {
		ret = ocfs2_read_inode_block(inode, &di_bh);
		if (ret) {
			mlog_errno(ret);
			goto out;
		}
	} else
		get_bh(di_bh);

	if (handle == NULL) {
		handle = ocfs2_start_trans(OCFS2_SB(inode->i_sb),
					   OCFS2_INODE_UPDATE_CREDITS);
		if (IS_ERR(handle)) {
			ret = PTR_ERR(handle);
			mlog_errno(ret);
			goto out_brelse;
		}

		commit_handle = 1;
	}

	di = (struct ocfs2_dinode *)di_bh->b_data;
	ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh,
				      OCFS2_JOURNAL_ACCESS_WRITE);
	if (ret) {
		mlog_errno(ret);
		goto out_commit;
	}

	inode->i_mode = new_mode;
	di->i_mode = cpu_to_le16(inode->i_mode);

	ocfs2_journal_dirty(handle, di_bh);

out_commit:
	if (commit_handle)
		ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
out_brelse:
	brelse(di_bh);
out:
	return ret;
}

/*
/*
 * Set the access or default ACL of an inode.
 * Set the access or default ACL of an inode.
 */
 */
@@ -193,9 +249,14 @@ static int ocfs2_set_acl(handle_t *handle,
			if (ret < 0)
			if (ret < 0)
				return ret;
				return ret;
			else {
			else {
				inode->i_mode = mode;
				if (ret == 0)
				if (ret == 0)
					acl = NULL;
					acl = NULL;

				ret = ocfs2_acl_set_mode(inode, di_bh,
							 handle, mode);
				if (ret)
					return ret;

			}
			}
		}
		}
		break;
		break;
@@ -283,6 +344,7 @@ int ocfs2_init_acl(handle_t *handle,
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
	struct posix_acl *acl = NULL;
	struct posix_acl *acl = NULL;
	int ret = 0;
	int ret = 0;
	mode_t mode;


	if (!S_ISLNK(inode->i_mode)) {
	if (!S_ISLNK(inode->i_mode)) {
		if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) {
		if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) {
@@ -291,12 +353,17 @@ int ocfs2_init_acl(handle_t *handle,
			if (IS_ERR(acl))
			if (IS_ERR(acl))
				return PTR_ERR(acl);
				return PTR_ERR(acl);
		}
		}
		if (!acl)
		if (!acl) {
			inode->i_mode &= ~current_umask();
			mode = inode->i_mode & ~current_umask();
			ret = ocfs2_acl_set_mode(inode, di_bh, handle, mode);
			if (ret) {
				mlog_errno(ret);
				goto cleanup;
			}
		}
	}
	}
	if ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) && acl) {
	if ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) && acl) {
		struct posix_acl *clone;
		struct posix_acl *clone;
		mode_t mode;


		if (S_ISDIR(inode->i_mode)) {
		if (S_ISDIR(inode->i_mode)) {
			ret = ocfs2_set_acl(handle, inode, di_bh,
			ret = ocfs2_set_acl(handle, inode, di_bh,
@@ -313,7 +380,7 @@ int ocfs2_init_acl(handle_t *handle,
		mode = inode->i_mode;
		mode = inode->i_mode;
		ret = posix_acl_create_masq(clone, &mode);
		ret = posix_acl_create_masq(clone, &mode);
		if (ret >= 0) {
		if (ret >= 0) {
			inode->i_mode = mode;
			ret = ocfs2_acl_set_mode(inode, di_bh, handle, mode);
			if (ret > 0) {
			if (ret > 0) {
				ret = ocfs2_set_acl(handle, inode,
				ret = ocfs2_set_acl(handle, inode,
						    di_bh, ACL_TYPE_ACCESS,
						    di_bh, ACL_TYPE_ACCESS,
+1 −3
Original line number Original line Diff line number Diff line
@@ -1875,7 +1875,6 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data,
ok:
ok:
		spin_unlock(&res->spinlock);
		spin_unlock(&res->spinlock);
	}
	}
	spin_unlock(&dlm->spinlock);


	// mlog(0, "woo!  got an assert_master from node %u!\n",
	// mlog(0, "woo!  got an assert_master from node %u!\n",
	// 	     assert->node_idx);
	// 	     assert->node_idx);
@@ -1926,7 +1925,6 @@ ok:
		/* master is known, detach if not already detached.
		/* master is known, detach if not already detached.
		 * ensures that only one assert_master call will happen
		 * ensures that only one assert_master call will happen
		 * on this mle. */
		 * on this mle. */
		spin_lock(&dlm->spinlock);
		spin_lock(&dlm->master_lock);
		spin_lock(&dlm->master_lock);


		rr = atomic_read(&mle->mle_refs.refcount);
		rr = atomic_read(&mle->mle_refs.refcount);
@@ -1959,7 +1957,6 @@ ok:
			__dlm_put_mle(mle);
			__dlm_put_mle(mle);
		}
		}
		spin_unlock(&dlm->master_lock);
		spin_unlock(&dlm->master_lock);
		spin_unlock(&dlm->spinlock);
	} else if (res) {
	} else if (res) {
		if (res->owner != assert->node_idx) {
		if (res->owner != assert->node_idx) {
			mlog(0, "assert_master from %u, but current "
			mlog(0, "assert_master from %u, but current "
@@ -1967,6 +1964,7 @@ ok:
			     res->owner, namelen, name);
			     res->owner, namelen, name);
		}
		}
	}
	}
	spin_unlock(&dlm->spinlock);


done:
done:
	ret = 0;
	ret = 0;
+15 −0
Original line number Original line Diff line number Diff line
@@ -891,6 +891,21 @@ static int ocfs2_query_inode_wipe(struct inode *inode,
	/* Do some basic inode verification... */
	/* Do some basic inode verification... */
	di = (struct ocfs2_dinode *) di_bh->b_data;
	di = (struct ocfs2_dinode *) di_bh->b_data;
	if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL))) {
	if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL))) {
		/*
		 * Inodes in the orphan dir must have ORPHANED_FL.  The only
		 * inodes that come back out of the orphan dir are reflink
		 * targets. A reflink target may be moved out of the orphan
		 * dir between the time we scan the directory and the time we
		 * process it. This would lead to HAS_REFCOUNT_FL being set but
		 * ORPHANED_FL not.
		 */
		if (di->i_dyn_features & cpu_to_le16(OCFS2_HAS_REFCOUNT_FL)) {
			mlog(0, "Reflinked inode %llu is no longer orphaned.  "
			     "it shouldn't be deleted\n",
			     (unsigned long long)oi->ip_blkno);
			goto bail;
		}

		/* for lack of a better error? */
		/* for lack of a better error? */
		status = -EEXIST;
		status = -EEXIST;
		mlog(ML_ERROR,
		mlog(ML_ERROR,
+6 −4
Original line number Original line Diff line number Diff line
@@ -872,8 +872,10 @@ static int ocfs2_sync_local_to_main(struct ocfs2_super *osb,
			     (unsigned long long)la_start_blk,
			     (unsigned long long)la_start_blk,
			     (unsigned long long)blkno);
			     (unsigned long long)blkno);


			status = ocfs2_free_clusters(handle, main_bm_inode,
			status = ocfs2_release_clusters(handle,
						     main_bm_bh, blkno, count);
							main_bm_inode,
							main_bm_bh, blkno,
							count);
			if (status < 0) {
			if (status < 0) {
				mlog_errno(status);
				mlog_errno(status);
				goto bail;
				goto bail;
@@ -984,8 +986,7 @@ static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb,
	}
	}


retry_enospc:
retry_enospc:
	(*ac)->ac_bits_wanted = osb->local_alloc_bits;
	(*ac)->ac_bits_wanted = osb->local_alloc_default_bits;

	status = ocfs2_reserve_cluster_bitmap_bits(osb, *ac);
	status = ocfs2_reserve_cluster_bitmap_bits(osb, *ac);
	if (status == -ENOSPC) {
	if (status == -ENOSPC) {
		if (ocfs2_recalc_la_window(osb, OCFS2_LA_EVENT_ENOSPC) ==
		if (ocfs2_recalc_la_window(osb, OCFS2_LA_EVENT_ENOSPC) ==
@@ -1061,6 +1062,7 @@ retry_enospc:
		    OCFS2_LA_DISABLED)
		    OCFS2_LA_DISABLED)
			goto bail;
			goto bail;


		ac->ac_bits_wanted = osb->local_alloc_default_bits;
		status = ocfs2_claim_clusters(osb, handle, ac,
		status = ocfs2_claim_clusters(osb, handle, ac,
					      osb->local_alloc_bits,
					      osb->local_alloc_bits,
					      &cluster_off,
					      &cluster_off,
+1 −1
Original line number Original line Diff line number Diff line
@@ -133,7 +133,7 @@ int ocfs2_lock(struct file *file, int cmd, struct file_lock *fl)


	if (!(fl->fl_flags & FL_POSIX))
	if (!(fl->fl_flags & FL_POSIX))
		return -ENOLCK;
		return -ENOLCK;
	if (__mandatory_lock(inode))
	if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
		return -ENOLCK;
		return -ENOLCK;


	return ocfs2_plock(osb->cconn, OCFS2_I(inode)->ip_blkno, file, cmd, fl);
	return ocfs2_plock(osb->cconn, OCFS2_I(inode)->ip_blkno, file, cmd, fl);
Loading