On Tue, 05 May 2015 15:12:28 +0800 "Hillf Danton" wrote: > > > > From: NeilBrown > > > > 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 > > Signed-off-by: Al Viro > > --- > > 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