From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: tytso@mit.edu, darrick.wong@oracle.com
Cc: linux-ext4@vger.kernel.org
Subject: [PATCH 01/32] libext2fs: support modifying arbitrary extended attributes (v5)
Date: Sat, 01 Mar 2014 23:16:45 -0800 [thread overview]
Message-ID: <20140302071645.28217.98125.stgit@birch.djwong.org> (raw)
In-Reply-To: <20140302071639.28217.57302.stgit@birch.djwong.org>
v5: Add magic number checking to the extended attribute editing
handle; move inline data to the head of the attribute list when
writing so that inline data ends up in the inode area; and always zero
the attribute space before writing to ensure that we can delete the
last xattr.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
debugfs/debugfs.c | 4 +++-
lib/ext2fs/ext2_err.et.in | 3 +++
lib/ext2fs/ext2fs.h | 2 +-
lib/ext2fs/ext_attr.c | 39 ++++++++++++++++++++++++++++++++++++---
4 files changed, 43 insertions(+), 5 deletions(-)
diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c
index a3fcbf4..aded072 100644
--- a/debugfs/debugfs.c
+++ b/debugfs/debugfs.c
@@ -561,6 +561,7 @@ static int dump_attr(char *name, char *value, size_t value_len, void *data)
static void dump_inode_attributes(FILE *out, ext2_ino_t ino)
{
struct ext2_xattr_handle *h;
+ size_t sz;
errcode_t err;
err = ext2fs_xattrs_open(current_fs, ino, &h);
@@ -571,7 +572,8 @@ static void dump_inode_attributes(FILE *out, ext2_ino_t ino)
if (err)
goto out;
- if (ext2fs_xattrs_count(h) == 0)
+ err = ext2fs_xattrs_count(h, &sz);
+ if (err || sz == 0)
goto out;
fprintf(out, "Extended attributes:\n");
diff --git a/lib/ext2fs/ext2_err.et.in b/lib/ext2fs/ext2_err.et.in
index 0a69aa3..198a56c 100644
--- a/lib/ext2fs/ext2_err.et.in
+++ b/lib/ext2fs/ext2_err.et.in
@@ -503,4 +503,7 @@ ec EXT2_ET_EA_NO_SPACE,
ec EXT2_ET_MISSING_EA_FEATURE,
"Filesystem is missing ext_attr or inline_data feature"
+ec EXT2_ET_MAGIC_EA_HANDLE,
+ "Wrong magic number for extended attribute structure"
+
end
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index dd6404e..b1b9d3d 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -1180,7 +1180,7 @@ errcode_t ext2fs_xattrs_open(ext2_filsys fs, ext2_ino_t ino,
errcode_t ext2fs_xattrs_close(struct ext2_xattr_handle **handle);
errcode_t ext2fs_free_ext_attr(ext2_filsys fs, ext2_ino_t ino,
struct ext2_inode_large *inode);
-size_t ext2fs_xattrs_count(struct ext2_xattr_handle *handle);
+errcode_t ext2fs_xattrs_count(struct ext2_xattr_handle *handle, size_t *count);
/* extent.c */
extern errcode_t ext2fs_extent_header_verify(void *ptr, int size);
diff --git a/lib/ext2fs/ext_attr.c b/lib/ext2fs/ext_attr.c
index e69275e..44d7615 100644
--- a/lib/ext2fs/ext_attr.c
+++ b/lib/ext2fs/ext_attr.c
@@ -195,6 +195,7 @@ struct ext2_xattr {
};
struct ext2_xattr_handle {
+ errcode_t magic;
ext2_filsys fs;
struct ext2_xattr *attrs;
size_t length, count;
@@ -238,6 +239,24 @@ static struct ea_name_index ea_names[] = {
{0, NULL},
};
+static void move_inline_data_to_front(struct ext2_xattr_handle *h)
+{
+ struct ext2_xattr *x;
+ struct ext2_xattr tmp;
+
+ for (x = h->attrs + 1; x < h->attrs + h->length; x++) {
+ if (!x->name)
+ continue;
+
+ if (strcmp(x->name, "system.data") == 0) {
+ memcpy(&tmp, x, sizeof(tmp));
+ memcpy(x, h->attrs, sizeof(tmp));
+ memcpy(h->attrs, &tmp, sizeof(tmp));
+ return;
+ }
+ }
+}
+
static const char *find_ea_prefix(int index)
{
struct ea_name_index *e;
@@ -412,6 +431,7 @@ static errcode_t write_xattrs_to_buffer(struct ext2_xattr_handle *handle,
unsigned int entry_size, value_size;
int idx, ret;
+ memset(entries_start, 0, storage_size);
/* For all remaining x... */
for (; x < handle->attrs + handle->length; x++) {
if (!x->name)
@@ -471,6 +491,7 @@ errcode_t ext2fs_xattrs_write(struct ext2_xattr_handle *handle)
unsigned int i;
errcode_t err;
+ EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EA_HANDLE);
i = EXT2_INODE_SIZE(handle->fs->super);
if (i < sizeof(*inode))
i = sizeof(*inode);
@@ -484,6 +505,8 @@ errcode_t ext2fs_xattrs_write(struct ext2_xattr_handle *handle)
if (err)
goto out;
+ move_inline_data_to_front(handle);
+
x = handle->attrs;
/* Does the inode have size for EA? */
if (EXT2_INODE_SIZE(handle->fs->super) <= EXT2_GOOD_OLD_INODE_SIZE +
@@ -511,7 +534,7 @@ errcode_t ext2fs_xattrs_write(struct ext2_xattr_handle *handle)
write_ea_block:
/* Write the EA block */
- err = ext2fs_get_memzero(handle->fs->blocksize, &block_buf);
+ err = ext2fs_get_mem(handle->fs->blocksize, &block_buf);
if (err)
goto out;
@@ -590,6 +613,7 @@ static errcode_t read_xattrs_from_buffer(struct ext2_xattr_handle *handle,
x++;
entry = entries;
+ remain = storage_size;
while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
__u32 hash;
@@ -682,6 +706,7 @@ errcode_t ext2fs_xattrs_read(struct ext2_xattr_handle *handle)
int i;
errcode_t err;
+ EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EA_HANDLE);
i = EXT2_INODE_SIZE(handle->fs->super);
if (i < sizeof(*inode))
i = sizeof(*inode);
@@ -781,6 +806,7 @@ errcode_t ext2fs_xattrs_iterate(struct ext2_xattr_handle *h,
errcode_t err;
int ret;
+ EXT2_CHECK_MAGIC(h, EXT2_ET_MAGIC_EA_HANDLE);
for (x = h->attrs; x < h->attrs + h->length; x++) {
if (!x->name)
continue;
@@ -802,6 +828,7 @@ errcode_t ext2fs_xattr_get(struct ext2_xattr_handle *h, const char *key,
void *val;
errcode_t err;
+ EXT2_CHECK_MAGIC(h, EXT2_ET_MAGIC_EA_HANDLE);
for (x = h->attrs; x < h->attrs + h->length; x++) {
if (!x->name)
continue;
@@ -829,6 +856,7 @@ errcode_t ext2fs_xattr_set(struct ext2_xattr_handle *handle,
char *new_value;
errcode_t err;
+ EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EA_HANDLE);
last_empty = NULL;
for (x = handle->attrs; x < handle->attrs + handle->length; x++) {
if (!x->name) {
@@ -894,6 +922,7 @@ errcode_t ext2fs_xattr_remove(struct ext2_xattr_handle *handle,
struct ext2_xattr *x;
errcode_t err;
+ EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EA_HANDLE);
for (x = handle->attrs; x < handle->attrs + handle->length; x++) {
if (!x->name)
continue;
@@ -927,6 +956,7 @@ errcode_t ext2fs_xattrs_open(ext2_filsys fs, ext2_ino_t ino,
if (err)
return err;
+ h->magic = EXT2_ET_MAGIC_EA_HANDLE;
h->length = 4;
err = ext2fs_get_arrayzero(h->length, sizeof(struct ext2_xattr),
&h->attrs);
@@ -946,6 +976,7 @@ errcode_t ext2fs_xattrs_close(struct ext2_xattr_handle **handle)
struct ext2_xattr_handle *h = *handle;
errcode_t err;
+ EXT2_CHECK_MAGIC(h, EXT2_ET_MAGIC_EA_HANDLE);
if (h->dirty) {
err = ext2fs_xattrs_write(h);
if (err)
@@ -958,7 +989,9 @@ errcode_t ext2fs_xattrs_close(struct ext2_xattr_handle **handle)
return 0;
}
-size_t ext2fs_xattrs_count(struct ext2_xattr_handle *handle)
+errcode_t ext2fs_xattrs_count(struct ext2_xattr_handle *handle, size_t *count)
{
- return handle->count;
+ EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EA_HANDLE);
+ *count = handle->count;
+ return 0;
}
next prev parent reply other threads:[~2014-03-02 7:16 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-02 7:16 [PATCH 00/32] e2fsprogs patchbomb 2/14 Darrick J. Wong
2014-03-02 7:16 ` Darrick J. Wong [this message]
2014-03-02 7:16 ` [PATCH 02/32] debugfs: create commands to edit extended attributes Darrick J. Wong
2014-03-02 7:16 ` [PATCH 03/32] libext2fs: fix 64bit overflow in ext2fs_block_alloc_stats_range Darrick J. Wong
2014-03-02 7:17 ` [PATCH 04/32] misc: fix header complaints and resource leaks in e2fsprogs Darrick J. Wong
2014-03-02 7:17 ` [PATCH 05/32] libext2fs: fix memory leak when drastically shrinking extent tree depth Darrick J. Wong
2014-03-02 7:17 ` [PATCH 06/32] libext2fs: fix parents when modifying extents Darrick J. Wong
2014-03-02 7:17 ` [PATCH 07/32] e2fsck: fix inline_data flag errors in pass1 Darrick J. Wong
2014-03-02 7:17 ` [PATCH 08/32] e2fsck: print runs of duplicate blocks instead of all of them Darrick J. Wong
2014-03-02 7:17 ` [PATCH 09/32] e2fsck: verify checksums after checking everything else Darrick J. Wong
2014-03-02 7:17 ` [PATCH 10/32] dumpe2fs: add switch to disable checksum verification Darrick J. Wong
2014-03-02 7:17 ` [PATCH 11/32] mke2fs: set block_validity as a default mount option Darrick J. Wong
2014-03-02 7:17 ` [PATCH 12/32] libext2fs: support allocating uninit blocks in bmap2() Darrick J. Wong
2014-03-02 7:18 ` [PATCH 13/32] libext2fs: file IO routines should handle uninit blocks Darrick J. Wong
2014-03-02 7:18 ` [PATCH 14/32] resize2fs: convert fs to and from 64bit mode Darrick J. Wong
2014-03-02 7:18 ` [PATCH 15/32] resize2fs: when toggling 64bit, don't free in-use bg data clusters Darrick J. Wong
2014-03-02 7:18 ` [PATCH 16/32] resize2fs: adjust reserved_gdt_blocks when changing group descriptor size Darrick J. Wong
2014-03-02 7:18 ` [PATCH 17/32] libext2fs: have UNIX IO manager use pread/pwrite Darrick J. Wong
2014-03-02 7:18 ` [PATCH 18/32] ext2fs: add readahead method to improve scanning Darrick J. Wong
2014-03-02 7:18 ` [PATCH 19/32] libext2fs: allow clients to read-ahead metadata Darrick J. Wong
2014-03-02 7:18 ` [PATCH 20/32] e2fsck: read-ahead metadata during passes 1, 2, and 4 Darrick J. Wong
2014-03-02 7:18 ` [PATCH 21/32] libext2fs: when appending to a file, don't split an index block in equal halves Darrick J. Wong
2014-03-02 7:18 ` [PATCH 22/32] libext2fs: find inode goal when allocating blocks Darrick J. Wong
2014-03-02 7:19 ` [PATCH 23/32] libext2fs: find a range of empty blocks Darrick J. Wong
2014-03-02 7:19 ` [PATCH 24/32] libext2fs: provide a function to set inode size Darrick J. Wong
2014-03-02 7:19 ` [PATCH 25/32] libext2fs: implement fallocate Darrick J. Wong
2014-03-02 7:19 ` [PATCH 27/32] fuse2fs: translate ACL structures Darrick J. Wong
2014-03-02 7:19 ` [PATCH 28/32] fuse2fs: handle 64-bit dates correctly Darrick J. Wong
2014-03-02 7:19 ` [PATCH 29/32] fuse2fs: implement fallocate Darrick J. Wong
2014-03-02 7:19 ` [PATCH 31/32] tests: enable using fuse2fs with metadata checksum test Darrick J. Wong
2014-03-02 7:20 ` [PATCH 32/32] tests: test date handling Darrick J. Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140302071645.28217.98125.stgit@birch.djwong.org \
--to=darrick.wong@oracle.com \
--cc=linux-ext4@vger.kernel.org \
--cc=tytso@mit.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).