diff mbox series

Fix filesystem issue: description of the fix Fix mark_buffer_dirty_inode to mark_buffer_dirty_fsync Signed-off-by: HyeonWoo Cha <chw1119@hanyang.ac.kr>

Message ID 20240603065910.20736-1-chw1119@hanyang.ac.kr (mailing list archive)
State New
Headers show
Series Fix filesystem issue: description of the fix Fix mark_buffer_dirty_inode to mark_buffer_dirty_fsync Signed-off-by: HyeonWoo Cha <chw1119@hanyang.ac.kr> | expand

Commit Message

Hyeonwoo Cha June 3, 2024, 6:59 a.m. UTC
---
 fs/affs/amigaffs.c          | 17 +++++++++++------
 fs/affs/file.c              | 26 ++++++++++++++------------
 fs/affs/inode.c             | 16 ++++++++++------
 fs/affs/namei.c             |  9 +++++----
 fs/bfs/dir.c                |  7 ++++---
 fs/buffer.c                 | 36 ++++++++++++++++++------------------
 fs/ext2/inode.c             |  8 ++++----
 fs/ext4/ext4_jbd2.c         |  2 +-
 fs/fat/dir.c                | 14 +++++++-------
 fs/fat/fatent.c             | 10 +++++-----
 fs/fat/namei_msdos.c        |  4 ++--
 fs/fat/namei_vfat.c         |  2 +-
 fs/minix/itree_common.c     |  8 ++++----
 fs/reiserfs/fix_node.c      |  7 +++++--
 fs/sysv/itree.c             |  2 +-
 fs/udf/directory.c          |  4 ++--
 fs/udf/inode.c              | 12 ++++++------
 fs/udf/namei.c              |  2 +-
 fs/udf/truncate.c           |  2 +-
 include/linux/buffer_head.h |  2 +-
 20 files changed, 103 insertions(+), 87 deletions(-)

Comments

Al Viro June 3, 2024, 7:35 a.m. UTC | #1
On Mon, Jun 03, 2024 at 03:59:10PM +0900, Hyeonwoo Cha wrote:

NAK.  Reasons:
	* patch described as a fix; that implies that some behaviour
change is there.  Yet there's no description of that change or
explanation of the problem being fixed.
	* lack of _any_ explanations, period.  Including e.g.
a discussion of the reasons why the change makes sense.
	* apparent blind trust in continued applicability of comments
that date back to 2002; in any case, no analysis is offered anywhere -
reviewers are supposed to do that themselves, presumably.
	* failure to Cc the original author of the comment in question.
diff mbox series

Patch

