Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
[pandora-kernel.git] / fs / 9p / vfs_inode.c
index 133db36..7a7ec2d 100644 (file)
@@ -204,7 +204,6 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode)
                inode->i_mode = mode;
                inode->i_uid = current->fsuid;
                inode->i_gid = current->fsgid;
-               inode->i_blksize = sb->s_blocksize;
                inode->i_blocks = 0;
                inode->i_rdev = 0;
                inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
@@ -270,7 +269,10 @@ v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, u32 perm,
        err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall);
        if (err < 0) {
                PRINT_FCALL_ERROR("clone error", fcall);
-               goto put_fid;
+               if (fcall && fcall->id == RWALK)
+                       goto clunk_fid;
+               else
+                       goto put_fid;
        }
        kfree(fcall);
 
@@ -297,7 +299,7 @@ clunk_fid:
        fid = V9FS_NOFID;
 
 put_fid:
-       if (fid >= 0)
+       if (fid != V9FS_NOFID)
                v9fs_put_idpool(fid, &v9ses->fidpool);
 
        kfree(fcall);
@@ -322,6 +324,9 @@ v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry)
                &fcall);
 
        if (err < 0) {
+               if (fcall && fcall->id == RWALK)
+                       goto clunk_fid;
+
                PRINT_FCALL_ERROR("walk error", fcall);
                v9fs_put_idpool(nfid, &v9ses->fidpool);
                goto error;
@@ -428,11 +433,11 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir)
        result = v9fs_t_remove(v9ses, fid, &fcall);
        if (result < 0) {
                PRINT_FCALL_ERROR("remove fails", fcall);
-       } else {
-               v9fs_put_idpool(fid, &v9ses->fidpool);
-               v9fs_fid_destroy(v9fid);
        }
 
+       v9fs_put_idpool(fid, &v9ses->fidpool);
+       v9fs_fid_destroy(v9fid);
+
        kfree(fcall);
        return result;
 }
@@ -524,9 +529,6 @@ error:
        if (vfid)
                v9fs_fid_destroy(vfid);
 
-       if (inode)
-               iput(inode);
-
        return err;
 }
 
@@ -640,19 +642,26 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
        }
 
        result = v9fs_t_walk(v9ses, dirfidnum, newfid,
-               (char *)dentry->d_name.name, NULL);
+               (char *)dentry->d_name.name, &fcall);
+
        if (result < 0) {
-               v9fs_put_idpool(newfid, &v9ses->fidpool);
+               if (fcall && fcall->id == RWALK)
+                       v9fs_t_clunk(v9ses, newfid);
+               else
+                       v9fs_put_idpool(newfid, &v9ses->fidpool);
+
                if (result == -ENOENT) {
                        d_add(dentry, NULL);
                        dprintk(DEBUG_VFS,
                                "Return negative dentry %p count %d\n",
                                dentry, atomic_read(&dentry->d_count));
+                       kfree(fcall);
                        return NULL;
                }
                dprintk(DEBUG_ERROR, "walk error:%d\n", result);
                goto FreeFcall;
        }
+       kfree(fcall);
 
        result = v9fs_t_stat(v9ses, newfid, &fcall);
        if (result < 0) {
@@ -940,9 +949,8 @@ v9fs_stat2inode(struct v9fs_stat *stat, struct inode *inode,
 
        inode->i_size = stat->length;
 
-       inode->i_blksize = sb->s_blocksize;
        inode->i_blocks =
-           (inode->i_size + inode->i_blksize - 1) >> sb->s_blocksize_bits;
+           (inode->i_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
 }
 
 /**
@@ -1041,6 +1049,9 @@ static int v9fs_vfs_readlink(struct dentry *dentry, char __user * buffer,
        int ret;
        char *link = __getname();
 
+       if (unlikely(!link))
+               return -ENOMEM;
+
        if (buflen > PATH_MAX)
                buflen = PATH_MAX;
 
@@ -1158,9 +1169,6 @@ error:
        if (vfid)
                v9fs_fid_destroy(vfid);
 
-       if (inode)
-               iput(inode);
-
        return err;
 
 }
@@ -1214,6 +1222,9 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
        }
 
        name = __getname();
+       if (unlikely(!name))
+               return -ENOMEM;
+
        sprintf(name, "%d\n", oldfid->fid);
        retval = v9fs_vfs_mkspecial(dir, dentry, V9FS_DMLINK, name);
        __putname(name);