Hi! > commit 4cd9973f9ff69e37dd0ba2bd6e6423f8179c329a upstream. > > Patch series "ocfs2: fix nfsd over ocfs2 issues", v2. > > This is a series of patches to fix issues on nfsd over ocfs2. patch 1 > is to avoid inode removed while nfsd access it patch 2 & 3 is to fix a > panic issue. > > This patch (of 4): > > When nfsd is getting file dentry using handle or parent dentry of some > dentry, one cluster lock is used to avoid inode removed from other node, > but it still could be removed from local node, so use a rw lock to avoid > this. This causes locking imbalance: > @@ -2851,6 +2857,11 @@ int ocfs2_nfs_sync_lock(struct ocfs2_super *osb, int ex) > if (ocfs2_is_hard_readonly(osb)) > return -EROFS; > > + if (ex) > + down_write(&osb->nfs_sync_rwlock); > + else > + down_read(&osb->nfs_sync_rwlock); > + > if (ocfs2_mount_local(osb)) > return 0; > ... status = ocfs2_cluster_lock(osb, lockres, ex ? LKM_EXMODE :LKM_PRMODE, 0, 0); ... return status; } When ocfs2_nfs_sync_lock() returns error, caller can not know if the lock was taken or not. ocfs2_get_dentry() for example will not call ocfs2_nfs_sync_unlock() if sync_lock() failed, resulting in lock imbalance if ocfs2_cluster_lock() fails. (Totally untested). Signed-off-by: Pavel Machek (CIP) <pavel@xxxxxxx> Best regards, Pavel diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index c141b06811a6..8149fb6f1f0d 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c @@ -2867,9 +2867,15 @@ int ocfs2_nfs_sync_lock(struct ocfs2_super *osb, int ex) status = ocfs2_cluster_lock(osb, lockres, ex ? LKM_EXMODE : LKM_PRMODE, 0, 0); - if (status < 0) + if (status < 0) { mlog(ML_ERROR, "lock on nfs sync lock failed %d\n", status); + if (ex) + up_write(&osb->nfs_sync_rwlock); + else + up_read(&osb->nfs_sync_rwlock); + } + return status; } Best regards, Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Attachment:
signature.asc
Description: Digital signature