@@ -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,62 +1578,26 @@ 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)
-{
- 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 (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.
- */
- if (length >= MAXNAMELEN)
- return false;
-
- /* There shouldn't be any nulls here */
- 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)
+ unsigned 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);
- }
+ if (flags & XFS_ATTR_PARENT)
+ return xfs_parent_namecheck(mp, name, length, flags);
- return xfs_str_attr_namecheck(name, length);
+ /*
+ * MAXNAMELEN includes the trailing null, but (name/length) leave it
+ * out, so use >= for the length check.
+ */
+ if (length >= MAXNAMELEN)
+ return false;
+
+ /* There shouldn't be any nulls here */
+ return !memchr(name, 0, length);
}
int __init
@@ -551,7 +551,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);
@@ -55,6 +55,50 @@ xfs_init_parent_ptr(struct xfs_parent_ptr *xpp,
* 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);
+
/*
* Dynamically allocd structure used to wrap the needed data to pass around
* the defer ops machinery