#ifdef OBD_CTXT_DEBUG
/* Debugging check only needed during development */
-#define ASSERT_CTXT_MAGIC(magic) do { if ((magic) != OBD_RUN_CTXT_MAGIC) { \
- CERROR("bad ctxt magic\n"); LBUG(); } } while(0)
-#define ASSERT_NOT_KERNEL_CTXT(msg) do { if (segment_eq(get_fs(), get_ds())) { \
- CERROR(msg); LBUG(); } } while(0)
-#define ASSERT_KERNEL_CTXT(msg) do { if (!segment_eq(get_fs(), get_ds())) { \
- CERROR(msg); LBUG(); } } while(0)
+#define ASSERT_CTXT_MAGIC(magic) LASSERT((magic) == OBD_RUN_CTXT_MAGIC)
+#define ASSERT_NOT_KERNEL_CTXT(msg) LASSERT(!segment_eq(get_fs(), get_ds()))
+#define ASSERT_KERNEL_CTXT(msg) LASSERT(segment_eq(get_fs(), get_ds()))
#else
#define ASSERT_CTXT_MAGIC(magic) do {} while(0)
#define ASSERT_NOT_KERNEL_CTXT(msg) do {} while(0)
#endif
/* push / pop to root of obd store */
-void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new,
+void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new_ctx,
struct obd_ucred *uc)
{
//ASSERT_NOT_KERNEL_CTXT("already in kernel context!\n");
- ASSERT_CTXT_MAGIC(new->magic);
+ ASSERT_CTXT_MAGIC(new_ctx->magic);
OBD_SET_CTXT_MAGIC(save);
+
+ /*
+ CDEBUG(D_INFO, "== push %p->%p == cur fs %p pwd %p (%*s), pwdmnt %p\n",
+ save, current, current->fs, current->fs->pwd,
+ current->fs->pwd->d_name.len, current->fs->pwd->d_name.name,
+ current->fs->pwdmnt);
+ */
+
save->fs = get_fs();
+ LASSERT(atomic_read(¤t->fs->pwd->d_count));
+ LASSERT(atomic_read(&new_ctx->pwd->d_count));
save->pwd = dget(current->fs->pwd);
save->pwdmnt = mntget(current->fs->pwdmnt);
LASSERT(save->pwd);
LASSERT(save->pwdmnt);
- LASSERT(new->pwd);
- LASSERT(new->pwdmnt);
+ LASSERT(new_ctx->pwd);
+ LASSERT(new_ctx->pwdmnt);
+
+ if (uc) {
+ save->fsuid = current->fsuid;
+ save->fsgid = current->fsgid;
+ save->cap = current->cap_effective;
- save->fsuid = current->fsuid;
- save->fsgid = current->fsgid;
- if (uc) {
current->fsuid = uc->ouc_fsuid;
current->fsgid = uc->ouc_fsgid;
+ current->cap_effective = uc->ouc_cap;
}
- set_fs(new->fs);
- set_fs_pwd(current->fs, new->pwdmnt, new->pwd);
+ set_fs(new_ctx->fs);
+ set_fs_pwd(current->fs, new_ctx->pwdmnt, new_ctx->pwd);
+
+ /*
+ CDEBUG(D_INFO, "== push %p==%p == cur fs %p pwd %p (%*s), pwdmnt %p\n",
+ new_ctx, current, current->fs, current->fs->pwd,
+ current->fs->pwd->d_name.len, current->fs->pwd->d_name.name,
+ current->fs->pwdmnt);
+ */
}
-void pop_ctxt(struct obd_run_ctxt *saved)
+void pop_ctxt(struct obd_run_ctxt *saved, struct obd_run_ctxt *new_ctx,
+ struct obd_ucred *uc)
{
//printk("pc0");
ASSERT_CTXT_MAGIC(saved->magic);
//printk("pc1");
ASSERT_KERNEL_CTXT("popping non-kernel context!\n");
+
+ /*
+ CDEBUG(D_INFO, " == pop %p==%p == cur %p pwd %p (%*s), pwdmnt %p\n",
+ new_ctx, current, current->fs, current->fs->pwd,
+ current->fs->pwd->d_name.len, current->fs->pwd->d_name.name,
+ current->fs->pwdmnt);
+ */
+
+ LASSERT(current->fs->pwd == new_ctx->pwd);
+ LASSERT(current->fs->pwdmnt == new_ctx->pwdmnt);
+
//printk("pc2");
set_fs(saved->fs);
//printk("pc3\n");
//printk("pc5");
mntput(saved->pwdmnt);
//printk("pc6\n");
- current->fsuid = saved->fsuid;
- current->fsgid = saved->fsgid;
+ if (uc) {
+ current->fsuid = saved->fsuid;
+ current->fsgid = saved->fsgid;
+ current->cap_effective = saved->cap;
+ }
+
+ /*
+ CDEBUG(D_INFO, "== pop %p->%p == cur fs %p pwd %p (%*s), pwdmnt %p\n",
+ saved, current, current->fs, current->fs->pwd,
+ current->fs->pwd->d_name.len, current->fs->pwd->d_name.name,
+ current->fs->pwdmnt);
+ */
}
/* utility to make a file */
ASSERT_KERNEL_CTXT("kernel doing mknod outside kernel context\n");
CDEBUG(D_INODE, "creating file %*s\n", (int)strlen(name), name);
+
down(&dir->d_inode->i_sem);
dchild = lookup_one_len(name, dir, strlen(name));
if (IS_ERR(dchild))
- GOTO(out, PTR_ERR(dchild));
+ GOTO(out_up, dchild);
if (dchild->d_inode) {
- if (((dchild->d_inode->i_mode ^ mode) & S_IFMT) != 0)
- GOTO(out, err = -EEXIST);
+ if ((dchild->d_inode->i_mode & S_IFMT) != S_IFREG)
+ GOTO(out_err, err = -EEXIST);
- GOTO(out, dchild);
+ GOTO(out_up, dchild);
}
- err = vfs_create(dir->d_inode, dchild, (mode & S_IFMT) | S_IFREG);
- EXIT;
-out:
- up(&dir->d_inode->i_sem);
- if (err) {
- dput(dchild);
- RETURN(ERR_PTR(err));
- }
+ err = vfs_create(dir->d_inode, dchild, (mode & ~S_IFMT) | S_IFREG);
+ if (err)
+ GOTO(out_err, err);
+ up(&dir->d_inode->i_sem);
RETURN(dchild);
+
+out_err:
+ dput(dchild);
+ dchild = ERR_PTR(err);
+out_up:
+ up(&dir->d_inode->i_sem);
+ return dchild;
}
/* utility to make a directory */
down(&dir->d_inode->i_sem);
dchild = lookup_one_len(name, dir, strlen(name));
if (IS_ERR(dchild))
- GOTO(out, PTR_ERR(dchild));
+ GOTO(out_up, dchild);
if (dchild->d_inode) {
if (!S_ISDIR(dchild->d_inode->i_mode))
- GOTO(out, err = -ENOTDIR);
+ GOTO(out_err, err = -ENOTDIR);
- GOTO(out, dchild);
+ GOTO(out_up, dchild);
}
err = vfs_mkdir(dir->d_inode, dchild, mode);
- EXIT;
-out:
- up(&dir->d_inode->i_sem);
- if (err) {
- dput(dchild);
- RETURN(ERR_PTR(err));
- }
+ if (err)
+ GOTO(out_err, err);
+ up(&dir->d_inode->i_sem);
RETURN(dchild);
+
+out_err:
+ dput(dchild);
+ dchild = ERR_PTR(err);
+out_up:
+ up(&dir->d_inode->i_sem);
+ return dchild;
}
/*
*/
int lustre_fwrite(struct file *file, const char *str, int len, loff_t *off)
{
+ ENTRY;
ASSERT_KERNEL_CTXT("kernel doing write outside kernel context\n");
- if (!file || !file->f_op || !off)
+ if (!file)
+ RETURN(-ENOENT);
+ if (!file->f_op)
RETURN(-ENOSYS);
+ if (!off)
+ RETURN(-EINVAL);
if (!file->f_op->write)
RETURN(-EROFS);
- return file->f_op->write(file, str, len, off);
+ RETURN(file->f_op->write(file, str, len, off));
}
/*
*/
int lustre_fsync(struct file *file)
{
+ ENTRY;
ASSERT_KERNEL_CTXT("kernel doing sync outside kernel context\n");
if (!file || !file->f_op || !file->f_op->fsync)
RETURN(-ENOSYS);
- return file->f_op->fsync(file, file->f_dentry, 0);
+ RETURN(file->f_op->fsync(file, file->f_dentry, 0));
}