@@ -559,59 +559,61 @@ static struct shrinker nfsd_file_shrinker = {
559559 .seeks = 1 ,
560560};
561561
562- static void
563- __nfsd_file_close_inode (struct inode * inode , unsigned int hashval ,
564- struct list_head * dispose )
562+ /*
563+ * Find all cache items across all net namespaces that match @inode and
564+ * move them to @dispose. The lookup is atomic wrt nfsd_file_acquire().
565+ */
566+ static unsigned int
567+ __nfsd_file_close_inode (struct inode * inode , struct list_head * dispose )
565568{
569+ unsigned int hashval = (unsigned int )hash_long (inode -> i_ino ,
570+ NFSD_FILE_HASH_BITS );
571+ unsigned int count = 0 ;
566572 struct nfsd_file * nf ;
567573 struct hlist_node * tmp ;
568574
569575 spin_lock (& nfsd_file_hashtbl [hashval ].nfb_lock );
570576 hlist_for_each_entry_safe (nf , tmp , & nfsd_file_hashtbl [hashval ].nfb_head , nf_node ) {
571- if (inode == nf -> nf_inode )
577+ if (inode == nf -> nf_inode ) {
572578 nfsd_file_unhash_and_release_locked (nf , dispose );
579+ count ++ ;
580+ }
573581 }
574582 spin_unlock (& nfsd_file_hashtbl [hashval ].nfb_lock );
583+ return count ;
575584}
576585
577586/**
578587 * nfsd_file_close_inode_sync - attempt to forcibly close a nfsd_file
579588 * @inode: inode of the file to attempt to remove
580589 *
581- * Walk the whole hash bucket, looking for any files that correspond to "inode".
582- * If any do, then unhash them and put the hashtable reference to them and
583- * destroy any that had their last reference put. Also ensure that any of the
584- * fputs also have their final __fput done as well.
590+ * Unhash and put, then flush and fput all cache items associated with @inode.
585591 */
586592void
587593nfsd_file_close_inode_sync (struct inode * inode )
588594{
589- unsigned int hashval = (unsigned int )hash_long (inode -> i_ino ,
590- NFSD_FILE_HASH_BITS );
591595 LIST_HEAD (dispose );
596+ unsigned int count ;
592597
593- __nfsd_file_close_inode (inode , hashval , & dispose );
594- trace_nfsd_file_close_inode_sync (inode , ! list_empty ( & dispose ) );
598+ count = __nfsd_file_close_inode (inode , & dispose );
599+ trace_nfsd_file_close_inode_sync (inode , count );
595600 nfsd_file_dispose_list_sync (& dispose );
596601}
597602
598603/**
599604 * nfsd_file_close_inode - attempt a delayed close of a nfsd_file
600605 * @inode: inode of the file to attempt to remove
601606 *
602- * Walk the whole hash bucket, looking for any files that correspond to "inode".
603- * If any do, then unhash them and put the hashtable reference to them and
604- * destroy any that had their last reference put.
607+ * Unhash and put all cache item associated with @inode.
605608 */
606609static void
607610nfsd_file_close_inode (struct inode * inode )
608611{
609- unsigned int hashval = (unsigned int )hash_long (inode -> i_ino ,
610- NFSD_FILE_HASH_BITS );
611612 LIST_HEAD (dispose );
613+ unsigned int count ;
612614
613- __nfsd_file_close_inode (inode , hashval , & dispose );
614- trace_nfsd_file_close_inode (inode , ! list_empty ( & dispose ) );
615+ count = __nfsd_file_close_inode (inode , & dispose );
616+ trace_nfsd_file_close_inode (inode , count );
615617 nfsd_file_dispose_list_delayed (& dispose );
616618}
617619
0 commit comments