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