Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[cascardo/linux.git] / fs / overlayfs / dir.c
index 480fc78..306b6c1 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/cred.h>
 #include <linux/posix_acl.h>
 #include <linux/posix_acl_xattr.h>
+#include <linux/atomic.h>
 #include "overlayfs.h"
 
 void ovl_cleanup(struct inode *wdir, struct dentry *wdentry)
@@ -37,8 +38,10 @@ struct dentry *ovl_lookup_temp(struct dentry *workdir, struct dentry *dentry)
 {
        struct dentry *temp;
        char name[20];
+       static atomic_t temp_id = ATOMIC_INIT(0);
 
-       snprintf(name, sizeof(name), "#%lx", (unsigned long) dentry);
+       /* counter is allowed to wrap, since temp dentries are ephemeral */
+       snprintf(name, sizeof(name), "#%x", atomic_inc_return(&temp_id));
 
        temp = lookup_one_len(name, workdir, strlen(name));
        if (!IS_ERR(temp) && temp->d_inode) {
@@ -489,6 +492,15 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
        if (override_cred) {
                override_cred->fsuid = inode->i_uid;
                override_cred->fsgid = inode->i_gid;
+               if (!hardlink) {
+                       err = security_dentry_create_files_as(dentry,
+                                       stat->mode, &dentry->d_name, old_cred,
+                                       override_cred);
+                       if (err) {
+                               put_cred(override_cred);
+                               goto out_revert_creds;
+                       }
+               }
                put_cred(override_creds(override_cred));
                put_cred(override_cred);
 
@@ -499,6 +511,7 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
                        err = ovl_create_over_whiteout(dentry, inode, stat,
                                                        link, hardlink);
        }
+out_revert_creds:
        revert_creds(old_cred);
        if (!err) {
                struct inode *realinode = d_inode(ovl_dentry_upper(dentry));
@@ -1003,10 +1016,7 @@ const struct inode_operations ovl_dir_inode_operations = {
        .mknod          = ovl_mknod,
        .permission     = ovl_permission,
        .getattr        = ovl_dir_getattr,
-       .setxattr       = generic_setxattr,
-       .getxattr       = generic_getxattr,
        .listxattr      = ovl_listxattr,
-       .removexattr    = generic_removexattr,
        .get_acl        = ovl_get_acl,
        .update_time    = ovl_update_time,
 };