lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20101008093202.GX19804@ZenIV.linux.org.uk>
Date:	Fri, 8 Oct 2010 10:32:02 +0100
From:	Al Viro <viro@...IV.linux.org.uk>
To:	Dave Chinner <david@...morbit.com>
Cc:	linux-fsdevel@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH 09/18] fs: rework icount to be a locked variable

On Fri, Oct 08, 2010 at 04:21:23PM +1100, Dave Chinner wrote:
> From: Dave Chinner <dchinner@...hat.com>
> 
> The inode reference count is currently an atomic variable so that it can be
> sampled/modified outside the inode_lock. However, the inode_lock is still
> needed to synchronise the final reference count and checks against the inode
> state.
> 
> To avoid needing the protection of the inode lock, protect the inode reference
> count with the per-inode i_lock and convert it to a normal variable. To avoid
> existing out-of-tree code accidentally compiling against the new method, rename
> the i_count field to i_ref. This is relatively straight forward as there
> are limited external references to the i_count field remaining.

You are overdoing the information hiding here; _way_ too many small
functions that don't buy you anything so far, AFAICS.  Moreover, why
the hell not make them static inlines and get rid of the exports?

> -	if (atomic_add_unless(&inode->i_count, -1, 1))
> +	/* XXX: filesystems should not play refcount games like this */
> +	spin_lock(&inode->i_lock);
> +	if (inode->i_ref > 1) {
> +		inode->i_ref--;
> +		spin_unlock(&inode->i_lock);
>  		return;
> +	}
> +	spin_unlock(&inode->i_lock);

... or, perhaps, they needs a helper along the lines of "try to do iput()
if it's known to hit easy case".

I really don't like the look of code around -ENOSPC returns, though.
What exactly is going on there?  Can it e.g. interfere with that
delayed iput stuff?

>  void iref(struct inode *inode)
>  {
>  	spin_lock(&inode_lock);
> +	spin_lock(&inode->i_lock);
>  	iref_locked(inode);
> +	spin_unlock(&inode->i_lock);
>  	spin_unlock(&inode_lock);
>  }

*cringe*

>  int iref_read(struct inode *inode)
>  {
> -	return atomic_read(&inode->i_count);
> +	int ref;
> +
> +	spin_lock(&inode->i_lock);
> +	ref = inode->i_ref;
> +	spin_unlock(&inode->i_lock);
> +	return ref;

What's the point of locking here?

> @@ -1324,8 +1359,16 @@ void iput(struct inode *inode)
>  	if (inode) {
>  		BUG_ON(inode->i_state & I_CLEAR);
>  
> -		if (atomic_dec_and_lock(&inode->i_count, &inode_lock))
> +		spin_lock(&inode_lock);
> +		spin_lock(&inode->i_lock);
> +		inode->i_ref--;
> +		if (inode->i_ref == 0) {
> +			spin_unlock(&inode->i_lock);
>  			iput_final(inode);
> +			return;
> +		}

*UGH*  So you take inode_lock on every damn iput()?
>  		state->owner = owner;
>  		atomic_inc(&owner->so_count);
>  		list_add(&state->inode_states, &nfsi->open_states);
> -		state->inode = igrab(inode);
>  		spin_unlock(&inode->i_lock);
> +		state->inode = igrab(inode);

Why is that safe?

> --- a/fs/notify/inode_mark.c
> +++ b/fs/notify/inode_mark.c
> @@ -257,7 +257,8 @@ void fsnotify_unmount_inodes(struct list_head *list)
>  		 * actually evict all unreferenced inodes from icache which is
>  		 * unnecessarily violent and may in fact be illegal to do.
>  		 */
> -		if (!iref_read(inode))
> +		spin_lock(&inode->i_lock);
> +		if (!inode->i_ref)
>  			continue;

Really?
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