[Ocfs2-commits] mfasheh commits r2640 - in branches/locking-changes: Documentation/filesystems fs/ocfs2

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Wed Oct 5 18:04:12 CDT 2005


Author: mfasheh
Date: 2005-10-05 18:04:11 -0500 (Wed, 05 Oct 2005)
New Revision: 2640

Modified:
   branches/locking-changes/Documentation/filesystems/ocfs2.txt
   branches/locking-changes/fs/ocfs2/file.c
   branches/locking-changes/fs/ocfs2/inode.c
Log:
* take the rw lock in setattr for size changes



Modified: branches/locking-changes/Documentation/filesystems/ocfs2.txt
===================================================================
--- branches/locking-changes/Documentation/filesystems/ocfs2.txt	2005-10-05 22:38:22 UTC (rev 2639)
+++ branches/locking-changes/Documentation/filesystems/ocfs2.txt	2005-10-05 23:04:11 UTC (rev 2640)
@@ -98,10 +98,12 @@
   + notify_change
     ( i_alloc_sem
     + ocfs2_setattr
+      ( rw_lock
       ( meta_lock
       + ocfs2_truncate_file
         () data_lock
       ) meta_lock
+      ) rw_lock
     ) i_alloc_sem
   ) i_sem
 
@@ -114,6 +116,9 @@
       ) ip_alloc_sem
       ) meta_lock
 
+Lock Ordering - The Short Story:
+i_sem -> i_alloc_sem -> rw_lock -> meta_lock -> ip_alloc_sem -> data_lock
+
 .. make this prettier ..
 
 -- Locks and what they cover --

Modified: branches/locking-changes/fs/ocfs2/file.c
===================================================================
--- branches/locking-changes/fs/ocfs2/file.c	2005-10-05 22:38:22 UTC (rev 2639)
+++ branches/locking-changes/fs/ocfs2/file.c	2005-10-05 23:04:11 UTC (rev 2640)
@@ -753,8 +753,7 @@
 
 int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
 {
-	int status = 0;
-	u64 newsize;
+	int status = 0, size_change;
 	struct inode *inode = dentry->d_inode;
 	struct super_block *sb = inode->i_sb;
 	ocfs2_super *osb = OCFS2_SB(sb);
@@ -786,22 +785,27 @@
 	if (status)
 		return status;
 
-	newsize = attr->ia_size;
+	size_change = S_ISREG(inode->i_mode) && attr->ia_valid & ATTR_SIZE;
+	if (size_change) {
+		status = ocfs2_rw_lock(inode, 1);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+	}
 
 	status = ocfs2_meta_lock(inode, NULL, &bh, 1);
 	if (status < 0) {
 		if (status != -ENOENT)
 			mlog_errno(status);
-		goto bail;
+		goto bail_unlock_rw;
 	}
 
-	if (S_ISREG(inode->i_mode) &&
-	    attr->ia_valid & ATTR_SIZE &&
-	    newsize != i_size_read(inode)) {
-		if (i_size_read(inode) > newsize)
-			status = ocfs2_truncate_file(inode, bh, newsize);
+	if (size_change && attr->ia_size != i_size_read(inode)) {
+		if (i_size_read(inode) > attr->ia_size)
+			status = ocfs2_truncate_file(inode, bh, attr->ia_size);
 		else
-			status = ocfs2_extend_file(inode, bh, newsize);
+			status = ocfs2_extend_file(inode, bh, attr->ia_size);
 		if (status < 0) {
 			if (status != -ENOSPC)
 				mlog_errno(status);
@@ -831,6 +835,9 @@
 	ocfs2_commit_trans(handle);
 bail_unlock:
 	ocfs2_meta_unlock(inode, 1);
+bail_unlock_rw:
+	if (size_change)
+		ocfs2_rw_unlock(inode, 1);
 bail:
 	if (bh)
 		brelse(bh);

Modified: branches/locking-changes/fs/ocfs2/inode.c
===================================================================
--- branches/locking-changes/fs/ocfs2/inode.c	2005-10-05 22:38:22 UTC (rev 2639)
+++ branches/locking-changes/fs/ocfs2/inode.c	2005-10-05 23:04:11 UTC (rev 2640)
@@ -789,7 +789,12 @@
 
 	/* Lock down the inode. This gives us an up to date view of
 	 * it's metadata (for verification), and allows us to
-	 * serialize delete_inode votes. */
+	 * serialize delete_inode votes. 
+	 *
+	 * Even though we might be doing a truncate, we don't take the
+	 * allocation lock here as it won't be needed - nobody will
+	 * have the file open.
+	 */
 	status = ocfs2_meta_lock(inode, NULL, &di_bh, 1);
 	if (status < 0) {
 		if (status != -ENOENT)



More information about the Ocfs2-commits mailing list