diff --git a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c
index fd669daa4..b11e7fcb2 100644
--- a/fs/affs/amigaffs.c
+++ b/fs/affs/amigaffs.c
@@ -27,6 +27,7 @@  affs_insert_hash(struct inode *dir, struct buffer_head *bh)
 {
 	struct super_block *sb = dir->i_sb;
 	struct buffer_head *dir_bh;
+	struct address_space *mapping = dir->i_mapping;
 	u32 ino, hash_ino;
 	int offset;
 
@@ -57,7 +58,7 @@  affs_insert_hash(struct inode *dir, struct buffer_head *bh)
 		AFFS_TAIL(sb, dir_bh)->hash_chain = cpu_to_be32(ino);
 
 	affs_adjust_checksum(dir_bh, ino);
-	mark_buffer_dirty_inode(dir_bh, dir);
+	mark_buffer_dirty_fsync(dir_bh, mapping);
 	affs_brelse(dir_bh);
 
 	inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
@@ -74,6 +75,7 @@  affs_insert_hash(struct inode *dir, struct buffer_head *bh)
 int
 affs_remove_hash(struct inode *dir, struct buffer_head *rem_bh)
 {
+	struct address_space *mapping = dir->i_mapping;
 	struct super_block *sb;
 	struct buffer_head *bh;
 	u32 rem_ino, hash_ino;
@@ -100,7 +102,7 @@  affs_remove_hash(struct inode *dir, struct buffer_head *rem_bh)
 			else
 				AFFS_TAIL(sb, bh)->hash_chain = ino;
 			affs_adjust_checksum(bh, be32_to_cpu(ino) - hash_ino);
-			mark_buffer_dirty_inode(bh, dir);
+			mark_buffer_dirty_fsync(bh, mapping);
 			AFFS_TAIL(sb, rem_bh)->parent = 0;
 			retval = 0;
 			break;
@@ -142,6 +144,7 @@  static int
 affs_remove_link(struct dentry *dentry)
 {
 	struct inode *dir, *inode = d_inode(dentry);
+	struct address_space *mapping = inode->i_mapping;
 	struct super_block *sb = inode->i_sb;
 	struct buffer_head *bh, *link_bh = NULL;
 	u32 link_ino, ino;
@@ -180,7 +183,7 @@  affs_remove_link(struct dentry *dentry)
 			affs_unlock_dir(dir);
 			goto done;
 		}
-		mark_buffer_dirty_inode(link_bh, inode);
+		mark_buffer_dirty_fsync(link_bh, mapping);
 
 		memcpy(AFFS_TAIL(sb, bh)->name, AFFS_TAIL(sb, link_bh)->name, 32);
 		retval = affs_insert_hash(dir, bh);
@@ -188,7 +191,7 @@  affs_remove_link(struct dentry *dentry)
 			affs_unlock_dir(dir);
 			goto done;
 		}
-		mark_buffer_dirty_inode(bh, inode);
+		mark_buffer_dirty_fsync(bh, mapping);
 
 		affs_unlock_dir(dir);
 		iput(dir);
@@ -203,7 +206,7 @@  affs_remove_link(struct dentry *dentry)
 			__be32 ino2 = AFFS_TAIL(sb, link_bh)->link_chain;
 			AFFS_TAIL(sb, bh)->link_chain = ino2;
 			affs_adjust_checksum(bh, be32_to_cpu(ino2) - link_ino);
-			mark_buffer_dirty_inode(bh, inode);
+			mark_buffer_dirty_fsync(bh, mapping);
 			retval = 0;
 			/* Fix the link count, if bh is a normal header block without links */
 			switch (be32_to_cpu(AFFS_TAIL(sb, bh)->stype)) {
@@ -276,6 +279,8 @@  affs_remove_header(struct dentry *dentry)
 
 	retval = -ENOENT;
 	inode = d_inode(dentry);
+	struct address_space *mapping = inode->i_mapping;
+
 	if (!inode)
 		goto done;
 
@@ -306,7 +311,7 @@  affs_remove_header(struct dentry *dentry)
 	retval = affs_remove_hash(dir, bh);
 	if (retval)
 		goto done_unlock;
-	mark_buffer_dirty_inode(bh, inode);
+	mark_buffer_dirty_fsync(bh, mapping);
 
 	affs_unlock_dir(dir);
 
diff --git a/fs/affs/file.c b/fs/affs/file.c
index 04c018e19..1d769bf43 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -119,6 +119,7 @@  affs_grow_extcache(struct inode *inode, u32 lc_idx)
 static struct buffer_head *
 affs_alloc_extblock(struct inode *inode, struct buffer_head *bh, u32 ext)
 {
+	struct address_space *mapping = inode->i_mapping;
 	struct super_block *sb = inode->i_sb;
 	struct buffer_head *new_bh;
 	u32 blocknr, tmp;
@@ -139,14 +140,14 @@  affs_alloc_extblock(struct inode *inode, struct buffer_head *bh, u32 ext)
 	AFFS_TAIL(sb, new_bh)->parent = cpu_to_be32(inode->i_ino);
 	affs_fix_checksum(sb, new_bh);
 
-	mark_buffer_dirty_inode(new_bh, inode);
+	mark_buffer_dirty_fsync(new_bh, mapping);
 
 	tmp = be32_to_cpu(AFFS_TAIL(sb, bh)->extension);
 	if (tmp)
 		affs_warning(sb, "alloc_ext", "previous extension set (%x)", tmp);
 	AFFS_TAIL(sb, bh)->extension = cpu_to_be32(blocknr);
 	affs_adjust_checksum(bh, blocknr - tmp);
-	mark_buffer_dirty_inode(bh, inode);
+	mark_buffer_dirty_fsync(bh, mapping);
 
 	AFFS_I(inode)->i_extcnt++;
 	mark_inode_dirty(inode);
@@ -558,6 +559,7 @@  static int affs_do_read_folio_ofs(struct folio *folio, size_t to, int create)
 static int
 affs_extent_file_ofs(struct inode *inode, u32 newsize)
 {
+	struct address_space *mapping = inode->i_mapping;
 	struct super_block *sb = inode->i_sb;
 	struct buffer_head *bh, *prev_bh;
 	u32 bidx, boff;
@@ -579,7 +581,7 @@  affs_extent_file_ofs(struct inode *inode, u32 newsize)
 		memset(AFFS_DATA(bh) + boff, 0, tmp);
 		be32_add_cpu(&AFFS_DATA_HEAD(bh)->size, tmp);
 		affs_fix_checksum(sb, bh);
-		mark_buffer_dirty_inode(bh, inode);
+		mark_buffer_dirty_fsync(bh, mapping);
 		size += tmp;
 		bidx++;
 	} else if (bidx) {
@@ -601,7 +603,7 @@  affs_extent_file_ofs(struct inode *inode, u32 newsize)
 		AFFS_DATA_HEAD(bh)->size = cpu_to_be32(tmp);
 		affs_fix_checksum(sb, bh);
 		bh->b_state &= ~(1UL << BH_New);
-		mark_buffer_dirty_inode(bh, inode);
+		mark_buffer_dirty_fsync(bh, mapping);
 		if (prev_bh) {
 			u32 tmp_next = be32_to_cpu(AFFS_DATA_HEAD(prev_bh)->next);
 
@@ -611,7 +613,7 @@  affs_extent_file_ofs(struct inode *inode, u32 newsize)
 					     bidx, tmp_next);
 			AFFS_DATA_HEAD(prev_bh)->next = cpu_to_be32(bh->b_blocknr);
 			affs_adjust_checksum(prev_bh, bh->b_blocknr - tmp_next);
-			mark_buffer_dirty_inode(prev_bh, inode);
+			mark_buffer_dirty_fsync(prev_bh, mapping);
 			affs_brelse(prev_bh);
 		}
 		size += bsize;
@@ -728,7 +730,7 @@  static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
 		memcpy(AFFS_DATA(bh) + boff, data + from, tmp);
 		be32_add_cpu(&AFFS_DATA_HEAD(bh)->size, tmp);
 		affs_fix_checksum(sb, bh);
-		mark_buffer_dirty_inode(bh, inode);
+		mark_buffer_dirty_fsync(bh, mapping);
 		written += tmp;
 		from += tmp;
 		bidx++;
@@ -761,12 +763,12 @@  static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
 						     bidx, tmp_next);
 				AFFS_DATA_HEAD(prev_bh)->next = cpu_to_be32(bh->b_blocknr);
 				affs_adjust_checksum(prev_bh, bh->b_blocknr - tmp_next);
-				mark_buffer_dirty_inode(prev_bh, inode);
+				mark_buffer_dirty_fsync(prev_bh, mapping);
 			}
 		}
 		affs_brelse(prev_bh);
 		affs_fix_checksum(sb, bh);
