@@ -848,42 +848,67 @@ static const struct afs_operation_ops afs_setattr_operation = {
848
848
int afs_setattr (struct user_namespace * mnt_userns , struct dentry * dentry ,
849
849
struct iattr * attr )
850
850
{
851
+ const unsigned int supported =
852
+ ATTR_SIZE | ATTR_MODE | ATTR_UID | ATTR_GID |
853
+ ATTR_MTIME | ATTR_MTIME_SET | ATTR_TIMES_SET | ATTR_TOUCH ;
851
854
struct afs_operation * op ;
852
855
struct afs_vnode * vnode = AFS_FS_I (d_inode (dentry ));
856
+ struct inode * inode = & vnode -> vfs_inode ;
857
+ loff_t i_size ;
853
858
int ret ;
854
859
855
860
_enter ("{%llx:%llu},{n=%pd},%x" ,
856
861
vnode -> fid .vid , vnode -> fid .vnode , dentry ,
857
862
attr -> ia_valid );
858
863
859
- if (!(attr -> ia_valid & (ATTR_SIZE | ATTR_MODE | ATTR_UID | ATTR_GID |
860
- ATTR_MTIME | ATTR_MTIME_SET | ATTR_TIMES_SET |
861
- ATTR_TOUCH ))) {
864
+ if (!(attr -> ia_valid & supported )) {
862
865
_leave (" = 0 [unsupported]" );
863
866
return 0 ;
864
867
}
865
868
869
+ i_size = i_size_read (inode );
866
870
if (attr -> ia_valid & ATTR_SIZE ) {
867
- if (!S_ISREG (vnode -> vfs_inode . i_mode ))
871
+ if (!S_ISREG (inode -> i_mode ))
868
872
return - EISDIR ;
869
873
870
- ret = inode_newsize_ok (& vnode -> vfs_inode , attr -> ia_size );
874
+ ret = inode_newsize_ok (inode , attr -> ia_size );
871
875
if (ret )
872
876
return ret ;
873
877
874
- if (attr -> ia_size == i_size_read ( & vnode -> vfs_inode ) )
878
+ if (attr -> ia_size == i_size )
875
879
attr -> ia_valid &= ~ATTR_SIZE ;
876
880
}
877
881
878
882
fscache_use_cookie (afs_vnode_cache (vnode ), true);
879
883
880
- /* flush any dirty data outstanding on a regular file */
881
- if (S_ISREG (vnode -> vfs_inode .i_mode ))
882
- filemap_write_and_wait (vnode -> vfs_inode .i_mapping );
883
-
884
884
/* Prevent any new writebacks from starting whilst we do this. */
885
885
down_write (& vnode -> validate_lock );
886
886
887
+ if ((attr -> ia_valid & ATTR_SIZE ) && S_ISREG (inode -> i_mode )) {
888
+ loff_t size = attr -> ia_size ;
889
+
890
+ /* Wait for any outstanding writes to the server to complete */
891
+ loff_t from = min (size , i_size );
892
+ loff_t to = max (size , i_size );
893
+ ret = filemap_fdatawait_range (inode -> i_mapping , from , to );
894
+ if (ret < 0 )
895
+ goto out_unlock ;
896
+
897
+ /* Don't talk to the server if we're just shortening in-memory
898
+ * writes that haven't gone to the server yet.
899
+ */
900
+ if (!(attr -> ia_valid & (supported & ~ATTR_SIZE & ~ATTR_MTIME )) &&
901
+ attr -> ia_size < i_size &&
902
+ attr -> ia_size > vnode -> status .size ) {
903
+ truncate_pagecache (inode , attr -> ia_size );
904
+ fscache_resize_cookie (afs_vnode_cache (vnode ),
905
+ attr -> ia_size );
906
+ i_size_write (inode , attr -> ia_size );
907
+ ret = 0 ;
908
+ goto out_unlock ;
909
+ }
910
+ }
911
+
887
912
op = afs_alloc_operation (((attr -> ia_valid & ATTR_FILE ) ?
888
913
afs_file_key (attr -> ia_file ) : NULL ),
889
914
vnode -> volume );
0 commit comments