Re: [PATCH 03/79] ovl: rearrange ovl_follow_link to it doesn't need to call ->put_link

From: NeilBrown
Date: Tue May 05 2015 - 04:34:27 EST


On Tue, 05 May 2015 15:12:28 +0800 "Hillf Danton" <hillf.zj@xxxxxxxxxxxxxxx>
wrote:

> >
> > From: NeilBrown <neilb@xxxxxxx>
> >
> > ovl_follow_link current calls ->put_link on an error path.
> > However ->put_link is about to change in a way that it will be
> > impossible to call it from ovl_follow_link.
> >
> > So rearrange the code to avoid the need for that error path.
> > Specifically: move the kmalloc() call before the ->follow_link()
> > call to the subordinate filesystem.
> >
> > Signed-off-by: NeilBrown <neilb@xxxxxxx>
> > Signed-off-by: Al Viro <viro@xxxxxxxxxxxxxxxxxx>
> > ---
> > fs/overlayfs/inode.c | 25 ++++++++++++-------------
> > 1 file changed, 12 insertions(+), 13 deletions(-)
> >
> > diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
> > index 04f1248..1b4b9c5e 100644
> > --- a/fs/overlayfs/inode.c
> > +++ b/fs/overlayfs/inode.c
> > @@ -145,6 +145,7 @@ static void *ovl_follow_link(struct dentry *dentry, struct nameidata *nd)
> > void *ret;
> > struct dentry *realdentry;
> > struct inode *realinode;
> > + struct ovl_link_data *data = NULL;
> >
> > realdentry = ovl_dentry_real(dentry);
> > realinode = realdentry->d_inode;
> > @@ -152,25 +153,23 @@ static void *ovl_follow_link(struct dentry *dentry, struct nameidata *nd)
> > if (WARN_ON(!realinode->i_op->follow_link))
> > return ERR_PTR(-EPERM);
> >
> > - ret = realinode->i_op->follow_link(realdentry, nd);
> > - if (IS_ERR(ret))
> > - return ret;
> > -
> > if (realinode->i_op->put_link) {
> > - struct ovl_link_data *data;
> > -
> > data = kmalloc(sizeof(struct ovl_link_data), GFP_KERNEL);
> > - if (!data) {
> > - realinode->i_op->put_link(realdentry, nd, ret);
> > + if (!data)
> > return ERR_PTR(-ENOMEM);
> > - }
> > data->realdentry = realdentry;
> > - data->cookie = ret;
> > + }
> >
> > - return data;
> > - } else {
> > - return NULL;
> > + ret = realinode->i_op->follow_link(realdentry, nd);
> > + if (IS_ERR(ret)) {
> > + kfree(data);
> > + return ret;
> > }
> > +
> > + if (data)
>
> No need to check again(see the above kfree(data) please).

kfree(NULL) is perfectly valid.

NeilBrown


>
> > + data->cookie = ret;
> > +
> > + return data;
> > }
> >
> > static void ovl_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
> > --
> > 2.1.4

Attachment: pgp8t1Cw0uf0V.pgp
Description: OpenPGP digital signature