Whamcloud - gitweb
b=5654
authorphil <phil>
Fri, 4 Feb 2005 19:30:22 +0000 (19:30 +0000)
committerphil <phil>
Fri, 4 Feb 2005 19:30:22 +0000 (19:30 +0000)
The lock ordering of i_sem and i_alloc_sem changed between 2.4 and 2.6,
which causes deadlocks if multiple threads try to truncate a single file.

I don't really like this solution, but it's the best I can come up with
right now.

lustre/ChangeLog
lustre/llite/llite_lib.c

index 54a64e7..ee1de1d 100644 (file)
@@ -19,6 +19,7 @@ tbd         Cluster File Systems, Inc. <info@clusterfs.com>
        - block device patches to fix I/O request sizes in 2.6 (5482)
        - protect KMS changes with its own lock, not i_sem (5492, 5624, 3453)
        - look up hostnames for IB nals (5602)
+       - 2.6 changed lock ordering of 2 semaphores, caused deadlock (5654)
        * miscellania
        - service request history (4965)
        - put {ll,lov,osc}_async_page structs in a single slab (4699)
index 0290382..eb835fa 100644 (file)
@@ -1018,9 +1018,16 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr)
                 /* bug 1639: avoid write/truncate i_sem/DLM deadlock */
                 LASSERT(atomic_read(&inode->i_sem.count) <= 0);
                 up(&inode->i_sem);
+                up_write(&inode->i_alloc_sem);
                 rc = ll_extent_lock(NULL, inode, lsm, LCK_PW, &policy, &lockh,
                                     ast_flags);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+                down_write(&inode->i_alloc_sem);
+                down(&inode->i_sem);
+#else
                 down(&inode->i_sem);
+                down_write(&inode->i_alloc_sem);
+#endif
                 if (rc != 0)
                         RETURN(rc);
 
@@ -1029,10 +1036,17 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr)
                 /* We need to drop the semaphore here, because this unlock may
                  * result in a cancellation, which will need the i_sem */
                 up(&inode->i_sem);
+                up_write(&inode->i_alloc_sem);
                 /* unlock now as we don't mind others file lockers racing with
                  * the mds updates below? */
                 err = ll_extent_unlock(NULL, inode, lsm, LCK_PW, &lockh);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+                down_write(&inode->i_alloc_sem);
+                down(&inode->i_sem);
+#else
                 down(&inode->i_sem);
+                down_write(&inode->i_alloc_sem);
+#endif
                 if (err) {
                         CERROR("ll_extent_unlock failed: %d\n", err);
                         if (!rc)