Re: [RFC PATCH v2 1/2] fs: add AT_REPLACE flag for linkat() which replaces the target
From: Linus Torvalds <torvalds@linux-foundation.org>
Date: 2017-03-21 16:30:32
Also in:
linux-fsdevel
On Tue, Mar 21, 2017 at 7:51 AM, Omar Sandoval [off-list ref] wrote:
*/
-int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry, struct inode **delegated_inode)
+int vfs_link(struct dentry *old_dentry, struct inode *dir,
+ struct dentry *new_dentry, struct inode **delegated_inode,
+ unsigned int flags)
{
struct inode *inode = old_dentry->d_inode;
+ struct inode *target = new_dentry->d_inode;
unsigned max_links = dir->i_sb->s_max_links;
int error;
if (!inode)
return -ENOENT;
- error = may_create(dir, new_dentry);
+ if (target) {
+ if (flags & AT_REPLACE)
+ error = may_delete(dir, new_dentry, d_is_dir(old_dentry));
+ else
+ error = -EEXIST;
+ } else {
+ error = may_create(dir, new_dentry);
+ }
This looks bogus.
In particular, that "may_delete()" cannot be right. It should still
*also* have the right to create something in that directory.
But even if you replace it with checks for both deletion _and_
creation, it won't be right, since the test for d_is_negative() on the
target in may_delete() looks wrong for this situation.
Normally, you cannot delete a negative entry (think of what that would
do in a overlay situation), but it should still be ok to link a
positive entry on top of a negative one.
Also, I think the above is incorrect for yet another case: moving
somethign on top of a directory should be disallowed. We do later on
check that the *source* isn't a directory (since you can't link
directories), but I'm not seeing where you'd be checking that you
don't move over a directory either.
So I don't think this patch is acceptable as such. I also suspect that
it should be done in multiple phases.
Linus