Selaa lähdekoodia

[XFS] Handle inode semaphores properly for dmapi queues

SGI-PV: 931572
SGI-Modid: xfs-linux-melb:xfs-kern:189560a

Signed-off-by: Dean Roehrich <roehrich@sgi.com>
Signed-off-by: Nathan Scott <nathans@sgi.com>
Dean Roehrich 20 vuotta sitten
vanhempi
commit
e1a40fa907
2 muutettua tiedostoa jossa 20 lisäystä ja 13 poistoa
  1. 8 2
      fs/xfs/linux-2.6/xfs_lrw.c
  2. 12 11
      fs/xfs/xfs_dmapi.h

+ 8 - 2
fs/xfs/linux-2.6/xfs_lrw.c

@@ -280,10 +280,11 @@ xfs_read(
 	if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&
 	if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&
 	    !(ioflags & IO_INVIS)) {
 	    !(ioflags & IO_INVIS)) {
 		vrwlock_t locktype = VRWLOCK_READ;
 		vrwlock_t locktype = VRWLOCK_READ;
+		int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags);
 
 
 		ret = -XFS_SEND_DATA(mp, DM_EVENT_READ,
 		ret = -XFS_SEND_DATA(mp, DM_EVENT_READ,
 					BHV_TO_VNODE(bdp), *offset, size,
 					BHV_TO_VNODE(bdp), *offset, size,
-					FILP_DELAY_FLAG(file), &locktype);
+					dmflags, &locktype);
 		if (ret) {
 		if (ret) {
 			xfs_iunlock(ip, XFS_IOLOCK_SHARED);
 			xfs_iunlock(ip, XFS_IOLOCK_SHARED);
 			goto unlock_isem;
 			goto unlock_isem;
@@ -843,11 +844,15 @@ retry:
 	    !(ioflags & IO_INVIS)) {
 	    !(ioflags & IO_INVIS)) {
 
 
 		xfs_rwunlock(bdp, locktype);
 		xfs_rwunlock(bdp, locktype);
+		if (need_isem)
+			up(&inode->i_sem);
 		error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp,
 		error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp,
 				DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL,
 				DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL,
 				0, 0, 0); /* Delay flag intentionally  unused */
 				0, 0, 0); /* Delay flag intentionally  unused */
 		if (error)
 		if (error)
-			goto out_unlock_isem;
+			goto out_nounlocks;
+		if (need_isem)
+			down(&inode->i_sem);
 		xfs_rwlock(bdp, locktype);
 		xfs_rwlock(bdp, locktype);
 		pos = xip->i_d.di_size;
 		pos = xip->i_d.di_size;
 		ret = 0;
 		ret = 0;
@@ -962,6 +967,7 @@ retry:
  out_unlock_isem:
  out_unlock_isem:
 	if (need_isem)
 	if (need_isem)
 		up(&inode->i_sem);
 		up(&inode->i_sem);
+ out_nounlocks:
 	return -error;
 	return -error;
 }
 }
 
 

+ 12 - 11
fs/xfs/xfs_dmapi.h

@@ -166,27 +166,32 @@ typedef enum {
 #define DM_FLAGS_NDELAY		0x001	/* return EAGAIN after dm_pending() */
 #define DM_FLAGS_NDELAY		0x001	/* return EAGAIN after dm_pending() */
 #define DM_FLAGS_UNWANTED	0x002	/* event not in fsys dm_eventset_t */
 #define DM_FLAGS_UNWANTED	0x002	/* event not in fsys dm_eventset_t */
 #define DM_FLAGS_ISEM		0x004	/* thread holds i_sem */
 #define DM_FLAGS_ISEM		0x004	/* thread holds i_sem */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21)
-/* i_alloc_sem was added in 2.4.22-pre1 */
 #define DM_FLAGS_IALLOCSEM_RD	0x010	/* thread holds i_alloc_sem rd */
 #define DM_FLAGS_IALLOCSEM_RD	0x010	/* thread holds i_alloc_sem rd */
 #define DM_FLAGS_IALLOCSEM_WR	0x020	/* thread holds i_alloc_sem wr */
 #define DM_FLAGS_IALLOCSEM_WR	0x020	/* thread holds i_alloc_sem wr */
-#endif
-#endif
 
 
 /*
 /*
  *	Based on IO_ISDIRECT, decide which i_ flag is set.
  *	Based on IO_ISDIRECT, decide which i_ flag is set.
  */
  */
-#ifdef DM_FLAGS_IALLOCSEM_RD
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
+#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
+			      DM_FLAGS_ISEM : 0)
+#define DM_SEM_FLAG_WR	(DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_ISEM)
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) && \
+    (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22))
 #define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
 #define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
 			      DM_FLAGS_IALLOCSEM_RD : DM_FLAGS_ISEM)
 			      DM_FLAGS_IALLOCSEM_RD : DM_FLAGS_ISEM)
 #define DM_SEM_FLAG_WR	(DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_ISEM)
 #define DM_SEM_FLAG_WR	(DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_ISEM)
-#else
+#endif
+
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,21)
 #define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
 #define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
 			      0 : DM_FLAGS_ISEM)
 			      0 : DM_FLAGS_ISEM)
 #define DM_SEM_FLAG_WR	(DM_FLAGS_ISEM)
 #define DM_SEM_FLAG_WR	(DM_FLAGS_ISEM)
 #endif
 #endif
 
 
+
 /*
 /*
  *	Macros to turn caller specified delay/block flags into
  *	Macros to turn caller specified delay/block flags into
  *	dm_send_xxxx_event flag DM_FLAGS_NDELAY.
  *	dm_send_xxxx_event flag DM_FLAGS_NDELAY.
@@ -209,8 +214,4 @@ void xfs_dm_exit(struct file_system_type *);
 #define XFS_DM_EXIT(fstype)
 #define XFS_DM_EXIT(fstype)
 #endif
 #endif
 
 
-#define HAVE_XFS_DM_MM
-int xfs_dm_mm_get(struct vm_area_struct *vma);
-void xfs_dm_mm_put(struct vm_area_struct *vma);
-
 #endif  /* __XFS_DMAPI_H__ */
 #endif  /* __XFS_DMAPI_H__ */