> 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