Pass credentials down to the ext3 block allocator.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/ext3/acl.c            |   24 ++++--
 fs/ext3/acl.h            |    5 +
 fs/ext3/balloc.c         |   24 ++++--
 fs/ext3/dir.c            |    9 ++
 fs/ext3/ialloc.c         |    5 +
 fs/ext3/inode.c          |   35 ++++++---
 fs/ext3/namei.c          |  174 +++++++++++++++++++++++++++-------------------
 fs/ext3/super.c          |    6 +-
 fs/ext3/xattr.c          |   23 ++++--
 fs/ext3/xattr.h          |    6 +-
 fs/ext3/xattr_security.c |    7 +-
 fs/ext3/xattr_trusted.c  |    4 +
 fs/ext3/xattr_user.c     |    4 +
 include/linux/ext3_fs.h  |   22 ++++--
 14 files changed, 212 insertions(+), 136 deletions(-)

diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c
index d34e996..1db810a 100644
--- a/fs/ext3/acl.c
+++ b/fs/ext3/acl.c
@@ -221,7 +221,7 @@ ext3_get_acl(struct inode *inode, int type)
  */
 static int
 ext3_set_acl(handle_t *handle, struct inode *inode, int type,
-            struct posix_acl *acl)
+            struct posix_acl *acl, struct cred *cred)
 {
        struct ext3_inode_info *ei = EXT3_I(inode);
        int name_index;
@@ -265,7 +265,7 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int 
type,
        }
 
        error = ext3_xattr_set_handle(handle, inode, name_index, "",
-                                     value, size, 0);
+                                     value, size, 0, cred);
 
        kfree(value);
        if (!error) {
@@ -311,7 +311,8 @@ ext3_permission(struct inode *inode, int mask, struct 
nameidata *nd)
  * inode->i_mutex: up (access to inode is still exclusive)
  */
 int
-ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
+ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir,
+             struct cred *cred)
 {
        struct posix_acl *acl = NULL;
        int error = 0;
@@ -331,7 +332,7 @@ ext3_init_acl(handle_t *handle, struct inode *inode, struct 
inode *dir)
 
                if (S_ISDIR(inode->i_mode)) {
                        error = ext3_set_acl(handle, inode,
-                                            ACL_TYPE_DEFAULT, acl);
+                                            ACL_TYPE_DEFAULT, acl, cred);
                        if (error)
                                goto cleanup;
                }
@@ -347,7 +348,8 @@ ext3_init_acl(handle_t *handle, struct inode *inode, struct 
inode *dir)
                        if (error > 0) {
                                /* This is an extended ACL */
                                error = ext3_set_acl(handle, inode,
-                                                    ACL_TYPE_ACCESS, clone);
+                                                    ACL_TYPE_ACCESS, clone,
+                                                    cred);
                        }
                }
                posix_acl_release(clone);
@@ -372,7 +374,7 @@ cleanup:
  * inode->i_mutex: down
  */
 int
-ext3_acl_chmod(struct inode *inode)
+ext3_acl_chmod(struct inode *inode, struct cred *cred)
 {
        struct posix_acl *acl, *clone;
         int error;
@@ -401,10 +403,10 @@ ext3_acl_chmod(struct inode *inode)
                        ext3_std_error(inode->i_sb, error);
                        goto out;
                }
-               error = ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, clone);
+               error = ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, clone, 
cred);
                ext3_journal_stop(handle);
                if (error == -ENOSPC &&
-                   ext3_should_retry_alloc(inode->i_sb, &retries))
+                   ext3_should_retry_alloc(inode->i_sb, &retries, cred))
                        goto retry;
        }
 out:
@@ -483,6 +485,7 @@ static int
 ext3_xattr_set_acl(struct inode *inode, int type, const void *value,
                   size_t size)
 {
+       struct cred *cred = current->cred;
        handle_t *handle;
        struct posix_acl *acl;
        int error, retries = 0;
@@ -508,9 +511,10 @@ retry:
        handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS(inode->i_sb));
        if (IS_ERR(handle))
                return PTR_ERR(handle);
-       error = ext3_set_acl(handle, inode, type, acl);
+       error = ext3_set_acl(handle, inode, type, acl, cred);
        ext3_journal_stop(handle);
-       if (error == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries))
+       if (error == -ENOSPC &&
+           ext3_should_retry_alloc(inode->i_sb, &retries, cred))
                goto retry;
 
 release_and_out:
diff --git a/fs/ext3/acl.h b/fs/ext3/acl.h
index 0d1e627..f35ccac 100644
--- a/fs/ext3/acl.h
+++ b/fs/ext3/acl.h
@@ -59,8 +59,9 @@ static inline int ext3_acl_count(size_t size)
 
 /* acl.c */
 extern int ext3_permission (struct inode *, int, struct nameidata *);
-extern int ext3_acl_chmod (struct inode *);
-extern int ext3_init_acl (handle_t *, struct inode *, struct inode *);
+extern int ext3_acl_chmod (struct inode *, struct cred *);
+extern int ext3_init_acl (handle_t *, struct inode *, struct inode *,
+                         struct cred *);
 
 #else  /* CONFIG_EXT3_FS_POSIX_ACL */
 #include <linux/sched.h>
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index 316ec8b..c1ff445 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -1350,19 +1350,19 @@ out:
 /**
  * ext3_has_free_blocks()
  * @sbi:               in-core super block structure.
+ * @cred:              the credentials in force
  *
  * Check if filesystem has at least 1 free block available for allocation.
  */
-static int ext3_has_free_blocks(struct ext3_sb_info *sbi)
+static int ext3_has_free_blocks(struct ext3_sb_info *sbi, struct cred *cred)
 {
        ext3_fsblk_t free_blocks, root_blocks;
 
        free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
        root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
        if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
-               sbi->s_resuid != current->cred->uid &&
-               (sbi->s_resgid == 0 ||
-                !in_group_p (current->cred, sbi->s_resgid))) {
+               sbi->s_resuid != cred->uid &&
+               (sbi->s_resgid == 0 || !in_group_p(cred, sbi->s_resgid))) {
                return 0;
        }
        return 1;
