[Ocfs2-commits] mfasheh commits r2724 - branches/ocfs2-1.0/fs/ocfs2

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Wed Dec 7 20:10:37 CST 2005


Author: mfasheh
Signed-off-by: jlbec
Date: 2005-12-07 20:10:36 -0600 (Wed, 07 Dec 2005)
New Revision: 2724

Modified:
   branches/ocfs2-1.0/fs/ocfs2/dlmglue.c
   branches/ocfs2-1.0/fs/ocfs2/mmap.c
Log:
* Merge 2721-2722 from trunk:
        2721: Properly shutdown the vote thread on dlm initialization error.
        2722: Clear suid / sgid early in the write path

Signed-off-by: jlbec



Modified: branches/ocfs2-1.0/fs/ocfs2/dlmglue.c
===================================================================
--- branches/ocfs2-1.0/fs/ocfs2/dlmglue.c	2005-12-08 02:06:59 UTC (rev 2723)
+++ branches/ocfs2-1.0/fs/ocfs2/dlmglue.c	2005-12-08 02:10:36 UTC (rev 2724)
@@ -1976,8 +1976,11 @@
 
 	status = 0;
 bail:
-	if (status < 0)
+	if (status < 0) {
 		ocfs2_dlm_shutdown_debug(osb);
+		if (osb->vote_task)
+			kthread_stop(osb->vote_task);
+	}
 
 	mlog_exit(status);
 	return status;

Modified: branches/ocfs2-1.0/fs/ocfs2/mmap.c
===================================================================
--- branches/ocfs2-1.0/fs/ocfs2/mmap.c	2005-12-08 02:06:59 UTC (rev 2723)
+++ branches/ocfs2-1.0/fs/ocfs2/mmap.c	2005-12-08 02:10:36 UTC (rev 2724)
@@ -23,6 +23,7 @@
  * Boston, MA 021110-1307, USA.
  */
 
+#include <linux/sched.h>
 #include <linux/fs.h>
 #include <linux/types.h>
 #include <linux/slab.h>
@@ -37,11 +38,15 @@
 
 #include "ocfs2.h"
 
+#include "alloc.h"
 #include "dlmglue.h"
 #include "file.h"
 #include "inode.h"
+#include "journal.h"
 #include "mmap.h"
 
+#include "buffer_head_io.h"
+
 static inline u64 ocfs2_binode_blkno(struct ocfs2_backing_inode *binode);
 static inline struct rb_node * __ocfs2_buffer_lock_ctxt_root(
 	struct ocfs2_buffer_lock_ctxt *ctxt);
@@ -434,6 +439,74 @@
 	ctxt->b_next_unlocked = NULL;
 }
 
+static int ocfs2_write_remove_suid(struct inode *inode)
+{
+	int ret;
+	struct buffer_head *bh = NULL;
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+	ocfs2_journal_handle *handle;
+	ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	ocfs2_dinode *di;
+
+	mlog_entry("(Inode %"MLFu64", mode 0%o)\n", oi->ip_blkno,
+		   inode->i_mode);
+
+	handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS);
+	if (handle == NULL) {
+		ret = -ENOMEM;
+		mlog_errno(ret);
+		goto out;
+	}
+
+	ret = ocfs2_read_block(osb, oi->ip_blkno, &bh, OCFS2_BH_CACHED, inode);
+	if (ret < 0) {
+		mlog_errno(ret);
+		goto out_trans;
+	}
+
+	ocfs2_set_inode_lock_trans(osb->journal, inode);
+
+	ret = ocfs2_journal_access(handle, inode, bh,
+				   OCFS2_JOURNAL_ACCESS_WRITE);
+	if (ret < 0) {
+		mlog_errno(ret);
+		goto out_bh;
+	}
+
+	inode->i_mode &= ~S_ISUID;
+	if ((inode->i_mode & S_ISGID) && (inode->i_mode & S_IXGRP))
+		inode->i_mode &= ~S_ISGID;
+
+	di = (ocfs2_dinode *) bh->b_data;
+	di->i_mode = inode->i_mode;
+
+	ret = ocfs2_journal_dirty(handle, bh);
+	if (ret < 0)
+		mlog_errno(ret);
+out_bh:
+	brelse(bh);
+out_trans:
+	ocfs2_commit_trans(handle);
+out:
+
+	mlog_exit(ret);
+	return ret;
+}
+
+static inline int ocfs2_write_should_remove_suid(struct inode *inode)
+{
+	mode_t mode = inode->i_mode;
+
+	if (!capable(CAP_FSETID)) {
+		if (unlikely(mode & S_ISUID))
+			return 1;
+
+		if (unlikely((mode & S_ISGID) && (mode & S_IXGRP)))
+			return 1;
+	}
+	return 0;
+}
+
 /*
  * This builds up the locking state that will be used by a write.  both normal
  * file writes and AIO writes come in through here.  This function does no
@@ -513,6 +586,35 @@
 	if (level)
 		info->wl_target_binode->ba_lock_meta_level = 1;
 
+	/* Clear suid / sgid if necessary. We do this here instead of
+	 * later in the write path because remove_suid() calls
+	 * ->setattr without any hint that we may have already done
+	 * our cluster locking. Since ocfs2_setattr() *must* take
+	 * cluster locks to proceeed, this will lead us to recursively
+	 * lock the inode. There's also the dinode i_size state which
+	 * can be lost via setattr during extending writes (we set
+	 * inode->i_size at the end of a write. */
+	if (ocfs2_write_should_remove_suid(inode)) {
+		if (!level) {
+			mlog(0, "inode %"MLFu64", had a PR, looping back for "
+			     "EX so we can remove SUID\n",
+			     OCFS2_I(inode)->ip_blkno);
+			ocfs2_meta_unlock(inode, level);
+			info->wl_have_target_meta = 0;
+			level = 1;
+			goto lock;
+		}
+
+		status = ocfs2_write_remove_suid(inode);
+		if (status < 0) {
+			mlog_errno(status);
+			ret = status;
+			ocfs2_meta_unlock(inode, level);
+			info->wl_have_target_meta = 0;
+			goto bail;
+		}
+	}
+
 	/* work on a copy of ppos until we're sure that we won't have
 	 * to recalculate it due to relocking. */
 	saved_ppos = *ppos;



More information about the Ocfs2-commits mailing list