-		mark_buffer_dirty_inode(bh, inode);
+		mark_buffer_dirty_fsync(bh, mapping);
 		written += bsize;
 		from += bsize;
 		bidx++;
@@ -795,13 +797,13 @@  static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
 						     bidx, tmp_next);
 				AFFS_DATA_HEAD(prev_bh)->next = cpu_to_be32(bh->b_blocknr);
 				affs_adjust_checksum(prev_bh, bh->b_blocknr - tmp_next);
-				mark_buffer_dirty_inode(prev_bh, inode);
+				mark_buffer_dirty_fsync(prev_bh, mapping);
 			}
 		} else if (be32_to_cpu(AFFS_DATA_HEAD(bh)->size) < tmp)
 			AFFS_DATA_HEAD(bh)->size = cpu_to_be32(tmp);
 		affs_brelse(prev_bh);
 		affs_fix_checksum(sb, bh);
-		mark_buffer_dirty_inode(bh, inode);
+		mark_buffer_dirty_fsync(bh, mapping);
 		written += tmp;
 		from += tmp;
 		bidx++;
@@ -863,6 +865,7 @@  affs_free_prealloc(struct inode *inode)
 void
 affs_truncate(struct inode *inode)
 {
+	struct address_space *mapping = inode->i_mapping;
 	struct super_block *sb = inode->i_sb;
 	u32 ext, ext_key;
 	u32 last_blk, blkcnt, blk;
@@ -881,7 +884,6 @@  affs_truncate(struct inode *inode)
 	}
 
 	if (inode->i_size > AFFS_I(inode)->mmu_private) {
-		struct address_space *mapping = inode->i_mapping;
 		struct page *page;
 		void *fsdata = NULL;
 		loff_t isize = inode->i_size;
@@ -938,7 +940,7 @@  affs_truncate(struct inode *inode)
 	}
 	AFFS_TAIL(sb, ext_bh)->extension = 0;
 	affs_fix_checksum(sb, ext_bh);
-	mark_buffer_dirty_inode(ext_bh, inode);
+	mark_buffer_dirty_fsync(ext_bh, mapping);
 	affs_brelse(ext_bh);
 
 	if (inode->i_size) {
diff --git a/fs/affs/inode.c b/fs/affs/inode.c
index 0210df8d3..a4e610944 100644
--- a/fs/affs/inode.c
+++ b/fs/affs/inode.c
@@ -165,6 +165,8 @@  struct inode *affs_iget(struct super_block *sb, unsigned long ino)
 int
 affs_write_inode(struct inode *inode, struct writeback_control *wbc)
 {
+	
+	struct address_space *mapping = inode->i_mapping;
 	struct super_block	*sb = inode->i_sb;
 	struct buffer_head	*bh;
 	struct affs_tail	*tail;
@@ -206,7 +208,7 @@  affs_write_inode(struct inode *inode, struct writeback_control *wbc)
 		}
 	}
 	affs_fix_checksum(sb, bh);
-	mark_buffer_dirty_inode(bh, inode);
+	mark_buffer_dirty_fsync(bh, mapping);
 	affs_brelse(bh);
 	affs_free_prealloc(inode);
 	return 0;
@@ -289,7 +291,8 @@  affs_evict_inode(struct inode *inode)
 
 struct inode *
 affs_new_inode(struct inode *dir)
