[PATCH] inode-diet: Eliminate i_blksize from the inode structure
[safe/jmp/linux-2.6] / fs / 9p / vfs_file.c
index e13577d..c3c47ed 100644 (file)
@@ -7,9 +7,8 @@
  *  Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
  *
  *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
  *
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 int v9fs_file_open(struct inode *inode, struct file *file)
 {
        struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
-       struct v9fs_fid *v9fid, *fid;
+       struct v9fs_fid *vfid;
        struct v9fs_fcall *fcall = NULL;
-       int open_mode = 0;
-       unsigned int iounit = 0;
-       int newfid = -1;
-       long result = -1;
+       int omode;
+       int fid = V9FS_NOFID;
+       int err;
 
        dprintk(DEBUG_VFS, "inode: %p file: %p \n", inode, file);
 
-       v9fid = v9fs_fid_get_created(file->f_dentry);
-       if (!v9fid)
-               v9fid = v9fs_fid_lookup(file->f_dentry);
-
-       if (!v9fid) {
+       vfid = v9fs_fid_lookup(file->f_dentry);
+       if (!vfid) {
                dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n");
                return -EBADF;
        }
 
-       if (!v9fid->fidcreate) {
-               fid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL);
-               if (fid == NULL) {
-                       dprintk(DEBUG_ERROR, "Out of Memory\n");
-                       return -ENOMEM;
-               }
-
-               fid->fidopen = 0;
-               fid->fidcreate = 0;
-               fid->fidclunked = 0;
-               fid->iounit = 0;
-               fid->v9ses = v9ses;
-
-               newfid = v9fs_get_idpool(&v9ses->fidpool);
-               if (newfid < 0) {
-                       eprintk(KERN_WARNING, "newfid fails!\n");
-                       return -ENOSPC;
-               }
-
-               result =
-                   v9fs_t_walk(v9ses, v9fid->fid, newfid, NULL, NULL);
+       fid = v9fs_get_idpool(&v9ses->fidpool);
+       if (fid < 0) {
+               eprintk(KERN_WARNING, "newfid fails!\n");
+               return -ENOSPC;
+       }
 
-               if (result < 0) {
-                       v9fs_put_idpool(newfid, &v9ses->fidpool);
-                       dprintk(DEBUG_ERROR, "rewalk didn't work\n");
-                       return -EBADF;
+       err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, &fcall);
+       if (err < 0) {
+               dprintk(DEBUG_ERROR, "rewalk didn't work\n");
+               if (fcall && fcall->id == RWALK)
+                       goto clunk_fid;
+               else {
+                       v9fs_put_idpool(fid, &v9ses->fidpool);
+                       goto free_fcall;
                }
+       }
+       kfree(fcall);
+
+       /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */
+       /* translate open mode appropriately */
+       omode = v9fs_uflags2omode(file->f_flags);
+       err = v9fs_t_open(v9ses, fid, omode, &fcall);
+       if (err < 0) {
+               PRINT_FCALL_ERROR("open failed", fcall);
+               goto clunk_fid;
+       }
 
-               fid->fid = newfid;
-               v9fid = fid;
-               /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */
-               /* translate open mode appropriately */
-               open_mode = file->f_flags & 0x3;
-
-               if (file->f_flags & O_EXCL)
-                       open_mode |= V9FS_OEXCL;
-
-               if (v9ses->extended) {
-                       if (file->f_flags & O_TRUNC)
-                               open_mode |= V9FS_OTRUNC;
-
-                       if (file->f_flags & O_APPEND)
-                               open_mode |= V9FS_OAPPEND;
-               }
+       vfid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL);
+       if (vfid == NULL) {
+               dprintk(DEBUG_ERROR, "out of memory\n");
+               err = -ENOMEM;
+               goto clunk_fid;
+       }
 
-               result = v9fs_t_open(v9ses, newfid, open_mode, &fcall);
-               if (result < 0) {
-                       dprintk(DEBUG_ERROR,
-                               "open failed, open_mode 0x%x: %s\n", open_mode,
-                               FCALL_ERROR(fcall));
-                       kfree(fcall);
-                       return result;
-               }
+       file->private_data = vfid;
+       vfid->fid = fid;
+       vfid->fidopen = 1;
+       vfid->fidclunked = 0;
+       vfid->iounit = fcall->params.ropen.iounit;
+       vfid->rdir_pos = 0;
+       vfid->rdir_fcall = NULL;
+       vfid->filp = file;
+       kfree(fcall);
 
-               iounit = fcall->params.ropen.iounit;
-               kfree(fcall);
-       } else {
-               /* create case */
-               newfid = v9fid->fid;
-               iounit = v9fid->iounit;
-               v9fid->fidcreate = 0;
-       }
+       return 0;
 
-       file->private_data = v9fid;
+clunk_fid:
+       v9fs_t_clunk(v9ses, fid);
 
-       v9fid->rdir_pos = 0;
-       v9fid->rdir_fcall = NULL;
-       v9fid->fidopen = 1;
-       v9fid->filp = file;
-       v9fid->iounit = iounit;
+free_fcall:
+       kfree(fcall);
 
-       return 0;
+       return err;
 }
 
 /**
@@ -256,7 +232,6 @@ v9fs_file_write(struct file *filp, const char __user * data,
        int result = -EIO;
        int rsize = 0;
        int total = 0;
-       char *buf;
 
        dprintk(DEBUG_VFS, "data %p count %d offset %x\n", data, (int)count,
                (int)*offset);
@@ -264,28 +239,14 @@ v9fs_file_write(struct file *filp, const char __user * data,
        if (v9fid->iounit != 0 && rsize > v9fid->iounit)
                rsize = v9fid->iounit;
 
-       buf = kmalloc(v9ses->maxdata - V9FS_IOHDRSZ, GFP_KERNEL);
-       if (!buf)
-               return -ENOMEM;
-
        do {
                if (count < rsize)
                        rsize = count;
 
-               result = copy_from_user(buf, data, rsize);
-               if (result) {
-                       dprintk(DEBUG_ERROR, "Problem copying from user\n");
-                       kfree(buf);
-                       return -EFAULT;
-               }
-
-               dump_data(buf, rsize);
-               result = v9fs_t_write(v9ses, fid, *offset, rsize, buf, &fcall);
+               result = v9fs_t_write(v9ses, fid, *offset, rsize, data, &fcall);
                if (result < 0) {
-                       eprintk(KERN_ERR, "error while writing: %s(%d)\n",
-                               FCALL_ERROR(fcall), result);
+                       PRINT_FCALL_ERROR("error while writing", fcall);
                        kfree(fcall);
-                       kfree(buf);
                        return result;
                } else
                        *offset += result;
@@ -305,15 +266,16 @@ v9fs_file_write(struct file *filp, const char __user * data,
                total += result;
        } while (count);
 
-       kfree(buf);
+               invalidate_inode_pages2(inode->i_mapping);
        return total;
 }
 
-struct file_operations v9fs_file_operations = {
+const struct file_operations v9fs_file_operations = {
        .llseek = generic_file_llseek,
        .read = v9fs_file_read,
        .write = v9fs_file_write,
        .open = v9fs_file_open,
        .release = v9fs_dir_release,
        .lock = v9fs_file_lock,
+       .mmap = generic_file_mmap,
 };