*     @inode contains the inode structure.
  *     Deallocate the inode security structure and set @inode->i_security to
  *     NULL. 
+ * @inode_init_security:
+ *     Obtain the security attribute name suffix and value to set on a newly
+ *     created inode and set up the incore security field for the new inode.
+ *     This hook is called by the fs code as part of the inode creation
+ *     transaction and provides for atomic labeling of the inode, unlike
+ *     the post_create/mkdir/... hooks called by the VFS.  The hook function
+ *     is expected to allocate the name and value via kmalloc, with the caller
+ *     being responsible for calling kfree after using them.
+ *     If the security module does not use security attributes or does
+ *     not wish to put a security attribute on this particular inode,
+ *     then it should return -EOPNOTSUPP to skip this processing.
+ *     @inode contains the inode structure of the newly created inode.
+ *     @dir contains the inode structure of the parent directory.
+ *     @name will be set to the allocated name suffix (e.g. selinux).
+ *     @value will be set to the allocated attribute value.
+ *     @len will be set to the length of the value.
+ *     Returns 0 if @name and @value have been successfully set,
+ *             -EOPNOTSUPP if no security attribute is needed, or
+ *             -ENOMEM on memory allocation failure.
  * @inode_create:
  *     Check permission to create a regular file.
  *     @dir contains inode structure of the parent of the new file.
 
        int (*inode_alloc_security) (struct inode *inode);      
        void (*inode_free_security) (struct inode *inode);
+       int (*inode_init_security) (struct inode *inode, struct inode *dir,
+                                   char **name, void **value, size_t *len);
        int (*inode_create) (struct inode *dir,
                             struct dentry *dentry, int mode);
        void (*inode_post_create) (struct inode *dir,
                return;
        security_ops->inode_free_security (inode);
 }
+
+static inline int security_inode_init_security (struct inode *inode,
+                                               struct inode *dir,
+                                               char **name,
+                                               void **value,
+                                               size_t *len)
+{
+       if (unlikely (IS_PRIVATE (inode)))
+               return -EOPNOTSUPP;
+       return security_ops->inode_init_security (inode, dir, name, value, len);
+}
        
 static inline int security_inode_create (struct inode *dir,
                                         struct dentry *dentry,
 
 static inline void security_inode_free (struct inode *inode)
 { }
+
+static inline int security_inode_init_security (struct inode *inode,
+                                               struct inode *dir,
+                                               char **name,
+                                               void **value,
+                                               size_t *len)
+{
+       return -EOPNOTSUPP;
+}
        
 static inline int security_inode_create (struct inode *dir,
                                         struct dentry *dentry,
 
        return;
 }
 
+static int dummy_inode_init_security (struct inode *inode, struct inode *dir,
+                                     char **name, void **value, size_t *len)
+{
+       return -EOPNOTSUPP;
+}
+
 static int dummy_inode_create (struct inode *inode, struct dentry *dentry,
                               int mask)
 {
        set_to_dummy_if_null(ops, sb_post_pivotroot);
        set_to_dummy_if_null(ops, inode_alloc_security);
        set_to_dummy_if_null(ops, inode_free_security);
+       set_to_dummy_if_null(ops, inode_init_security);
        set_to_dummy_if_null(ops, inode_create);
        set_to_dummy_if_null(ops, inode_post_create);
        set_to_dummy_if_null(ops, inode_link);
 
        struct inode *inode;
        struct inode_security_struct *dsec;
        struct superblock_security_struct *sbsec;
+       struct inode_security_struct *isec;
        u32 newsid;
        char *context;
        unsigned int len;
                return 0;
        }
 
+       isec = inode->i_security;
+
+       if (isec->security_attr_init)
+               return 0;
+
        if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
                newsid = tsec->create_sid;
        } else {
        inode_free_security(inode);
 }
 
+static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
+                                      char **name, void **value,
+                                      size_t *len)
+{
+       struct task_security_struct *tsec;
+       struct inode_security_struct *dsec;
+       struct superblock_security_struct *sbsec;
+       struct inode_security_struct *isec;
+       u32 newsid;
+       int rc;
+       char *namep, *context;
+
+       tsec = current->security;
+       dsec = dir->i_security;
+       sbsec = dir->i_sb->s_security;
+       isec = inode->i_security;
+
+       if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
+               newsid = tsec->create_sid;
+       } else {
+               rc = security_transition_sid(tsec->sid, dsec->sid,
+                                            inode_mode_to_security_class(inode->i_mode),
+                                            &newsid);
+               if (rc) {
+                       printk(KERN_WARNING "%s:  "
+                              "security_transition_sid failed, rc=%d (dev=%s "
+                              "ino=%ld)\n",
+                              __FUNCTION__,
+                              -rc, inode->i_sb->s_id, inode->i_ino);
+                       return rc;
+               }
+       }
+
+       inode_security_set_sid(inode, newsid);
+
+       namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_KERNEL);
+       if (!namep)
+               return -ENOMEM;
+       *name = namep;
+
+       rc = security_sid_to_context(newsid, &context, len);
+       if (rc) {
+               kfree(namep);
+               return rc;
+       }
+       *value = context;
+
+       isec->security_attr_init = 1;
+
+       return 0;
+}
+
 static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int mask)
 {
        return may_create(dir, dentry, SECCLASS_FILE);
 
        .inode_alloc_security =         selinux_inode_alloc_security,
        .inode_free_security =          selinux_inode_free_security,
+       .inode_init_security =          selinux_inode_init_security,
        .inode_create =                 selinux_inode_create,
        .inode_post_create =            selinux_inode_post_create,
        .inode_link =                   selinux_inode_link,
 
        unsigned char initialized;     /* initialization flag */
        struct semaphore sem;
        unsigned char inherit;         /* inherit SID from parent entry */
+       unsigned char security_attr_init; /* security attributes init flag */
 };
 
 struct file_security_struct {