diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c
index 80e472da0483cd0b5dbda946045d76b8485b73ac..65fe307c9239b01b74a628a2dda360308578cb40 100644
--- a/lustre/llite/llite_lib.c
+++ b/lustre/llite/llite_lib.c
@@ -1532,9 +1532,19 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr)
 
 int ll_setattr(struct dentry *de, struct iattr *attr)
 {
+        int mode;
+
         if ((attr->ia_valid & (ATTR_CTIME|ATTR_SIZE|ATTR_MODE)) ==
             (ATTR_CTIME|ATTR_SIZE|ATTR_MODE))
                 attr->ia_valid |= MDS_OPEN_OWNEROVERRIDE;
+        if ((attr->ia_valid & (ATTR_MODE|ATTR_FORCE|ATTR_SIZE)) == 
+            (ATTR_SIZE|ATTR_MODE)) {
+                mode = de->d_inode->i_mode;
+                if (((mode & S_ISUID) && (!(attr->ia_mode & S_ISUID))) ||
+                    ((mode & S_ISGID) && (mode & S_IXGRP) &&
+                    (!(attr->ia_mode & S_ISGID))))
+                        attr->ia_valid |= ATTR_FORCE;
+        }
 
         return ll_setattr_raw(de->d_inode, attr);
 }