diff options
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 80 |
1 files changed, 37 insertions, 43 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 50ca088d8860..302ea15f02e6 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -129,15 +129,8 @@ static inline int cifs_posix_open_inode_helper(struct inode *inode, | |||
129 | struct file *file, struct cifsInodeInfo *pCifsInode, | 129 | struct file *file, struct cifsInodeInfo *pCifsInode, |
130 | struct cifsFileInfo *pCifsFile, int oplock, u16 netfid) | 130 | struct cifsFileInfo *pCifsFile, int oplock, u16 netfid) |
131 | { | 131 | { |
132 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | ||
133 | /* struct timespec temp; */ /* BB REMOVEME BB */ | ||
134 | 132 | ||
135 | file->private_data = kmalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); | ||
136 | if (file->private_data == NULL) | ||
137 | return -ENOMEM; | ||
138 | pCifsFile = cifs_init_private(file->private_data, inode, file, netfid); | ||
139 | write_lock(&GlobalSMBSeslock); | 133 | write_lock(&GlobalSMBSeslock); |
140 | list_add(&pCifsFile->tlist, &cifs_sb->tcon->openFileList); | ||
141 | 134 | ||
142 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); | 135 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); |
143 | if (pCifsInode == NULL) { | 136 | if (pCifsInode == NULL) { |
@@ -145,17 +138,6 @@ static inline int cifs_posix_open_inode_helper(struct inode *inode, | |||
145 | return -EINVAL; | 138 | return -EINVAL; |
146 | } | 139 | } |
147 | 140 | ||
148 | /* want handles we can use to read with first | ||
149 | in the list so we do not have to walk the | ||
150 | list to search for one in write_begin */ | ||
151 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) { | ||
152 | list_add_tail(&pCifsFile->flist, | ||
153 | &pCifsInode->openFileList); | ||
154 | } else { | ||
155 | list_add(&pCifsFile->flist, | ||
156 | &pCifsInode->openFileList); | ||
157 | } | ||
158 | |||
159 | if (pCifsInode->clientCanCacheRead) { | 141 | if (pCifsInode->clientCanCacheRead) { |
160 | /* we have the inode open somewhere else | 142 | /* we have the inode open somewhere else |
161 | no need to discard cache data */ | 143 | no need to discard cache data */ |
@@ -198,6 +180,38 @@ psx_client_can_cache: | |||
198 | return 0; | 180 | return 0; |
199 | } | 181 | } |
200 | 182 | ||
183 | static struct cifsFileInfo * | ||
184 | cifs_fill_filedata(struct file *file) | ||
185 | { | ||
186 | struct list_head *tmp; | ||
187 | struct cifsFileInfo *pCifsFile = NULL; | ||
188 | struct cifsInodeInfo *pCifsInode = NULL; | ||
189 | |||
190 | /* search inode for this file and fill in file->private_data */ | ||
191 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); | ||
192 | read_lock(&GlobalSMBSeslock); | ||
193 | list_for_each(tmp, &pCifsInode->openFileList) { | ||
194 | pCifsFile = list_entry(tmp, struct cifsFileInfo, flist); | ||
195 | if ((pCifsFile->pfile == NULL) && | ||
196 | (pCifsFile->pid == current->tgid)) { | ||
197 | /* mode set in cifs_create */ | ||
198 | |||
199 | /* needed for writepage */ | ||
200 | pCifsFile->pfile = file; | ||
201 | file->private_data = pCifsFile; | ||
202 | break; | ||
203 | } | ||
204 | } | ||
205 | read_unlock(&GlobalSMBSeslock); | ||
206 | |||
207 | if (file->private_data != NULL) { | ||
208 | return pCifsFile; | ||
209 | } else if ((file->f_flags & O_CREAT) && (file->f_flags & O_EXCL)) | ||
210 | cERROR(1, ("could not find file instance for " | ||
211 | "new file %p", file)); | ||
212 | return NULL; | ||
213 | } | ||
214 | |||
201 | /* all arguments to this function must be checked for validity in caller */ | 215 | /* all arguments to this function must be checked for validity in caller */ |
202 | static inline int cifs_open_inode_helper(struct inode *inode, struct file *file, | 216 | static inline int cifs_open_inode_helper(struct inode *inode, struct file *file, |
203 | struct cifsInodeInfo *pCifsInode, struct cifsFileInfo *pCifsFile, | 217 | struct cifsInodeInfo *pCifsInode, struct cifsFileInfo *pCifsFile, |
@@ -272,7 +286,6 @@ int cifs_open(struct inode *inode, struct file *file) | |||
272 | struct cifsTconInfo *tcon; | 286 | struct cifsTconInfo *tcon; |
273 | struct cifsFileInfo *pCifsFile; | 287 | struct cifsFileInfo *pCifsFile; |
274 | struct cifsInodeInfo *pCifsInode; | 288 | struct cifsInodeInfo *pCifsInode; |
275 | struct list_head *tmp; | ||
276 | char *full_path = NULL; | 289 | char *full_path = NULL; |
277 | int desiredAccess; | 290 | int desiredAccess; |
278 | int disposition; | 291 | int disposition; |
@@ -284,32 +297,12 @@ int cifs_open(struct inode *inode, struct file *file) | |||
284 | cifs_sb = CIFS_SB(inode->i_sb); | 297 | cifs_sb = CIFS_SB(inode->i_sb); |
285 | tcon = cifs_sb->tcon; | 298 | tcon = cifs_sb->tcon; |
286 | 299 | ||
287 | /* search inode for this file and fill in file->private_data */ | ||
288 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); | 300 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); |
289 | read_lock(&GlobalSMBSeslock); | 301 | pCifsFile = cifs_fill_filedata(file); |
290 | list_for_each(tmp, &pCifsInode->openFileList) { | 302 | if (pCifsFile) { |
291 | pCifsFile = list_entry(tmp, struct cifsFileInfo, | ||
292 | flist); | ||
293 | if ((pCifsFile->pfile == NULL) && | ||
294 | (pCifsFile->pid == current->tgid)) { | ||
295 | /* mode set in cifs_create */ | ||
296 | |||
297 | /* needed for writepage */ | ||
298 | pCifsFile->pfile = file; | ||
299 | |||
300 | file->private_data = pCifsFile; | ||
301 | break; | ||
302 | } | ||
303 | } | ||
304 | read_unlock(&GlobalSMBSeslock); | ||
305 | |||
306 | if (file->private_data != NULL) { | ||
307 | rc = 0; | ||
308 | FreeXid(xid); | 303 | FreeXid(xid); |
309 | return rc; | 304 | return 0; |
310 | } else if ((file->f_flags & O_CREAT) && (file->f_flags & O_EXCL)) | 305 | } |
311 | cERROR(1, ("could not find file instance for " | ||
312 | "new file %p", file)); | ||
313 | 306 | ||
314 | full_path = build_path_from_dentry(file->f_path.dentry); | 307 | full_path = build_path_from_dentry(file->f_path.dentry); |
315 | if (full_path == NULL) { | 308 | if (full_path == NULL) { |
@@ -339,6 +332,7 @@ int cifs_open(struct inode *inode, struct file *file) | |||
339 | /* no need for special case handling of setting mode | 332 | /* no need for special case handling of setting mode |
340 | on read only files needed here */ | 333 | on read only files needed here */ |
341 | 334 | ||
335 | pCifsFile = cifs_fill_filedata(file); | ||
342 | cifs_posix_open_inode_helper(inode, file, pCifsInode, | 336 | cifs_posix_open_inode_helper(inode, file, pCifsInode, |
343 | pCifsFile, oplock, netfid); | 337 | pCifsFile, oplock, netfid); |
344 | goto out; | 338 | goto out; |