@@ -1372,6 +1372,7 @@ static int ext3_has_free_blocks(struct ext3_sb_info *sbi)
  * ext3_should_retry_alloc()
  * @sb:                        super block
  * @retries            number of attemps has been made
+ * @cred:              the credentials in force
  *
  * ext3_should_retry_alloc() is called when ENOSPC is returned, and if
  * it is profitable to retry the operation, this function will wait
@@ -1380,9 +1381,10 @@ static int ext3_has_free_blocks(struct ext3_sb_info *sbi)
  *
  * if the total number of retries exceed three times, return FALSE.
  */
-int ext3_should_retry_alloc(struct super_block *sb, int *retries)
+int ext3_should_retry_alloc(struct super_block *sb, int *retries,
+                           struct cred *cred)
 {
-       if (!ext3_has_free_blocks(EXT3_SB(sb)) || (*retries)++ > 3)
+       if (!ext3_has_free_blocks(EXT3_SB(sb), cred) || (*retries)++ > 3)
                return 0;
 
        jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id);
@@ -1397,6 +1399,7 @@ int ext3_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:              the credentials in force
  *
  * ext3_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
@@ -1405,7 +1408,8 @@ int ext3_should_retry_alloc(struct super_block *sb, int 
*retries)
  *
  */
 ext3_fsblk_t ext3_new_blocks(handle_t *handle, struct inode *inode,
-                       ext3_fsblk_t goal, unsigned long *count, int *errp)
+                       ext3_fsblk_t goal, unsigned long *count, int *errp,
+                       struct cred *cred)
 {
        struct buffer_head *bitmap_bh = NULL;
        struct buffer_head *gdp_bh;
@@ -1461,7 +1465,7 @@ ext3_fsblk_t ext3_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 (!ext3_has_free_blocks(sbi)) {
+       if (!ext3_has_free_blocks(sbi, cred)) {
                *errp = -ENOSPC;
                goto out;
        }
@@ -1668,11 +1672,11 @@ out:
 }
 
 ext3_fsblk_t ext3_new_block(handle_t *handle, struct inode *inode,
-                       ext3_fsblk_t goal, int *errp)
+                       ext3_fsblk_t goal, int *errp, struct cred *cred)
 {
        unsigned long count = 1;
 
-       return ext3_new_blocks(handle, inode, goal, &count, errp);
+       return ext3_new_blocks(handle, inode, goal, &count, errp, cred);
 }
 
 /**
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c
index c00723a..d745f99 100644
--- a/fs/ext3/dir.c
+++ b/fs/ext3/dir.c
@@ -96,6 +96,7 @@ int ext3_check_dir_entry (const char * function, struct inode 
* dir,
 static int ext3_readdir(struct file * filp,
                         void * dirent, filldir_t filldir)
 {
+       struct cred *cred = filp->f_cred;
        int error = 0;
        unsigned long offset;
        int i, stored;
@@ -134,7 +135,7 @@ static int ext3_readdir(struct file * filp,
 
                map_bh.b_state = 0;
                err = ext3_get_blocks_handle(NULL, inode, blk, 1,
-                                               &map_bh, 0, 0);
+                                               &map_bh, 0, 0, cred);
                if (err > 0) {
                        pgoff_t index = map_bh.b_blocknr >>
                                        (PAGE_CACHE_SHIFT - inode->i_blkbits);
@@ -144,7 +145,7 @@ static int ext3_readdir(struct file * filp,
                                        &filp->f_ra, filp,
                                        index, 1);
                        filp->f_ra.prev_index = index;
-                       bh = ext3_bread(NULL, inode, blk, 0, &err);
+                       bh = ext3_bread(NULL, inode, blk, 0, &err, cred);
                }
 
                /*
@@ -432,6 +433,7 @@ static int call_filldir(struct file * filp, void * dirent,
 static int ext3_dx_readdir(struct file * filp,
                         void * dirent, filldir_t filldir)
 {
+       struct cred *cred = filp->f_cred;
        struct dir_private_info *info = filp->private_data;
        struct inode *inode = filp->f_path.dentry->d_inode;
        struct fname *fname;
@@ -480,7 +482,8 @@ static int ext3_dx_readdir(struct file * filp,
                        filp->f_version = inode->i_version;
                        ret = ext3_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/ext3/ialloc.c b/fs/ext3/ialloc.c
index 195e9e8..596d8ca 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -421,7 +421,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 *ext3_new_inode(handle_t *handle, struct inode * dir, int mode)
+struct inode *ext3_new_inode(handle_t *handle, struct inode * dir, int mode,
+                            struct cred *cred)
 {
        struct super_block *sb;
        struct buffer_head *bitmap_bh = NULL;
@@ -602,7 +603,7 @@ got:
                goto fail_drop;
        }
 
-       err = ext3_init_acl(handle, inode, dir);
+       err = ext3_init_acl(handle, inode, dir, cred);
        if (err)
                goto fail_free_drop;
 
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 6c74622..57a2e74 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -513,10 +513,12 @@ static int ext3_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 in force
  */
 static int ext3_alloc_blocks(handle_t *handle, struct inode *inode,
                        ext3_fsblk_t goal, int indirect_blks, int blks,
-                       ext3_fsblk_t new_blocks[4], int *err)
+                       ext3_fsblk_t new_blocks[4], int *err,
+                       struct cred *cred)
 {
        int target, i;
        unsigned long count = 0;
@@ -537,7 +539,8 @@ static int ext3_alloc_blocks(handle_t *handle, struct inode 
*inode,
        while (1) {
                count = target;
                /* allocating blocks for indirect blocks and direct blocks */
-               current_block = ext3_new_blocks(handle,inode,goal,&count,err);
+               current_block = ext3_new_blocks(handle,inode,goal,&count,err,
+                                               cred);
                if (*err)
                        goto failed_out;
 
@@ -572,6 +575,7 @@ failed_out:
  *     @blks: number of allocated direct blocks
  *     @offsets: offsets (in the blocks) to store the pointers to next.
  *     @branch: place to store the chain in.
+ *     @cred:  the credentials in force
  *
  *     This function allocates blocks, zeroes out all but the last one,
  *     links them into chain and (if we are synchronous) writes them to disk.
@@ -592,7 +596,7 @@ failed_out:
  */
 static int ext3_alloc_branch(handle_t *handle, struct inode *inode,
                        int indirect_blks, int *blks, ext3_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;
@@ -603,7 +607,7 @@ static int ext3_alloc_branch(handle_t *handle, struct inode 
*inode,
        ext3_fsblk_t current_block;
 
        num = ext3_alloc_blocks(handle, inode, goal, indirect_blks,
-                               *blks, new_blocks, &err);
+                               *blks, new_blocks, &err, cred);
        if (err)
                return err;
 
@@ -788,7 +792,7 @@ err_out:
 int ext3_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];
@@ -899,7 +903,7 @@ int ext3_get_blocks_handle(handle_t *handle, struct inode 
*inode,
         * Block out ext3_truncate while we alter the tree
         */
        err = ext3_alloc_branch(handle, inode, indirect_blks, &count, goal,
-                               offsets + (partial - chain), partial);
+                               offsets + (partial - chain), partial, cred);
 
        /*
         * The ext3_splice_branch call will free and forget any buffers
@@ -946,6 +950,7 @@ out:
 static int ext3_get_block(struct inode *inode, sector_t iblock,
                        struct buffer_head *bh_result, int create)
 {
+       struct cred *cred = current->cred;
        handle_t *handle = ext3_journal_current_handle();
        int ret = 0;
        unsigned max_blocks = bh_result->b_size >> inode->i_blkbits;
@@ -984,7 +989,7 @@ static int ext3_get_block(struct inode *inode, sector_t 
iblock,
 get_block:
        if (ret == 0) {
                ret = ext3_get_blocks_handle(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;
@@ -997,7 +1002,8 @@ get_block:
  * `handle' can be NULL if create is zero
  */
 struct buffer_head *ext3_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;
@@ -1008,7 +1014,7 @@ struct buffer_head *ext3_getblk(handle_t *handle, struct 
inode *inode,
        dummy.b_blocknr = -1000;
        buffer_trace_init(&dummy.b_history);
        err = ext3_get_blocks_handle(handle, inode, block, 1,
-                                       &dummy, create, 1);
+                                       &dummy, create, 1, cred);
        /*
         * ext3_get_blocks_handle() returns number of blocks
         * mapped. 0 in case of a HOLE.
@@ -1064,11 +1070,12 @@ err:
 }
 
 struct buffer_head *ext3_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 = ext3_getblk(handle, inode, block, create, err);
+       bh = ext3_getblk(handle, inode, block, create, err, cred);
        if (!bh)
                return bh;
        if (buffer_uptodate(bh))
@@ -1175,7 +1182,8 @@ retry:
 prepare_write_failed:
        if (ret)
                ext3_journal_stop(handle);
-       if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries))
+       if (ret == -ENOSPC &&
+           ext3_should_retry_alloc(inode->i_sb, &retries, file->f_cred))
                goto retry;
 out:
        return ret;
@@ -2930,6 +2938,7 @@ int ext3_write_inode(struct inode *inode, int wait)
  */
 int ext3_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;
@@ -2992,7 +3001,7 @@ int ext3_setattr(struct dentry *dentry, struct iattr 
*attr)
                ext3_orphan_del(NULL, inode);
 
        if (!rc && (ia_valid & ATTR_MODE))
-               rc = ext3_acl_chmod(inode);
+               rc = ext3_acl_chmod(inode, cred);
 
 err_out:
        ext3_std_error(inode->i_sb, error);
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index 6919a18..4a6adaa 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -51,13 +51,14 @@
 
 static struct buffer_head *ext3_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 = ext3_bread(handle, inode, *block, 1, err))) {
+       if ((bh = ext3_bread(handle, inode, *block, 1, err, cred))) {
                inode->i_size += inode->i_sb->s_blocksize;
                EXT3_I(inode)->i_disksize = inode->i_size;
                ext3_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 ext3_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 ext3_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 * ext3_dx_find_entry(struct dentry *dentry,
-                      struct ext3_dir_entry_2 **res_dir, int *err);
+                      struct ext3_dir_entry_2 **res_dir, int *err,
+                      struct cred *cred);
 static int ext3_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 = ext3_bread (NULL,dir, 0, 0, err)))
