On Tue, May 10, 2016 at 04:36:56PM -0700, James Bottomley wrote: > +static int shiftfs_rename2(struct inode *olddir, struct dentry *old, > + struct inode *newdir, struct dentry *new, > + unsigned int flags) > +{ > + struct dentry *rodd = olddir->i_private, *rndd = newdir->i_private, > + *realold = old->d_inode->i_private, > + *realnew = new->d_inode->i_private; > + struct inode *realolddir = rodd->d_inode, *realnewdir = rndd->d_inode; > + const struct inode_operations *iop = realolddir->i_op; > + int err; > + const struct cred *oldcred, *newcred; > + > + oldcred = shiftfs_new_creds(&newcred, old->d_sb); > + err = iop->rename2(realolddir, realold, realnewdir, realnew, flags); > + shiftfs_old_creds(oldcred, &newcred); ... and you've just violated all locking rules for ->rename2(). > +static struct dentry *shiftfs_lookup(struct inode *dir, struct dentry *dentry, > + unsigned int flags) > +{ > + struct dentry *real = dir->i_private, *new; > + struct inode *reali = real->d_inode, *newi; > + const struct cred *oldcred, *newcred; > + > + /* note: violation of usual fs rules here: dentries are never > + * added with d_add. This is because we want no dentry cache > + * for shiftfs. All lookups proceed through the dentry cache > + * of the underlying filesystem, meaning we always see any > + * changes in the underlying */ Bloody wonderful. So * we lose caching the negative lookups * we've got buggered hardlinks (different inodes for those) * it has never, ever been tried on -next (would do rather nasty things on that d_instantiate()) > + > + kfree(sfc); > + > + return err; > +} > + file->f_op = &sfc->fop; Lovely - now try that with underlying fs something built modular. Or try to use it on top of something with non-trivial dentry_operations (hell, on top of itself, for starters). -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html