hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/nfs/filelayout/filelayout.c
....@@ -49,6 +49,7 @@
4949 MODULE_DESCRIPTION("The NFSv4 file layout driver");
5050
5151 #define FILELAYOUT_POLL_RETRY_MAX (15*HZ)
52
+static const struct pnfs_commit_ops filelayout_commit_ops;
5253
5354 static loff_t
5455 filelayout_get_dense_offset(struct nfs4_filelayout_segment *flseg,
....@@ -186,7 +187,7 @@
186187 pnfs_error_mark_layout_for_return(inode, lseg);
187188 pnfs_set_lo_fail(lseg);
188189 rpc_wake_up(&tbl->slot_tbl_waitq);
189
- /* fall through */
190
+ fallthrough;
190191 default:
191192 reset:
192193 dprintk("%s Retry through MDS. Error %d\n", __func__,
....@@ -750,70 +751,15 @@
750751 /* This assumes a single RW lseg */
751752 if (lseg->pls_range.iomode == IOMODE_RW) {
752753 struct nfs4_filelayout *flo;
754
+ struct inode *inode;
753755
754756 flo = FILELAYOUT_FROM_HDR(lseg->pls_layout);
755
- flo->commit_info.nbuckets = 0;
756
- kfree(flo->commit_info.buckets);
757
- flo->commit_info.buckets = NULL;
757
+ inode = flo->generic_hdr.plh_inode;
758
+ spin_lock(&inode->i_lock);
759
+ pnfs_generic_ds_cinfo_release_lseg(&flo->commit_info, lseg);
760
+ spin_unlock(&inode->i_lock);
758761 }
759762 _filelayout_free_lseg(fl);
760
-}
761
-
762
-static int
763
-filelayout_alloc_commit_info(struct pnfs_layout_segment *lseg,
764
- struct nfs_commit_info *cinfo,
765
- gfp_t gfp_flags)
766
-{
767
- struct nfs4_filelayout_segment *fl = FILELAYOUT_LSEG(lseg);
768
- struct pnfs_commit_bucket *buckets;
769
- int size, i;
770
-
771
- if (fl->commit_through_mds)
772
- return 0;
773
-
774
- size = (fl->stripe_type == STRIPE_SPARSE) ?
775
- fl->dsaddr->ds_num : fl->dsaddr->stripe_count;
776
-
777
- if (cinfo->ds->nbuckets >= size) {
778
- /* This assumes there is only one IOMODE_RW lseg. What
779
- * we really want to do is have a layout_hdr level
780
- * dictionary of <multipath_list4, fh> keys, each
781
- * associated with a struct list_head, populated by calls
782
- * to filelayout_write_pagelist().
783
- * */
784
- return 0;
785
- }
786
-
787
- buckets = kcalloc(size, sizeof(struct pnfs_commit_bucket),
788
- gfp_flags);
789
- if (!buckets)
790
- return -ENOMEM;
791
- for (i = 0; i < size; i++) {
792
- INIT_LIST_HEAD(&buckets[i].written);
793
- INIT_LIST_HEAD(&buckets[i].committing);
794
- /* mark direct verifier as unset */
795
- buckets[i].direct_verf.committed = NFS_INVALID_STABLE_HOW;
796
- }
797
-
798
- spin_lock(&cinfo->inode->i_lock);
799
- if (cinfo->ds->nbuckets >= size)
800
- goto out;
801
- for (i = 0; i < cinfo->ds->nbuckets; i++) {
802
- list_splice(&cinfo->ds->buckets[i].written,
803
- &buckets[i].written);
804
- list_splice(&cinfo->ds->buckets[i].committing,
805
- &buckets[i].committing);
806
- buckets[i].direct_verf.committed =
807
- cinfo->ds->buckets[i].direct_verf.committed;
808
- buckets[i].wlseg = cinfo->ds->buckets[i].wlseg;
809
- buckets[i].clseg = cinfo->ds->buckets[i].clseg;
810
- }
811
- swap(cinfo->ds->buckets, buckets);
812
- cinfo->ds->nbuckets = size;
813
-out:
814
- spin_unlock(&cinfo->inode->i_lock);
815
- kfree(buckets);
816
- return 0;
817763 }
818764
819765 static struct pnfs_layout_segment *
....@@ -837,6 +783,12 @@
837783 return &fl->generic_hdr;
838784 }
839785
786
+static bool
787
+filelayout_lseg_is_striped(const struct nfs4_filelayout_segment *flseg)
788
+{
789
+ return flseg->num_fh > 1;
790
+}
791
+
840792 /*
841793 * filelayout_pg_test(). Called by nfs_can_coalesce_requests()
842794 *
....@@ -857,6 +809,8 @@
857809 size = pnfs_generic_pg_test(pgio, prev, req);
858810 if (!size)
859811 return 0;
812
+ else if (!filelayout_lseg_is_striped(FILELAYOUT_LSEG(pgio->pg_lseg)))
813
+ return size;
860814
861815 /* see if req and prev are in the same stripe */
862816 if (prev) {
....@@ -917,7 +871,7 @@
917871 pnfs_generic_pg_check_layout(pgio);
918872 if (!pgio->pg_lseg) {
919873 pgio->pg_lseg = fl_pnfs_update_layout(pgio->pg_inode,
920
- req->wb_context,
874
+ nfs_req_openctx(req),
921875 0,
922876 NFS4_MAX_UINT64,
923877 IOMODE_READ,
....@@ -938,13 +892,10 @@
938892 filelayout_pg_init_write(struct nfs_pageio_descriptor *pgio,
939893 struct nfs_page *req)
940894 {
941
- struct nfs_commit_info cinfo;
942
- int status;
943
-
944895 pnfs_generic_pg_check_layout(pgio);
945896 if (!pgio->pg_lseg) {
946897 pgio->pg_lseg = fl_pnfs_update_layout(pgio->pg_inode,
947
- req->wb_context,
898
+ nfs_req_openctx(req),
948899 0,
949900 NFS4_MAX_UINT64,
950901 IOMODE_RW,
....@@ -959,17 +910,7 @@
959910
960911 /* If no lseg, fall back to write through mds */
961912 if (pgio->pg_lseg == NULL)
962
- goto out_mds;
963
- nfs_init_cinfo(&cinfo, pgio->pg_inode, pgio->pg_dreq);
964
- status = filelayout_alloc_commit_info(pgio->pg_lseg, &cinfo, GFP_NOFS);
965
- if (status < 0) {
966
- pnfs_put_lseg(pgio->pg_lseg);
967
- pgio->pg_lseg = NULL;
968
- goto out_mds;
969
- }
970
- return;
971
-out_mds:
972
- nfs_pageio_reset_write_mds(pgio);
913
+ nfs_pageio_reset_write_mds(pgio);
973914 }
974915
975916 static const struct nfs_pageio_ops filelayout_pg_read_ops = {
....@@ -1078,36 +1019,6 @@
10781019 return -EAGAIN;
10791020 }
10801021
1081
-/* filelayout_search_commit_reqs - Search lists in @cinfo for the head reqest
1082
- * for @page
1083
- * @cinfo - commit info for current inode
1084
- * @page - page to search for matching head request
1085
- *
1086
- * Returns a the head request if one is found, otherwise returns NULL.
1087
- */
1088
-static struct nfs_page *
1089
-filelayout_search_commit_reqs(struct nfs_commit_info *cinfo, struct page *page)
1090
-{
1091
- struct nfs_page *freq, *t;
1092
- struct pnfs_commit_bucket *b;
1093
- int i;
1094
-
1095
- /* Linearly search the commit lists for each bucket until a matching
1096
- * request is found */
1097
- for (i = 0, b = cinfo->ds->buckets; i < cinfo->ds->nbuckets; i++, b++) {
1098
- list_for_each_entry_safe(freq, t, &b->written, wb_list) {
1099
- if (freq->wb_page == page)
1100
- return freq->wb_head;
1101
- }
1102
- list_for_each_entry_safe(freq, t, &b->committing, wb_list) {
1103
- if (freq->wb_page == page)
1104
- return freq->wb_head;
1105
- }
1106
- }
1107
-
1108
- return NULL;
1109
-}
1110
-
11111022 static int
11121023 filelayout_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
11131024 int how, struct nfs_commit_info *cinfo)
....@@ -1140,13 +1051,17 @@
11401051 struct nfs4_filelayout *flo;
11411052
11421053 flo = kzalloc(sizeof(*flo), gfp_flags);
1143
- return flo != NULL ? &flo->generic_hdr : NULL;
1054
+ if (flo == NULL)
1055
+ return NULL;
1056
+ pnfs_init_ds_commit_info(&flo->commit_info);
1057
+ flo->commit_info.ops = &filelayout_commit_ops;
1058
+ return &flo->generic_hdr;
11441059 }
11451060
11461061 static void
11471062 filelayout_free_layout_hdr(struct pnfs_layout_hdr *lo)
11481063 {
1149
- kfree(FILELAYOUT_FROM_HDR(lo));
1064
+ kfree_rcu(FILELAYOUT_FROM_HDR(lo), generic_hdr.plh_rcu);
11501065 }
11511066
11521067 static struct pnfs_ds_commit_info *
....@@ -1160,10 +1075,52 @@
11601075 return &FILELAYOUT_FROM_HDR(layout)->commit_info;
11611076 }
11621077
1078
+static void
1079
+filelayout_setup_ds_info(struct pnfs_ds_commit_info *fl_cinfo,
1080
+ struct pnfs_layout_segment *lseg)
1081
+{
1082
+ struct nfs4_filelayout_segment *fl = FILELAYOUT_LSEG(lseg);
1083
+ struct inode *inode = lseg->pls_layout->plh_inode;
1084
+ struct pnfs_commit_array *array, *new;
1085
+ unsigned int size = (fl->stripe_type == STRIPE_SPARSE) ?
1086
+ fl->dsaddr->ds_num : fl->dsaddr->stripe_count;
1087
+
1088
+ new = pnfs_alloc_commit_array(size, GFP_NOIO);
1089
+ if (new) {
1090
+ spin_lock(&inode->i_lock);
1091
+ array = pnfs_add_commit_array(fl_cinfo, new, lseg);
1092
+ spin_unlock(&inode->i_lock);
1093
+ if (array != new)
1094
+ pnfs_free_commit_array(new);
1095
+ }
1096
+}
1097
+
1098
+static void
1099
+filelayout_release_ds_info(struct pnfs_ds_commit_info *fl_cinfo,
1100
+ struct inode *inode)
1101
+{
1102
+ spin_lock(&inode->i_lock);
1103
+ pnfs_generic_ds_cinfo_destroy(fl_cinfo);
1104
+ spin_unlock(&inode->i_lock);
1105
+}
1106
+
1107
+static const struct pnfs_commit_ops filelayout_commit_ops = {
1108
+ .setup_ds_info = filelayout_setup_ds_info,
1109
+ .release_ds_info = filelayout_release_ds_info,
1110
+ .mark_request_commit = filelayout_mark_request_commit,
1111
+ .clear_request_commit = pnfs_generic_clear_request_commit,
1112
+ .scan_commit_lists = pnfs_generic_scan_commit_lists,
1113
+ .recover_commit_reqs = pnfs_generic_recover_commit_reqs,
1114
+ .search_commit_reqs = pnfs_generic_search_commit_reqs,
1115
+ .commit_pagelist = filelayout_commit_pagelist,
1116
+};
1117
+
11631118 static struct pnfs_layoutdriver_type filelayout_type = {
11641119 .id = LAYOUT_NFSV4_1_FILES,
11651120 .name = "LAYOUT_NFSV4_1_FILES",
11661121 .owner = THIS_MODULE,
1122
+ .flags = PNFS_LAYOUTGET_ON_OPEN,
1123
+ .max_layoutget_response = 4096, /* 1 page or so... */
11671124 .alloc_layout_hdr = filelayout_alloc_layout_hdr,
11681125 .free_layout_hdr = filelayout_free_layout_hdr,
11691126 .alloc_lseg = filelayout_alloc_lseg,
....@@ -1171,12 +1128,6 @@
11711128 .pg_read_ops = &filelayout_pg_read_ops,
11721129 .pg_write_ops = &filelayout_pg_write_ops,
11731130 .get_ds_info = &filelayout_get_ds_info,
1174
- .mark_request_commit = filelayout_mark_request_commit,
1175
- .clear_request_commit = pnfs_generic_clear_request_commit,
1176
- .scan_commit_lists = pnfs_generic_scan_commit_lists,
1177
- .recover_commit_reqs = pnfs_generic_recover_commit_reqs,
1178
- .search_commit_reqs = filelayout_search_commit_reqs,
1179
- .commit_pagelist = filelayout_commit_pagelist,
11801131 .read_pagelist = filelayout_read_pagelist,
11811132 .write_pagelist = filelayout_write_pagelist,
11821133 .alloc_deviceid_node = filelayout_alloc_deviceid_node,