@@ -273,6 +273,8 @@ xfs_attr_get(
XFS_STATS_INC(args->dp->i_mount, xs_attr_get);
+ ASSERT(!args->trans);
+
if (xfs_is_shutdown(args->dp->i_mount))
return -EIO;
@@ -285,8 +287,27 @@ xfs_attr_get(
/* Entirely possible to look up a name which doesn't exist */
args->op_flags = XFS_DA_OP_OKNOENT;
+ error = xfs_trans_alloc_empty(args->dp->i_mount, &args->trans);
+ if (error)
+ return error;
+
lock_mode = xfs_ilock_attr_map_shared(args->dp);
+
+ /*
+ * Make sure the attr fork iext tree is loaded. Use the empty
+ * transaction to load the bmbt so that we avoid livelocking on loops.
+ */
+ if (xfs_inode_hasattr(args->dp)) {
+ error = xfs_iread_extents(args->trans, args->dp, XFS_ATTR_FORK);
+ if (error)
+ goto out_cancel;
+ }
+
error = xfs_attr_get_ilocked(args);
+
+out_cancel:
+ xfs_trans_cancel(args->trans);
+ args->trans = NULL;
xfs_iunlock(args->dp, lock_mode);
return error;