Whamcloud - gitweb
Merge b_md to HEAD for 0.5.19 release.
[fs/lustre-release.git] / lustre / lib / simple.c
index 9477aaa..73a4383 100644 (file)
 
 #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(&current->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 */
@@ -95,28 +134,32 @@ struct dentry *simple_mknod(struct dentry *dir, char *name, int mode)
 
         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 */
@@ -131,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;
 }
 
 /*
@@ -171,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));
 }
 
 /*
@@ -187,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));
 }