aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/cifsproto.h3
-rw-r--r--fs/cifs/dir.c36
-rw-r--r--fs/cifs/file.c31
3 files changed, 20 insertions, 50 deletions
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 733e71b57c7a..42da854cda36 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -91,6 +91,9 @@ extern u64 cifs_UnixTimeToNT(struct timespec);
91extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, 91extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
92 int offset); 92 int offset);
93 93
94extern struct cifsFileInfo *cifs_new_fileinfo(struct inode *newinode,
95 __u16 fileHandle, struct file *file,
96 struct cifsTconInfo *tcon, unsigned int oflags);
94extern int cifs_posix_open(char *full_path, struct inode **pinode, 97extern int cifs_posix_open(char *full_path, struct inode **pinode,
95 struct vfsmount *mnt, int mode, int oflags, 98 struct vfsmount *mnt, int mode, int oflags,
96 __u32 *poplock, __u16 *pnetfid, int xid); 99 __u32 *poplock, __u16 *pnetfid, int xid);
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 9a5df7a84698..627a60a6c1b1 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -130,9 +130,9 @@ cifs_bp_rename_retry:
130 return full_path; 130 return full_path;
131} 131}
132 132
133static void 133struct cifsFileInfo *
134cifs_fill_fileinfo(struct inode *newinode, __u16 fileHandle, 134cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
135 struct vfsmount *mnt, bool write_only) 135 struct file *file, struct vfsmount *mnt, unsigned int oflags)
136{ 136{
137 int oplock = 0; 137 int oplock = 0;
138 struct cifsFileInfo *pCifsFile; 138 struct cifsFileInfo *pCifsFile;
@@ -140,9 +140,8 @@ cifs_fill_fileinfo(struct inode *newinode, __u16 fileHandle,
140 struct cifs_sb_info *cifs_sb = CIFS_SB(mnt->mnt_sb); 140 struct cifs_sb_info *cifs_sb = CIFS_SB(mnt->mnt_sb);
141 141
142 pCifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); 142 pCifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
143
144 if (pCifsFile == NULL) 143 if (pCifsFile == NULL)
145 return; 144 return pCifsFile;
146 145
147 if (oplockEnabled) 146 if (oplockEnabled)
148 oplock = REQ_OPLOCK; 147 oplock = REQ_OPLOCK;
@@ -151,6 +150,7 @@ cifs_fill_fileinfo(struct inode *newinode, __u16 fileHandle,
151 pCifsFile->pid = current->tgid; 150 pCifsFile->pid = current->tgid;
152 pCifsFile->pInode = igrab(newinode); 151 pCifsFile->pInode = igrab(newinode);
153 pCifsFile->mnt = mnt; 152 pCifsFile->mnt = mnt;
153 pCifsFile->pfile = file;
154 pCifsFile->invalidHandle = false; 154 pCifsFile->invalidHandle = false;
155 pCifsFile->closePend = false; 155 pCifsFile->closePend = false;
156 mutex_init(&pCifsFile->fh_mutex); 156 mutex_init(&pCifsFile->fh_mutex);
@@ -159,18 +159,16 @@ cifs_fill_fileinfo(struct inode *newinode, __u16 fileHandle,
159 atomic_set(&pCifsFile->count, 1); 159 atomic_set(&pCifsFile->count, 1);
160 slow_work_init(&pCifsFile->oplock_break, &cifs_oplock_break_ops); 160 slow_work_init(&pCifsFile->oplock_break, &cifs_oplock_break_ops);
161 161
162 /* set the following in open now
163 pCifsFile->pfile = file; */
164 write_lock(&GlobalSMBSeslock); 162 write_lock(&GlobalSMBSeslock);
165 list_add(&pCifsFile->tlist, &cifs_sb->tcon->openFileList); 163 list_add(&pCifsFile->tlist, &cifs_sb->tcon->openFileList);
166 pCifsInode = CIFS_I(newinode); 164 pCifsInode = CIFS_I(newinode);
167 if (pCifsInode) { 165 if (pCifsInode) {
168 /* if readable file instance put first in list*/ 166 /* if readable file instance put first in list*/
169 if (write_only) 167 if (oflags & FMODE_READ)
168 list_add(&pCifsFile->flist, &pCifsInode->openFileList);
169 else
170 list_add_tail(&pCifsFile->flist, 170 list_add_tail(&pCifsFile->flist,
171 &pCifsInode->openFileList); 171 &pCifsInode->openFileList);
172 else
173 list_add(&pCifsFile->flist, &pCifsInode->openFileList);
174 172
175 if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { 173 if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
176 pCifsInode->clientCanCacheAll = true; 174 pCifsInode->clientCanCacheAll = true;
@@ -180,6 +178,8 @@ cifs_fill_fileinfo(struct inode *newinode, __u16 fileHandle,
180 pCifsInode->clientCanCacheRead = true; 178 pCifsInode->clientCanCacheRead = true;
181 } 179 }
182 write_unlock(&GlobalSMBSeslock); 180 write_unlock(&GlobalSMBSeslock);
181
182 return pCifsFile;
183} 183}
184 184
185int cifs_posix_open(char *full_path, struct inode **pinode, 185int cifs_posix_open(char *full_path, struct inode **pinode,
@@ -187,7 +187,6 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
187 __u32 *poplock, __u16 *pnetfid, int xid) 187 __u32 *poplock, __u16 *pnetfid, int xid)
188{ 188{
189 int rc; 189 int rc;
190 bool write_only = false;
191 FILE_UNIX_BASIC_INFO *presp_data; 190 FILE_UNIX_BASIC_INFO *presp_data;
192 __u32 posix_flags = 0; 191 __u32 posix_flags = 0;
193 struct cifs_sb_info *cifs_sb = CIFS_SB(mnt->mnt_sb); 192 struct cifs_sb_info *cifs_sb = CIFS_SB(mnt->mnt_sb);
@@ -226,9 +225,6 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
226 if (oflags & O_DIRECT) 225 if (oflags & O_DIRECT)
227 posix_flags |= SMB_O_DIRECT; 226 posix_flags |= SMB_O_DIRECT;
228 227
229 if (!(oflags & FMODE_READ))
230 write_only = true;
231
232 mode &= ~current_umask(); 228 mode &= ~current_umask();
233 rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode, 229 rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode,
234 pnetfid, presp_data, poplock, full_path, 230 pnetfid, presp_data, poplock, full_path,
@@ -256,7 +252,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
256 cifs_fattr_to_inode(*pinode, &fattr); 252 cifs_fattr_to_inode(*pinode, &fattr);
257 } 253 }
258 254
259 cifs_fill_fileinfo(*pinode, *pnetfid, mnt, write_only); 255 cifs_new_fileinfo(*pinode, *pnetfid, NULL, mnt, oflags);
260 256
261posix_open_ret: 257posix_open_ret:
262 kfree(presp_data); 258 kfree(presp_data);
@@ -301,7 +297,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
301 FILE_ALL_INFO *buf = NULL; 297 FILE_ALL_INFO *buf = NULL;
302 struct inode *newinode = NULL; 298 struct inode *newinode = NULL;
303 int disposition = FILE_OVERWRITE_IF; 299 int disposition = FILE_OVERWRITE_IF;
304 bool write_only = false;
305 300
306 xid = GetXid(); 301 xid = GetXid();
307 302
@@ -354,11 +349,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
354 desiredAccess = 0; 349 desiredAccess = 0;
355 if (oflags & FMODE_READ) 350 if (oflags & FMODE_READ)
356 desiredAccess |= GENERIC_READ; /* is this too little? */ 351 desiredAccess |= GENERIC_READ; /* is this too little? */
357 if (oflags & FMODE_WRITE) { 352 if (oflags & FMODE_WRITE)
358 desiredAccess |= GENERIC_WRITE; 353 desiredAccess |= GENERIC_WRITE;
359 if (!(oflags & FMODE_READ))
360 write_only = true;
361 }
362 354
363 if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) 355 if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
364 disposition = FILE_CREATE; 356 disposition = FILE_CREATE;
@@ -473,8 +465,8 @@ cifs_create_set_dentry:
473 /* mknod case - do not leave file open */ 465 /* mknod case - do not leave file open */
474 CIFSSMBClose(xid, tcon, fileHandle); 466 CIFSSMBClose(xid, tcon, fileHandle);
475 } else if (!(posix_create) && (newinode)) { 467 } else if (!(posix_create) && (newinode)) {
476 cifs_fill_fileinfo(newinode, fileHandle, nd->path.mnt, 468 cifs_new_fileinfo(newinode, fileHandle, NULL,
477 write_only); 469 nd->path.mnt, oflags);
478 } 470 }
479cifs_create_out: 471cifs_create_out:
480 kfree(buf); 472 kfree(buf);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 90f61786f516..fee993c92f1a 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -40,29 +40,6 @@
40#include "cifs_debug.h" 40#include "cifs_debug.h"
41#include "cifs_fs_sb.h" 41#include "cifs_fs_sb.h"
42 42
43static inline struct cifsFileInfo *cifs_init_private(
44 struct cifsFileInfo *private_data, struct inode *inode,
45 struct file *file, __u16 netfid)
46{
47 memset(private_data, 0, sizeof(struct cifsFileInfo));
48 private_data->netfid = netfid;
49 private_data->pid = current->tgid;
50 mutex_init(&private_data->fh_mutex);
51 mutex_init(&private_data->lock_mutex);
52 INIT_LIST_HEAD(&private_data->llist);
53 private_data->pfile = file; /* needed for writepage */
54 private_data->pInode = igrab(inode);
55 private_data->mnt = file->f_path.mnt;
56 private_data->invalidHandle = false;
57 private_data->closePend = false;
58 /* Initialize reference count to one. The private data is
59 freed on the release of the last reference */
60 atomic_set(&private_data->count, 1);
61 slow_work_init(&private_data->oplock_break, &cifs_oplock_break_ops);
62
63 return private_data;
64}
65
66static inline int cifs_convert_flags(unsigned int flags) 43static inline int cifs_convert_flags(unsigned int flags)
67{ 44{
68 if ((flags & O_ACCMODE) == O_RDONLY) 45 if ((flags & O_ACCMODE) == O_RDONLY)
@@ -420,15 +397,13 @@ int cifs_open(struct inode *inode, struct file *file)
420 cFYI(1, ("cifs_open returned 0x%x", rc)); 397 cFYI(1, ("cifs_open returned 0x%x", rc));
421 goto out; 398 goto out;
422 } 399 }
423 file->private_data = 400 pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt,
424 kmalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); 401 file->f_flags);
402 file->private_data = pCifsFile;
425 if (file->private_data == NULL) { 403 if (file->private_data == NULL) {
426 rc = -ENOMEM; 404 rc = -ENOMEM;
427 goto out; 405 goto out;
428 } 406 }
429 pCifsFile = cifs_init_private(file->private_data, inode, file, netfid);
430 write_lock(&GlobalSMBSeslock);
431 list_add(&pCifsFile->tlist, &tcon->openFileList);
432 407
433 pCifsInode = CIFS_I(file->f_path.dentry->d_inode); 408 pCifsInode = CIFS_I(file->f_path.dentry->d_inode);
434 if (pCifsInode) { 409 if (pCifsInode) {