1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * Copyright (C) 2002 Cluster File Systems, Inc.
8 * This code is issued under the GNU General Public License.
9 * See the file COPYING in this distribution
11 * by Peter Braam <braam@clusterfs.com>
12 * and Andreas Dilger <adilger@clusterfs.com>
17 #include <linux/version.h>
19 #include <asm/unistd.h>
21 #define DEBUG_SUBSYSTEM S_FILTER
23 #include <linux/obd_support.h>
24 #include <linux/obd.h>
25 #include <linux/lustre_mds.h>
26 #include <linux/lustre_lib.h>
27 #include <linux/lustre_net.h>
30 /* Debugging check only needed during development */
31 #define ASSERT_CTXT_MAGIC(magic) do { if ((magic) != OBD_RUN_CTXT_MAGIC) { \
32 CERROR("bad ctxt magic\n"); LBUG(); } } while(0)
33 #define ASSERT_NOT_KERNEL_CTXT(msg) do { if (segment_eq(get_fs(), get_ds())) { \
34 CERROR(msg); LBUG(); } } while(0)
35 #define ASSERT_KERNEL_CTXT(msg) do { if (!segment_eq(get_fs(), get_ds())) { \
36 CERROR(msg); LBUG(); } } while(0)
38 #define ASSERT_CTXT_MAGIC(magic) do {} while(0)
39 #define ASSERT_NOT_KERNEL_CTXT(msg) do {} while(0)
40 #define ASSERT_KERNEL_CTXT(msg) do {} while(0)
43 /* push / pop to root of obd store */
44 void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new,
47 //ASSERT_NOT_KERNEL_CTXT("already in kernel context!\n");
48 ASSERT_CTXT_MAGIC(new->magic);
49 OBD_SET_CTXT_MAGIC(save);
51 save->pwd = dget(current->fs->pwd);
52 save->pwdmnt = mntget(current->fs->pwdmnt);
55 LASSERT(save->pwdmnt);
59 save->fsuid = current->fsuid;
60 save->fsgid = current->fsgid;
61 save->cap = current->cap_effective;
63 current->fsuid = uc->ouc_fsuid;
64 current->fsgid = uc->ouc_fsgid;
65 current->cap_effective = uc->ouc_cap;
68 set_fs_pwd(current->fs, new->pwdmnt, new->pwd);
70 // cap_lower(current->cap_effective, CAP_DAC_OVERRIDE);
73 void pop_ctxt(struct obd_run_ctxt *saved)
76 ASSERT_CTXT_MAGIC(saved->magic);
78 ASSERT_KERNEL_CTXT("popping non-kernel context!\n");
82 set_fs_pwd(current->fs, saved->pwdmnt, saved->pwd);
87 mntput(saved->pwdmnt);
89 current->fsuid = saved->fsuid;
90 current->fsgid = saved->fsgid;
91 current->cap_effective = saved->cap;
93 // if (saved->override)
94 // cap_raise(current->cap_effective, CAP_DAC_OVERRIDE);
97 /* utility to make a file */
98 struct dentry *simple_mknod(struct dentry *dir, char *name, int mode)
100 struct dentry *dchild;
104 ASSERT_KERNEL_CTXT("kernel doing mknod outside kernel context\n");
105 CDEBUG(D_INODE, "creating file %*s\n", (int)strlen(name), name);
107 down(&dir->d_inode->i_sem);
108 dchild = lookup_one_len(name, dir, strlen(name));
110 GOTO(out, PTR_ERR(dchild));
112 if (dchild->d_inode) {
113 if ((dchild->d_inode->i_mode & S_IFMT) != S_IFREG)
114 GOTO(out, err = -EEXIST);
119 err = vfs_create(dir->d_inode, dchild, (mode & ~S_IFMT) | S_IFREG);
122 up(&dir->d_inode->i_sem);
125 RETURN(ERR_PTR(err));
131 /* utility to make a directory */
132 struct dentry *simple_mkdir(struct dentry *dir, char *name, int mode)
134 struct dentry *dchild;
138 ASSERT_KERNEL_CTXT("kernel doing mkdir outside kernel context\n");
139 CDEBUG(D_INODE, "creating directory %*s\n", (int)strlen(name), name);
140 down(&dir->d_inode->i_sem);
141 dchild = lookup_one_len(name, dir, strlen(name));
143 GOTO(out, PTR_ERR(dchild));
145 if (dchild->d_inode) {
146 if (!S_ISDIR(dchild->d_inode->i_mode))
147 GOTO(out, err = -ENOTDIR);
152 err = vfs_mkdir(dir->d_inode, dchild, mode);
155 up(&dir->d_inode->i_sem);
158 RETURN(ERR_PTR(err));
165 * Read a file from within kernel context. Prior to calling this
166 * function we should already have done a push_ctxt().
168 int lustre_fread(struct file *file, char *str, int len, loff_t *off)
170 ASSERT_KERNEL_CTXT("kernel doing read outside kernel context\n");
171 if (!file || !file->f_op || !file->f_op->read || !off)
174 return file->f_op->read(file, str, len, off);
178 * Write a file from within kernel context. Prior to calling this
179 * function we should already have done a push_ctxt().
181 int lustre_fwrite(struct file *file, const char *str, int len, loff_t *off)
183 ASSERT_KERNEL_CTXT("kernel doing write outside kernel context\n");
184 if (!file || !file->f_op || !off)
187 if (!file->f_op->write)
190 return file->f_op->write(file, str, len, off);
194 * Sync a file from within kernel context. Prior to calling this
195 * function we should already have done a push_ctxt().
197 int lustre_fsync(struct file *file)
199 ASSERT_KERNEL_CTXT("kernel doing sync outside kernel context\n");
200 if (!file || !file->f_op || !file->f_op->fsync)
203 return file->f_op->fsync(file, file->f_dentry, 0);