From: phil Date: Fri, 4 Feb 2005 19:30:22 +0000 (+0000) Subject: b=5654 X-Git-Tag: v1_8_0_110~486^5~42 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=d95cbe05e3f74410b4bb2c7ac63dbc448052f913;p=fs%2Flustre-release.git b=5654 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. --- diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 54a64e7..ee1de1d 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -19,6 +19,7 @@ tbd Cluster File Systems, Inc. - 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) diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 0290382..eb835fa 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -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)