lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20071012160605.15119.60626.stgit@warthog.procyon.org.uk>
Date:	Fri, 12 Oct 2007 17:06:05 +0100
From:	David Howells <dhowells@...hat.com>
To:	viro@....linux.org.uk
Cc:	kwc@...i.umich.edu, Trond.Myklebust@...app.com,
	linux-kernel@...r.kernel.org, dhowells@...hat.com
Subject: [PATCH 09/52] CRED: Pass credentials down to ext4 block allocator

Pass credentials down to the ext4 block allocator.

Signed-off-by: David Howells <dhowells@...hat.com>
---

 fs/ext4/balloc.c                |   23 ++--
 fs/ext4/dir.c                   |   15 ++-
 fs/ext4/extents.c               |  129 +++++++++++++----------
 fs/ext4/ialloc.c                |    7 +
 fs/ext4/inode.c                 |  118 +++++++++++++--------
 fs/ext4/ioctl.c                 |    4 +
 fs/ext4/namei.c                 |  221 +++++++++++++++++++++++----------------
 fs/ext4/super.c                 |    8 +
 fs/ext4/xattr.c                 |   25 ++--
 fs/ext4/xattr.h                 |    7 +
 fs/ext4/xattr_trusted.c         |    4 +
 fs/ext4/xattr_user.c            |    4 +
 include/linux/ext4_fs.h         |   36 ++++--
 include/linux/ext4_fs_extents.h |    2 
 include/linux/ext4_jbd2.h       |    3 -
 15 files changed, 359 insertions(+), 247 deletions(-)

diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index a6ced53..e95557c 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -1367,19 +1367,20 @@ out:
 /**
  * ext4_has_free_blocks()
  * @sbi:		in-core super block structure.
+ * @cred:		credentials currently in force
  *
  * Check if filesystem has at least 1 free block available for allocation.
  */
-static int ext4_has_free_blocks(struct ext4_sb_info *sbi)
+static int ext4_has_free_blocks(struct ext4_sb_info *sbi, struct cred *cred)
 {
 	ext4_fsblk_t free_blocks, root_blocks;
 
 	free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
 	root_blocks = ext4_r_blocks_count(sbi->s_es);
 	if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
-		sbi->s_resuid != current->cred->uid &&
+		sbi->s_resuid != cred->uid &&
 		(sbi->s_resgid == 0 ||
-		 !in_group_p (current->cred, sbi->s_resgid))) {
+		 !in_group_p (cred, sbi->s_resgid))) {
 		return 0;
 	}
 	return 1;
@@ -1389,6 +1390,7 @@ static int ext4_has_free_blocks(struct ext4_sb_info *sbi)
  * ext4_should_retry_alloc()
  * @sb:			super block
  * @retries		number of attemps has been made
+ * @cred:		credentials currently in force
  *
  * ext4_should_retry_alloc() is called when ENOSPC is returned, and if
  * it is profitable to retry the operation, this function will wait
@@ -1397,9 +1399,10 @@ static int ext4_has_free_blocks(struct ext4_sb_info *sbi)
  *
  * if the total number of retries exceed three times, return FALSE.
  */
-int ext4_should_retry_alloc(struct super_block *sb, int *retries)
+int ext4_should_retry_alloc(struct super_block *sb, int *retries,
+			    struct cred *cred)
 {
-	if (!ext4_has_free_blocks(EXT4_SB(sb)) || (*retries)++ > 3)
+	if (!ext4_has_free_blocks(EXT4_SB(sb), cred) || (*retries)++ > 3)
 		return 0;
 
 	jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id);
@@ -1414,6 +1417,7 @@ int ext4_should_retry_alloc(struct super_block *sb, int *retries)
  * @goal:		given target block(filesystem wide)
  * @count:		target number of blocks to allocate
  * @errp:		error code
+ * @cred:		credentials currently in force
  *
  * ext4_new_blocks uses a goal block to assist allocation.  It tries to
  * allocate block(s) from the block group contains the goal block first. If that
@@ -1422,7 +1426,8 @@ int ext4_should_retry_alloc(struct super_block *sb, int *retries)
  *
  */
 ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode,
-			ext4_fsblk_t goal, unsigned long *count, int *errp)
+			ext4_fsblk_t goal, unsigned long *count, int *errp,
+			struct cred *cred)
 {
 	struct buffer_head *bitmap_bh = NULL;
 	struct buffer_head *gdp_bh;
@@ -1478,7 +1483,7 @@ ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode,
 	if (block_i && ((windowsz = block_i->rsv_window_node.rsv_goal_size) > 0))
 		my_rsv = &block_i->rsv_window_node;
 
-	if (!ext4_has_free_blocks(sbi)) {
+	if (!ext4_has_free_blocks(sbi, cred)) {
 		*errp = -ENOSPC;
 		goto out;
 	}
@@ -1682,11 +1687,11 @@ out:
 }
 
 ext4_fsblk_t ext4_new_block(handle_t *handle, struct inode *inode,
-			ext4_fsblk_t goal, int *errp)
+			ext4_fsblk_t goal, int *errp, struct cred *cred)
 {
 	unsigned long count = 1;
 
-	return ext4_new_blocks(handle, inode, goal, &count, errp);
+	return ext4_new_blocks(handle, inode, goal, &count, errp, cred);
 }
 
 /**
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index 3ab01c0..3ccd926 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -34,7 +34,7 @@ static unsigned char ext4_filetype_table[] = {
 
 static int ext4_readdir(struct file *, void *, filldir_t);
 static int ext4_dx_readdir(struct file * filp,
-			   void * dirent, filldir_t filldir);
+			   void * dirent, filldir_t filldir, struct cred *cred);
 static int ext4_release_dir (struct inode * inode,
 				struct file * filp);
 
@@ -96,6 +96,7 @@ int ext4_check_dir_entry (const char * function, struct inode * dir,
 static int ext4_readdir(struct file * filp,
 			 void * dirent, filldir_t filldir)
 {
+	struct cred *cred = filp->f_cred;
 	int error = 0;
 	unsigned long offset;
 	int i, stored;
@@ -112,7 +113,7 @@ static int ext4_readdir(struct file * filp,
 				    EXT4_FEATURE_COMPAT_DIR_INDEX) &&
 	    ((EXT4_I(inode)->i_flags & EXT4_INDEX_FL) ||
 	     ((inode->i_size >> sb->s_blocksize_bits) == 1))) {
-		err = ext4_dx_readdir(filp, dirent, filldir);
+		err = ext4_dx_readdir(filp, dirent, filldir, cred);
 		if (err != ERR_BAD_DX_DIR) {
 			ret = err;
 			goto out;
@@ -133,7 +134,8 @@ static int ext4_readdir(struct file * filp,
 		struct buffer_head *bh = NULL;
 
 		map_bh.b_state = 0;
-		err = ext4_get_blocks_wrap(NULL, inode, blk, 1, &map_bh, 0, 0);
+		err = ext4_get_blocks_wrap(NULL, inode, blk, 1, &map_bh, 0, 0,
+					   cred);
 		if (err > 0) {
 			pgoff_t index = map_bh.b_blocknr >>
 					(PAGE_CACHE_SHIFT - inode->i_blkbits);
@@ -143,7 +145,7 @@ static int ext4_readdir(struct file * filp,
 					&filp->f_ra, filp,
 					index, 1);
 			filp->f_ra.prev_index = index;
-			bh = ext4_bread(NULL, inode, blk, 0, &err);
+			bh = ext4_bread(NULL, inode, blk, 0, &err, cred);
 		}
 
 		/*
@@ -430,7 +432,8 @@ static int call_filldir(struct file * filp, void * dirent,
 }
 
 static int ext4_dx_readdir(struct file * filp,
-			 void * dirent, filldir_t filldir)
+			 void * dirent, filldir_t filldir,
+			 struct cred *cred)
 {
 	struct dir_private_info *info = filp->private_data;
 	struct inode *inode = filp->f_path.dentry->d_inode;
@@ -480,7 +483,7 @@ static int ext4_dx_readdir(struct file * filp,
 			filp->f_version = inode->i_version;
 			ret = ext4_htree_fill_tree(filp, info->curr_hash,
 						   info->curr_minor_hash,
-						   &info->next_hash);
+						   &info->next_hash, cred);
 			if (ret < 0)
 				return ret;
 			if (ret == 0) {
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 78beb09..472be1a 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -129,7 +129,8 @@ static int ext4_ext_get_access(handle_t *handle, struct inode *inode,
  *  - EIO
  */
 static int ext4_ext_dirty(handle_t *handle, struct inode *inode,
-				struct ext4_ext_path *path)
+				struct ext4_ext_path *path,
+				struct cred *cred)
 {
 	int err;
 	if (path->p_bh) {
@@ -137,7 +138,7 @@ static int ext4_ext_dirty(handle_t *handle, struct inode *inode,
 		err = ext4_journal_dirty_metadata(handle, path->p_bh);
 	} else {
 		/* path points to leaf/index in inode body */
-		err = ext4_mark_inode_dirty(handle, inode);
+		err = ext4_mark_inode_dirty(handle, inode, cred);
 	}
 	return err;
 }
@@ -177,12 +178,13 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode,
 static ext4_fsblk_t
 ext4_ext_new_block(handle_t *handle, struct inode *inode,
 			struct ext4_ext_path *path,
-			struct ext4_extent *ex, int *err)
+			struct ext4_extent *ex, int *err,
+			struct cred *cred)
 {
 	ext4_fsblk_t goal, newblock;
 
 	goal = ext4_ext_find_goal(inode, path, le32_to_cpu(ex->ee_block));
-	newblock = ext4_new_block(handle, inode, goal, err);
+	newblock = ext4_new_block(handle, inode, goal, err, cred);
 	return newblock;
 }
 
@@ -479,7 +481,7 @@ ext4_ext_binsearch(struct inode *inode, struct ext4_ext_path *path, int block)
 
 }
 
-int ext4_ext_tree_init(handle_t *handle, struct inode *inode)
+int ext4_ext_tree_init(handle_t *handle, struct inode *inode, struct cred *cred)
 {
 	struct ext4_extent_header *eh;
 
@@ -488,7 +490,7 @@ int ext4_ext_tree_init(handle_t *handle, struct inode *inode)
 	eh->eh_entries = 0;
 	eh->eh_magic = EXT4_EXT_MAGIC;
 	eh->eh_max = cpu_to_le16(ext4_ext_space_root(inode));
-	ext4_mark_inode_dirty(handle, inode);
+	ext4_mark_inode_dirty(handle, inode, cred);
 	ext4_ext_invalidate_cache(inode);
 	return 0;
 }
@@ -568,7 +570,8 @@ err:
  */
 static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
 				struct ext4_ext_path *curp,
-				int logical, ext4_fsblk_t ptr)
+				int logical, ext4_fsblk_t ptr,
+				struct cred *cred)
 {
 	struct ext4_extent_idx *ix;
 	int len, err;
@@ -611,7 +614,7 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
 			     > le16_to_cpu(curp->p_hdr->eh_max));
 	BUG_ON(ix > EXT_LAST_INDEX(curp->p_hdr));
 
-	err = ext4_ext_dirty(handle, inode, curp);
+	err = ext4_ext_dirty(handle, inode, curp, cred);
 	ext4_std_error(inode->i_sb, err);
 
 	return err;
@@ -629,7 +632,8 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
  */
 static int ext4_ext_split(handle_t *handle, struct inode *inode,
 				struct ext4_ext_path *path,
-				struct ext4_extent *newext, int at)
+				struct ext4_extent *newext, int at,
+				struct cred *cred)
 {
 	struct buffer_head *bh = NULL;
 	int depth = ext_depth(inode);
@@ -679,7 +683,8 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
 	/* allocate all needed blocks */
 	ext_debug("allocate %d blocks for indexes/leaf\n", depth - at);
 	for (a = 0; a < depth - at; a++) {
-		newblock = ext4_ext_new_block(handle, inode, path, newext, &err);
+		newblock = ext4_ext_new_block(handle, inode, path, newext, &err,
+					      cred);
 		if (newblock == 0)
 			goto cleanup;
 		ablocks[a] = newblock;
@@ -746,7 +751,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
 			goto cleanup;
 		path[depth].p_hdr->eh_entries =
 		     cpu_to_le16(le16_to_cpu(path[depth].p_hdr->eh_entries)-m);
-		err = ext4_ext_dirty(handle, inode, path + depth);
+		err = ext4_ext_dirty(handle, inode, path + depth, cred);
 		if (err)
 			goto cleanup;
 
@@ -827,7 +832,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
 			if (err)
 				goto cleanup;
 			path[i].p_hdr->eh_entries = cpu_to_le16(le16_to_cpu(path[i].p_hdr->eh_entries)-m);
-			err = ext4_ext_dirty(handle, inode, path + i);
+			err = ext4_ext_dirty(handle, inode, path + i, cred);
 			if (err)
 				goto cleanup;
 		}
@@ -837,7 +842,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
 
 	/* insert new index */
 	err = ext4_ext_insert_index(handle, inode, path + at,
-				    le32_to_cpu(border), newblock);
+				    le32_to_cpu(border), newblock, cred);
 
 cleanup:
 	if (bh) {
@@ -869,7 +874,8 @@ cleanup:
  */
 static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
 					struct ext4_ext_path *path,
-					struct ext4_extent *newext)
+					struct ext4_extent *newext,
+					struct cred *cred)
 {
 	struct ext4_ext_path *curp = path;
 	struct ext4_extent_header *neh;
@@ -878,7 +884,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
 	ext4_fsblk_t newblock;
 	int err = 0;
 
-	newblock = ext4_ext_new_block(handle, inode, path, newext, &err);
+	newblock = ext4_ext_new_block(handle, inode, path, newext, &err, cred);
 	if (newblock == 0)
 		return err;
 
@@ -940,7 +946,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
 		  le32_to_cpu(fidx->ei_block), idx_pblock(fidx));
 
 	neh->eh_depth = cpu_to_le16(path->p_depth + 1);
