Re: [PATCH 6.6 3/3] nilfs2: handle errors that nilfs_prepare_chunk() may return

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



[ Sasha's backport helper bot ]

Hi,

Summary of potential issues and notes:
ℹ️ This is part 3/3 of a series

The upstream commit SHA1 provided is correct: ee70999a988b8abc3490609142f50ebaa8344432

Note: The patch differs from the upstream commit:
---
1:  ee70999a988b8 ! 1:  1d6894c5f5775 nilfs2: handle errors that nilfs_prepare_chunk() may return
    @@ Metadata
      ## Commit message ##
         nilfs2: handle errors that nilfs_prepare_chunk() may return
     
    +    commit ee70999a988b8abc3490609142f50ebaa8344432 upstream.
    +
         Patch series "nilfs2: fix issues with rename operations".
     
         This series fixes BUG_ON check failures reported by syzbot around rename
         operations, and a minor behavioral issue where the mtime of a child
         directory changes when it is renamed instead of moved.
     
    -
         This patch (of 2):
     
         The directory manipulation routines nilfs_set_link() and
    @@ Commit message
         Fix this issue by adding missing error paths in nilfs_set_link(),
         nilfs_delete_entry(), and their caller nilfs_rename().
     
    +    [konishi.ryusuke@xxxxxxxxx: adjusted for page/folio conversion]
         Link: https://lkml.kernel.org/r/20250111143518.7901-1-konishi.ryusuke@xxxxxxxxx
         Link: https://lkml.kernel.org/r/20250111143518.7901-2-konishi.ryusuke@xxxxxxxxx
         Signed-off-by: Ryusuke Konishi <konishi.ryusuke@xxxxxxxxx>
    @@ fs/nilfs2/dir.c: int nilfs_inode_by_name(struct inode *dir, const struct qstr *q
      
     -void nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de,
     +int nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de,
    - 		    struct folio *folio, struct inode *inode)
    + 		    struct page *page, struct inode *inode)
      {
    - 	size_t from = offset_in_folio(folio, de);
    + 	unsigned int from = (char *)de - (char *)page_address(page);
     @@ fs/nilfs2/dir.c: void nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de,
      
    - 	folio_lock(folio);
    - 	err = nilfs_prepare_chunk(folio, from, to);
    + 	lock_page(page);
    + 	err = nilfs_prepare_chunk(page, from, to);
     -	BUG_ON(err);
     +	if (unlikely(err)) {
    -+		folio_unlock(folio);
    ++		unlock_page(page);
     +		return err;
     +	}
      	de->inode = cpu_to_le64(inode->i_ino);
    - 	de->file_type = fs_umode_to_ftype(inode->i_mode);
    - 	nilfs_commit_chunk(folio, mapping, from, to);
    - 	inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
    + 	nilfs_set_de_type(de, inode);
    + 	nilfs_commit_chunk(page, mapping, from, to);
    + 	dir->i_mtime = inode_set_ctime_current(dir);
     +	return 0;
      }
      
      /*
    -@@ fs/nilfs2/dir.c: int nilfs_delete_entry(struct nilfs_dir_entry *dir, struct folio *folio)
    - 		from = (char *)pde - kaddr;
    - 	folio_lock(folio);
    - 	err = nilfs_prepare_chunk(folio, from, to);
    +@@ fs/nilfs2/dir.c: int nilfs_delete_entry(struct nilfs_dir_entry *dir, struct page *page)
    + 		from = (char *)pde - (char *)page_address(page);
    + 	lock_page(page);
    + 	err = nilfs_prepare_chunk(page, from, to);
     -	BUG_ON(err);
     +	if (unlikely(err)) {
    -+		folio_unlock(folio);
    ++		unlock_page(page);
     +		goto out;
     +	}
      	if (pde)
    @@ fs/nilfs2/namei.c: static int nilfs_rename(struct mnt_idmap *idmap,
      			err = PTR_ERR(new_de);
      			goto out_dir;
      		}
    --		nilfs_set_link(new_dir, new_de, new_folio, old_inode);
    -+		err = nilfs_set_link(new_dir, new_de, new_folio, old_inode);
    - 		folio_release_kmap(new_folio, new_de);
    +-		nilfs_set_link(new_dir, new_de, new_page, old_inode);
    ++		err = nilfs_set_link(new_dir, new_de, new_page, old_inode);
    + 		nilfs_put_page(new_page);
     +		if (unlikely(err))
     +			goto out_dir;
      		nilfs_mark_inode_dirty(new_dir);
    @@ fs/nilfs2/namei.c: static int nilfs_rename(struct mnt_idmap *idmap,
      	 */
      	inode_set_ctime_current(old_inode);
      
    --	nilfs_delete_entry(old_de, old_folio);
    +-	nilfs_delete_entry(old_de, old_page);
     -
     -	if (dir_de) {
    --		nilfs_set_link(old_inode, dir_de, dir_folio, new_dir);
    --		folio_release_kmap(dir_folio, dir_de);
    +-		nilfs_set_link(old_inode, dir_de, dir_page, new_dir);
    +-		nilfs_put_page(dir_page);
     -		drop_nlink(old_dir);
    -+	err = nilfs_delete_entry(old_de, old_folio);
    ++	err = nilfs_delete_entry(old_de, old_page);
     +	if (likely(!err)) {
     +		if (dir_de) {
    -+			err = nilfs_set_link(old_inode, dir_de, dir_folio,
    ++			err = nilfs_set_link(old_inode, dir_de, dir_page,
     +					     new_dir);
     +			drop_nlink(old_dir);
     +		}
     +		nilfs_mark_inode_dirty(old_dir);
      	}
    --	folio_release_kmap(old_folio, old_de);
    +-	nilfs_put_page(old_page);
     -
     -	nilfs_mark_inode_dirty(old_dir);
      	nilfs_mark_inode_dirty(old_inode);
    @@ fs/nilfs2/namei.c: static int nilfs_rename(struct mnt_idmap *idmap,
     -
      out_dir:
      	if (dir_de)
    - 		folio_release_kmap(dir_folio, dir_de);
    + 		nilfs_put_page(dir_page);
      out_old:
    - 	folio_release_kmap(old_folio, old_de);
    + 	nilfs_put_page(old_page);
      out:
     -	nilfs_transaction_abort(old_dir->i_sb);
     +	if (likely(!err))
    @@ fs/nilfs2/namei.c: static int nilfs_rename(struct mnt_idmap *idmap,
      
     
      ## fs/nilfs2/nilfs.h ##
    -@@ fs/nilfs2/nilfs.h: struct nilfs_dir_entry *nilfs_find_entry(struct inode *, const struct qstr *,
    - int nilfs_delete_entry(struct nilfs_dir_entry *, struct folio *);
    - int nilfs_empty_dir(struct inode *);
    - struct nilfs_dir_entry *nilfs_dotdot(struct inode *, struct folio **);
    --void nilfs_set_link(struct inode *, struct nilfs_dir_entry *,
    --			   struct folio *, struct inode *);
    +@@ fs/nilfs2/nilfs.h: nilfs_find_entry(struct inode *, const struct qstr *, struct page **);
    + extern int nilfs_delete_entry(struct nilfs_dir_entry *, struct page *);
    + extern int nilfs_empty_dir(struct inode *);
    + extern struct nilfs_dir_entry *nilfs_dotdot(struct inode *, struct page **);
    +-extern void nilfs_set_link(struct inode *, struct nilfs_dir_entry *,
    +-			   struct page *, struct inode *);
     +int nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de,
    -+		   struct folio *folio, struct inode *inode);
    ++		   struct page *page, struct inode *inode);
      
    - /* file.c */
    - extern int nilfs_sync_file(struct file *, loff_t, loff_t, int);
    + static inline void nilfs_put_page(struct page *page)
    + {
---

NOTE: These results are for this patch alone. Full series testing will be
performed when all parts are received.

Results of testing on various branches:

| Branch                    | Patch Apply | Build Test |
|---------------------------|-------------|------------|
| stable/linux-6.6.y        |  Success    |  Success   |




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux