[PATCH 5/9] xfs: Add xfs_attr_set_deferred and xfs_attr_remove_deferred

Allison Henderson
2019-04-12T22:52:49Z

These routines set up set and start a new deferred attribute
operation. These functions are meant to be called by other
code needing to initiate a deferred attribute operation. We
will use these routines later in the parent pointer patches.

Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
---
fs/xfs/libxfs/xfs_attr.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++
fs/xfs/libxfs/xfs_attr.h | 7 +++++
2 files changed, 87 insertions(+)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index fadd485..c3477fa7 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -30,6 +30,7 @@
#include "xfs_trans_space.h"
#include "xfs_trace.h"
#include "xfs_attr_item.h"
+#include "xfs_attr.h"

/*
* xfs_attr.c
@@ -429,6 +430,52 @@ xfs_attr_set(
goto out_unlock;
}

+/* Sets an attribute for an inode as a deferred operation */
+int
+xfs_attr_set_deferred(
+ struct xfs_inode *dp,
+ struct xfs_trans *tp,
+ const unsigned char *name,
+ unsigned int namelen,
+ const unsigned char *value,
+ unsigned int valuelen,
+ int flags)
+{
+
+ struct xfs_attr_item *new;
+ char *name_value;
+
+ /*
+ * All set operations must have a name
+ * but not necessarily a value.
+ * Generic 062
+ */
+ if (!namelen) {
+ ASSERT(0);
+ return -EFSCORRUPTED;
+ }
+
+ new = kmem_alloc(XFS_ATTR_ITEM_SIZEOF(namelen, valuelen),
+ KM_SLEEP|KM_NOFS);
+ name_value = ((char *)new) + sizeof(struct xfs_attr_item);
+ memset(new, 0, XFS_ATTR_ITEM_SIZEOF(namelen, valuelen));
+ new->xattri_ip = dp;
+ new->xattri_op_flags = XFS_ATTR_OP_FLAGS_SET;
+ new->xattri_name_len = namelen;
+ new->xattri_value_len = valuelen;
+ new->xattri_flags = flags;
+ memcpy(&name_value[0], name, namelen);
+ new->xattri_name = name_value;
+ new->xattri_value = name_value + namelen;
+
+ if (valuelen > 0)
+ memcpy(&name_value[namelen], value, valuelen);
+
+ xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
+
+ return 0;
+}
+
/*
* Generic handler routine to remove a name from an attribute list.
* Transitions attribute list from Btree to shortform as necessary.
@@ -513,6 +560,39 @@ xfs_attr_remove(
return error;
}

+/* Removes an attribute for an inode as a deferred operation */
+int
+xfs_attr_remove_deferred(
+ struct xfs_inode *dp,
+ struct xfs_trans *tp,
+ const unsigned char *name,
+ unsigned int namelen,
+ int flags)
+{
+
+ struct xfs_attr_item *new;
+ char *name_value;
+
+ if (!namelen) {
+ ASSERT(0);
+ return -EFSCORRUPTED;
+ }
+
+ new = kmem_alloc(XFS_ATTR_ITEM_SIZEOF(namelen, 0), KM_SLEEP|KM_NOFS);
+ name_value = ((char *)new) + sizeof(struct xfs_attr_item);
+ memset(new, 0, XFS_ATTR_ITEM_SIZEOF(namelen, 0));
+ new->xattri_ip = dp;
+ new->xattri_op_flags = XFS_ATTR_OP_FLAGS_REMOVE;
+ new->xattri_name_len = namelen;
+ new->xattri_value_len = 0;
+ new->xattri_flags = flags;
+ memcpy(name_value, name, namelen);
+
+ xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
+
+ return 0;
+}
+
/*========================================================================
* External routines when attribute list is inside the inode
*========================================================================*/
diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
index 92d9a15..83b3621 100644
--- a/fs/xfs/libxfs/xfs_attr.h
+++ b/fs/xfs/libxfs/xfs_attr.h
@@ -175,5 +175,12 @@ bool xfs_attr_namecheck(const void *name, size_t length);
int xfs_attr_args_init(struct xfs_da_args *args, struct xfs_inode *dp,
const unsigned char *name, size_t namelen, int flags);
int xfs_attr_calc_size(struct xfs_da_args *args, int *local);
+int xfs_attr_set_deferred(struct xfs_inode *dp, struct xfs_trans *tp,
+ const unsigned char *name, unsigned int name_len,
+ const unsigned char *value, unsigned int valuelen,
+ int flags);
+int xfs_attr_remove_deferred(struct xfs_inode *dp, struct xfs_trans *tp,
+ const unsigned char *name, unsigned int namelen,
+ int flags);

#endif /* __XFS_ATTR_H__ */
--
2.7.4