From: Olga Kornievskaia <kolga@xxxxxxxxxx> In 4.1+, the server is allowed to set a flag NFS4_RESULT_PRESERVE_UNLINKED in reply to the OPEN, that tells the client that it does not need to do a silly rename of an opened file when it's being removed. Signed-off-by: Olga Kornievskaia <kolga@xxxxxxxxxx> --- fs/nfs/dir.c | 6 ++++-- fs/nfs/nfs4proc.c | 2 ++ include/linux/nfs_fs.h | 1 + include/uapi/linux/nfs4.h | 1 + 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 00b222e48d6f..71f72e102b42 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -2319,8 +2319,10 @@ int nfs_unlink(struct inode *dir, struct dentry *dentry) spin_unlock(&dentry->d_lock); /* Start asynchronous writeout of the inode */ write_inode_now(d_inode(dentry), 0); - error = nfs_sillyrename(dir, dentry); - goto out; + if (!(NFS_I(d_inode(dentry))->flags & NFS_INO_PRESERVE_UNLINKED)) { + error = nfs_sillyrename(dir, dentry); + goto out; + } } if (!d_unhashed(dentry)) { __d_drop(dentry); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 2fbe04d12e44..1a9d25f23dcd 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2727,6 +2727,8 @@ static int _nfs4_proc_open(struct nfs4_opendata *data, nfs4_sequence_free_slot(&o_res->seq_res); nfs4_proc_getattr(server, &o_res->fh, o_res->f_attr, NULL); } + if (o_res->rflags & NFS4_OPEN_RESULT_PRESERVE_UNLINKED) + set_bit(NFS_INO_PRESERVE_UNLINKED, &NFS_I(dir)->flags); return 0; } diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 7a134e4c03e8..36fcd8d0487c 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -297,6 +297,7 @@ struct nfs4_copy_state { #define NFS_INO_LAYOUTCOMMITTING (10) /* layoutcommit inflight */ #define NFS_INO_LAYOUTSTATS (11) /* layoutstats inflight */ #define NFS_INO_ODIRECT (12) /* I/O setting is O_DIRECT */ +#define NFS_INO_PRESERVE_UNLINKED (13) /* preserve file if removed while open */ static inline struct nfs_inode *NFS_I(const struct inode *inode) { diff --git a/include/uapi/linux/nfs4.h b/include/uapi/linux/nfs4.h index 800bb0ffa6e6..14acfe5300b7 100644 --- a/include/uapi/linux/nfs4.h +++ b/include/uapi/linux/nfs4.h @@ -46,6 +46,7 @@ #define NFS4_OPEN_RESULT_CONFIRM 0x0002 #define NFS4_OPEN_RESULT_LOCKTYPE_POSIX 0x0004 #define NFS4_OPEN_RESULT_MAY_NOTIFY_LOCK 0x0020 +#define NFS4_OPEN_RESULT_PRESERVE_UNLINKED 0x0008 #define NFS4_SHARE_ACCESS_MASK 0x000F #define NFS4_SHARE_ACCESS_READ 0x0001 -- 2.27.0