diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c
index 1a82ddf4a15c495c451f4ef7424d6cd9d46cd734..76104a93ccd8c6e9de8daf595cf21c48858c0d67 100644
--- a/lustre/llite/llite_lib.c
+++ b/lustre/llite/llite_lib.c
@@ -1529,9 +1529,19 @@ out:
 
 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);
 }