* [PATCH 01/32] libext2fs: add EXT4_FEATURE_INCOMPAT_INLINE_DATA flag
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 02/32] mke2fs: make it support inline data feature Zheng Liu
` (31 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
Add EXT4_FEATURE_INCOMPAT_INLINE_DATA flag to support inline
data feature.
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
lib/ext2fs/ext2_fs.h | 1 +
lib/ext2fs/ext2fs.h | 6 ++++--
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h
index 20decff..4914946 100644
--- a/lib/ext2fs/ext2_fs.h
+++ b/lib/ext2fs/ext2_fs.h
@@ -721,6 +721,7 @@ struct ext2_super_block {
#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200
#define EXT4_FEATURE_INCOMPAT_EA_INODE 0x0400
#define EXT4_FEATURE_INCOMPAT_DIRDATA 0x1000
+#define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x2000
#define EXT2_FEATURE_COMPAT_SUPP 0
#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index fda6ade..89815eb 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -576,7 +576,8 @@ typedef struct ext2_icount *ext2_icount_t;
EXT3_FEATURE_INCOMPAT_EXTENTS|\
EXT4_FEATURE_INCOMPAT_FLEX_BG|\
EXT4_FEATURE_INCOMPAT_MMP|\
- EXT4_FEATURE_INCOMPAT_64BIT)
+ EXT4_FEATURE_INCOMPAT_64BIT|\
+ EXT4_FEATURE_INCOMPAT_INLINE_DATA)
#else
#define EXT2_LIB_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE|\
EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
@@ -585,7 +586,8 @@ typedef struct ext2_icount *ext2_icount_t;
EXT3_FEATURE_INCOMPAT_EXTENTS|\
EXT4_FEATURE_INCOMPAT_FLEX_BG|\
EXT4_FEATURE_INCOMPAT_MMP|\
- EXT4_FEATURE_INCOMPAT_64BIT)
+ EXT4_FEATURE_INCOMPAT_64BIT|\
+ EXT4_FEATURE_INCOMPAT_INLINE_DATA)
#endif
#ifdef CONFIG_QUOTA
#define EXT2_LIB_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 02/32] mke2fs: make it support inline data feature
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
2012-04-16 11:39 ` [PATCH 01/32] libext2fs: add EXT4_FEATURE_INCOMPAT_INLINE_DATA flag Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 03/32] libext2fs: add inline_data feature Zheng Liu
` (30 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
EXT2_FEATURE_COMPAT_EXT_ATTR flag will be set when inline_data is set
because inline data feature depends on it.
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
misc/mke2fs.c | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/misc/mke2fs.c b/misc/mke2fs.c
index 7ec8cc2..145a6a8 100644
--- a/misc/mke2fs.c
+++ b/misc/mke2fs.c
@@ -856,7 +856,8 @@ static __u32 ok_features[3] = {
EXT2_FEATURE_INCOMPAT_META_BG|
EXT4_FEATURE_INCOMPAT_FLEX_BG|
EXT4_FEATURE_INCOMPAT_MMP |
- EXT4_FEATURE_INCOMPAT_64BIT,
+ EXT4_FEATURE_INCOMPAT_64BIT|
+ EXT4_FEATURE_INCOMPAT_INLINE_DATA,
/* R/O compat */
EXT2_FEATURE_RO_COMPAT_LARGE_FILE|
EXT4_FEATURE_RO_COMPAT_HUGE_FILE|
@@ -1922,6 +1923,13 @@ profile_error:
exit(1);
}
+ /* if inline_data is set, ext_attr would be set because inline_data
+ * depends on it.
+ */
+ if ((fs_param.s_feature_incompat & EXT4_FEATURE_INCOMPAT_INLINE_DATA) &&
+ !(fs_param.s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR))
+ fs_param.s_feature_compat |= EXT2_FEATURE_COMPAT_EXT_ATTR;
+
if (fs_param.s_blocks_per_group) {
if (fs_param.s_blocks_per_group < 256 ||
fs_param.s_blocks_per_group > 8 * (unsigned) blocksize) {
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 03/32] libext2fs: add inline_data feature
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
2012-04-16 11:39 ` [PATCH 01/32] libext2fs: add EXT4_FEATURE_INCOMPAT_INLINE_DATA flag Zheng Liu
2012-04-16 11:39 ` [PATCH 02/32] mke2fs: make it support inline data feature Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 04/32] mke2fs: add inline_data feature in mke2fs's manpage Zheng Liu
` (29 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
Add EXT4_FEATURE_INCOMPAT_INLINE_DATA flag into feautre list.
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
lib/e2p/feature.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/lib/e2p/feature.c b/lib/e2p/feature.c
index 19e6f0c..aadc03e 100644
--- a/lib/e2p/feature.c
+++ b/lib/e2p/feature.c
@@ -87,6 +87,8 @@ static struct feature feature_list[] = {
"mmp" },
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_FLEX_BG,
"flex_bg"},
+ { E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_INLINE_DATA,
+ "inline_data"},
{ 0, 0, 0 },
};
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 04/32] mke2fs: add inline_data feature in mke2fs's manpage
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (2 preceding siblings ...)
2012-04-16 11:39 ` [PATCH 03/32] libext2fs: add inline_data feature Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 05/32] libext2fs: add ext2fs_find_entry_ext_attr function Zheng Liu
` (28 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
Update mke2fs's manpage.
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
misc/mke2fs.8.in | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/misc/mke2fs.8.in b/misc/mke2fs.8.in
index 6d443a2..bfe6c94 100644
--- a/misc/mke2fs.8.in
+++ b/misc/mke2fs.8.in
@@ -551,6 +551,9 @@ option).
@JDEV@must be created with the same
@JDEV@block size as the filesystems that will be using it.
.TP
+.B inline_data
+Allow data to be stored in inode
+.TP
.B large_file
Filesystem can contain files that are greater than 2GB. (Modern kernels
set this feature automatically when a file > 2GB is created.)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 05/32] libext2fs: add ext2fs_find_entry_ext_attr function
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (3 preceding siblings ...)
2012-04-16 11:39 ` [PATCH 04/32] mke2fs: add inline_data feature in mke2fs's manpage Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 06/32] libext2fs: add EXT4_INLINE_DATA_FL flag for inode Zheng Liu
` (27 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
we need to search extend attributes to get entry of inline data.
Thus, add this function to do this work.
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
lib/ext2fs/ext2fs.h | 3 +++
lib/ext2fs/ext_attr.c | 26 ++++++++++++++++++++++++++
2 files changed, 29 insertions(+), 0 deletions(-)
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 89815eb..a6518be 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -1075,6 +1075,9 @@ extern errcode_t ext2fs_adjust_ea_refcount(ext2_filsys fs, blk_t blk,
extern errcode_t ext2fs_adjust_ea_refcount2(ext2_filsys fs, blk64_t blk,
char *block_buf,
int adjust, __u32 *newcount);
+extern errcode_t ext2fs_find_entry_ext_attr(struct ext2_ext_attr_entry **pentry,
+ int name_index, const char *name,
+ size_t size, int sorted);
/* 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 1889824..f027296 100644
--- a/lib/ext2fs/ext_attr.c
+++ b/lib/ext2fs/ext_attr.c
@@ -155,3 +155,29 @@ errcode_t ext2fs_adjust_ea_refcount(ext2_filsys fs, blk_t blk,
{
return ext2fs_adjust_ea_refcount(fs, blk, block_buf, adjust, newcount);
}
+
+errcode_t ext2fs_find_entry_ext_attr(struct ext2_ext_attr_entry **pentry,
+ int name_index, const char *name,
+ size_t size, int sorted)
+{
+ struct ext2_ext_attr_entry *entry;
+ size_t name_len;
+ int cmp;
+
+ if (name == NULL)
+ return -1;
+ name_len = strlen(name);
+ entry = *pentry;
+ for (; !EXT2_EXT_IS_LAST_ENTRY(entry); entry = EXT2_EXT_ATTR_NEXT(entry)) {
+ cmp = name_index - entry->e_name_index;
+ if (!cmp)
+ cmp = name_len - entry->e_name_len;
+ if (!cmp)
+ cmp = memcmp(name, EXT2_EXT_ATTR_NAME(entry), name_len);
+ if (!cmp)
+ break;
+ }
+ *pentry = entry;
+
+ return cmp;
+}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 06/32] libext2fs: add EXT4_INLINE_DATA_FL flag for inode
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (4 preceding siblings ...)
2012-04-16 11:39 ` [PATCH 05/32] libext2fs: add ext2fs_find_entry_ext_attr function Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 07/32] libext2fs: add data structures for inline data feature Zheng Liu
` (26 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
Add EXT4_INLINE_DATA_FL flag.
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
lib/ext2fs/ext2_fs.h | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h
index 4914946..0f0239b 100644
--- a/lib/ext2fs/ext2_fs.h
+++ b/lib/ext2fs/ext2_fs.h
@@ -301,6 +301,7 @@ struct ext2_dx_countlimit {
#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
#define EXT4_EA_INODE_FL 0x00200000 /* Inode used for large EA */
/* EXT4_EOFBLOCKS_FL 0x00400000 was here */
+#define EXT4_INLINE_DATA_FL 0x00800000 /* Inode has inline data */
#define EXT4_SNAPFILE_FL 0x01000000 /* Inode is a snapshot */
#define EXT4_SNAPFILE_DELETED_FL 0x04000000 /* Snapshot is being deleted */
#define EXT4_SNAPFILE_SHRUNK_FL 0x08000000 /* Snapshot shrink has completed */
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 07/32] libext2fs: add data structures for inline data feature
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (5 preceding siblings ...)
2012-04-16 11:39 ` [PATCH 06/32] libext2fs: add EXT4_INLINE_DATA_FL flag for inode Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 08/32] libext2fs: add inline_data file Zheng Liu
` (25 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
Add ext2_ext_attr_ibody_heaer to check extend attribute.
Add inline_data to indicate the position of inline data in
extend attribute and the size of inline data.
Signed-off-by: Zheng Liu <wenqing.lz@taoba.com>
---
lib/ext2fs/ext2_ext_attr.h | 4 ++++
lib/ext2fs/ext2_fs.h | 7 +++++++
2 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/lib/ext2fs/ext2_ext_attr.h b/lib/ext2fs/ext2_ext_attr.h
index ed548d1..78ef7fc 100644
--- a/lib/ext2fs/ext2_ext_attr.h
+++ b/lib/ext2fs/ext2_ext_attr.h
@@ -23,6 +23,10 @@ struct ext2_ext_attr_header {
__u32 h_reserved[4]; /* zero right now */
};
+struct ext2_ext_attr_ibody_header {
+ __u32 h_magic;
+};
+
struct ext2_ext_attr_entry {
__u8 e_name_len; /* length of name */
__u8 e_name_index; /* attribute name index */
diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h
index 0f0239b..4a275d9 100644
--- a/lib/ext2fs/ext2_fs.h
+++ b/lib/ext2fs/ext2_fs.h
@@ -855,4 +855,11 @@ struct mmp_struct {
*/
#define EXT4_MMP_MIN_CHECK_INTERVAL 5
+struct inline_data {
+ __u16 inline_off;
+ __u16 inline_size;
+};
+
+#define EXT4_MIN_INLINE_DATA_SIZE ((sizeof(__u32) * EXT2_N_BLOCKS))
+
#endif /* _LINUX_EXT2_FS_H */
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 08/32] libext2fs: add inline_data file
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (6 preceding siblings ...)
2012-04-16 11:39 ` [PATCH 07/32] libext2fs: add data structures for inline data feature Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 09/32] debugfs: make ncheck cmd support inline data Zheng Liu
` (24 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
inline_data.c file is craeted to implement related functions to support
inline_data feature.
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
lib/ext2fs/Makefile.in | 5 +
lib/ext2fs/Makefile.pq | 1 +
lib/ext2fs/ext2fs.h | 54 ++++
lib/ext2fs/inline_data.c | 715 ++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 775 insertions(+), 0 deletions(-)
create mode 100644 lib/ext2fs/inline_data.c
diff --git a/lib/ext2fs/Makefile.in b/lib/ext2fs/Makefile.in
index 507a459..af631ce 100644
--- a/lib/ext2fs/Makefile.in
+++ b/lib/ext2fs/Makefile.in
@@ -58,6 +58,7 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \
ind_block.o \
initialize.o \
inline.o \
+ inline_data.o \
inode.o \
io_manager.o \
ismounted.o \
@@ -130,6 +131,7 @@ SRCS= ext2_err.c \
$(srcdir)/ind_block.c \
$(srcdir)/initialize.c \
$(srcdir)/inline.c \
+ $(srcdir)/inline_data.c \
$(srcdir)/inode.c \
$(srcdir)/inode_io.c \
$(srcdir)/imager.c \
@@ -727,6 +729,9 @@ inline.o: $(srcdir)/inline.c $(top_builddir)/lib/config.h \
$(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
$(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+inline_data.o: $(srcdir)/inline_data.c $(top_builddir)/lib/config.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext2fs.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/ext2fsP.h
inode.o: $(srcdir)/inode.c $(top_builddir)/lib/config.h \
$(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
$(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
diff --git a/lib/ext2fs/Makefile.pq b/lib/ext2fs/Makefile.pq
index 2f7b654..89082a7 100644
--- a/lib/ext2fs/Makefile.pq
+++ b/lib/ext2fs/Makefile.pq
@@ -27,6 +27,7 @@ OBJS= alloc.obj \
icount.obj \
initialize.obj \
inline.obj \
+ inline_data.obj \
inode.obj \
ismounted.obj \
link.obj \
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index a6518be..cb1b58e 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -1266,6 +1266,60 @@ extern errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino,
extern ext2_ino_t ext2fs_get_icount_size(ext2_icount_t icount);
errcode_t ext2fs_icount_validate(ext2_icount_t icount, FILE *);
+/* inline_data.c */
+extern errcode_t ext2fs_inline_data_iterate(ext2_filsys fs,
+ ext2_ino_t ino,
+ int flags,
+ char *block_buf,
+ int (*func)(struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *priv_data),
+ void *priv_data);
+extern errcode_t ext2fs_inline_data_iterate2(ext2_filsys fs,
+ ext2_ino_t ino,
+ int flags,
+ char *block_buf,
+ int (*func)(ext2_ino_t ino,
+ int entry,
+ struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *priv_data),
+ void *priv_data);
+extern errcode_t ext2fs_inline_data_iterate3(ext2_filsys fs,
+ ext2_ino_t ino,
+ int flags,
+ char *block_buf,
+ const char *name,
+ int namelen,
+ int (*func)(struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *priv_data),
+ void *priv_data);
+extern errcode_t ext2fs_inline_data_search_dir(ext2_filsys fs, ext2_ino_t ino,
+ char *search_name, int len);
+extern errcode_t ext2fs_inline_data_expand_dir(ext2_filsys fs, ext2_ino_t ino,
+ int flags, char *block_buf,
+ int (*func)(ext2_filsys fs,
+ blk64_t *blocknr,
+ e2_blkcnt_t blockcnt,
+ blk64_t ref_blk,
+ int ref_offset,
+ void *priv_data),
+ void *priv_data);
+extern void *ext2fs_get_inline_xattr_pos(struct ext2_inode_large *inode,
+ struct inline_data *idata);
+extern void ext2fs_iget_extra_inode(ext2_filsys fs, struct ext2_inode_large *inode,
+ struct inline_data *idata);
+extern int ext2fs_has_inline_data(ext2_filsys fs, ext2_ino_t ino);
+extern int ext2fs_inline_data_in_extra(ext2_filsys fs, ext2_ino_t ino);
+extern int ext2fs_inline_data_size(ext2_filsys fs, ext2_ino_t ino);
+
/* inode.c */
extern errcode_t ext2fs_flush_icache(ext2_filsys fs);
extern errcode_t ext2fs_get_next_inode_full(ext2_inode_scan scan,
diff --git a/lib/ext2fs/inline_data.c b/lib/ext2fs/inline_data.c
new file mode 100644
index 0000000..4ebd592
--- /dev/null
+++ b/lib/ext2fs/inline_data.c
@@ -0,0 +1,715 @@
+/*
+ * inline_data.c --- data in inode
+ *
+ * Copyright (C) 2012 Zheng Liu <wenqing.lz@taobao.com>
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include <stdio.h>
+
+#include "ext2_fs.h"
+#include "ext2_ext_attr.h"
+
+#include "ext2fs.h"
+#include "ext2fsP.h"
+
+#define EXT4_XATTR_SYSTEM_DATA_INDEX 7
+#define EXT4_XATTR_SYSTEM_DATA_NAME "data"
+
+struct inline_data_context {
+ ext2_ino_t ino;
+ int flags;
+ char *buf;
+ int (*func)(ext2_ino_t ino,
+ int entry,
+ struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *priv_data);
+ void *priv_data;
+ errcode_t errcode;
+};
+
+static void inline_data_update_dir_entry(ext2_filsys fs, void *de_buf,
+ int old_size, int new_size)
+{
+ struct ext2_dir_entry *entry, *prev;
+ void *limit;
+ unsigned int de_len;
+
+ entry = (struct ext2_dir_entry *)de_buf;
+ if (old_size) {
+ limit = de_buf + old_size;
+ do {
+ prev = entry;
+ ext2fs_get_rec_len(fs, entry, &de_len);
+ de_buf += de_len;
+ entry = (struct ext2_dir_entry *)de_buf;
+ } while (de_buf < limit);
+
+ ext2fs_set_rec_len(fs, de_len + new_size - old_size, prev);
+ } else {
+ entry->inode = 0;
+ ext2fs_set_rec_len(fs, new_size, entry);
+ }
+}
+
+static int inline_data_destory_data(ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode_large *inode,
+ struct inline_data *idata)
+{
+ struct ext2_ext_attr_entry *entry;
+ errcode_t retval;
+ char *start, *end;
+ int cmp;
+ __u32 *magic;
+
+ if (!idata->inline_off)
+ return 0;
+
+ if (inode->i_extra_isize > (EXT2_INODE_SIZE(fs->super) -
+ EXT2_GOOD_OLD_INODE_SIZE)) {
+ fprintf(stderr, "invalid inode->i_extra_isize (%u)\n",
+ inode->i_extra_isize);
+ return -1;
+ }
+
+ magic = (__u32*)((char *)inode + EXT2_GOOD_OLD_INODE_SIZE +
+ inode->i_extra_isize);
+ start = (char *)magic + sizeof(__u32);
+ end = (char *)inode + EXT2_INODE_SIZE(fs->super);
+ entry = (struct ext2_ext_attr_entry *)start;
+
+ cmp = ext2fs_find_entry_ext_attr(&entry, EXT4_XATTR_SYSTEM_DATA_INDEX,
+ EXT4_XATTR_SYSTEM_DATA_NAME,
+ end - start, 0);
+
+ if (!cmp) {
+ entry->e_value_offs = 0;
+ entry->e_value_block = 0;
+ entry->e_value_size = 0;
+ }
+
+ memset((void *)inode->i_block, 0, EXT4_MIN_INLINE_DATA_SIZE);
+
+ if (fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS) {
+ if (LINUX_S_ISDIR(inode->i_mode) ||
+ LINUX_S_ISREG(inode->i_mode) ||
+ LINUX_S_ISLNK(inode->i_mode))
+ inode->i_flags |= EXT4_EXTENTS_FL;
+ }
+
+ inode->i_flags &= ~EXT4_INLINE_DATA_FL;
+
+ retval = ext2fs_write_inode_full(fs, ino, (void *)inode,
+ EXT2_INODE_SIZE(fs->super));
+ if (retval)
+ return retval;
+
+ return 0;
+}
+
+static int inline_data_search_dir(ext2_filsys fs,
+ struct ext2_inode_large *inode,
+ char *start,
+ int size,
+ void *priv_data)
+{
+ struct inline_data_context *ctx;
+ struct ext2_dir_entry *dirent;
+ unsigned int rec_len;
+ unsigned int offset = 0;
+ char *dlimit;
+ int ret;
+ int do_abort = 0;
+ int changed = 0;
+
+ ctx = (struct inline_data_context *)priv_data;
+
+ dirent = (struct ext2_dir_entry *)start;
+ dlimit = start + size;
+
+ while ((char *)dirent < dlimit) {
+ if (ext2fs_get_rec_len(fs, dirent, &rec_len))
+ return BLOCK_ABORT;
+ if (!dirent->inode &&
+ !(ctx->flags & DIRENT_FLAG_INCLUDE_EMPTY))
+ goto next;
+ ret = (ctx->func)(ctx->ino, 0, dirent,
+ offset, size, start,
+ ctx->priv_data);
+
+ if (ret & DIRENT_CHANGED) {
+ if (ext2fs_get_rec_len(fs, dirent, &rec_len))
+ return BLOCK_ABORT;
+ changed++;
+ }
+
+ if (ret & DIRENT_ABORT)
+ do_abort++;
+
+next:
+ dirent = (struct ext2_dir_entry *)((char *)dirent + rec_len);
+ offset += rec_len;
+ }
+
+ if (changed) {
+ ctx->errcode = ext2fs_write_inode_full(fs, ctx->ino, (void *)inode,
+ EXT2_INODE_SIZE(fs->super));
+ if (ctx->errcode)
+ return BLOCK_ABORT;
+ }
+
+ if (do_abort)
+ return BLOCK_ABORT;
+
+ return 0;
+}
+
+static int inline_data_search_dir2(ext2_filsys fs, char *start, int size,
+ char *search_name, int len)
+{
+ struct ext2_dir_entry *dirent;
+ unsigned int rec_len;
+ char *dlimit;
+ int ret;
+ int do_abort = 0;
+
+ dirent = (struct ext2_dir_entry *)start;
+ dlimit = start + size;
+
+ while ((char *)dirent < dlimit) {
+ if (ext2fs_get_rec_len(fs, dirent, &rec_len))
+ return BLOCK_ABORT;
+ if (dirent->inode &&
+ len == (dirent->name_len & 0xFF) &&
+ strncmp(search_name, dirent->name, len) == 0) {
+ printf("Entry found at inline data\n");
+ break;
+ }
+ dirent = (struct ext2_dir_entry *)((char *)dirent + rec_len);
+ }
+
+ return 0;
+}
+
+void *ext2fs_get_inline_xattr_pos(struct ext2_inode_large *inode,
+ struct inline_data *idata)
+{
+ struct ext2_ext_attr_entry *entry;
+ struct ext2_ext_attr_ibody_header *header;
+
+ header = (struct ext2_ext_attr_ibody_header *)
+ ((void *)inode +
+ EXT2_GOOD_OLD_INODE_SIZE +
+ inode->i_extra_isize);
+ entry = (struct ext2_ext_attr_entry *)
+ ((void *)inode + idata->inline_off);
+
+ return (void *)((struct ext2_ext_attr_header *)((header) + 1)) +
+ entry->e_value_offs;
+}
+
+void ext2fs_iget_extra_inode(ext2_filsys fs, struct ext2_inode_large *inode,
+ struct inline_data *idata)
+{
+ struct ext2_ext_attr_entry *entry;
+ char *start, *end;
+ int cmp;
+ __u32 *magic;
+
+ idata->inline_off = 0;
+ if (inode->i_extra_isize > (EXT2_INODE_SIZE(fs->super) -
+ EXT2_GOOD_OLD_INODE_SIZE)) {
+ fprintf(stderr, "invalid inode->i_extra_isize (%u)\n",
+ inode->i_extra_isize);
+ return;
+ }
+
+ magic = (__u32*)((char *)inode + EXT2_GOOD_OLD_INODE_SIZE +
+ inode->i_extra_isize);
+ if (*magic == EXT2_EXT_ATTR_MAGIC) {
+ end = (char *)inode + EXT2_INODE_SIZE(fs->super);
+ start = (char *)magic + sizeof(__u32);
+ entry = (struct ext2_ext_attr_entry *)start;
+
+ cmp = ext2fs_find_entry_ext_attr(&entry, EXT4_XATTR_SYSTEM_DATA_INDEX,
+ EXT4_XATTR_SYSTEM_DATA_NAME,
+ end - start, 0);
+ if (!cmp) {
+ idata->inline_off = (__u16)((void *)entry -
+ (void *)inode);
+ idata->inline_size = EXT4_MIN_INLINE_DATA_SIZE +
+ entry->e_value_size;
+ }
+ }
+}
+
+int ext2fs_has_inline_data(ext2_filsys fs, ext2_ino_t ino)
+{
+ struct ext2_inode *inode;
+ errcode_t retval;
+ __u32 flags;
+
+ retval = ext2fs_get_mem(EXT2_INODE_SIZE(fs->super), &inode);
+ if (retval)
+ return 0;
+
+ retval = ext2fs_read_inode_full(fs, ino, inode,
+ EXT2_INODE_SIZE(fs->super));
+ if (retval)
+ return 0;
+
+ flags = inode->i_flags;
+ ext2fs_free_mem(&inode);
+
+ return (flags & EXT4_INLINE_DATA_FL);
+}
+
+struct xlate {
+ int (*func)(struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *priv_data);
+ void *real_private;
+};
+
+static int xlate_func(ext2_ino_t dir EXT2FS_ATTR((unused)),
+ int entry EXT2FS_ATTR((unused)),
+ struct ext2_dir_entry *dirent, int offset,
+ int blocksize, char *buf, void *priv_data)
+{
+ struct xlate *xl = (struct xlate *)priv_data;
+
+ return (*xl->func)(dirent, offset, blocksize, buf, xl->real_private);
+}
+
+errcode_t ext2fs_inline_data_iterate(ext2_filsys fs,
+ ext2_ino_t ino,
+ int flags,
+ char *block_buf,
+ int (*func)(struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *priv_data),
+ void *priv_data)
+{
+ struct xlate xl;
+
+ xl.real_private = priv_data;
+ xl.func = func;
+
+ return ext2fs_inline_data_iterate2(fs, ino, flags, block_buf,
+ xlate_func, &xl);
+}
+
+errcode_t ext2fs_inline_data_iterate2(ext2_filsys fs,
+ ext2_ino_t ino, int flags, char *block_buf,
+ int (*func)(ext2_ino_t ino,
+ int entry,
+ struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *priv_data),
+ void *priv_data)
+{
+ struct inline_data_context ctx;
+ struct ext2_inode_large *inode;
+ struct inline_data idata;
+ errcode_t retval;
+ blk64_t blk64;
+ void *inline_start;
+ int inline_size;
+ int ret = 0;
+ int i, limit, r;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ retval = ext2fs_check_directory(fs, ino);
+ if (retval)
+ return retval;
+
+ retval = ext2fs_get_mem(EXT2_INODE_SIZE(fs->super), &inode);
+ if (retval)
+ return retval;
+ retval = ext2fs_read_inode_full(fs, ino, (void *)inode,
+ EXT2_INODE_SIZE(fs->super));
+ if (retval) {
+ ext2fs_free_mem(&inode);
+ return retval;
+ }
+
+ ctx.ino = ino;
+ ctx.flags = flags;
+ ctx.buf = block_buf;
+ ctx.func = func;
+ ctx.priv_data = priv_data;
+ ctx.errcode = 0;
+
+ inline_start = inode->i_block;
+ inline_size = EXT4_MIN_INLINE_DATA_SIZE;
+ ret = inline_data_search_dir(fs, inode, inline_start, inline_size, &ctx);
+ if (ret)
+ goto out;
+
+ ext2fs_iget_extra_inode(fs, inode, &idata);
+ if (idata.inline_size > EXT4_MIN_INLINE_DATA_SIZE) {
+ inline_start = ext2fs_get_inline_xattr_pos(inode, &idata);
+ inline_size = idata.inline_size - EXT4_MIN_INLINE_DATA_SIZE;
+ ret = inline_data_search_dir(fs, inode, inline_start, inline_size, &ctx);
+
+ if (ret)
+ goto out;
+ }
+
+out:
+ return ret & BLOCK_ABORT ? 0 : ret;
+}
+
+errcode_t ext2fs_inline_data_iterate3(ext2_filsys fs,
+ ext2_ino_t ino,
+ int flags,
+ char *block_buf,
+ const char *name,
+ int namelen,
+ int (*func)(struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *priv_data),
+ void *priv_data)
+{
+ struct xlate xl;
+ struct inline_data_context ctx;
+ struct ext2_inode_large *inode;
+ struct inline_data idata;
+ ext2_extent_handle_t handle;
+ errcode_t retval;
+ blk64_t blk;
+ void *inline_start;
+ char *backup_buf;
+ char *blk_buf;
+ int inline_size;
+ int ret = 0;
+ int i, limit, r;
+
+ xl.real_private = priv_data;
+ xl.func = func;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ retval = ext2fs_get_mem(EXT2_INODE_SIZE(fs->super), &inode);
+ if (retval)
+ return retval;
+ retval = ext2fs_read_inode_full(fs, ino, (void *)inode,
+ EXT2_INODE_SIZE(fs->super));
+ if (retval) {
+ ext2fs_free_mem(&inode);
+ return retval;
+ }
+
+ ctx.ino = ino;
+ ctx.flags = flags;
+ ctx.buf = block_buf;
+ ctx.func = xlate_func;
+ ctx.priv_data = &xl;
+ ctx.errcode = 0;
+
+ inline_start = inode->i_block;
+ inline_size = EXT4_MIN_INLINE_DATA_SIZE;
+ ret = inline_data_search_dir(fs, inode, inline_start, inline_size, &ctx);
+ if (ret)
+ goto out;
+
+ ext2fs_iget_extra_inode(fs, inode, &idata);
+ inline_size = idata.inline_size - EXT4_MIN_INLINE_DATA_SIZE;
+ if (inline_size > 0) {
+ inline_start = ext2fs_get_inline_xattr_pos(inode, &idata);
+ ret = inline_data_search_dir(fs, inode, inline_start, inline_size, &ctx);
+ if (ret)
+ goto out;
+ }
+
+ /*
+ * TODO: we should try to expand xattr space firstly. But
+ * when creating too many dirs, Tao got a performance regression.
+ * Thus, it will be discussed and re-designed.
+ */
+
+ /*
+ * The inline space is filled up. So create a new block for it.
+ * As the extent tree will be created, we have to save the inline
+ * dir first.
+ */
+ inline_size = idata.inline_size;
+ retval = ext2fs_get_mem(inline_size, &backup_buf);
+ if (retval) {
+ ret = retval;
+ goto out;
+ }
+
+ memcpy(backup_buf, (void *)inode->i_block, EXT4_MIN_INLINE_DATA_SIZE);
+ if (inline_size > EXT4_MIN_INLINE_DATA_SIZE)
+ memcpy(backup_buf + EXT4_MIN_INLINE_DATA_SIZE,
+ ext2fs_get_inline_xattr_pos(inode, &idata),
+ inline_size - EXT4_MIN_INLINE_DATA_SIZE);
+
+ /* clear the entry and the flag in dir now */
+ ret = inline_data_destory_data(fs, ino, inode, &idata);
+ if (ret)
+ goto out;
+
+ retval = ext2fs_new_block2(fs, 0, 0, &blk);
+ if (retval)
+ goto out;
+
+ ext2fs_iblk_set(fs, (void *)inode, 1);
+ if (!(fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS))
+ inode->i_block[0] = blk;
+ inode->i_size = fs->blocksize;
+
+ retval = ext2fs_get_mem(fs->blocksize, &blk_buf);
+ if (retval)
+ goto out;
+
+ memcpy(blk_buf, backup_buf, inline_size);
+
+ /* set the final dir entry to cover the whole block */
+ inline_data_update_dir_entry(fs, blk_buf, inline_size, fs->blocksize);
+
+ retval = ext2fs_write_dir_block(fs, blk, blk_buf);
+ if (retval)
+ goto out;
+ retval = ext2fs_write_inode_full(fs, ino, (void *)inode,
+ EXT2_INODE_SIZE(fs->super));
+ if (retval)
+ goto out;
+
+ if (fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS) {
+ retval = ext2fs_extent_open2(fs, ino, (void *)inode, &handle);
+ if (retval)
+ goto out;
+ retval = ext2fs_extent_set_bmap(handle, 0, blk, 0);
+ ext2fs_extent_free(handle);
+ if (retval)
+ goto out;
+ }
+
+ /* Update accouting */
+ ext2fs_block_alloc_stats2(fs, blk, +1);
+
+ /* try to add a new entry */
+ retval = ext2fs_dir_iterate(fs, ino, DIRENT_FLAG_INCLUDE_EMPTY,
+ 0, func, priv_data);
+
+ ext2fs_free_mem(&backup_buf);
+ ext2fs_free_mem(&blk_buf);
+out:
+ ext2fs_free_mem(&inode);
+ return ret & BLOCK_ABORT ? 0 : ret;
+}
+
+errcode_t ext2fs_inline_data_search_dir(ext2_filsys fs, ext2_ino_t ino,
+ char *search_name, int len)
+{
+ struct ext2_inode_large *inode;
+ struct ext2_dir_entry *entry;
+ struct inline_data idata;
+ unsigned int rec_len;
+ errcode_t retval;
+ char *dlimit;
+ void *start;
+ int size;
+ int ret = 0;
+
+ retval = ext2fs_get_mem(EXT2_INODE_SIZE(fs->super), &inode);
+ if (retval)
+ return retval;
+
+ retval = ext2fs_read_inode_full(fs, ino, (void *)inode,
+ EXT2_INODE_SIZE(fs->super));
+ if (retval)
+ return retval;
+
+ if (!(inode->i_flags & EXT4_INLINE_DATA_FL))
+ goto out;
+
+ start = inode->i_block;
+ size = EXT4_MIN_INLINE_DATA_SIZE;
+ ret = inline_data_search_dir2(fs, start, size, search_name, len);
+ if (!ret)
+ goto out;
+
+ ret = 0;
+ ext2fs_iget_extra_inode(fs, inode, &idata);
+ if (idata.inline_size == EXT4_MIN_INLINE_DATA_SIZE)
+ goto out;
+
+ start = ext2fs_get_inline_xattr_pos(inode, &idata);
+ size = idata.inline_size - EXT4_MIN_INLINE_DATA_SIZE;
+ ret = inline_data_search_dir2(fs, start, size, search_name, len);
+
+out:
+ ext2fs_free_mem(&inode);
+ return ret;
+}
+
+errcode_t ext2fs_inline_data_header_verify(ext2_filsys fs,
+ struct ext2_inode *inode)
+{
+ struct inline_data idata;
+ int ret = 0;
+
+ ext2fs_iget_extra_inode(fs, (void *)inode, &idata);
+ if (idata.inline_off == 0)
+ ret = -1;
+
+ return ret;
+}
+
+int ext2fs_inline_data_in_extra(ext2_filsys fs, ext2_ino_t ino)
+{
+ struct ext2_inode *inode;
+ struct inline_data idata;
+
+ ext2fs_get_mem(EXT2_INODE_SIZE(fs->super), &inode);
+ ext2fs_read_inode_full(fs, ino, inode, EXT2_INODE_SIZE(fs->super));
+
+ ext2fs_iget_extra_inode(fs, inode, &idata);
+ ext2fs_free_mem(&inode);
+ if (idata.inline_off == 0 ||
+ idata.inline_size == EXT4_MIN_INLINE_DATA_SIZE)
+ return 0;
+ else
+ return 1;
+}
+
+int ext2fs_inline_data_size(ext2_filsys fs, ext2_ino_t ino)
+{
+ struct ext2_inode *inode;
+ struct inline_data idata;
+
+ inode = (struct ext2_inode *) malloc(EXT2_INODE_SIZE(fs->super));
+ ext2fs_read_inode_full(fs, ino, inode, EXT2_INODE_SIZE(fs->super));
+
+ ext2fs_iget_extra_inode(fs, inode, &idata);
+ free(inode);
+ if (idata.inline_off == 0)
+ return 0;
+ else
+ return idata.inline_size;
+}
+
+errcode_t ext2fs_inline_data_expand_dir(ext2_filsys fs,
+ ext2_ino_t ino,
+ int flags,
+ char *block_buf,
+ int (*func)(ext2_filsys fs,
+ blk64_t *blocknr,
+ e2_blkcnt_t blockcnt,
+ blk64_t ref_blk,
+ int ref_offset,
+ void *priv_data),
+ void *priv_data)
+{
+ struct ext2_inode_large *inode;
+ struct inline_data idata;
+ ext2_extent_handle_t handle;
+ errcode_t retval;
+ blk64_t blk;
+ void *inline_start;
+ char *backup_buf;
+ char *blk_buf;
+ int inline_size;
+ int ret = 0;
+ int i, limit, r;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ retval = ext2fs_get_mem(EXT2_INODE_SIZE(fs->super), &inode);
+ if (retval)
+ return retval;
+ retval = ext2fs_read_inode_full(fs, ino, (void *)inode,
+ EXT2_INODE_SIZE(fs->super));
+ if (retval) {
+ ext2fs_free_mem(&inode);
+ return retval;
+ }
+
+ ext2fs_iget_extra_inode(fs, inode, &idata);
+
+ inline_size = idata.inline_size;
+ retval = ext2fs_get_mem(inline_size, &backup_buf);
+ if (retval) {
+ ret = retval;
+ goto out;
+ }
+
+ memcpy(backup_buf, (void *)inode->i_block, EXT4_MIN_INLINE_DATA_SIZE);
+ if (inline_size > EXT4_MIN_INLINE_DATA_SIZE)
+ memcpy(backup_buf + EXT4_MIN_INLINE_DATA_SIZE,
+ ext2fs_get_inline_xattr_pos(inode, &idata),
+ inline_size - EXT4_MIN_INLINE_DATA_SIZE);
+
+ /* clear the entry and the flag in dir now */
+ ret = inline_data_destory_data(fs, ino, inode, &idata);
+ if (ret)
+ goto out;
+
+ retval = ext2fs_new_block2(fs, 0, 0, &blk);
+ if (retval)
+ goto out;
+
+ ext2fs_iblk_set(fs, (void *)inode, 1);
+ if (!(fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS))
+ inode->i_block[0] = blk;
+ inode->i_size = fs->blocksize;
+
+ retval = ext2fs_get_mem(fs->blocksize, &blk_buf);
+ if (retval)
+ goto out;
+
+ memcpy(blk_buf, backup_buf, inline_size);
+
+ /* set the final dir entry to cover the whole block */
+ inline_data_update_dir_entry(fs, blk_buf, inline_size, fs->blocksize);
+
+ retval = ext2fs_write_dir_block(fs, blk, blk_buf);
+ if (retval)
+ goto out;
+ retval = ext2fs_write_inode_full(fs, ino, (void *)inode,
+ EXT2_INODE_SIZE(fs->super));
+ if (retval)
+ goto out;
+
+ if (fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS) {
+ retval = ext2fs_extent_open2(fs, ino, (void *)inode, &handle);
+ if (retval)
+ goto out;
+ retval = ext2fs_extent_set_bmap(handle, 0, blk, 0);
+ ext2fs_extent_free(handle);
+ if (retval)
+ goto out;
+ }
+
+ /* Update accouting */
+ ext2fs_block_alloc_stats2(fs, blk, +1);
+
+ /* try to add a new entry */
+ retval = ext2fs_block_iterate3(fs, ino, flags, 0, func, priv_data);
+
+ ext2fs_free_mem(&backup_buf);
+ ext2fs_free_mem(&blk_buf);
+out:
+ ext2fs_free_mem(&inode);
+ return ret & BLOCK_ABORT ? 0 : ret;
+}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 09/32] debugfs: make ncheck cmd support inline data
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (7 preceding siblings ...)
2012-04-16 11:39 ` [PATCH 08/32] libext2fs: add inline_data file Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 10/32] debugfs: make chroot and cd " Zheng Liu
` (23 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
when inode has inline data, ext2fs_inline_data_iterate function is called
to traverse dirs.
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
debugfs/ncheck.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/debugfs/ncheck.c b/debugfs/ncheck.c
index 58f3a50..6dda919 100644
--- a/debugfs/ncheck.c
+++ b/debugfs/ncheck.c
@@ -171,8 +171,12 @@ void do_ncheck(int argc, char **argv)
iw.dir = ino;
iw.get_pathname_failed = 0;
- retval = ext2fs_dir_iterate(current_fs, ino, 0, 0,
- ncheck_proc, &iw);
+ if (ext2fs_has_inline_data(current_fs, ino))
+ retval = ext2fs_inline_data_iterate(current_fs, ino, 0,
+ 0, ncheck_proc, &iw);
+ else
+ retval = ext2fs_dir_iterate(current_fs, ino, 0, 0,
+ ncheck_proc, &iw);
ext2fs_free_mem(&iw.parent);
if (retval) {
com_err("ncheck", retval,
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 10/32] debugfs: make chroot and cd cmd support inline data
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (8 preceding siblings ...)
2012-04-16 11:39 ` [PATCH 09/32] debugfs: make ncheck cmd support inline data Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 11/32] debugfs: make ls " Zheng Liu
` (22 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
Both chroot and cd command call ext2fs_lookup. So we can let it supoort
inline data simultaneously.
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
lib/ext2fs/lookup.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/lib/ext2fs/lookup.c b/lib/ext2fs/lookup.c
index 0e66e71..9835082 100644
--- a/lib/ext2fs/lookup.c
+++ b/lib/ext2fs/lookup.c
@@ -60,7 +60,11 @@ errcode_t ext2fs_lookup(ext2_filsys fs, ext2_ino_t dir, const char *name,
ls.inode = inode;
ls.found = 0;
- retval = ext2fs_dir_iterate(fs, dir, 0, buf, lookup_proc, &ls);
+ if (ext2fs_has_inline_data(fs, dir))
+ retval = ext2fs_inline_data_iterate(fs, dir, 0, buf,
+ lookup_proc, &ls);
+ else
+ retval = ext2fs_dir_iterate(fs, dir, 0, buf, lookup_proc, &ls);
if (retval)
return retval;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 11/32] debugfs: make ls cmd support inline data
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (9 preceding siblings ...)
2012-04-16 11:39 ` [PATCH 10/32] debugfs: make chroot and cd " Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 12/32] debugfs: make stat " Zheng Liu
` (21 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
debugfs/ls.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/debugfs/ls.c b/debugfs/ls.c
index b4036de..14e7022 100644
--- a/debugfs/ls.c
+++ b/debugfs/ls.c
@@ -170,8 +170,12 @@ void do_list_dir(int argc, char *argv[])
if (ls.options & DELETED_OPT)
flags |= DIRENT_FLAG_INCLUDE_REMOVED;
- retval = ext2fs_dir_iterate2(current_fs, inode, flags,
- 0, list_dir_proc, &ls);
+ if (ext2fs_has_inline_data(current_fs, inode))
+ retval = ext2fs_inline_data_iterate2(current_fs, inode,flags,
+ 0, list_dir_proc, &ls);
+ else
+ retval = ext2fs_dir_iterate2(current_fs, inode, flags,
+ 0, list_dir_proc, &ls);
fprintf(ls.f, "\n");
close_pager(ls.f);
if (retval)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 12/32] debugfs: make stat cmd support inline data
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (10 preceding siblings ...)
2012-04-16 11:39 ` [PATCH 11/32] debugfs: make ls " Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 13/32] debufs: make blocks " Zheng Liu
` (20 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
It only tells the user that this inode contains inline data.
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
debugfs/debugfs.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c
index 590468d..df9b954 100644
--- a/debugfs/debugfs.c
+++ b/debugfs/debugfs.c
@@ -801,6 +801,10 @@ void internal_dump_inode(FILE *out, const char *prefix,
if (inode->i_dtime)
fprintf(out, "%sdtime: 0x%08x -- %s", prefix, inode->i_dtime,
time_to_string(inode->i_dtime));
+ if (inode->i_flags & EXT4_INLINE_DATA_FL) {
+ fprintf(out, "Inode has inline data\n");
+ return;
+ }
if (EXT2_INODE_SIZE(current_fs->super) > EXT2_GOOD_OLD_INODE_SIZE)
internal_dump_inode_extra(out, prefix, inode_num,
(struct ext2_inode_large *) inode);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 13/32] debufs: make blocks cmd support inline data
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (11 preceding siblings ...)
2012-04-16 11:39 ` [PATCH 12/32] debugfs: make stat " Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 14/32] debugfs: make filefrag " Zheng Liu
` (19 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4
From: Zheng Liu <wenqing.lz@taobao.com>
Block entries don't point to blocks. So it doesn't show anything when this
inode has inline data.
Singed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
debugfs/debugfs.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c
index df9b954..17e5ec8 100644
--- a/debugfs/debugfs.c
+++ b/debugfs/debugfs.c
@@ -958,6 +958,9 @@ void do_blocks(int argc, char *argv[])
return;
}
+ if (ext2fs_has_inline_data(current_fs, inode))
+ return;
+
ext2fs_block_iterate3(current_fs, inode, BLOCK_FLAG_READ_ONLY, NULL,
print_blocks_proc, NULL);
fputc('\n', stdout);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 14/32] debugfs: make filefrag cmd support inline data
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (12 preceding siblings ...)
2012-04-16 11:39 ` [PATCH 13/32] debufs: make blocks " Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 15/32] debugfs: make link " Zheng Liu
` (18 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
Inode with inline data doesn't have any fragmentations.
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
debugfs/filefrag.c | 30 ++++++++++++++++++------------
1 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/debugfs/filefrag.c b/debugfs/filefrag.c
index 7f28bc0..c94396c 100644
--- a/debugfs/filefrag.c
+++ b/debugfs/filefrag.c
@@ -153,16 +153,18 @@ static void filefrag(ext2_ino_t ino, struct ext2_inode *inode,
fprintf(fs->f, "\n%s has %llu block(s), i_size is %llu\n",
fs->name, num_blocks, EXT2_I_SIZE(inode));
}
- print_header(fs);
- retval = ext2fs_block_iterate3(current_fs, ino,
- BLOCK_FLAG_READ_ONLY, NULL,
- filefrag_blocks_proc, fs);
- if (retval)
- com_err("ext2fs_block_iterate3", retval, 0);
-
- report_filefrag(fs);
- fprintf(fs->f, "%s: %d contiguous extents%s\n", fs->name, fs->ext,
- LINUX_S_ISDIR(inode->i_mode) ? " (dir)" : "");
+ if (!ext2fs_has_inline_data(current_fs, ino)) {
+ print_header(fs);
+ retval = ext2fs_block_iterate3(current_fs, ino,
+ BLOCK_FLAG_READ_ONLY, NULL,
+ filefrag_blocks_proc, fs);
+ if (retval)
+ com_err("ext2fs_block_iterate3", retval, 0);
+
+ report_filefrag(fs);
+ fprintf(fs->f, "%s: %d contiguous extents%s\n", fs->name, fs->ext,
+ LINUX_S_ISDIR(inode->i_mode) ? " (dir)" : "");
+ }
}
static int filefrag_dir_proc(ext2_ino_t dir EXT2FS_ATTR((unused)),
@@ -240,8 +242,12 @@ static void dir_iterate(ext2_ino_t ino, struct filefrag_struct *fs)
fs->dir_name = fs->name;
while (1) {
- retval = ext2fs_dir_iterate2(current_fs, ino, 0,
- 0, filefrag_dir_proc, fs);
+ if (ext2fs_has_inline_data(current_fs, ino))
+ retval = ext2fs_inline_data_iterate2(current_fs, ino,
+ 0, 0, filefrag_dir_proc, fs);
+ else
+ retval = ext2fs_dir_iterate2(current_fs, ino, 0,
+ 0, filefrag_dir_proc, fs);
if (retval)
com_err("ext2fs_dir_iterate2", retval, 0);
if (p) {
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 15/32] debugfs: make link cmd support inline data
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (13 preceding siblings ...)
2012-04-16 11:39 ` [PATCH 14/32] debugfs: make filefrag " Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 16/32] debugfs: make unlink " Zheng Liu
` (17 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
lib/ext2fs/link.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/lib/ext2fs/link.c b/lib/ext2fs/link.c
index 2d03b57..e62567c 100644
--- a/lib/ext2fs/link.c
+++ b/lib/ext2fs/link.c
@@ -131,8 +131,13 @@ errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name,
ls.blocksize = fs->blocksize;
ls.err = 0;
- retval = ext2fs_dir_iterate(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY,
- 0, link_proc, &ls);
+ if (ext2fs_has_inline_data(fs, dir))
+ retval = ext2fs_inline_data_iterate3(fs, dir,
+ DIRENT_FLAG_INCLUDE_EMPTY, 0, ls.name,
+ ls.namelen, link_proc, &ls);
+ else
+ retval = ext2fs_dir_iterate(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY,
+ 0, link_proc, &ls);
if (retval)
return retval;
if (ls.err)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 16/32] debugfs: make unlink cmd support inline data
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (14 preceding siblings ...)
2012-04-16 11:39 ` [PATCH 15/32] debugfs: make link " Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 17/32] debugfs: make mkdir " Zheng Liu
` (16 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
lib/ext2fs/unlink.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/lib/ext2fs/unlink.c b/lib/ext2fs/unlink.c
index d2d31cc..6852d4a 100644
--- a/lib/ext2fs/unlink.c
+++ b/lib/ext2fs/unlink.c
@@ -90,8 +90,13 @@ errcode_t ext2fs_unlink(ext2_filsys fs, ext2_ino_t dir,
ls.done = 0;
ls.prev = 0;
- retval = ext2fs_dir_iterate(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY,
- 0, unlink_proc, &ls);
+ if (ext2fs_has_inline_data(fs, dir))
+ retval = ext2fs_inline_data_iterate(fs, dir,
+ DIRENT_FLAG_INCLUDE_EMPTY, 0,
+ unlink_proc, &ls);
+ else
+ retval = ext2fs_dir_iterate(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY,
+ 0, unlink_proc, &ls);
if (retval)
return retval;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 17/32] debugfs: make mkdir cmd support inline data
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (15 preceding siblings ...)
2012-04-16 11:39 ` [PATCH 16/32] debugfs: make unlink " Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 18/32] debugfs: make rmdir " Zheng Liu
` (15 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
We need to reload inode in ext2fs_mkdir because inode with inline itself
data is modified in ext2fs_link.
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
lib/ext2fs/mkdir.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/lib/ext2fs/mkdir.c b/lib/ext2fs/mkdir.c
index b12bf2d..d9a8278 100644
--- a/lib/ext2fs/mkdir.c
+++ b/lib/ext2fs/mkdir.c
@@ -134,6 +134,10 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
* Update parent inode's counts
*/
if (parent != ino) {
+ /* Reload parent inode */
+ retval = ext2fs_read_inode(fs, parent, &parent_inode);
+ if (retval)
+ goto cleanup;
parent_inode.i_links_count++;
retval = ext2fs_write_inode(fs, parent, &parent_inode);
if (retval)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 18/32] debugfs: make rmdir cmd support inline data
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (16 preceding siblings ...)
2012-04-16 11:39 ` [PATCH 17/32] debugfs: make mkdir " Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 19/32] debugfs: make rm and kill_file " Zheng Liu
` (14 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
debugfs/debugfs.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c
index 17e5ec8..7a97c48 100644
--- a/debugfs/debugfs.c
+++ b/debugfs/debugfs.c
@@ -1948,8 +1948,12 @@ void do_rmdir(int argc, char *argv[])
rds.parent = 0;
rds.empty = 1;
- retval = ext2fs_dir_iterate2(current_fs, inode_num, 0,
- 0, rmdir_proc, &rds);
+ if (ext2fs_has_inline_data(current_fs, inode_num))
+ retval = ext2fs_inline_data_iterate2(current_fs, inode_num, 0,
+ 0, rmdir_proc, &rds);
+ else
+ retval = ext2fs_dir_iterate2(current_fs, inode_num, 0,
+ 0, rmdir_proc, &rds);
if (retval) {
com_err(argv[0], retval, "while iterating over directory");
return;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 19/32] debugfs: make rm and kill_file cmd support inline data
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (17 preceding siblings ...)
2012-04-16 11:39 ` [PATCH 18/32] debugfs: make rmdir " Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 20/32] debugfs: make pwd " Zheng Liu
` (13 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
rm and kill_file command don't need to release blocks.
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
debugfs/debugfs.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c
index 7a97c48..517751f 100644
--- a/debugfs/debugfs.c
+++ b/debugfs/debugfs.c
@@ -1841,8 +1841,9 @@ static void kill_file_by_inode(ext2_ino_t inode)
if (!ext2fs_inode_has_valid_blocks2(current_fs, &inode_buf))
return;
- ext2fs_block_iterate3(current_fs, inode, BLOCK_FLAG_READ_ONLY, NULL,
- release_blocks_proc, NULL);
+ if (!ext2fs_has_inline_data(current_fs, inode))
+ ext2fs_block_iterate3(current_fs, inode, BLOCK_FLAG_READ_ONLY,
+ NULL, release_blocks_proc, NULL);
printf("\n");
ext2fs_inode_alloc_stats2(current_fs, inode, -1,
LINUX_S_ISDIR(inode_buf.i_mode));
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 20/32] debugfs: make pwd cmd support inline data
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (18 preceding siblings ...)
2012-04-16 11:39 ` [PATCH 19/32] debugfs: make rm and kill_file " Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 21/32] debugfs: make expand_dir " Zheng Liu
` (12 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
lib/ext2fs/get_pathname.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/lib/ext2fs/get_pathname.c b/lib/ext2fs/get_pathname.c
index 52aea62..f92f17d 100644
--- a/lib/ext2fs/get_pathname.c
+++ b/lib/ext2fs/get_pathname.c
@@ -98,7 +98,12 @@ static errcode_t ext2fs_get_pathname_int(ext2_filsys fs, ext2_ino_t dir,
gp.name = 0;
gp.errcode = 0;
- retval = ext2fs_dir_iterate(fs, dir, 0, buf, get_pathname_proc, &gp);
+ if (ext2fs_has_inline_data(fs, dir))
+ retval = ext2fs_inline_data_iterate(fs, dir, 0, buf,
+ get_pathname_proc, &gp);
+ else
+ retval = ext2fs_dir_iterate(fs, dir, 0, buf,
+ get_pathname_proc, &gp);
if (retval == EXT2_ET_NO_DIRECTORY) {
char tmp[32];
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 21/32] debugfs: make expand_dir cmd support inline data
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (19 preceding siblings ...)
2012-04-16 11:39 ` [PATCH 20/32] debugfs: make pwd " Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 22/32] debugfs: make lsdel " Zheng Liu
` (11 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
lib/ext2fs/expanddir.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/lib/ext2fs/expanddir.c b/lib/ext2fs/expanddir.c
index 41c4088..8caa97b 100644
--- a/lib/ext2fs/expanddir.c
+++ b/lib/ext2fs/expanddir.c
@@ -111,8 +111,12 @@ errcode_t ext2fs_expand_dir(ext2_filsys fs, ext2_ino_t dir)
es.goal = 0;
es.newblocks = 0;
- retval = ext2fs_block_iterate3(fs, dir, BLOCK_FLAG_APPEND,
- 0, expand_dir_proc, &es);
+ if (ext2fs_has_inline_data(fs, dir))
+ retval = ext2fs_inline_data_expand_dir(fs, dir, BLOCK_CHANGED,
+ 0, expand_dir_proc, &es);
+ else
+ retval = ext2fs_block_iterate3(fs, dir, BLOCK_FLAG_APPEND,
+ 0, expand_dir_proc, &es);
if (es.err)
return es.err;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 22/32] debugfs: make lsdel cmd support inline data
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (20 preceding siblings ...)
2012-04-16 11:39 ` [PATCH 21/32] debugfs: make expand_dir " Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 23/32] debugfs: make undel " Zheng Liu
` (10 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
debugfs/lsdel.c | 19 +++++++++++--------
1 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/debugfs/lsdel.c b/debugfs/lsdel.c
index bed0ce6..ff283cd 100644
--- a/debugfs/lsdel.c
+++ b/debugfs/lsdel.c
@@ -141,15 +141,18 @@ void do_lsdel(int argc, char **argv)
lsd.free_blocks = 0;
lsd.bad_blocks = 0;
- retval = ext2fs_block_iterate3(current_fs, ino,
- BLOCK_FLAG_READ_ONLY, block_buf,
- lsdel_proc, &lsd);
- if (retval) {
- com_err("ls_deleted_inodes", retval,
- "while calling ext2fs_block_iterate2");
- goto next;
+ if (!ext2fs_has_inline_data(current_fs, ino)) {
+ retval = ext2fs_block_iterate3(current_fs, ino,
+ BLOCK_FLAG_READ_ONLY, block_buf,
+ lsdel_proc, &lsd);
+ if (retval) {
+ com_err("ls_deleted_inodes", retval,
+ "while calling ext2fs_block_iterate2");
+ goto next;
+ }
}
- if (lsd.free_blocks && !lsd.bad_blocks) {
+ if (lsd.free_blocks && !lsd.bad_blocks ||
+ ext2fs_has_inline_data(current_fs, ino)) {
if (num_delarray >= max_delarray) {
max_delarray += 50;
delarray = realloc(delarray,
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 23/32] debugfs: make undel cmd support inline data
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (21 preceding siblings ...)
2012-04-16 11:39 ` [PATCH 22/32] debugfs: make lsdel " Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:39 ` [PATCH 24/32] debugfs: make dump and cat " Zheng Liu
` (9 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
Inode with inline data doesn't need to mark blocks.
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
debugfs/debugfs.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c
index 517751f..b591b9b 100644
--- a/debugfs/debugfs.c
+++ b/debugfs/debugfs.c
@@ -1435,8 +1435,9 @@ void do_undel(int argc, char *argv[])
if (debugfs_write_inode(ino, &inode, argv[0]))
return;
- ext2fs_block_iterate3(current_fs, ino, BLOCK_FLAG_READ_ONLY, NULL,
- mark_blocks_proc, NULL);
+ if (!ext2fs_has_inline_data(current_fs, ino))
+ ext2fs_block_iterate3(current_fs, ino, BLOCK_FLAG_READ_ONLY, NULL,
+ mark_blocks_proc, NULL);
ext2fs_inode_alloc_stats2(current_fs, ino, +1, 0);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 24/32] debugfs: make dump and cat cmd support inline data
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (22 preceding siblings ...)
2012-04-16 11:39 ` [PATCH 23/32] debugfs: make undel " Zheng Liu
@ 2012-04-16 11:39 ` Zheng Liu
2012-04-16 11:40 ` [PATCH 25/32] debugfs: make rdump " Zheng Liu
` (8 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:39 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
dump and cat command use the same function to read data. We can direclty read
the data from inode.
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
debugfs/dump.c | 30 ++++++++++++++++++++++++++++++
1 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/debugfs/dump.c b/debugfs/dump.c
index a15a0b7..10ebe7a 100644
--- a/debugfs/dump.c
+++ b/debugfs/dump.c
@@ -113,6 +113,36 @@ static void dump_file(const char *cmdname, ext2_ino_t ino, int fd,
if (debugfs_read_inode(ino, &inode, cmdname))
return;
+ if (ext2fs_has_inline_data(current_fs, ino)) {
+ struct ext2_inode_large *inode;
+ struct inline_data idata;
+ void *inline_start;
+ int inline_size;
+
+ retval = ext2fs_get_mem(EXT2_INODE_SIZE(current_fs->super),
+ &inode);
+ if (retval)
+ return;
+
+ retval = ext2fs_read_inode_full(current_fs, ino, (void *)inode,
+ EXT2_INODE_SIZE(current_fs->super));
+ if (retval)
+ goto out;
+ write(fd, inode->i_block, EXT4_MIN_INLINE_DATA_SIZE);
+
+ ext2fs_iget_extra_inode(current_fs, inode, &idata);
+ if (idata.inline_off == EXT4_MIN_INLINE_DATA_SIZE)
+ goto out;
+
+ inline_start = ext2fs_get_inline_xattr_pos(inode, &idata);
+ inline_size = idata.inline_size - EXT4_MIN_INLINE_DATA_SIZE;
+ write(fd, inline_start, inline_size);
+
+out:
+ ext2fs_free_mem(&inode);
+ return;
+ }
+
retval = ext2fs_file_open(current_fs, ino, 0, &e2_file);
if (retval) {
com_err(cmdname, retval, "while opening ext2 file");
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 25/32] debugfs: make rdump cmd support inline data
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (23 preceding siblings ...)
2012-04-16 11:39 ` [PATCH 24/32] debugfs: make dump and cat " Zheng Liu
@ 2012-04-16 11:40 ` Zheng Liu
2012-04-16 11:40 ` [PATCH 26/32] debugfs: make dirsearch " Zheng Liu
` (7 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:40 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
debugfs/dump.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/debugfs/dump.c b/debugfs/dump.c
index 10ebe7a..84de606 100644
--- a/debugfs/dump.c
+++ b/debugfs/dump.c
@@ -308,8 +308,12 @@ static void rdump_inode(ext2_ino_t ino, struct ext2_inode *inode,
goto errout;
}
- retval = ext2fs_dir_iterate(current_fs, ino, 0, 0,
- rdump_dirent, (void *) fullname);
+ if (ext2fs_has_inline_data(current_fs, ino))
+ retval = ext2fs_inline_data_iterate(current_fs, ino, 0, 0,
+ rdump_dirent, (void *) fullname);
+ else
+ retval = ext2fs_dir_iterate(current_fs, ino, 0, 0,
+ rdump_dirent, (void *) fullname);
if (retval)
com_err("rdump", retval, "while dumping %s", fullname);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 26/32] debugfs: make dirsearch cmd support inline data
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (24 preceding siblings ...)
2012-04-16 11:40 ` [PATCH 25/32] debugfs: make rdump " Zheng Liu
@ 2012-04-16 11:40 ` Zheng Liu
2012-04-16 11:40 ` [PATCH 27/32] debugfs: make bma " Zheng Liu
` (6 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:40 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
debugfs/htree.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/debugfs/htree.c b/debugfs/htree.c
index 05745eb..0e77c31 100644
--- a/debugfs/htree.c
+++ b/debugfs/htree.c
@@ -354,9 +354,15 @@ void do_dirsearch(int argc, char *argv[])
pb.search_name = argv[2];
pb.len = strlen(pb.search_name);
+ if (ext2fs_has_inline_data(current_fs, inode))
+ if (ext2fs_inline_data_search_dir(current_fs, inode, argv[2],
+ strlen(argv[2])) == 0)
+ goto out;
+
ext2fs_block_iterate3(current_fs, inode, BLOCK_FLAG_READ_ONLY, 0,
search_dir_block, &pb);
+out:
free(pb.buf);
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 27/32] debugfs: make bma cmd support inline data
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (25 preceding siblings ...)
2012-04-16 11:40 ` [PATCH 26/32] debugfs: make dirsearch " Zheng Liu
@ 2012-04-16 11:40 ` Zheng Liu
2012-04-16 11:40 ` [PATCH 28/32] e2fsck: add three problem descriptions in pass1 Zheng Liu
` (5 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:40 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
Now this command returns inode's phy block when this inode has inline data.
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
lib/ext2fs/bmap.c | 16 ++++++++++++++++
1 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/lib/ext2fs/bmap.c b/lib/ext2fs/bmap.c
index 16d51e0..101fe90 100644
--- a/lib/ext2fs/bmap.c
+++ b/lib/ext2fs/bmap.c
@@ -264,6 +264,22 @@ errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode,
block_buf = buf;
}
+ if (inode->i_flags & EXT4_INLINE_DATA_FL) {
+ unsigned long group, block, offset;
+
+ group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
+ if (group > fs->group_desc_count)
+ return EXT2_ET_BAD_INODE_NUM;
+ offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
+ EXT2_INODE_SIZE(fs->super);
+ block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
+ if (!ext2fs_inode_table_loc(fs, (unsigned) group))
+ return EXT2_ET_MISSING_INODE_TABLE;
+ *phys_blk = ext2fs_inode_table_loc(fs, group) + block;
+
+ goto done;
+ }
+
if (inode->i_flags & EXT4_EXTENTS_FL) {
retval = ext2fs_extent_open2(fs, ino, inode, &handle);
if (retval)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 28/32] e2fsck: add three problem descriptions in pass1
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (26 preceding siblings ...)
2012-04-16 11:40 ` [PATCH 27/32] debugfs: make bma " Zheng Liu
@ 2012-04-16 11:40 ` Zheng Liu
2012-04-16 11:40 ` [PATCH 29/32] e2fsck: check incorrect inline data flag Zheng Liu
` (4 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:40 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
In pass1, we will meet three problems. So add descriptions in problem table.
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
e2fsck/problem.c | 15 +++++++++++++++
e2fsck/problem.h | 9 +++++++++
2 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index d51a408..de6153d 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -946,6 +946,21 @@ static struct e2fsck_problem problem_table[] = {
N_("@i %i has zero length extent\n\t(@n logical @b %c, physical @b %b)\n"),
PROMPT_CLEAR, 0 },
+ /* INLINE_DATA is set and EXT_ATTR is not set */
+ { PR_1_INLINE_DATA_AND_EXT_ATTR,
+ N_("INLINE_DATA is set in @S, but it is missing EXT_ATTR feature\n"),
+ PROMPT_FIX, 0 },
+
+ /* Inode has inline data, superblock missing INCOMPAT_INLINE_DATA feature */
+ { PR_1_INLINE_DATA_FEATURE,
+ N_("@i %i is in inline data format, but @S is missing INLINEDATA feature\n"),
+ PROMPT_CLEAR, PR_PREEN_OK },
+
+ /* INLINE_DATA_FL flag set on a non-inline-data filesystem */
+ { PR_1_INLINE_DATA_SET,
+ N_("@i %i has INLINE_DATA_FL flag set on @f without inline data support.\n"),
+ PROMPT_CLEAR, 0 },
+
/* Pass 1b errors */
/* Pass 1B: Rescan for duplicate/bad blocks */
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index 07df810..79b6825 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -558,6 +558,15 @@ struct problem_context {
/* Extent has zero length */
#define PR_1_EXTENT_LENGTH_ZERO 0x010066
+/* INLINE_DATA is set and EXT_ATTR is not set */
+#define PR_1_INLINE_DATA_AND_EXT_ATTR 0x010067
+
+/* Inode has inline data, superblock missing INCOMPAT_INLINE_DATA feature */
+#define PR_1_INLINE_DATA_FEATURE 0x010068
+
+/* INLINE_DATA_FL flag set on a non-inline-data capable filesystem */
+#define PR_1_INLINE_DATA_SET 0x010069
+
/*
* Pass 1b errors
*/
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 29/32] e2fsck: check incorrect inline data flag
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (27 preceding siblings ...)
2012-04-16 11:40 ` [PATCH 28/32] e2fsck: add three problem descriptions in pass1 Zheng Liu
@ 2012-04-16 11:40 ` Zheng Liu
2012-04-16 11:40 ` [PATCH 30/32] e2fsck: make pass1 support inline data Zheng Liu
` (3 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:40 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
First, we need to check whether or not EXT_ATTR feature is set when
INLINE_DATA feature is set. Then we will check inode flag to set
EXT4_INLINE_DATA_FL flag. If the user doesn't set this flag, INLINE_DATA
feature will be clear.
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
e2fsck/pass1.c | 33 ++++++++++++++++++++++++++++++++-
1 files changed, 32 insertions(+), 1 deletions(-)
diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index c7645d1..023d8ed 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -559,7 +559,7 @@ void e2fsck_pass1(e2fsck_t ctx)
struct ext2_super_block *sb = ctx->fs->super;
const char *old_op;
unsigned int save_type;
- int imagic_fs, extent_fs;
+ int imagic_fs, extent_fs, inlinedata_fs;
int busted_fs_time = 0;
int inode_size;
@@ -592,6 +592,7 @@ void e2fsck_pass1(e2fsck_t ctx)
imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
extent_fs = (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS);
+ inlinedata_fs = (sb->s_feature_incompat & EXT4_FEATURE_INCOMPAT_INLINE_DATA);
/*
* Allocate bitmaps structures
@@ -722,6 +723,17 @@ void e2fsck_pass1(e2fsck_t ctx)
ext2fs_mark_block_bitmap2(ctx->block_found_map,
fs->super->s_mmp_block);
+ /*
+ * If INLINE_DATA is set and EXT_ATTR doesn't, EXT_ATTR needs to be set
+ * because INLINE_DATA depends on it. So the user need to determine
+ * whether EXT_ATTR is set or not.
+ */
+ if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
+ inlinedata_fs) {
+ if (fix_problem(ctx, PR_1_INLINE_DATA_AND_EXT_ATTR, &pctx))
+ ext2fs_mark_super_dirty(fs);
+ }
+
while (1) {
if (ino % (fs->super->s_inodes_per_group * 4) == 1) {
if (e2fsck_mmp_update(fs))
@@ -762,6 +774,25 @@ void e2fsck_pass1(e2fsck_t ctx)
}
/*
+ * Test for incorrect inline data flags settings.
+ *
+ * TODO: check EXT2_ROOT_INO when '/' supports inline data
+ * feature.
+ */
+ if ((inode->i_flags & EXT4_INLINE_DATA_FL) && !inlinedata_fs &&
+ (ino >= EXT2_FIRST_INODE(fs->super))) {
+ if (ext2fs_inline_data_header_verify(fs, inode) == 0 &&
+ fix_problem(ctx, PR_1_INLINE_DATA_FEATURE, &pctx)) {
+ sb->s_feature_incompat |= EXT4_FEATURE_INCOMPAT_INLINE_DATA;
+ ext2fs_mark_super_dirty(fs);
+ inlinedata_fs = 1;
+ } else if (fix_problem(ctx, PR_1_INLINE_DATA_SET, &pctx)) {
+ e2fsck_clear_inode(ctx, ino, inode, 0, "pass1");
+ continue;
+ }
+ }
+
+ /*
* Test for incorrect extent flag settings.
*
* On big-endian machines we must be careful:
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 30/32] e2fsck: make pass1 support inline data
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (28 preceding siblings ...)
2012-04-16 11:40 ` [PATCH 29/32] e2fsck: check incorrect inline data flag Zheng Liu
@ 2012-04-16 11:40 ` Zheng Liu
2012-04-16 11:40 ` [PATCH 31/32] libext2fs: add read/write inline data functions Zheng Liu
` (2 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:40 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
e2fsck/pass1.c | 37 ++++++++++++++++++++++++++++++++++---
e2fsck/pass1b.c | 5 +++--
lib/ext2fs/dblist_dir.c | 8 ++++++--
3 files changed, 43 insertions(+), 7 deletions(-)
diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index 023d8ed..2b1873f 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -304,6 +304,10 @@ static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
goto fix;
}
+ /* not do the following checks for inline_data */
+ if (strcmp(EXT2_EXT_ATTR_NAME(entry), "data") == 0)
+ goto next;
+
/* attribute len eats this space */
remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
@@ -331,6 +335,7 @@ static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
goto fix;
}
+next:
remain -= entry->e_value_size;
entry = EXT2_EXT_ATTR_NEXT(entry);
@@ -1158,7 +1163,8 @@ void e2fsck_pass1(e2fsck_t ctx)
ctx->fs_sockets_count++;
} else
mark_inode_bad(ctx, ino);
- if (!(inode->i_flags & EXT4_EXTENTS_FL)) {
+ if (!(inode->i_flags & EXT4_EXTENTS_FL) &&
+ !(inode->i_flags & EXT4_INLINE_DATA_FL)) {
if (inode->i_block[EXT2_IND_BLOCK])
ctx->fs_ind_count++;
if (inode->i_block[EXT2_DIND_BLOCK])
@@ -1167,6 +1173,7 @@ void e2fsck_pass1(e2fsck_t ctx)
ctx->fs_tind_count++;
}
if (!(inode->i_flags & EXT4_EXTENTS_FL) &&
+ !(inode->i_flags & EXT4_INLINE_DATA_FL) &&
(inode->i_block[EXT2_IND_BLOCK] ||
inode->i_block[EXT2_DIND_BLOCK] ||
inode->i_block[EXT2_TIND_BLOCK] ||
@@ -1980,6 +1987,22 @@ static void check_blocks_extents(e2fsck_t ctx, struct problem_context *pctx,
ext2fs_extent_free(ehandle);
}
+static void check_blocks_inline_data(e2fsck_t ctx, struct problem_context *pctx,
+ struct process_block_struct *pb)
+{
+ if (pb->is_dir) {
+ pctx->errcode = ext2fs_add_dir_block2(ctx->fs->dblist,
+ pb->ino, 0, 0);
+ if (pctx->errcode) {
+ pctx->blk = 0;
+ pctx->num = 0;
+ fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
+ /* Should never get here */
+ ctx->flags |= E2F_FLAG_ABORT;
+ }
+ }
+}
+
/*
* This subroutine is called on each inode to account for all of the
* blocks used by that inode.
@@ -1994,6 +2017,7 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
int bad_size = 0;
int dirty_inode = 0;
int extent_fs;
+ int inlinedata_fs;
__u64 size;
pb.ino = ino;
@@ -2017,6 +2041,8 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
extent_fs = (ctx->fs->super->s_feature_incompat &
EXT3_FEATURE_INCOMPAT_EXTENTS);
+ inlinedata_fs = (ctx->fs->super->s_feature_incompat &
+ EXT4_FEATURE_INCOMPAT_INLINE_DATA);
if (inode->i_flags & EXT2_COMPRBLK_FL) {
if (fs->super->s_feature_incompat &
@@ -2040,6 +2066,8 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
if (ext2fs_inode_has_valid_blocks2(fs, inode)) {
if (extent_fs && (inode->i_flags & EXT4_EXTENTS_FL))
check_blocks_extents(ctx, pctx, &pb);
+ else if (inlinedata_fs && (inode->i_flags & EXT4_INLINE_DATA_FL))
+ check_blocks_inline_data(ctx, pctx, &pb);
else {
pctx->errcode = ext2fs_block_iterate3(fs, ino,
pb.is_dir ? BLOCK_FLAG_HOLE : 0,
@@ -2082,7 +2110,8 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
}
}
- if (!pb.num_blocks && pb.is_dir) {
+ if (!pb.num_blocks && pb.is_dir &&
+ !(inode->i_flags & EXT4_INLINE_DATA_FL)) {
if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
e2fsck_clear_inode(ctx, ino, inode, 0, "check_blocks");
ctx->fs_directory_count--;
@@ -2108,7 +2137,9 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
#endif
if (pb.is_dir) {
int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
- if (inode->i_size & (fs->blocksize - 1))
+ if (inode->i_flags & EXT4_INLINE_DATA_FL)
+ ;
+ else if (inode->i_size & (fs->blocksize - 1))
bad_size = 5;
else if (nblock > (pb.last_block + 1))
bad_size = 1;
diff --git a/e2fsck/pass1b.c b/e2fsck/pass1b.c
index 93fb630..6ff2af6 100644
--- a/e2fsck/pass1b.c
+++ b/e2fsck/pass1b.c
@@ -315,8 +315,9 @@ static void pass1b(e2fsck_t ctx, char *block_buf)
pb.inode = &inode;
pb.cur_cluster = ~0;
- if (ext2fs_inode_has_valid_blocks2(fs, &inode) ||
- (ino == EXT2_BAD_INO))
+ if ((ext2fs_inode_has_valid_blocks2(fs, &inode) ||
+ (ino == EXT2_BAD_INO)) &&
+ !(inode.i_flags & EXT4_INLINE_DATA_FL))
pctx.errcode = ext2fs_block_iterate3(fs, ino,
BLOCK_FLAG_READ_ONLY, block_buf,
process_pass1b_block, &pb);
diff --git a/lib/ext2fs/dblist_dir.c b/lib/ext2fs/dblist_dir.c
index d4d5111..cc54d7a 100644
--- a/lib/ext2fs/dblist_dir.c
+++ b/lib/ext2fs/dblist_dir.c
@@ -72,8 +72,12 @@ static int db_dir_proc(ext2_filsys fs, struct ext2_db_entry2 *db_info,
ctx->dir = db_info->ino;
ctx->errcode = 0;
- ret = ext2fs_process_dir_block(fs, &db_info->blk,
- db_info->blockcnt, 0, 0, priv_data);
+ if (ext2fs_has_inline_data(fs, ctx->dir))
+ ret = ext2fs_inline_data_iterate2(fs, ctx->dir, 0, NULL,
+ ctx->func, ctx->priv_data);
+ else
+ ret = ext2fs_process_dir_block(fs, &db_info->blk,
+ db_info->blockcnt, 0, 0, priv_data);
if ((ret & BLOCK_ABORT) && !ctx->errcode)
return DBLIST_ABORT;
return 0;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 31/32] libext2fs: add read/write inline data functions
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (29 preceding siblings ...)
2012-04-16 11:40 ` [PATCH 30/32] e2fsck: make pass1 support inline data Zheng Liu
@ 2012-04-16 11:40 ` Zheng Liu
2012-04-16 11:40 ` [PATCH 32/32] e2fsck: check inline data in pass2 Zheng Liu
2012-04-16 15:08 ` [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Andreas Dilger
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:40 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
Add read/write inline data functions for pass2.
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
lib/ext2fs/dirblock.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++
lib/ext2fs/ext2fs.h | 6 ++++
2 files changed, 68 insertions(+), 0 deletions(-)
diff --git a/lib/ext2fs/dirblock.c b/lib/ext2fs/dirblock.c
index cb3a104..8fdffe5 100644
--- a/lib/ext2fs/dirblock.c
+++ b/lib/ext2fs/dirblock.c
@@ -71,6 +71,45 @@ errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
return ext2fs_read_dir_block3(fs, block, buf, 0);
}
+errcode_t ext2fs_read_dir_inline_data(ext2_filsys fs, ext2_ino_t ino, void *buf)
+{
+ struct ext2_inode_large *inode;
+ struct inline_data idata;
+
+ ext2fs_get_mem(EXT2_INODE_SIZE(fs->super), &inode);
+ ext2fs_read_inode_full(fs, ino, (void *)inode, EXT2_INODE_SIZE(fs->super));
+
+ if (!(inode->i_flags & EXT4_INLINE_DATA_FL))
+ return -1;
+
+ memcpy(buf, inode->i_block, EXT4_MIN_INLINE_DATA_SIZE);
+
+ ext2fs_free_mem(&inode);
+ return 0;
+}
+
+errcode_t ext2fs_read_dir_inline_data_more(ext2_filsys fs, ext2_ino_t ino, void *buf)
+{
+ struct ext2_inode_large *inode;
+ struct inline_data idata;
+
+ ext2fs_get_mem(EXT2_INODE_SIZE(fs->super), &inode);
+ ext2fs_read_inode_full(fs, ino, (void *)inode, EXT2_INODE_SIZE(fs->super));
+
+ if (!(inode->i_flags & EXT4_INLINE_DATA_FL))
+ return -1;
+
+ ext2fs_iget_extra_inode(fs, inode, &idata);
+ if (idata.inline_size == EXT4_MIN_INLINE_DATA_SIZE)
+ return 0;
+
+ memcpy(buf + EXT4_MIN_INLINE_DATA_SIZE,
+ ext2fs_get_inline_xattr_pos(inode, &idata),
+ idata.inline_size - EXT4_MIN_INLINE_DATA_SIZE);
+
+ ext2fs_free_mem(&inode);
+ return 0;
+}
errcode_t ext2fs_write_dir_block3(ext2_filsys fs, blk64_t block,
void *inbuf, int flags EXT2FS_ATTR((unused)))
@@ -125,3 +164,26 @@ errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
return ext2fs_write_dir_block3(fs, block, inbuf, 0);
}
+errcode_t ext2fs_write_dir_inline_data(ext2_filsys fs, ext2_ino_t ino, void *buf)
+{
+ struct ext2_inode_large *inode;
+ struct inline_data idata;
+
+ ext2fs_get_mem(EXT2_INODE_SIZE(fs->super), &inode);
+ ext2fs_read_inode_full(fs, ino, (void *)inode, EXT2_INODE_SIZE(fs->super));
+
+ memcpy(inode->i_block, buf, EXT4_MIN_INLINE_DATA_SIZE);
+
+ ext2fs_iget_extra_inode(fs, inode, &idata);
+ if (idata.inline_size == EXT4_MIN_INLINE_DATA_SIZE)
+ goto out;
+
+ memcpy(ext2fs_get_inline_xattr_pos(inode, &idata),
+ buf + EXT4_MIN_INLINE_DATA_SIZE,
+ idata.inline_size - EXT4_MIN_INLINE_DATA_SIZE);
+
+out:
+ ext2fs_write_inode_full(fs, ino, (void *)inode, EXT2_INODE_SIZE(fs->super));
+ ext2fs_free_mem(&inode);
+ return 0;
+}
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index cb1b58e..dcc9700 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -1009,12 +1009,18 @@ extern errcode_t ext2fs_read_dir_block2(ext2_filsys fs, blk_t block,
void *buf, int flags);
extern errcode_t ext2fs_read_dir_block3(ext2_filsys fs, blk64_t block,
void *buf, int flags);
+extern errcode_t ext2fs_read_dir_inline_data(ext2_filsys fs, ext2_ino_t ino,
+ void *buf);
+extern errcode_t ext2fs_read_dir_inline_data_more(ext2_filsys fs, ext2_ino_t ino,
+ void *buf);
extern errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
void *buf);
extern errcode_t ext2fs_write_dir_block2(ext2_filsys fs, blk_t block,
void *buf, int flags);
extern errcode_t ext2fs_write_dir_block3(ext2_filsys fs, blk64_t block,
void *buf, int flags);
+extern errcode_t ext2fs_write_dir_inline_data(ext2_filsys fs, ext2_ino_t ino,
+ void *buf);
/* dirhash.c */
extern errcode_t ext2fs_dirhash(int version, const char *name, int len,
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 32/32] e2fsck: check inline data in pass2
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (30 preceding siblings ...)
2012-04-16 11:40 ` [PATCH 31/32] libext2fs: add read/write inline data functions Zheng Liu
@ 2012-04-16 11:40 ` Zheng Liu
2012-04-16 15:08 ` [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Andreas Dilger
32 siblings, 0 replies; 35+ messages in thread
From: Zheng Liu @ 2012-04-16 11:40 UTC (permalink / raw)
To: linux-ext4; +Cc: Zheng Liu
From: Zheng Liu <wenqing.lz@taobao.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
e2fsck/pass2.c | 50 ++++++++++++++++++++++++++++++++++++++-------
lib/ext2fs/inline_data.c | 4 +-
2 files changed, 44 insertions(+), 10 deletions(-)
diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c
index 882950d..0b902f2 100644
--- a/e2fsck/pass2.c
+++ b/e2fsck/pass2.c
@@ -70,6 +70,7 @@ static int allocate_dir_block(e2fsck_t ctx,
static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
static int htree_depth(struct dx_dir_info *dx_dir,
struct dx_dirblock_info *dx_db);
+static int is_last_entry(ext2_filsys fs, ext2_ino_t ino, unsigned int offset);
static EXT2_QSORT_TYPE special_dir_block_cmp(const void *a, const void *b);
struct check_dir_struct {
@@ -715,6 +716,7 @@ static int check_dir_block(ext2_filsys fs,
struct dx_dirblock_info *dx_db = 0;
#endif /* ENABLE_HTREE */
struct ext2_dir_entry *dirent, *prev;
+ struct ext2_inode inode;
ext2_dirhash_t hash;
unsigned int offset = 0;
int dir_modified = 0;
@@ -759,7 +761,8 @@ static int check_dir_block(ext2_filsys fs,
cd->pctx.dirent = 0;
cd->pctx.num = 0;
- if (db->blk == 0) {
+ /* We don't need to allocate dir blocks for inline_data dir */
+ if (db->blk == 0 && !ext2fs_has_inline_data(fs, db->ino)) {
if (allocate_dir_block(ctx, db, buf, &cd->pctx))
return 0;
block_nr = db->blk;
@@ -780,7 +783,15 @@ static int check_dir_block(ext2_filsys fs,
#endif
ehandler_operation(_("reading directory block"));
- cd->pctx.errcode = ext2fs_read_dir_block3(fs, block_nr, buf, 0);
+ ext2fs_read_inode(fs, ino, &inode);
+ if (inode.i_flags & EXT4_INLINE_DATA_FL) {
+ cd->pctx.errcode = ext2fs_read_dir_inline_data(fs, ino, buf);
+ if (!cd->pctx.errcode)
+ cd->pctx.errcode = ext2fs_read_dir_inline_data_more(fs,
+ ino, buf);
+ } else {
+ cd->pctx.errcode = ext2fs_read_dir_block3(fs, block_nr, buf, 0);
+ }
ehandler_operation(0);
if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
cd->pctx.errcode = 0; /* We'll handle this ourselves */
@@ -1107,7 +1118,7 @@ out_htree:
(void) ext2fs_get_rec_len(fs, dirent, &rec_len);
offset += rec_len;
dot_state++;
- } while (offset < fs->blocksize);
+ } while (is_last_entry(fs, ino, offset));
#if 0
printf("\n");
#endif
@@ -1125,14 +1136,29 @@ out_htree:
}
#endif /* ENABLE_HTREE */
if (offset != fs->blocksize) {
- cd->pctx.num = rec_len - fs->blocksize + offset;
- if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
- dirent->rec_len = cd->pctx.num;
- dir_modified++;
+ if (!(inode.i_flags & EXT4_INLINE_DATA_FL)) {
+ cd->pctx.errcode = rec_len - fs->blocksize + offset;
+ if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
+ dirent->rec_len = cd->pctx.num;
+ dir_modified++;
+ }
+ } else {
+ if (offset != ext2fs_inline_data_size(fs, ino)) {
+ cd->pctx.errcode = rec_len + offset -
+ ext2fs_inline_data_size(fs, ino);
+ if (fix_problem(ctx, PR_2_FINAL_RECLEN,
+ &cd->pctx)) {
+ dirent->rec_len = cd->pctx.num;
+ dir_modified++;
+ }
+ }
}
}
if (dir_modified) {
- cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
+ if (inode.i_flags & EXT4_INLINE_DATA_FL)
+ cd->pctx.errcode = ext2fs_write_dir_inline_data(fs, ino, buf);
+ else
+ cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
if (cd->pctx.errcode) {
if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
&cd->pctx))
@@ -1483,3 +1509,11 @@ static int allocate_dir_block(e2fsck_t ctx,
return 0;
}
+
+static int is_last_entry(ext2_filsys fs, ext2_ino_t ino, unsigned int offset)
+{
+ if (ext2fs_has_inline_data(fs, ino))
+ return (offset < ext2fs_inline_data_size(fs, ino));
+ else
+ return (offset < fs->blocksize);
+}
diff --git a/lib/ext2fs/inline_data.c b/lib/ext2fs/inline_data.c
index 4ebd592..8dc7b8c 100644
--- a/lib/ext2fs/inline_data.c
+++ b/lib/ext2fs/inline_data.c
@@ -584,7 +584,7 @@ int ext2fs_inline_data_in_extra(ext2_filsys fs, ext2_ino_t ino)
ext2fs_get_mem(EXT2_INODE_SIZE(fs->super), &inode);
ext2fs_read_inode_full(fs, ino, inode, EXT2_INODE_SIZE(fs->super));
- ext2fs_iget_extra_inode(fs, inode, &idata);
+ ext2fs_iget_extra_inode(fs, (void *)inode, &idata);
ext2fs_free_mem(&inode);
if (idata.inline_off == 0 ||
idata.inline_size == EXT4_MIN_INLINE_DATA_SIZE)
@@ -601,7 +601,7 @@ int ext2fs_inline_data_size(ext2_filsys fs, ext2_ino_t ino)
inode = (struct ext2_inode *) malloc(EXT2_INODE_SIZE(fs->super));
ext2fs_read_inode_full(fs, ino, inode, EXT2_INODE_SIZE(fs->super));
- ext2fs_iget_extra_inode(fs, inode, &idata);
+ ext2fs_iget_extra_inode(fs, (void *)inode, &idata);
free(inode);
if (idata.inline_off == 0)
return 0;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data
2012-04-16 11:39 [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Zheng Liu
` (31 preceding siblings ...)
2012-04-16 11:40 ` [PATCH 32/32] e2fsck: check inline data in pass2 Zheng Liu
@ 2012-04-16 15:08 ` Andreas Dilger
2012-04-16 15:10 ` Tao Ma
32 siblings, 1 reply; 35+ messages in thread
From: Andreas Dilger @ 2012-04-16 15:08 UTC (permalink / raw)
To: Zheng Liu; +Cc: linux-ext4, Zheng Liu
On 2012-04-16, at 4:39 AM, Zheng Liu wrote:
> Here is v2 for making e2fsprogs support inline data. Now debugfs
> supports inline data in read-write mode. Meanwhile e2fsck has
> been improved to support inline data feature.
>
> v1->v2:
> * [mke2fs] automatically set EXT_ATTR feature when INLINE_DATA is set
> * [debugfs] supports read-write mode
As with the previous patch series, there is a need to show some
benchmark data that indicates how much improvement this feature
provides. Some examples would include percentage of directories
stored inline (e.g. in a typical distro installation), performance
improvement (e.g. cold-cache filesystem traversal). It is likely
that these improvements will be more visible with bigalloc enabled
for a large cluster size (e.g. space savings).
Without a clear indication of performance improvement, the patch
cannot be included due to added complexity and unclear benefits.
> In mke2fs, EXT4_FEATURE_INCOMPAT_INLINE_DATA is set to 0x2000 to
> consist with kernel. When making a new ext4 file system with
> INLINE_DATA feature, mke2fs will check whether EXT_ATTR is set or
> not. If it is not set, mke2fs will mark it automatically because
> INLINE_DATA depends on it.
>
> In debugfs, it can support inline data in read-write mode. Now
> there is two problems that need to be solved. No matter whether
> the size of data is fit into inline data or not, 'write' command
> writes the data into disk blocks rather than inode itself. 'mkdir'
> command will expand dir to a new disk block when inode->i_block
> has full because Tao found a performance regression when a huge
> number of dirs are added and removed in EA space. It causes that
> the code in kernel might be changed. So now 'mkdir' cmd doesn't
> add a new dir entry in EA space.
>
> TODO list:
> * [mke2fs] initialize ROOT dir with inline data flag
> * [mke2fs] initialize LOST+FOUND dir with inline data flag
Note that it does not make sense to store lost+found inline. It
is purposely created with multiple leaf blocks so that blocks
do not need to be allocated during e2fsck runs. Probably the
same is true for root - it will almost certainly immediately
be moved out of the inode due to file creations.
Cheers, Andreas
> * [debugfs] 'write' cmd writes the data into inode itself
> * [debugfs] 'mkdir' cmd add dir entry into EA space
>
> Regards,
> Zheng
>
> libext2fs: add EXT4_FEATURE_INCOMPAT_INLINE_DATA flag
> mke2fs: make it support inline data feature
> libext2fs: add inline_data feature
> mke2fs: add inline_data feature in mke2fs's manpage
> libext2fs: add ext2fs_find_entry_ext_attr function
> libext2fs: add EXT4_INLINE_DATA_FL flag for inode
> libext2fs: add data structures for inline data feature
> libext2fs: add inline_data file
> debugfs: make ncheck cmd support inline data
> debugfs: make chroot and cd cmd support inline data
> debugfs: make ls cmd support inline data
> debugfs: make stat cmd support inline data
> debufs: make blocks cmd support inline data
> debugfs: make filefrag cmd support inline data
> debugfs: make link cmd support inline data
> debugfs: make unlink cmd support inline data
> debugfs: make mkdir cmd support inline data
> debugfs: make rmdir cmd support inline data
> debugfs: make rm and kill_file cmd support inline data
> debugfs: make pwd cmd support inline data
> debugfs: make expand_dir cmd support inline data
> debugfs: make lsdel cmd support inline data
> debugfs: make undel cmd support inline data
> debugfs: make dump and cat cmd support inline data
> debugfs: make rdump cmd support inline data
> debugfs: make dirsearch cmd support inline data
> debugfs: make bma cmd support inline data
> e2fsck: add three problem descriptions in pass1
> e2fsck: check incorrect inline data flag
> e2fsck: make pass1 support inline data
> libext2fs: add read/write inline data functions
> e2fsck: check inline data in pass2
>
> debugfs/debugfs.c | 25 ++-
> debugfs/dump.c | 38 +++-
> debugfs/filefrag.c | 30 ++-
> debugfs/htree.c | 6 +
> debugfs/ls.c | 8 +-
> debugfs/lsdel.c | 19 +-
> debugfs/ncheck.c | 8 +-
> e2fsck/pass1.c | 70 ++++-
> e2fsck/pass1b.c | 5 +-
> e2fsck/pass2.c | 50 +++-
> e2fsck/problem.c | 15 +
> e2fsck/problem.h | 9 +
> lib/e2p/feature.c | 2 +
> lib/ext2fs/Makefile.in | 5 +
> lib/ext2fs/Makefile.pq | 1 +
> lib/ext2fs/bmap.c | 16 +
> lib/ext2fs/dblist_dir.c | 8 +-
> lib/ext2fs/dirblock.c | 62 ++++
> lib/ext2fs/expanddir.c | 8 +-
> lib/ext2fs/ext2_ext_attr.h | 4 +
> lib/ext2fs/ext2_fs.h | 9 +
> lib/ext2fs/ext2fs.h | 69 ++++-
> lib/ext2fs/ext_attr.c | 26 ++
> lib/ext2fs/get_pathname.c | 7 +-
> lib/ext2fs/inline_data.c | 715 ++++++++++++++++++++++++++++++++++++++++++++
> lib/ext2fs/link.c | 9 +-
> lib/ext2fs/lookup.c | 6 +-
> lib/ext2fs/mkdir.c | 4 +
> lib/ext2fs/unlink.c | 9 +-
> misc/mke2fs.8.in | 3 +
> misc/mke2fs.c | 10 +-
> 31 files changed, 1197 insertions(+), 59 deletions(-)
> --
> To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
Cheers, Andreas
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data
2012-04-16 15:08 ` [PATCH 00/32] e2fsprogs: make e2fsprogs support inline data Andreas Dilger
@ 2012-04-16 15:10 ` Tao Ma
0 siblings, 0 replies; 35+ messages in thread
From: Tao Ma @ 2012-04-16 15:10 UTC (permalink / raw)
To: Andreas Dilger; +Cc: Zheng Liu, linux-ext4
On 04/16/2012 11:08 PM, Andreas Dilger wrote:
> On 2012-04-16, at 4:39 AM, Zheng Liu wrote:
>> Here is v2 for making e2fsprogs support inline data. Now debugfs
>> supports inline data in read-write mode. Meanwhile e2fsck has
>> been improved to support inline data feature.
>>
>> v1->v2:
>> * [mke2fs] automatically set EXT_ATTR feature when INLINE_DATA is set
>> * [debugfs] supports read-write mode
>
> As with the previous patch series, there is a need to show some
> benchmark data that indicates how much improvement this feature
> provides. Some examples would include percentage of directories
> stored inline (e.g. in a typical distro installation), performance
> improvement (e.g. cold-cache filesystem traversal). It is likely
> that these improvements will be more visible with bigalloc enabled
> for a large cluster size (e.g. space savings).
yeah, I am doing some benchmark test and collect the data. They will be
available when I send out the new version.
>
> Without a clear indication of performance improvement, the patch
> cannot be included due to added complexity and unclear benefits.
sure, please wait for the kernel patches. :)
>
>> In mke2fs, EXT4_FEATURE_INCOMPAT_INLINE_DATA is set to 0x2000 to
>> consist with kernel. When making a new ext4 file system with
>> INLINE_DATA feature, mke2fs will check whether EXT_ATTR is set or
>> not. If it is not set, mke2fs will mark it automatically because
>> INLINE_DATA depends on it.
>>
>> In debugfs, it can support inline data in read-write mode. Now
>> there is two problems that need to be solved. No matter whether
>> the size of data is fit into inline data or not, 'write' command
>> writes the data into disk blocks rather than inode itself. 'mkdir'
>> command will expand dir to a new disk block when inode->i_block
>> has full because Tao found a performance regression when a huge
>> number of dirs are added and removed in EA space. It causes that
>> the code in kernel might be changed. So now 'mkdir' cmd doesn't
>> add a new dir entry in EA space.
>>
>> TODO list:
>> * [mke2fs] initialize ROOT dir with inline data flag
>> * [mke2fs] initialize LOST+FOUND dir with inline data flag
>
> Note that it does not make sense to store lost+found inline. It
> is purposely created with multiple leaf blocks so that blocks
> do not need to be allocated during e2fsck runs. Probably the
> same is true for root - it will almost certainly immediately
> be moved out of the inode due to file creations.
fair enough.
Thanks
Tao
>
> Cheers, Andreas
>
>> * [debugfs] 'write' cmd writes the data into inode itself
>> * [debugfs] 'mkdir' cmd add dir entry into EA space
>>
>> Regards,
>> Zheng
>>
>> libext2fs: add EXT4_FEATURE_INCOMPAT_INLINE_DATA flag
>> mke2fs: make it support inline data feature
>> libext2fs: add inline_data feature
>> mke2fs: add inline_data feature in mke2fs's manpage
>> libext2fs: add ext2fs_find_entry_ext_attr function
>> libext2fs: add EXT4_INLINE_DATA_FL flag for inode
>> libext2fs: add data structures for inline data feature
>> libext2fs: add inline_data file
>> debugfs: make ncheck cmd support inline data
>> debugfs: make chroot and cd cmd support inline data
>> debugfs: make ls cmd support inline data
>> debugfs: make stat cmd support inline data
>> debufs: make blocks cmd support inline data
>> debugfs: make filefrag cmd support inline data
>> debugfs: make link cmd support inline data
>> debugfs: make unlink cmd support inline data
>> debugfs: make mkdir cmd support inline data
>> debugfs: make rmdir cmd support inline data
>> debugfs: make rm and kill_file cmd support inline data
>> debugfs: make pwd cmd support inline data
>> debugfs: make expand_dir cmd support inline data
>> debugfs: make lsdel cmd support inline data
>> debugfs: make undel cmd support inline data
>> debugfs: make dump and cat cmd support inline data
>> debugfs: make rdump cmd support inline data
>> debugfs: make dirsearch cmd support inline data
>> debugfs: make bma cmd support inline data
>> e2fsck: add three problem descriptions in pass1
>> e2fsck: check incorrect inline data flag
>> e2fsck: make pass1 support inline data
>> libext2fs: add read/write inline data functions
>> e2fsck: check inline data in pass2
>>
>> debugfs/debugfs.c | 25 ++-
>> debugfs/dump.c | 38 +++-
>> debugfs/filefrag.c | 30 ++-
>> debugfs/htree.c | 6 +
>> debugfs/ls.c | 8 +-
>> debugfs/lsdel.c | 19 +-
>> debugfs/ncheck.c | 8 +-
>> e2fsck/pass1.c | 70 ++++-
>> e2fsck/pass1b.c | 5 +-
>> e2fsck/pass2.c | 50 +++-
>> e2fsck/problem.c | 15 +
>> e2fsck/problem.h | 9 +
>> lib/e2p/feature.c | 2 +
>> lib/ext2fs/Makefile.in | 5 +
>> lib/ext2fs/Makefile.pq | 1 +
>> lib/ext2fs/bmap.c | 16 +
>> lib/ext2fs/dblist_dir.c | 8 +-
>> lib/ext2fs/dirblock.c | 62 ++++
>> lib/ext2fs/expanddir.c | 8 +-
>> lib/ext2fs/ext2_ext_attr.h | 4 +
>> lib/ext2fs/ext2_fs.h | 9 +
>> lib/ext2fs/ext2fs.h | 69 ++++-
>> lib/ext2fs/ext_attr.c | 26 ++
>> lib/ext2fs/get_pathname.c | 7 +-
>> lib/ext2fs/inline_data.c | 715 ++++++++++++++++++++++++++++++++++++++++++++
>> lib/ext2fs/link.c | 9 +-
>> lib/ext2fs/lookup.c | 6 +-
>> lib/ext2fs/mkdir.c | 4 +
>> lib/ext2fs/unlink.c | 9 +-
>> misc/mke2fs.8.in | 3 +
>> misc/mke2fs.c | 10 +-
>> 31 files changed, 1197 insertions(+), 59 deletions(-)
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
> Cheers, Andreas
>
>
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 35+ messages in thread