@@ -721,36 +721,33 @@ upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat,
721721}
722722
723723/**
724- * truncate_upper
724+ * __ecryptfs_truncate
725725 * @dentry: The ecryptfs layer dentry
726726 * @ia: Address of the ecryptfs inode's attributes
727- * @lower_ia: Address of the lower inode's attributes
728727 *
729- * Function to handle truncations modifying the size of the file. Note
730- * that the file sizes are interpolated. When expanding, we are simply
731- * writing strings of 0's out. When truncating, we truncate the upper
732- * inode and update the lower_ia according to the page index
733- * interpolations. If ATTR_SIZE is set in lower_ia->ia_valid upon return,
734- * the caller must use lower_ia in a call to notify_change() to perform
735- * the truncation of the lower inode.
728+ * Handle truncations modifying the size of the file. Note that the file sizes
729+ * are interpolated. When expanding, we are simply writing strings of 0's out.
730+ * When truncating, we truncate the upper inode and update the lower_ia
731+ * according to the page index interpolations.
736732 *
737733 * Returns zero on success; non-zero otherwise
738734 */
739- static int truncate_upper (struct dentry * dentry , struct iattr * ia ,
740- struct iattr * lower_ia )
735+ static int __ecryptfs_truncate (struct dentry * dentry , const struct iattr * ia )
741736{
737+ struct dentry * lower_dentry = ecryptfs_dentry_to_lower (dentry );
742738 struct inode * inode = d_inode (dentry );
743739 struct ecryptfs_crypt_stat * crypt_stat ;
744740 loff_t i_size = i_size_read (inode );
745741 loff_t lower_size_before_truncate ;
746742 loff_t lower_size_after_truncate ;
743+ struct iattr lower_ia ;
747744 size_t num_zeros ;
748745 int rc ;
749746
750- if (unlikely ((ia -> ia_size == i_size ))) {
751- lower_ia -> ia_valid &= ~ATTR_SIZE ;
747+ ecryptfs_iattr_to_lower (& lower_ia , ia );
748+
749+ if (unlikely ((ia -> ia_size == i_size )))
752750 return 0 ;
753- }
754751
755752 crypt_stat = & ecryptfs_inode_to_private (inode )-> crypt_stat ;
756753 lower_size_before_truncate =
@@ -783,15 +780,13 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
783780 * new end of the file.
784781 */
785782 rc = ecryptfs_write (inode , zero , ia -> ia_size - 1 , 1 );
786- lower_ia -> ia_valid &= ~ATTR_SIZE ;
787783 goto out ;
788784 }
789785
790786 if (!(crypt_stat -> flags & ECRYPTFS_ENCRYPTED )) {
791787 truncate_setsize (inode , ia -> ia_size );
792- lower_ia -> ia_size = ia -> ia_size ;
793- lower_ia -> ia_valid |= ATTR_SIZE ;
794- goto out ;
788+ lower_ia .ia_size = ia -> ia_size ;
789+ goto set_size ;
795790 }
796791
797792 /*
@@ -821,12 +816,15 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
821816 * We are reducing the size of the ecryptfs file, and need to know if we
822817 * need to reduce the size of the lower file.
823818 */
824- if (lower_size_after_truncate < lower_size_before_truncate ) {
825- lower_ia -> ia_size = lower_size_after_truncate ;
826- lower_ia -> ia_valid |= ATTR_SIZE ;
827- } else {
828- lower_ia -> ia_valid &= ~ATTR_SIZE ;
829- }
819+ if (lower_size_after_truncate >= lower_size_before_truncate )
820+ goto out ;
821+
822+ lower_ia .ia_size = lower_size_after_truncate ;
823+ set_size :
824+ lower_ia .ia_valid |= ATTR_SIZE ;
825+ inode_lock (d_inode (lower_dentry ));
826+ rc = notify_change (& nop_mnt_idmap , lower_dentry , & lower_ia , NULL );
827+ inode_unlock (d_inode (lower_dentry ));
830828out :
831829 ecryptfs_put_lower_file (inode );
832830 return rc ;
@@ -844,20 +842,12 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
844842 */
845843int ecryptfs_truncate (struct dentry * dentry , loff_t new_length )
846844{
847- struct iattr ia = { .ia_valid = ATTR_SIZE , .ia_size = new_length };
848- struct iattr lower_ia = { .ia_valid = 0 };
849- int rc ;
850-
851- rc = truncate_upper (dentry , & ia , & lower_ia );
852- if (!rc && lower_ia .ia_valid & ATTR_SIZE ) {
853- struct dentry * lower_dentry = ecryptfs_dentry_to_lower (dentry );
845+ const struct iattr ia = {
846+ .ia_valid = ATTR_SIZE ,
847+ .ia_size = new_length ,
848+ };
854849
855- inode_lock (d_inode (lower_dentry ));
856- rc = notify_change (& nop_mnt_idmap , lower_dentry ,
857- & lower_ia , NULL );
858- inode_unlock (d_inode (lower_dentry ));
859- }
860- return rc ;
850+ return __ecryptfs_truncate (dentry , & ia );
861851}
862852
863853static int
@@ -887,7 +877,6 @@ static int ecryptfs_setattr(struct mnt_idmap *idmap,
887877 struct inode * inode = d_inode (dentry );
888878 struct dentry * lower_dentry = ecryptfs_dentry_to_lower (dentry );
889879 struct inode * lower_inode = ecryptfs_inode_to_lower (inode );
890- struct iattr lower_ia ;
891880 struct ecryptfs_crypt_stat * crypt_stat ;
892881 int rc ;
893882
@@ -935,17 +924,18 @@ static int ecryptfs_setattr(struct mnt_idmap *idmap,
935924 if (rc )
936925 goto out ;
937926
938- ecryptfs_iattr_to_lower (& lower_ia , ia );
939927 if (ia -> ia_valid & ATTR_SIZE ) {
940- rc = truncate_upper (dentry , ia , & lower_ia );
941- if (rc < 0 )
942- goto out ;
943- }
928+ rc = __ecryptfs_truncate (dentry , ia );
929+ } else {
930+ struct iattr lower_ia ;
944931
932+ ecryptfs_iattr_to_lower (& lower_ia , ia );
945933
946- inode_lock (d_inode (lower_dentry ));
947- rc = notify_change (& nop_mnt_idmap , lower_dentry , & lower_ia , NULL );
948- inode_unlock (d_inode (lower_dentry ));
934+ inode_lock (d_inode (lower_dentry ));
935+ rc = notify_change (& nop_mnt_idmap , lower_dentry , & lower_ia ,
936+ NULL );
937+ inode_unlock (d_inode (lower_dentry ));
938+ }
949939out :
950940 fsstack_copy_attr_all (inode , lower_inode );
951941 return rc ;
0 commit comments