filecache.c (e375780b631a5fc2a61a3b4fa12429255361a31e) filecache.c (08af54b3e5729bc1d56ad3190af811301bdc37a1)
1/*
2 * Open file cache.
3 *
4 * (c) 2015 - Jeff Layton <jeff.layton@primarydata.com>
5 */
6
7#include <linux/hash.h>
8#include <linux/slab.h>

--- 105 unchanged lines hidden (view full) ---

114nfsd_file_mark_find_or_create(struct nfsd_file *nf)
115{
116 int err;
117 struct fsnotify_mark *mark;
118 struct nfsd_file_mark *nfm = NULL, *new;
119 struct inode *inode = nf->nf_inode;
120
121 do {
1/*
2 * Open file cache.
3 *
4 * (c) 2015 - Jeff Layton <jeff.layton@primarydata.com>
5 */
6
7#include <linux/hash.h>
8#include <linux/slab.h>

--- 105 unchanged lines hidden (view full) ---

114nfsd_file_mark_find_or_create(struct nfsd_file *nf)
115{
116 int err;
117 struct fsnotify_mark *mark;
118 struct nfsd_file_mark *nfm = NULL, *new;
119 struct inode *inode = nf->nf_inode;
120
121 do {
122 fsnotify_group_lock(nfsd_file_fsnotify_group);
122 mutex_lock(&nfsd_file_fsnotify_group->mark_mutex);
123 mark = fsnotify_find_mark(&inode->i_fsnotify_marks,
123 mark = fsnotify_find_mark(&inode->i_fsnotify_marks,
124 nfsd_file_fsnotify_group);
124 nfsd_file_fsnotify_group);
125 if (mark) {
126 nfm = nfsd_file_mark_get(container_of(mark,
127 struct nfsd_file_mark,
128 nfm_mark));
125 if (mark) {
126 nfm = nfsd_file_mark_get(container_of(mark,
127 struct nfsd_file_mark,
128 nfm_mark));
129 fsnotify_group_unlock(nfsd_file_fsnotify_group);
129 mutex_unlock(&nfsd_file_fsnotify_group->mark_mutex);
130 if (nfm) {
131 fsnotify_put_mark(mark);
132 break;
133 }
134 /* Avoid soft lockup race with nfsd_file_mark_put() */
135 fsnotify_destroy_mark(mark, nfsd_file_fsnotify_group);
136 fsnotify_put_mark(mark);
130 if (nfm) {
131 fsnotify_put_mark(mark);
132 break;
133 }
134 /* Avoid soft lockup race with nfsd_file_mark_put() */
135 fsnotify_destroy_mark(mark, nfsd_file_fsnotify_group);
136 fsnotify_put_mark(mark);
137 } else {
138 fsnotify_group_unlock(nfsd_file_fsnotify_group);
139 }
137 } else
138 mutex_unlock(&nfsd_file_fsnotify_group->mark_mutex);
140
141 /* allocate a new nfm */
142 new = kmem_cache_alloc(nfsd_file_mark_slab, GFP_KERNEL);
143 if (!new)
144 return NULL;
145 fsnotify_init_mark(&new->nfm_mark, nfsd_file_fsnotify_group);
146 new->nfm_mark.mask = FS_ATTRIB|FS_DELETE_SELF;
147 refcount_set(&new->nfm_ref, 1);

--- 150 unchanged lines hidden (view full) ---

298 WARN_ON(test_bit(NFSD_FILE_HASHED, &nf->nf_flags));
299 nfsd_file_free(nf);
300 }
301}
302
303void
304nfsd_file_put(struct nfsd_file *nf)
305{
139
140 /* allocate a new nfm */
141 new = kmem_cache_alloc(nfsd_file_mark_slab, GFP_KERNEL);
142 if (!new)
143 return NULL;
144 fsnotify_init_mark(&new->nfm_mark, nfsd_file_fsnotify_group);
145 new->nfm_mark.mask = FS_ATTRIB|FS_DELETE_SELF;
146 refcount_set(&new->nfm_ref, 1);

--- 150 unchanged lines hidden (view full) ---

297 WARN_ON(test_bit(NFSD_FILE_HASHED, &nf->nf_flags));
298 nfsd_file_free(nf);
299 }
300}
301
302void
303nfsd_file_put(struct nfsd_file *nf)
304{
305 might_sleep();
306
306 set_bit(NFSD_FILE_REFERENCED, &nf->nf_flags);
307 if (test_bit(NFSD_FILE_HASHED, &nf->nf_flags) == 0) {
308 nfsd_file_flush(nf);
309 nfsd_file_put_noref(nf);
310 } else {
311 nfsd_file_put_noref(nf);
312 if (nf->nf_file)
313 nfsd_file_schedule_laundrette();

--- 360 unchanged lines hidden (view full) ---

674 }
675
676 ret = lease_register_notifier(&nfsd_file_lease_notifier);
677 if (ret) {
678 pr_err("nfsd: unable to register lease notifier: %d\n", ret);
679 goto out_shrinker;
680 }
681
307 set_bit(NFSD_FILE_REFERENCED, &nf->nf_flags);
308 if (test_bit(NFSD_FILE_HASHED, &nf->nf_flags) == 0) {
309 nfsd_file_flush(nf);
310 nfsd_file_put_noref(nf);
311 } else {
312 nfsd_file_put_noref(nf);
313 if (nf->nf_file)
314 nfsd_file_schedule_laundrette();

--- 360 unchanged lines hidden (view full) ---

675 }
676
677 ret = lease_register_notifier(&nfsd_file_lease_notifier);
678 if (ret) {
679 pr_err("nfsd: unable to register lease notifier: %d\n", ret);
680 goto out_shrinker;
681 }
682
682 nfsd_file_fsnotify_group = fsnotify_alloc_group(&nfsd_file_fsnotify_ops,
683 FSNOTIFY_GROUP_NOFS);
683 nfsd_file_fsnotify_group = fsnotify_alloc_group(&nfsd_file_fsnotify_ops);
684 if (IS_ERR(nfsd_file_fsnotify_group)) {
685 pr_err("nfsd: unable to create fsnotify group: %ld\n",
686 PTR_ERR(nfsd_file_fsnotify_group));
687 ret = PTR_ERR(nfsd_file_fsnotify_group);
688 nfsd_file_fsnotify_group = NULL;
689 goto out_notifier;
690 }
691

--- 202 unchanged lines hidden (view full) ---

894 break;
895 }
896 }
897 rcu_read_unlock();
898 trace_nfsd_file_is_cached(inode, hashval, (int)ret);
899 return ret;
900}
901
684 if (IS_ERR(nfsd_file_fsnotify_group)) {
685 pr_err("nfsd: unable to create fsnotify group: %ld\n",
686 PTR_ERR(nfsd_file_fsnotify_group));
687 ret = PTR_ERR(nfsd_file_fsnotify_group);
688 nfsd_file_fsnotify_group = NULL;
689 goto out_notifier;
690 }
691

