Index: linux-2.4.24/fs/ext3/extents-in-ea.c =================================================================== --- linux-2.4.24.orig/fs/ext3/extents-in-ea.c 2004-08-10 16:13:06.000000000 +0400 +++ linux-2.4.24/fs/ext3/extents-in-ea.c 2004-08-10 16:18:18.000000000 +0400 @@ -222,3 +222,112 @@ return err; } +static int +ext3_ext_store_extent_cb(struct ext3_extents_tree *tree, + struct ext3_ext_path *path, + struct ext3_extent *newex, int exist) +{ + struct ext3_extent_buf *buf = (struct ext3_extent_buf *) tree->private; + + if (!exist) + return EXT_CONTINUE; + if (buf->err < 0) + return EXT_BREAK; + if (buf->cur - buf->buffer + sizeof(*newex) > buf->buflen) + return EXT_BREAK; + + if (!copy_to_user(buf->cur, newex, sizeof(*newex))) { + buf->err++; + buf->cur += sizeof(*newex); + } else { + buf->err = -EFAULT; + return EXT_BREAK; + } + return EXT_CONTINUE; +} + +static int +ext3_ext_collect_stats_cb(struct ext3_extents_tree *tree, + struct ext3_ext_path *path, + struct ext3_extent *ex, int exist) +{ + struct ext3_extent_tree_stats *buf = + (struct ext3_extent_tree_stats *) tree->private; + int depth; + + if (!exist) + return EXT_CONTINUE; + + depth = EXT_DEPTH(tree); + buf->extents_num++; + if (path[depth].p_ext == EXT_FIRST_EXTENT(path[depth].p_hdr)) + buf->leaf_num++; + return EXT_CONTINUE; +} + +struct ea_tree_desc { + int name_index; + char eaname[256]; +}; + +int ext3_ext_in_ea_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + int err = 0; + + if (cmd == EXT3_IOC_EA_TREE_INIT) { + struct ea_tree_desc desc; + + if (copy_from_user(&desc, (void *) arg, sizeof(desc))) + return -EFAULT; + err = ext3_init_tree_in_ea(inode, desc.name_index, + desc.eaname, 64); + } else if (cmd == EXT3_IOC_GET_EA_EXTENTS) { + struct ext3_extents_tree tree; + struct ext3_extent_buf buf; + struct ea_tree_desc desc; + + if (copy_from_user(&buf, (void *) arg, sizeof(buf))) + return -EFAULT; + if (copy_from_user(&desc, buf.cur, sizeof(desc))) + return -EFAULT; + err = ext3_init_tree_in_ea_desc(&tree, inode, + desc.name_index, desc.eaname); + if (err) + goto out; + buf.cur = buf.buffer; + buf.err = 0; + tree.private = &buf; + err = ext3_ext_walk_space(&tree, buf.start, EXT_MAX_BLOCK, + ext3_ext_store_extent_cb); + if (err == 0) + err = buf.err; + ext3_release_tree_in_ea_desc(&tree); + } else if (cmd == EXT3_IOC_EA_TREE_ALLOCATE) { + struct ext3_extent_buf buf; + struct ea_tree_desc desc; + + if (copy_from_user(&buf, (void *) arg, sizeof(buf))) + return -EFAULT; + if (copy_from_user(&desc, buf.cur, sizeof(desc))) + return -EFAULT; + err = ext3_ext_in_ea_alloc_space(inode, desc.name_index, + desc.eaname, buf.start, + buf.err); + } else if (cmd == EXT3_IOC_EA_TREE_REMOVE) { + struct ext3_extent_buf buf; + struct ea_tree_desc desc; + + if (copy_from_user(&buf, (void *) arg, sizeof(buf))) + return -EFAULT; + if (copy_from_user(&desc, buf.cur, sizeof(desc))) + return -EFAULT; + err = ext3_ext_in_ea_remove_space(inode, desc.name_index, + desc.eaname, buf.start, + buf.err); + } + +out: + return err; +} + Index: linux-2.4.24/fs/ext3/ioctl.c =================================================================== --- linux-2.4.24.orig/fs/ext3/ioctl.c 2004-08-10 16:09:22.000000000 +0400 +++ linux-2.4.24/fs/ext3/ioctl.c 2004-08-10 16:14:40.000000000 +0400 @@ -178,6 +178,13 @@ case EXT3_IOC_GET_TREE_STATS: case EXT3_IOC_GET_TREE_DEPTH: return ext3_ext_ioctl(inode, filp, cmd, arg); + case EXT3_IOC_GET_EA_EXTENTS: + case EXT3_IOC_GET_EA_TREE_DEPTH: + case EXT3_IOC_GET_EA_TREE_STATS: + case EXT3_IOC_EA_TREE_INIT: + case EXT3_IOC_EA_TREE_ALLOCATE: + case EXT3_IOC_EA_TREE_REMOVE: + return ext3_ext_in_ea_ioctl(inode, filp, cmd, arg); default: return -ENOTTY; } Index: linux-2.4.24/include/linux/ext3_fs.h =================================================================== --- linux-2.4.24.orig/include/linux/ext3_fs.h 2004-08-10 16:09:22.000000000 +0400 +++ linux-2.4.24/include/linux/ext3_fs.h 2004-08-10 16:14:40.000000000 +0400 @@ -214,6 +214,14 @@ #define EXT3_IOC_GET_TREE_DEPTH _IOR('f', 6, long) #define EXT3_IOC_GET_TREE_STATS _IOR('f', 7, long) +#define EXT3_IOC_GET_EA_EXTENTS _IOR('f', 10, long) +#define EXT3_IOC_GET_EA_TREE_DEPTH _IOR('f', 11, long) +#define EXT3_IOC_GET_EA_TREE_STATS _IOR('f', 12, long) +#define EXT3_IOC_EA_TREE_INIT _IOW('f', 13, long) +#define EXT3_IOC_EA_TREE_ALLOCATE _IOW('f', 14, long) +#define EXT3_IOC_EA_TREE_REMOVE _IOW('f', 15, long) + + /* * Structure of an inode on the disk */