From: From: Andreas Gruenbacher * Various minor cleanups and simplifications in the extended attributes and acl code. * Use a smarter shortcut rule in ext[23]_permission(): If the mask contains permissions that are not also contained in the group file mode permission bits, those permissions can never be granted by an acl. (The previous shortcut rule was more coarse.) fs/ext2/acl.c | 85 ++++++++++++++++++++++++++++++++---------------------- fs/ext2/xattr.c | 55 ++++++++++++++++------------------- fs/ext3/acl.c | 88 +++++++++++++++++++++++++++++++++----------------------- fs/ext3/xattr.c | 49 ++++++++++++++----------------- 4 files changed, 153 insertions(+), 124 deletions(-) diff -puN fs/ext2/acl.c~xattr-cleanup fs/ext2/acl.c --- 25/fs/ext2/acl.c~xattr-cleanup 2003-07-02 16:35:37.000000000 -0700 +++ 25-akpm/fs/ext2/acl.c 2003-07-02 16:35:37.000000000 -0700 @@ -1,7 +1,7 @@ /* * linux/fs/ext2/acl.c * - * Copyright (C) 2001 by Andreas Gruenbacher, + * Copyright (C) 2001-2003 Andreas Gruenbacher, */ #include @@ -19,7 +19,7 @@ static struct posix_acl * ext2_acl_from_disk(const void *value, size_t size) { const char *end = (char *)value + size; - int n, count; + size_t n, count; struct posix_acl *acl; if (!value) @@ -85,7 +85,7 @@ ext2_acl_to_disk(const struct posix_acl { ext2_acl_header *ext_acl; char *e; - int n; + size_t n; *size = ext2_acl_size(acl->a_count); ext_acl = (ext2_acl_header *)kmalloc(sizeof(ext2_acl_header) + @@ -130,10 +130,11 @@ fail: static struct posix_acl * ext2_get_acl(struct inode *inode, int type) { + const size_t max_size = ext2_acl_size(EXT2_ACL_MAX_ENTRIES); + struct ext2_inode_inode *ei = EXT2_I(inode); int name_index; char *value; - struct posix_acl *acl, **p_acl; - const size_t size = ext2_acl_size(EXT2_ACL_MAX_ENTRIES); + struct posix_acl *acl; int retval; if (!test_opt(inode->i_sb, POSIX_ACL)) @@ -141,36 +142,43 @@ ext2_get_acl(struct inode *inode, int ty switch(type) { case ACL_TYPE_ACCESS: - p_acl = &EXT2_I(inode)->i_acl; + if (ei->i_acl != EXT2_ACL_NOT_CACHED) + return posix_acl_dup(ei->i_acl); name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS; break; case ACL_TYPE_DEFAULT: - p_acl = &EXT2_I(inode)->i_default_acl; + if (ei->i_default_acl != EXT2_ACL_NOT_CACHED) + return posix_acl_dup(ei->i_default_acl); name_index = EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT; break; default: return ERR_PTR(-EINVAL); } - if (*p_acl != EXT2_ACL_NOT_CACHED) - return posix_acl_dup(*p_acl); - value = kmalloc(size, GFP_KERNEL); + value = kmalloc(max_size, GFP_KERNEL); if (!value) return ERR_PTR(-ENOMEM); - retval = ext2_xattr_get(inode, name_index, "", value, size); - - if (retval == -ENODATA || retval == -ENOSYS) - *p_acl = acl = NULL; - else if (retval < 0) - acl = ERR_PTR(retval); - else { + retval = ext2_xattr_get(inode, name_index, "", value, max_size); + acl = ERR_PTR(retval); + if (retval >= 0) acl = ext2_acl_from_disk(value, retval); - if (!IS_ERR(acl)) - *p_acl = posix_acl_dup(acl); - } + else if (retval == -ENODATA || retval == -ENOSYS) + acl = NULL; kfree(value); + + if (!IS_ERR(acl)) { + switch(type) { + case ACL_TYPE_ACCESS: + ei->i_acl = posix_acl_dup(acl); + break; + + case ACL_TYPE_DEFAULT: + ei->i_default_acl = posix_acl_dup(acl); + break; + } + } return acl; } @@ -180,9 +188,9 @@ ext2_get_acl(struct inode *inode, int ty static int ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) { + struct ext2_inode_info *ei = EXT2_I(inode); int name_index; void *value = NULL; - struct posix_acl **p_acl; size_t size; int error; @@ -194,7 +202,6 @@ ext2_set_acl(struct inode *inode, int ty switch(type) { case ACL_TYPE_ACCESS: name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS; - p_acl = &EXT2_I(inode)->i_acl; if (acl) { mode_t mode = inode->i_mode; error = posix_acl_equiv_mode(acl, &mode); @@ -211,7 +218,6 @@ ext2_set_acl(struct inode *inode, int ty case ACL_TYPE_DEFAULT: name_index = EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT; - p_acl = &EXT2_I(inode)->i_default_acl; if (!S_ISDIR(inode->i_mode)) return acl ? -EACCES : 0; break; @@ -232,9 +238,19 @@ ext2_set_acl(struct inode *inode, int ty if (value) kfree(value); if (!error) { - if (*p_acl && *p_acl != EXT2_ACL_NOT_CACHED) - posix_acl_release(*p_acl); - *p_acl = posix_acl_dup(acl); + switch(type) { + case ACL_TYPE_ACCESS: + if (ei->i_acl != EXT2_ACL_NOT_CACHED) + posix_acl_release(ei->i_acl); + ei->i_acl = posix_acl_dup(acl); + break; + + case ACL_TYPE_DEFAULT: + if (ei->i_default_acl != EXT2_ACL_NOT_CACHED) + posix_acl_release(ei->i_default_acl); + ei->i_default_acl = posix_acl_dup(acl); + break; + } } return error; } @@ -254,11 +270,13 @@ __ext2_permission(struct inode *inode, i if (current->fsuid == inode->i_uid) { mode >>= 6; } else if (test_opt(inode->i_sb, POSIX_ACL)) { - /* ACL can't contain additional permissions if - the ACL_MASK entry is 0 */ - if (!(mode & S_IRWXG)) + struct ext2_inode_info *ei = EXT2_I(inode); + + /* The access ACL cannot grant access if the group class + permission bits don't contain all requested permissions. */ + if (((mode >> 3) & mask & S_IRWXO) != mask) goto check_groups; - if (EXT2_I(inode)->i_acl == EXT2_ACL_NOT_CACHED) { + if (ei->i_acl == EXT2_ACL_NOT_CACHED) { struct posix_acl *acl; if (lock) { @@ -271,12 +289,11 @@ __ext2_permission(struct inode *inode, i if (IS_ERR(acl)) return PTR_ERR(acl); posix_acl_release(acl); - if (EXT2_I(inode)->i_acl == EXT2_ACL_NOT_CACHED) + if (ei->i_acl == EXT2_ACL_NOT_CACHED) return -EIO; } - if (EXT2_I(inode)->i_acl) { - int error = posix_acl_permission(inode, - EXT2_I(inode)->i_acl, mask); + if (ei->i_acl) { + int error = posix_acl_permission(inode, ei->i_acl,mask); if (error == -EACCES) goto check_capabilities; return error; diff -puN fs/ext2/xattr.c~xattr-cleanup fs/ext2/xattr.c --- 25/fs/ext2/xattr.c~xattr-cleanup 2003-07-02 16:35:37.000000000 -0700 +++ 25-akpm/fs/ext2/xattr.c 2003-07-02 16:35:37.000000000 -0700 @@ -1,7 +1,7 @@ /* * linux/fs/ext2/xattr.c * - * Copyright (C) 2001 by Andreas Gruenbacher, + * Copyright (C) 2001-2003 Andreas Gruenbacher * * Fix by Harrison Xing . * Extended attributes for symlinks and special files added per @@ -83,8 +83,9 @@ EXPORT_SYMBOL(ext2_xattr_set); } while (0) # define ea_bdebug(bh, f...) do { \ char b[BDEVNAME_SIZE]; \ - printk(KERN_DEBUG "block %s:%ld: ", \ - bdevname(bh->b_bdev, b), bh->b_blocknr); \ + printk(KERN_DEBUG "block %s:%lu: ", \ + bdevname(bh->b_bdev, b), \ + (unsigned long) bh->b_blocknr); \ printk(f); \ printk("\n"); \ } while (0) @@ -196,7 +197,6 @@ ext2_xattr_handler(int name_index) * Inode operation getxattr() * * dentry->d_inode->i_sem down - * BKL held [before 2.5.x] */ ssize_t ext2_getxattr(struct dentry *dentry, const char *name, @@ -215,7 +215,6 @@ ext2_getxattr(struct dentry *dentry, con * Inode operation listxattr() * * dentry->d_inode->i_sem down - * BKL held [before 2.5.x] */ ssize_t ext2_listxattr(struct dentry *dentry, char *buffer, size_t size) @@ -227,7 +226,6 @@ ext2_listxattr(struct dentry *dentry, ch * Inode operation setxattr() * * dentry->d_inode->i_sem down - * BKL held [before 2.5.x] */ int ext2_setxattr(struct dentry *dentry, const char *name, @@ -248,7 +246,6 @@ ext2_setxattr(struct dentry *dentry, con * Inode operation removexattr() * * dentry->d_inode->i_sem down - * BKL held [before 2.5.x] */ int ext2_removexattr(struct dentry *dentry, const char *name) @@ -278,9 +275,9 @@ ext2_xattr_get(struct inode *inode, int { struct buffer_head *bh = NULL; struct ext2_xattr_entry *entry; - unsigned int size; + size_t name_len, size; char *end; - int name_len, error; + int error; ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld", name_index, name, buffer, (long)buffer_size); @@ -376,7 +373,7 @@ ext2_xattr_list(struct inode *inode, cha { struct buffer_head *bh = NULL; struct ext2_xattr_entry *entry; - unsigned int size = 0; + size_t size = 0; char *buf, *end; int error; @@ -482,8 +479,8 @@ ext2_xattr_set(struct inode *inode, int struct buffer_head *bh = NULL; struct ext2_xattr_header *header = NULL; struct ext2_xattr_entry *here, *last; - unsigned int name_len; - int min_offs = sb->s_blocksize, not_found = 1, free, error; + size_t name_len, free, min_offs = sb->s_blocksize; + int not_found = 1, error; char *end; /* @@ -540,7 +537,7 @@ bad_block: ext2_error(sb, "ext2_xattr_s if ((char *)next >= end) goto bad_block; if (!here->e_value_block && here->e_value_size) { - int offs = le16_to_cpu(here->e_value_offs); + size_t offs = le16_to_cpu(here->e_value_offs); if (offs < min_offs) min_offs = offs; } @@ -560,7 +557,7 @@ bad_block: ext2_error(sb, "ext2_xattr_s if ((char *)next >= end) goto bad_block; if (!last->e_value_block && last->e_value_size) { - int offs = le16_to_cpu(last->e_value_offs); + size_t offs = le16_to_cpu(last->e_value_offs); if (offs < min_offs) min_offs = offs; } @@ -584,25 +581,23 @@ bad_block: ext2_error(sb, "ext2_xattr_s error = 0; if (value == NULL) goto cleanup; - else - free -= EXT2_XATTR_LEN(name_len); } else { /* Request to create an existing attribute? */ error = -EEXIST; if (flags & XATTR_CREATE) goto cleanup; if (!here->e_value_block && here->e_value_size) { - unsigned int size = le32_to_cpu(here->e_value_size); + size_t size = le32_to_cpu(here->e_value_size); if (le16_to_cpu(here->e_value_offs) + size > sb->s_blocksize || size > sb->s_blocksize) goto bad_block; free += EXT2_XATTR_SIZE(size); } + free += EXT2_XATTR_LEN(name_len); } - free -= EXT2_XATTR_SIZE(value_len); error = -ENOSPC; - if (free < 0) + if (free < EXT2_XATTR_LEN(name_len) + EXT2_XATTR_SIZE(value_len)) goto cleanup; /* Here we know that we can set the new attribute. */ @@ -640,8 +635,8 @@ bad_block: ext2_error(sb, "ext2_xattr_s if (not_found) { /* Insert the new name. */ - int size = EXT2_XATTR_LEN(name_len); - int rest = (char *)last - (char *)here; + size_t size = EXT2_XATTR_LEN(name_len); + size_t rest = (char *)last - (char *)here; memmove((char *)here + size, here, rest); memset(here, 0, size); here->e_name_index = name_index; @@ -651,7 +646,7 @@ bad_block: ext2_error(sb, "ext2_xattr_s /* Remove the old value. */ if (!here->e_value_block && here->e_value_size) { char *first_val = (char *)header + min_offs; - int offs = le16_to_cpu(here->e_value_offs); + size_t offs = le16_to_cpu(here->e_value_offs); char *val = (char *)header + offs; size_t size = EXT2_XATTR_SIZE( le32_to_cpu(here->e_value_size)); @@ -663,7 +658,7 @@ bad_block: ext2_error(sb, "ext2_xattr_s /* Adjust all value offsets. */ last = ENTRY(header+1); while (!IS_LAST_ENTRY(last)) { - int o = le16_to_cpu(last->e_value_offs); + size_t o = le16_to_cpu(last->e_value_offs); if (!last->e_value_block && o < offs) last->e_value_offs = cpu_to_le16(o + size); @@ -678,7 +673,7 @@ bad_block: ext2_error(sb, "ext2_xattr_s goto cleanup; } else { /* Remove the old name. */ - int size = EXT2_XATTR_LEN(name_len); + size_t size = EXT2_XATTR_LEN(name_len); last = ENTRY((char *)last - size); memmove(here, (char*)here + size, (char*)last - (char*)here); @@ -732,9 +727,9 @@ ext2_xattr_set2(struct inode *inode, str * The old block will be released after updating * the inode. */ - ea_bdebug(new_bh, "%s block %ld", + ea_bdebug(new_bh, "%s block %lu", (old_bh == new_bh) ? "keeping" : "reusing", - new_bh->b_blocknr); + (unsigned long) new_bh->b_blocknr); error = -EDQUOT; if (DQUOT_ALLOC_BLOCK(inode, 1)) @@ -751,8 +746,10 @@ ext2_xattr_set2(struct inode *inode, str ext2_xattr_cache_insert(new_bh); } else { /* We need to allocate a new block */ - int goal = le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block) + - EXT2_I(inode)->i_block_group * EXT2_BLOCKS_PER_GROUP(sb); + int goal = le32_to_cpu(EXT2_SB(sb)->s_es-> + s_first_data_block) + + EXT2_I(inode)->i_block_group * + EXT2_BLOCKS_PER_GROUP(sb); int block = ext2_new_block(inode, goal, 0, 0, &error); if (error) goto cleanup; @@ -857,8 +854,8 @@ ext2_xattr_delete_inode(struct inode *in if (HDR(bh)->h_refcount == cpu_to_le32(1)) { ext2_xattr_cache_remove(bh); ext2_free_blocks(inode, EXT2_I(inode)->i_file_acl, 1); + get_bh(bh); bforget(bh); - bh = NULL; } else { HDR(bh)->h_refcount = cpu_to_le32( le32_to_cpu(HDR(bh)->h_refcount) - 1); diff -puN fs/ext3/acl.c~xattr-cleanup fs/ext3/acl.c --- 25/fs/ext3/acl.c~xattr-cleanup 2003-07-02 16:35:37.000000000 -0700 +++ 25-akpm/fs/ext3/acl.c 2003-07-02 16:35:37.000000000 -0700 @@ -1,7 +1,7 @@ /* * linux/fs/ext3/acl.c * - * Copyright (C) 2001 by Andreas Gruenbacher, + * Copyright (C) 2001-2003 Andreas Gruenbacher, */ #include @@ -20,7 +20,7 @@ static struct posix_acl * ext3_acl_from_disk(const void *value, size_t size) { const char *end = (char *)value + size; - int n, count; + size_t n, count; struct posix_acl *acl; if (!value) @@ -86,7 +86,7 @@ ext3_acl_to_disk(const struct posix_acl { ext3_acl_header *ext_acl; char *e; - int n; + size_t n; *size = ext3_acl_size(acl->a_count); ext_acl = (ext3_acl_header *)kmalloc(sizeof(ext3_acl_header) + @@ -133,10 +133,11 @@ fail: static struct posix_acl * ext3_get_acl(struct inode *inode, int type) { + const size_t max_size = ext3_acl_size(EXT3_ACL_MAX_ENTRIES); + struct ext3_inode_info *ei = EXT3_I(inode); int name_index; char *value; - struct posix_acl *acl, **p_acl; - const size_t size = ext3_acl_size(EXT3_ACL_MAX_ENTRIES); + struct posix_acl *acl; int retval; if (!test_opt(inode->i_sb, POSIX_ACL)) @@ -144,36 +145,43 @@ ext3_get_acl(struct inode *inode, int ty switch(type) { case ACL_TYPE_ACCESS: - p_acl = &EXT3_I(inode)->i_acl; + if (ei->i_acl != EXT3_ACL_NOT_CACHED) + return posix_acl_dup(ei->i_acl); name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS; break; case ACL_TYPE_DEFAULT: - p_acl = &EXT3_I(inode)->i_default_acl; + if (ei->i_default_acl != EXT3_ACL_NOT_CACHED) + return posix_acl_dup(ei->i_default_acl); name_index = EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT; break; default: return ERR_PTR(-EINVAL); } - if (*p_acl != EXT3_ACL_NOT_CACHED) - return posix_acl_dup(*p_acl); - value = kmalloc(size, GFP_KERNEL); + value = kmalloc(max_size, GFP_KERNEL); if (!value) return ERR_PTR(-ENOMEM); - retval = ext3_xattr_get(inode, name_index, "", value, size); - - if (retval == -ENODATA || retval == -ENOSYS) - *p_acl = acl = NULL; - else if (retval < 0) - acl = ERR_PTR(retval); - else { + retval = ext3_xattr_get(inode, name_index, "", value, max_size); + acl = ERR_PTR(retval); + if (retval > 0) acl = ext3_acl_from_disk(value, retval); - if (!IS_ERR(acl)) - *p_acl = posix_acl_dup(acl); - } + else if (retval == -ENODATA || retval == -ENOSYS) + acl = NULL; kfree(value); + + if (!IS_ERR(acl)) { + switch(type) { + case ACL_TYPE_ACCESS: + ei->i_acl = posix_acl_dup(acl); + break; + + case ACL_TYPE_DEFAULT: + ei->i_default_acl = posix_acl_dup(acl); + break; + } + } return acl; } @@ -186,9 +194,9 @@ static int ext3_set_acl(handle_t *handle, struct inode *inode, int type, struct posix_acl *acl) { + struct ext3_inode_info *ei = EXT3_I(inode); int name_index; void *value = NULL; - struct posix_acl **p_acl; size_t size; int error; @@ -198,7 +206,6 @@ ext3_set_acl(handle_t *handle, struct in switch(type) { case ACL_TYPE_ACCESS: name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS; - p_acl = &EXT3_I(inode)->i_acl; if (acl) { mode_t mode = inode->i_mode; error = posix_acl_equiv_mode(acl, &mode); @@ -215,7 +222,6 @@ ext3_set_acl(handle_t *handle, struct in case ACL_TYPE_DEFAULT: name_index = EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT; - p_acl = &EXT3_I(inode)->i_default_acl; if (!S_ISDIR(inode->i_mode)) return acl ? -EACCES : 0; break; @@ -231,14 +237,25 @@ ext3_set_acl(handle_t *handle, struct in return (int)PTR_ERR(value); } - error = ext3_xattr_set_handle(handle, inode, name_index, "", value, size, 0); + error = ext3_xattr_set_handle(handle, inode, name_index, "", + value, size, 0); if (value) kfree(value); if (!error) { - if (*p_acl && *p_acl != EXT3_ACL_NOT_CACHED) - posix_acl_release(*p_acl); - *p_acl = posix_acl_dup(acl); + switch(type) { + case ACL_TYPE_ACCESS: + if (ei->i_acl != EXT3_ACL_NOT_CACHED) + posix_acl_release(ei->i_acl); + ei->i_acl = posix_acl_dup(acl); + break; + + case ACL_TYPE_DEFAULT: + if (ei->i_default_acl != EXT3_ACL_NOT_CACHED) + posix_acl_release(ei->i_default_acl); + ei->i_default_acl = posix_acl_dup(acl); + break; + } } return error; } @@ -258,11 +275,13 @@ __ext3_permission(struct inode *inode, i if (current->fsuid == inode->i_uid) { mode >>= 6; } else if (test_opt(inode->i_sb, POSIX_ACL)) { - /* ACL can't contain additional permissions if - the ACL_MASK entry is 0 */ - if (!(mode & S_IRWXG)) + struct ext3_inode_info *ei = EXT3_I(inode); + + /* The access ACL cannot grant access if the group class + permission bits don't contain all requested permissions. */ + if (((mode >> 3) & mask & S_IRWXO) != mask) goto check_groups; - if (EXT3_I(inode)->i_acl == EXT3_ACL_NOT_CACHED) { + if (ei->i_acl == EXT3_ACL_NOT_CACHED) { struct posix_acl *acl; if (lock) { @@ -275,12 +294,11 @@ __ext3_permission(struct inode *inode, i if (IS_ERR(acl)) return PTR_ERR(acl); posix_acl_release(acl); - if (EXT3_I(inode)->i_acl == EXT3_ACL_NOT_CACHED) + if (ei->i_acl == EXT3_ACL_NOT_CACHED) return -EIO; } - if (EXT3_I(inode)->i_acl) { - int error = posix_acl_permission(inode, - EXT3_I(inode)->i_acl, mask); + if (ei->i_acl) { + int error = posix_acl_permission(inode, ei->i_acl,mask); if (error == -EACCES) goto check_capabilities; return error; diff -puN fs/ext3/xattr.c~xattr-cleanup fs/ext3/xattr.c --- 25/fs/ext3/xattr.c~xattr-cleanup 2003-07-02 16:35:37.000000000 -0700 +++ 25-akpm/fs/ext3/xattr.c 2003-07-02 16:35:37.000000000 -0700 @@ -1,7 +1,7 @@ /* * linux/fs/ext3/xattr.c * - * Copyright (C) 2001 by Andreas Gruenbacher, + * Copyright (C) 2001-2003 Andreas Gruenbacher, * * Fix by Harrison Xing . * Ext3 code with a lot of help from Eric Jarman . @@ -63,8 +63,6 @@ #include "xattr.h" #include "acl.h" -#define EXT3_EA_USER "user." - #define HDR(bh) ((struct ext3_xattr_header *)((bh)->b_data)) #define ENTRY(ptr) ((struct ext3_xattr_entry *)(ptr)) #define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1) @@ -79,8 +77,9 @@ } while (0) # define ea_bdebug(bh, f...) do { \ char b[BDEVNAME_SIZE]; \ - printk(KERN_DEBUG "block %s:%ld: ", \ - bdevname(bh->b_bdev, b), bh->b_blocknr); \ + printk(KERN_DEBUG "block %s:%lu: ", \ + bdevname(bh->b_bdev, b), \ + (unsigned long) bh->b_blocknr); \ printk(f); \ printk("\n"); \ } while (0) @@ -271,9 +270,9 @@ ext3_xattr_get(struct inode *inode, int { struct buffer_head *bh = NULL; struct ext3_xattr_entry *entry; - unsigned int size; + size_t name_len, size; char *end; - int name_len, error; + int error; ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld", name_index, name, buffer, (long)buffer_size); @@ -369,7 +368,7 @@ ext3_xattr_list(struct inode *inode, cha { struct buffer_head *bh = NULL; struct ext3_xattr_entry *entry; - unsigned int size = 0; + size_t size = 0; char *buf, *end; int error; @@ -478,8 +477,8 @@ ext3_xattr_set_handle(handle_t *handle, struct buffer_head *bh = NULL; struct ext3_xattr_header *header = NULL; struct ext3_xattr_entry *here, *last; - unsigned int name_len; - int min_offs = sb->s_blocksize, not_found = 1, free, error; + size_t name_len, free, min_offs = sb->s_blocksize; + int not_found = 1, error; char *end; /* @@ -536,7 +535,7 @@ bad_block: ext3_error(sb, "ext3_xattr_s if ((char *)next >= end) goto bad_block; if (!here->e_value_block && here->e_value_size) { - int offs = le16_to_cpu(here->e_value_offs); + size_t offs = le16_to_cpu(here->e_value_offs); if (offs < min_offs) min_offs = offs; } @@ -556,7 +555,7 @@ bad_block: ext3_error(sb, "ext3_xattr_s if ((char *)next >= end) goto bad_block; if (!last->e_value_block && last->e_value_size) { - int offs = le16_to_cpu(last->e_value_offs); + size_t offs = le16_to_cpu(last->e_value_offs); if (offs < min_offs) min_offs = offs; } @@ -580,25 +579,23 @@ bad_block: ext3_error(sb, "ext3_xattr_s error = 0; if (value == NULL) goto cleanup; - else - free -= EXT3_XATTR_LEN(name_len); } else { /* Request to create an existing attribute? */ error = -EEXIST; if (flags & XATTR_CREATE) goto cleanup; if (!here->e_value_block && here->e_value_size) { - unsigned int size = le32_to_cpu(here->e_value_size); + size_t size = le32_to_cpu(here->e_value_size); if (le16_to_cpu(here->e_value_offs) + size > sb->s_blocksize || size > sb->s_blocksize) goto bad_block; free += EXT3_XATTR_SIZE(size); } + free += EXT3_XATTR_LEN(name_len); } - free -= EXT3_XATTR_SIZE(value_len); error = -ENOSPC; - if (free < 0) + if (free < EXT3_XATTR_LEN(name_len) + EXT3_XATTR_SIZE(value_len)) goto cleanup; /* Here we know that we can set the new attribute. */ @@ -639,8 +636,8 @@ bad_block: ext3_error(sb, "ext3_xattr_s if (not_found) { /* Insert the new name. */ - int size = EXT3_XATTR_LEN(name_len); - int rest = (char *)last - (char *)here; + size_t size = EXT3_XATTR_LEN(name_len); + size_t rest = (char *)last - (char *)here; memmove((char *)here + size, here, rest); memset(here, 0, size); here->e_name_index = name_index; @@ -650,7 +647,7 @@ bad_block: ext3_error(sb, "ext3_xattr_s /* Remove the old value. */ if (!here->e_value_block && here->e_value_size) { char *first_val = (char *)header + min_offs; - int offs = le16_to_cpu(here->e_value_offs); + size_t offs = le16_to_cpu(here->e_value_offs); char *val = (char *)header + offs; size_t size = EXT3_XATTR_SIZE( le32_to_cpu(here->e_value_size)); @@ -662,7 +659,7 @@ bad_block: ext3_error(sb, "ext3_xattr_s /* Adjust all value offsets. */ last = ENTRY(header+1); while (!IS_LAST_ENTRY(last)) { - int o = le16_to_cpu(last->e_value_offs); + size_t o = le16_to_cpu(last->e_value_offs); if (!last->e_value_block && o < offs) last->e_value_offs = cpu_to_le16(o + size); @@ -678,7 +675,7 @@ bad_block: ext3_error(sb, "ext3_xattr_s goto cleanup; } else { /* Remove the old name. */ - int size = EXT3_XATTR_LEN(name_len); + size_t size = EXT3_XATTR_LEN(name_len); last = ENTRY((char *)last - size); memmove(here, (char*)here + size, (char*)last - (char*)here); @@ -733,9 +730,9 @@ ext3_xattr_set_handle2(handle_t *handle, * The old block will be released after updating * the inode. */ - ea_bdebug(new_bh, "%s block %ld", + ea_bdebug(new_bh, "%s block %lu", (old_bh == new_bh) ? "keeping" : "reusing", - new_bh->b_blocknr); + (unsigned long) new_bh->b_blocknr); error = -EDQUOT; if (DQUOT_ALLOC_BLOCK(inode, 1)) @@ -759,7 +756,7 @@ ext3_xattr_set_handle2(handle_t *handle, EXT3_SB(sb)->s_es->s_first_data_block) + EXT3_I(inode)->i_block_group * EXT3_BLOCKS_PER_GROUP(sb); - int block = ext3_new_block(handle, + int block = ext3_new_block(handle, inode, goal, 0, 0, &error); if (error) goto cleanup; @@ -895,8 +892,8 @@ ext3_xattr_delete_inode(handle_t *handle if (HDR(bh)->h_refcount == cpu_to_le32(1)) { ext3_xattr_cache_remove(bh); ext3_free_blocks(handle, inode, EXT3_I(inode)->i_file_acl, 1); + get_bh(bh); ext3_forget(handle, 1, inode, bh, EXT3_I(inode)->i_file_acl); - bh = NULL; } else { HDR(bh)->h_refcount = cpu_to_le32( le32_to_cpu(HDR(bh)->h_refcount) - 1); _