@@ -77,8 +77,8 @@ attr_sf_entry_size(
sf = (struct xfs_attr_shortform *)((char *)obj + byteize(startoff));
e = &sf->list[0];
for (i = 0; i < idx; i++)
- e = XFS_ATTR_SF_NEXTENTRY(e);
- return bitize((int)XFS_ATTR_SF_ENTSIZE(e));
+ e = xfs_attr_sf_nextentry(e);
+ return bitize((int)xfs_attr_sf_entsize(e));
}
static int
@@ -134,7 +134,7 @@ attr_shortform_list_offset(
sf = (struct xfs_attr_shortform *)((char *)obj + byteize(startoff));
e = &sf->list[0];
for (i = 0; i < idx; i++)
- e = XFS_ATTR_SF_NEXTENTRY(e);
+ e = xfs_attr_sf_nextentry(e);
return bitize((int)((char *)e - (char *)sf));
}
@@ -154,6 +154,6 @@ attrshort_size(
sf = (struct xfs_attr_shortform *)((char *)obj + byteize(startoff));
e = &sf->list[0];
for (i = 0; i < sf->hdr.count; i++)
- e = XFS_ATTR_SF_NEXTENTRY(e);
+ e = xfs_attr_sf_nextentry(e);
return bitize((int)((char *)e - (char *)sf));
}
@@ -1399,7 +1399,7 @@ process_sf_attr(
"%llu", (long long)cur_ino);
break;
} else if ((char *)asfep - (char *)asfp +
- XFS_ATTR_SF_ENTSIZE(asfep) > ino_attr_size) {
+ xfs_attr_sf_entsize(asfep) > ino_attr_size) {
if (show_warnings)
print_warning("attr entry length in inode %llu "
"overflows space", (long long)cur_ino);
@@ -1414,7 +1414,7 @@ process_sf_attr(
}
asfep = (struct xfs_attr_sf_entry *)((char *)asfep +
- XFS_ATTR_SF_ENTSIZE(asfep));
+ xfs_attr_sf_entsize(asfep));
}
/* zero stale data in rest of space in attr fork, if any */
@@ -83,4 +83,31 @@ extern int platform_nproc(void);
#define NSEC_PER_SEC (1000000000ULL)
#define NSEC_PER_USEC (1000ULL)
+/*
+ * Compute a*b+c, returning SIZE_MAX on overflow. Internal helper for
+ * struct_size() below.
+ */
+static inline size_t __ab_c_size(size_t a, size_t b, size_t c)
+{
+ return (a * b) + c;
+}
+
+#define __must_be_array(a) (0)
+
+/**
+ * struct_size() - Calculate size of structure with trailing array.
+ * @p: Pointer to the structure.
+ * @member: Name of the array member.
+ * @count: Number of elements in the array.
+ *
+ * Calculates size of memory needed for structure @p followed by an
+ * array of @count number of @member elements.
+ *
+ * Return: number of bytes needed or SIZE_MAX on overflow.
+ */
+#define struct_size(p, member, count) \
+ __ab_c_size(count, \
+ sizeof(*(p)->member) + __must_be_array((p)->member),\
+ sizeof(*(p)))
+
#endif /* __XFS_PLATFORM_DEFS_H__ */
@@ -428,7 +428,7 @@ xfs_attr_set(
*/
if (XFS_IFORK_Q(dp) == 0) {
int sf_size = sizeof(struct xfs_attr_sf_hdr) +
- XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen,
+ xfs_attr_sf_entsize_byname(args->namelen,
args->valuelen);
error = xfs_bmap_add_attrfork(dp, sf_size, rsvd);
@@ -523,6 +523,14 @@ xfs_attr_set(
* External routines when attribute list is inside the inode
*========================================================================*/
+static inline int xfs_attr_sf_totsize(struct xfs_inode *dp)
+{
+ struct xfs_attr_shortform *sf;
+
+ sf = (struct xfs_attr_shortform *)dp->i_afp->if_u1.if_data;
+ return be16_to_cpu(sf->hdr.totsize);
+}
+
/*
* Add a name to the shortform attribute list structure
* This is the external routine.
@@ -555,8 +563,8 @@ xfs_attr_shortform_addname(xfs_da_args_t *args)
args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX)
return -ENOSPC;
- newsize = XFS_ATTR_SF_TOTSIZE(args->dp);
- newsize += XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen, args->valuelen);
+ newsize = xfs_attr_sf_totsize(args->dp);
+ newsize += xfs_attr_sf_entsize_byname(args->namelen, args->valuelen);
forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize);
if (!forkoff)
@@ -681,9 +681,9 @@ xfs_attr_sf_findname(
sf = (struct xfs_attr_shortform *)args->dp->i_afp->if_u1.if_data;
sfe = &sf->list[0];
end = sf->hdr.count;
- for (i = 0; i < end; sfe = XFS_ATTR_SF_NEXTENTRY(sfe),
+ for (i = 0; i < end; sfe = xfs_attr_sf_nextentry(sfe),
base += size, i++) {
- size = XFS_ATTR_SF_ENTSIZE(sfe);
+ size = xfs_attr_sf_entsize(sfe);
if (!xfs_attr_match(args, sfe->namelen, sfe->nameval,
sfe->flags))
continue;
@@ -730,7 +730,7 @@ xfs_attr_shortform_add(
ASSERT(0);
offset = (char *)sfe - (char *)sf;
- size = XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen, args->valuelen);
+ size = xfs_attr_sf_entsize_byname(args->namelen, args->valuelen);
xfs_idata_realloc(dp, size, XFS_ATTR_FORK);
sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
sfe = (struct xfs_attr_sf_entry *)((char *)sf + offset);
@@ -789,7 +789,7 @@ xfs_attr_shortform_remove(
error = xfs_attr_sf_findname(args, &sfe, &base);
if (error != -EEXIST)
return error;
- size = XFS_ATTR_SF_ENTSIZE(sfe);
+ size = xfs_attr_sf_entsize(sfe);
/*
* Fix up the attribute fork data, covering the hole
@@ -846,7 +846,7 @@ xfs_attr_shortform_lookup(xfs_da_args_t *args)
sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
sfe = &sf->list[0];
for (i = 0; i < sf->hdr.count;
- sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) {
+ sfe = xfs_attr_sf_nextentry(sfe), i++) {
if (xfs_attr_match(args, sfe->namelen, sfe->nameval,
sfe->flags))
return -EEXIST;
@@ -873,7 +873,7 @@ xfs_attr_shortform_getvalue(
sf = (struct xfs_attr_shortform *)args->dp->i_afp->if_u1.if_data;
sfe = &sf->list[0];
for (i = 0; i < sf->hdr.count;
- sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) {
+ sfe = xfs_attr_sf_nextentry(sfe), i++) {
if (xfs_attr_match(args, sfe->namelen, sfe->nameval,
sfe->flags))
return xfs_attr_copy_value(args,
@@ -948,7 +948,7 @@ xfs_attr_shortform_to_leaf(
ASSERT(error != -ENOSPC);
if (error)
goto out;
- sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
+ sfe = xfs_attr_sf_nextentry(sfe);
}
error = 0;
*leaf_bp = bp;
@@ -989,7 +989,7 @@ xfs_attr_shortform_allfit(
return 0;
if (be16_to_cpu(name_loc->valuelen) >= XFS_ATTR_SF_ENTSIZE_MAX)
return 0;
- bytes += XFS_ATTR_SF_ENTSIZE_BYNAME(name_loc->namelen,
+ bytes += xfs_attr_sf_entsize_byname(name_loc->namelen,
be16_to_cpu(name_loc->valuelen));
}
if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) &&
@@ -1047,7 +1047,7 @@ xfs_attr_shortform_verify(
* within the data buffer. The next entry starts after the
* name component, so nextentry is an acceptable test.
*/
- next_sfep = XFS_ATTR_SF_NEXTENTRY(sfep);
+ next_sfep = xfs_attr_sf_nextentry(sfep);
if ((char *)next_sfep > endp)
return __this_address;
@@ -26,18 +26,26 @@ typedef struct xfs_attr_sf_sort {
unsigned char *name; /* name value, pointer into buffer */
} xfs_attr_sf_sort_t;
-#define XFS_ATTR_SF_ENTSIZE_BYNAME(nlen,vlen) /* space name/value uses */ \
- ((sizeof(struct xfs_attr_sf_entry) + (nlen) + (vlen)))
#define XFS_ATTR_SF_ENTSIZE_MAX /* max space for name&value */ \
((1 << (NBBY*(int)sizeof(uint8_t))) - 1)
-#define XFS_ATTR_SF_ENTSIZE(sfep) /* space an entry uses */ \
- ((int)sizeof(struct xfs_attr_sf_entry) + \
- (sfep)->namelen+(sfep)->valuelen)
-#define XFS_ATTR_SF_NEXTENTRY(sfep) /* next entry in struct */ \
- ((struct xfs_attr_sf_entry *)((char *)(sfep) + \
- XFS_ATTR_SF_ENTSIZE(sfep)))
-#define XFS_ATTR_SF_TOTSIZE(dp) /* total space in use */ \
- (be16_to_cpu(((struct xfs_attr_shortform *) \
- ((dp)->i_afp->if_u1.if_data))->hdr.totsize))
+
+/* space name/value uses */
+static inline int xfs_attr_sf_entsize_byname(uint8_t nlen, uint8_t vlen)
+{
+ return sizeof(struct xfs_attr_sf_entry) + nlen + vlen;
+}
+
+/* space an entry uses */
+static inline int xfs_attr_sf_entsize(struct xfs_attr_sf_entry *sfep)
+{
+ return struct_size(sfep, nameval, sfep->namelen + sfep->valuelen);
+}
+
+/* next entry in struct */
+static inline struct xfs_attr_sf_entry *
+xfs_attr_sf_nextentry(struct xfs_attr_sf_entry *sfep)
+{
+ return (void *)sfep + xfs_attr_sf_entsize(sfep);
+}
#endif /* __XFS_ATTR_SF_H__ */
@@ -314,7 +314,7 @@ process_shortform_attr(
currententry->valuelen);
remainingspace = remainingspace -
- XFS_ATTR_SF_ENTSIZE(currententry);
+ xfs_attr_sf_entsize(currententry);
if (junkit) {
if (!no_modify) {
@@ -324,7 +324,7 @@ process_shortform_attr(
i, ino);
tempentry = (struct xfs_attr_sf_entry *)
((intptr_t) currententry +
- XFS_ATTR_SF_ENTSIZE(currententry));
+ xfs_attr_sf_entsize(currententry));
memmove(currententry,tempentry,remainingspace);
asf->hdr.count -= 1;
i--; /* no worries, it will wrap back to 0 */
@@ -339,8 +339,8 @@ process_shortform_attr(
/* Let's get ready for the next entry... */
nextentry = (struct xfs_attr_sf_entry *)((intptr_t) nextentry +
- XFS_ATTR_SF_ENTSIZE(currententry));
- currentsize = currentsize + XFS_ATTR_SF_ENTSIZE(currententry);
+ xfs_attr_sf_entsize(currententry));
+ currentsize = currentsize + xfs_attr_sf_entsize(currententry);
} /* end the loop */