@@ -26,6 +26,7 @@
#include "xfs_trace.h"
#include "xfs_attr_item.h"
#include "xfs_xattr.h"
+#include "xfs_parent.h"
struct kmem_cache *xfs_attr_intent_cache;
@@ -1577,36 +1578,17 @@ xfs_attr_node_get(
return error;
}
-/*
- * Verify parent pointer attribute is valid.
- * Return true on success or false on failure
- */
-STATIC bool
-xfs_verify_pptr(
- struct xfs_mount *mp,
- const struct xfs_parent_name_rec *rec)
+/* Returns true if the attribute entry name is valid. */
+bool
+xfs_attr_namecheck(
+ struct xfs_mount *mp,
+ const void *name,
+ size_t length,
+ unsigned int flags)
{
- xfs_ino_t p_ino;
- xfs_dir2_dataptr_t p_diroffset;
-
- p_ino = be64_to_cpu(rec->p_ino);
- p_diroffset = be32_to_cpu(rec->p_diroffset);
-
- if (!xfs_verify_ino(mp, p_ino))
- return false;
+ if (flags & XFS_ATTR_PARENT)
+ return xfs_parent_namecheck(mp, name, length, flags);
- if (p_diroffset > XFS_DIR2_MAX_DATAPTR)
- return false;
-
- return true;
-}
-
-/* Returns true if the string attribute entry name is valid. */
-static bool
-xfs_str_attr_namecheck(
- const void *name,
- size_t length)
-{
/*
* MAXNAMELEN includes the trailing null, but (name/length) leave it
* out, so use >= for the length check.
@@ -1618,23 +1600,6 @@ xfs_str_attr_namecheck(
return !memchr(name, 0, length);
}
-/* Returns true if the attribute entry name is valid. */
-bool
-xfs_attr_namecheck(
- struct xfs_mount *mp,
- const void *name,
- size_t length,
- int flags)
-{
- if (flags & XFS_ATTR_PARENT) {
- if (length != sizeof(struct xfs_parent_name_rec))
- return false;
- return xfs_verify_pptr(mp, (struct xfs_parent_name_rec *)name);
- }
-
- return xfs_str_attr_namecheck(name, length);
-}
-
int __init
xfs_attr_intent_init_cache(void)
{
@@ -552,7 +552,7 @@ int xfs_attr_set(struct xfs_da_args *args);
int xfs_attr_set_iter(struct xfs_attr_intent *attr);
int xfs_attr_remove_iter(struct xfs_attr_intent *attr);
bool xfs_attr_namecheck(struct xfs_mount *mp, const void *name, size_t length,
- int flags);
+ unsigned int flags);
int xfs_attr_calc_size(struct xfs_da_args *args, int *local);
void xfs_init_attr_trans(struct xfs_da_args *args, struct xfs_trans_res *tres,
unsigned int *total);
@@ -45,6 +45,50 @@ struct kmem_cache *xfs_parent_intent_cache;
* occurring.
*/
+/* Return true if parent pointer EA name is valid. */
+bool
+xfs_parent_namecheck(
+ struct xfs_mount *mp,
+ const struct xfs_parent_name_rec *rec,
+ size_t reclen,
+ unsigned int attr_flags)
+{
+ xfs_ino_t p_ino;
+ xfs_dir2_dataptr_t p_diroffset;
+
+ if (reclen != sizeof(struct xfs_parent_name_rec))
+ return false;
+
+ /* Only one namespace bit allowed. */
+ if (hweight32(attr_flags & XFS_ATTR_NSP_ONDISK_MASK) > 1)
+ return false;
+
+ p_ino = be64_to_cpu(rec->p_ino);
+ if (!xfs_verify_ino(mp, p_ino))
+ return false;
+
+ p_diroffset = be32_to_cpu(rec->p_diroffset);
+ if (p_diroffset > XFS_DIR2_MAX_DATAPTR)
+ return false;
+
+ return true;
+}
+
+/* Return true if parent pointer EA value is valid. */
+bool
+xfs_parent_valuecheck(
+ struct xfs_mount *mp,
+ const void *value,
+ size_t valuelen)
+{
+ if (valuelen == 0 || valuelen >= MAXNAMELEN)
+ return false;
+
+ if (value == NULL)
+ return false;
+
+ return true;
+}
/* Initializes a xfs_parent_name_rec to be stored as an attribute name */
void
@@ -8,6 +8,13 @@
extern struct kmem_cache *xfs_parent_intent_cache;
+/* Metadata validators */
+bool xfs_parent_namecheck(struct xfs_mount *mp,
+ const struct xfs_parent_name_rec *rec, size_t reclen,
+ unsigned int attr_flags);
+bool xfs_parent_valuecheck(struct xfs_mount *mp, const void *value,
+ size_t valuelen);
+
/*
* Incore version of a parent pointer, also contains dirent name so callers
* can pass/obtain all the parent pointer information in a single structure