aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@suse.de>2005-01-14 23:35:23 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-14 23:35:23 -0800
commitbe51a1d918683d3ec3ccdd18ad29637bfa304a23 (patch)
tree986d3acf9435eff500c22a8f1c0e1ee19d56f251 /fs
parent12b29a3a9bcfad4e245f4cf3bbc4812641ecc1ea (diff)
downloadhistory-be51a1d918683d3ec3ccdd18ad29637bfa304a23.tar.gz
[PATCH] ext3/ea: revert old ea-in-inode patch
Revert the recently-added (post-2.6.10) ea-in-inode speedup patch. We have a new one. Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/ext3/ialloc.c5
-rw-r--r--fs/ext3/inode.c10
-rw-r--r--fs/ext3/xattr.c683
-rw-r--r--fs/ext3/xattr.h9
4 files changed, 67 insertions, 640 deletions
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
index 54e43497235f57..5a6a65fd318242 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -596,11 +596,6 @@ got:
spin_unlock(&sbi->s_next_gen_lock);
ei->i_state = EXT3_STATE_NEW;
- if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) {
- ei->i_extra_isize = sizeof(__u16) /* i_extra_isize */
- + sizeof(__u16); /* i_pad1 */
- } else
- ei->i_extra_isize = 0;
ret = inode;
if(DQUOT_ALLOC_INODE(inode)) {
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 0a92408946a9cb..9a3495afc8497b 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -2277,7 +2277,7 @@ static unsigned long ext3_get_inode_block(struct super_block *sb,
* trying to determine the inode's location on-disk and no read need be
* performed.
*/
-int ext3_get_inode_loc(struct inode *inode,
+static int ext3_get_inode_loc(struct inode *inode,
struct ext3_iloc *iloc, int in_mem)
{
unsigned long block;
@@ -2485,11 +2485,6 @@ void ext3_read_inode(struct inode * inode)
ei->i_data[block] = raw_inode->i_block[block];
INIT_LIST_HEAD(&ei->i_orphan);
- if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE)
- ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize);
- else
- ei->i_extra_isize = 0;
-
if (S_ISREG(inode->i_mode)) {
inode->i_op = &ext3_file_inode_operations;
inode->i_fop = &ext3_file_operations;
@@ -2625,9 +2620,6 @@ static int ext3_do_update_inode(handle_t *handle,
} else for (block = 0; block < EXT3_N_BLOCKS; block++)
raw_inode->i_block[block] = ei->i_data[block];
- if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE)
- raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize);
-
BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
rc = ext3_journal_dirty_metadata(handle, bh);
if (!err)
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index 31ef0eef09a3c1..532908a40ad1d8 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -9,7 +9,6 @@
* suggestion of Luka Renko <luka.renko@hermes.si>.
* xattr consolidation Copyright (c) 2004 James Morris <jmorris@redhat.com>,
* Red Hat Inc.
- * ea-in-inode support by Alex Tomas <alex@clusterfs.com> aka bzzz
*/
/*
@@ -90,9 +89,10 @@
# define ea_bdebug(f...)
#endif
-static int ext3_xattr_set_handle2(handle_t *handle, struct inode *inode,
- struct buffer_head *old_bh,
- struct ext3_xattr_header *header);
+static int ext3_xattr_set_handle2(handle_t *, struct inode *,
+ struct buffer_head *,
+ struct ext3_xattr_header *);
+
static int ext3_xattr_cache_insert(struct buffer_head *);
static struct buffer_head *ext3_xattr_cache_find(handle_t *, struct inode *,
struct ext3_xattr_header *,
@@ -139,12 +139,28 @@ ext3_xattr_handler(int name_index)
}
/*
- * ext3_xattr_block_get()
+ * Inode operation listxattr()
*
- * routine looks for attribute in EA block and returns it's value and size
+ * dentry->d_inode->i_sem: don't care
*/
-static int
-ext3_xattr_block_get(struct inode *inode, int name_index, const char *name,
+ssize_t
+ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
+{
+ return ext3_xattr_list(dentry->d_inode, buffer, size);
+}
+
+/*
+ * ext3_xattr_get()
+ *
+ * Copy an extended attribute into the buffer
+ * provided, or compute the buffer size required.
+ * Buffer is NULL to compute the size of the buffer required.
+ *
+ * Returns a negative error number on failure, or the number of bytes
+ * used / required on success.
+ */
+int
+ext3_xattr_get(struct inode *inode, int name_index, const char *name,
void *buffer, size_t buffer_size)
{
struct buffer_head *bh = NULL;
@@ -158,6 +174,7 @@ ext3_xattr_block_get(struct inode *inode, int name_index, const char *name,
if (name == NULL)
return -EINVAL;
+ down_read(&EXT3_I(inode)->xattr_sem);
error = -ENODATA;
if (!EXT3_I(inode)->i_file_acl)
goto cleanup;
@@ -230,87 +247,15 @@ found:
cleanup:
brelse(bh);
+ up_read(&EXT3_I(inode)->xattr_sem);
return error;
}
/*
- * ext3_xattr_ibody_get()
- *
- * routine looks for attribute in inode body and returns it's value and size
- */
-static int
-ext3_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
- void *buffer, size_t buffer_size)
-{
- int size, name_len = strlen(name), storage_size;
- struct ext3_xattr_entry *last;
- struct ext3_inode *raw_inode;
- struct ext3_iloc iloc;
- char *start, *end;
- int ret = -ENOENT;
-
- if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
- return -ENOENT;
-
- ret = ext3_get_inode_loc(inode, &iloc, 1);
- if (ret)
- return ret;
- raw_inode = ext3_raw_inode(&iloc);
-
- storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
- EXT3_GOOD_OLD_INODE_SIZE -
- EXT3_I(inode)->i_extra_isize -
- sizeof(__u32);
- start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
- EXT3_I(inode)->i_extra_isize;
- if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) {
- brelse(iloc.bh);
- return -ENOENT;
- }
- start += sizeof(__u32);
- end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
-
- last = (struct ext3_xattr_entry *) start;
- while (!IS_LAST_ENTRY(last)) {
- struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
- if (le32_to_cpu(last->e_value_size) > storage_size ||
- (char *) next >= end) {
- ext3_error(inode->i_sb, "ext3_xattr_ibody_get",
- "inode %ld", inode->i_ino);
- brelse(iloc.bh);
- return -EIO;
- }
- if (name_index == last->e_name_index &&
- name_len == last->e_name_len &&
- !memcmp(name, last->e_name, name_len))
- goto found;
- last = next;
- }
-
- /* can't find EA */
- brelse(iloc.bh);
- return -ENOENT;
-
-found:
- size = le32_to_cpu(last->e_value_size);
- if (buffer) {
- ret = -ERANGE;
- if (buffer_size >= size) {
- memcpy(buffer, start + le16_to_cpu(last->e_value_offs),
- size);
- ret = size;
- }
- } else
- ret = size;
- brelse(iloc.bh);
- return ret;
-}
-
-/*
- * ext3_xattr_get()
+ * ext3_xattr_list()
*
- * Copy an extended attribute into the buffer
+ * Copy a list of attribute names into the buffer
* provided, or compute the buffer size required.
* Buffer is NULL to compute the size of the buffer required.
*
@@ -318,31 +263,7 @@ found:
* used / required on success.
*/
int
-ext3_xattr_get(struct inode *inode, int name_index, const char *name,
- void *buffer, size_t buffer_size)
-{
- int err;
-
- down_read(&EXT3_I(inode)->xattr_sem);
-
- /* try to find attribute in inode body */
- err = ext3_xattr_ibody_get(inode, name_index, name,
- buffer, buffer_size);
- if (err < 0)
- /* search was unsuccessful, try to find EA in dedicated block */
- err = ext3_xattr_block_get(inode, name_index, name,
- buffer, buffer_size);
- up_read(&EXT3_I(inode)->xattr_sem);
-
- return err;
-}
-
-/* ext3_xattr_block_list()
- *
- * generate list of attributes stored in EA block
- */
-static int
-ext3_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size)
+ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
{
struct buffer_head *bh = NULL;
struct ext3_xattr_entry *entry;
@@ -353,6 +274,7 @@ ext3_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size)
ea_idebug(inode, "buffer=%p, buffer_size=%ld",
buffer, (long)buffer_size);
+ down_read(&EXT3_I(inode)->xattr_sem);
error = 0;
if (!EXT3_I(inode)->i_file_acl)
goto cleanup;
@@ -362,7 +284,7 @@ ext3_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size)
if (!bh)
goto cleanup;
ea_bdebug(bh, "b_count=%d, refcount=%d",
- (int) atomic_read(&(bh->b_count)), (int) le32_to_cpu(HDR(bh)->h_refcount));
+ atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
end = bh->b_data + bh->b_size;
if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
HDR(bh)->h_blocks != cpu_to_le32(1)) {
@@ -409,140 +331,9 @@ bad_block: ext3_error(inode->i_sb, "ext3_xattr_list",
cleanup:
brelse(bh);
-
- return error;
-}
-
-/* ext3_xattr_ibody_list()
- *
- * generate list of attributes stored in inode body
- */
-static int
-ext3_xattr_ibody_list(struct inode *inode, char *buffer, size_t buffer_size)
-{
- struct ext3_xattr_entry *last;
- struct ext3_inode *raw_inode;
- size_t rest = buffer_size;
- struct ext3_iloc iloc;
- char *start, *end;
- int storage_size;
- int size = 0;
- int ret;
-
- if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
- return 0;
-
- ret = ext3_get_inode_loc(inode, &iloc, 1);
- if (ret)
- return ret;
- raw_inode = ext3_raw_inode(&iloc);
-
- storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
- EXT3_GOOD_OLD_INODE_SIZE -
- EXT3_I(inode)->i_extra_isize -
- sizeof(__u32);
- start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
- EXT3_I(inode)->i_extra_isize;
- if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC)
- goto cleanup;
- start += sizeof(__u32);
- end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
-
- last = (struct ext3_xattr_entry *) start;
- while (!IS_LAST_ENTRY(last)) {
- struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
- if ((char *) next >= end) {
- ext3_error(inode->i_sb, "ext3_xattr_ibody_list",
- "inode %ld", inode->i_ino);
- ret = -EIO;
- goto cleanup;
- }
- last = next;
- }
-
- last = (struct ext3_xattr_entry *) start;
- for (; !IS_LAST_ENTRY(last); last = EXT3_XATTR_NEXT(last)) {
- struct xattr_handler *handler =
- ext3_xattr_handler(last->e_name_index);
-
- if (!handler)
- continue;
-
- size += handler->list(inode, buffer, rest, last->e_name,
- last->e_name_len);
- if (buffer) {
- if (size > rest) {
- ret = -ERANGE;
- goto cleanup;
- }
- buffer += size;
- }
- rest -= size;
- }
- ret = buffer_size - rest; /* total size */
-
-cleanup:
- brelse(iloc.bh);
- return ret;
-}
-
-/*
- * ext3_xattr_list()
- *
- * Copy a list of attribute names into the buffer
- * provided, or compute the buffer size required.
- * Buffer is NULL to compute the size of the buffer required.
- *
- * Returns a negative error number on failure, or the number of bytes
- * used / required on success.
- */
-static int
-ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
-{
- int size = buffer_size;
- int error;
-
- down_read(&EXT3_I(inode)->xattr_sem);
-
- /* get list of attributes stored in inode body */
- error = ext3_xattr_ibody_list(inode, buffer, buffer_size);
- if (error < 0) {
- /* some error occured while collecting
- * attributes in inode body */
- size = 0;
- goto cleanup;
- }
- size = error;
-
- /* get list of attributes stored in dedicated block */
- if (buffer) {
- buffer_size -= error;
- if (buffer_size <= 0) {
- buffer = NULL;
- buffer_size = 0;
- } else
- buffer += error;
- }
-
- error = ext3_xattr_block_list(inode, buffer, buffer_size);
- /* listing was successful, so we return len */
- if (error < 0)
- size = 0;
-
-cleanup:
up_read(&EXT3_I(inode)->xattr_sem);
- return error + size;
-}
-/*
- * Inode operation listxattr()
- *
- * dentry->d_inode->i_sem: don't care
- */
-ssize_t
-ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
-{
- return ext3_xattr_list(dentry->d_inode, buffer, size);
+ return error;
}
/*
@@ -566,292 +357,19 @@ static void ext3_xattr_update_super_block(handle_t *handle,
}
/*
- * ext3_xattr_ibody_find()
- *
- * search attribute and calculate free space in inode body
- * NOTE: free space includes space our attribute hold
- */
-static int
-ext3_xattr_ibody_find(struct inode *inode, int name_index,
- const char *name, int *free)
-{
- struct ext3_xattr_entry *last;
- struct ext3_inode *raw_inode;
- int name_len = strlen(name);
- int err, storage_size;
- struct ext3_iloc iloc;
- char *start, *end;
- int ret = -ENOENT;
-
- *free = 0;
- if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
- return ret;
-
- err = ext3_get_inode_loc(inode, &iloc, 1);
- if (err)
- return -EIO;
- raw_inode = ext3_raw_inode(&iloc);
-
- storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
- EXT3_GOOD_OLD_INODE_SIZE -
- EXT3_I(inode)->i_extra_isize -
- sizeof(__u32);
- *free = storage_size - sizeof(__u32);
- start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
- EXT3_I(inode)->i_extra_isize;
- if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) {
- brelse(iloc.bh);
- return -ENOENT;
- }
- start += sizeof(__u32);
- end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
-
- last = (struct ext3_xattr_entry *) start;
- while (!IS_LAST_ENTRY(last)) {
- struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
- if (le32_to_cpu(last->e_value_size) > storage_size ||
- (char *) next >= end) {
- ext3_error(inode->i_sb, "ext3_xattr_ibody_find",
- "inode %ld", inode->i_ino);
- brelse(iloc.bh);
- return -EIO;
- }
-
- if (name_index == last->e_name_index &&
- name_len == last->e_name_len &&
- !memcmp(name, last->e_name, name_len)) {
- ret = 0;
- } else {
- *free -= EXT3_XATTR_LEN(last->e_name_len);
- *free -= le32_to_cpu(last->e_value_size);
- }
- last = next;
- }
-
- brelse(iloc.bh);
- return ret;
-}
-
-/*
- * ext3_xattr_block_find()
- *
- * search attribute and calculate free space in EA block (if it allocated)
- * NOTE: free space includes space our attribute hold
- */
-static int
-ext3_xattr_block_find(struct inode *inode, int name_index,
- const char *name, int *free)
-{
- struct buffer_head *bh = NULL;
- struct ext3_xattr_entry *entry;
- char *end;
- int name_len, error = -ENOENT;
-
- if (!EXT3_I(inode)->i_file_acl) {
- *free = inode->i_sb->s_blocksize -
- sizeof(struct ext3_xattr_header) -
- sizeof(__u32);
- return -ENOENT;
- }
- ea_idebug(inode, "reading block %d", EXT3_I(inode)->i_file_acl);
- bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl);
- if (!bh)
- return -EIO;
- ea_bdebug(bh, "b_count=%d, refcount=%d",
- atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
- end = bh->b_data + bh->b_size;
- if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
- HDR(bh)->h_blocks != cpu_to_le32(1)) {
-bad_block: ext3_error(inode->i_sb, "ext3_xattr_get",
- "inode %ld: bad block %d", inode->i_ino,
- EXT3_I(inode)->i_file_acl);
- brelse(bh);
- return -EIO;
- }
- /* find named attribute */
- name_len = strlen(name);
- *free = bh->b_size - sizeof(__u32);
-
- entry = FIRST_ENTRY(bh);
- while (!IS_LAST_ENTRY(entry)) {
- struct ext3_xattr_entry *next =
- EXT3_XATTR_NEXT(entry);
- if ((char *)next >= end)
- goto bad_block;
- if (name_index == entry->e_name_index &&
- name_len == entry->e_name_len &&
- memcmp(name, entry->e_name, name_len) == 0) {
- error = 0;
- } else {
- *free -= EXT3_XATTR_LEN(entry->e_name_len);
- *free -= le32_to_cpu(entry->e_value_size);
- }
- entry = next;
- }
- brelse(bh);
-
- return error;
-}
-
-/*
- * ext3_xattr_ibody_set()
+ * ext3_xattr_set_handle()
*
- * this routine add/remove/replace attribute in inode body
- */
-static int
-ext3_xattr_ibody_set(handle_t *handle, struct inode *inode, int name_index,
- const char *name, const void *value, size_t value_len,
- int flags)
-{
- struct ext3_xattr_entry *last, *next, *here = NULL;
- struct ext3_inode *raw_inode;
- int name_len = strlen(name);
- int esize = EXT3_XATTR_LEN(name_len);
- struct buffer_head *bh;
- int err, storage_size;
- struct ext3_iloc iloc;
- int free, min_offs;
- char *start, *end;
-
- if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
- return -ENOSPC;
-
- err = ext3_get_inode_loc(inode, &iloc, 1);
- if (err)
- return err;
- raw_inode = ext3_raw_inode(&iloc);
- bh = iloc.bh;
-
- storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
- EXT3_GOOD_OLD_INODE_SIZE -
- EXT3_I(inode)->i_extra_isize -
- sizeof(__u32);
- start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
- EXT3_I(inode)->i_extra_isize;
- if ((*(__u32*) start) != EXT3_XATTR_MAGIC) {
- /* inode had no attributes before */
- *((__u32*) start) = cpu_to_le32(EXT3_XATTR_MAGIC);
- }
- start += sizeof(__u32);
- end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
- min_offs = storage_size;
- free = storage_size - sizeof(__u32);
-
- last = (struct ext3_xattr_entry *) start;
- while (!IS_LAST_ENTRY(last)) {
- next = EXT3_XATTR_NEXT(last);
- if (le32_to_cpu(last->e_value_size) > storage_size ||
- (char *) next >= end) {
- ext3_error(inode->i_sb, "ext3_xattr_ibody_set",
- "inode %ld", inode->i_ino);
- brelse(bh);
- return -EIO;
- }
-
- if (last->e_value_size) {
- int offs = le16_to_cpu(last->e_value_offs);
- if (offs < min_offs)
- min_offs = offs;
- }
- if (name_index == last->e_name_index &&
- name_len == last->e_name_len &&
- !memcmp(name, last->e_name, name_len))
- here = last;
- else {
- /* we calculate all but our attribute
- * because it will be removed before changing */
- free -= EXT3_XATTR_LEN(last->e_name_len);
- free -= le32_to_cpu(last->e_value_size);
- }
- last = next;
- }
-
- if (value && (esize + value_len > free)) {
- brelse(bh);
- return -ENOSPC;
- }
-
- err = ext3_reserve_inode_write(handle, inode, &iloc);
- if (err) {
- brelse(bh);
- return err;
- }
-
- /* optimization: can we simple replace old value ? */
- if (here && value_len == le32_to_cpu(here->e_value_size)) {
- int offs = le16_to_cpu(here->e_value_offs);
- memcpy(start + offs, value, value_len);
- goto done;
- }
-
- if (here) {
- /* time to remove old value */
- struct ext3_xattr_entry *e;
- int size = le32_to_cpu(here->e_value_size);
- int border = le16_to_cpu(here->e_value_offs);
- char *src;
-
- /* move tail */
- memmove(start + min_offs + size, start + min_offs,
- border - min_offs);
-
- /* recalculate offsets */
- e = (struct ext3_xattr_entry *) start;
- while (!IS_LAST_ENTRY(e)) {
- struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(e);
- int offs = le16_to_cpu(e->e_value_offs);
- if (offs < border)
- e->e_value_offs =
- cpu_to_le16(offs + size);
- e = next;
- }
- min_offs += size;
-
- /* remove entry */
- border = EXT3_XATTR_LEN(here->e_name_len);
- src = (char *) here + EXT3_XATTR_LEN(here->e_name_len);
- size = (char *) last - src;
- if ((char *) here + size > end)
- printk("ALERT at %s:%d: 0x%p + %d > 0x%p\n",
- __FILE__, __LINE__, here, size, end);
- memmove(here, src, size);
- last = (struct ext3_xattr_entry *) ((char *) last - border);
- *((__u32 *) last) = 0;
- }
-
- if (value) {
- int offs = min_offs - value_len;
- /* use last to create new entry */
- last->e_name_len = strlen(name);
- last->e_name_index = name_index;
- last->e_value_offs = cpu_to_le16(offs);
- last->e_value_size = cpu_to_le32(value_len);
- last->e_hash = last->e_value_block = 0;
- memset(last->e_name, 0, esize);
- memcpy(last->e_name, name, last->e_name_len);
- if (start + offs + value_len > end)
- printk("ALERT at %s:%d: 0x%p + %d + %zd > 0x%p\n",
- __FILE__, __LINE__, start, offs,
- value_len, end);
- memcpy(start + offs, value, value_len);
- last = EXT3_XATTR_NEXT(last);
- *((__u32 *) last) = 0;
- }
-
-done:
- ext3_mark_iloc_dirty(handle, inode, &iloc);
- brelse(bh);
-
- return 0;
-}
-
-/*
- * ext3_xattr_block_set()
+ * Create, replace or remove an extended attribute for this inode. Buffer
+ * is NULL to remove an existing extended attribute, and non-NULL to
+ * either replace an existing extended attribute, or create a new extended
+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
+ * specify that an extended attribute must exist and must not exist
+ * previous to the call, respectively.
*
- * this routine add/remove/replace attribute in EA block
+ * Returns 0, or a negative error number on failure.
*/
-static int
-ext3_xattr_block_set(handle_t *handle, struct inode *inode, int name_index,
+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)
{
@@ -874,7 +392,22 @@ ext3_xattr_block_set(handle_t *handle, struct inode *inode, int name_index,
* towards the end of the block).
* end -- Points right after the block pointed to by header.
*/
+
+ ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
+ name_index, name, value, (long)value_len);
+
+ if (IS_RDONLY(inode))
+ return -EROFS;
+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+ return -EPERM;
+ if (value == NULL)
+ value_len = 0;
+ if (name == NULL)
+ return -EINVAL;
name_len = strlen(name);
+ if (name_len > 255 || value_len > sb->s_blocksize)
+ return -ERANGE;
+ down_write(&EXT3_I(inode)->xattr_sem);
if (EXT3_I(inode)->i_file_acl) {
/* The inode already has an extended attribute block. */
bh = sb_bread(sb, EXT3_I(inode)->i_file_acl);
@@ -1100,112 +633,12 @@ cleanup:
brelse(bh);
if (!(bh && header == HDR(bh)))
kfree(header);
+ up_write(&EXT3_I(inode)->xattr_sem);
return error;
}
/*
- * ext3_xattr_set_handle()
- *
- * Create, replace or remove an extended attribute for this inode. Buffer
- * is NULL to remove an existing extended attribute, and non-NULL to
- * either replace an existing extended attribute, or create a new extended
- * attribute. The flags XATTR_REPLACE and XATTR_CREATE
- * specify that an extended attribute must exist and must not exist
- * previous to the call, respectively.
- *
- * Returns 0, or a negative error number on failure.
- */
-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 free1 = -1, free2 = -1;
- int err, where = 0, total;
- int name_len;
-
- ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
- name_index, name, value, (long)value_len);
-
- if (IS_RDONLY(inode))
- return -EROFS;
- if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
- return -EPERM;
- if (value == NULL)
- value_len = 0;
- if (name == NULL)
- return -EINVAL;
- name_len = strlen(name);
- if (name_len > 255 || value_len > inode->i_sb->s_blocksize)
- return -ERANGE;
- down_write(&EXT3_I(inode)->xattr_sem);
-
-#define EX_FOUND_IN_IBODY 1
-#define EX_FOUND_IN_BLOCK 2
-
- /* try to find attribute in inode body */
- err = ext3_xattr_ibody_find(inode, name_index, name, &free1);
- if (err == 0) {
- /* found EA in inode */
- where = EX_FOUND_IN_IBODY;
- } else if (err == -ENOENT) {
- /* there is no such attribute in inode body */
- /* try to find attribute in dedicated block */
- err = ext3_xattr_block_find(inode, name_index, name, &free2);
- if (err != 0 && err != -ENOENT) {
- /* not found EA in block */
- goto finish;
- } else if (err == 0) {
- /* found EA in block */
- where = EX_FOUND_IN_BLOCK;
- }
- } else
- goto finish;
-
- /* check flags: may replace? may create ? */
- if (where && (flags & XATTR_CREATE)) {
- err = -EEXIST;
- goto finish;
- } else if (!where && (flags & XATTR_REPLACE)) {
- err = -ENODATA;
- goto finish;
- }
-
- /* check if we have enough space to store attribute */
- total = EXT3_XATTR_LEN(strlen(name)) + value_len;
- if (total > free1 && free2 > 0 && total > free2) {
- /* have no enough space */
- err = -ENOSPC;
- goto finish;
- }
-
- /* there are two cases when we want to remove EA from original storage:
- * a) EA is stored in the inode, but new value doesn't fit
- * b) EA is stored in the block, but new value fit in inode
- */
- if (where == EX_FOUND_IN_IBODY && total > free1)
- ext3_xattr_ibody_set(handle, inode, name_index, name,
- NULL, 0, flags);
- else if (where == EX_FOUND_IN_BLOCK && total <= free1)
- ext3_xattr_block_set(handle, inode, name_index,
- name, NULL, 0, flags);
-
- /* try to store EA in inode body */
- err = ext3_xattr_ibody_set(handle, inode, name_index, name,
- value, value_len, flags);
- if (err) {
- /* can't store EA in inode body: try to store in block */
- err = ext3_xattr_block_set(handle, inode, name_index, name,
- value, value_len, flags);
- }
-
-finish:
- up_write(&EXT3_I(inode)->xattr_sem);
- return err;
-}
-
-/*
* Second half of ext3_xattr_set_handle(): Update the file system.
*/
static int
diff --git a/fs/ext3/xattr.h b/fs/ext3/xattr.h
index b2b25ad82451cb..6ca51c0e65fa00 100644
--- a/fs/ext3/xattr.h
+++ b/fs/ext3/xattr.h
@@ -65,8 +65,9 @@ extern struct xattr_handler ext3_xattr_security_handler;
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_handle(handle_t *, struct inode *, int, const char *, const void *, size_t, int);
extern void ext3_xattr_delete_inode(handle_t *, struct inode *);
extern void ext3_xattr_put_super(struct super_block *);
@@ -86,6 +87,12 @@ ext3_xattr_get(struct inode *inode, int name_index, const char *name,
}
static inline int
+ext3_xattr_list(struct inode *inode, void *buffer, size_t size)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int
ext3_xattr_set(struct inode *inode, int name_index, const char *name,
const void *value, size_t size, int flags)
{