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 --- |