X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Flib%2Fsimple.c;h=73a4383173f2470ca1450191d66c5bb7cd1d6623;hb=ccb42f2458669aaac84a661091b05a59bb781197;hp=56c819bac7e2c83ae16000d091abb36e15bc20da;hpb=292c6455830e5be84186829f2234b37b21f5e600;p=fs%2Flustre-release.git diff --git a/lustre/lib/simple.c b/lustre/lib/simple.c index 56c819b..73a4383 100644 --- a/lustre/lib/simple.c +++ b/lustre/lib/simple.c @@ -28,12 +28,9 @@ #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) @@ -41,37 +38,69 @@ #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"); @@ -82,8 +111,18 @@ void pop_ctxt(struct obd_run_ctxt *saved) //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 */ @@ -99,25 +138,28 @@ struct dentry *simple_mknod(struct dentry *dir, char *name, int mode) 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 & S_IFMT) != S_IFREG) - GOTO(out, err = -EEXIST); + 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)); - } + 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 */ @@ -132,25 +174,28 @@ struct dentry *simple_mkdir(struct dentry *dir, char *name, int mode) 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; } /* @@ -172,14 +217,19 @@ int lustre_fread(struct file *file, char *str, int len, loff_t *off) */ 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)); } /* @@ -188,9 +238,10 @@ int lustre_fwrite(struct file *file, const char *str, int len, loff_t *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)); }