@@ -5914,6 +5914,28 @@ static void nfsd4_open_deleg_none_ext(struct nfsd4_open *open, int status)
5914
5914
}
5915
5915
}
5916
5916
5917
+ static bool
5918
+ nfs4_delegation_stat (struct nfs4_delegation * dp , struct svc_fh * currentfh ,
5919
+ struct kstat * stat )
5920
+ {
5921
+ struct nfsd_file * nf = find_rw_file (dp -> dl_stid .sc_file );
5922
+ struct path path ;
5923
+ int rc ;
5924
+
5925
+ if (!nf )
5926
+ return false;
5927
+
5928
+ path .mnt = currentfh -> fh_export -> ex_path .mnt ;
5929
+ path .dentry = file_dentry (nf -> nf_file );
5930
+
5931
+ rc = vfs_getattr (& path , stat ,
5932
+ (STATX_SIZE | STATX_CTIME | STATX_CHANGE_COOKIE ),
5933
+ AT_STATX_SYNC_AS_STAT );
5934
+
5935
+ nfsd_file_put (nf );
5936
+ return rc == 0 ;
5937
+ }
5938
+
5917
5939
/*
5918
5940
* The Linux NFS server does not offer write delegations to NFSv4.0
5919
5941
* clients in order to avoid conflicts between write delegations and
@@ -5949,7 +5971,6 @@ nfs4_open_delegation(struct nfsd4_open *open, struct nfs4_ol_stateid *stp,
5949
5971
int cb_up ;
5950
5972
int status = 0 ;
5951
5973
struct kstat stat ;
5952
- struct path path ;
5953
5974
5954
5975
cb_up = nfsd4_cb_channel_good (oo -> oo_owner .so_client );
5955
5976
open -> op_recall = false;
@@ -5985,20 +6006,16 @@ nfs4_open_delegation(struct nfsd4_open *open, struct nfs4_ol_stateid *stp,
5985
6006
memcpy (& open -> op_delegate_stateid , & dp -> dl_stid .sc_stateid , sizeof (dp -> dl_stid .sc_stateid ));
5986
6007
5987
6008
if (open -> op_share_access & NFS4_SHARE_ACCESS_WRITE ) {
5988
- open -> op_delegate_type = NFS4_OPEN_DELEGATE_WRITE ;
5989
- trace_nfsd_deleg_write (& dp -> dl_stid .sc_stateid );
5990
- path .mnt = currentfh -> fh_export -> ex_path .mnt ;
5991
- path .dentry = currentfh -> fh_dentry ;
5992
- if (vfs_getattr (& path , & stat ,
5993
- (STATX_SIZE | STATX_CTIME | STATX_CHANGE_COOKIE ),
5994
- AT_STATX_SYNC_AS_STAT )) {
6009
+ if (!nfs4_delegation_stat (dp , currentfh , & stat )) {
5995
6010
nfs4_put_stid (& dp -> dl_stid );
5996
6011
destroy_delegation (dp );
5997
6012
goto out_no_deleg ;
5998
6013
}
6014
+ open -> op_delegate_type = NFS4_OPEN_DELEGATE_WRITE ;
5999
6015
dp -> dl_cb_fattr .ncf_cur_fsize = stat .size ;
6000
6016
dp -> dl_cb_fattr .ncf_initial_cinfo =
6001
6017
nfsd4_change_attribute (& stat , d_inode (currentfh -> fh_dentry ));
6018
+ trace_nfsd_deleg_write (& dp -> dl_stid .sc_stateid );
6002
6019
} else {
6003
6020
open -> op_delegate_type = NFS4_OPEN_DELEGATE_READ ;
6004
6021
trace_nfsd_deleg_read (& dp -> dl_stid .sc_stateid );
0 commit comments