diff options
| author | Jeff Garzik <jgarzik@pobox.com> | 2005-10-04 10:16:31 -0400 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@pobox.com> | 2005-10-04 10:16:31 -0400 |
| commit | 2ee73cc2d507df7b28050fba5d08bd33dd34848c (patch) | |
| tree | af5f33b265318e0f4b61f788691fe4f780ec402c /fs/9p/vfs_file.c | |
| parent | c1d9728ecc5b560465df3c0c0d3b3825c2710b40 (diff) | |
| parent | ed39f731ab2e77e58122232f6e27333331d7793d (diff) | |
Merge /spare/repo/linux-2.6/
Diffstat (limited to 'fs/9p/vfs_file.c')
| -rw-r--r-- | fs/9p/vfs_file.c | 88 |
1 files changed, 28 insertions, 60 deletions
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 1f8ae7d580ab..a4799e971d1c 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c | |||
| @@ -53,30 +53,36 @@ | |||
| 53 | int v9fs_file_open(struct inode *inode, struct file *file) | 53 | int v9fs_file_open(struct inode *inode, struct file *file) |
| 54 | { | 54 | { |
| 55 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | 55 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); |
| 56 | struct v9fs_fid *v9fid = v9fs_fid_lookup(file->f_dentry, FID_WALK); | 56 | struct v9fs_fid *v9fid, *fid; |
| 57 | struct v9fs_fid *v9newfid = NULL; | ||
| 58 | struct v9fs_fcall *fcall = NULL; | 57 | struct v9fs_fcall *fcall = NULL; |
| 59 | int open_mode = 0; | 58 | int open_mode = 0; |
| 60 | unsigned int iounit = 0; | 59 | unsigned int iounit = 0; |
| 61 | int newfid = -1; | 60 | int newfid = -1; |
| 62 | long result = -1; | 61 | long result = -1; |
| 63 | 62 | ||
| 64 | dprintk(DEBUG_VFS, "inode: %p file: %p v9fid= %p\n", inode, file, | 63 | dprintk(DEBUG_VFS, "inode: %p file: %p \n", inode, file); |
| 65 | v9fid); | 64 | |
| 65 | v9fid = v9fs_fid_get_created(file->f_dentry); | ||
| 66 | if (!v9fid) | ||
| 67 | v9fid = v9fs_fid_lookup(file->f_dentry); | ||
| 66 | 68 | ||
| 67 | if (!v9fid) { | 69 | if (!v9fid) { |
| 68 | struct dentry *dentry = file->f_dentry; | ||
| 69 | dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n"); | 70 | dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n"); |
| 71 | return -EBADF; | ||
| 72 | } | ||
| 70 | 73 | ||
| 71 | /* XXX - some duplication from lookup, generalize later */ | 74 | if (!v9fid->fidcreate) { |
| 72 | /* basically vfs_lookup is too heavy weight */ | 75 | fid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); |
| 73 | v9fid = v9fs_fid_lookup(file->f_dentry, FID_OP); | 76 | if (fid == NULL) { |
| 74 | if (!v9fid) | 77 | dprintk(DEBUG_ERROR, "Out of Memory\n"); |
| 75 | return -EBADF; | 78 | return -ENOMEM; |
| 79 | } | ||
| 76 | 80 | ||
| 77 | v9fid = v9fs_fid_lookup(dentry->d_parent, FID_WALK); | 81 | fid->fidopen = 0; |
| 78 | if (!v9fid) | 82 | fid->fidcreate = 0; |
| 79 | return -EBADF; | 83 | fid->fidclunked = 0; |
| 84 | fid->iounit = 0; | ||
| 85 | fid->v9ses = v9ses; | ||
| 80 | 86 | ||
| 81 | newfid = v9fs_get_idpool(&v9ses->fidpool); | 87 | newfid = v9fs_get_idpool(&v9ses->fidpool); |
| 82 | if (newfid < 0) { | 88 | if (newfid < 0) { |
| @@ -85,58 +91,16 @@ int v9fs_file_open(struct inode *inode, struct file *file) | |||
| 85 | } | 91 | } |
| 86 | 92 | ||
| 87 | result = | 93 | result = |
| 88 | v9fs_t_walk(v9ses, v9fid->fid, newfid, | 94 | v9fs_t_walk(v9ses, v9fid->fid, newfid, NULL, NULL); |
| 89 | (char *)file->f_dentry->d_name.name, NULL); | 95 | |
| 90 | if (result < 0) { | 96 | if (result < 0) { |
| 91 | v9fs_put_idpool(newfid, &v9ses->fidpool); | 97 | v9fs_put_idpool(newfid, &v9ses->fidpool); |
| 92 | dprintk(DEBUG_ERROR, "rewalk didn't work\n"); | 98 | dprintk(DEBUG_ERROR, "rewalk didn't work\n"); |
| 93 | return -EBADF; | 99 | return -EBADF; |
| 94 | } | 100 | } |
| 95 | 101 | ||
| 96 | v9fid = v9fs_fid_create(dentry); | 102 | fid->fid = newfid; |
| 97 | if (v9fid == NULL) { | 103 | v9fid = fid; |
| 98 | dprintk(DEBUG_ERROR, "couldn't insert\n"); | ||
| 99 | return -ENOMEM; | ||
| 100 | } | ||
| 101 | v9fid->fid = newfid; | ||
| 102 | } | ||
| 103 | |||
| 104 | if (v9fid->fidcreate) { | ||
| 105 | /* create case */ | ||
| 106 | newfid = v9fid->fid; | ||
| 107 | iounit = v9fid->iounit; | ||
| 108 | v9fid->fidcreate = 0; | ||
| 109 | } else { | ||
| 110 | if (!S_ISDIR(inode->i_mode)) | ||
| 111 | newfid = v9fid->fid; | ||
| 112 | else { | ||
| 113 | newfid = v9fs_get_idpool(&v9ses->fidpool); | ||
| 114 | if (newfid < 0) { | ||
| 115 | eprintk(KERN_WARNING, "allocation failed\n"); | ||
| 116 | return -ENOSPC; | ||
| 117 | } | ||
| 118 | /* This would be a somewhat critical clone */ | ||
| 119 | result = | ||
| 120 | v9fs_t_walk(v9ses, v9fid->fid, newfid, NULL, | ||
| 121 | &fcall); | ||
| 122 | if (result < 0) { | ||
| 123 | dprintk(DEBUG_ERROR, "clone error: %s\n", | ||
| 124 | FCALL_ERROR(fcall)); | ||
| 125 | kfree(fcall); | ||
| 126 | return result; | ||
| 127 | } | ||
| 128 | |||
| 129 | v9newfid = v9fs_fid_create(file->f_dentry); | ||
| 130 | v9newfid->fid = newfid; | ||
| 131 | v9newfid->qid = v9fid->qid; | ||
| 132 | v9newfid->iounit = v9fid->iounit; | ||
| 133 | v9newfid->fidopen = 0; | ||
| 134 | v9newfid->fidclunked = 0; | ||
| 135 | v9newfid->v9ses = v9ses; | ||
| 136 | v9fid = v9newfid; | ||
| 137 | kfree(fcall); | ||
| 138 | } | ||
| 139 | |||
| 140 | /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */ | 104 | /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */ |
| 141 | /* translate open mode appropriately */ | 105 | /* translate open mode appropriately */ |
| 142 | open_mode = file->f_flags & 0x3; | 106 | open_mode = file->f_flags & 0x3; |
| @@ -163,9 +127,13 @@ int v9fs_file_open(struct inode *inode, struct file *file) | |||
| 163 | 127 | ||
| 164 | iounit = fcall->params.ropen.iounit; | 128 | iounit = fcall->params.ropen.iounit; |
| 165 | kfree(fcall); | 129 | kfree(fcall); |
| 130 | } else { | ||
| 131 | /* create case */ | ||
| 132 | newfid = v9fid->fid; | ||
| 133 | iounit = v9fid->iounit; | ||
| 134 | v9fid->fidcreate = 0; | ||
| 166 | } | 135 | } |
| 167 | 136 | ||
| 168 | |||
| 169 | file->private_data = v9fid; | 137 | file->private_data = v9fid; |
| 170 | 138 | ||
| 171 | v9fid->rdir_pos = 0; | 139 | v9fid->rdir_pos = 0; |