-{
+{	
+	struct address_space *mapping = dir->i_mapping;
 	struct super_block	*sb = dir->i_sb;
 	struct inode		*inode;
 	u32			 block;
@@ -304,7 +307,7 @@  affs_new_inode(struct inode *dir)
 	bh = affs_getzeroblk(sb, block);
 	if (!bh)
 		goto err_bh;
-	mark_buffer_dirty_inode(bh, inode);
+	mark_buffer_dirty_fsync(bh, mapping);
 	affs_brelse(bh);
 
 	inode->i_uid     = current_fsuid();
@@ -347,6 +350,7 @@  affs_new_inode(struct inode *dir)
 int
 affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s32 type)
 {
+	struct address_space *mapping = inode->i_mapping;
 	struct super_block *sb = dir->i_sb;
 	struct buffer_head *inode_bh = NULL;
 	struct buffer_head *bh;
@@ -392,17 +396,17 @@  affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s3
 		AFFS_TAIL(sb, bh)->link_chain = chain;
 		AFFS_TAIL(sb, inode_bh)->link_chain = cpu_to_be32(block);
 		affs_adjust_checksum(inode_bh, block - be32_to_cpu(chain));
-		mark_buffer_dirty_inode(inode_bh, inode);
+		mark_buffer_dirty_fsync(inode_bh, mapping);
 		set_nlink(inode, 2);
 		ihold(inode);
 	}
 	affs_fix_checksum(sb, bh);
-	mark_buffer_dirty_inode(bh, inode);
+	mark_buffer_dirty_fsync(bh, mapping);
 	dentry->d_fsdata = (void *)(long)bh->b_blocknr;
 
 	affs_lock_dir(dir);
 	retval = affs_insert_hash(dir, bh);
-	mark_buffer_dirty_inode(bh, inode);
+	mark_buffer_dirty_fsync(bh, mapping);
 	affs_unlock_dir(dir);
 	affs_unlock_link(inode);
 
diff --git a/fs/affs/namei.c b/fs/affs/namei.c
index 8c154490a..a434ce621 100644
--- a/fs/affs/namei.c
+++ b/fs/affs/namei.c
@@ -373,7 +373,8 @@  affs_symlink(struct mnt_idmap *idmap, struct inode *dir,
 	}
 	*p = 0;
 	inode->i_size = i + 1;
-	mark_buffer_dirty_inode(bh, inode);
+	struct address_space *mapping = inode->i_mapping
+	mark_buffer_dirty_fsync(bh, mapping);
 	affs_brelse(bh);
 	mark_inode_dirty(inode);
 
@@ -443,7 +444,7 @@  affs_rename(struct inode *old_dir, struct dentry *old_dentry,
 	/* TODO: move it back to old_dir, if error? */
 
 done:
-	mark_buffer_dirty_inode(bh, retval ? old_dir : new_dir);
+	mark_buffer_dirty_fsync(bh, retval ? old_dir->i_mapping : new_dir->i_mapping);
 	affs_brelse(bh);
 	return retval;
 }
@@ -496,8 +497,8 @@  affs_xrename(struct inode *old_dir, struct dentry *old_dentry,
 	retval = affs_insert_hash(old_dir, bh_new);
 	affs_unlock_dir(old_dir);
 done:
-	mark_buffer_dirty_inode(bh_old, new_dir);
-	mark_buffer_dirty_inode(bh_new, old_dir);
+	mark_buffer_dirty_fsync(bh_old, new_dir->i_mapping);
+	mark_buffer_dirty_fsync(bh_new, old_dir->i_mapping);
 	affs_brelse(bh_old);
 	affs_brelse(bh_new);
 	return retval;
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c
index c375e22c4..b344a1b4a 100644
--- a/fs/bfs/dir.c
+++ b/fs/bfs/dir.c
@@ -169,6 +169,7 @@  static int bfs_link(struct dentry *old, struct inode *dir,
 static int bfs_unlink(struct inode *dir, struct dentry *dentry)
 {
 	int error = -ENOENT;
+	struct address_space *mapping = dir->i_mapping;
 	struct inode *inode = d_inode(dentry);
 	struct buffer_head *bh;
 	struct bfs_dirent *de;
@@ -186,7 +187,7 @@  static int bfs_unlink(struct inode *dir, struct dentry *dentry)
 		set_nlink(inode, 1);
 	}
 	de->ino = 0;
-	mark_buffer_dirty_inode(bh, dir);
+	mark_buffer_dirty_fsync(bh, mapping);
 	inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
 	mark_inode_dirty(dir);
 	inode_set_ctime_to_ts(inode, inode_get_ctime(dir));
@@ -246,7 +247,7 @@  static int bfs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
 		inode_set_ctime_current(new_inode);
 		inode_dec_link_count(new_inode);
 	}
-	mark_buffer_dirty_inode(old_bh, old_dir);
+	mark_buffer_dirty_fsync(old_bh, old_dir->i_mapping);
 	error = 0;
 
 end_rename:
@@ -296,7 +297,7 @@  static int bfs_add_entry(struct inode *dir, const struct qstr *child, int ino)
 				for (i = 0; i < BFS_NAMELEN; i++)
 					de->name[i] =
 						(i < namelen) ? name[i] : 0;
-				mark_buffer_dirty_inode(bh, dir);
+				mark_buffer_dirty_fsync(bh, dir->i_mapping);
 				brelse(bh);
 				return 0;
 			}
diff --git a/fs/buffer.c b/fs/buffer.c
index 8c19e705b..508851619 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -118,7 +118,7 @@  void buffer_check_dirty_writeback(struct folio *folio,
  * from becoming locked again - you have to lock it yourself
  * if you want to preserve its state.
  */
-void __wait_on_buffer(struct buffer_head * bh)
+void __wait_on_buffer(struct buffer_head *bh)
 {
 	wait_on_bit_io(&bh->b_state, BH_Lock, TASK_UNINTERRUPTIBLE);
 }
@@ -473,7 +473,7 @@  EXPORT_SYMBOL(mark_buffer_async_write);
  * try_to_free_buffers() will be operating against the *blockdev* mapping
  * at the time, not against the S_ISREG file which depends on those buffers.
  * So the locking for i_private_list is via the i_private_lock in the address_space
- * which backs the buffers.  Which is different from the address_space 
+ * which backs the buffers.  Which is different from the address_space
  * against which the buffers are listed.  So for a particular address_space,
  * mapping->i_private_lock does *not* protect mapping->i_private_list!  In fact,
  * mapping->i_private_list will always be protected by the backing blockdev's
@@ -666,26 +666,27 @@  void write_boundary_block(struct block_device *bdev,
 	}
 }
 
-void mark_buffer_dirty_inode(struct buffer_head *bh, struct inode *inode)
+void mark_buffer_dirty_fsync(struct buffer_head *bh, struct address_space *mapping)
 {
-	struct address_space *mapping = inode->i_mapping;
 	struct address_space *buffer_mapping = bh->b_folio->mapping;
 
 	mark_buffer_dirty(bh);
+
+	if (bh->b_assoc_map)
+        return;
+
 	if (!mapping->i_private_data) {
-		mapping->i_private_data = buffer_mapping;
-	} else {
-		BUG_ON(mapping->i_private_data != buffer_mapping);
-	}
-	if (!bh->b_assoc_map) {
-		spin_lock(&buffer_mapping->i_private_lock);
-		list_move_tail(&bh->b_assoc_buffers,
-				&mapping->i_private_list);
-		bh->b_assoc_map = mapping;
-		spin_unlock(&buffer_mapping->i_private_lock);
-	}
+    	mapping->i_private_data = buffer_mapping;
+    } else {
+        BUG_ON(mapping->i_private_data != buffer_mapping);
+    }
+
+    spin_lock(&buffer_mapping->i_private_lock);
+    list_move_tail(&bh->b_assoc_buffers, &mapping->i_private_list);
+    bh->b_assoc_map = mapping;
+    spin_unlock(&buffer_mapping->i_private_lock);
 }