-	err = ext4_ext_dirty(handle, inode, curp);
+	err = ext4_ext_dirty(handle, inode, curp, cred);
 out:
 	brelse(bh);
 
@@ -954,7 +960,8 @@ out:
  */
 static int ext4_ext_create_new_leaf(handle_t *handle, struct inode *inode,
 					struct ext4_ext_path *path,
-					struct ext4_extent *newext)
+					struct ext4_extent *newext,
+					struct cred *cred)
 {
 	struct ext4_ext_path *curp;
 	int depth, i, err = 0;
@@ -974,7 +981,7 @@ repeat:
 	if (EXT_HAS_FREE_INDEX(curp)) {
 		/* if we found index with free entry, then use that
 		 * entry: create all needed subtree and add new leaf */
-		err = ext4_ext_split(handle, inode, path, newext, i);
+		err = ext4_ext_split(handle, inode, path, newext, i, cred);
 
 		/* refill path */
 		ext4_ext_drop_refs(path);
@@ -985,7 +992,7 @@ repeat:
 			err = PTR_ERR(path);
 	} else {
 		/* tree is full, time to grow in depth */
-		err = ext4_ext_grow_indepth(handle, inode, path, newext);
+		err = ext4_ext_grow_indepth(handle, inode, path, newext, cred);
 		if (err)
 			goto out;
 
@@ -1086,7 +1093,7 @@ static unsigned ext4_ext_next_leaf_block(struct inode *inode,
  * TODO: do we need to correct tree in all cases?
  */
 int ext4_ext_correct_indexes(handle_t *handle, struct inode *inode,
-				struct ext4_ext_path *path)
+				struct ext4_ext_path *path, struct cred *cred)
 {
 	struct ext4_extent_header *eh;
 	int depth = ext_depth(inode);
@@ -1118,7 +1125,7 @@ int ext4_ext_correct_indexes(handle_t *handle, struct inode *inode,
 	if (err)
 		return err;
 	path[k].p_idx->ei_block = border;
-	err = ext4_ext_dirty(handle, inode, path + k);
+	err = ext4_ext_dirty(handle, inode, path + k, cred);
 	if (err)
 		return err;
 
@@ -1130,7 +1137,7 @@ int ext4_ext_correct_indexes(handle_t *handle, struct inode *inode,
 		if (err)
 			break;
 		path[k].p_idx->ei_block = border;
-		err = ext4_ext_dirty(handle, inode, path + k);
+		err = ext4_ext_dirty(handle, inode, path + k, cred);
 		if (err)
 			break;
 	}
@@ -1284,7 +1291,8 @@ out:
  */
 int ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
 				struct ext4_ext_path *path,
-				struct ext4_extent *newext)
+				struct ext4_extent *newext,
+				struct cred *cred)
 {
 	struct ext4_extent_header * eh;
 	struct ext4_extent *ex, *fex;
@@ -1356,7 +1364,7 @@ repeat:
 	 * There is no free space in the found leaf.
 	 * We're gonna add a new leaf in the tree.
 	 */
-	err = ext4_ext_create_new_leaf(handle, inode, path, newext);
+	err = ext4_ext_create_new_leaf(handle, inode, path, newext, cred);
 	if (err)
 		goto cleanup;
 	depth = ext_depth(inode);
@@ -1420,11 +1428,11 @@ merge:
 	/* try to merge extents to the left */
 
 	/* time to correct all indexes above */
-	err = ext4_ext_correct_indexes(handle, inode, path);
+	err = ext4_ext_correct_indexes(handle, inode, path, cred);
 	if (err)
 		goto cleanup;
 
-	err = ext4_ext_dirty(handle, inode, path + depth);
+	err = ext4_ext_dirty(handle, inode, path + depth, cred);
 
 cleanup:
 	if (npath) {
@@ -1638,7 +1646,7 @@ ext4_ext_in_cache(struct inode *inode, unsigned long block,
  * last index in the block only.
  */
 int ext4_ext_rm_idx(handle_t *handle, struct inode *inode,
-			struct ext4_ext_path *path)
+			struct ext4_ext_path *path, struct cred *cred)
 {
 	struct buffer_head *bh;
 	int err;
@@ -1652,7 +1660,7 @@ int ext4_ext_rm_idx(handle_t *handle, struct inode *inode,
 	if (err)
 		return err;
 	path->p_hdr->eh_entries = cpu_to_le16(le16_to_cpu(path->p_hdr->eh_entries)-1);
-	err = ext4_ext_dirty(handle, inode, path);
+	err = ext4_ext_dirty(handle, inode, path, cred);
 	if (err)
 		return err;
 	ext_debug("index is empty, remove it, free block %llu\n", leaf);
@@ -1762,7 +1770,8 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode,
 
 static int
 ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
-		struct ext4_ext_path *path, unsigned long start)
+		struct ext4_ext_path *path, unsigned long start,
+		struct cred *cred)
 {
 	int err = 0, correct_index = 0;
 	int depth = ext_depth(inode), credits;
@@ -1861,7 +1870,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
 		if (uninitialized && num)
 			ext4_ext_mark_uninitialized(ex);
 
-		err = ext4_ext_dirty(handle, inode, path + depth);
+		err = ext4_ext_dirty(handle, inode, path + depth, cred);
 		if (err)
 			goto out;
 
@@ -1873,12 +1882,12 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
 	}
 
 	if (correct_index && eh->eh_entries)
-		err = ext4_ext_correct_indexes(handle, inode, path);
+		err = ext4_ext_correct_indexes(handle, inode, path, cred);
 
 	/* if this leaf is free, then we should
 	 * remove it from index block above */
 	if (err == 0 && eh->eh_entries == 0 && path[depth].p_bh != NULL)
-		err = ext4_ext_rm_idx(handle, inode, path + depth);
+		err = ext4_ext_rm_idx(handle, inode, path + depth, cred);
 
 out:
 	return err;
@@ -1905,7 +1914,8 @@ ext4_ext_more_to_rm(struct ext4_ext_path *path)
 	return 1;
 }
 
-int ext4_ext_remove_space(struct inode *inode, unsigned long start)
+int ext4_ext_remove_space(struct inode *inode, unsigned long start,
+			  struct cred *cred)
 {
 	struct super_block *sb = inode->i_sb;
 	int depth = ext_depth(inode);
@@ -1941,7 +1951,8 @@ int ext4_ext_remove_space(struct inode *inode, unsigned long start)
 	while (i >= 0 && err == 0) {
 		if (i == depth) {
 			/* this is leaf block */
-			err = ext4_ext_rm_leaf(handle, inode, path, start);
+			err = ext4_ext_rm_leaf(handle, inode, path, start,
+					       cred);
 			/* root level has p_bh == NULL, brelse() eats this */
 			brelse(path[i].p_bh);
 			path[i].p_bh = NULL;
@@ -2003,7 +2014,8 @@ int ext4_ext_remove_space(struct inode *inode, unsigned long start)
 				/* index is empty, remove it;
 				 * handle must be already prepared by the
 				 * truncatei_leaf() */
-				err = ext4_ext_rm_idx(handle, inode, path + i);
+				err = ext4_ext_rm_idx(handle, inode, path + i,
+						      cred);
 			}
 			/* root level has p_bh == NULL, brelse() eats this */
 			brelse(path[i].p_bh);
@@ -2024,7 +2036,7 @@ int ext4_ext_remove_space(struct inode *inode, unsigned long start)
 			ext_inode_hdr(inode)->eh_depth = 0;
 			ext_inode_hdr(inode)->eh_max =
 				cpu_to_le16(ext4_ext_space_root(inode));
-			err = ext4_ext_dirty(handle, inode, path);
+			err = ext4_ext_dirty(handle, inode, path, cred);
 		}
 	}
 out:
@@ -2098,7 +2110,8 @@ void ext4_ext_release(struct super_block *sb)
 int ext4_ext_convert_to_initialized(handle_t *handle, struct inode *inode,
 					struct ext4_ext_path *path,
 					ext4_fsblk_t iblock,
-					unsigned long max_blocks)
+					unsigned long max_blocks,
+					struct cred *cred)
 {
 	struct ext4_extent *ex, newex;
 	struct ext4_extent *ex1 = NULL;
@@ -2141,7 +2154,7 @@ int ext4_ext_convert_to_initialized(handle_t *handle, struct inode *inode,
 		ext4_ext_store_pblock(ex3, newblock + max_blocks);
 		ex3->ee_len = cpu_to_le16(allocated - max_blocks);
 		ext4_ext_mark_uninitialized(ex3);
-		err = ext4_ext_insert_extent(handle, inode, path, ex3);
+		err = ext4_ext_insert_extent(handle, inode, path, ex3, cred);
 		if (err)
 			goto out;
 		/*
@@ -2198,7 +2211,8 @@ int ext4_ext_convert_to_initialized(handle_t *handle, struct inode *inode,
 		 */
 		ret = ext4_ext_try_to_merge(inode, path, ex2 - 1);
 		if (ret) {
-			err = ext4_ext_correct_indexes(handle, inode, path);
+			err = ext4_ext_correct_indexes(handle, inode, path,
+						       cred);
 			if (err)
 				goto out;
 			depth = ext_depth(inode);
@@ -2213,16 +2227,17 @@ int ext4_ext_convert_to_initialized(handle_t *handle, struct inode *inode,
 	if (!ex3) {
 		ret = ext4_ext_try_to_merge(inode, path, ex2);
 		if (ret) {
-			err = ext4_ext_correct_indexes(handle, inode, path);
+			err = ext4_ext_correct_indexes(handle, inode, path,
+						       cred);
 			if (err)
 				goto out;
 		}
 	}
 	/* Mark modified extent as dirty */
-	err = ext4_ext_dirty(handle, inode, path + depth);
+	err = ext4_ext_dirty(handle, inode, path + depth, cred);
 	goto out;
 insert:
-	err = ext4_ext_insert_extent(handle, inode, path, &newex);
+	err = ext4_ext_insert_extent(handle, inode, path, &newex, cred);
 out:
 	return err ? err : allocated;
 }
@@ -2230,7 +2245,8 @@ out:
 int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
 			ext4_fsblk_t iblock,
 			unsigned long max_blocks, struct buffer_head *bh_result,
-			int create, int extend_disksize)
+			int create, int extend_disksize,
+			struct cred *cred)
 {
 	struct ext4_ext_path *path = NULL;
 	struct ext4_extent_header *eh;
@@ -2321,7 +2337,8 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
 
 			ret = ext4_ext_convert_to_initialized(handle, inode,
 								path, iblock,
-								max_blocks);
+								max_blocks,
+								cred);
 			if (ret <= 0)
 				goto out2;
 			else
@@ -2373,7 +2390,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
 		allocated = le16_to_cpu(newex.ee_len);
 	else
 		allocated = max_blocks;
-	newblock = ext4_new_blocks(handle, inode, goal, &allocated, &err);
+	newblock = ext4_new_blocks(handle, inode, goal, &allocated, &err, cred);
 	if (!newblock)
 		goto out2;
 	ext_debug("allocate new block: goal %llu, found %llu/%lu\n",
@@ -2384,7 +2401,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
 	newex.ee_len = cpu_to_le16(allocated);
 	if (create == EXT4_CREATE_UNINITIALIZED_EXT)  /* Mark uninitialized */
 		ext4_ext_mark_uninitialized(&newex);
-	err = ext4_ext_insert_extent(handle, inode, path, &newex);
+	err = ext4_ext_insert_extent(handle, inode, path, &newex, cred);
 	if (err) {
 		/* free data blocks we just allocated */
 		ext4_free_blocks(handle, inode, ext_pblock(&newex),
@@ -2421,7 +2438,8 @@ out2:
 	return err ? err : allocated;
 }
 
-void ext4_ext_truncate(struct inode * inode, struct page *page)
+void ext4_ext_truncate(struct inode * inode, struct page *page,
+		       struct cred *cred)
 {
 	struct address_space *mapping = inode->i_mapping;
 	struct super_block *sb = inode->i_sb;
@@ -2460,11 +2478,11 @@ void ext4_ext_truncate(struct inode * inode, struct page *page)
 
 	/* we have to know where to truncate from in crash case */
 	EXT4_I(inode)->i_disksize = inode->i_size;
-	ext4_mark_inode_dirty(handle, inode);
+	ext4_mark_inode_dirty(handle, inode, cred);
 
 	last_block = (inode->i_size + sb->s_blocksize - 1)
 			>> EXT4_BLOCK_SIZE_BITS(sb);
-	err = ext4_ext_remove_space(inode, last_block);
+	err = ext4_ext_remove_space(inode, last_block, cred);
 
 	/* In a multi-transaction truncate, we only make the final
 	 * transaction synchronous.
@@ -2517,6 +2535,7 @@ int ext4_ext_writepage_trans_blocks(struct inode *inode, int num)
  */
 long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len)
 {
+	struct cred *cred = current->cred;
 	handle_t *handle;
 	ext4_fsblk_t block, max_blocks;
 	ext4_fsblk_t nblocks = 0;
@@ -2558,7 +2577,8 @@ retry:
 
 		ret = ext4_ext_get_blocks(handle, inode, block,
 					  max_blocks, &map_bh,
-					  EXT4_CREATE_UNINITIALIZED_EXT, 0);
+					  EXT4_CREATE_UNINITIALIZED_EXT, 0,
+					  cred);
 		WARN_ON(!ret);
 		if (!ret) {
 			ext4_error(inode->i_sb, "ext4_fallocate",
@@ -2566,7 +2586,7 @@ retry:
 				   ", block=%llu, max_blocks=%llu",
 				   inode->i_ino, block, max_blocks);
 			ret = -EIO;
-			ext4_mark_inode_dirty(handle, inode);
+			ext4_mark_inode_dirty(handle, inode, cred);
 			ret2 = ext4_journal_stop(handle);
 			break;
 		}
@@ -2574,7 +2594,7 @@ retry:
 			/* check wrap through sign-bit/zero here */
 			if ((block + ret) < 0 || (block + ret) < block) {
 				ret = -EIO;
-				ext4_mark_inode_dirty(handle, inode);
+				ext4_mark_inode_dirty(handle, inode, cred);
 				ret2 = ext4_journal_stop(handle);
 				break;
 			}
@@ -2593,13 +2613,14 @@ retry:
 				inode->i_ctime = now;
 		}
 
-		ext4_mark_inode_dirty(handle, inode);
+		ext4_mark_inode_dirty(handle, inode, cred);
 		ret2 = ext4_journal_stop(handle);
 		if (ret2)
 			break;
 	}
 
-	if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
+	if (ret == -ENOSPC &&
+	    ext4_should_retry_alloc(inode->i_sb, &retries, cred))
 		goto retry;
 
 	/*
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 488cc2b..937610d 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -424,7 +424,8 @@ static int find_group_other(struct super_block *sb, struct inode *parent)
  * For other inodes, search forward from the parent directory's block
  * group to find a free inode.
  */
-struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode)
+struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode,
+			     struct cred *cred)
 {
 	struct super_block *sb;
 	struct buffer_head *bitmap_bh = NULL;
@@ -613,14 +614,14 @@ got:
 	if (err)
 		goto fail_free_drop;
 
-	err = ext4_mark_inode_dirty(handle, inode);
+	err = ext4_mark_inode_dirty(handle, inode, cred);
 	if (err) {
 		ext4_std_error(sb, err);
 		goto fail_free_drop;
 	}
 	if (test_opt(sb, EXTENTS)) {
 		EXT4_I(inode)->i_flags |= EXT4_EXTENTS_FL;
-		ext4_ext_tree_init(handle, inode);
+		ext4_ext_tree_init(handle, inode, cred);
 		if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
 			err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh);
 			if (err) goto fail;
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index c4fb1eb..f09cb71 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -179,6 +179,7 @@ static int ext4_journal_test_restart(handle_t *handle, struct inode *inode)
  */
 void ext4_delete_inode (struct inode * inode)
 {
+	struct cred *cred = &init_cred;
 	handle_t *handle;
 
 	truncate_inode_pages(&inode->i_data, 0);
@@ -220,7 +221,7 @@ void ext4_delete_inode (struct inode * inode)
 	 * having errors), but we can't free the inode if the mark_dirty
 	 * fails.
 	 */
-	if (ext4_mark_inode_dirty(handle, inode))
+	if (ext4_mark_inode_dirty(handle, inode, cred))
 		/* If that failed, just do the required in-core inode clear. */
 		clear_inode(inode);
 	else
@@ -511,10 +512,11 @@ static int ext4_blks_to_allocate(Indirect *branch, int k, unsigned long blks,
  *	the indirect blocks(if needed) and the first direct block,
  *	@blks:	on return it will store the total number of allocated
  *		direct blocks
+ *	@cred:	the credentials currently in force
  */
 static int ext4_alloc_blocks(handle_t *handle, struct inode *inode,
 			ext4_fsblk_t goal, int indirect_blks, int blks,
-			ext4_fsblk_t new_blocks[4], int *err)
+			ext4_fsblk_t new_blocks[4], int *err, struct cred *cred)
 {
 	int target, i;
 	unsigned long count = 0;
@@ -535,7 +537,8 @@ static int ext4_alloc_blocks(handle_t *handle, struct inode *inode,
 	while (1) {
 		count = target;
 		/* allocating blocks for indirect blocks and direct blocks */
-		current_block = ext4_new_blocks(handle,inode,goal,&count,err);
+		current_block = ext4_new_blocks(handle, inode, goal, &count,
+						err, cred);
 		if (*err)
 			goto failed_out;
 
@@ -590,7 +593,7 @@ failed_out:
  */
 static int ext4_alloc_branch(handle_t *handle, struct inode *inode,
 			int indirect_blks, int *blks, ext4_fsblk_t goal,
-			int *offsets, Indirect *branch)
+			int *offsets, Indirect *branch, struct cred *cred)
 {
 	int blocksize = inode->i_sb->s_blocksize;
 	int i, n = 0;
@@ -601,7 +604,7 @@ static int ext4_alloc_branch(handle_t *handle, struct inode *inode,
 	ext4_fsblk_t current_block;
 
 	num = ext4_alloc_blocks(handle, inode, goal, indirect_blks,
-				*blks, new_blocks, &err);
+				*blks, new_blocks, &err, cred);
 	if (err)
 		return err;
 
@@ -674,13 +677,15 @@ failed:
  * @where: location of missing link
  * @num:   number of indirect blocks we are adding
  * @blks:  number of direct blocks we are adding
+ * @cred:  the credentials in force
  *
  * This function fills the missing link and does all housekeeping needed in
  * inode (->i_blocks, etc.). In case of success we end up with the full
  * chain to new block and return 0.
  */
 static int ext4_splice_branch(handle_t *handle, struct inode *inode,
-			long block, Indirect *where, int num, int blks)
+			long block, Indirect *where, int num, int blks,
+			struct cred *cred)
 {
 	int i;
 	int err = 0;
@@ -727,7 +732,7 @@ static int ext4_splice_branch(handle_t *handle, struct inode *inode,
 	/* We are done with atomic stuff, now do the rest of housekeeping */
 
 	inode->i_ctime = ext4_current_time(inode);
-	ext4_mark_inode_dirty(handle, inode);
+	ext4_mark_inode_dirty(handle, inode, cred);
 
 	/* had we spliced it onto indirect block? */
 	if (where->bh) {
@@ -786,7 +791,7 @@ err_out:
 int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
 		sector_t iblock, unsigned long maxblocks,
 		struct buffer_head *bh_result,
-		int create, int extend_disksize)
+		int create, int extend_disksize, struct cred *cred)
 {
 	int err = -EIO;
 	int offsets[4];
@@ -898,7 +903,7 @@ int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
 	 * Block out ext4_truncate while we alter the tree
 	 */
 	err = ext4_alloc_branch(handle, inode, indirect_blks, &count, goal,
-				offsets + (partial - chain), partial);
+				offsets + (partial - chain), partial, cred);
 
 	/*
 	 * The ext4_splice_branch call will free and forget any buffers
@@ -909,7 +914,7 @@ int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
 	 */
 	if (!err)
 		err = ext4_splice_branch(handle, inode, iblock,
-					partial, indirect_blks, count);
+					partial, indirect_blks, count, cred);
 	/*
 	 * i_disksize growing is protected by truncate_mutex.  Don't forget to
 	 * protect it if you're about to implement concurrent
@@ -945,6 +950,7 @@ out:
 static int ext4_get_block(struct inode *inode, sector_t iblock,
 			struct buffer_head *bh_result, int create)
 {
+	struct cred *cred = current->cred;
 	handle_t *handle = ext4_journal_current_handle();
 	int ret = 0;
 	unsigned max_blocks = bh_result->b_size >> inode->i_blkbits;
@@ -983,7 +989,7 @@ static int ext4_get_block(struct inode *inode, sector_t iblock,
 get_block:
 	if (ret == 0) {
 		ret = ext4_get_blocks_wrap(handle, inode, iblock,
-					max_blocks, bh_result, create, 0);
+					max_blocks, bh_result, create, 0, cred);
 		if (ret > 0) {
 			bh_result->b_size = (ret << inode->i_blkbits);
 			ret = 0;
@@ -996,7 +1002,8 @@ get_block:
  * `handle' can be NULL if create is zero
  */
 struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode,
-				long block, int create, int *errp)
+				long block, int create, int *errp,
+				struct cred *cred)
 {
 	struct buffer_head dummy;
 	int fatal = 0, err;
@@ -1007,7 +1014,7 @@ struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode,
 	dummy.b_blocknr = -1000;
 	buffer_trace_init(&dummy.b_history);
 	err = ext4_get_blocks_wrap(handle, inode, block, 1,
-					&dummy, create, 1);
+					&dummy, create, 1, cred);
 	/*
 	 * ext4_get_blocks_handle() returns number of blocks
 	 * mapped. 0 in case of a HOLE.
@@ -1063,11 +1070,12 @@ err:
 }
 
 struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode,
-			       int block, int create, int *err)
+			       int block, int create, int *err,
+			       struct cred *cred)
 {
 	struct buffer_head * bh;
 
-	bh = ext4_getblk(handle, inode, block, create, err);
+	bh = ext4_getblk(handle, inode, block, create, err, cred);
 	if (!bh)
 		return bh;
 	if (buffer_uptodate(bh))
@@ -1149,6 +1157,7 @@ static int do_journal_get_write_access(handle_t *handle,
 static int ext4_prepare_write(struct file *file, struct page *page,
 			      unsigned from, unsigned to)
 {
+	struct cred *cred = file->f_cred;
 	struct inode *inode = page->mapping->host;
 	int ret, needed_blocks = ext4_writepage_trans_blocks(inode);
 	handle_t *handle;
@@ -1174,7 +1183,8 @@ retry:
 prepare_write_failed:
 	if (ret)
 		ext4_journal_stop(handle);
-	if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
+	if (ret == -ENOSPC &&
+	    ext4_should_retry_alloc(inode->i_sb, &retries, cred))
 		goto retry;
 out:
 	return ret;
@@ -1260,6 +1270,7 @@ static int ext4_writeback_commit_write(struct file *file, struct page *page,
 static int ext4_journalled_commit_write(struct file *file,
 			struct page *page, unsigned from, unsigned to)
 {
+	struct cred *cred = file->f_cred;
 	handle_t *handle = ext4_journal_current_handle();
 	struct inode *inode = page->mapping->host;
 	int ret = 0, ret2;
@@ -1280,7 +1291,7 @@ static int ext4_journalled_commit_write(struct file *file,
 	EXT4_I(inode)->i_state |= EXT4_STATE_JDATA;
 	if (inode->i_size > EXT4_I(inode)->i_disksize) {
 		EXT4_I(inode)->i_disksize = inode->i_size;
-		ret2 = ext4_mark_inode_dirty(handle, inode);
+		ret2 = ext4_mark_inode_dirty(handle, inode, cred);
 		if (!ret)
 			ret = ret2;
 	}
@@ -1619,6 +1630,7 @@ static ssize_t ext4_direct_IO(int rw, struct kiocb *iocb,
 			unsigned long nr_segs)
 {
 	struct file *file = iocb->ki_filp;
+	struct cred *cred = file->f_cred;
 	struct inode *inode = file->f_mapping->host;
 	struct ext4_inode_info *ei = EXT4_I(inode);
 	handle_t *handle = NULL;
@@ -1670,7 +1682,7 @@ out_stop:
 				 * ext4_mark_inode_dirty() to userspace.  So
 				 * ignore it.
 				 */
-				ext4_mark_inode_dirty(handle, inode);
+				ext4_mark_inode_dirty(handle, inode, cred);
 			}
 		}
 		err = ext4_journal_stop(handle);
