@@ -16,6 +16,7 @@ LIBHFILES = libxfs.h \
kmem.h \
list.h \
parent.h \
+ spinlock.h \
xfs_inode.h \
xfs_log_recover.h \
xfs_metadump.h \
@@ -18,6 +18,7 @@
#include "kmem.h"
#include "libfrog/radix-tree.h"
#include "atomic.h"
+#include "spinlock.h"
#include "xfs_types.h"
#include "xfs_fs.h"
new file mode 100644
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019-20 RedHat, Inc.
+ * All Rights Reserved.
+ */
+#ifndef __LIBXFS_SPINLOCK_H__
+#define __LIBXFS_SPINLOCK_H__
+
+/*
+ * This implements kernel compatible spinlock exclusion semantics. These,
+ * however, are not spinlocks, as spinlocks cannot be reliably implemented in
+ * userspace without using realtime scheduling task contexts. Hence this
+ * interface is implemented with pthread mutexes and so can block, but this is
+ * no different to the kernel RT build which replaces spinlocks with mutexes.
+ * Hence we know it works.
+ */
+
+typedef pthread_mutex_t spinlock_t;
+
+#define spin_lock_init(l) pthread_mutex_init(l, NULL)
+#define spin_lock(l) pthread_mutex_lock(l)
+#define spin_trylock(l) (pthread_mutex_trylock(l) != EBUSY)
+#define spin_unlock(l) pthread_mutex_unlock(l)
+
+#endif /* __LIBXFS_SPINLOCK_H__ */
@@ -42,6 +42,7 @@ struct inode {
struct timespec i_atime;
struct timespec i_mtime;
struct timespec i_ctime;
+ spinlock_t i_lock;
};
static inline uint32_t i_uid_read(struct inode *inode)
@@ -20,6 +20,7 @@ typedef struct xfs_mount {
#define m_icount m_sb.sb_icount
#define m_ifree m_sb.sb_ifree
#define m_fdblocks m_sb.sb_fdblocks
+ spinlock_t m_sb_lock;
/*
* Bitsets of per-fs metadata that have been checked and/or are sick.
@@ -30,6 +31,7 @@ typedef struct xfs_mount {
char *m_fsname; /* filesystem name */
int m_bsize; /* fs logical block size */
+ spinlock_t m_agirotor_lock;
xfs_agnumber_t m_agfrotor; /* last ag where space found */
xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */
xfs_agnumber_t m_maxagi; /* highest inode alloc group */
@@ -35,6 +35,7 @@ struct xfs_inode_log_item {
unsigned int ili_last_fields; /* fields when flushed*/
unsigned int ili_fields; /* fields to be logged */
unsigned int ili_fsync_fields; /* ignored by userspace */
+ spinlock_t ili_lock;
};
typedef struct xfs_buf_log_item {
@@ -683,7 +683,9 @@ libxfs_mount(
mp->m_flags = (LIBXFS_MOUNT_32BITINODES|LIBXFS_MOUNT_32BITINOOPT);
mp->m_sb = *sb;
INIT_RADIX_TREE(&mp->m_perag_tree, GFP_KERNEL);
- sbp = &(mp->m_sb);
+ sbp = &mp->m_sb;
+ spin_lock_init(&mp->m_sb_lock);
+ spin_lock_init(&mp->m_agirotor_lock);
xfs_sb_mount_common(mp, sb);
@@ -48,6 +48,7 @@
#include "kmem.h"
#include "libfrog/radix-tree.h"
#include "atomic.h"
+#include "spinlock.h"
#include "xfs_types.h"
#include "xfs_arch.h"
@@ -189,9 +190,6 @@ enum ce { CE_DEBUG, CE_CONT, CE_NOTE, CE_WARN, CE_ALERT, CE_PANIC };
#endif
/* miscellaneous kernel routines not in user space */
-#define spin_lock_init(a) ((void) 0)
-#define spin_lock(a) ((void) 0)
-#define spin_unlock(a) ((void) 0)
#define likely(x) (x)
#define unlikely(x) (x)
@@ -1062,6 +1062,8 @@ libxfs_iget(
ip->i_ino = ino;
ip->i_mount = mp;
+ spin_lock_init(&VFS_I(ip)->i_lock);
+
error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, 0);
if (error)
goto out_destroy;