[Ocfs2-devel] [PATCH] ocfs2: Add quota calls for allocation and freeing of inodes and space

Jan Kara jack at suse.cz
Wed Oct 22 07:49:00 PDT 2008


On Tue 21-10-08 16:34:46, Joel Becker wrote:
> On Mon, Oct 20, 2008 at 07:23:58PM +0200, Jan Kara wrote:
> > Add quota calls for allocation and freeing of inodes and space, also update
> > estimates on number of needed credits for a transaction. Move out inode
> > allocation from ocfs2_mknod_locked() because vfs_dq_init() must be called
> > outside of a transaction.
> > 
> > Signed-off-by: Jan Kara <jack at suse.cz>
> > @@ -5954,6 +5955,8 @@ static int ocfs2_do_truncate(struct ocfs2_super *osb,
> >  		goto bail;
> >  	}
> >  
> > +	vfs_dq_free_space_nodirty(inode,
> > +			ocfs2_clusters_to_bytes(osb->sb, clusters_to_del));
> >  	spin_lock(&OCFS2_I(inode)->ip_lock);
> >  	OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters) -
> >  				      clusters_to_del;
> 
> 	In this one instance, you don't clean up the quota change on
> error, even though clusters_to_del might remain allocated.  How come?
  Good point. Is there a way to find out how many clusters were actually
truncated before we failed?

> 	On that note, I don't see us a) fixing the inode up on failure
> or b) writing out the new values.  Now, I remember from the past that we
> allow a smaller i_clusters than actually in the tree, because our alloc
> code can handle that.  So I'm sure that the fallout from us not fixing
> up i_clusters and/or writing it is safe.
> 	But I wonder what the right behavior is with regards to quota.
  Well, quota usage must be always in sync with i_clusters - or better
i_blocks - because on chown or chgrp, that is what you're going to transfer
from one user to another one.
  As a side note, I've actually noticed a few paths (even for cases of
ENOSPC) in OCFS2 where if we fail during allocation, we actually leave
behind allocated blocks not attached anywhere (i.e., only fsck can reclaim
them). I discussed it with Mark and it's not completely trivial to fix. So
I've worked it around so that quota allocation is done before allocating
any blocks and I also tried to take care that at least quota stays correct
after a failure.

> > @@ -908,7 +911,8 @@ void ocfs2_delete_inode(struct inode *inode)
> >  
> >  	mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino);
> >  
> > -	if (is_bad_inode(inode)) {
> > +	/* Inode left after unsuccessful inode allocation? */
> > +	if (is_bad_inode(inode) || !OCFS2_I(inode)->ip_blkno) {
> >  		mlog(0, "Skipping delete of bad inode\n");
> >  		goto bail;
> >  	}
> 
> 	!ip_blkno is your way of saying you called
> ocfs2_get_init_inode() but failed ocfs2_claim_new_inode() in
> ocfs2_mknod_locked(), right?
  Or user is over quota...

> Probably want to adjust your comment to
> point out that is_bad_inode() comes from read_inode(), !ip_blkno from
> mknod().
  Good point. Will do.

> 	I checked into just having your failed mknod() call
> make_bad_inode(), but it doesn't fit.  We don't even want to get there.
  Yes, I was also looking into it before introducing the test and for some
reason I didn't like it much.

								Honza
-- 
Jan Kara <jack at suse.cz>
SUSE Labs, CR



More information about the Ocfs2-devel mailing list