Merge master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6
[pandora-kernel.git] / arch / powerpc / platforms / cell / spufs / inode.c
index 687f80d..3950ddc 100644 (file)
@@ -82,7 +82,6 @@ spufs_new_inode(struct super_block *sb, int mode)
        inode->i_mode = mode;
        inode->i_uid = current->fsuid;
        inode->i_gid = current->fsgid;
-       inode->i_blksize = PAGE_CACHE_SIZE;
        inode->i_blocks = 0;
        inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 out:
@@ -103,7 +102,7 @@ spufs_setattr(struct dentry *dentry, struct iattr *attr)
 
 static int
 spufs_new_file(struct super_block *sb, struct dentry *dentry,
-               struct file_operations *fops, int mode,
+               const struct file_operations *fops, int mode,
                struct spu_context *ctx)
 {
        static struct inode_operations spufs_file_iops = {
@@ -120,7 +119,7 @@ spufs_new_file(struct super_block *sb, struct dentry *dentry,
        ret = 0;
        inode->i_op = &spufs_file_iops;
        inode->i_fop = fops;
-       inode->u.generic_ip = SPUFS_I(inode)->i_ctx = get_spu_context(ctx);
+       inode->i_private = SPUFS_I(inode)->i_ctx = get_spu_context(ctx);
        d_add(dentry, inode);
 out:
        return ret;
@@ -137,8 +136,8 @@ spufs_delete_inode(struct inode *inode)
 static void spufs_prune_dir(struct dentry *dir)
 {
        struct dentry *dentry, *tmp;
-       down(&dir->d_inode->i_sem);
-       list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_child) {
+       mutex_lock(&dir->d_inode->i_mutex);
+       list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_u.d_child) {
                spin_lock(&dcache_lock);
                spin_lock(&dentry->d_lock);
                if (!(d_unhashed(dentry)) && dentry->d_inode) {
@@ -154,23 +153,15 @@ static void spufs_prune_dir(struct dentry *dir)
                }
        }
        shrink_dcache_parent(dir);
-       up(&dir->d_inode->i_sem);
+       mutex_unlock(&dir->d_inode->i_mutex);
 }
 
+/* Caller must hold root->i_mutex */
 static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry)
 {
-       struct spu_context *ctx;
-
        /* remove all entries */
-       down(&root->i_sem);
        spufs_prune_dir(dir_dentry);
-       up(&root->i_sem);
-
-       /* We have to give up the mm_struct */
-       ctx = SPUFS_I(dir_dentry->d_inode)->i_ctx;
-       spu_forget(ctx);
 
-       /* XXX Do we need to hold i_sem here ? */
        return simple_rmdir(root, dir_dentry);
 }
 
@@ -199,16 +190,23 @@ out:
 
 static int spufs_dir_close(struct inode *inode, struct file *file)
 {
+       struct spu_context *ctx;
        struct inode *dir;
        struct dentry *dentry;
        int ret;
 
        dentry = file->f_dentry;
        dir = dentry->d_parent->d_inode;
+       ctx = SPUFS_I(dentry->d_inode)->i_ctx;
 
+       mutex_lock(&dir->i_mutex);
        ret = spufs_rmdir(dir, dentry);
+       mutex_unlock(&dir->i_mutex);
        WARN_ON(ret);
 
+       /* We have to give up the mm_struct */
+       spu_forget(ctx);
+
        return dcache_dir_close(inode, file);
 }
 
@@ -241,7 +239,7 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
                inode->i_gid = dir->i_gid;
                inode->i_mode &= S_ISGID;
        }
-       ctx = alloc_spu_context(inode->i_mapping);
+       ctx = alloc_spu_context();
        SPUFS_I(inode)->i_ctx = ctx;
        if (!ctx)
                goto out_iput;
@@ -293,9 +291,8 @@ out:
 
 static struct file_system_type spufs_type;
 
-long
-spufs_create_thread(struct nameidata *nd, const char *name,
-                       unsigned int flags, mode_t mode)
+long spufs_create_thread(struct nameidata *nd,
+                        unsigned int flags, mode_t mode)
 {
        struct dentry *dentry;
        int ret;
@@ -306,6 +303,10 @@ spufs_create_thread(struct nameidata *nd, const char *name,
            nd->dentry != nd->dentry->d_sb->s_root)
                goto out;
 
+       /* all flags are reserved */
+       if (flags)
+               goto out;
+
        dentry = lookup_create(nd, 1);
        ret = PTR_ERR(dentry);
        if (IS_ERR(dentry))
@@ -325,13 +326,18 @@ spufs_create_thread(struct nameidata *nd, const char *name,
         * in error path of *_open().
         */
        ret = spufs_context_open(dget(dentry), mntget(nd->mnt));
-       if (ret < 0)
-               spufs_rmdir(nd->dentry->d_inode, dentry);
+       if (ret < 0) {
+               WARN_ON(spufs_rmdir(nd->dentry->d_inode, dentry));
+               mutex_unlock(&nd->dentry->d_inode->i_mutex);
+               spu_forget(SPUFS_I(dentry->d_inode)->i_ctx);
+               dput(dentry);
+               goto out;
+       }
 
 out_dput:
        dput(dentry);
 out_dir:
-       up(&nd->dentry->d_inode->i_sem);
+       mutex_unlock(&nd->dentry->d_inode->i_mutex);
 out:
        return ret;
 }
@@ -429,11 +435,11 @@ spufs_fill_super(struct super_block *sb, void *data, int silent)
        return spufs_create_root(sb, data);
 }
 
-static struct super_block *
+static int
 spufs_get_sb(struct file_system_type *fstype, int flags,
-               const char *name, void *data)
+               const char *name, void *data, struct vfsmount *mnt)
 {
-       return get_sb_single(fstype, flags, data, spufs_fill_super);
+       return get_sb_single(fstype, flags, data, spufs_fill_super, mnt);
 }
 
 static struct file_system_type spufs_type = {
@@ -443,7 +449,7 @@ static struct file_system_type spufs_type = {
        .kill_sb = kill_litter_super,
 };
 
-static int spufs_init(void)
+static int __init spufs_init(void)
 {
        int ret;
        ret = -ENOMEM;
@@ -473,7 +479,7 @@ out:
 }
 module_init(spufs_init);
 
-static void spufs_exit(void)
+static void __exit spufs_exit(void)
 {
        spu_sched_exit();
        unregister_spu_syscalls(&spufs_calls);