1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2004 Cluster File Systems, Inc.
6 * This file is part of Lustre, http://www.lustre.org.
8 * Lustre is free software; you can redistribute it and/or
9 * modify it under the terms of version 2 of the GNU General Public
10 * License as published by the Free Software Foundation.
12 * Lustre is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Lustre; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 * LIB functions follow
29 klonal_dist(lib_nal_t *nal, ptl_nid_t nid, unsigned long *dist)
31 *dist = 0; /* it's me */
36 klonal_send (lib_nal_t *nal,
43 unsigned int payload_niov,
44 struct iovec *payload_iov,
45 size_t payload_offset,
49 .klod_type = KLOD_IOV,
50 .klod_niov = payload_niov,
51 .klod_offset = payload_offset,
52 .klod_nob = payload_nob,
53 .klod_iov = { .iov = payload_iov } };
56 LASSERT(nid == klonal_lib.libnal_ni.ni_pid.nid);
58 rc = lib_parse(&klonal_lib, hdr, &klod);
60 lib_finalize(&klonal_lib, private, libmsg, PTL_OK);
66 klonal_send_pages (lib_nal_t *nal,
73 unsigned int payload_niov,
74 ptl_kiov_t *payload_kiov,
75 size_t payload_offset,
79 .klod_type = KLOD_KIOV,
80 .klod_niov = payload_niov,
81 .klod_offset = payload_offset,
82 .klod_nob = payload_nob,
83 .klod_iov = { .kiov = payload_kiov } };
86 LASSERT(nid == klonal_lib.libnal_ni.ni_pid.nid);
88 rc = lib_parse(&klonal_lib, hdr, &klod);
90 lib_finalize(&klonal_lib, private, libmsg, PTL_OK);
96 klonal_recv(lib_nal_t *nal,
105 klo_desc_t *klod = (klo_desc_t *)private;
107 /* I only handle mapped->mapped matches */
108 LASSERT(klod->klod_type == KLOD_IOV);
113 while (offset >= iov->iov_len) {
114 offset -= iov->iov_len;
120 while (klod->klod_offset >= klod->klod_iov.iov->iov_len) {
121 klod->klod_offset -= klod->klod_iov.iov->iov_len;
122 klod->klod_iov.iov++;
124 LASSERT(klod->klod_niov > 0);
128 int fraglen = MIN(iov->iov_len - offset,
129 klod->klod_iov.iov->iov_len - klod->klod_offset);
132 LASSERT(klod->klod_niov > 0);
137 memcpy((void *)((unsigned long)iov->iov_base + offset),
138 (void *)((unsigned long)klod->klod_iov.iov->iov_base +
142 if (offset + fraglen < iov->iov_len) {
150 if (klod->klod_offset + fraglen < klod->klod_iov.iov->iov_len ) {
151 klod->klod_offset += fraglen;
153 klod->klod_offset = 0;
154 klod->klod_iov.iov++;
161 lib_finalize(&klonal_lib, private, libmsg, PTL_OK);
166 klonal_recv_pages(lib_nal_t *nal,
175 void *srcaddr = NULL;
176 void *dstaddr = NULL;
177 unsigned long srcfrag = 0;
178 unsigned long dstfrag = 0;
179 unsigned long fraglen;
180 klo_desc_t *klod = (klo_desc_t *)private;
182 /* I only handle unmapped->unmapped matches */
183 LASSERT(klod->klod_type == KLOD_KIOV);
188 while (offset >= kiov->kiov_len) {
189 offset -= kiov->kiov_len;
195 while (klod->klod_offset >= klod->klod_iov.kiov->kiov_len) {
196 klod->klod_offset -= klod->klod_iov.kiov->kiov_len;
197 klod->klod_iov.kiov++;
199 LASSERT(klod->klod_niov > 0);
203 /* CAVEAT EMPTOR: I kmap 2 pages at once == slight risk of deadlock */
205 if (dstaddr == NULL) {
206 dstaddr = (void *)((unsigned long)kmap(kiov->kiov_page) +
207 kiov->kiov_offset + offset);
208 dstfrag = kiov->kiov_len - offset;
211 LASSERT(klod->klod_niov > 0);
212 if (srcaddr == NULL) {
213 srcaddr = (void *)((unsigned long)kmap(klod->klod_iov.kiov->kiov_page) +
214 klod->klod_iov.kiov->kiov_offset + klod->klod_offset);
215 srcfrag = klod->klod_iov.kiov->kiov_len - klod->klod_offset;
218 fraglen = MIN(srcfrag, dstfrag);
222 memcpy(dstaddr, srcaddr, fraglen);
224 if (fraglen < dstfrag) {
226 dstaddr = (void *)((unsigned long)dstaddr + fraglen);
228 kunmap(kiov->kiov_page);
235 if (fraglen < srcfrag) {
237 srcaddr = (void *)((unsigned long)srcaddr + fraglen);
239 kunmap(klod->klod_iov.kiov->kiov_page);
241 klod->klod_offset = 0;
242 klod->klod_iov.kiov++;
250 kunmap(kiov->kiov_page);
253 kunmap(klod->klod_iov.kiov->kiov_page);
255 lib_finalize(&klonal_lib, private, libmsg, PTL_OK);
259 lib_nal_t klonal_lib =
261 libnal_data: &klonal_data, /* NAL private data */
262 libnal_send: klonal_send,
263 libnal_send_pages: klonal_send_pages,
264 libnal_recv: klonal_recv,
265 libnal_recv_pages: klonal_recv_pages,
266 libnal_dist: klonal_dist