diff options
Diffstat (limited to 'fs/nfsd/filecache.c')
| -rw-r--r-- | fs/nfsd/filecache.c | 79 | 
1 files changed, 16 insertions, 63 deletions
| diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index fdf89fcf1a0c..8bc807c5fea4 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -44,12 +44,9 @@ struct nfsd_fcache_bucket {  static DEFINE_PER_CPU(unsigned long, nfsd_file_cache_hits);  struct nfsd_fcache_disposal { -	struct list_head list;  	struct work_struct work; -	struct net *net;  	spinlock_t lock;  	struct list_head freeme; -	struct rcu_head rcu;  };  static struct workqueue_struct *nfsd_filecache_wq __read_mostly; @@ -62,8 +59,6 @@ static long				nfsd_file_lru_flags;  static struct fsnotify_group		*nfsd_file_fsnotify_group;  static atomic_long_t			nfsd_filecache_count;  static struct delayed_work		nfsd_filecache_laundrette; -static DEFINE_SPINLOCK(laundrette_lock); -static LIST_HEAD(laundrettes);  static void nfsd_file_gc(void); @@ -194,7 +189,6 @@ nfsd_file_alloc(struct inode *inode, unsigned int may, unsigned int hashval,  				__set_bit(NFSD_FILE_BREAK_READ, &nf->nf_flags);  		}  		nf->nf_mark = NULL; -		init_rwsem(&nf->nf_rwsem);  		trace_nfsd_file_alloc(nf);  	}  	return nf; @@ -249,7 +243,7 @@ nfsd_file_do_unhash(struct nfsd_file *nf)  	trace_nfsd_file_unhash(nf);  	if (nfsd_file_check_write_error(nf)) -		nfsd_reset_boot_verifier(net_generic(nf->nf_net, nfsd_net_id)); +		nfsd_reset_write_verifier(net_generic(nf->nf_net, nfsd_net_id));  	--nfsd_file_hashtbl[nf->nf_hashval].nfb_count;  	hlist_del_rcu(&nf->nf_node);  	atomic_long_dec(&nfsd_filecache_count); @@ -367,19 +361,13 @@ nfsd_file_list_remove_disposal(struct list_head *dst,  static void  nfsd_file_list_add_disposal(struct list_head *files, struct net *net)  { -	struct nfsd_fcache_disposal *l; +	struct nfsd_net *nn = net_generic(net, nfsd_net_id); +	struct nfsd_fcache_disposal *l = nn->fcache_disposal; -	rcu_read_lock(); -	list_for_each_entry_rcu(l, &laundrettes, list) { -		if (l->net == net) { -			spin_lock(&l->lock); -			list_splice_tail_init(files, &l->freeme); -			spin_unlock(&l->lock); -			queue_work(nfsd_filecache_wq, &l->work); -			break; -		} -	} -	rcu_read_unlock(); +	spin_lock(&l->lock); +	list_splice_tail_init(files, &l->freeme); +	spin_unlock(&l->lock); +	queue_work(nfsd_filecache_wq, &l->work);  }  static void @@ -755,7 +743,7 @@ nfsd_file_cache_purge(struct net *net)  }  static struct nfsd_fcache_disposal * -nfsd_alloc_fcache_disposal(struct net *net) +nfsd_alloc_fcache_disposal(void)  {  	struct nfsd_fcache_disposal *l; @@ -763,7 +751,6 @@ nfsd_alloc_fcache_disposal(struct net *net)  	if (!l)  		return NULL;  	INIT_WORK(&l->work, nfsd_file_delayed_close); -	l->net = net;  	spin_lock_init(&l->lock);  	INIT_LIST_HEAD(&l->freeme);  	return l; @@ -772,61 +759,27 @@ nfsd_alloc_fcache_disposal(struct net *net)  static void  nfsd_free_fcache_disposal(struct nfsd_fcache_disposal *l)  { -	rcu_assign_pointer(l->net, NULL);  	cancel_work_sync(&l->work);  	nfsd_file_dispose_list(&l->freeme); -	kfree_rcu(l, rcu); -} - -static void -nfsd_add_fcache_disposal(struct nfsd_fcache_disposal *l) -{ -	spin_lock(&laundrette_lock); -	list_add_tail_rcu(&l->list, &laundrettes); -	spin_unlock(&laundrette_lock); -} - -static void -nfsd_del_fcache_disposal(struct nfsd_fcache_disposal *l) -{ -	spin_lock(&laundrette_lock); -	list_del_rcu(&l->list); -	spin_unlock(&laundrette_lock); -} - -static int -nfsd_alloc_fcache_disposal_net(struct net *net) -{ -	struct nfsd_fcache_disposal *l; - -	l = nfsd_alloc_fcache_disposal(net); -	if (!l) -		return -ENOMEM; -	nfsd_add_fcache_disposal(l); -	return 0; +	kfree(l);  }  static void  nfsd_free_fcache_disposal_net(struct net *net)  { -	struct nfsd_fcache_disposal *l; +	struct nfsd_net *nn = net_generic(net, nfsd_net_id); +	struct nfsd_fcache_disposal *l = nn->fcache_disposal; -	rcu_read_lock(); -	list_for_each_entry_rcu(l, &laundrettes, list) { -		if (l->net != net) -			continue; -		nfsd_del_fcache_disposal(l); -		rcu_read_unlock(); -		nfsd_free_fcache_disposal(l); -		return; -	} -	rcu_read_unlock(); +	nfsd_free_fcache_disposal(l);  }  int  nfsd_file_cache_start_net(struct net *net)  { -	return nfsd_alloc_fcache_disposal_net(net); +	struct nfsd_net *nn = net_generic(net, nfsd_net_id); + +	nn->fcache_disposal = nfsd_alloc_fcache_disposal(); +	return nn->fcache_disposal ? 0 : -ENOMEM;  }  void |