@@ -1955,7 +1967,8 @@ no_top:
  */
 static void ext4_clear_blocks(handle_t *handle, struct inode *inode,
 		struct buffer_head *bh, ext4_fsblk_t block_to_free,
-		unsigned long count, __le32 *first, __le32 *last)
+		unsigned long count, __le32 *first, __le32 *last,
+		struct cred *cred)
 {
 	__le32 *p;
 	if (try_to_extend_transaction(handle, inode)) {
@@ -1963,7 +1976,7 @@ static void ext4_clear_blocks(handle_t *handle, struct inode *inode,
 			BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata");
 			ext4_journal_dirty_metadata(handle, bh);
 		}
-		ext4_mark_inode_dirty(handle, inode);
+		ext4_mark_inode_dirty(handle, inode, cred);
 		ext4_journal_test_restart(handle, inode);
 		if (bh) {
 			BUFFER_TRACE(bh, "retaking write access");
@@ -2000,6 +2013,7 @@ static void ext4_clear_blocks(handle_t *handle, struct inode *inode,
  * @this_bh:	indirect buffer_head which contains *@...st and *@...t
  * @first:	array of block numbers
  * @last:	points immediately past the end of array
+ * @cred:	credentials to use
  *
  * We are freeing all blocks refered from that array (numbers are stored as
  * little-endian 32-bit) and updating @inode->i_blocks appropriately.
@@ -2014,7 +2028,8 @@ static void ext4_clear_blocks(handle_t *handle, struct inode *inode,
  */
 static void ext4_free_data(handle_t *handle, struct inode *inode,
 			   struct buffer_head *this_bh,
-			   __le32 *first, __le32 *last)
+			   __le32 *first, __le32 *last,
+			   struct cred *cred)
 {
 	ext4_fsblk_t block_to_free = 0;    /* Starting block # of a run */
 	unsigned long count = 0;	    /* Number of blocks in the run */
@@ -2048,7 +2063,8 @@ static void ext4_free_data(handle_t *handle, struct inode *inode,
 			} else {
 				ext4_clear_blocks(handle, inode, this_bh,
 						  block_to_free,
-						  count, block_to_free_p, p);
+						  count, block_to_free_p, p,
+						  cred);
 				block_to_free = nr;
 				block_to_free_p = p;
 				count = 1;
@@ -2058,7 +2074,7 @@ static void ext4_free_data(handle_t *handle, struct inode *inode,
 
 	if (count > 0)
 		ext4_clear_blocks(handle, inode, this_bh, block_to_free,
-				  count, block_to_free_p, p);
+				  count, block_to_free_p, p, cred);
 
 	if (this_bh) {
 		BUFFER_TRACE(this_bh, "call ext4_journal_dirty_metadata");
@@ -2081,7 +2097,8 @@ static void ext4_free_data(handle_t *handle, struct inode *inode,
  */
 static void ext4_free_branches(handle_t *handle, struct inode *inode,
 			       struct buffer_head *parent_bh,
-			       __le32 *first, __le32 *last, int depth)
+			       __le32 *first, __le32 *last, int depth,
+			       struct cred *cred)
 {
 	ext4_fsblk_t nr;
 	__le32 *p;
@@ -2117,7 +2134,7 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode,
 			ext4_free_branches(handle, inode, bh,
 					   (__le32*)bh->b_data,
 					   (__le32*)bh->b_data + addr_per_block,
-					   depth);
+					   depth, cred);
 
 			/*
 			 * We've probably journalled the indirect block several
@@ -2159,7 +2176,7 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode,
 			if (is_handle_aborted(handle))
 				return;
 			if (try_to_extend_transaction(handle, inode)) {
-				ext4_mark_inode_dirty(handle, inode);
+				ext4_mark_inode_dirty(handle, inode, cred);
 				ext4_journal_test_restart(handle, inode);
 			}
 
@@ -2184,7 +2201,7 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode,
 	} else {
 		/* We have reached the bottom of the tree. */
 		BUFFER_TRACE(parent_bh, "free data blocks");
-		ext4_free_data(handle, inode, parent_bh, first, last);
+		ext4_free_data(handle, inode, parent_bh, first, last, cred);
 	}
 }
 
@@ -2218,6 +2235,7 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode,
  */
 void ext4_truncate(struct inode *inode)
 {
+	struct cred *cred = current->cred;
 	handle_t *handle;
 	struct ext4_inode_info *ei = EXT4_I(inode);
 	__le32 *i_data = ei->i_data;
@@ -2255,7 +2273,7 @@ void ext4_truncate(struct inode *inode)
 	}
 
 	if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)
-		return ext4_ext_truncate(inode, page);
+		return ext4_ext_truncate(inode, page, cred);
 
 	handle = start_transaction(inode);
 	if (IS_ERR(handle)) {
@@ -2307,7 +2325,7 @@ void ext4_truncate(struct inode *inode)
 
 	if (n == 1) {		/* direct blocks */
 		ext4_free_data(handle, inode, NULL, i_data+offsets[0],
-			       i_data + EXT4_NDIR_BLOCKS);
+			       i_data + EXT4_NDIR_BLOCKS, cred);
 		goto do_indirects;
 	}
 
@@ -2317,7 +2335,8 @@ void ext4_truncate(struct inode *inode)
 		if (partial == chain) {
 			/* Shared branch grows from the inode */
 			ext4_free_branches(handle, inode, NULL,
-					   &nr, &nr+1, (chain+n-1) - partial);
+					   &nr, &nr+1, (chain+n-1) - partial,
+					   cred);
 			*partial->p = 0;
 			/*
 			 * We mark the inode dirty prior to restart,
@@ -2328,14 +2347,15 @@ void ext4_truncate(struct inode *inode)
 			BUFFER_TRACE(partial->bh, "get_write_access");
 			ext4_free_branches(handle, inode, partial->bh,
 					partial->p,
-					partial->p+1, (chain+n-1) - partial);
+					partial->p+1, (chain+n-1) - partial,
+					cred);
 		}
 	}
 	/* Clear the ends of indirect blocks on the shared branch */
 	while (partial > chain) {
 		ext4_free_branches(handle, inode, partial->bh, partial->p + 1,
 				   (__le32*)partial->bh->b_data+addr_per_block,
-				   (chain+n-1) - partial);
+				   (chain+n-1) - partial, cred);
 		BUFFER_TRACE(partial->bh, "call brelse");
 		brelse (partial->bh);
 		partial--;
@@ -2346,19 +2366,22 @@ do_indirects:
 	default:
 		nr = i_data[EXT4_IND_BLOCK];
 		if (nr) {
-			ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 1);
+			ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 1,
+					   cred);
 			i_data[EXT4_IND_BLOCK] = 0;
 		}
 	case EXT4_IND_BLOCK:
 		nr = i_data[EXT4_DIND_BLOCK];
 		if (nr) {
-			ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 2);
+			ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 2,
+					   cred);
 			i_data[EXT4_DIND_BLOCK] = 0;
 		}
 	case EXT4_DIND_BLOCK:
 		nr = i_data[EXT4_TIND_BLOCK];
 		if (nr) {
-			ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 3);
+			ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 3,
+					   cred);
 			i_data[EXT4_TIND_BLOCK] = 0;
 		}
 	case EXT4_TIND_BLOCK:
