int inode_setattr(struct inode * inode, struct iattr * attr)
 {
        unsigned int ia_valid = attr->ia_valid;
-       int error = 0;
-
-       if (ia_valid & ATTR_SIZE) {
-               if (attr->ia_size != i_size_read(inode)) {
-                       error = vmtruncate(inode, attr->ia_size);
-                       if (error || (ia_valid == ATTR_SIZE))
-                               goto out;
-               } else {
-                       /*
-                        * We skipped the truncate but must still update
-                        * timestamps
-                        */
-                       ia_valid |= ATTR_MTIME|ATTR_CTIME;
-               }
+
+       if (ia_valid & ATTR_SIZE &&
+           attr->ia_size != i_size_read(inode)) {
+               int error = vmtruncate(inode, attr->ia_size);
+               if (error)
+                       return error;
        }
 
        if (ia_valid & ATTR_UID)
                inode->i_mode = mode;
        }
        mark_inode_dirty(inode);
-out:
-       return error;
+
+       return 0;
 }
 EXPORT_SYMBOL(inode_setattr);
 
 
                goto close_fail;
        if (!file->f_op->write)
                goto close_fail;
-       if (do_truncate(file->f_dentry, 0, file) != 0)
+       if (do_truncate(file->f_dentry, 0, 0, file) != 0)
                goto close_fail;
 
        retval = binfmt->core_dump(signr, regs, file);
 
                if (!error) {
                        DQUOT_INIT(inode);
                        
-                       error = do_truncate(dentry, 0, NULL);
+                       error = do_truncate(dentry, 0, ATTR_MTIME|ATTR_CTIME, NULL);
                }
                put_write_access(inode);
                if (error)
 
        return error;
 }
 
-int do_truncate(struct dentry *dentry, loff_t length, struct file *filp)
+int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
+       struct file *filp)
 {
        int err;
        struct iattr newattrs;
                return -EINVAL;
 
        newattrs.ia_size = length;
-       newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
+       newattrs.ia_valid = ATTR_SIZE | time_attrs;
        if (filp) {
                newattrs.ia_file = filp;
                newattrs.ia_valid |= ATTR_FILE;
        error = locks_verify_truncate(inode, NULL, length);
        if (!error) {
                DQUOT_INIT(inode);
-               error = do_truncate(nd.dentry, length, NULL);
+               error = do_truncate(nd.dentry, length, 0, NULL);
        }
        put_write_access(inode);
 
 
        error = locks_verify_truncate(inode, file, length);
        if (!error)
-               error = do_truncate(dentry, length, file);
+               error = do_truncate(dentry, length, 0, file);
 out_putf:
        fput(file);
 out:
 
 
 /* fs/open.c */
 
-extern int do_truncate(struct dentry *, loff_t start, struct file *filp);
+extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
+                      struct file *filp);
 extern long do_sys_open(const char __user *filename, int flags, int mode);
 extern struct file *filp_open(const char *, int, int);
 extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);