[PATCH 03/52] CRED: Pass credentials down to ext3 block allocator

From: David Howells
Date: Fri Oct 12 2007 - 12:09:13 EST


Pass credentials down to the ext3 block allocator.

Signed-off-by: David Howells <dhowells@xxxxxxxxxx>
---

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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/