[Unionfs] Reuse of deleted file names by another user
Erez Zadok
ezk at cs.sunysb.edu
Tue Oct 23 00:04:51 EDT 2007
In message <471D13B5.7090804 at hoelldampf.net>, Jens Hoelldampf writes:
> Erez Zadok wrote:
> > In message <47151670.2090407 at hoelldampf.net>, Jens Hoelldampf writes:
> >> Hi,
> >>
> >> when I delete a file on a unionfs-2.1.6 branch, it is not possible to
> >> create the file with another user afterwards:
> >>
> >> fagus ~ # touch /var/tmp/a
> >> fagus ~ # rm /var/tmp/a
> >> fagus ~ # su - jhl
> >> jhl at fagus ~ $ touch /var/tmp/a
> >> touch: setting times of `/var/tmp/a': No such file or directory
> >> jhl at fagus ~ $ ls -la /nfsro/unionfs_rw/var/tmp/
> >> total 0
> >> drwxrwxrwt 2 root root 60 2007-10-16 21:47 .
> >> drwxr-xr-x 10 root root 200 2007-10-16 21:42 ..
> >> -rwxr-xr-x 1 root root 0 2007-10-16 21:47 .wh.a
> >> jhl at fagus ~ $
> >>
> >> Regards,
> >> Jens
> >
> > Jens, I wasn't able to reproduce your setup with 2.6.23. Can you send me
> > more info: what kernel you're running, what's the branch configuration
> > (types etc.), any special lower-branch mount options you're using, etc. If
> > you're using NFS, what version, what export options, etc.
>
> Hi,
>
> sorry for the late reply. I also tested 2.1.7 - same problem.
> The details:
>
> * vanilla kernel 2.6.23.1, unionfs 2.1.7
>
> * relevant mounts:
> > rootfs / rootfs rw 0 0
> > 129.187.147.253:/ptg/rootfs/gentoo_x86_2007a_jhl / nfs ro,vers=3,rsize=4096,wsize=4096,hard,nolock,proto=udp,timeo=7,retrans=3,sec=sys,addr=129.187.147.253 0 0
> > tmpfs /nfsro/unionfs_rw tmpfs rw 0 0
> > none /var unionfs rw,dirs=/nfsro/unionfs_rw/var=rw:/var=ro 0 0
>
> * NFS server, /etc/exports
> > /ptg/rootfs 129.187.147.0/24(ro,mp=/ptg,async,no_root_squash,subtree_check)
>
> Regards,
> Jens
Jens, thanks. I was finally able to reproduce this: whiteout files couldn't
be removed from sticky directories if the whiteout was created by another
user. Can you try the following patch and let me know how it works.
Erez.
diff --git a/fs/unionfs/inode.c b/fs/unionfs/inode.c
index 6ca52f4..f4facf4 100644
--- a/fs/unionfs/inode.c
+++ b/fs/unionfs/inode.c
@@ -90,6 +90,23 @@ static int unionfs_create(struct inode *parent, struct dentry *dentry,
err = vfs_unlink(lower_dir_dentry->d_inode, wh_dentry);
unlock_dir(lower_dir_dentry);
+ /*
+ * Whiteouts are special files and should be deleted
+ * no matter what (as if they never existed), in
+ * order to allow this create operation to succeed.
+ * This is especially important in sticky
+ * directories: a whiteout may have been created by
+ * one user, but the newly created file may be
+ * created by another user. Therefore, in order to
+ * maintain Unix semantics, if the vfs_unlink above
+ * ailed, then we have to try to directly unlink the
+ * whiteout. Note: in the ODF version of unionfs,
+ * whiteout are handled much more cleanly.
+ */
+ if (err == -EPERM) {
+ struct inode *inode = lower_dir_dentry->d_inode;
+ err = inode->i_op->unlink(inode, wh_dentry);
+ }
if (err) {
printk(KERN_ERR "unionfs: create: could not "
"unlink whiteout, err = %d\n", err);
More information about the unionfs
mailing list