All of lore.kernel.org
 help / color / mirror / Atom feed
From: Al Viro <viro@zeniv.linux.org.uk>
To: linux-fsdevel@vger.kernel.org
Cc: Evgeniy Dushistov <dushistov@mail.ru>,
	"Fabio M. De Francesco" <fmdefrancesco@gmail.com>
Subject: [PATCH 05/12] ufs: fix handling of delete_entry and set_link failures
Date: Wed, 13 Dec 2023 03:18:20 +0000	[thread overview]
Message-ID: <20231213031827.2767531-5-viro@zeniv.linux.org.uk> (raw)
In-Reply-To: <20231213031827.2767531-1-viro@zeniv.linux.org.uk>

similar to minixfs series - make ufs_set_link() report failures,
lift dir_put_page() into the callers of ufs_set_link() and
ufs_delete_entry(), make ufs_rename() handle failures in both.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/ufs/dir.c   | 27 ++++++++++++---------------
 fs/ufs/namei.c | 40 +++++++++++++++++-----------------------
 fs/ufs/ufs.h   |  2 +-
 3 files changed, 30 insertions(+), 39 deletions(-)

diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index fcf13e3ca869..5edacece384b 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -81,8 +81,7 @@ ino_t ufs_inode_by_name(struct inode *dir, const struct qstr *qstr)
 }
 
 
-/* Releases the page */
-void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
+int ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
 		  struct page *page, struct inode *inode,
 		  bool update_times)
 {
@@ -92,17 +91,19 @@ void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
 
 	lock_page(page);
 	err = ufs_prepare_chunk(page, pos, len);
-	BUG_ON(err);
+	if (unlikely(err)) {
+		unlock_page(page);
+		return err;
+	}
 
 	de->d_ino = cpu_to_fs32(dir->i_sb, inode->i_ino);
 	ufs_set_de_type(dir->i_sb, de, inode->i_mode);
 
 	ufs_commit_chunk(page, pos, len);
-	unmap_and_put_page(page, de);
 	if (update_times)
 		inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
 	mark_inode_dirty(dir);
-	ufs_handle_dirsync(dir);
+	return ufs_handle_dirsync(dir);
 }
 
 
@@ -522,8 +523,6 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir,
 	struct ufs_dir_entry *de = (struct ufs_dir_entry *) (kaddr + from);
 	int err;
 
-	UFSD("ENTER\n");
-
 	UFSD("ino %u, reclen %u, namlen %u, name %s\n",
 	      fs32_to_cpu(sb, de->d_ino),
 	      fs16_to_cpu(sb, de->d_reclen),
@@ -533,8 +532,7 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir,
 		if (de->d_reclen == 0) {
 			ufs_error(inode->i_sb, __func__,
 				  "zero-length directory entry");
-			err = -EIO;
-			goto out;
+			return -EIO;
 		}
 		pde = de;
 		de = ufs_next_entry(sb, de);
@@ -545,18 +543,17 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir,
 	pos = page_offset(page) + from;
 	lock_page(page);
 	err = ufs_prepare_chunk(page, pos, to - from);
-	BUG_ON(err);
+	if (unlikely(err)) {
+		unlock_page(page);
+		return err;
+	}
 	if (pde)
 		pde->d_reclen = cpu_to_fs16(sb, to - from);
 	dir->d_ino = 0;
 	ufs_commit_chunk(page, pos, to - from);
 	inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
 	mark_inode_dirty(inode);
-	err = ufs_handle_dirsync(inode);
-out:
-	unmap_and_put_page(page, kaddr);
-	UFSD("EXIT\n");
-	return err;
+	return ufs_handle_dirsync(inode);
 }
 
 int ufs_make_empty(struct inode * inode, struct inode *dir)
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index 25fa97340f73..b8082fb53a08 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -210,20 +210,18 @@ static int ufs_unlink(struct inode *dir, struct dentry *dentry)
 	struct inode * inode = d_inode(dentry);
 	struct ufs_dir_entry *de;
 	struct page *page;
-	int err = -ENOENT;
+	int err;
 
 	de = ufs_find_entry(dir, &dentry->d_name, &page);
 	if (!de)
-		goto out;
+		return -ENOENT;
 
 	err = ufs_delete_entry(dir, de, page);
-	if (err)
-		goto out;
-
-	inode_set_ctime_to_ts(inode, inode_get_ctime(dir));
-	inode_dec_link_count(inode);
-	err = 0;
-out:
+	if (!err) {
+		inode_set_ctime_to_ts(inode, inode_get_ctime(dir));
+		inode_dec_link_count(inode);
+	}
+	unmap_and_put_page(page, de);
 	return err;
 }
 
