On Aug 16, 2017, at 9:41 AM, Jan Kara <jack@xxxxxxx> wrote: > > Push down acquisition of dqio_sem into ->read_file_info() callback. This > is for consistency with other operations and it also allows us to get > rid of an ugliness in OCFS2. Always nice to get rid of workarounds like this (which I admit I've had to do similar things in the past as well). Reviewed-by: Andreas Dilger <adilger@xxxxxxxxx> One minor cleanup suggestion below, but probably for a later patch. > Signed-off-by: Jan Kara <jack@xxxxxxx> > > diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c > index 5e47012d2f57..373d7cfea5b0 100644 > --- a/fs/quota/quota_v2.c > +++ b/fs/quota/quota_v2.c > @@ -90,29 +90,38 @@ static int v2_read_file_info(struct super_block *sb, int type) > { > struct v2_disk_dqinfo dinfo; > struct v2_disk_dqheader dqhead; > - struct mem_dqinfo *info = sb_dqinfo(sb, type); > + struct quota_info *dqopt = sb_dqopt(sb); > + struct mem_dqinfo *info = &dqopt->info[type]; > struct qtree_mem_dqinfo *qinfo; > ssize_t size; > unsigned int version; > + int ret; > > - if (!v2_read_header(sb, type, &dqhead)) > - return -1; > + down_read(&dqopt->dqio_sem); > + if (!v2_read_header(sb, type, &dqhead)) { > + ret = -1; This is a bit strange to return -1 here, but -ENOMEM below. The various ->quota_read() methods return -EIO or other proper error codes, so it makes sense to return those back from v2_read_header() and onward here. > + goto out; > + } > version = le32_to_cpu(dqhead.dqh_version); > if ((info->dqi_fmt_id == QFMT_VFS_V0 && version != 0) || > - (info->dqi_fmt_id == QFMT_VFS_V1 && version != 1)) > - return -1; > + (info->dqi_fmt_id == QFMT_VFS_V1 && version != 1)) { > + ret = -1; This could be -EINVAL or -EIO or similar. > + goto out; > + } > > size = sb->s_op->quota_read(sb, type, (char *)&dinfo, > sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF); > if (size != sizeof(struct v2_disk_dqinfo)) { > quota_error(sb, "Can't read info structure"); > - return -1; > + ret = -1; > + goto out; ->quota_read() is returning a proper error code, except in the case of short reads, which could be converted to -EIO or similar. > } > info->dqi_priv = kmalloc(sizeof(struct qtree_mem_dqinfo), GFP_NOFS); > if (!info->dqi_priv) { > printk(KERN_WARNING > "Not enough memory for quota information structure.\n"); > - return -ENOMEM; > + ret = -ENOMEM; > + goto out; > } > qinfo = info->dqi_priv; > if (version == 0) { > @@ -147,7 +156,10 @@ static int v2_read_file_info(struct super_block *sb, int type) > qinfo->dqi_entry_size = sizeof(struct v2r1_disk_dqblk); > qinfo->dqi_ops = &v2r1_qtree_ops; > } > - return 0; > + ret = 0; > +out: > + up_read(&dqopt->dqio_sem); > + return ret; > } > > /* Write information header to quota file */ > -- > 2.12.3 > Cheers, Andreas
Attachment:
signature.asc
Description: Message signed with OpenPGP