@@ -2369,7 +2392,7 @@ do_indirects:
 
 	mutex_unlock(&ei->truncate_mutex);
 	inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
-	ext4_mark_inode_dirty(handle, inode);
+	ext4_mark_inode_dirty(handle, inode, cred);
 
 	/*
 	 * In a multi-transaction truncate, we only make the final transaction
@@ -2946,6 +2969,7 @@ int ext4_write_inode(struct inode *inode, int wait)
  */
 int ext4_setattr(struct dentry *dentry, struct iattr *attr)
 {
+	struct cred *cred = current->cred;
 	struct inode *inode = dentry->d_inode;
 	int error, rc = 0;
 	const unsigned int ia_valid = attr->ia_valid;
@@ -2977,7 +3001,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
 			inode->i_uid = attr->ia_uid;
 		if (attr->ia_valid & ATTR_GID)
 			inode->i_gid = attr->ia_gid;
-		error = ext4_mark_inode_dirty(handle, inode);
+		error = ext4_mark_inode_dirty(handle, inode, cred);
 		ext4_journal_stop(handle);
 	}
 
@@ -2993,7 +3017,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
 
 		error = ext4_orphan_add(handle, inode);
 		EXT4_I(inode)->i_disksize = attr->ia_size;
-		rc = ext4_mark_inode_dirty(handle, inode);
+		rc = ext4_mark_inode_dirty(handle, inode, cred);
 		if (!error)
 			error = rc;
 		ext4_journal_stop(handle);
@@ -3116,7 +3140,8 @@ ext4_reserve_inode_write(handle_t *handle, struct inode *inode,
  * Returns 0 on success or negative error number on failure.
  */
 int ext4_expand_extra_isize(struct inode *inode, unsigned int new_extra_isize,
-			struct ext4_iloc iloc, handle_t *handle)
+			struct ext4_iloc iloc, handle_t *handle,
+			struct cred *cred)
 {
 	struct ext4_inode *raw_inode;
 	struct ext4_xattr_ibody_header *header;
@@ -3141,7 +3166,7 @@ int ext4_expand_extra_isize(struct inode *inode, unsigned int new_extra_isize,
 
 	/* try to expand with EAs present */
 	return ext4_expand_extra_isize_ea(inode, new_extra_isize,
-					  raw_inode, handle);
+					  raw_inode, handle, cred);
 }
 
 /*
@@ -3165,7 +3190,8 @@ int ext4_expand_extra_isize(struct inode *inode, unsigned int new_extra_isize,
  * to do a write_super() to free up some memory.  It has the desired
  * effect.
  */
-int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
+int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode,
+			  struct cred *cred)
 {
 	struct ext4_iloc iloc;
 	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
@@ -3187,7 +3213,7 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
 			     EXT4_DATA_TRANS_BLOCKS(inode->i_sb))) == 0) {
 			ret = ext4_expand_extra_isize(inode,
 						      sbi->s_want_extra_isize,
-						      iloc, handle);
+						      iloc, handle, cred);
 			if (ret) {
 				EXT4_I(inode)->i_state |= EXT4_STATE_NO_EXPAND;
 				if (mnt_count != sbi->s_es->s_mnt_count) {
@@ -3221,6 +3247,7 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
  */
 void ext4_dirty_inode(struct inode *inode)
 {
+	struct cred *cred = current->cred;
 	handle_t *current_handle = ext4_journal_current_handle();
 	handle_t *handle;
 
@@ -3235,7 +3262,7 @@ void ext4_dirty_inode(struct inode *inode)
 	} else {
 		jbd_debug(5, "marking dirty.  outer handle=%p\n",
 				current_handle);
-		ext4_mark_inode_dirty(handle, inode);
+		ext4_mark_inode_dirty(handle, inode, cred);
 	}
 	ext4_journal_stop(handle);
 out:
@@ -3271,7 +3298,8 @@ static int ext4_pin_inode(handle_t *handle, struct inode *inode)
 }
 #endif
 
-int ext4_change_inode_journal_flag(struct inode *inode, int val)
+int ext4_change_inode_journal_flag(struct inode *inode, int val,
+				   struct cred *cred)
 {
 	journal_t *journal;
 	handle_t *handle;
@@ -3316,7 +3344,7 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
 
-	err = ext4_mark_inode_dirty(handle, inode);
+	err = ext4_mark_inode_dirty(handle, inode, cred);
 	handle->h_sync = 1;
 	ext4_journal_stop(handle);
 	ext4_std_error(inode->i_sb, err);
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index c04c7cc..4110510 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -21,6 +21,7 @@ int ext4_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
 		unsigned long arg)
 {
 	struct ext4_inode_info *ei = EXT4_I(inode);
+	struct cred *cred = filp->f_cred;
 	unsigned int flags;
 	unsigned short rsv_window_size;
 
@@ -108,7 +109,8 @@ flags_err:
 		}
 
 		if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL))
