source: gpfs_3.1_ker2.6.20/lpp/mmfs/src/gpl-linux/block.c @ 16

Last change on this file since 16 was 16, checked in by rock, 16 years ago
File size: 8.9 KB
Line 
1/***************************************************************************
2 *
3 * Copyright (C) 2001 International Business Machines
4 * All rights reserved.
5 *
6 * This file is part of the GPFS mmfslinux kernel module.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 *  1. Redistributions of source code must retain the above copyright notice,
13 *     this list of conditions and the following disclaimer.
14 *  2. Redistributions in binary form must reproduce the above copyright
15 *     notice, this list of conditions and the following disclaimer in the
16 *     documentation and/or other materials provided with the distribution.
17 *  3. The name of the author may not be used to endorse or promote products
18 *     derived from this software without specific prior written
19 *     permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
30 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 *************************************************************************** */
33/* @(#)90       1.28  src/avs/fs/mmfs/ts/kernext/gpl-linux/block.c, mmfs, avs_rgpfs24, rgpfs240610b 8/4/04 23:12:51 */
34#if LINUX_KERNEL_VERSION < 2050000
35
36#define __NO_VERSION__
37
38#ifndef __KERNEL__
39#define __KERNEL__
40#endif
41
42#include <Shark-gpl.h>
43
44#include <linux/types.h>
45#include <linux/kernel.h>
46#include <linux/stat.h>
47#include <linux/errno.h>
48#include <linux/module.h>
49#include <linux/blkdev.h>
50#include <asm/uaccess.h>
51
52#include <linux/devfs_fs_kernel.h>
53
54#include <verdep.h>
55#include <cxiTypes.h>
56#include <linux2gpfs.h>
57#include <cxiIOBuffer.h>
58#include <cxiSharedSeg.h>
59#include <cxiSystem.h>
60#include <Trace.h>
61
62
63/* Major number for GPFS filesystem /dev entries.  Note that FS_MAJOR
64   is just our first choice for a number.  Since we don't have a reserved
65   number (see linux/major.h) we have to be prepared to receive EBUSY when
66   we register.  If FS_MAJOR is already taken, we allow devfs_register_blkdev
67   to assign us any available number.  After we've registered, our major
68   number will be stored in GPFSFileSysMajorNumber.  */
69#define FS_MAJOR 239
70
71static unsigned int GPFSFileSysMajorNumber = 0;
72
73
74/* just return a zero'd buffer */
75ssize_t 
76gpfs_fb_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
77{
78  ssize_t written = 0;
79  int toWrite;
80  int rc = 0;
81
82  ENTER(0);
83  TRACE3(TRACE_BOPS, 2, TRCID_FBREAD_ENTER,
84         "gpfs_fb_read: enter file 0x%X buf 0x%X nbytes %d\n", 
85         file, buf, nbytes);
86
87  while (nbytes)
88  {
89    toWrite = (nbytes >= PAGE_SIZE) ? PAGE_SIZE : nbytes;
90
91    rc = clear_user(buf, toWrite);
92    if (rc)
93      goto xerror;
94
95    nbytes -= toWrite;
96    buf += toWrite;
97    written += toWrite;
98  }
99
100xerror:
101  TRACE1(TRACE_BOPS, 2, TRCID_FBREAD_EXIT,
102         "gpfs_fb_read: exit written %d\n", written);
103
104  EXIT(0);
105  return (rc ? -ENOSYS : written);
106}
107
108ssize_t 
109gpfs_fb_write(struct file *file, const char *buf, size_t nbytes, loff_t *ppos)
110{
111  ENTER(0);
112  TRACE3(TRACE_BOPS, 2, TRCID_FBWRITE_ENTER,
113         "gpfs_fb_write: enter file 0x%X buf 0x%X nbytes %d\n", 
114         file, buf, nbytes);
115  EXIT(0);
116  return nbytes;
117}
118
119int 
120gpfs_fb_open(struct inode *inode, struct file *file)
121{
122  struct block_device *bdP;
123  int openers;
124  int count;
125
126  ENTER(0);
127  TRACE2(TRACE_BOPS, 2, TRCID_FBOPEN_ENTER,
128         "gpfs_fb_open: inode 0x%X file 0x%X\n", inode, file);
129
130  if (inode->i_bdev)
131  {
132    bdP = inode->i_bdev;
133
134# if LINUX_KERNEL_VERSION >= 2041300
135    openers = bdP->bd_openers;
136    count   = atomic_read(&bdP->bd_count);
137#else
138    openers = atomic_read(&bdP->bd_openers);
139    count   = atomic_read(&bdP->bd_count);
140#endif
141
142    TRACE3(TRACE_BOPS, 2, TRCID_FBOPEN_EXIT,
143           "gpfs_fb_open: exit bdP 0x%lX openers %d count %d\n", 
144           bdP, openers, count);
145  }
146  EXIT(0);
147  return 0;
148}
149
150int 
151gpfs_fb_release(struct inode *inode, struct file *file)
152{
153  struct block_device *bdP;
154  int openers;
155  int count;
156
157  ENTER(0);
158  TRACE2(TRACE_BOPS, 2, TRCID_FBRELEASE_ENTER,
159         "gpfs_fb_release: inode 0x%X file 0x%X\n", inode, file);
160
161  if (inode->i_bdev)
162  {
163    bdP = inode->i_bdev;
164# if LINUX_KERNEL_VERSION >= 2041300
165    openers = bdP->bd_openers;
166    count   = atomic_read(&bdP->bd_count);
167#else
168    openers = atomic_read(&bdP->bd_openers);
169    count   = atomic_read(&bdP->bd_count);
170#endif
171
172    /* We're responsible for calling this to lower the openers
173     * count as we have a specific release routine.   We're using
174     * BDEV_RAW since that doesn't incur any operations in
175     * blkdev_put()
176     */
177    blkdev_put(bdP, BDEV_RAW);
178
179    TRACE3(TRACE_BOPS, 2, TRCID_FBRELEASE_EXIT,
180           "gpfs_fb_release: exit bdP 0x%lX openers %d count %d\n", 
181           bdP, openers, count);
182  }
183  EXIT(0);
184  return 0;
185}
186
187int 
188gpfs_fb_ioctl(struct inode *inode, struct file *file, unsigned p1, 
189              unsigned long p2)
190{
191  ENTER(0);
192  TRACE4(TRACE_BOPS, 2, TRCID_FBIOCTL_ENTER,
193         "gpfs_fb_ioctl: inode 0x%X file 0x%X p1 %d p2 %d\n",
194         inode, file, p1, p2);
195  EXIT(0);
196  return 0;
197}
198
199int
200gpfs_b_open(struct inode *inode, struct file *file)
201{
202  struct block_device *bdP;
203  int openers;
204  int count;
205
206  ENTER(0);
207  TRACE2(TRACE_BOPS, 2, TRCID_BOPEN_ENTER,
208         "gpfs_b_open: inode 0x%X file 0x%X\n", inode, file);
209  if (!inode)
210          return -EINVAL;
211
212  if (inode->i_bdev)
213  {
214    bdP = inode->i_bdev;
215# if LINUX_KERNEL_VERSION >= 2041300
216    openers = bdP->bd_openers;
217    count   = atomic_read(&bdP->bd_count);
218#else
219    openers = atomic_read(&bdP->bd_openers);
220    count   = atomic_read(&bdP->bd_count);
221#endif
222
223    TRACE3(TRACE_BOPS, 2, TRCID_BOPEN_EXIT,
224           "gpfs_b_open: exit bdP 0x%lX openers %d count %d\n", 
225           bdP, openers, count);
226  }
227  file->f_op = &gpfs_fbps;
228
229  EXIT(0);
230  return 0;          /* success */
231}
232
233int 
234gpfs_b_release(struct inode *inode, struct file *file)
235{
236  struct block_device *bdP;
237  int openers;
238  int count;
239
240  ENTER(0);
241  TRACE2(TRACE_BOPS, 2, TRCID_BRELEASE_ENTER,
242         "gpfs_b_release: inode 0x%X file 0x%X\n", inode, file);
243
244  if (inode->i_bdev)
245  {
246    bdP = inode->i_bdev;
247# if LINUX_KERNEL_VERSION >= 2041300
248    openers = bdP->bd_openers;
249    count   = atomic_read(&bdP->bd_count);
250#else
251    openers = atomic_read(&bdP->bd_openers);
252    count   = atomic_read(&bdP->bd_count);
253#endif
254
255    TRACE3(TRACE_BOPS, 2, TRCID_BRELEASE_EXIT,
256           "gpfs_b_release: exit bdP 0x%lX openers %d count %d\n", 
257           bdP, openers, count);
258  }
259  EXIT(0);
260  return 0;          /* success */
261}
262
263int 
264gpfs_b_ioctl(struct inode *inode, struct file *file, unsigned p1,
265             unsigned long p2)
266{
267  ENTER(0);
268  TRACE4(TRACE_BOPS, 2, TRCID_BIOCTL_ENTER,
269         "gpfs_fb_ioctl: inode 0x%X file 0x%X p1 %d p2 %d\n",
270         inode, file, p1, p2);
271  EXIT(0);
272  return 0;
273}
274
275int
276gpfs_make_request(request_queue_t *rq, int rw, struct buffer_head *bh)
277{
278  ENTER(0);
279  BUFHEAD_ERROR_IODONE(bh);
280  EXIT(0);
281  return 0;
282}
283
284
285int 
286gpfs_block_init()
287{
288  int rc;
289
290  ENTER(0);
291  GPFSFileSysMajorNumber = FS_MAJOR;
292
293retry:
294  rc = register_blkdev(GPFSFileSysMajorNumber, "gpfs", &gpfs_bops);
295  if (rc < 0)
296  {
297    TRACE2(TRACE_BOPS, 2, TRCID_BLOCK_011,
298           "gpfs_block_init: unable to get major %d rc %d\n",
299           GPFSFileSysMajorNumber, rc);
300
301    /* If FS_MAJOR was already taken, register without specifying a major
302       number (allow devfs_register_blkdev to choose an available one). */
303
304    if ((rc == -EBUSY) && (GPFSFileSysMajorNumber == FS_MAJOR))
305    {
306      GPFSFileSysMajorNumber = 0;
307      goto retry;
308    }
309
310    GPFSFileSysMajorNumber = 0;
311    EXIT(0);
312    return -1;
313  }
314
315  /* If devfs_register_blkdev chose the number, save it so we can
316     properly unregister later. */
317
318  if (GPFSFileSysMajorNumber == 0)
319    GPFSFileSysMajorNumber = rc;
320
321
322  /* set up a null strategy routine */
323  blk_queue_make_request(BLK_DEFAULT_QUEUE(GPFSFileSysMajorNumber),
324                         gpfs_make_request);
325                         
326  TRACE2(TRACE_BOPS, 2, TRCID_BLOCK_013,
327         "gpfs_block_init: register_blkdev %d rc %d\n",
328         GPFSFileSysMajorNumber, rc);
329  EXIT(0);
330  return 0;
331}
332
333void 
334gpfs_block_clean()
335{
336  int rc;
337
338  ENTER(0);
339  rc = unregister_blkdev(GPFSFileSysMajorNumber, "gpfs");
340  TRACE2(TRACE_BOPS, 2, TRCID_BLOCK_015,
341         "gpfs_block_clean: unregister_blkdev %d rc %d\n",
342         GPFSFileSysMajorNumber, rc);
343
344  GPFSFileSysMajorNumber = 0;
345  EXIT(0);
346}
347#endif /* LINUX_KERNEL_VERSION < 2050000 */
Note: See TracBrowser for help on using the repository browser.