-EXPORT_SYMBOL(mark_buffer_dirty_inode);
+EXPORT_SYMBOL(mark_buffer_dirty_fsync);
 
 /**
  * block_dirty_folio - Mark a folio as dirty.
@@ -843,7 +844,6 @@  static int fsync_buffers_list(spinlock_t *lock, struct list_head *list)
 		brelse(bh);
 		spin_lock(lock);
 	}
-	
 	spin_unlock(lock);
 	err2 = osync_buffers_list(lock, list);
 	if (err)
@@ -2155,7 +2155,7 @@  int __block_write_begin_int(struct folio *folio, loff_t pos, unsigned len,
 		    !buffer_unwritten(bh) &&
 		     (block_start < from || block_end > to)) {
 			bh_read_nowait(bh, 0);
-			*wait_bh++=bh;
+			*wait_bh++ = bh;
 		}
 	}
 	/*
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 0caa1650c..5410d3f47 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -526,7 +526,7 @@  static int ext2_alloc_branch(struct inode *inode,
 		}
 		set_buffer_uptodate(bh);
 		unlock_buffer(bh);
-		mark_buffer_dirty_inode(bh, inode);
+		mark_buffer_dirty_fsync(bh, inode->i_mapping);
 		/* We used to sync bh here if IS_SYNC(inode).
 		 * But we now rely upon generic_write_sync()
 		 * and b_inode_buffers.  But not for directories.
@@ -597,7 +597,7 @@  static void ext2_splice_branch(struct inode *inode,
 
 	/* had we spliced it onto indirect block? */
 	if (where->bh)
-		mark_buffer_dirty_inode(where->bh, inode);
+		mark_buffer_dirty_fsync(where->bh, inode->i_mapping);
 
 	inode_set_ctime_current(inode);
 	mark_inode_dirty(inode);
@@ -1199,7 +1199,7 @@  static void __ext2_truncate_blocks(struct inode *inode, loff_t offset)
 		if (partial == chain)
 			mark_inode_dirty(inode);
 		else
-			mark_buffer_dirty_inode(partial->bh, inode);
+			mark_buffer_dirty_fsync(partial->bh, inode->i_mapping);
 		ext2_free_branches(inode, &nr, &nr+1, (chain+n-1) - partial);
 	}
 	/* Clear the ends of indirect blocks on the shared branch */
@@ -1208,7 +1208,7 @@  static void __ext2_truncate_blocks(struct inode *inode, loff_t offset)
 				   partial->p + 1,
 				   (__le32*)partial->bh->b_data+addr_per_block,
 				   (chain+n-1) - partial);
-		mark_buffer_dirty_inode(partial->bh, inode);
+		mark_buffer_dirty_fsync(partial->bh, inode->i_mapping);
 		brelse (partial->bh);
 		partial--;
 	}
diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c
index da4a82456..93fe0ec45 100644
--- a/fs/ext4/ext4_jbd2.c
+++ b/fs/ext4/ext4_jbd2.c
@@ -379,7 +379,7 @@  int __ext4_handle_dirty_metadata(const char *where, unsigned int line,
 		}
 	} else {
 		if (inode)
-			mark_buffer_dirty_inode(bh, inode);
+			mark_buffer_dirty_fsync(bh, inode->i_mapping);
 		else
 			mark_buffer_dirty(bh);
 		if (inode && inode_needs_sync(inode)) {
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index acbec5bdd..85f84c633 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -1024,7 +1024,7 @@  static int __fat_remove_entries(struct inode *dir, loff_t pos, int nr_slots)
 			de++;
 			nr_slots--;
 		}
-		mark_buffer_dirty_inode(bh, dir);
+		mark_buffer_dirty_fsync(bh, dir->i_mapping);
 		if (IS_DIRSYNC(dir))
 			err = sync_dirty_buffer(bh);
 		brelse(bh);
@@ -1059,7 +1059,7 @@  int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo)
 		de--;
 		nr_slots--;
 	}