-			err = ext4_change_inode_journal_flag(inode, jflag);
+			err = ext4_change_inode_journal_flag(inode, jflag,
+							     cred);
 		mutex_unlock(&inode->i_mutex);
 		return err;
 	}
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 301f41f..be28f73 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -51,13 +51,14 @@
 
 static struct buffer_head *ext4_append(handle_t *handle,
 					struct inode *inode,
-					u32 *block, int *err)
+					u32 *block, int *err,
+					struct cred *cred)
 {
 	struct buffer_head *bh;
 
 	*block = inode->i_size >> inode->i_sb->s_blocksize_bits;
 
-	if ((bh = ext4_bread(handle, inode, *block, 1, err))) {
+	if ((bh = ext4_bread(handle, inode, *block, 1, err, cred))) {
 		inode->i_size += inode->i_sb->s_blocksize;
 		EXT4_I(inode)->i_disksize = inode->i_size;
 		ext4_journal_get_write_access(handle,bh);
@@ -159,7 +160,8 @@ static struct dx_frame *dx_probe(struct dentry *dentry,
 				 struct inode *dir,
 				 struct dx_hash_info *hinfo,
 				 struct dx_frame *frame,
-				 int *err);
+				 int *err,
+				 struct cred *cred);
 static void dx_release (struct dx_frame *frames);
 static int dx_make_map (struct ext4_dir_entry_2 *de, int size,
 			struct dx_hash_info *hinfo, struct dx_map_entry map[]);
@@ -171,11 +173,13 @@ static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block);
 static int ext4_htree_next_block(struct inode *dir, __u32 hash,
 				 struct dx_frame *frame,
 				 struct dx_frame *frames,
-				 __u32 *start_hash);
+				 __u32 *start_hash,
+				 struct cred *cred);
 static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry,
-		       struct ext4_dir_entry_2 **res_dir, int *err);
+		       struct ext4_dir_entry_2 **res_dir, int *err,
+		       struct cred *cred);
 static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
