[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