diff mbox series

btrfs: update target inode's ctime on unlink

Message ID 20240812-btrfs-unlink-v1-1-ee5c2ef538eb@kernel.org (mailing list archive)
State Not Applicable
Headers show
Series btrfs: update target inode's ctime on unlink | expand

Checks

Context Check Description
netdev/tree_selection success Not a local patch

Commit Message

Jeff Layton Aug. 12, 2024, 4:30 p.m. UTC
Unlink changes the link count on the target inode. POSIX mandates that
the ctime must also change when this occurs.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
Found using the nfstest_posix testsuite with knfsd exporting btrfs.
---
 fs/btrfs/inode.c | 1 +
 1 file changed, 1 insertion(+)


---
base-commit: 7c626ce4bae1ac14f60076d00eafe71af30450ba
change-id: 20240812-btrfs-unlink-77293421e416

Best regards,

Comments

David Sterba Aug. 12, 2024, 4:42 p.m. UTC | #1
On Mon, Aug 12, 2024 at 12:30:52PM -0400, Jeff Layton wrote:
> Unlink changes the link count on the target inode. POSIX mandates that
> the ctime must also change when this occurs.

Right, thanks. According to https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html:

Upon successful completion, unlink() shall mark for update the last data
modification and last file status change timestamps of the parent
directory. Also, if the file's link count is not 0, the last file status
change timestamp of the file shall be marked for update.


> Signed-off-by: Jeff Layton <jlayton@kernel.org>

Reviewed-by: David Sterba <dsterba@suse.com>
Jeff Layton Aug. 12, 2024, 4:51 p.m. UTC | #2
On Mon, 2024-08-12 at 18:42 +0200, David Sterba wrote:
> On Mon, Aug 12, 2024 at 12:30:52PM -0400, Jeff Layton wrote:
> > Unlink changes the link count on the target inode. POSIX mandates that
> > the ctime must also change when this occurs.
> 
> Right, thanks. According to https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html:
> 
> Upon successful completion, unlink() shall mark for update the last data
> modification and last file status change timestamps of the parent
> directory. Also, if the file's link count is not 0, the last file status
> change timestamp of the file shall be marked for update.
> 

Weird way to phrase to that. IMO, we still want to stamp the inode's
ctime even if the link count goes to 0. That's what Linux generally
does, anyway. Oh well..
 
> 
> > Signed-off-by: Jeff Layton <jlayton@kernel.org>
> 
> Reviewed-by: David Sterba <dsterba@suse.com>


FWIW, this should probably go in via the btrfs tree.
Qu Wenruo Aug. 12, 2024, 11:27 p.m. UTC | #3
在 2024/8/13 02:00, Jeff Layton 写道:
> Unlink changes the link count on the target inode. POSIX mandates that
> the ctime must also change when this occurs.
> 
> Signed-off-by: Jeff Layton <jlayton@kernel.org>

Reviewed-by: Qu Wenruo <wqu@suse.com>

And since we decreased the nlink of the target inode already, updating 
the timestamp will not cause extra COW overhead.

So this won't cause any extra performance penalty.

Thanks,
Qu

> ---
> Found using the nfstest_posix testsuite with knfsd exporting btrfs.
> ---
>   fs/btrfs/inode.c | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
> index 333b0e8587a2..b1b6564ab68f 100644
> --- a/fs/btrfs/inode.c
> +++ b/fs/btrfs/inode.c
> @@ -4195,6 +4195,7 @@ static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans,
>   
>   	btrfs_i_size_write(dir, dir->vfs_inode.i_size - name->len * 2);
>   	inode_inc_iversion(&inode->vfs_inode);
> +	inode_set_ctime_current(&inode->vfs_inode);
>   	inode_inc_iversion(&dir->vfs_inode);
>    	inode_set_mtime_to_ts(&dir->vfs_inode, inode_set_ctime_current(&dir->vfs_inode));
>   	ret = btrfs_update_inode(trans, dir);
> 
> ---
> base-commit: 7c626ce4bae1ac14f60076d00eafe71af30450ba
> change-id: 20240812-btrfs-unlink-77293421e416
> 
> Best regards,
David Sterba Aug. 13, 2024, 1 p.m. UTC | #4
On Mon, Aug 12, 2024 at 12:51:21PM -0400, Jeff Layton wrote:
> On Mon, 2024-08-12 at 18:42 +0200, David Sterba wrote:
> > On Mon, Aug 12, 2024 at 12:30:52PM -0400, Jeff Layton wrote:
> > > Unlink changes the link count on the target inode. POSIX mandates that
> > > the ctime must also change when this occurs.
> > 
> > Right, thanks. According to https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html:
> > 
> > Upon successful completion, unlink() shall mark for update the last data
> > modification and last file status change timestamps of the parent
> > directory. Also, if the file's link count is not 0, the last file status
> > change timestamp of the file shall be marked for update.
> > 
> 
> Weird way to phrase to that. IMO, we still want to stamp the inode's
> ctime even if the link count goes to 0. That's what Linux generally
> does, anyway. Oh well..
>  
> > 
> > > Signed-off-by: Jeff Layton <jlayton@kernel.org>
> > 
> > Reviewed-by: David Sterba <dsterba@suse.com>
> 
> 
> FWIW, this should probably go in via the btrfs tree. 

Yes, we'll take it.
Christoph Hellwig Aug. 13, 2024, 1:27 p.m. UTC | #5
On Mon, Aug 12, 2024 at 12:30:52PM -0400, Jeff Layton wrote:
> Unlink changes the link count on the target inode. POSIX mandates that
> the ctime must also change when this occurs.
> 
> Signed-off-by: Jeff Layton <jlayton@kernel.org>
> ---
> Found using the nfstest_posix testsuite with knfsd exporting btrfs.

Can you also wire this up for xfstests?  I suspect other file systems
might have similar issues, so running this as part of normal file system
QA would be helpful.
diff mbox series

Patch

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 333b0e8587a2..b1b6564ab68f 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -4195,6 +4195,7 @@  static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans,
 
 	btrfs_i_size_write(dir, dir->vfs_inode.i_size - name->len * 2);
 	inode_inc_iversion(&inode->vfs_inode);
+	inode_set_ctime_current(&inode->vfs_inode);
 	inode_inc_iversion(&dir->vfs_inode);
  	inode_set_mtime_to_ts(&dir->vfs_inode, inode_set_ctime_current(&dir->vfs_inode));
 	ret = btrfs_update_inode(trans, dir);