@@ -253,14 +251,14 @@ static int ufs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
 	struct ufs_dir_entry *dir_de = NULL;
 	struct page *old_page;
 	struct ufs_dir_entry *old_de;
-	int err = -ENOENT;
+	int err;
 
 	if (flags & ~RENAME_NOREPLACE)
 		return -EINVAL;
 
 	old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page);
 	if (!old_de)
-		goto out;
+		return -ENOENT;
 
 	if (S_ISDIR(old_inode->i_mode)) {
 		err = -EIO;
@@ -281,7 +279,10 @@ static int ufs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
 		new_de = ufs_find_entry(new_dir, &new_dentry->d_name, &new_page);
 		if (!new_de)
 			goto out_dir;
-		ufs_set_link(new_dir, new_de, new_page, old_inode, 1);
+		err = ufs_set_link(new_dir, new_de, new_page, old_inode, 1);
+		unmap_and_put_page(new_page, new_de);
+		if (err)
+			goto out_dir;
 		inode_set_ctime_current(new_inode);
 		if (dir_de)
 			drop_nlink(new_inode);
@@ -299,27 +300,20 @@ static int ufs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
  	 * rename.
 	 */
 	inode_set_ctime_current(old_inode);
-
-	ufs_delete_entry(old_dir, old_de, old_page);
 	mark_inode_dirty(old_inode);
 
-	if (dir_de) {
+	err = ufs_delete_entry(old_dir, old_de, old_page);
+	if (!err && dir_de) {
 		if (old_dir != new_dir)
-			ufs_set_link(old_inode, dir_de, dir_page, new_dir, 0);
-		else {
-			unmap_and_put_page(dir_page, dir_de);
-		}
+			err = ufs_set_link(old_inode, dir_de, dir_page,
+					   new_dir, 0);
 		inode_dec_link_count(old_dir);
 	}
-	return 0;
-
-
 out_dir:
 	if (dir_de)
 		unmap_and_put_page(dir_page, dir_de);
 out_old:
 	unmap_and_put_page(old_page, old_de);
-out:
 	return err;
 }
 
diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h
index 6b499180643b..b521ab01471a 100644
--- a/fs/ufs/ufs.h
+++ b/fs/ufs/ufs.h
@@ -106,7 +106,7 @@ extern struct ufs_dir_entry *ufs_find_entry(struct inode *, const struct qstr *,
 extern int ufs_delete_entry(struct inode *, struct ufs_dir_entry *, struct page *);
 extern int ufs_empty_dir (struct inode *);
 extern struct ufs_dir_entry *ufs_dotdot(struct inode *, struct page **);
-extern void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
+extern int ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
 			 struct page *page, struct inode *inode, bool update_times);
 
 /* file.c */
-- 
2.39.2


  parent reply	other threads:[~2023-12-13  3:18 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-13  3:16 [patches][cft] ufs stuff Al Viro
2023-12-13  3:18 ` [PATCH 01/12] fs/ufs: Use the offset_in_page() helper Al Viro
2023-12-13  3:18   ` [PATCH 02/12] fs/ufs: Change the signature of ufs_get_page() Al Viro
2023-12-13  3:18   ` [PATCH 03/12] fs/ufs: Use ufs_put_page() in ufs_rename() Al Viro
2023-12-13  3:18   ` [PATCH 04/12] fs/ufs: Replace kmap() with kmap_local_page() Al Viro
2023-12-13  3:18   ` Al Viro [this message]
2023-12-13  3:18   ` [PATCH 06/12] ufs: untangle ubh_...block...() macros, part 1 Al Viro
2023-12-13  3:18   ` [PATCH 07/12] ufs: untangle ubh_...block...(), part 2 Al Viro
2023-12-13  3:18   ` [PATCH 08/12] ufs: untangle ubh_...block...(), part 3 Al Viro
2023-12-13  3:18   ` [PATCH 09/12] ufs_clusteracct(): switch to passing fragment number Al Viro
2023-12-13  3:18   ` [PATCH 10/12] ufs_inode_getfrag(): remove junk comment Al Viro
2023-12-13  3:18   ` [PATCH 11/12] ufs: get rid of ubh_{ubhcpymem,memcpyubh}() Al Viro
2023-12-13  3:18   ` [PATCH 12/12] clean ufs_trunc_direct() up a bit Al Viro
2023-12-13  6:53 ` [patches][cft] ufs stuff Al Viro

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231213031827.2767531-5-viro@zeniv.linux.org.uk \
    --to=viro@zeniv.linux.org.uk \
    --cc=dushistov@mail.ru \
    --cc=fmdefrancesco@gmail.com \
    --cc=linux-fsdevel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.