[PATCH 2/4][DISCO] shiftfs: rework and extend

Seth Forshee seth.forshee at canonical.com
Thu Apr 4 12:39:44 UTC 2019


On Wed, Apr 03, 2019 at 10:15:13PM -0500, Tyler Hicks wrote:

<snip>

> > +static int shiftfs_real_fdget(const struct file *file, struct fd *lowerfd)
> > +{
> > +	struct shiftfs_file_info *file_info = file->private_data;
> > +	struct file *realfile = file_info->realfile;
> > +
> > +	lowerfd->flags = 0;
> > +	lowerfd->file = realfile;
> > +
> > +	/* Did the flags change since open? */
> > +	if (unlikely(file->f_flags & lowerfd->file->f_flags))
> 
> Is this the right bitwise operation? Maybe I'm misunderstanding the
> intent but I'd have thought you would want to XOR the two f_flags to
> detect any changes.

You are right, that looks like a typo.

> 
> > +		return shiftfs_change_flags(lowerfd->file, file->f_flags);
> > +
> > +	return 0;
> > +}
> > +
> > +static int shiftfs_open(struct inode *inode, struct file *file)
> > +{
> > +	struct shiftfs_super_info *ssi = inode->i_sb->s_fs_info;
> > +	struct shiftfs_file_info *file_info;
> > +	struct file *realfile;
> > +	struct path *realpath;
> > +
> > +	file_info = kmem_cache_zalloc(shiftfs_file_info_cache, GFP_KERNEL);
> > +	if (!file_info)
> > +		return -ENOMEM;
> > +	file->private_data = file_info;
> > +
> > +	realpath = &file_info->realpath;
> > +	realpath->mnt = ssi->mnt;
> > +	realpath->dentry = file->f_path.dentry->d_fsdata;
> > +
> > +	realfile = shiftfs_open_realfile(file, realpath);
> > +	if (IS_ERR(realfile)) {
> > +		kfree(file_info);
> 
> This should be a call to kmem_cache_free() instead of kfree().
> 
> Also, I think you'll want to set file->private_data to NULL in this
> error path so that we don't try to re-free it shiftfs_release().

Good catch.

> 
> > +		return PTR_ERR(realfile);
> > +	}
> > +
> > +	file_info->realfile = realfile;
> > +	return 0;
> > +}
> > +
> > +static int shiftfs_release(struct inode *inode, struct file *file)
> > +{
> > +	struct shiftfs_file_info *file_info = file->private_data;
> > +
> > +	fput(file_info->realfile);
> 
> As alluded to above, I think shiftfs_release() can be reached when
> shiftfs_open() fails. Check dentry_open() for such a sequence. In that
> case, you'll only want to call fput() when file_info and
> file_info->realfile are both non-NULL.
> 
> > +	kmem_cache_free(shiftfs_file_info_cache, file_info);
> 
> May as well only do this when file_info is non-NULL, too.

Agree with both points.

Thanks,
Seth



More information about the kernel-team mailing list