-	mark_buffer_dirty_inode(bh, dir);
+	mark_buffer_dirty_fsync(bh, dir->i_mapping);
 	if (IS_DIRSYNC(dir))
 		err = sync_dirty_buffer(bh);
 	brelse(bh);
@@ -1111,7 +1111,7 @@  static int fat_zeroed_cluster(struct inode *dir, sector_t blknr, int nr_used,
 		memset(bhs[n]->b_data, 0, sb->s_blocksize);
 		set_buffer_uptodate(bhs[n]);
 		unlock_buffer(bhs[n]);
-		mark_buffer_dirty_inode(bhs[n], dir);
+		mark_buffer_dirty_fsync(bhs[n], dir->i_mapping);
 
 		n++;
 		blknr++;
@@ -1192,7 +1192,7 @@  int fat_alloc_new_dir(struct inode *dir, struct timespec64 *ts)
 	memset(de + 2, 0, sb->s_blocksize - 2 * sizeof(*de));
 	set_buffer_uptodate(bhs[0]);
 	unlock_buffer(bhs[0]);
-	mark_buffer_dirty_inode(bhs[0], dir);
+	mark_buffer_dirty_fsync(bhs[0], dir->i_mapping);
 
 	err = fat_zeroed_cluster(dir, blknr, 1, bhs, MAX_BUF_PER_PAGE);
 	if (err)
@@ -1254,7 +1254,7 @@  static int fat_add_new_entries(struct inode *dir, void *slots, int nr_slots,
 			memcpy(bhs[n]->b_data, slots, copy);
 			set_buffer_uptodate(bhs[n]);
 			unlock_buffer(bhs[n]);
-			mark_buffer_dirty_inode(bhs[n], dir);
+			mark_buffer_dirty_fsync(bhs[n], dir->i_mapping);
 			slots += copy;
 			size -= copy;
 			if (!size)
@@ -1356,7 +1356,7 @@  int fat_add_entries(struct inode *dir, void *slots, int nr_slots,
 		for (i = 0; i < long_bhs; i++) {
 			int copy = min_t(int, sb->s_blocksize - offset, size);
 			memcpy(bhs[i]->b_data + offset, slots, copy);
-			mark_buffer_dirty_inode(bhs[i], dir);
+			mark_buffer_dirty_fsync(bhs[i], dir->i_mapping);
 			offset = 0;
 			slots += copy;
 			size -= copy;
@@ -1367,7 +1367,7 @@  int fat_add_entries(struct inode *dir, void *slots, int nr_slots,
 			/* Fill the short name slot. */
 			int copy = min_t(int, sb->s_blocksize - offset, size);
 			memcpy(bhs[i]->b_data + offset, slots, copy);
-			mark_buffer_dirty_inode(bhs[i], dir);
+			mark_buffer_dirty_fsync(bhs[i], dir->i_mapping);
 			if (IS_DIRSYNC(dir))
 				err = sync_dirty_buffer(bhs[i]);
 		}
diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c
index 1db348f8f..4aa928e09 100644
--- a/fs/fat/fatent.c
+++ b/fs/fat/fatent.c
@@ -170,9 +170,9 @@  static void fat12_ent_put(struct fat_entry *fatent, int new)
 	}
 	spin_unlock(&fat12_entry_lock);
 
-	mark_buffer_dirty_inode(fatent->bhs[0], fatent->fat_inode);
+	mark_buffer_dirty_fsync(fatent->bhs[0], fatent->fat_inode->i_mapping);
 	if (fatent->nr_bhs == 2)
-		mark_buffer_dirty_inode(fatent->bhs[1], fatent->fat_inode);
+		mark_buffer_dirty_fsync(fatent->bhs[1], fatent->fat_inode->i_mapping);
 }
 
 static void fat16_ent_put(struct fat_entry *fatent, int new)
@@ -181,7 +181,7 @@  static void fat16_ent_put(struct fat_entry *fatent, int new)
 		new = EOF_FAT16;
 
 	*fatent->u.ent16_p = cpu_to_le16(new);
-	mark_buffer_dirty_inode(fatent->bhs[0], fatent->fat_inode);
+	mark_buffer_dirty_fsync(fatent->bhs[0], fatent->fat_inode->i_mapping);
 }
 
 static void fat32_ent_put(struct fat_entry *fatent, int new)
@@ -189,7 +189,7 @@  static void fat32_ent_put(struct fat_entry *fatent, int new)
 	WARN_ON(new & 0xf0000000);
 	new |= le32_to_cpu(*fatent->u.ent32_p) & ~0x0fffffff;
 	*fatent->u.ent32_p = cpu_to_le32(new);
-	mark_buffer_dirty_inode(fatent->bhs[0], fatent->fat_inode);
+	mark_buffer_dirty_fsync(fatent->bhs[0], fatent->fat_inode->i_mapping);
 }
 
 static int fat12_ent_next(struct fat_entry *fatent)