-			     struct inode *inode);
+			     struct inode *inode, struct cred *cred);
 
 /*
  * Future: use high four bits of block for coalesce-on-delete flags
@@ -329,7 +333,8 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
  */
 static struct dx_frame *
 dx_probe(struct dentry *dentry, struct inode *dir,
-	 struct dx_hash_info *hinfo, struct dx_frame *frame_in, int *err)
+	 struct dx_hash_info *hinfo, struct dx_frame *frame_in, int *err,
+	 struct cred *cred)
 {
 	unsigned count, indirect;
 	struct dx_entry *at, *entries, *p, *q, *m;
@@ -341,7 +346,7 @@ dx_probe(struct dentry *dentry, struct inode *dir,
 	frame->bh = NULL;
 	if (dentry)
 		dir = dentry->d_parent->d_inode;
-	if (!(bh = ext4_bread (NULL,dir, 0, 0, err)))
+	if (!(bh = ext4_bread (NULL,dir, 0, 0, err, cred)))
 		goto fail;
 	root = (struct dx_root *) bh->b_data;
 	if (root->info.hash_version != DX_HASH_TEA &&
@@ -436,7 +441,7 @@ dx_probe(struct dentry *dentry, struct inode *dir,
 		frame->entries = entries;
 		frame->at = at;
 		if (!indirect--) return frame;
-		if (!(bh = ext4_bread (NULL,dir, dx_get_block(at), 0, err)))
+		if (!(bh = ext4_bread (NULL,dir, dx_get_block(at), 0, err, cred)))
 			goto fail2;
 		at = entries = ((struct dx_node *) bh->b_data)->entries;
 		if (dx_get_limit(entries) != dx_node_limit (dir)) {
@@ -492,7 +497,8 @@ static void dx_release (struct dx_frame *frames)
 static int ext4_htree_next_block(struct inode *dir, __u32 hash,
 				 struct dx_frame *frame,
 				 struct dx_frame *frames,
-				 __u32 *start_hash)
+				 __u32 *start_hash,
+				 struct cred *cred)
 {
 	struct dx_frame *p;
 	struct buffer_head *bh;
@@ -536,7 +542,7 @@ static int ext4_htree_next_block(struct inode *dir, __u32 hash,
 	 */
 	while (num_frames--) {
 		if (!(bh = ext4_bread(NULL, dir, dx_get_block(p->at),
-				      0, &err)))
+				      0, &err, cred)))
 			return err; /* Failure */
 		p++;
 		brelse (p->bh);
@@ -563,14 +569,15 @@ static inline struct ext4_dir_entry_2 *ext4_next_entry(struct ext4_dir_entry_2 *
 static int htree_dirblock_to_tree(struct file *dir_file,
 				  struct inode *dir, int block,
 				  struct dx_hash_info *hinfo,
-				  __u32 start_hash, __u32 start_minor_hash)
+				  __u32 start_hash, __u32 start_minor_hash,
+				  struct cred *cred)
 {
 	struct buffer_head *bh;
 	struct ext4_dir_entry_2 *de, *top;
 	int err, count = 0;
 
 	dxtrace(printk("In htree dirblock_to_tree: block %d\n", block));
-	if (!(bh = ext4_bread (NULL, dir, block, 0, &err)))
+	if (!(bh = ext4_bread (NULL, dir, block, 0, &err, cred)))
 		return err;
 
 	de = (struct ext4_dir_entry_2 *) bh->b_data;
@@ -615,7 +622,8 @@ static int htree_dirblock_to_tree(struct file *dir_file,
  * or a negative error code.
  */
 int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
-			 __u32 start_minor_hash, __u32 *next_hash)
+			 __u32 start_minor_hash, __u32 *next_hash,
+			 struct cred *cred)
 {
 	struct dx_hash_info hinfo;
 	struct ext4_dir_entry_2 *de;
@@ -633,13 +641,15 @@ int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
 		hinfo.hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version;
 		hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
 		count = htree_dirblock_to_tree(dir_file, dir, 0, &hinfo,
-					       start_hash, start_minor_hash);
+					       start_hash, start_minor_hash,
+					       cred);
 		*next_hash = ~0;
 		return count;
 	}
 	hinfo.hash = start_hash;
 	hinfo.minor_hash = 0;
-	frame = dx_probe(NULL, dir_file->f_path.dentry->d_inode, &hinfo, frames, &err);
+	frame = dx_probe(NULL, dir_file->f_path.dentry->d_inode, &hinfo, frames,
+			 &err, cred);
 	if (!frame)
 		return err;
 
@@ -661,7 +671,8 @@ int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
 	while (1) {
 		block = dx_get_block(frame->at);
 		ret = htree_dirblock_to_tree(dir_file, dir, block, &hinfo,
-					     start_hash, start_minor_hash);
+					     start_hash, start_minor_hash,
+					     cred);
 		if (ret < 0) {
 			err = ret;
 			goto errout;
@@ -669,7 +680,7 @@ int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
 		count += ret;
 		hashval = ~0;
 		ret = ext4_htree_next_block(dir, HASH_NB_ALWAYS,
-					    frame, frames, &hashval);
+					    frame, frames, &hashval, cred);
 		*next_hash = hashval;
 		if (ret < 0) {
 			err = ret;
@@ -845,7 +856,8 @@ static inline int search_dirblock(struct buffer_head * bh,
  * to brelse() it when appropriate.
  */
 static struct buffer_head * ext4_find_entry (struct dentry *dentry,
-					struct ext4_dir_entry_2 ** res_dir)
+					struct ext4_dir_entry_2 ** res_dir,
+					struct cred *cred)
 {
 	struct super_block * sb;
 	struct buffer_head * bh_use[NAMEI_RA_SIZE];
@@ -871,7 +883,7 @@ static struct buffer_head * ext4_find_entry (struct dentry *dentry,
 		return NULL;
 #ifdef CONFIG_EXT4_INDEX
 	if (is_dx(dir)) {
-		bh = ext4_dx_find_entry(dentry, res_dir, &err);
+		bh = ext4_dx_find_entry(dentry, res_dir, &err, cred);
 		/*
 		 * On success, or if the error was file not found,
 		 * return.  Otherwise, fall back to doing a search the
@@ -907,7 +919,7 @@ restart:
 					break;
 				}
 				num++;
-				bh = ext4_getblk(NULL, dir, b++, 0, &err);
+				bh = ext4_getblk(NULL, dir, b++, 0, &err, cred);
 				bh_use[ra_max] = bh;
 				if (bh)
 					ll_rw_block(READ_META, 1, &bh);
@@ -959,7 +971,8 @@ cleanup_and_exit:
 
 #ifdef CONFIG_EXT4_INDEX
 static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry,
-		       struct ext4_dir_entry_2 **res_dir, int *err)
+		       struct ext4_dir_entry_2 **res_dir, int *err,
+		       struct cred *cred)
 {
 	struct super_block * sb;
 	struct dx_hash_info	hinfo;
@@ -976,7 +989,8 @@ static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry,
 	sb = dir->i_sb;
 	/* NFS may look up ".." - look at dx_root directory block */
 	if (namelen > 2 || name[0] != '.'||(name[1] != '.' && name[1] != '\0')){
-		if (!(frame = dx_probe(dentry, NULL, &hinfo, frames, err)))
+		if (!(frame = dx_probe(dentry, NULL, &hinfo, frames, err,
+				       cred)))
 			return NULL;
 	} else {
 		frame = frames;
@@ -987,7 +1001,7 @@ static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry,
 	hash = hinfo.hash;
 	do {
 		block = dx_get_block(frame->at);
-		if (!(bh = ext4_bread (NULL,dir, block, 0, err)))
+		if (!(bh = ext4_bread (NULL,dir, block, 0, err, cred)))
 			goto errout;
 		de = (struct ext4_dir_entry_2 *) bh->b_data;
 		top = (struct ext4_dir_entry_2 *) ((char *) de + sb->s_blocksize -
@@ -1009,7 +1023,7 @@ static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry,
 		brelse (bh);
 		/* Check to see if we should continue to search */
 		retval = ext4_htree_next_block(dir, hash, frame,
-					       frames, NULL);
+					       frames, NULL, cred);
 		if (retval < 0) {
 			ext4_warning(sb, __FUNCTION__,
 			     "error reading index page in directory #%lu",
@@ -1029,6 +1043,7 @@ errout:
 
 static struct dentry *ext4_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
 {
+	struct cred *cred = current->cred;
 	struct inode * inode;
 	struct ext4_dir_entry_2 * de;
 	struct buffer_head * bh;
@@ -1036,7 +1051,7 @@ static struct dentry *ext4_lookup(struct inode * dir, struct dentry *dentry, str
 	if (dentry->d_name.len > EXT4_NAME_LEN)
 		return ERR_PTR(-ENAMETOOLONG);
 
-	bh = ext4_find_entry(dentry, &de);
+	bh = ext4_find_entry(dentry, &de, cred);
 	inode = NULL;
 	if (bh) {
 		unsigned long ino = le32_to_cpu(de->inode);
@@ -1056,6 +1071,7 @@ static struct dentry *ext4_lookup(struct inode * dir, struct dentry *dentry, str
 
 struct dentry *ext4_get_parent(struct dentry *child)
 {
+	struct cred *cred = current->cred;
 	unsigned long ino;
 	struct dentry *parent;
 	struct inode *inode;
@@ -1067,7 +1083,7 @@ struct dentry *ext4_get_parent(struct dentry *child)
 	dotdot.d_name.len = 2;
 	dotdot.d_parent = child; /* confusing, isn't it! */
 
-	bh = ext4_find_entry(&dotdot, &de);
+	bh = ext4_find_entry(&dotdot, &de, cred);
 	inode = NULL;
 	if (!bh)
 		return ERR_PTR(-ENOENT);
@@ -1166,7 +1182,8 @@ static struct ext4_dir_entry_2* dx_pack_dirents(char *base, int size)
  */
 static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
 			struct buffer_head **bh,struct dx_frame *frame,
-			struct dx_hash_info *hinfo, int *error)
+			struct dx_hash_info *hinfo, int *error,
+			struct cred *cred)
 {
 	unsigned blocksize = dir->i_sb->s_blocksize;
 	unsigned count, continued;
@@ -1179,7 +1196,7 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
 	struct ext4_dir_entry_2 *de = NULL, *de2;
 	int	err = 0;
 
-	bh2 = ext4_append (handle, dir, &newblock, &err);
+	bh2 = ext4_append (handle, dir, &newblock, &err, cred);
 	if (!(bh2)) {
 		brelse(*bh);
 		*bh = NULL;
@@ -1271,7 +1288,7 @@ errout:
  */
 static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
 			     struct inode *inode, struct ext4_dir_entry_2 *de,
-			     struct buffer_head * bh)
+			     struct buffer_head * bh, struct cred *cred)
 {
 	struct inode	*dir = dentry->d_parent->d_inode;
 	const char	*name = dentry->d_name.name;
@@ -1344,7 +1361,7 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
 	dir->i_mtime = dir->i_ctime = ext4_current_time(dir);
 	ext4_update_dx_flag(dir);
 	dir->i_version++;
-	ext4_mark_inode_dirty(handle, dir);
+	ext4_mark_inode_dirty(handle, dir, cred);
 	BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata");
 	err = ext4_journal_dirty_metadata(handle, bh);
 	if (err)
@@ -1359,7 +1376,8 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
  * directory, and adds the dentry to the indexed directory.
  */
 static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
-			    struct inode *inode, struct buffer_head *bh)
+			    struct inode *inode, struct buffer_head *bh,
+			    struct cred *cred)
 {
 	struct inode	*dir = dentry->d_parent->d_inode;
 	const char	*name = dentry->d_name.name;
@@ -1387,7 +1405,7 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
 	}
 	root = (struct dx_root *) bh->b_data;
 
-	bh2 = ext4_append (handle, dir, &block, &retval);
+	bh2 = ext4_append (handle, dir, &block, &retval, cred);
 	if (!(bh2)) {
 		brelse(bh);
 		return retval;
@@ -1425,12 +1443,12 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
 	frame->at = entries;
 	frame->bh = bh;
 	bh = bh2;
-	de = do_split(handle,dir, &bh, frame, &hinfo, &retval);
+	de = do_split(handle,dir, &bh, frame, &hinfo, &retval, cred);
 	dx_release (frames);
 	if (!(de))
 		return retval;
 
-	return add_dirent_to_buf(handle, dentry, inode, de, bh);
+	return add_dirent_to_buf(handle, dentry, inode, de, bh, cred);
 }
 #endif
 
@@ -1445,7 +1463,7 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
  * the entry, as someone else might have used it while you slept.
  */
 static int ext4_add_entry (handle_t *handle, struct dentry *dentry,
-	struct inode *inode)
+	struct inode *inode, struct cred *cred)
 {
 	struct inode *dir = dentry->d_parent->d_inode;
 	unsigned long offset;
@@ -1465,37 +1483,39 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry,
 		return -EINVAL;
 #ifdef CONFIG_EXT4_INDEX
 	if (is_dx(dir)) {
-		retval = ext4_dx_add_entry(handle, dentry, inode);
+		retval = ext4_dx_add_entry(handle, dentry, inode, cred);
 		if (!retval || (retval != ERR_BAD_DX_DIR))
 			return retval;
 		EXT4_I(dir)->i_flags &= ~EXT4_INDEX_FL;
 		dx_fallback++;
-		ext4_mark_inode_dirty(handle, dir);
+		ext4_mark_inode_dirty(handle, dir, cred);
 	}
 #endif
 	blocks = dir->i_size >> sb->s_blocksize_bits;
 	for (block = 0, offset = 0; block < blocks; block++) {
-		bh = ext4_bread(handle, dir, block, 0, &retval);
+		bh = ext4_bread(handle, dir, block, 0, &retval, cred);
 		if(!bh)
 			return retval;
-		retval = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
+		retval = add_dirent_to_buf(handle, dentry, inode, NULL, bh,
+					   cred);
 		if (retval != -ENOSPC)
 			return retval;
 
 #ifdef CONFIG_EXT4_INDEX
 		if (blocks == 1 && !dx_fallback &&
 		    EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX))
-			return make_indexed_dir(handle, dentry, inode, bh);
+			return make_indexed_dir(handle, dentry, inode, bh,
+						cred);
 #endif
 		brelse(bh);
 	}
-	bh = ext4_append(handle, dir, &block, &retval);
+	bh = ext4_append(handle, dir, &block, &retval, cred);
 	if (!bh)
 		return retval;
 	de = (struct ext4_dir_entry_2 *) bh->b_data;
 	de->inode = 0;
 	de->rec_len = cpu_to_le16(blocksize);
-	return add_dirent_to_buf(handle, dentry, inode, de, bh);
+	return add_dirent_to_buf(handle, dentry, inode, de, bh, cred);
 }
 
 #ifdef CONFIG_EXT4_INDEX
@@ -1503,7 +1523,7 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry,
  * Returns 0 for success, or a negative error value
  */
 static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
-			     struct inode *inode)
+			     struct inode *inode, struct cred *cred)
 {
 	struct dx_frame frames[2], *frame;
 	struct dx_entry *entries, *at;
@@ -1514,13 +1534,14 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
 	struct ext4_dir_entry_2 *de;
 	int err;
 
-	frame = dx_probe(dentry, NULL, &hinfo, frames, &err);
+	frame = dx_probe(dentry, NULL, &hinfo, frames, &err, cred);
 	if (!frame)
 		return err;
 	entries = frame->entries;
 	at = frame->at;
 
-	if (!(bh = ext4_bread(handle,dir, dx_get_block(frame->at), 0, &err)))
+	if (!(bh = ext4_bread(handle,dir, dx_get_block(frame->at), 0, &err,
+			      cred)))
 		goto cleanup;
 
 	BUFFER_TRACE(bh, "get_write_access");
@@ -1528,7 +1549,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
 	if (err)
 		goto journal_error;
 
-	err = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
+	err = add_dirent_to_buf(handle, dentry, inode, NULL, bh, cred);
 	if (err != -ENOSPC) {
 		bh = NULL;
 		goto cleanup;
@@ -1553,7 +1574,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
 			err = -ENOSPC;
 			goto cleanup;
 		}
-		bh2 = ext4_append (handle, dir, &newblock, &err);
+		bh2 = ext4_append (handle, dir, &newblock, &err, cred);
 		if (!(bh2))
 			goto cleanup;
 		node2 = (struct dx_node *)(bh2->b_data);
@@ -1618,10 +1639,10 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
 		}
 		ext4_journal_dirty_metadata(handle, frames[0].bh);
 	}
-	de = do_split(handle, dir, &bh, frame, &hinfo, &err);
+	de = do_split(handle, dir, &bh, frame, &hinfo, &err, cred);
 	if (!de)
 		goto cleanup;
-	err = add_dirent_to_buf(handle, dentry, inode, de, bh);
+	err = add_dirent_to_buf(handle, dentry, inode, de, bh, cred);
 	bh = NULL;
 	goto cleanup;
 
@@ -1705,11 +1726,11 @@ static void ext4_dec_count(handle_t *handle, struct inode *inode)
 
 
 static int ext4_add_nondir(handle_t *handle,
-		struct dentry *dentry, struct inode *inode)
+		struct dentry *dentry, struct inode *inode, struct cred *cred)
 {
-	int err = ext4_add_entry(handle, dentry, inode);
+	int err = ext4_add_entry(handle, dentry, inode, cred);
 	if (!err) {
-		ext4_mark_inode_dirty(handle, inode);
+		ext4_mark_inode_dirty(handle, inode, cred);
 		d_instantiate(dentry, inode);
 		return 0;
 	}
@@ -1729,6 +1750,7 @@ static int ext4_add_nondir(handle_t *handle,
 static int ext4_create (struct inode * dir, struct dentry * dentry, int mode,
 		struct nameidata *nd)
 {
+	struct cred *cred = current->cred;
 	handle_t *handle;
 	struct inode * inode;
 	int err, retries = 0;
@@ -1743,16 +1765,17 @@ retry:
 	if (IS_DIRSYNC(dir))
 		handle->h_sync = 1;
 
-	inode = ext4_new_inode (handle, dir, mode);
+	inode = ext4_new_inode (handle, dir, mode, cred);
 	err = PTR_ERR(inode);
 	if (!IS_ERR(inode)) {
 		inode->i_op = &ext4_file_inode_operations;
 		inode->i_fop = &ext4_file_operations;
 		ext4_set_aops(inode);
-		err = ext4_add_nondir(handle, dentry, inode);
+		err = ext4_add_nondir(handle, dentry, inode, cred);
 	}
 	ext4_journal_stop(handle);
-	if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
+	if (err == -ENOSPC &&
+	    ext4_should_retry_alloc(dir->i_sb, &retries, cred))
 		goto retry;
 	return err;
 }
@@ -1760,6 +1783,7 @@ retry:
 static int ext4_mknod (struct inode * dir, struct dentry *dentry,
 			int mode, dev_t rdev)
 {
+	struct cred *cred = current->cred;
 	handle_t *handle;
 	struct inode *inode;
 	int err, retries = 0;
@@ -1777,23 +1801,25 @@ retry:
 	if (IS_DIRSYNC(dir))
 		handle->h_sync = 1;
 
-	inode = ext4_new_inode (handle, dir, mode);
+	inode = ext4_new_inode (handle, dir, mode, cred);
 	err = PTR_ERR(inode);
 	if (!IS_ERR(inode)) {
 		init_special_inode(inode, inode->i_mode, rdev);
 #ifdef CONFIG_EXT4DEV_FS_XATTR
 		inode->i_op = &ext4_special_inode_operations;
 #endif
-		err = ext4_add_nondir(handle, dentry, inode);
+		err = ext4_add_nondir(handle, dentry, inode, cred);
 	}
 	ext4_journal_stop(handle);
-	if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
+	if (err == -ENOSPC &&
+	    ext4_should_retry_alloc(dir->i_sb, &retries, cred))
 		goto retry;
 	return err;
 }
 
 static int ext4_mkdir(struct inode * dir, struct dentry * dentry, int mode)
 {
+	struct cred *cred = current->cred;
 	handle_t *handle;
 	struct inode * inode;
 	struct buffer_head * dir_block;
@@ -1813,7 +1839,7 @@ retry:
 	if (IS_DIRSYNC(dir))
 		handle->h_sync = 1;
 
-	inode = ext4_new_inode (handle, dir, S_IFDIR | mode);
+	inode = ext4_new_inode (handle, dir, S_IFDIR | mode, cred);
 	err = PTR_ERR(inode);
 	if (IS_ERR(inode))
 		goto out_stop;
@@ -1821,10 +1847,10 @@ retry:
 	inode->i_op = &ext4_dir_inode_operations;
 	inode->i_fop = &ext4_dir_operations;
 	inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize;
-	dir_block = ext4_bread (handle, inode, 0, 1, &err);
+	dir_block = ext4_bread (handle, inode, 0, 1, &err, cred);
 	if (!dir_block) {
 		ext4_dec_count(handle, inode); /* is this nlink == 0? */
-		ext4_mark_inode_dirty(handle, inode);
+		ext4_mark_inode_dirty(handle, inode, cred);
 		iput (inode);
 		goto out_stop;
 	}
@@ -1847,21 +1873,22 @@ retry:
 	BUFFER_TRACE(dir_block, "call ext4_journal_dirty_metadata");
 	ext4_journal_dirty_metadata(handle, dir_block);
 	brelse (dir_block);
-	ext4_mark_inode_dirty(handle, inode);
-	err = ext4_add_entry (handle, dentry, inode);
+	ext4_mark_inode_dirty(handle, inode, cred);
+	err = ext4_add_entry (handle, dentry, inode, cred);
 	if (err) {
 		inode->i_nlink = 0;
-		ext4_mark_inode_dirty(handle, inode);
+		ext4_mark_inode_dirty(handle, inode, cred);
 		iput (inode);
 		goto out_stop;
 	}
 	ext4_inc_count(handle, dir);
 	ext4_update_dx_flag(dir);
-	ext4_mark_inode_dirty(handle, dir);
+	ext4_mark_inode_dirty(handle, dir, cred);
 	d_instantiate(dentry, inode);
 out_stop:
 	ext4_journal_stop(handle);
-	if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
+	if (err == -ENOSPC &&
+	    ext4_should_retry_alloc(dir->i_sb, &retries, cred))
 		goto retry;
 	return err;
 }
@@ -1869,7 +1896,7 @@ out_stop:
 /*
  * routine to check that the specified directory is empty (for rmdir)
  */
-static int empty_dir (struct inode * inode)
+static int empty_dir (struct inode * inode, struct cred *cred)
 {
 	unsigned long offset;
 	struct buffer_head * bh;
@@ -1879,7 +1906,7 @@ static int empty_dir (struct inode * inode)
 
 	sb = inode->i_sb;
 	if (inode->i_size < EXT4_DIR_REC_LEN(1) + EXT4_DIR_REC_LEN(2) ||
-	    !(bh = ext4_bread (NULL, inode, 0, 0, &err))) {
+	    !(bh = ext4_bread (NULL, inode, 0, 0, &err, cred))) {
 		if (err)
 			ext4_error(inode->i_sb, __FUNCTION__,
 				   "error %d reading directory #%lu offset 0",
@@ -1912,7 +1939,8 @@ static int empty_dir (struct inode * inode)
 			err = 0;
 			brelse (bh);
 			bh = ext4_bread (NULL, inode,
-				offset >> EXT4_BLOCK_SIZE_BITS(sb), 0, &err);
+				offset >> EXT4_BLOCK_SIZE_BITS(sb), 0, &err,
+				cred);
 			if (!bh) {
 				if (err)
 					ext4_error(sb, __FUNCTION__,
@@ -2086,6 +2114,7 @@ out_brelse:
 
 static int ext4_rmdir (struct inode * dir, struct dentry *dentry)
 {
+	struct cred *cred = current->cred;
 	int retval;
 	struct inode * inode;
 	struct buffer_head * bh;
@@ -2100,7 +2129,7 @@ static int ext4_rmdir (struct inode * dir, struct dentry *dentry)
 		return PTR_ERR(handle);
 
 	retval = -ENOENT;
-	bh = ext4_find_entry (dentry, &de);
+	bh = ext4_find_entry (dentry, &de, cred);
 	if (!bh)
 		goto end_rmdir;
 
@@ -2114,7 +2143,7 @@ static int ext4_rmdir (struct inode * dir, struct dentry *dentry)
 		goto end_rmdir;
 
 	retval = -ENOTEMPTY;
-	if (!empty_dir (inode))
+	if (!empty_dir (inode, cred))
 		goto end_rmdir;
 
 	retval = ext4_delete_entry(handle, dir, de, bh);
@@ -2132,10 +2161,10 @@ static int ext4_rmdir (struct inode * dir, struct dentry *dentry)
 	inode->i_size = 0;
 	ext4_orphan_add(handle, inode);
 	inode->i_ctime = dir->i_ctime = dir->i_mtime = ext4_current_time(inode);
-	ext4_mark_inode_dirty(handle, inode);
+	ext4_mark_inode_dirty(handle, inode, cred);
 	ext4_dec_count(handle, dir);
 	ext4_update_dx_flag(dir);
-	ext4_mark_inode_dirty(handle, dir);
+	ext4_mark_inode_dirty(handle, dir, cred);
 
 end_rmdir:
 	ext4_journal_stop(handle);
@@ -2145,6 +2174,7 @@ end_rmdir:
 
 static int ext4_unlink(struct inode * dir, struct dentry *dentry)
 {
+	struct cred *cred = current->cred;
 	int retval;
 	struct inode * inode;
 	struct buffer_head * bh;
@@ -2162,7 +2192,7 @@ static int ext4_unlink(struct inode * dir, struct dentry *dentry)
 		handle->h_sync = 1;
 
 	retval = -ENOENT;
-	bh = ext4_find_entry (dentry, &de);
+	bh = ext4_find_entry (dentry, &de, cred);
 	if (!bh)
 		goto end_unlink;
 
@@ -2183,12 +2213,12 @@ static int ext4_unlink(struct inode * dir, struct dentry *dentry)
 		goto end_unlink;
 	dir->i_ctime = dir->i_mtime = ext4_current_time(dir);
 	ext4_update_dx_flag(dir);
-	ext4_mark_inode_dirty(handle, dir);
+	ext4_mark_inode_dirty(handle, dir, cred);
 	ext4_dec_count(handle, inode);
 	if (!inode->i_nlink)
 		ext4_orphan_add(handle, inode);
 	inode->i_ctime = ext4_current_time(inode);
-	ext4_mark_inode_dirty(handle, inode);
+	ext4_mark_inode_dirty(handle, inode, cred);
 	retval = 0;
 
 end_unlink:
@@ -2200,6 +2230,7 @@ end_unlink:
 static int ext4_symlink (struct inode * dir,
 		struct dentry *dentry, const char * symname)
 {
+	struct cred *cred = current->cred;
 	handle_t *handle;
 	struct inode * inode;
 	int l, err, retries = 0;
@@ -2218,7 +2249,7 @@ retry:
 	if (IS_DIRSYNC(dir))
 		handle->h_sync = 1;
 
-	inode = ext4_new_inode (handle, dir, S_IFLNK|S_IRWXUGO);
+	inode = ext4_new_inode (handle, dir, S_IFLNK|S_IRWXUGO, cred);
 	err = PTR_ERR(inode);
 	if (IS_ERR(inode))
 		goto out_stop;
@@ -2235,7 +2266,7 @@ retry:
 				mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS);
 		if (err) {
 			ext4_dec_count(handle, inode);
-			ext4_mark_inode_dirty(handle, inode);
+			ext4_mark_inode_dirty(handle, inode, cred);
 			iput (inode);
 			goto out_stop;
 		}
@@ -2245,10 +2276,11 @@ retry:
 		inode->i_size = l-1;
 	}
 	EXT4_I(inode)->i_disksize = inode->i_size;
-	err = ext4_add_nondir(handle, dentry, inode);
+	err = ext4_add_nondir(handle, dentry, inode, cred);
 out_stop:
 	ext4_journal_stop(handle);
-	if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
+	if (err == -ENOSPC &&
+	    ext4_should_retry_alloc(dir->i_sb, &retries, cred))
 		goto retry;
 	return err;
 }
@@ -2256,6 +2288,7 @@ out_stop:
 static int ext4_link (struct dentry * old_dentry,
 		struct inode * dir, struct dentry *dentry)
 {
+	struct cred *cred = current->cred;
 	handle_t *handle;
 	struct inode *inode = old_dentry->d_inode;
 	int err, retries = 0;
@@ -2283,9 +2316,10 @@ retry:
 	ext4_inc_count(handle, inode);
 	atomic_inc(&inode->i_count);
 
-	err = ext4_add_nondir(handle, dentry, inode);
+	err = ext4_add_nondir(handle, dentry, inode, cred);
 	ext4_journal_stop(handle);
-	if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
+	if (err == -ENOSPC &&
+	    ext4_should_retry_alloc(dir->i_sb, &retries, cred))
 		goto retry;
 	return err;
 }
@@ -2301,6 +2335,7 @@ retry:
 static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry,
 			   struct inode * new_dir,struct dentry *new_dentry)
 {
+	struct cred *cred = current->cred;
 	handle_t *handle;
 	struct inode * old_inode, * new_inode;
 	struct buffer_head * old_bh, * new_bh, * dir_bh;
@@ -2322,7 +2357,7 @@ static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry,
 	if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
 		handle->h_sync = 1;
 
-	old_bh = ext4_find_entry (old_dentry, &old_de);
+	old_bh = ext4_find_entry (old_dentry, &old_de, cred);
 	/*
 	 *  Check for inode number is _not_ due to possible IO errors.
 	 *  We might rmdir the source, keep it as pwd of some process
@@ -2335,7 +2370,7 @@ static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry,
 		goto end_rename;
 
 	new_inode = new_dentry->d_inode;
-	new_bh = ext4_find_entry (new_dentry, &new_de);
+	new_bh = ext4_find_entry (new_dentry, &new_de, cred);
 	if (new_bh) {
 		if (!new_inode) {
 			brelse (new_bh);
@@ -2345,11 +2380,11 @@ static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry,
 	if (S_ISDIR(old_inode->i_mode)) {
 		if (new_inode) {
 			retval = -ENOTEMPTY;
-			if (!empty_dir (new_inode))
+			if (!empty_dir (new_inode, cred))
 				goto end_rename;
 		}
 		retval = -EIO;
-		dir_bh = ext4_bread (handle, old_inode, 0, 0, &retval);
+		dir_bh = ext4_bread (handle, old_inode, 0, 0, &retval, cred);
 		if (!dir_bh)
 			goto end_rename;
 		if (le32_to_cpu(PARENT_INO(dir_bh->b_data)) != old_dir->i_ino)
@@ -2360,7 +2395,7 @@ static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry,
 			goto end_rename;
 	}
 	if (!new_bh) {
-		retval = ext4_add_entry (handle, new_dentry, old_inode);
+		retval = ext4_add_entry (handle, new_dentry, old_inode, cred);
 		if (retval)
 			goto end_rename;
 	} else {
@@ -2382,7 +2417,7 @@ static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry,
 	 * rename.
 	 */
 	old_inode->i_ctime = ext4_current_time(old_inode);
-	ext4_mark_inode_dirty(handle, old_inode);
+	ext4_mark_inode_dirty(handle, old_inode, cred);
 
 	/*
 	 * ok, that's it
@@ -2399,7 +2434,7 @@ static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry,
 		struct buffer_head *old_bh2;
 		struct ext4_dir_entry_2 *old_de2;
 
-		old_bh2 = ext4_find_entry(old_dentry, &old_de2);
+		old_bh2 = ext4_find_entry(old_dentry, &old_de2, cred);
 		if (old_bh2) {
 			retval = ext4_delete_entry(handle, old_dir,
 						   old_de2, old_bh2);
@@ -2432,12 +2467,12 @@ static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry,
 		} else {
 			ext4_inc_count(handle, new_dir);
 			ext4_update_dx_flag(new_dir);
-			ext4_mark_inode_dirty(handle, new_dir);
+			ext4_mark_inode_dirty(handle, new_dir, cred);
 		}
 	}
-	ext4_mark_inode_dirty(handle, old_dir);
+	ext4_mark_inode_dirty(handle, old_dir, cred);
 	if (new_inode) {
-		ext4_mark_inode_dirty(handle, new_inode);
+		ext4_mark_inode_dirty(handle, new_inode, cred);
 		if (!new_inode->i_nlink)
 			ext4_orphan_add(handle, new_inode);
 	}
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 05434a1..f8d5bc7 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -2791,6 +2791,7 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
 static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data,
 			       size_t len, loff_t off)
 {
+	struct cred *cred = current->cred;
 	struct inode *inode = sb_dqopt(sb)->files[type];
 	sector_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb);
 	int err = 0;
@@ -2808,7 +2809,7 @@ static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data,
 	while (toread > 0) {
 		tocopy = sb->s_blocksize - offset < toread ?
 				sb->s_blocksize - offset : toread;
-		bh = ext4_bread(NULL, inode, blk, 0, &err);
+		bh = ext4_bread(NULL, inode, blk, 0, &err, cred);
 		if (err)
 			return err;
 		if (!bh)	/* A hole? */
@@ -2829,6 +2830,7 @@ static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data,
 static ssize_t ext4_quota_write(struct super_block *sb, int type,
 				const char *data, size_t len, loff_t off)
 {
+	struct cred *cred = current->cred;
 	struct inode *inode = sb_dqopt(sb)->files[type];
 	sector_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb);
 	int err = 0;
@@ -2849,7 +2851,7 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
 	while (towrite > 0) {
 		tocopy = sb->s_blocksize - offset < towrite ?
 				sb->s_blocksize - offset : towrite;
-		bh = ext4_bread(handle, inode, blk, 1, &err);
+		bh = ext4_bread(handle, inode, blk, 1, &err, cred);
 		if (!bh)
 			goto out;
 		if (journal_quota) {
@@ -2887,7 +2889,7 @@ out:
 	}
 	inode->i_version++;
 	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-	ext4_mark_inode_dirty(handle, inode);
+	ext4_mark_inode_dirty(handle, inode, cred);
 	mutex_unlock(&inode->i_mutex);
 	return len - towrite;
 }
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index b10d68f..0c43a31 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -686,7 +686,8 @@ cleanup:
 static int
 ext4_xattr_block_set(handle_t *handle, struct inode *inode,
 		     struct ext4_xattr_info *i,
-		     struct ext4_xattr_block_find *bs)
+		     struct ext4_xattr_block_find *bs,
+		     struct cred *cred)
 {
 	struct super_block *sb = inode->i_sb;
 	struct buffer_head *new_bh = NULL;
@@ -814,7 +815,7 @@ inserted:
 				(ext4_fsblk_t)EXT4_I(inode)->i_block_group *
 				EXT4_BLOCKS_PER_GROUP(sb);
 			ext4_fsblk_t block = ext4_new_block(handle, inode,
-							goal, &error);
+							goal, &error, cred);
 			if (error)
 				goto cleanup;
 			ea_idebug(inode, "creating block %d", block);
@@ -947,7 +948,7 @@ ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
 int
 ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
 		      const char *name, const void *value, size_t value_len,
-		      int flags)
+		      int flags, struct cred *cred)
 {
 	struct ext4_xattr_info i = {
 		.name_index = name_index,
@@ -1005,14 +1006,14 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
 		if (!is.s.not_found)
 			error = ext4_xattr_ibody_set(handle, inode, &i, &is);
 		else if (!bs.s.not_found)
-			error = ext4_xattr_block_set(handle, inode, &i, &bs);
+			error = ext4_xattr_block_set(handle, inode, &i, &bs, cred);
 	} else {
 		error = ext4_xattr_ibody_set(handle, inode, &i, &is);
 		if (!error && !bs.s.not_found) {
 			i.value = NULL;
-			error = ext4_xattr_block_set(handle, inode, &i, &bs);
+			error = ext4_xattr_block_set(handle, inode, &i, &bs, cred);
 		} else if (error == -ENOSPC) {
-			error = ext4_xattr_block_set(handle, inode, &i, &bs);
+			error = ext4_xattr_block_set(handle, inode, &i, &bs, cred);
 			if (error)
 				goto cleanup;
 			if (!is.s.not_found) {
@@ -1054,7 +1055,8 @@ cleanup:
  */
 int
 ext4_xattr_set(struct inode *inode, int name_index, const char *name,
-	       const void *value, size_t value_len, int flags)
+	       const void *value, size_t value_len, int flags,
+	       struct cred *cred)
 {
 	handle_t *handle;
 	int error, retries = 0;
@@ -1067,10 +1069,10 @@ retry:
 		int error2;
 
 		error = ext4_xattr_set_handle(handle, inode, name_index, name,
-					      value, value_len, flags);
+					      value, value_len, flags, cred);
 		error2 = ext4_journal_stop(handle);
 		if (error == -ENOSPC &&
-		    ext4_should_retry_alloc(inode->i_sb, &retries))
+		    ext4_should_retry_alloc(inode->i_sb, &retries, cred))
 			goto retry;
 		if (error == 0)
 			error = error2;
@@ -1109,7 +1111,8 @@ static void ext4_xattr_shift_entries(struct ext4_xattr_entry *entry,
  * Returns 0 on success or negative error number on failure.
  */
 int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
-			       struct ext4_inode *raw_inode, handle_t *handle)
+			       struct ext4_inode *raw_inode, handle_t *handle,
+			       struct cred *cred)
 {
 	struct ext4_xattr_ibody_header *header;
 	struct ext4_xattr_entry *entry, *last, *first;
@@ -1299,7 +1302,7 @@ retry:
 			goto cleanup;
 
 		/* Add entry which was removed from the inode into the block */
-		error = ext4_xattr_block_set(handle, inode, &i, bs);
+		error = ext4_xattr_block_set(handle, inode, &i, bs, cred);
 		if (error)
 			goto cleanup;
 		kfree(b_entry_name);
diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h
index d7f5d6a..f737d16 100644
--- a/fs/ext4/xattr.h
+++ b/fs/ext4/xattr.h
@@ -75,14 +75,15 @@ extern ssize_t ext4_listxattr(struct dentry *, char *, size_t);
 
 extern int ext4_xattr_get(struct inode *, int, const char *, void *, size_t);
 extern int ext4_xattr_list(struct inode *, char *, size_t);
-extern int ext4_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
-extern int ext4_xattr_set_handle(handle_t *, struct inode *, int, const char *, const void *, size_t, int);
+extern int ext4_xattr_set(struct inode *, int, const char *, const void *, size_t, int, struct cred *);
+extern int ext4_xattr_set_handle(handle_t *, struct inode *, int, const char *, const void *, size_t, int, struct cred *);
 
 extern void ext4_xattr_delete_inode(handle_t *, struct inode *);
 extern void ext4_xattr_put_super(struct super_block *);
 
 extern int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
-			    struct ext4_inode *raw_inode, handle_t *handle);
+			    struct ext4_inode *raw_inode, handle_t *handle,
+			    struct cred *cred);
 
 extern int init_ext4_xattr(void);
 extern void exit_ext4_xattr(void);
diff --git a/fs/ext4/xattr_trusted.c b/fs/ext4/xattr_trusted.c
index e0f05ac..283e4c3 100644
--- a/fs/ext4/xattr_trusted.c
+++ b/fs/ext4/xattr_trusted.c
@@ -47,10 +47,12 @@ static int
 ext4_xattr_trusted_set(struct inode *inode, const char *name,
 		       const void *value, size_t size, int flags)
 {
+	struct cred *cred = current->cred;
+
 	if (strcmp(name, "") == 0)
 		return -EINVAL;
 	return ext4_xattr_set(inode, EXT4_XATTR_INDEX_TRUSTED, name,
-			      value, size, flags);
+			      value, size, flags, cred);
 }
 
 struct xattr_handler ext4_xattr_trusted_handler = {
diff --git a/fs/ext4/xattr_user.c b/fs/ext4/xattr_user.c
index 7ed3d8e..d3dd4de 100644
--- a/fs/ext4/xattr_user.c
+++ b/fs/ext4/xattr_user.c
@@ -47,12 +47,14 @@ static int
 ext4_xattr_user_set(struct inode *inode, const char *name,
 		    const void *value, size_t size, int flags)
 {
+	struct cred *cred = current->cred;
+
 	if (strcmp(name, "") == 0)
 		return -EINVAL;
 	if (!test_opt(inode->i_sb, XATTR_USER))
 		return -EOPNOTSUPP;
 	return ext4_xattr_set(inode, EXT4_XATTR_INDEX_USER, name,
-			      value, size, flags);
+			      value, size, flags, cred);
 }
 
 struct xattr_handler ext4_xattr_user_handler = {
diff --git a/include/linux/ext4_fs.h b/include/linux/ext4_fs.h
index 12354d5..7fd3ae8 100644
--- a/include/linux/ext4_fs.h
+++ b/include/linux/ext4_fs.h
@@ -892,9 +892,10 @@ extern ext4_grpblk_t ext4_block_group_offset(struct super_block *sb,
 extern int ext4_bg_has_super(struct super_block *sb, int group);
 extern unsigned long ext4_bg_num_gdb(struct super_block *sb, int group);
 extern ext4_fsblk_t ext4_new_block (handle_t *handle, struct inode *inode,
-			ext4_fsblk_t goal, int *errp);
+			ext4_fsblk_t goal, int *errp, struct cred *cred);
 extern ext4_fsblk_t ext4_new_blocks (handle_t *handle, struct inode *inode,
-			ext4_fsblk_t goal, unsigned long *count, int *errp);
+			ext4_fsblk_t goal, unsigned long *count, int *errp,
+			struct cred *cred);
 extern void ext4_free_blocks (handle_t *handle, struct inode *inode,
 			ext4_fsblk_t block, unsigned long count);
 extern void ext4_free_blocks_sb (handle_t *handle, struct super_block *sb,
@@ -905,7 +906,8 @@ extern void ext4_check_blocks_bitmap (struct super_block *);
 extern struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
 						    unsigned int block_group,
 						    struct buffer_head ** bh);
-extern int ext4_should_retry_alloc(struct super_block *sb, int *retries);
+extern int ext4_should_retry_alloc(struct super_block *sb, int *retries,
+				   struct cred *cred);
 extern void ext4_init_block_alloc_info(struct inode *);
 extern void ext4_rsv_window_add(struct super_block *sb, struct ext4_reserve_window_node *rsv);
 
@@ -926,7 +928,8 @@ extern int ext4fs_dirhash(const char *name, int len, struct
 			  dx_hash_info *hinfo);
 
 /* ialloc.c */
-extern struct inode * ext4_new_inode (handle_t *, struct inode *, int);
+extern struct inode * ext4_new_inode (handle_t *, struct inode *, int,
+				      struct cred *);
 extern void ext4_free_inode (handle_t *, struct inode *);
 extern struct inode * ext4_orphan_get (struct super_block *, unsigned long);
 extern unsigned long ext4_count_free_inodes (struct super_block *);
@@ -938,11 +941,13 @@ extern unsigned long ext4_count_free (struct buffer_head *, unsigned);
 /* inode.c */
 int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode,
 		struct buffer_head *bh, ext4_fsblk_t blocknr);
-struct buffer_head * ext4_getblk (handle_t *, struct inode *, long, int, int *);
-struct buffer_head * ext4_bread (handle_t *, struct inode *, int, int, int *);
+struct buffer_head * ext4_getblk (handle_t *, struct inode *, long, int, int *,
+				  struct cred *);
+struct buffer_head * ext4_bread (handle_t *, struct inode *, int, int, int *,
+				 struct cred *);
 int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
 	sector_t iblock, unsigned long maxblocks, struct buffer_head *bh_result,
-	int create, int extend_disksize);
+	int create, int extend_disksize, struct cred *cred);
 
 extern struct inode *ext4_iget(struct super_block *, unsigned long);
 extern int  ext4_write_inode (struct inode *, int);
@@ -951,7 +956,7 @@ extern void ext4_delete_inode (struct inode *);
 extern int  ext4_sync_inode (handle_t *, struct inode *);
 extern void ext4_discard_reservation (struct inode *);
 extern void ext4_dirty_inode(struct inode *);
-extern int ext4_change_inode_journal_flag(struct inode *, int);
+extern int ext4_change_inode_journal_flag(struct inode *, int, struct cred *);
 extern int ext4_get_inode_loc(struct inode *, struct ext4_iloc *);
 extern void ext4_truncate (struct inode *);
 extern void ext4_set_inode_flags(struct inode *);
@@ -970,7 +975,8 @@ extern long ext4_compat_ioctl (struct file *, unsigned int, unsigned long);
 extern int ext4_orphan_add(handle_t *, struct inode *);
 extern int ext4_orphan_del(handle_t *, struct inode *);
 extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
-				__u32 start_minor_hash, __u32 *next_hash);
+				__u32 start_minor_hash, __u32 *next_hash,
+				struct cred *cred);
 
 /* resize.c */
 extern int ext4_group_add(struct super_block *sb,
@@ -1068,13 +1074,13 @@ extern const struct inode_operations ext4_symlink_inode_operations;
 extern const struct inode_operations ext4_fast_symlink_inode_operations;
 
 /* extents.c */
-extern int ext4_ext_tree_init(handle_t *handle, struct inode *);
+extern int ext4_ext_tree_init(handle_t *handle, struct inode *, struct cred *);
 extern int ext4_ext_writepage_trans_blocks(struct inode *, int);
 extern int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
 			ext4_fsblk_t iblock,
 			unsigned long max_blocks, struct buffer_head *bh_result,
-			int create, int extend_disksize);
-extern void ext4_ext_truncate(struct inode *, struct page *);
+			int create, int extend_disksize, struct cred *cred);
+extern void ext4_ext_truncate(struct inode *, struct page *, struct cred *);
 extern void ext4_ext_init(struct super_block *);
 extern void ext4_ext_release(struct super_block *);
 extern long ext4_fallocate(struct inode *inode, int mode, loff_t offset,
@@ -1082,13 +1088,13 @@ extern long ext4_fallocate(struct inode *inode, int mode, loff_t offset,
 static inline int
 ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
 			unsigned long max_blocks, struct buffer_head *bh,
-			int create, int extend_disksize)
+			int create, int extend_disksize, struct cred *cred)
 {
 	if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)
 		return ext4_ext_get_blocks(handle, inode, block, max_blocks,
-					bh, create, extend_disksize);
+					bh, create, extend_disksize, cred);
 	return ext4_get_blocks_handle(handle, inode, block, max_blocks, bh,
-					create, extend_disksize);
+					create, extend_disksize, cred);
 }
 
 