--- 202 unchanged lines hidden (view full) ---

894 break;
895 }
896 }
897 rcu_read_unlock();
898 trace_nfsd_file_is_cached(inode, hashval, (int)ret);
899 return ret;
900}
901
902__be32
903nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp,
904 unsigned int may_flags, struct nfsd_file **pnf)
902static __be32
903nfsd_do_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp,
904 unsigned int may_flags, struct nfsd_file **pnf, bool open)
905{
906 __be32 status;
907 struct net *net = SVC_NET(rqstp);
908 struct nfsd_file *nf, *new;
909 struct inode *inode;
910 unsigned int hashval;
911 bool retry = true;
912

--- 78 unchanged lines hidden (view full) ---

991 ++nfsd_file_hashtbl[hashval].nfb_count;
992 nfsd_file_hashtbl[hashval].nfb_maxcount = max(nfsd_file_hashtbl[hashval].nfb_maxcount,
993 nfsd_file_hashtbl[hashval].nfb_count);
994 spin_unlock(&nfsd_file_hashtbl[hashval].nfb_lock);
995 if (atomic_long_inc_return(&nfsd_filecache_count) >= NFSD_FILE_LRU_THRESHOLD)
996 nfsd_file_gc();
997
998 nf->nf_mark = nfsd_file_mark_find_or_create(nf);
905{
906 __be32 status;
907 struct net *net = SVC_NET(rqstp);
908 struct nfsd_file *nf, *new;
909 struct inode *inode;
910 unsigned int hashval;
911 bool retry = true;
912

--- 78 unchanged lines hidden (view full) ---

991 ++nfsd_file_hashtbl[hashval].nfb_count;
992 nfsd_file_hashtbl[hashval].nfb_maxcount = max(nfsd_file_hashtbl[hashval].nfb_maxcount,
993 nfsd_file_hashtbl[hashval].nfb_count);
994 spin_unlock(&nfsd_file_hashtbl[hashval].nfb_lock);
995 if (atomic_long_inc_return(&nfsd_filecache_count) >= NFSD_FILE_LRU_THRESHOLD)
996 nfsd_file_gc();
997
998 nf->nf_mark = nfsd_file_mark_find_or_create(nf);
999 if (nf->nf_mark)
1000 status = nfsd_open_verified(rqstp, fhp, S_IFREG,
1001 may_flags, &nf->nf_file);
1002 else
999 if (nf->nf_mark) {
1000 if (open) {
1001 status = nfsd_open_verified(rqstp, fhp, may_flags,
1002 &nf->nf_file);
1003 trace_nfsd_file_open(nf, status);
1004 } else
1005 status = nfs_ok;
1006 } else
1003 status = nfserr_jukebox;
1004 /*
1005 * If construction failed, or we raced with a call to unlink()
1006 * then unhash.
1007 */
1008 if (status != nfs_ok || inode->i_nlink == 0) {
1009 bool do_free;
1010 spin_lock(&nfsd_file_hashtbl[hashval].nfb_lock);
1011 do_free = nfsd_file_unhash(nf);
1012 spin_unlock(&nfsd_file_hashtbl[hashval].nfb_lock);
1013 if (do_free)
1014 nfsd_file_put_noref(nf);
1015 }
1016 clear_bit_unlock(NFSD_FILE_PENDING, &nf->nf_flags);
1017 smp_mb__after_atomic();
1018 wake_up_bit(&nf->nf_flags, NFSD_FILE_PENDING);
1019 goto out;
1020}
1021
1007 status = nfserr_jukebox;
1008 /*
1009 * If construction failed, or we raced with a call to unlink()
1010 * then unhash.
1011 */
1012 if (status != nfs_ok || inode->i_nlink == 0) {
1013 bool do_free;
1014 spin_lock(&nfsd_file_hashtbl[hashval].nfb_lock);
1015 do_free = nfsd_file_unhash(nf);
1016 spin_unlock(&nfsd_file_hashtbl[hashval].nfb_lock);
1017 if (do_free)
1018 nfsd_file_put_noref(nf);
1019 }
1020 clear_bit_unlock(NFSD_FILE_PENDING, &nf->nf_flags);
1021 smp_mb__after_atomic();
1022 wake_up_bit(&nf->nf_flags, NFSD_FILE_PENDING);
1023 goto out;
1024}
1025
1026/**
1027 * nfsd_file_acquire - Get a struct nfsd_file with an open file
1028 * @rqstp: the RPC transaction being executed
1029 * @fhp: the NFS filehandle of the file to be opened
1030 * @may_flags: NFSD_MAY_ settings for the file
1031 * @pnf: OUT: new or found "struct nfsd_file" object
1032 *
1033 * Returns nfs_ok and sets @pnf on success; otherwise an nfsstat in
1034 * network byte order is returned.
1035 */
1036__be32
1037nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp,
1038 unsigned int may_flags, struct nfsd_file **pnf)
1039{
1040 return nfsd_do_file_acquire(rqstp, fhp, may_flags, pnf, true);
1041}
1042
1043/**
1044 * nfsd_file_create - Get a struct nfsd_file, do not open
1045 * @rqstp: the RPC transaction being executed
1046 * @fhp: the NFS filehandle of the file just created
1047 * @may_flags: NFSD_MAY_ settings for the file
1048 * @pnf: OUT: new or found "struct nfsd_file" object
1049 *
1050 * Returns nfs_ok and sets @pnf on success; otherwise an nfsstat in
1051 * network byte order is returned.
1052 */
1053__be32
1054nfsd_file_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1055 unsigned int may_flags, struct nfsd_file **pnf)
1056{
1057 return nfsd_do_file_acquire(rqstp, fhp, may_flags, pnf, false);
1058}
1059
1022/*
1023 * Note that fields may be added, removed or reordered in the future. Programs
1024 * scraping this file for info should test the labels to ensure they're
1025 * getting the correct field.
1026 */
1027static int nfsd_file_cache_stats_show(struct seq_file *m, void *v)
1028{
1029 unsigned int i, count = 0, longest = 0;

--- 29 unchanged lines hidden ---
1060/*
1061 * Note that fields may be added, removed or reordered in the future. Programs
1062 * scraping this file for info should test the labels to ensure they're
1063 * getting the correct field.
1064 */
1065static int nfsd_file_cache_stats_show(struct seq_file *m, void *v)
1066{
1067 unsigned int i, count = 0, longest = 0;

--- 29 unchanged lines hidden ---