diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c
index dbf95a8094db3d05c4c663676008ba9c248378c5..85b8d06bd72aad34bc518f03cbf8b5db35a452bf 100644
--- a/lustre/llite/llite_lib.c
+++ b/lustre/llite/llite_lib.c
@@ -1638,6 +1638,16 @@ int ll_setattr(struct dentry *de, struct iattr *attr)
             (ATTR_CTIME|ATTR_SIZE|ATTR_MODE))
                 attr->ia_valid |= MDS_OPEN_OWNEROVERRIDE;
 
+        if ((de->d_inode->i_mode & S_ISUID) &&
+            !(attr->ia_mode & S_ISUID) &&
+            !(attr->ia_valid & ATTR_KILL_SUID))
+                attr->ia_valid |= ATTR_KILL_SUID;
+
+        if (((de->d_inode->i_mode & (S_ISGID|S_IXGRP)) == (S_ISGID|S_IXGRP)) &&
+            !(attr->ia_mode & S_ISGID) &&
+            !(attr->ia_valid & ATTR_KILL_SGID))
+                attr->ia_valid |= ATTR_KILL_SGID;
+
         return ll_setattr_raw(de->d_inode, attr);
 }
 
diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c
index 74b628b21fd0b1503db0d18f8a17a9d034d1a9a0..39d3814ab6609642f50a91f248aa316d35c8fb1b 100644
--- a/lustre/mdd/mdd_object.c
+++ b/lustre/mdd/mdd_object.c
@@ -735,6 +735,7 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj,
                 /* Bypass la_vaild == LA_MODE,
                  * this is for changing file with SUID or SGID. */
                 if ((la->la_valid & ~LA_MODE) &&
+                    !(ma->ma_attr_flags & MDS_PERM_BYPASS) &&
                     (uc->mu_fsuid != tmp_la->la_uid) &&
                     !mdd_capable(uc, CAP_FOWNER))
                         RETURN(-EPERM);
diff --git a/lustre/mdt/mdt_lib.c b/lustre/mdt/mdt_lib.c
index ec1463dd73821ded3458ae81b7b71c6159beeab2..5fffcf2052c160631298161cabb0b348d6aedfa4 100644
--- a/lustre/mdt/mdt_lib.c
+++ b/lustre/mdt/mdt_lib.c
@@ -683,6 +683,9 @@ static __u64 mdt_attr_valid_xlate(__u64 in, struct mdt_reint_record *rr,
         if (in & MDS_OPEN_OWNEROVERRIDE)
                 ma->ma_attr_flags |= MDS_OPEN_OWNEROVERRIDE;
 
+        if (in & (ATTR_KILL_SUID|ATTR_KILL_SGID))
+                ma->ma_attr_flags |= MDS_PERM_BYPASS;
+
         /*XXX need ATTR_RAW?*/
         in &= ~(ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_BLOCKS|
                 ATTR_ATIME|ATTR_MTIME|ATTR_CTIME|ATTR_FROM_OPEN|