diff --git a/include/linux/ext4_fs_extents.h b/include/linux/ext4_fs_extents.h
index 81406f3..8f38419 100644
--- a/include/linux/ext4_fs_extents.h
+++ b/include/linux/ext4_fs_extents.h
@@ -232,7 +232,7 @@ extern int ext4_ext_try_to_merge(struct inode *inode,
 				 struct ext4_ext_path *path,
 				 struct ext4_extent *);
 extern unsigned int ext4_ext_check_overlap(struct inode *, struct ext4_extent *, struct ext4_ext_path *);
-extern int ext4_ext_insert_extent(handle_t *, struct inode *, struct ext4_ext_path *, struct ext4_extent *);
+extern int ext4_ext_insert_extent(handle_t *, struct inode *, struct ext4_ext_path *, struct ext4_extent *, struct cred *);
 extern int ext4_ext_walk_space(struct inode *, unsigned long, unsigned long, ext_prepare_callback, void *);
 extern struct ext4_ext_path * ext4_ext_find_extent(struct inode *, int, struct ext4_ext_path *);
 
diff --git a/include/linux/ext4_jbd2.h b/include/linux/ext4_jbd2.h
index d716e63..3ec5e5b 100644
--- a/include/linux/ext4_jbd2.h
+++ b/include/linux/ext4_jbd2.h
@@ -105,7 +105,8 @@ ext4_mark_iloc_dirty(handle_t *handle,
 int ext4_reserve_inode_write(handle_t *handle, struct inode *inode,
 			struct ext4_iloc *iloc);
 
-int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode);
+int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode,
+			  struct cred *cred);
 
 /*
  * Wrapper functions with which ext4 calls into JBD.  The intent here is

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