#include "vfs.h"
 #include "nfsd.h"
 #include "nfsfh.h"
+#include "netns.h"
 #include "filecache.h"
 #include "trace.h"
 
 }
 
 static struct nfsd_file *
-nfsd_file_alloc(struct inode *inode, unsigned int may, unsigned int hashval)
+nfsd_file_alloc(struct inode *inode, unsigned int may, unsigned int hashval,
+               struct net *net)
 {
        struct nfsd_file *nf;
 
                INIT_LIST_HEAD(&nf->nf_lru);
                nf->nf_file = NULL;
                nf->nf_cred = get_current_cred();
+               nf->nf_net = net;
                nf->nf_flags = 0;
                nf->nf_inode = inode;
                nf->nf_hashval = hashval;
  * Note this can deadlock with nfsd_file_lru_cb.
  */
 void
-nfsd_file_cache_purge(void)
+nfsd_file_cache_purge(struct net *net)
 {
        unsigned int            i;
        struct nfsd_file        *nf;
+       struct hlist_node       *next;
        LIST_HEAD(dispose);
        bool del;
 
                return;
 
        for (i = 0; i < NFSD_FILE_HASH_SIZE; i++) {
-               spin_lock(&nfsd_file_hashtbl[i].nfb_lock);
-               while(!hlist_empty(&nfsd_file_hashtbl[i].nfb_head)) {
-                       nf = hlist_entry(nfsd_file_hashtbl[i].nfb_head.first,
-                                        struct nfsd_file, nf_node);
+               struct nfsd_fcache_bucket *nfb = &nfsd_file_hashtbl[i];
+
+               spin_lock(&nfb->nfb_lock);
+               hlist_for_each_entry_safe(nf, next, &nfb->nfb_head, nf_node) {
+                       if (net && nf->nf_net != net)
+                               continue;
                        del = nfsd_file_unhash_and_release_locked(nf, &dispose);
 
                        /*
                         */
                        WARN_ON_ONCE(!del);
                }
-               spin_unlock(&nfsd_file_hashtbl[i].nfb_lock);
+               spin_unlock(&nfb->nfb_lock);
                nfsd_file_dispose_list(&dispose);
        }
 }
         * calling nfsd_file_cache_purge
         */
        cancel_delayed_work_sync(&nfsd_filecache_laundrette);
-       nfsd_file_cache_purge();
+       nfsd_file_cache_purge(NULL);
        list_lru_destroy(&nfsd_file_lru);
        rcu_barrier();
        fsnotify_put_group(nfsd_file_fsnotify_group);
 
 static struct nfsd_file *
 nfsd_file_find_locked(struct inode *inode, unsigned int may_flags,
-                       unsigned int hashval)
+                       unsigned int hashval, struct net *net)
 {
        struct nfsd_file *nf;
        unsigned char need = may_flags & NFSD_FILE_MAY_MASK;
                        continue;
                if (nf->nf_inode != inode)
                        continue;
+               if (nf->nf_net != net)
+                       continue;
                if (!nfsd_match_cred(nf->nf_cred, current_cred()))
                        continue;
                if (nfsd_file_get(nf) != NULL)
                  unsigned int may_flags, struct nfsd_file **pnf)
 {
        __be32  status;
+       struct net *net = SVC_NET(rqstp);
        struct nfsd_file *nf, *new;
        struct inode *inode;
        unsigned int hashval;
        hashval = (unsigned int)hash_long(inode->i_ino, NFSD_FILE_HASH_BITS);
 retry:
        rcu_read_lock();
-       nf = nfsd_file_find_locked(inode, may_flags, hashval);
+       nf = nfsd_file_find_locked(inode, may_flags, hashval, net);
        rcu_read_unlock();
        if (nf)
                goto wait_for_construction;
 
-       new = nfsd_file_alloc(inode, may_flags, hashval);
+       new = nfsd_file_alloc(inode, may_flags, hashval, net);
        if (!new) {
                trace_nfsd_file_acquire(rqstp, hashval, inode, may_flags,
                                        NULL, nfserr_jukebox);
        }
 
        spin_lock(&nfsd_file_hashtbl[hashval].nfb_lock);
-       nf = nfsd_file_find_locked(inode, may_flags, hashval);
+       nf = nfsd_file_find_locked(inode, may_flags, hashval, net);
        if (nf == NULL)
                goto open_file;
        spin_unlock(&nfsd_file_hashtbl[hashval].nfb_lock);