Whamcloud - gitweb
file lustre_types.h was added on branch b1_4_mountconf on 2006-04-26 18:45:44 +0000
[fs/lustre-release.git] / lustre / obdfilter / filter_san.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  linux/fs/obdfilter/filter_san.c
5  *
6  *  Copyright (c) 2001-2003 Cluster File Systems, Inc.
7  *   Author: Peter Braam <braam@clusterfs.com>
8  *   Author: Andreas Dilger <adilger@clusterfs.com>
9  *
10  *   This file is part of the Lustre file system, http://www.lustre.org
11  *   Lustre is a trademark of Cluster File Systems, Inc.
12  *
13  *   You may have signed or agreed to another license before downloading
14  *   this software.  If so, you are bound by the terms and conditions
15  *   of that agreement, and the following does not apply to you.  See the
16  *   LICENSE file included with this distribution for more information.
17  *
18  *   If you did not agree to a different license, then this copy of Lustre
19  *   is open source software; you can redistribute it and/or modify it
20  *   under the terms of version 2 of the GNU General Public License as
21  *   published by the Free Software Foundation.
22  *
23  *   In either case, Lustre is distributed in the hope that it will be
24  *   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
25  *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  *   license text for more details.
27  */
28
29 #define DEBUG_SUBSYSTEM S_FILTER
30
31 #include <linux/config.h>
32 #include <linux/module.h>
33 #include <linux/pagemap.h> // XXX kill me soon
34 #include <linux/version.h>
35
36 #include <linux/obd_class.h>
37 #include <linux/lustre_fsfilt.h>
38 #include "filter_internal.h"
39
40 /* sanobd setup methods - use a specific mount option */
41 int filter_san_setup(struct obd_device *obd, obd_count len, void *buf)
42 {
43         struct lustre_cfg* lcfg = buf;
44         unsigned long page;
45         int rc;
46
47         if (lcfg->lcfg_bufcount < 3 || LUSTRE_CFG_BUFLEN(lcfg, 2) < 1)
48                 RETURN(-EINVAL);
49
50         /* 2.6.9 selinux wants a full option page for do_kern_mount (bug6471) */
51         page = get_zeroed_page(GFP_KERNEL);
52         if (!page)
53                 RETURN(-ENOMEM);
54
55         /* for ext3/ldiskfs filesystem, we must mount in 'writeback' mode */
56         if (!strcmp(lustre_cfg_string(lcfg, 2), "ldiskfs"))
57                 strcpy((void *)page, "data=writeback");
58         else if (!strcmp(lustre_cfg_string(lcfg, 2), "ext3"))
59                 strcpy((void *)page, "data=writeback,asyncdel");
60         else
61                 LBUG(); /* just a reminder */
62
63         rc = filter_common_setup(obd, len, buf, (void *)page);
64         free_page(page);
65
66         return rc;
67 }
68
69 int filter_san_preprw(int cmd, struct obd_export *exp, struct obdo *oa,
70                       int objcount, struct obd_ioobj *obj, int niocount,
71                       struct niobuf_remote *nb)
72 {
73         struct obd_ioobj *o = obj;
74         struct niobuf_remote *rnb = nb;
75         int rc = 0;
76         int i;
77         ENTRY;
78         LASSERT(objcount == 1);
79
80         for (i = 0; i < objcount; i++, o++) {
81                 struct dentry *dentry;
82                 struct inode *inode;
83 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
84                 sector_t (*fs_bmap)(struct address_space *, sector_t);
85 #else
86                 int (*fs_bmap)(struct address_space *, long);
87 #endif
88                 int j;
89
90                 dentry = filter_oa2dentry(exp->exp_obd, oa);
91                 if (IS_ERR(dentry))
92                         GOTO(out, rc = PTR_ERR(dentry));
93
94                 inode = dentry->d_inode;
95                 fs_bmap = inode->i_mapping->a_ops->bmap;
96
97                 for (j = 0; j < o->ioo_bufcnt; j++, rnb++) {
98                         long block;
99
100                         block = rnb->offset >> inode->i_blkbits;
101
102                         if (cmd == OBD_BRW_READ) {
103                                 block = fs_bmap(inode->i_mapping, block);
104                         } else {
105                                 loff_t newsize = rnb->offset + rnb->len;
106                                 /* fs_prep_san_write will also update inode
107                                  * size for us:
108                                  * (1) new alloced block
109                                  * (2) existed block but size extented
110                                  */
111                                 /* FIXME We could call fs_prep_san_write()
112                                  * only once for all the blocks allocation.
113                                  * Now call it once for each block, for
114                                  * simplicity. And if error happens, we
115                                  * probably need to release previous alloced
116                                  * block */
117                                 rc = fs_prep_san_write(exp->exp_obd, inode,
118                                                        &block, 1, newsize);
119                                 if (rc)
120                                         break;
121                         }
122
123                         rnb->offset = block;
124                 }
125                 f_dput(dentry);
126         }
127 out:
128         RETURN(rc);
129 }
130