filecache.c (8d0d254b15cc5b7d46d85fb7ab8ecede9575e672) | filecache.c (243a5263014a30436c93ed3f1f864c1da845455e) |
---|---|
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> --- 1028 unchanged lines hidden (view full) --- 1037nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, 1038 unsigned int may_flags, struct nfsd_file **pnf, bool open) 1039{ 1040 struct nfsd_file_lookup_key key = { 1041 .type = NFSD_FILE_KEY_FULL, 1042 .need = may_flags & NFSD_FILE_MAY_MASK, 1043 .net = SVC_NET(rqstp), 1044 }; | 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> --- 1028 unchanged lines hidden (view full) --- 1037nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, 1038 unsigned int may_flags, struct nfsd_file **pnf, bool open) 1039{ 1040 struct nfsd_file_lookup_key key = { 1041 .type = NFSD_FILE_KEY_FULL, 1042 .need = may_flags & NFSD_FILE_MAY_MASK, 1043 .net = SVC_NET(rqstp), 1044 }; |
1045 struct nfsd_file *nf, *new; 1046 bool retry = true; | 1045 bool open_retry = true; 1046 struct nfsd_file *nf; |
1047 __be32 status; | 1047 __be32 status; |
1048 int ret; |
|
1048 1049 status = fh_verify(rqstp, fhp, S_IFREG, 1050 may_flags|NFSD_MAY_OWNER_OVERRIDE); 1051 if (status != nfs_ok) 1052 return status; 1053 key.inode = d_inode(fhp->fh_dentry); 1054 key.cred = get_current_cred(); 1055 1056retry: | 1049 1050 status = fh_verify(rqstp, fhp, S_IFREG, 1051 may_flags|NFSD_MAY_OWNER_OVERRIDE); 1052 if (status != nfs_ok) 1053 return status; 1054 key.inode = d_inode(fhp->fh_dentry); 1055 key.cred = get_current_cred(); 1056 1057retry: |
1057 /* Avoid allocation if the item is already in cache */ 1058 nf = rhashtable_lookup_fast(&nfsd_file_rhash_tbl, &key, 1059 nfsd_file_rhash_params); | 1058 rcu_read_lock(); 1059 nf = rhashtable_lookup(&nfsd_file_rhash_tbl, &key, 1060 nfsd_file_rhash_params); |
1060 if (nf) 1061 nf = nfsd_file_get(nf); | 1061 if (nf) 1062 nf = nfsd_file_get(nf); |
1063 rcu_read_unlock(); |
|
1062 if (nf) 1063 goto wait_for_construction; 1064 | 1064 if (nf) 1065 goto wait_for_construction; 1066 |
1065 new = nfsd_file_alloc(&key, may_flags); 1066 if (!new) { | 1067 nf = nfsd_file_alloc(&key, may_flags); 1068 if (!nf) { |
1067 status = nfserr_jukebox; 1068 goto out_status; 1069 } 1070 | 1069 status = nfserr_jukebox; 1070 goto out_status; 1071 } 1072 |
1071 nf = rhashtable_lookup_get_insert_key(&nfsd_file_rhash_tbl, 1072 &key, &new->nf_rhash, 1073 nfsd_file_rhash_params); 1074 if (!nf) { 1075 nf = new; | 1073 ret = rhashtable_lookup_insert_key(&nfsd_file_rhash_tbl, 1074 &key, &nf->nf_rhash, 1075 nfsd_file_rhash_params); 1076 if (likely(ret == 0)) |
1076 goto open_file; | 1077 goto open_file; |
1077 } 1078 if (IS_ERR(nf)) 1079 goto insert_err; 1080 nf = nfsd_file_get(nf); 1081 if (nf == NULL) { 1082 nf = new; 1083 goto open_file; 1084 } 1085 nfsd_file_slab_free(&new->nf_rcu); | |
1086 | 1078 |
1079 nfsd_file_slab_free(&nf->nf_rcu); 1080 if (ret == -EEXIST) 1081 goto retry; 1082 trace_nfsd_file_insert_err(rqstp, key.inode, may_flags, ret); 1083 status = nfserr_jukebox; 1084 goto out_status; 1085 |
|
1087wait_for_construction: 1088 wait_on_bit(&nf->nf_flags, NFSD_FILE_PENDING, TASK_UNINTERRUPTIBLE); 1089 1090 /* Did construction of this file fail? */ 1091 if (!test_bit(NFSD_FILE_HASHED, &nf->nf_flags)) { 1092 trace_nfsd_file_cons_err(rqstp, key.inode, may_flags, nf); | 1086wait_for_construction: 1087 wait_on_bit(&nf->nf_flags, NFSD_FILE_PENDING, TASK_UNINTERRUPTIBLE); 1088 1089 /* Did construction of this file fail? */ 1090 if (!test_bit(NFSD_FILE_HASHED, &nf->nf_flags)) { 1091 trace_nfsd_file_cons_err(rqstp, key.inode, may_flags, nf); |
1093 if (!retry) { | 1092 if (!open_retry) { |
1094 status = nfserr_jukebox; 1095 goto out; 1096 } | 1093 status = nfserr_jukebox; 1094 goto out; 1095 } |
1097 retry = false; | 1096 open_retry = false; |
1098 nfsd_file_put_noref(nf); 1099 goto retry; 1100 } 1101 1102 nfsd_file_lru_remove(nf); 1103 this_cpu_inc(nfsd_file_cache_hits); 1104 1105 status = nfserrno(nfsd_open_break_lease(file_inode(nf->nf_file), may_flags)); --- 31 unchanged lines hidden (view full) --- 1137 */ 1138 if (status != nfs_ok || key.inode->i_nlink == 0) 1139 if (nfsd_file_unhash(nf)) 1140 nfsd_file_put_noref(nf); 1141 clear_bit_unlock(NFSD_FILE_PENDING, &nf->nf_flags); 1142 smp_mb__after_atomic(); 1143 wake_up_bit(&nf->nf_flags, NFSD_FILE_PENDING); 1144 goto out; | 1097 nfsd_file_put_noref(nf); 1098 goto retry; 1099 } 1100 1101 nfsd_file_lru_remove(nf); 1102 this_cpu_inc(nfsd_file_cache_hits); 1103 1104 status = nfserrno(nfsd_open_break_lease(file_inode(nf->nf_file), may_flags)); --- 31 unchanged lines hidden (view full) --- 1136 */ 1137 if (status != nfs_ok || key.inode->i_nlink == 0) 1138 if (nfsd_file_unhash(nf)) 1139 nfsd_file_put_noref(nf); 1140 clear_bit_unlock(NFSD_FILE_PENDING, &nf->nf_flags); 1141 smp_mb__after_atomic(); 1142 wake_up_bit(&nf->nf_flags, NFSD_FILE_PENDING); 1143 goto out; |
1145 1146insert_err: 1147 nfsd_file_slab_free(&new->nf_rcu); 1148 trace_nfsd_file_insert_err(rqstp, key.inode, may_flags, PTR_ERR(nf)); 1149 nf = NULL; 1150 status = nfserr_jukebox; 1151 goto out_status; | |
1152} 1153 1154/** 1155 * nfsd_file_acquire - Get a struct nfsd_file with an open file 1156 * @rqstp: the RPC transaction being executed 1157 * @fhp: the NFS filehandle of the file to be opened 1158 * @may_flags: NFSD_MAY_ settings for the file 1159 * @pnf: OUT: new or found "struct nfsd_file" object --- 80 unchanged lines hidden --- | 1144} 1145 1146/** 1147 * nfsd_file_acquire - Get a struct nfsd_file with an open file 1148 * @rqstp: the RPC transaction being executed 1149 * @fhp: the NFS filehandle of the file to be opened 1150 * @may_flags: NFSD_MAY_ settings for the file 1151 * @pnf: OUT: new or found "struct nfsd_file" object --- 80 unchanged lines hidden --- |