^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Common NFS I/O operations for the pnfs file based
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * layout drivers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2014, Primary Data, Inc. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Tom Haynes <loghyr@primarydata.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/nfs_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/nfs_page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/sunrpc/addr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "nfs4session.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "pnfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define NFSDBG_FACILITY NFSDBG_PNFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) void pnfs_generic_rw_release(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct nfs_pgio_header *hdr = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) nfs_put_client(hdr->ds_clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) hdr->mds_ops->rpc_release(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) EXPORT_SYMBOL_GPL(pnfs_generic_rw_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /* Fake up some data that will cause nfs_commit_release to retry the writes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) void pnfs_generic_prepare_to_resend_writes(struct nfs_commit_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct nfs_writeverf *verf = data->res.verf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) data->task.tk_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) memset(&verf->verifier, 0, sizeof(verf->verifier));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) verf->committed = NFS_UNSTABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) EXPORT_SYMBOL_GPL(pnfs_generic_prepare_to_resend_writes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) void pnfs_generic_write_commit_done(struct rpc_task *task, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct nfs_commit_data *wdata = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* Note this may cause RPC to be resent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) wdata->mds_ops->rpc_call_done(task, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) EXPORT_SYMBOL_GPL(pnfs_generic_write_commit_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) void pnfs_generic_commit_release(void *calldata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct nfs_commit_data *data = calldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) data->completion_ops->completion(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) pnfs_put_lseg(data->lseg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) nfs_put_client(data->ds_clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) nfs_commitdata_release(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) EXPORT_SYMBOL_GPL(pnfs_generic_commit_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static struct pnfs_layout_segment *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) pnfs_free_bucket_lseg(struct pnfs_commit_bucket *bucket)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (list_empty(&bucket->committing) && list_empty(&bucket->written)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct pnfs_layout_segment *freeme = bucket->lseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) bucket->lseg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return freeme;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /* The generic layer is about to remove the req from the commit list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * If this will make the bucket empty, it will need to put the lseg reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * Note this must be called holding nfsi->commit_mutex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) pnfs_generic_clear_request_commit(struct nfs_page *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct nfs_commit_info *cinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct pnfs_commit_bucket *bucket = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (!test_and_clear_bit(PG_COMMIT_TO_DS, &req->wb_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) cinfo->ds->nwritten--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (list_is_singular(&req->wb_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) bucket = list_first_entry(&req->wb_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct pnfs_commit_bucket, written);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) nfs_request_remove_commit_list(req, cinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (bucket)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) pnfs_put_lseg(pnfs_free_bucket_lseg(bucket));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) EXPORT_SYMBOL_GPL(pnfs_generic_clear_request_commit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct pnfs_commit_array *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) pnfs_alloc_commit_array(size_t n, gfp_t gfp_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct pnfs_commit_array *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct pnfs_commit_bucket *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) p = kmalloc(struct_size(p, buckets, n), gfp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) p->nbuckets = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) INIT_LIST_HEAD(&p->cinfo_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) INIT_LIST_HEAD(&p->lseg_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) p->lseg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) for (b = &p->buckets[0]; n != 0; b++, n--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) INIT_LIST_HEAD(&b->written);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) INIT_LIST_HEAD(&b->committing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) b->lseg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) b->direct_verf.committed = NFS_INVALID_STABLE_HOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) EXPORT_SYMBOL_GPL(pnfs_alloc_commit_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) pnfs_free_commit_array(struct pnfs_commit_array *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) kfree_rcu(p, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) EXPORT_SYMBOL_GPL(pnfs_free_commit_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static struct pnfs_commit_array *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) pnfs_find_commit_array_by_lseg(struct pnfs_ds_commit_info *fl_cinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct pnfs_layout_segment *lseg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct pnfs_commit_array *array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) list_for_each_entry_rcu(array, &fl_cinfo->commits, cinfo_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (array->lseg == lseg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct pnfs_commit_array *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) pnfs_add_commit_array(struct pnfs_ds_commit_info *fl_cinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct pnfs_commit_array *new,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct pnfs_layout_segment *lseg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct pnfs_commit_array *array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) array = pnfs_find_commit_array_by_lseg(fl_cinfo, lseg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (array)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) new->lseg = lseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) refcount_set(&new->refcount, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) list_add_rcu(&new->cinfo_list, &fl_cinfo->commits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) list_add(&new->lseg_list, &lseg->pls_commits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) EXPORT_SYMBOL_GPL(pnfs_add_commit_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static struct pnfs_commit_array *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) pnfs_lookup_commit_array(struct pnfs_ds_commit_info *fl_cinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct pnfs_layout_segment *lseg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct pnfs_commit_array *array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) array = pnfs_find_commit_array_by_lseg(fl_cinfo, lseg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (!array) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) fl_cinfo->ops->setup_ds_info(fl_cinfo, lseg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) array = pnfs_find_commit_array_by_lseg(fl_cinfo, lseg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) pnfs_release_commit_array_locked(struct pnfs_commit_array *array)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) list_del_rcu(&array->cinfo_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) list_del(&array->lseg_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) pnfs_free_commit_array(array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) pnfs_put_commit_array_locked(struct pnfs_commit_array *array)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (refcount_dec_and_test(&array->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) pnfs_release_commit_array_locked(array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) pnfs_put_commit_array(struct pnfs_commit_array *array, struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (refcount_dec_and_lock(&array->refcount, &inode->i_lock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) pnfs_release_commit_array_locked(array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) spin_unlock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static struct pnfs_commit_array *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) pnfs_get_commit_array(struct pnfs_commit_array *array)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (refcount_inc_not_zero(&array->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) pnfs_remove_and_free_commit_array(struct pnfs_commit_array *array)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) array->lseg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) list_del_init(&array->lseg_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) pnfs_put_commit_array_locked(array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) pnfs_generic_ds_cinfo_release_lseg(struct pnfs_ds_commit_info *fl_cinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct pnfs_layout_segment *lseg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) struct pnfs_commit_array *array, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) list_for_each_entry_safe(array, tmp, &lseg->pls_commits, lseg_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) pnfs_remove_and_free_commit_array(array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) EXPORT_SYMBOL_GPL(pnfs_generic_ds_cinfo_release_lseg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) pnfs_generic_ds_cinfo_destroy(struct pnfs_ds_commit_info *fl_cinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) struct pnfs_commit_array *array, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) list_for_each_entry_safe(array, tmp, &fl_cinfo->commits, cinfo_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) pnfs_remove_and_free_commit_array(array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) EXPORT_SYMBOL_GPL(pnfs_generic_ds_cinfo_destroy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * Locks the nfs_page requests for commit and moves them to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * @bucket->committing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) pnfs_bucket_scan_ds_commit_list(struct pnfs_commit_bucket *bucket,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct nfs_commit_info *cinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) int max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct list_head *src = &bucket->written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct list_head *dst = &bucket->committing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) lockdep_assert_held(&NFS_I(cinfo->inode)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) ret = nfs_scan_commit_list(src, dst, cinfo, max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) cinfo->ds->nwritten -= ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) cinfo->ds->ncommitting += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static int pnfs_bucket_scan_array(struct nfs_commit_info *cinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct pnfs_commit_bucket *buckets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) unsigned int nbuckets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) int max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) int rv = 0, cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) for (i = 0; i < nbuckets && max != 0; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) cnt = pnfs_bucket_scan_ds_commit_list(&buckets[i], cinfo, max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) rv += cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) max -= cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /* Move reqs from written to committing lists, returning count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * of number moved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) int pnfs_generic_scan_commit_lists(struct nfs_commit_info *cinfo, int max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) struct pnfs_commit_array *array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) int rv = 0, cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) list_for_each_entry_rcu(array, &fl_cinfo->commits, cinfo_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (!array->lseg || !pnfs_get_commit_array(array))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) cnt = pnfs_bucket_scan_array(cinfo, array->buckets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) array->nbuckets, max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) pnfs_put_commit_array(array, cinfo->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) rv += cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) max -= cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (!max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) EXPORT_SYMBOL_GPL(pnfs_generic_scan_commit_lists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) pnfs_bucket_recover_commit_reqs(struct list_head *dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct pnfs_commit_bucket *buckets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) unsigned int nbuckets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) struct nfs_commit_info *cinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) struct pnfs_commit_bucket *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) struct pnfs_layout_segment *freeme;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) unsigned int nwritten, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) restart:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) for (i = 0, b = buckets; i < nbuckets; i++, b++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) nwritten = nfs_scan_commit_list(&b->written, dst, cinfo, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (!nwritten)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) ret += nwritten;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) freeme = pnfs_free_bucket_lseg(b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (freeme) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) pnfs_put_lseg(freeme);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) goto restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /* Pull everything off the committing lists and dump into @dst. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) void pnfs_generic_recover_commit_reqs(struct list_head *dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct nfs_commit_info *cinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct pnfs_commit_array *array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) unsigned int nwritten;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) lockdep_assert_held(&NFS_I(cinfo->inode)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) list_for_each_entry_rcu(array, &fl_cinfo->commits, cinfo_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (!array->lseg || !pnfs_get_commit_array(array))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) nwritten = pnfs_bucket_recover_commit_reqs(dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) array->buckets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) array->nbuckets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) cinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) pnfs_put_commit_array(array, cinfo->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) fl_cinfo->nwritten -= nwritten;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) EXPORT_SYMBOL_GPL(pnfs_generic_recover_commit_reqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static struct nfs_page *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) pnfs_bucket_search_commit_reqs(struct pnfs_commit_bucket *buckets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) unsigned int nbuckets, struct page *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) struct nfs_page *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) struct pnfs_commit_bucket *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* Linearly search the commit lists for each bucket until a matching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * request is found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) for (i = 0, b = buckets; i < nbuckets; i++, b++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) list_for_each_entry(req, &b->written, wb_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (req->wb_page == page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return req->wb_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) list_for_each_entry(req, &b->committing, wb_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (req->wb_page == page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return req->wb_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /* pnfs_generic_search_commit_reqs - Search lists in @cinfo for the head reqest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * for @page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * @cinfo - commit info for current inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * @page - page to search for matching head request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * Returns a the head request if one is found, otherwise returns NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) struct nfs_page *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) pnfs_generic_search_commit_reqs(struct nfs_commit_info *cinfo, struct page *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) struct pnfs_commit_array *array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) struct nfs_page *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) list_for_each_entry(array, &fl_cinfo->commits, cinfo_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) req = pnfs_bucket_search_commit_reqs(array->buckets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) array->nbuckets, page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) return req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) EXPORT_SYMBOL_GPL(pnfs_generic_search_commit_reqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) static struct pnfs_layout_segment *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) pnfs_bucket_get_committing(struct list_head *head,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) struct pnfs_commit_bucket *bucket,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct nfs_commit_info *cinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct pnfs_layout_segment *lseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct list_head *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) list_for_each(pos, &bucket->committing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) cinfo->ds->ncommitting--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) list_splice_init(&bucket->committing, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) lseg = pnfs_free_bucket_lseg(bucket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (!lseg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) lseg = pnfs_get_lseg(bucket->lseg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return lseg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static struct nfs_commit_data *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) pnfs_bucket_fetch_commitdata(struct pnfs_commit_bucket *bucket,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct nfs_commit_info *cinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) struct nfs_commit_data *data = nfs_commitdata_alloc(false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) data->lseg = pnfs_bucket_get_committing(&data->pages, bucket, cinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static void pnfs_generic_retry_commit(struct pnfs_commit_bucket *buckets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) unsigned int nbuckets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) struct nfs_commit_info *cinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) unsigned int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) struct pnfs_commit_bucket *bucket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct pnfs_layout_segment *freeme;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) LIST_HEAD(pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) for (bucket = buckets; idx < nbuckets; bucket++, idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (list_empty(&bucket->committing))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) mutex_lock(&NFS_I(cinfo->inode)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) freeme = pnfs_bucket_get_committing(&pages, bucket, cinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) nfs_retry_commit(&pages, freeme, cinfo, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) pnfs_put_lseg(freeme);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) static unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) pnfs_bucket_alloc_ds_commits(struct list_head *list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) struct pnfs_commit_bucket *buckets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) unsigned int nbuckets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) struct nfs_commit_info *cinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) struct pnfs_commit_bucket *bucket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) struct nfs_commit_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) unsigned int nreq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) for (i = 0, bucket = buckets; i < nbuckets; i++, bucket++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (list_empty(&bucket->committing))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) mutex_lock(&NFS_I(cinfo->inode)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (!list_empty(&bucket->committing)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) data = pnfs_bucket_fetch_commitdata(bucket, cinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) goto out_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) data->ds_commit_index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) list_add_tail(&data->list, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) nreq++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) return nreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) out_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) /* Clean up on error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) pnfs_generic_retry_commit(buckets, nbuckets, cinfo, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return nreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) static unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) pnfs_alloc_ds_commits_list(struct list_head *list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) struct pnfs_ds_commit_info *fl_cinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct nfs_commit_info *cinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct pnfs_commit_array *array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) unsigned int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) list_for_each_entry_rcu(array, &fl_cinfo->commits, cinfo_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (!array->lseg || !pnfs_get_commit_array(array))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) ret += pnfs_bucket_alloc_ds_commits(list, array->buckets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) array->nbuckets, cinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) pnfs_put_commit_array(array, cinfo->inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) /* This follows nfs_commit_list pretty closely */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) pnfs_generic_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) int how, struct nfs_commit_info *cinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) int (*initiate_commit)(struct nfs_commit_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) int how))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct nfs_commit_data *data, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) LIST_HEAD(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) unsigned int nreq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (!list_empty(mds_pages)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) data = nfs_commitdata_alloc(true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) data->ds_commit_index = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) list_splice_init(mds_pages, &data->pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) list_add_tail(&data->list, &list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) nreq++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) nreq += pnfs_alloc_ds_commits_list(&list, fl_cinfo, cinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (nreq == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) list_for_each_entry_safe(data, tmp, &list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) list_del(&data->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (data->ds_commit_index < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) nfs_init_commit(data, NULL, NULL, cinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) nfs_initiate_commit(NFS_CLIENT(inode), data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) NFS_PROTO(data->inode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) data->mds_ops, how,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) RPC_TASK_CRED_NOREF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) nfs_init_commit(data, NULL, data->lseg, cinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) initiate_commit(data, how);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) return PNFS_ATTEMPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) EXPORT_SYMBOL_GPL(pnfs_generic_commit_pagelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) * Data server cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * Data servers can be mapped to different device ids.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * nfs4_pnfs_ds reference counting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * - set to 1 on allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) * - incremented when a device id maps a data server already in the cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) * - decremented when deviceid is removed from the cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) static DEFINE_SPINLOCK(nfs4_ds_cache_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) static LIST_HEAD(nfs4_data_server_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) /* Debug routines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) print_ds(struct nfs4_pnfs_ds *ds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (ds == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) printk(KERN_WARNING "%s NULL device\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) printk(KERN_WARNING " ds %s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) " ref count %d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) " client %p\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) " cl_exchange_flags %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) ds->ds_remotestr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) refcount_read(&ds->ds_count), ds->ds_clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) ds->ds_clp ? ds->ds_clp->cl_exchange_flags : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) same_sockaddr(struct sockaddr *addr1, struct sockaddr *addr2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct sockaddr_in *a, *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) struct sockaddr_in6 *a6, *b6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (addr1->sa_family != addr2->sa_family)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) switch (addr1->sa_family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) a = (struct sockaddr_in *)addr1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) b = (struct sockaddr_in *)addr2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (a->sin_addr.s_addr == b->sin_addr.s_addr &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) a->sin_port == b->sin_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) a6 = (struct sockaddr_in6 *)addr1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) b6 = (struct sockaddr_in6 *)addr2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) /* LINKLOCAL addresses must have matching scope_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) if (ipv6_addr_src_scope(&a6->sin6_addr) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) IPV6_ADDR_SCOPE_LINKLOCAL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) a6->sin6_scope_id != b6->sin6_scope_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (ipv6_addr_equal(&a6->sin6_addr, &b6->sin6_addr) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) a6->sin6_port == b6->sin6_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) dprintk("%s: unhandled address family: %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) __func__, addr1->sa_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * Checks if 'dsaddrs1' contains a subset of 'dsaddrs2'. If it does,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * declare a match.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) _same_data_server_addrs_locked(const struct list_head *dsaddrs1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) const struct list_head *dsaddrs2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) struct nfs4_pnfs_ds_addr *da1, *da2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) struct sockaddr *sa1, *sa2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) bool match = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) list_for_each_entry(da1, dsaddrs1, da_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) sa1 = (struct sockaddr *)&da1->da_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) match = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) list_for_each_entry(da2, dsaddrs2, da_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) sa2 = (struct sockaddr *)&da2->da_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) match = same_sockaddr(sa1, sa2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (!match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) return match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * Lookup DS by addresses. nfs4_ds_cache_lock is held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) static struct nfs4_pnfs_ds *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) _data_server_lookup_locked(const struct list_head *dsaddrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) struct nfs4_pnfs_ds *ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) list_for_each_entry(ds, &nfs4_data_server_cache, ds_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (_same_data_server_addrs_locked(&ds->ds_addrs, dsaddrs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) static void destroy_ds(struct nfs4_pnfs_ds *ds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct nfs4_pnfs_ds_addr *da;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) dprintk("--> %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) ifdebug(FACILITY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) print_ds(ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) nfs_put_client(ds->ds_clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) while (!list_empty(&ds->ds_addrs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) da = list_first_entry(&ds->ds_addrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) struct nfs4_pnfs_ds_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) da_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) list_del_init(&da->da_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) kfree(da->da_remotestr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) kfree(da);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) kfree(ds->ds_remotestr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) kfree(ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) void nfs4_pnfs_ds_put(struct nfs4_pnfs_ds *ds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (refcount_dec_and_lock(&ds->ds_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) &nfs4_ds_cache_lock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) list_del_init(&ds->ds_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) spin_unlock(&nfs4_ds_cache_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) destroy_ds(ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) EXPORT_SYMBOL_GPL(nfs4_pnfs_ds_put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * Create a string with a human readable address and port to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * complicated setup around many dprinks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) static char *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) nfs4_pnfs_remotestr(struct list_head *dsaddrs, gfp_t gfp_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) struct nfs4_pnfs_ds_addr *da;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) char *remotestr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) len = 3; /* '{', '}' and eol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) list_for_each_entry(da, dsaddrs, da_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) len += strlen(da->da_remotestr) + 1; /* string plus comma */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) remotestr = kzalloc(len, gfp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (!remotestr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) p = remotestr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) *(p++) = '{';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) list_for_each_entry(da, dsaddrs, da_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) size_t ll = strlen(da->da_remotestr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) if (ll > len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) memcpy(p, da->da_remotestr, ll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) p += ll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) len -= ll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (len < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) (*p++) = ',';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (len < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) *(p++) = '}';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) *p = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) return remotestr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) kfree(remotestr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * Given a list of multipath struct nfs4_pnfs_ds_addr, add it to ds cache if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * uncached and return cached struct nfs4_pnfs_ds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) struct nfs4_pnfs_ds *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) nfs4_pnfs_ds_add(struct list_head *dsaddrs, gfp_t gfp_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) struct nfs4_pnfs_ds *tmp_ds, *ds = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) char *remotestr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (list_empty(dsaddrs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) dprintk("%s: no addresses defined\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) ds = kzalloc(sizeof(*ds), gfp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (!ds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) /* this is only used for debugging, so it's ok if its NULL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) remotestr = nfs4_pnfs_remotestr(dsaddrs, gfp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) spin_lock(&nfs4_ds_cache_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) tmp_ds = _data_server_lookup_locked(dsaddrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (tmp_ds == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) INIT_LIST_HEAD(&ds->ds_addrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) list_splice_init(dsaddrs, &ds->ds_addrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) ds->ds_remotestr = remotestr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) refcount_set(&ds->ds_count, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) INIT_LIST_HEAD(&ds->ds_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) ds->ds_clp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) list_add(&ds->ds_node, &nfs4_data_server_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) dprintk("%s add new data server %s\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) ds->ds_remotestr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) kfree(remotestr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) kfree(ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) refcount_inc(&tmp_ds->ds_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) dprintk("%s data server %s found, inc'ed ds_count to %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) __func__, tmp_ds->ds_remotestr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) refcount_read(&tmp_ds->ds_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) ds = tmp_ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) spin_unlock(&nfs4_ds_cache_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) return ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) EXPORT_SYMBOL_GPL(nfs4_pnfs_ds_add);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) static int nfs4_wait_ds_connect(struct nfs4_pnfs_ds *ds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) might_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) return wait_on_bit(&ds->ds_state, NFS4DS_CONNECTING, TASK_KILLABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) static void nfs4_clear_ds_conn_bit(struct nfs4_pnfs_ds *ds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) smp_mb__before_atomic();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) clear_and_wake_up_bit(NFS4DS_CONNECTING, &ds->ds_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) static struct nfs_client *(*get_v3_ds_connect)(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) struct nfs_server *mds_srv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) const struct sockaddr *ds_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) int ds_addrlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) int ds_proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) unsigned int ds_timeo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) unsigned int ds_retrans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) static bool load_v3_ds_connect(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (!get_v3_ds_connect) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) get_v3_ds_connect = symbol_request(nfs3_set_ds_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) WARN_ON_ONCE(!get_v3_ds_connect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) return(get_v3_ds_connect != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) void nfs4_pnfs_v3_ds_connect_unload(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (get_v3_ds_connect) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) symbol_put(nfs3_set_ds_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) get_v3_ds_connect = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) static int _nfs4_pnfs_v3_ds_connect(struct nfs_server *mds_srv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) struct nfs4_pnfs_ds *ds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) unsigned int timeo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) unsigned int retrans)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) struct nfs_client *clp = ERR_PTR(-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) struct nfs4_pnfs_ds_addr *da;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) dprintk("--> %s DS %s\n", __func__, ds->ds_remotestr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (!load_v3_ds_connect())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) list_for_each_entry(da, &ds->ds_addrs, da_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) dprintk("%s: DS %s: trying address %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) __func__, ds->ds_remotestr, da->da_remotestr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (!IS_ERR(clp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) struct xprt_create xprt_args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) .ident = XPRT_TRANSPORT_TCP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) .net = clp->cl_net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) .dstaddr = (struct sockaddr *)&da->da_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) .addrlen = da->da_addrlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) .servername = clp->cl_hostname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) /* Add this address as an alias */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) rpc_clnt_test_and_add_xprt, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) clp = get_v3_ds_connect(mds_srv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) (struct sockaddr *)&da->da_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) da->da_addrlen, IPPROTO_TCP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) timeo, retrans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (IS_ERR(clp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) clp->cl_rpcclient->cl_softerr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) clp->cl_rpcclient->cl_softrtry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (IS_ERR(clp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) status = PTR_ERR(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) smp_wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) WRITE_ONCE(ds->ds_clp, clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) dprintk("%s [new] addr: %s\n", __func__, ds->ds_remotestr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) struct nfs4_pnfs_ds *ds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) unsigned int timeo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) unsigned int retrans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) u32 minor_version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) struct nfs_client *clp = ERR_PTR(-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) struct nfs4_pnfs_ds_addr *da;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) dprintk("--> %s DS %s\n", __func__, ds->ds_remotestr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) list_for_each_entry(da, &ds->ds_addrs, da_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) dprintk("%s: DS %s: trying address %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) __func__, ds->ds_remotestr, da->da_remotestr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (!IS_ERR(clp) && clp->cl_mvops->session_trunk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) struct xprt_create xprt_args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) .ident = XPRT_TRANSPORT_TCP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) .net = clp->cl_net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) .dstaddr = (struct sockaddr *)&da->da_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) .addrlen = da->da_addrlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) .servername = clp->cl_hostname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) struct nfs4_add_xprt_data xprtdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) .clp = clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) .cred = nfs4_get_clid_cred(clp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) struct rpc_add_xprt_test rpcdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) .add_xprt_test = clp->cl_mvops->session_trunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) .data = &xprtdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) * Test this address for session trunking and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) * add as an alias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) rpc_clnt_setup_test_and_add_xprt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) &rpcdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (xprtdata.cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) put_cred(xprtdata.cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) clp = nfs4_set_ds_client(mds_srv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) (struct sockaddr *)&da->da_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) da->da_addrlen, IPPROTO_TCP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) timeo, retrans, minor_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (IS_ERR(clp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) status = nfs4_init_ds_session(clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) mds_srv->nfs_client->cl_lease_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) nfs_put_client(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) clp = ERR_PTR(-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (IS_ERR(clp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) status = PTR_ERR(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) smp_wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) WRITE_ONCE(ds->ds_clp, clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) dprintk("%s [new] addr: %s\n", __func__, ds->ds_remotestr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) * Create an rpc connection to the nfs4_pnfs_ds data server.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) * Currently only supports IPv4 and IPv6 addresses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) * If connection fails, make devid unavailable and return a -errno.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) int nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) struct nfs4_deviceid_node *devid, unsigned int timeo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) unsigned int retrans, u32 version, u32 minor_version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) err = nfs4_wait_ds_connect(ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (err || ds->ds_clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (nfs4_test_deviceid_unavailable(devid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) } while (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) if (ds->ds_clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) goto connect_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) switch (version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) err = _nfs4_pnfs_v3_ds_connect(mds_srv, ds, timeo, retrans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) err = _nfs4_pnfs_v4_ds_connect(mds_srv, ds, timeo, retrans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) minor_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) dprintk("%s: unsupported DS version %d\n", __func__, version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) err = -EPROTONOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) connect_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) nfs4_clear_ds_conn_bit(ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) * At this point the ds->ds_clp should be ready, but it might have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) * hit an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) if (!ds->ds_clp || !nfs_client_init_is_complete(ds->ds_clp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) WARN_ON_ONCE(ds->ds_clp ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) !nfs4_test_deviceid_unavailable(devid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) err = nfs_client_init_status(ds->ds_clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) EXPORT_SYMBOL_GPL(nfs4_pnfs_ds_connect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) * Currently only supports ipv4, ipv6 and one multi-path address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) struct nfs4_pnfs_ds_addr *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) nfs4_decode_mp_ds_addr(struct net *net, struct xdr_stream *xdr, gfp_t gfp_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) struct nfs4_pnfs_ds_addr *da = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) char *buf, *portstr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) __be16 port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) int nlen, rlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) int tmp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) __be32 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) char *netid, *match_netid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) size_t len, match_netid_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) char *startsep = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) char *endsep = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) /* r_netid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) p = xdr_inline_decode(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if (unlikely(!p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) nlen = be32_to_cpup(p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) p = xdr_inline_decode(xdr, nlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (unlikely(!p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) netid = kmalloc(nlen+1, gfp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) if (unlikely(!netid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) netid[nlen] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) memcpy(netid, p, nlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) /* r_addr: ip/ip6addr with port in dec octets - see RFC 5665 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) p = xdr_inline_decode(xdr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (unlikely(!p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) goto out_free_netid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) rlen = be32_to_cpup(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) p = xdr_inline_decode(xdr, rlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) if (unlikely(!p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) goto out_free_netid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) /* port is ".ABC.DEF", 8 chars max */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (rlen > INET6_ADDRSTRLEN + IPV6_SCOPE_ID_LEN + 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) dprintk("%s: Invalid address, length %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) rlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) goto out_free_netid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) buf = kmalloc(rlen + 1, gfp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) if (!buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) dprintk("%s: Not enough memory\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) goto out_free_netid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) buf[rlen] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) memcpy(buf, p, rlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) /* replace port '.' with '-' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) portstr = strrchr(buf, '.');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (!portstr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) dprintk("%s: Failed finding expected dot in port\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) goto out_free_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) *portstr = '-';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) /* find '.' between address and port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) portstr = strrchr(buf, '.');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) if (!portstr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) dprintk("%s: Failed finding expected dot between address and "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) "port\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) goto out_free_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) *portstr = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) da = kzalloc(sizeof(*da), gfp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) if (unlikely(!da))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) goto out_free_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) INIT_LIST_HEAD(&da->da_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (!rpc_pton(net, buf, portstr-buf, (struct sockaddr *)&da->da_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) sizeof(da->da_addr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) dprintk("%s: error parsing address %s\n", __func__, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) goto out_free_da;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) portstr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) sscanf(portstr, "%d-%d", &tmp[0], &tmp[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) port = htons((tmp[0] << 8) | (tmp[1]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) switch (da->da_addr.ss_family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) ((struct sockaddr_in *)&da->da_addr)->sin_port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) da->da_addrlen = sizeof(struct sockaddr_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) match_netid = "tcp";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) match_netid_len = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) ((struct sockaddr_in6 *)&da->da_addr)->sin6_port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) da->da_addrlen = sizeof(struct sockaddr_in6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) match_netid = "tcp6";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) match_netid_len = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) startsep = "[";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) endsep = "]";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) dprintk("%s: unsupported address family: %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) __func__, da->da_addr.ss_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) goto out_free_da;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) if (nlen != match_netid_len || strncmp(netid, match_netid, nlen)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) dprintk("%s: ERROR: r_netid \"%s\" != \"%s\"\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) __func__, netid, match_netid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) goto out_free_da;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) /* save human readable address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) len = strlen(startsep) + strlen(buf) + strlen(endsep) + 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) da->da_remotestr = kzalloc(len, gfp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) /* NULL is ok, only used for dprintk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) if (da->da_remotestr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) snprintf(da->da_remotestr, len, "%s%s%s:%u", startsep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) buf, endsep, ntohs(port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) dprintk("%s: Parsed DS addr %s\n", __func__, da->da_remotestr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) kfree(netid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) return da;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) out_free_da:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) kfree(da);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) out_free_buf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) dprintk("%s: Error parsing DS addr: %s\n", __func__, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) out_free_netid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) kfree(netid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) EXPORT_SYMBOL_GPL(nfs4_decode_mp_ds_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) pnfs_layout_mark_request_commit(struct nfs_page *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) struct pnfs_layout_segment *lseg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) struct nfs_commit_info *cinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) u32 ds_commit_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) struct list_head *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) struct pnfs_commit_array *array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) struct pnfs_commit_bucket *bucket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) mutex_lock(&NFS_I(cinfo->inode)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) array = pnfs_lookup_commit_array(cinfo->ds, lseg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) if (!array || !pnfs_is_valid_lseg(lseg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) goto out_resched;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) bucket = &array->buckets[ds_commit_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) list = &bucket->written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) /* Non-empty buckets hold a reference on the lseg. That ref
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) * is normally transferred to the COMMIT call and released
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) * there. It could also be released if the last req is pulled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) * off due to a rewrite, in which case it will be done in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) * pnfs_common_clear_request_commit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if (!bucket->lseg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) bucket->lseg = pnfs_get_lseg(lseg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) set_bit(PG_COMMIT_TO_DS, &req->wb_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) cinfo->ds->nwritten++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) nfs_request_add_commit_list_locked(req, list, cinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) nfs_mark_page_unstable(req->wb_page, cinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) out_resched:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) cinfo->completion_ops->resched_write(cinfo, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) EXPORT_SYMBOL_GPL(pnfs_layout_mark_request_commit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) pnfs_nfs_generic_sync(struct inode *inode, bool datasync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) if (!pnfs_layoutcommit_outstanding(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) ret = nfs_commit_inode(inode, FLUSH_SYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) if (datasync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) return pnfs_layoutcommit_inode(inode, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) EXPORT_SYMBOL_GPL(pnfs_nfs_generic_sync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)