Whamcloud - gitweb
WARNING: we currently crash on unmount after the last phase of runtests.
[fs/lustre-release.git] / lustre / lib / simple.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  lib/simple.c
5  *
6  * Copyright (C) 2002  Cluster File Systems, Inc.
7  *
8  * This code is issued under the GNU General Public License.
9  * See the file COPYING in this distribution
10  *
11  * by Peter Braam <braam@clusterfs.com>
12  * and Andreas Dilger <adilger@clusterfs.com>
13  */
14
15 #define EXPORT_SYMTAB
16
17 #include <linux/version.h>
18 #include <linux/fs.h>
19 #include <asm/unistd.h>
20
21 #define DEBUG_SUBSYSTEM S_FILTER
22
23 #include <linux/obd.h>
24 #include <linux/lustre_mds.h>
25 #include <linux/lustre_lib.h>
26 #include <linux/lustre_net.h>
27
28 #ifdef OBD_CTXT_DEBUG
29 /* Debugging check only needed during development */
30 #define ASSERT_CTXT_MAGIC(magic) do { if ((magic) != OBD_RUN_CTXT_MAGIC) { \
31                                 CERROR("bad ctxt magic\n"); LBUG(); } } while(0)
32 #define ASSERT_NOT_KERNEL_CTXT(msg) do { if (segment_eq(get_fs(), get_ds())) { \
33                                         CERROR(msg); LBUG(); } } while(0)
34 #define ASSERT_KERNEL_CTXT(msg) do { if (!segment_eq(get_fs(), get_ds())) { \
35                                         CERROR(msg); LBUG(); } } while(0)
36 #else
37 #define ASSERT_CTXT_MAGIC(magic) do {} while(0)
38 #define ASSERT_NOT_KERNEL_CTXT(msg) do {} while(0)
39 #define ASSERT_KERNEL_CTXT(msg) do {} while(0)
40 #endif
41
42 /* push / pop to root of obd store */
43 void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new)
44 {
45         //ASSERT_NOT_KERNEL_CTXT("already in kernel context!\n");
46         ASSERT_CTXT_MAGIC(new->magic);
47         OBD_SET_CTXT_MAGIC(save);
48         save->fs = get_fs();
49         save->pwd = dget(current->fs->pwd);
50         save->pwdmnt = mntget(current->fs->pwdmnt);
51
52         LASSERT(save->pwd);
53         LASSERT(save->pwdmnt);
54         LASSERT(new->pwd);
55         LASSERT(new->pwdmnt);
56
57         set_fs(new->fs);
58         set_fs_pwd(current->fs, new->pwdmnt, new->pwd);
59 }
60
61 void pop_ctxt(struct obd_run_ctxt *saved)
62 {
63         ASSERT_CTXT_MAGIC(saved->magic);
64         ASSERT_KERNEL_CTXT("popping non-kernel context!\n");
65         set_fs(saved->fs);
66         LASSERT(saved->pwd);
67         LASSERT(saved->pwdmnt);
68         set_fs_pwd(current->fs, saved->pwdmnt, saved->pwd);
69
70         dput(saved->pwd);
71         mntput(saved->pwdmnt);
72 }
73
74 /* utility to make a directory */
75 struct dentry *simple_mkdir(struct dentry *dir, char *name, int mode)
76 {
77         struct dentry *dchild;
78         int err;
79         ENTRY;
80
81         ASSERT_KERNEL_CTXT("kernel doing mkdir outside kernel context\n");
82         CDEBUG(D_INODE, "creating directory %*s\n", strlen(name), name);
83         dchild = lookup_one_len(name, dir, strlen(name));
84         if (IS_ERR(dchild))
85                 RETURN(dchild);
86
87         if (dchild->d_inode) {
88                 if (!S_ISDIR(dchild->d_inode->i_mode))
89                         GOTO(out, err = -ENOTDIR);
90
91                 RETURN(dchild);
92         }
93
94         err = vfs_mkdir(dir->d_inode, dchild, mode);
95         EXIT;
96 out:
97         if (err) {
98                 dput(dchild);
99                 RETURN(ERR_PTR(err));
100         }
101
102         RETURN(dchild);
103 }
104
105 /*
106  * Read a file from within kernel context.  Prior to calling this
107  * function we should already have done a push_ctxt().
108  */
109 int lustre_fread(struct file *file, char *str, int len, loff_t *off)
110 {
111         ASSERT_KERNEL_CTXT("kernel doing read outside kernel context\n");
112         if (!file || !file->f_op || !file->f_op->read || !off)
113                 RETURN(-ENOSYS);
114
115         return file->f_op->read(file, str, len, off);
116 }
117
118 /*
119  * Write a file from within kernel context.  Prior to calling this
120  * function we should already have done a push_ctxt().
121  */
122 int lustre_fwrite(struct file *file, const char *str, int len, loff_t *off)
123 {
124         ASSERT_KERNEL_CTXT("kernel doing write outside kernel context\n");
125         if (!file || !file->f_op || !off)
126                 RETURN(-ENOSYS);
127
128         if (!file->f_op->write)
129                 RETURN(-EROFS);
130
131         return file->f_op->write(file, str, len, off);
132 }
133
134 /*
135  * Sync a file from within kernel context.  Prior to calling this
136  * function we should already have done a push_ctxt().
137  */
138 int lustre_fsync(struct file *file)
139 {
140         ASSERT_KERNEL_CTXT("kernel doing sync outside kernel context\n");
141         if (!file || !file->f_op || !file->f_op->fsync)
142                 RETURN(-ENOSYS);
143
144         return file->f_op->fsync(file, file->f_dentry, 0);
145 }