+       if (!(bh = ext3_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,8 @@ dx_probe(struct dentry *dentry, struct inode *dir,
                frame->entries = entries;
                frame->at = at;
                if (!indirect--) return frame;
-               if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err)))
+               if (!(bh = ext3_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 +498,8 @@ static void dx_release (struct dx_frame *frames)
 static int ext3_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 +543,7 @@ static int ext3_htree_next_block(struct inode *dir, __u32 
hash,
         */
        while (num_frames--) {
                if (!(bh = ext3_bread(NULL, dir, dx_get_block(p->at),
-                                     0, &err)))
+                                     0, &err, cred)))
                        return err; /* Failure */
                p++;
                brelse (p->bh);
@@ -563,14 +570,15 @@ static inline struct ext3_dir_entry_2 
*ext3_next_entry(struct ext3_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 ext3_dir_entry_2 *de, *top;
        int err, count = 0;
 
        dxtrace(printk("In htree dirblock_to_tree: block %d\n", block));
-       if (!(bh = ext3_bread (NULL, dir, block, 0, &err)))
+       if (!(bh = ext3_bread (NULL, dir, block, 0, &err, cred)))
                return err;
 
        de = (struct ext3_dir_entry_2 *) bh->b_data;
@@ -615,7 +623,8 @@ static int htree_dirblock_to_tree(struct file *dir_file,
  * or a negative error code.
  */
 int ext3_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 ext3_dir_entry_2 *de;
@@ -633,13 +642,15 @@ int ext3_htree_fill_tree(struct file *dir_file, __u32 
start_hash,
                hinfo.hash_version = EXT3_SB(dir->i_sb)->s_def_hash_version;
                hinfo.seed = EXT3_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 +672,8 @@ int ext3_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 +681,7 @@ int ext3_htree_fill_tree(struct file *dir_file, __u32 
start_hash,
                count += ret;
                hashval = ~0;
                ret = ext3_htree_next_block(dir, HASH_NB_ALWAYS,
-                                           frame, frames, &hashval);
+                                           frame, frames, &hashval, cred);
                *next_hash = hashval;
                if (ret < 0) {
                        err = ret;
@@ -847,7 +859,8 @@ static inline int search_dirblock(struct buffer_head * bh,
  * to brelse() it when appropriate.
  */
 static struct buffer_head * ext3_find_entry (struct dentry *dentry,
-                                       struct ext3_dir_entry_2 ** res_dir)
+                                       struct ext3_dir_entry_2 ** res_dir,
+                                       struct cred *cred)
 {
        struct super_block * sb;
        struct buffer_head * bh_use[NAMEI_RA_SIZE];
@@ -873,7 +886,7 @@ static struct buffer_head * ext3_find_entry (struct dentry 
*dentry,
                return NULL;
 #ifdef CONFIG_EXT3_INDEX
        if (is_dx(dir)) {
-               bh = ext3_dx_find_entry(dentry, res_dir, &err);
+               bh = ext3_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
@@ -909,7 +922,7 @@ restart:
                                        break;
                                }
                                num++;
-                               bh = ext3_getblk(NULL, dir, b++, 0, &err);
+                               bh = ext3_getblk(NULL, dir, b++, 0, &err, cred);
                                bh_use[ra_max] = bh;
                                if (bh)
                                        ll_rw_block(READ_META, 1, &bh);
@@ -961,7 +974,8 @@ cleanup_and_exit:
 
 #ifdef CONFIG_EXT3_INDEX
 static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
-                      struct ext3_dir_entry_2 **res_dir, int *err)
+                      struct ext3_dir_entry_2 **res_dir, int *err,
+                      struct cred *cred)
 {
        struct super_block * sb;
        struct dx_hash_info     hinfo;
@@ -978,7 +992,8 @@ static struct buffer_head * ext3_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;
@@ -989,7 +1004,7 @@ static struct buffer_head * ext3_dx_find_entry(struct 
dentry *dentry,
        hash = hinfo.hash;
        do {
                block = dx_get_block(frame->at);
-               if (!(bh = ext3_bread (NULL,dir, block, 0, err)))
+               if (!(bh = ext3_bread (NULL,dir, block, 0, err, cred)))
                        goto errout;
                de = (struct ext3_dir_entry_2 *) bh->b_data;
                top = (struct ext3_dir_entry_2 *) ((char *) de + 
sb->s_blocksize -
@@ -1011,7 +1026,7 @@ static struct buffer_head * ext3_dx_find_entry(struct 
dentry *dentry,
                brelse (bh);
                /* Check to see if we should continue to search */
                retval = ext3_htree_next_block(dir, hash, frame,
-                                              frames, NULL);
+                                              frames, NULL, cred);
                if (retval < 0) {
                        ext3_warning(sb, __FUNCTION__,
                             "error reading index page in directory #%lu",
@@ -1031,6 +1046,7 @@ errout:
 
 static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, 
struct nameidata *nd)
 {
+       struct cred *cred = current->cred;
        struct inode * inode;
        struct ext3_dir_entry_2 * de;
        struct buffer_head * bh;
@@ -1038,7 +1054,7 @@ static struct dentry *ext3_lookup(struct inode * dir, 
struct dentry *dentry, str
        if (dentry->d_name.len > EXT3_NAME_LEN)
                return ERR_PTR(-ENAMETOOLONG);
 
-       bh = ext3_find_entry(dentry, &de);
+       bh = ext3_find_entry(dentry, &de, cred);
        inode = NULL;
        if (bh) {
                unsigned long ino = le32_to_cpu(de->inode);
@@ -1058,6 +1074,7 @@ static struct dentry *ext3_lookup(struct inode * dir, 
struct dentry *dentry, str
 
 struct dentry *ext3_get_parent(struct dentry *child)
 {
+       struct cred *cred = current->cred;
        unsigned long ino;
        struct dentry *parent;
        struct inode *inode;
@@ -1069,7 +1086,7 @@ struct dentry *ext3_get_parent(struct dentry *child)
        dotdot.d_name.len = 2;
        dotdot.d_parent = child; /* confusing, isn't it! */
 
-       bh = ext3_find_entry(&dotdot, &de);
+       bh = ext3_find_entry(&dotdot, &de, cred);
        inode = NULL;
        if (!bh)
                return ERR_PTR(-ENOENT);
@@ -1168,7 +1185,8 @@ static struct ext3_dir_entry_2* dx_pack_dirents(char 
*base, int size)
  */
 static struct ext3_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;
@@ -1181,7 +1199,7 @@ static struct ext3_dir_entry_2 *do_split(handle_t 
*handle, struct inode *dir,
        struct ext3_dir_entry_2 *de = NULL, *de2;
        int     err = 0;
 
-       bh2 = ext3_append (handle, dir, &newblock, &err);
+       bh2 = ext3_append (handle, dir, &newblock, &err, cred);
        if (!(bh2)) {
                brelse(*bh);
                *bh = NULL;
@@ -1361,7 +1379,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;
@@ -1389,7 +1408,7 @@ static int make_indexed_dir(handle_t *handle, struct 
dentry *dentry,
        }
        root = (struct dx_root *) bh->b_data;
 
-       bh2 = ext3_append (handle, dir, &block, &retval);
+       bh2 = ext3_append (handle, dir, &block, &retval, cred);
        if (!(bh2)) {
                brelse(bh);
                return retval;
@@ -1427,7 +1446,7 @@ 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;
@@ -1447,7 +1466,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 ext3_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;
@@ -1467,7 +1486,7 @@ static int ext3_add_entry (handle_t *handle, struct 
dentry *dentry,
                return -EINVAL;
 #ifdef CONFIG_EXT3_INDEX
        if (is_dx(dir)) {
-               retval = ext3_dx_add_entry(handle, dentry, inode);
+               retval = ext3_dx_add_entry(handle, dentry, inode, cred);
                if (!retval || (retval != ERR_BAD_DX_DIR))
                        return retval;
                EXT3_I(dir)->i_flags &= ~EXT3_INDEX_FL;
@@ -1477,7 +1496,7 @@ static int ext3_add_entry (handle_t *handle, struct 
dentry *dentry,
 #endif
        blocks = dir->i_size >> sb->s_blocksize_bits;
        for (block = 0, offset = 0; block < blocks; block++) {
-               bh = ext3_bread(handle, dir, block, 0, &retval);
+               bh = ext3_bread(handle, dir, block, 0, &retval, cred);
                if(!bh)
                        return retval;
                retval = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
@@ -1487,11 +1506,11 @@ static int ext3_add_entry (handle_t *handle, struct 
dentry *dentry,
 #ifdef CONFIG_EXT3_INDEX
                if (blocks == 1 && !dx_fallback &&
                    EXT3_HAS_COMPAT_FEATURE(sb, EXT3_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 = ext3_append(handle, dir, &block, &retval);
+       bh = ext3_append(handle, dir, &block, &retval, cred);
        if (!bh)
                return retval;
        de = (struct ext3_dir_entry_2 *) bh->b_data;
@@ -1505,7 +1524,7 @@ static int ext3_add_entry (handle_t *handle, struct 
dentry *dentry,
  * Returns 0 for success, or a negative error value
  */
 static int ext3_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;
@@ -1516,13 +1535,14 @@ static int ext3_dx_add_entry(handle_t *handle, struct 
dentry *dentry,
        struct ext3_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 = ext3_bread(handle,dir, dx_get_block(frame->at), 0, &err)))
+       if (!(bh = ext3_bread(handle,dir, dx_get_block(frame->at), 0, &err,
+                             cred)))
                goto cleanup;
 
        BUFFER_TRACE(bh, "get_write_access");
@@ -1555,7 +1575,7 @@ static int ext3_dx_add_entry(handle_t *handle, struct 
dentry *dentry,
                        err = -ENOSPC;
                        goto cleanup;
                }
-               bh2 = ext3_append (handle, dir, &newblock, &err);
+               bh2 = ext3_append (handle, dir, &newblock, &err, cred);
                if (!(bh2))
                        goto cleanup;
                node2 = (struct dx_node *)(bh2->b_data);
@@ -1620,7 +1640,7 @@ static int ext3_dx_add_entry(handle_t *handle, struct 
dentry *dentry,
                }
                ext3_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);
@@ -1678,9 +1698,9 @@ static int ext3_delete_entry (handle_t *handle,
 }
 
 static int ext3_add_nondir(handle_t *handle,
-               struct dentry *dentry, struct inode *inode)
+               struct dentry *dentry, struct inode *inode, struct cred *cred)
 {
-       int err = ext3_add_entry(handle, dentry, inode);
+       int err = ext3_add_entry(handle, dentry, inode, cred);
        if (!err) {
                ext3_mark_inode_dirty(handle, inode);
                d_instantiate(dentry, inode);
@@ -1702,6 +1722,7 @@ static int ext3_add_nondir(handle_t *handle,
 static int ext3_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;
@@ -1716,16 +1737,16 @@ retry:
        if (IS_DIRSYNC(dir))
                handle->h_sync = 1;
 
-       inode = ext3_new_inode (handle, dir, mode);
+       inode = ext3_new_inode (handle, dir, mode, cred);
        err = PTR_ERR(inode);
        if (!IS_ERR(inode)) {
                inode->i_op = &ext3_file_inode_operations;
                inode->i_fop = &ext3_file_operations;
                ext3_set_aops(inode);
-               err = ext3_add_nondir(handle, dentry, inode);
+               err = ext3_add_nondir(handle, dentry, inode, cred);
        }
        ext3_journal_stop(handle);
-       if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries))
+       if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries, 
cred))
                goto retry;
        return err;
 }
@@ -1733,6 +1754,7 @@ retry:
 static int ext3_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;
@@ -1750,23 +1772,25 @@ retry:
        if (IS_DIRSYNC(dir))
                handle->h_sync = 1;
 
-       inode = ext3_new_inode (handle, dir, mode);
+       inode = ext3_new_inode (handle, dir, mode, cred);
        err = PTR_ERR(inode);
        if (!IS_ERR(inode)) {
                init_special_inode(inode, inode->i_mode, rdev);
 #ifdef CONFIG_EXT3_FS_XATTR
                inode->i_op = &ext3_special_inode_operations;
 #endif
-               err = ext3_add_nondir(handle, dentry, inode);
+               err = ext3_add_nondir(handle, dentry, inode, cred);
        }
        ext3_journal_stop(handle);
-       if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries))
+       if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries,
+                                                     cred))
                goto retry;
        return err;
 }
 
 static int ext3_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;
@@ -1786,7 +1810,7 @@ retry:
        if (IS_DIRSYNC(dir))
                handle->h_sync = 1;
 
-       inode = ext3_new_inode (handle, dir, S_IFDIR | mode);
+       inode = ext3_new_inode (handle, dir, S_IFDIR | mode, cred);
        err = PTR_ERR(inode);
        if (IS_ERR(inode))
                goto out_stop;
@@ -1794,7 +1818,7 @@ retry:
        inode->i_op = &ext3_dir_inode_operations;
        inode->i_fop = &ext3_dir_operations;
        inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
-       dir_block = ext3_bread (handle, inode, 0, 1, &err);
+       dir_block = ext3_bread (handle, inode, 0, 1, &err, cred);
        if (!dir_block) {
                drop_nlink(inode); /* is this nlink == 0? */
                ext3_mark_inode_dirty(handle, inode);
@@ -1821,7 +1845,7 @@ retry:
        ext3_journal_dirty_metadata(handle, dir_block);
        brelse (dir_block);
        ext3_mark_inode_dirty(handle, inode);
-       err = ext3_add_entry (handle, dentry, inode);
+       err = ext3_add_entry (handle, dentry, inode, cred);
        if (err) {
                inode->i_nlink = 0;
                ext3_mark_inode_dirty(handle, inode);
@@ -1834,7 +1858,7 @@ retry:
        d_instantiate(dentry, inode);
 out_stop:
        ext3_journal_stop(handle);
-       if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries))
+       if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries, 
cred))
                goto retry;
        return err;
 }
@@ -1842,7 +1866,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;
@@ -1852,7 +1876,7 @@ static int empty_dir (struct inode * inode)
 
        sb = inode->i_sb;
        if (inode->i_size < EXT3_DIR_REC_LEN(1) + EXT3_DIR_REC_LEN(2) ||
-           !(bh = ext3_bread (NULL, inode, 0, 0, &err))) {
+           !(bh = ext3_bread (NULL, inode, 0, 0, &err, cred))) {
                if (err)
                        ext3_error(inode->i_sb, __FUNCTION__,
                                   "error %d reading directory #%lu offset 0",
@@ -1885,7 +1909,8 @@ static int empty_dir (struct inode * inode)
                        err = 0;
                        brelse (bh);
                        bh = ext3_bread (NULL, inode,
-                               offset >> EXT3_BLOCK_SIZE_BITS(sb), 0, &err);
+                               offset >> EXT3_BLOCK_SIZE_BITS(sb), 0, &err,
+                               cred);
                        if (!bh) {
                                if (err)
                                        ext3_error(sb, __FUNCTION__,
@@ -2059,6 +2084,7 @@ out_brelse:
 
 static int ext3_rmdir (struct inode * dir, struct dentry *dentry)
 {
+       struct cred *cred = current->cred;
        int retval;
        struct inode * inode;
        struct buffer_head * bh;
@@ -2073,7 +2099,7 @@ static int ext3_rmdir (struct inode * dir, struct dentry 
*dentry)
                return PTR_ERR(handle);
 
        retval = -ENOENT;
-       bh = ext3_find_entry (dentry, &de);
+       bh = ext3_find_entry (dentry, &de, cred);
        if (!bh)
                goto end_rmdir;
 
@@ -2087,7 +2113,7 @@ static int ext3_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 = ext3_delete_entry(handle, dir, de, bh);
@@ -2118,6 +2144,7 @@ end_rmdir:
 
 static int ext3_unlink(struct inode * dir, struct dentry *dentry)
 {
+       struct cred *cred = current->cred;
        int retval;
        struct inode * inode;
        struct buffer_head * bh;
@@ -2135,7 +2162,7 @@ static int ext3_unlink(struct inode * dir, struct dentry 
*dentry)
                handle->h_sync = 1;
 
        retval = -ENOENT;
-       bh = ext3_find_entry (dentry, &de);
+       bh = ext3_find_entry (dentry, &de, cred);
        if (!bh)
                goto end_unlink;
 
@@ -2173,6 +2200,7 @@ end_unlink:
 static int ext3_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;
@@ -2191,7 +2219,7 @@ retry:
        if (IS_DIRSYNC(dir))
                handle->h_sync = 1;
 
-       inode = ext3_new_inode (handle, dir, S_IFLNK|S_IRWXUGO);
+       inode = ext3_new_inode (handle, dir, S_IFLNK|S_IRWXUGO, cred);
        err = PTR_ERR(inode);
        if (IS_ERR(inode))
                goto out_stop;
@@ -2218,10 +2246,11 @@ retry:
                inode->i_size = l-1;
        }
        EXT3_I(inode)->i_disksize = inode->i_size;
-       err = ext3_add_nondir(handle, dentry, inode);
+       err = ext3_add_nondir(handle, dentry, inode, cred);
 out_stop:
        ext3_journal_stop(handle);
-       if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries))
+       if (err == -ENOSPC &&
+           ext3_should_retry_alloc(dir->i_sb, &retries, cred))
                goto retry;
        return err;
 }
@@ -2229,6 +2258,7 @@ out_stop:
 static int ext3_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;
@@ -2255,9 +2285,10 @@ retry:
        inc_nlink(inode);
        atomic_inc(&inode->i_count);
 
-       err = ext3_add_nondir(handle, dentry, inode);
+       err = ext3_add_nondir(handle, dentry, inode, cred);
        ext3_journal_stop(handle);
-       if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries))
+       if (err == -ENOSPC &&
+           ext3_should_retry_alloc(dir->i_sb, &retries, cred))
                goto retry;
        return err;
 }
@@ -2273,6 +2304,7 @@ retry:
 static int ext3_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;
@@ -2294,7 +2326,7 @@ static int ext3_rename (struct inode * old_dir, struct 
dentry *old_dentry,
        if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
                handle->h_sync = 1;
 
-       old_bh = ext3_find_entry (old_dentry, &old_de);
+       old_bh = ext3_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
@@ -2307,7 +2339,7 @@ static int ext3_rename (struct inode * old_dir, struct 
dentry *old_dentry,
                goto end_rename;
 
        new_inode = new_dentry->d_inode;
-       new_bh = ext3_find_entry (new_dentry, &new_de);
+       new_bh = ext3_find_entry (new_dentry, &new_de, cred);
        if (new_bh) {
                if (!new_inode) {
                        brelse (new_bh);
@@ -2317,11 +2349,11 @@ static int ext3_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 = ext3_bread (handle, old_inode, 0, 0, &retval);
+               dir_bh = ext3_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)
@@ -2332,7 +2364,7 @@ static int ext3_rename (struct inode * old_dir, struct 
dentry *old_dentry,
                        goto end_rename;
        }
        if (!new_bh) {
-               retval = ext3_add_entry (handle, new_dentry, old_inode);
+               retval = ext3_add_entry (handle, new_dentry, old_inode, cred);
                if (retval)
                        goto end_rename;
        } else {
@@ -2371,7 +2403,7 @@ static int ext3_rename (struct inode * old_dir, struct 
dentry *old_dentry,
                struct buffer_head *old_bh2;
                struct ext3_dir_entry_2 *old_de2;
 
-               old_bh2 = ext3_find_entry(old_dentry, &old_de2);
+               old_bh2 = ext3_find_entry(old_dentry, &old_de2, cred);
                if (old_bh2) {
                        retval = ext3_delete_entry(handle, old_dir,
                                                   old_de2, old_bh2);
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index add683b..14a558b 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -2671,6 +2671,7 @@ static int ext3_quota_on(struct super_block *sb, int 
type, int format_id,
 static ssize_t ext3_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 >> EXT3_BLOCK_SIZE_BITS(sb);
        int err = 0;
@@ -2688,7 +2689,7 @@ static ssize_t ext3_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 = ext3_bread(NULL, inode, blk, 0, &err);
+               bh = ext3_bread(NULL, inode, blk, 0, &err, cred);
                if (err)
                        return err;
                if (!bh)        /* A hole? */
@@ -2709,6 +2710,7 @@ static ssize_t ext3_quota_read(struct super_block *sb, 
int type, char *data,
 static ssize_t ext3_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 >> EXT3_BLOCK_SIZE_BITS(sb);
        int err = 0;
@@ -2729,7 +2731,7 @@ static ssize_t ext3_quota_write(struct super_block *sb, 
int type,
        while (towrite > 0) {
                tocopy = sb->s_blocksize - offset < towrite ?
                                sb->s_blocksize - offset : towrite;
-               bh = ext3_bread(handle, inode, blk, 1, &err);
+               bh = ext3_bread(handle, inode, blk, 1, &err, cred);
                if (!bh)
                        goto out;
                if (journal_quota) {
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index f58cbb2..3b34cea 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -676,7 +676,8 @@ cleanup:
 static int
 ext3_xattr_block_set(handle_t *handle, struct inode *inode,
                     struct ext3_xattr_info *i,
-                    struct ext3_xattr_block_find *bs)
+                    struct ext3_xattr_block_find *bs,
+                    struct cred *cred)
 {
        struct super_block *sb = inode->i_sb;
        struct buffer_head *new_bh = NULL;
@@ -805,7 +806,7 @@ inserted:
                                (ext3_fsblk_t)EXT3_I(inode)->i_block_group *
                                EXT3_BLOCKS_PER_GROUP(sb);
                        ext3_fsblk_t block = ext3_new_block(handle, inode,
-                                                       goal, &error);
+                                                       goal, &error, cred);
                        if (error)
                                goto cleanup;
                        ea_idebug(inode, "creating block %d", block);
@@ -938,7 +939,7 @@ ext3_xattr_ibody_set(handle_t *handle, struct inode *inode,
 int
 ext3_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 ext3_xattr_info i = {
                .name_index = name_index,
@@ -996,14 +997,17 @@ ext3_xattr_set_handle(handle_t *handle, struct inode 
*inode, int name_index,
                if (!is.s.not_found)
                        error = ext3_xattr_ibody_set(handle, inode, &i, &is);
                else if (!bs.s.not_found)
-                       error = ext3_xattr_block_set(handle, inode, &i, &bs);
+                       error = ext3_xattr_block_set(handle, inode, &i, &bs,
+                                                    cred);
        } else {
                error = ext3_xattr_ibody_set(handle, inode, &i, &is);
                if (!error && !bs.s.not_found) {
                        i.value = NULL;
-                       error = ext3_xattr_block_set(handle, inode, &i, &bs);
+                       error = ext3_xattr_block_set(handle, inode, &i, &bs,
+                                                    cred);
                } else if (error == -ENOSPC) {
-                       error = ext3_xattr_block_set(handle, inode, &i, &bs);
+                       error = ext3_xattr_block_set(handle, inode, &i, &bs,
+                                                    cred);
                        if (error)
                                goto cleanup;
                        if (!is.s.not_found) {
@@ -1043,7 +1047,8 @@ cleanup:
  */
 int
 ext3_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;
@@ -1056,10 +1061,10 @@ retry:
                int error2;
 
                error = ext3_xattr_set_handle(handle, inode, name_index, name,
-                                             value, value_len, flags);
+                                             value, value_len, flags, cred);
                error2 = ext3_journal_stop(handle);
                if (error == -ENOSPC &&
-                   ext3_should_retry_alloc(inode->i_sb, &retries))
+                   ext3_should_retry_alloc(inode->i_sb, &retries, cred))
                        goto retry;
                if (error == 0)
                        error = error2;
diff --git a/fs/ext3/xattr.h b/fs/ext3/xattr.h
index 6b1ae1c..761772a 100644
--- a/fs/ext3/xattr.h
+++ b/fs/ext3/xattr.h
@@ -68,8 +68,10 @@ extern ssize_t ext3_listxattr(struct dentry *, char *, 
size_t);
 
 extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t);
 extern int ext3_xattr_list(struct inode *, char *, size_t);
-extern int ext3_xattr_set(struct inode *, int, const char *, const void *, 
size_t, int);
-extern int ext3_xattr_set_handle(handle_t *, struct inode *, int, const char 
*, const void *, size_t, int);
+extern int ext3_xattr_set(struct inode *, int, const char *, const void *,
+                         size_t, int, struct cred *);
+extern int ext3_xattr_set_handle(handle_t *, struct inode *, int, const char *,
+                                const void *, size_t, int, struct cred *);
 
 extern void ext3_xattr_delete_inode(handle_t *, struct inode *);
 extern void ext3_xattr_put_super(struct super_block *);
diff --git a/fs/ext3/xattr_security.c b/fs/ext3/xattr_security.c
index 821efaf..76ccead 100644
--- a/fs/ext3/xattr_security.c
+++ b/fs/ext3/xattr_security.c
@@ -41,15 +41,18 @@ static int
 ext3_xattr_security_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 ext3_xattr_set(inode, EXT3_XATTR_INDEX_SECURITY, name,
-                             value, size, flags);
+                             value, size, flags, cred);
 }
 
 int
 ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir)
 {
+       struct cred *cred = current->cred;
        int err;
        size_t len;
        void *value;
@@ -62,7 +65,7 @@ ext3_init_security(handle_t *handle, struct inode *inode, 
struct inode *dir)
                return err;
        }
        err = ext3_xattr_set_handle(handle, inode, EXT3_XATTR_INDEX_SECURITY,
-                                   name, value, len, 0);
+                                   name, value, len, 0, cred);
        kfree(name);
        kfree(value);
        return err;
diff --git a/fs/ext3/xattr_trusted.c b/fs/ext3/xattr_trusted.c
index 0327497..eead225 100644
--- a/fs/ext3/xattr_trusted.c
+++ b/fs/ext3/xattr_trusted.c
@@ -47,10 +47,12 @@ static int
 ext3_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 ext3_xattr_set(inode, EXT3_XATTR_INDEX_TRUSTED, name,
-                             value, size, flags);
+                             value, size, flags, cred);
 }
 
 struct xattr_handler ext3_xattr_trusted_handler = {
diff --git a/fs/ext3/xattr_user.c b/fs/ext3/xattr_user.c
index 1abd8f9..1aa87ae 100644
--- a/fs/ext3/xattr_user.c
+++ b/fs/ext3/xattr_user.c
@@ -47,12 +47,14 @@ static int
 ext3_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 ext3_xattr_set(inode, EXT3_XATTR_INDEX_USER, name,
-                             value, size, flags);
+                             value, size, flags, cred);
 }
 
 struct xattr_handler ext3_xattr_user_handler = {
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index a5ccfea..23db760 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -761,9 +761,10 @@ ext3_group_first_block_no(struct super_block *sb, unsigned 
long group_no)
 extern int ext3_bg_has_super(struct super_block *sb, int group);
 extern unsigned long ext3_bg_num_gdb(struct super_block *sb, int group);
 extern ext3_fsblk_t ext3_new_block (handle_t *handle, struct inode *inode,
-                       ext3_fsblk_t goal, int *errp);
+                       ext3_fsblk_t goal, int *errp, struct cred *cred);
 extern ext3_fsblk_t ext3_new_blocks (handle_t *handle, struct inode *inode,
-                       ext3_fsblk_t goal, unsigned long *count, int *errp);
+                       ext3_fsblk_t goal, unsigned long *count, int *errp,
+                       struct cred *cred);
 extern void ext3_free_blocks (handle_t *handle, struct inode *inode,
                        ext3_fsblk_t block, unsigned long count);
 extern void ext3_free_blocks_sb (handle_t *handle, struct super_block *sb,
@@ -774,7 +775,8 @@ extern void ext3_check_blocks_bitmap (struct super_block *);
 extern struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb,
                                                    unsigned int block_group,
                                                    struct buffer_head ** bh);
-extern int ext3_should_retry_alloc(struct super_block *sb, int *retries);
+extern int ext3_should_retry_alloc(struct super_block *sb, int *retries,
+                                  struct cred *cred);
 extern void ext3_init_block_alloc_info(struct inode *);
 extern void ext3_rsv_window_add(struct super_block *sb, struct 
ext3_reserve_window_node *rsv);
 
@@ -795,7 +797,8 @@ extern int ext3fs_dirhash(const char *name, int len, struct
                          dx_hash_info *hinfo);
 
 /* ialloc.c */
-extern struct inode * ext3_new_inode (handle_t *, struct inode *, int);
+extern struct inode * ext3_new_inode (handle_t *, struct inode *, int,
+                                     struct cred *);
 extern void ext3_free_inode (handle_t *, struct inode *);
 extern struct inode * ext3_orphan_get (struct super_block *, unsigned long);
 extern unsigned long ext3_count_free_inodes (struct super_block *);
@@ -807,11 +810,13 @@ extern unsigned long ext3_count_free (struct buffer_head 
*, unsigned);
 /* inode.c */
 int ext3_forget(handle_t *handle, int is_metadata, struct inode *inode,
                struct buffer_head *bh, ext3_fsblk_t blocknr);
-struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int 
*);
-struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
+struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *,
+                                 struct cred *);
+struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *,
+                                struct cred *);
 int ext3_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 *ext3_iget (struct super_block *, unsigned long);
 extern int  ext3_write_inode (struct inode *, int);
@@ -836,7 +841,8 @@ extern long ext3_compat_ioctl (struct file *, unsigned int, 
unsigned long);
 extern int ext3_orphan_add(handle_t *, struct inode *);
 extern int ext3_orphan_del(handle_t *, struct inode *);
 extern int ext3_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 ext3_group_add(struct super_block *sb,

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

Reply via email to