@@ -842,21 +842,24 @@ xfs_failaddr_t xfs_da3_blkinfo_verify(struct xfs_buf *bp,
struct xfs_parent_name_rec {
__be64 p_ino;
__be32 p_gen;
- __u8 p_namehash[XFS_PARENT_NAME_HASH_SIZE];
+ __u8 p_namehash[];
} __attribute__((packed));
+#define XFS_PARENT_NAME_MAX_SIZE \
+ (sizeof(struct xfs_parent_name_rec) + XFS_PARENT_NAME_HASH_SIZE)
+
static inline unsigned int
xfs_parent_name_rec_sizeof(
unsigned int hashlen)
{
- return offsetof(struct xfs_parent_name_rec, p_namehash) + hashlen;
+ return sizeof(struct xfs_parent_name_rec) + hashlen;
}
static inline unsigned int
xfs_parent_name_hashlen(
unsigned int rec_sizeof)
{
- return rec_sizeof - offsetof(struct xfs_parent_name_rec, p_namehash);
+ return rec_sizeof - sizeof(struct xfs_parent_name_rec);
}
#endif /* __XFS_DA_FORMAT_H__ */
@@ -98,7 +98,7 @@ xfs_init_parent_name_rec(
rec->p_ino = cpu_to_be64(dp->i_ino);
rec->p_gen = cpu_to_be32(VFS_IC(dp)->i_generation);
return xfs_parent_namehash(ip, name, rec->p_namehash,
- sizeof(rec->p_namehash));
+ XFS_PARENT_NAME_HASH_SIZE);
}
/*
@@ -197,7 +197,7 @@ __xfs_parent_init(
parent->args.attr_filter = XFS_ATTR_PARENT;
parent->args.op_flags = XFS_DA_OP_OKNOENT | XFS_DA_OP_LOGGED;
parent->args.name = (const uint8_t *)&parent->rec;
- parent->args.namelen = sizeof(struct xfs_parent_name_rec);
+ parent->args.namelen = 0;
*parentp = parent;
return 0;
@@ -43,8 +43,14 @@ void xfs_parent_irec_to_disk(struct xfs_parent_name_rec *rec, int *reclen,
* the defer ops machinery
*/
struct xfs_parent_defer {
- struct xfs_parent_name_rec rec;
- struct xfs_parent_name_rec old_rec;
+ union {
+ struct xfs_parent_name_rec rec;
+ __u8 dummy1[XFS_PARENT_NAME_MAX_SIZE];
+ };
+ union {
+ struct xfs_parent_name_rec old_rec;
+ __u8 dummy2[XFS_PARENT_NAME_MAX_SIZE];
+ };
struct xfs_da_args args;
bool have_log;
};
@@ -112,7 +118,10 @@ unsigned int xfs_pptr_calc_space_res(struct xfs_mount *mp,
/* Scratchpad memory so that raw parent operations don't burn stack space. */
struct xfs_parent_scratch {
- struct xfs_parent_name_rec rec;
+ union {
+ struct xfs_parent_name_rec rec;
+ __u8 dummy1[XFS_PARENT_NAME_MAX_SIZE];
+ };
struct xfs_da_args args;
};
@@ -424,19 +424,19 @@ static inline unsigned int xfs_calc_pptr_link_overhead(void)
{
return sizeof(struct xfs_attri_log_format) +
xlog_calc_iovec_len(XATTR_NAME_MAX) +
- xlog_calc_iovec_len(sizeof(struct xfs_parent_name_rec));
+ xlog_calc_iovec_len(XFS_PARENT_NAME_MAX_SIZE);
}
static inline unsigned int xfs_calc_pptr_unlink_overhead(void)
{
return sizeof(struct xfs_attri_log_format) +
- xlog_calc_iovec_len(sizeof(struct xfs_parent_name_rec));
+ xlog_calc_iovec_len(XFS_PARENT_NAME_MAX_SIZE);
}
static inline unsigned int xfs_calc_pptr_replace_overhead(void)
{
return sizeof(struct xfs_attri_log_format) +
xlog_calc_iovec_len(XATTR_NAME_MAX) +
xlog_calc_iovec_len(XATTR_NAME_MAX) +
- xlog_calc_iovec_len(sizeof(struct xfs_parent_name_rec));
+ xlog_calc_iovec_len(XFS_PARENT_NAME_MAX_SIZE);
}
/*
@@ -682,19 +682,18 @@ static inline size_t ATTR_NVEC_SIZE(size_t size)
static int
xfs_attri_copy_name_format(
- char *buf,
- uint len,
- struct xfs_parent_name_rec *dst_attri_fmt)
+ char *buf,
+ uint len,
+ uint alfi_name_len,
+ struct xfs_parent_name_rec *dst_attri_fmt)
{
- uint dst_len = ATTR_NVEC_SIZE(sizeof(struct xfs_parent_name_rec));
-
- if (len == dst_len) {
- memcpy((char *)dst_attri_fmt, buf, len);
+ if (alfi_name_len <= len) {
+ memcpy(dst_attri_fmt, buf, alfi_name_len);
return 0;
}
fprintf(stderr, _("%s: bad size of attri name format: %u; expected %u\n"),
- progname, len, dst_len);
+ progname, len, alfi_name_len);
return 1;
}
@@ -764,6 +763,7 @@ xlog_print_trans_attri(
name_ptr = *ptr;
name_len = src_f->alfi_name_len;
error = xlog_print_trans_attri_name(ptr, be32_to_cpu(head->oh_len),
+ src_f->alfi_name_len,
src_f->alfi_attr_filter);
if (error)
goto error;
@@ -777,6 +777,7 @@ xlog_print_trans_attri(
nname_ptr = *ptr;
nname_len = src_f->alfi_nname_len;
error = xlog_print_trans_attri_name(ptr, be32_to_cpu(head->oh_len),
+ src_f->alfi_nname_len,
src_f->alfi_attr_filter);
if (error)
goto error;
@@ -814,10 +815,10 @@ int
xlog_print_trans_attri_name(
char **ptr,
uint src_len,
+ uint alfi_name_len,
uint attr_flags)
{
- struct xfs_parent_name_rec *src_f = NULL;
- uint dst_len;
+ struct xfs_parent_name_rec *src_f;
/*
* If this is not a parent pointer, just do a bin dump
@@ -828,10 +829,9 @@ xlog_print_trans_attri_name(
goto out;
}
- dst_len = ATTR_NVEC_SIZE(sizeof(struct xfs_parent_name_rec));
- if (dst_len != src_len) {
+ if (alfi_name_len > src_len) {
fprintf(stderr, _("%s: bad size of attri name format: %u; expected %u\n"),
- progname, src_len, dst_len);
+ progname, src_len, alfi_name_len);
return 1;
}
@@ -929,14 +929,12 @@ xlog_recover_print_attri(
src_rec = (struct xfs_parent_name_rec *)item->ri_buf[region].i_addr;
src_len = item->ri_buf[region].i_len;
- dst_len = ATTR_NVEC_SIZE(sizeof(struct xfs_parent_name_rec));
-
- if ((rec = ((struct xfs_parent_name_rec *)malloc(dst_len))) == NULL) {
+ if ((rec = calloc(src_len, 1)) == NULL) {
fprintf(stderr, _("%s: xlog_recover_print_attri: malloc failed\n"),
progname);
exit(1);
}
- if (xfs_attri_copy_name_format((char *)src_rec, src_len, rec)) {
+ if (xfs_attri_copy_name_format((char *)src_rec, src_len, f->alfi_name_len, rec)) {
goto out;
}
@@ -962,14 +960,12 @@ xlog_recover_print_attri(
src_rec = (struct xfs_parent_name_rec *)item->ri_buf[region].i_addr;
src_len = item->ri_buf[region].i_len;
- dst_len = ATTR_NVEC_SIZE(sizeof(struct xfs_parent_name_rec));
-
- if ((rec = ((struct xfs_parent_name_rec *)malloc(dst_len))) == NULL) {
+ if ((rec = calloc(dst_len, 1)) == NULL) {
fprintf(stderr, _("%s: xlog_recover_print_attri: malloc failed\n"),
progname);
exit(1);
}
- if (xfs_attri_copy_name_format((char *)src_rec, src_len, rec)) {
+ if (xfs_attri_copy_name_format((char *)src_rec, src_len, f->alfi_nname_len, rec)) {
goto out;
}
@@ -993,6 +989,7 @@ xlog_recover_print_attri(
if (f->alfi_attr_filter & XFS_ATTR_PARENT) {
src_value = (char *)item->ri_buf[region].i_addr;
+ src_len = item->ri_buf[region].i_len;
if ((value = ((char *)malloc(f->alfi_value_len))) == NULL) {
fprintf(stderr, _("%s: xlog_recover_print_attri: malloc failed\n"),
@@ -1000,6 +997,12 @@ xlog_recover_print_attri(
exit(1);
}
+ if (f->alfi_value_len > src_len) {
+ fprintf(stderr, _("%s: bad size of attri value format: %u; expected %u\n"),
+ progname, src_len, f->alfi_value_len);
+ exit(1);
+ }
+
value_ptr = src_value;
value_len = f->alfi_value_len;
@@ -59,7 +59,8 @@ extern void xlog_recover_print_bud(struct xlog_recover_item *item);
#define MAX_ATTR_VAL_PRINT 128
extern int xlog_print_trans_attri(char **ptr, uint src_len, int *i);
-extern int xlog_print_trans_attri_name(char **ptr, uint src_len, uint attr_flags);
+extern int xlog_print_trans_attri_name(char **ptr, uint src_len,
+ uint alfi_name_len, uint attr_flags);
extern int xlog_print_trans_attri_value(char **ptr, uint src_len, int value_len,
uint attr_flags);
extern void xlog_recover_print_attri(struct xlog_recover_item *item);