[PATCH V2 2/2] erofs: refactor read_inode calling convention

Yiyang Wu toolmanp at tlmp.cc
Mon Sep 2 17:57:17 AEST 2024


On Mon, Sep 02, 2024 at 03:18:54PM GMT, Gao Xiang wrote:
> 
> 
> > +	m_pofs += vi->xattr_isize;
> > +	/* inline symlink data shouldn't cross block boundary */
> > +	if (m_pofs + inode->i_size > bsz) {
> > +		erofs_err(inode->i_sb,
> > +			  "inline data cross block boundary @ nid %llu",
> > +			  vi->nid);
> 
> Since you move the code block of erofs_fill_symlink,
> 
> I think it'd be better to update this statement to
> 		erofs_err(inode->i_sb, "inline data cross block boundary @ nid %llu",
> 			  vi->nid);
> 
> As I mentioned, the print message doesn't have line limitation.

I just simply cannot tell the difference here. But since you put it
here, I will change this in the next version.

> > +		DBG_BUGON(1);
> > +		return -EFSCORRUPTED;
> > +	}
> > +
> > +	lnk = kmemdup_nul(kaddr + m_pofs, inode->i_size, GFP_KERNEL);
> > +
> > +	if (!lnk)
> > +		return -ENOMEM;
> 
> As I mentioned in the previous patch, so it could become
> 	inode->i_link = kmemdup_nul(kaddr + m_pofs, inode->i_size, GFP_KERNEL);
> 	return inode->i_link ? 0 : -ENOMEM;
> 

Looks good to me.

> > +		if(S_ISLNK(inode->i_mode)) {
> > +			err = erofs_fill_symlink(inode, kaddr, ofs);
> > +			if(err)
> 
> missing a blank:
> 			if (err)
> 
> 

Fixed here.
> > +				goto err_out;
> > +		}
> >   		vi->raw_blkaddr = le32_to_cpu(iu.raw_blkaddr);
> >   		break;
> >   	case S_IFCHR:
> > @@ -165,63 +202,29 @@ static void *erofs_read_inode(struct erofs_buf *buf,
> >   		inode->i_blocks = round_up(inode->i_size, sb->s_blocksize) >> 9;
> >   	else
> >   		inode->i_blocks = nblks << (sb->s_blocksize_bits - 9);
> > -	return kaddr;
> > +
> > +	erofs_put_metabuf(&buf);
> > +	return 0;
> >   err_out:
> 
> I wonder this can be unified too as:
> 
> err_out:
> 	DBG_BUGON(err);
> 	kfree(copied);			I'm not sure if it's really needed now.
I agree. copied doesn't need to be freed anymore as it's already freed when error happens in the first switch block of inode format part. 
Will be fixed in the next version.
> 	erofs_put_metabuf(&buf);
> 	return err;
> 
> >   	DBG_BUGON(1);
> >   	kfree(copied);
> > -	erofs_put_metabuf(buf);
> > -	return ERR_PTR(err);
> > +	erofs_put_metabuf(&buf);
> > +	return err;
> >   }
> > -static int erofs_fill_symlink(struct inode *inode, void *kaddr,
> > -			      unsigned int m_pofs)
> > -{
> > -	struct erofs_inode *vi = EROFS_I(inode);
> > -	unsigned int bsz = i_blocksize(inode);
> > -	char *lnk;
> > -
> > -	/* if it cannot be handled with fast symlink scheme */
> > -	if (vi->datalayout != EROFS_INODE_FLAT_INLINE ||
> > -	    inode->i_size >= bsz || inode->i_size < 0) {
> > -		inode->i_op = &erofs_symlink_iops;
> > -		return 0;
> > -	}
> > -
> > -	m_pofs += vi->xattr_isize;
> > -	/* inline symlink data shouldn't cross block boundary */
> > -	if (m_pofs + inode->i_size > bsz) {
> > -		erofs_err(inode->i_sb,
> > -			  "inline data cross block boundary @ nid %llu",
> > -			  vi->nid);
> > -		DBG_BUGON(1);
> > -		return -EFSCORRUPTED;
> > -	}
> > -
> > -	lnk = kmemdup_nul(kaddr + m_pofs, inode->i_size, GFP_KERNEL);
> > -
> > -	if (!lnk)
> > -		return -ENOMEM;
> > -
> > -	inode->i_link = lnk;
> > -	inode->i_op = &erofs_fast_symlink_iops;
> > -	return 0;
> > -}
> >   static int erofs_fill_inode(struct inode *inode)
> >   {
> >   	struct erofs_inode *vi = EROFS_I(inode);
> > -	struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
> > -	void *kaddr;
> > -	unsigned int ofs;
> >   	int err = 0;
> >   	trace_erofs_fill_inode(inode);
> >   	/* read inode base data from disk */
> > -	kaddr = erofs_read_inode(&buf, inode, &ofs);
> > -	if (IS_ERR(kaddr))
> > -		return PTR_ERR(kaddr);
> > +	err = erofs_read_inode(inode);
> > +	if (err)
> > +		goto out_unlock;
> 
> out_unlock can be avoided too, just
> 		return err;
> 
> >   	/* setup the new inode */
> >   	switch (inode->i_mode & S_IFMT) {
> > @@ -238,9 +241,11 @@ static int erofs_fill_inode(struct inode *inode)
> >   		inode_nohighmem(inode);
> >   		break;
> >   	case S_IFLNK:
> > -		err = erofs_fill_symlink(inode, kaddr, ofs);
> > -		if (err)
> > -			goto out_unlock;
> > +		if (inode->i_link)
> > +			inode->i_op = &erofs_fast_symlink_iops;
> > +		else
> > +			inode->i_op = &erofs_symlink_iops;
> > +
> >   		inode_nohighmem(inode);
> >   		break;
> >   	case S_IFCHR:
> > @@ -273,7 +278,6 @@ static int erofs_fill_inode(struct inode *inode)
> >   #endif
> >   	}
> >   out_unlock:
> 
> Remove this.

I'm not sure whether we need to remove this becasue device inodes do not
need other operation bindings below and still needs the out_unlock to be
early out. Another solution is to use the early return but i deem the
goto solution is clearer.

> 
> Thanks,
> Gao Xiang

Best Regards,
Yiyang Wu


More information about the Linux-erofs mailing list