> There are some problems around permission bits of a dir.
> For example, unionfs cannot remove the un-writable dir while unix/posix
> can. And if a dir doen't have exec bit (rare case), unionfs cannot
> handle it correctly.
> This patch will solve those problems.

This is a patch for mkdir on same purpose.
And revised superio functions, I am afraid the last patch might stop the
scheduler.

Junjiro Okajima


--- unionfs-20060221-0341/inode.c       23 Feb 2006 00:47:37 -0000      1.1
+++ unionfs-20060221-0341/inode.c       23 Feb 2006 14:19:05 -0000      1.2
@@ -470,6 +470,40 @@ static int unionfs_symlink(struct inode 
        return err;
 }
 
+static int make_dir_opq(struct dentry *hidden_dentry)
+{
+       int err;
+       struct inode *hidden_inode;
+       struct dentry *opq_dentry;
+       int do_superio;
+       struct superio sio;
+       const mode_t wh_mode = S_IRUSR | S_IWUSR;
+
+       hidden_inode = hidden_dentry->d_inode;
+       mutex_lock(&hidden_inode->i_mutex);
+       do_superio = permission(hidden_inode, MAY_WRITE | MAY_EXEC, NULL);
+       if (do_superio)
+               superio_store(&sio);
+       opq_dentry = LOOKUP_ONE_LEN(UNIONFS_DIR_OPAQUE, hidden_dentry,
+                                   sizeof(UNIONFS_DIR_OPAQUE) - 1);
+       err = PTR_ERR(opq_dentry);
+       if (!IS_ERR(opq_dentry)) {
+               err = vfs_create(hidden_inode, opq_dentry, wh_mode, NULL);
+               DPUT(opq_dentry);
+       }
+       if (do_superio) {
+               if (!err) {
+                       struct iattr ia;
+                       ia.ia_valid = ATTR_UID;
+                       ia.ia_uid = sio.fsuid;
+                       err = notify_change(opq_dentry, &ia);
+               }
+               superio_revert(&sio);
+       }
+       mutex_unlock(&hidden_inode->i_mutex);
+       return err;
+}
+
 static int unionfs_mkdir(struct inode *parent, struct dentry *dentry, int mode)
 {
        int err = 0;
@@ -585,27 +619,14 @@ static int unionfs_mkdir(struct inode *p
                                /* update number of links on parent directory */
                                parent->i_nlink = get_nlinks(parent);
                        }
-                       whiteout_dentry = LOOKUP_ONE_LEN(UNIONFS_DIR_OPAQUE,
-                                                        hidden_dentry,
-                                                        sizeof
-                                                        (UNIONFS_DIR_OPAQUE) -
-                                                        1);
-                       if (IS_ERR(whiteout_dentry)) {
-                               err = PTR_ERR(whiteout_dentry);
-                               goto out;
-                       }
-                       mutex_lock(&hidden_dentry->d_inode->i_mutex);
-                       err = vfs_create(hidden_dentry->d_inode,
-                                        whiteout_dentry, 0600, NULL);
-                       mutex_unlock(&hidden_dentry->d_inode->i_mutex);
-                       DPUT(whiteout_dentry);
-
+                       err = make_dir_opq(hidden_dentry);
                        if (err) {
                                fist_dprint(8,
                                            "mkdir: error creating directory 
override entry: %d\n",
                                            err);
                                goto out;
                        }
+                       set_dbopaque(dentry, bindex);
                        break;
                }
        }

--- unionfs-20060221-0341/subr.c        23 Feb 2006 00:47:37 -0000      1.1
+++ unionfs-20060221-0341/subr.c        23 Feb 2006 14:19:05 -0000      1.2
@@ -284,7 +284,7 @@ void superio_store(struct superio *sio)
                     | CAP_TO_MASK(CAP_SETPCAP)
                     | CAP_TO_MASK(CAP_SETUID));
 
-       write_lock(&tasklist_lock);     /* task_capability_lock is not exported 
*/
+       //write_lock(&tasklist_lock);   /* task_capability_lock is not exported 
*/
        err = security_capget(current, &sio->cap.effective,
                              &sio->cap.inheritable, &sio->cap.permitted);
        if (err) {
@@ -298,7 +298,7 @@ void superio_store(struct superio *sio)
        super = cap_drop(super, drop);
        security_capset_set(current, &super, &sio->cap.inheritable,
                            &sio->cap.permitted);
-       write_unlock(&tasklist_lock);
+       //write_unlock(&tasklist_lock);
 
        rl = current->signal->rlim + RLIMIT_CORE;
        task_lock(current->group_leader);       //??
@@ -317,10 +317,10 @@ void superio_revert(struct superio *sio)
        current->signal->rlim[RLIMIT_CORE].rlim_cur = sio->rlim_core;
        task_unlock(current->group_leader);
 
-       write_lock(&tasklist_lock);     /* task_capability_lock is not exported 
*/
+       //write_lock(&tasklist_lock);   /* task_capability_lock is not exported 
*/
        security_capset_set(current, &sio->cap.effective,
                            &sio->cap.inheritable, &sio->cap.permitted);
-       write_unlock(&tasklist_lock);
+       //write_unlock(&tasklist_lock);
 }
 
 /*
_______________________________________________
unionfs mailing list
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs

Reply via email to