]> err.no Git - linux-2.6/blobdiff - fs/buffer.c
[PATCH] knfsd: Fix type mismatch with filldir_t used by nfsd
[linux-2.6] / fs / buffer.c
index 263f88e4dffb8bcd617742374d0934d316be948f..460f1c43238e1f9eb20bd0ae50ed046305ceb384 100644 (file)
@@ -180,7 +180,7 @@ int fsync_bdev(struct block_device *bdev)
  * freeze_bdev  --  lock a filesystem and force it into a consistent state
  * @bdev:      blockdevice to lock
  *
- * This takes the block device bd_mount_mutex to make sure no new mounts
+ * This takes the block device bd_mount_sem to make sure no new mounts
  * happen on bdev until thaw_bdev() is called.
  * If a superblock is found on this device, we take the s_umount semaphore
  * on it to make sure nobody unmounts until the snapshot creation is done.
@@ -189,7 +189,7 @@ struct super_block *freeze_bdev(struct block_device *bdev)
 {
        struct super_block *sb;
 
-       mutex_lock(&bdev->bd_mount_mutex);
+       down(&bdev->bd_mount_sem);
        sb = get_super(bdev);
        if (sb && !(sb->s_flags & MS_RDONLY)) {
                sb->s_frozen = SB_FREEZE_WRITE;
@@ -231,7 +231,7 @@ void thaw_bdev(struct block_device *bdev, struct super_block *sb)
                drop_super(sb);
        }
 
-       mutex_unlock(&bdev->bd_mount_mutex);
+       up(&bdev->bd_mount_sem);
 }
 EXPORT_SYMBOL(thaw_bdev);
 
@@ -2834,7 +2834,7 @@ int try_to_free_buffers(struct page *page)
        int ret = 0;
 
        BUG_ON(!PageLocked(page));
-       if (PageDirty(page) || PageWriteback(page))
+       if (PageWriteback(page))
                return 0;
 
        if (mapping == NULL) {          /* can this still happen? */
@@ -2845,6 +2845,19 @@ int try_to_free_buffers(struct page *page)
        spin_lock(&mapping->private_lock);
        ret = drop_buffers(page, &buffers_to_free);
        spin_unlock(&mapping->private_lock);
+
+       /*
+        * If the filesystem writes its buffers by hand (eg ext3)
+        * then we can have clean buffers against a dirty page.  We
+        * clean the page here; otherwise the VM will never notice
+        * that the filesystem did any IO at all.
+        *
+        * Also, during truncate, discard_buffer will have marked all
+        * the page's buffers clean.  We discover that here and clean
+        * the page also.
+        */
+       if (ret)
+               cancel_dirty_page(page, PAGE_CACHE_SIZE);
 out:
        if (buffers_to_free) {
                struct buffer_head *bh = buffers_to_free;