@@ -395,7 +395,7 @@  static int fat_mirror_bhs(struct super_block *sb, struct buffer_head **bhs,
 			memcpy(c_bh->b_data, bhs[n]->b_data, sb->s_blocksize);
 			set_buffer_uptodate(c_bh);
 			unlock_buffer(c_bh);
-			mark_buffer_dirty_inode(c_bh, sbi->fat_inode);
+			mark_buffer_dirty_fsync(c_bh, sbi->fat_inode->i_mapping);
 			if (sb->s_flags & SB_SYNCHRONOUS)
 				err = sync_dirty_buffer(c_bh);
 			brelse(c_bh);
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
index 2116c4868..2fa341ba6 100644
--- a/fs/fat/namei_msdos.c
+++ b/fs/fat/namei_msdos.c
@@ -524,7 +524,7 @@  static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
 
 	if (update_dotdot) {
 		fat_set_start(dotdot_de, MSDOS_I(new_dir)->i_logstart);
-		mark_buffer_dirty_inode(dotdot_bh, old_inode);
+		mark_buffer_dirty_fsync(dotdot_bh, old_inode->i_mapping);
 		if (IS_DIRSYNC(new_dir)) {
 			err = sync_dirty_buffer(dotdot_bh);
 			if (err)
@@ -564,7 +564,7 @@  static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
 
 	if (update_dotdot) {
 		fat_set_start(dotdot_de, MSDOS_I(old_dir)->i_logstart);
-		mark_buffer_dirty_inode(dotdot_bh, old_inode);
+		mark_buffer_dirty_fsync(dotdot_bh, old_inode->i_mapping);
 		corrupt |= sync_dirty_buffer(dotdot_bh);
 	}
 error_inode:
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index c4d00999a..c4ed9fd7d 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -912,7 +912,7 @@  static int vfat_update_dotdot_de(struct inode *dir, struct inode *inode,
 				 struct msdos_dir_entry *dotdot_de)
 {
 	fat_set_start(dotdot_de, MSDOS_I(dir)->i_logstart);
-	mark_buffer_dirty_inode(dotdot_bh, inode);
+	mark_buffer_dirty_fsync(dotdot_bh, inode->i_mapping);
 	if (IS_DIRSYNC(dir))
 		return sync_dirty_buffer(dotdot_bh);
 	return 0;
diff --git a/fs/minix/itree_common.c b/fs/minix/itree_common.c
index dad131e30..4354da0ce 100644
--- a/fs/minix/itree_common.c
+++ b/fs/minix/itree_common.c
@@ -98,7 +98,7 @@  static int alloc_branch(struct inode *inode,
 		*branch[n].p = branch[n].key;
 		set_buffer_uptodate(bh);
 		unlock_buffer(bh);
-		mark_buffer_dirty_inode(bh, inode);
+		mark_buffer_dirty_fsync(bh, inode->i_mapping);
 		parent = nr;
 	}
 	if (n == num)
@@ -135,7 +135,7 @@  static inline int splice_branch(struct inode *inode,
 
 	/* had we spliced it onto indirect block? */
 	if (where->bh)
-		mark_buffer_dirty_inode(where->bh, inode);
+		mark_buffer_dirty_fsync(where->bh, inode->i_mapping);
 
 	mark_inode_dirty(inode);
 	return 0;
@@ -328,14 +328,14 @@  static inline void truncate (struct inode * inode)
 		if (partial == chain)
 			mark_inode_dirty(inode);
 		else
-			mark_buffer_dirty_inode(partial->bh, inode);
+			mark_buffer_dirty_fsync(partial->bh, inode->i_mapping);
 		free_branches(inode, &nr, &nr+1, (chain+n-1) - partial);
 	}
 	/* Clear the ends of indirect blocks on the shared branch */
 	while (partial > chain) {
 		free_branches(inode, partial->p + 1, block_end(partial->bh),
 				(chain+n-1) - partial);
-		mark_buffer_dirty_inode(partial->bh, inode);
+		mark_buffer_dirty_fsync(partial->bh, inode->i_mapping);
 		brelse (partial->bh);
 		partial--;
 	}
diff --git a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c
index 6c13a8d9a..ce94efe0a 100644
--- a/fs/reiserfs/fix_node.c
+++ b/fs/reiserfs/fix_node.c
@@ -2623,9 +2623,12 @@  int fix_nodes(int op_mode, struct tree_balance *tb,
 	}
 #endif
 
-	if (get_mem_for_virtual_node(tb) == REPEAT_SEARCH)
-		/* FIXME: maybe -ENOMEM when tb->vn_buf == 0? Now just repeat */
+	if (get_mem_for_virtual_node(tb) == REPEAT_SEARCH) {
+		if (tb->vn_buf == 0) {
+        	return -ENOMEM;
+   		}
 		return REPEAT_SEARCH;
+	}
 
 	/* Starting from the leaf level; for all levels h of the tree. */
 	for (h = 0; h < MAX_HEIGHT && tb->insert_size[h]; h++) {
diff --git a/fs/sysv/itree.c b/fs/sysv/itree.c
index 19bcb51a2..c50a77a4d 100644
--- a/fs/sysv/itree.c
+++ b/fs/sysv/itree.c
@@ -16,7 +16,7 @@  enum {DIRECT = 10, DEPTH = 4};	/* Have triple indirect */
 
 static inline void dirty_indirect(struct buffer_head *bh, struct inode *inode)
 {
-	mark_buffer_dirty_inode(bh, inode);
+	mark_buffer_dirty_fsync(bh, inode->i_mapping);
 	if (IS_SYNC(inode))
 		sync_dirty_buffer(bh);
 }
diff --git a/fs/udf/directory.c b/fs/udf/directory.c
index 93153665e..4ecb058c0 100644
--- a/fs/udf/directory.c
+++ b/fs/udf/directory.c
@@ -423,9 +423,9 @@  void udf_fiiter_write_fi(struct udf_fileident_iter *iter, uint8_t *impuse)
 	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
 		mark_inode_dirty(iter->dir);
 	} else {
-		mark_buffer_dirty_inode(iter->bh[0], iter->dir);
+		mark_buffer_dirty_fsync(iter->bh[0], iter->dir->i_mapping);
 		if (iter->bh[1])
-			mark_buffer_dirty_inode(iter->bh[1], iter->dir);
+			mark_buffer_dirty_fsync(iter->bh[1], iter->dir->i_mapping);
 	}
 	inode_inc_iversion(iter->dir);
 }
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 2fb21c5ff..3f2d8b150 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -1226,7 +1226,7 @@  struct buffer_head *udf_bread(struct inode *inode, udf_pblk_t block,
 		memset(bh->b_data, 0x00, inode->i_sb->s_blocksize);
 		set_buffer_uptodate(bh);
 		unlock_buffer(bh);
-		mark_buffer_dirty_inode(bh, inode);
+		mark_buffer_dirty_fsync(bh, inode->i_mapping);
 		return bh;
 	}
 
@@ -1978,7 +1978,7 @@  int udf_setup_indirect_aext(struct inode *inode, udf_pblk_t block,
 	memset(bh->b_data, 0x00, sb->s_blocksize);
 	set_buffer_uptodate(bh);
 	unlock_buffer(bh);
-	mark_buffer_dirty_inode(bh, inode);
+	mark_buffer_dirty_fsync(bh, inode->i_mapping);
 
 	aed = (struct allocExtDesc *)(bh->b_data);
 	if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT)) {
@@ -2068,7 +2068,7 @@  int __udf_add_aext(struct inode *inode, struct extent_position *epos,
 		else
 			udf_update_tag(epos->bh->b_data,
 					sizeof(struct allocExtDesc));
-		mark_buffer_dirty_inode(epos->bh, inode);
+		mark_buffer_dirty_fsync(epos->bh, inode->i_mapping);
 	}
 
 	return 0;
@@ -2152,7 +2152,7 @@  void udf_write_aext(struct inode *inode, struct extent_position *epos,
 				       le32_to_cpu(aed->lengthAllocDescs) +
 				       sizeof(struct allocExtDesc));
 		}
-		mark_buffer_dirty_inode(epos->bh, inode);
+		mark_buffer_dirty_fsync(epos->bh, inode->i_mapping);
 	} else {
 		mark_inode_dirty(inode);
 	}
@@ -2331,7 +2331,7 @@  int8_t udf_delete_aext(struct inode *inode, struct extent_position epos)
 			else
 				udf_update_tag(oepos.bh->b_data,
 						sizeof(struct allocExtDesc));
-			mark_buffer_dirty_inode(oepos.bh, inode);
+			mark_buffer_dirty_fsync(oepos.bh, inode->i_mapping);
 		}
 	} else {
 		udf_write_aext(inode, &oepos, &eloc, elen, 1);
@@ -2348,7 +2348,7 @@  int8_t udf_delete_aext(struct inode *inode, struct extent_position epos)
 			else
 				udf_update_tag(oepos.bh->b_data,
 						sizeof(struct allocExtDesc));
-			mark_buffer_dirty_inode(oepos.bh, inode);
+			mark_buffer_dirty_fsync(oepos.bh, inode->i_mapping);
 		}
 	}
 
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index 1308109fd..b6dfa195a 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -634,7 +634,7 @@  static int udf_symlink(struct mnt_idmap *idmap, struct inode *dir,
 		memset(epos.bh->b_data, 0x00, bsize);
 		set_buffer_uptodate(epos.bh);
 		unlock_buffer(epos.bh);
-		mark_buffer_dirty_inode(epos.bh, inode);
+		mark_buffer_dirty_fsync(epos.bh, inode->i_mapping);
 		ea = epos.bh->b_data + udf_ext0_offset(inode);
 	} else
 		ea = iinfo->i_data + iinfo->i_lenEAttr;
diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c
index a686c10fd..c73fabb8f 100644
--- a/fs/udf/truncate.c
+++ b/fs/udf/truncate.c
@@ -169,7 +169,7 @@  static void udf_update_alloc_ext_desc(struct inode *inode,
 		len += lenalloc;
 
 	udf_update_tag(epos->bh->b_data, len);
-	mark_buffer_dirty_inode(epos->bh, inode);
+	mark_buffer_dirty_fsync(epos->bh, inode->i_mapping);
 }
 
 /*
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 14acf1bbe..d8f650883 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -207,7 +207,7 @@  void end_buffer_read_sync(struct buffer_head *bh, int uptodate);
 void end_buffer_write_sync(struct buffer_head *bh, int uptodate);
 
 /* Things to do with buffers at mapping->private_list */
-void mark_buffer_dirty_inode(struct buffer_head *bh, struct inode *inode);
+void mark_buffer_dirty_fsync(struct buffer_head *bh, struct address_space *inode);
 int generic_buffers_fsync_noflush(struct file *file, loff_t start, loff_t end,
 				  bool datasync);
 int generic_buffers_fsync(struct file *file, loff_t start, loff_t end,