aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Shilovsky <pshilovsky@samba.org>2012-09-18 19:20:26 -0400
committerSteve French <smfrench@gmail.com>2012-09-24 22:46:26 -0400
commitfb1214e48f735cdb68446adb77ec37aa3de60697 (patch)
tree158dbfbedaf396f013e70f5288fdc906e990391c
parent4b4de76e35518fc0c636f628abca8c1b19ad6689 (diff)
CIFS: Move open code to ops struct
Acked-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org> Signed-off-by: Steve French <smfrench@gmail.com>
-rw-r--r--fs/cifs/cifsglob.h7
-rw-r--r--fs/cifs/cifsproto.h7
-rw-r--r--fs/cifs/dir.c17
-rw-r--r--fs/cifs/file.c63
-rw-r--r--fs/cifs/smb1ops.c29
5 files changed, 79 insertions, 44 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index a2a3865dee1b..e649fac7d6fe 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -171,6 +171,7 @@ struct cifs_tcon;
171struct dfs_info3_param; 171struct dfs_info3_param;
172struct cifs_fattr; 172struct cifs_fattr;
173struct smb_vol; 173struct smb_vol;
174struct cifs_fid;
174 175
175struct smb_version_operations { 176struct smb_version_operations {
176 int (*send_cancel)(struct TCP_Server_Info *, void *, 177 int (*send_cancel)(struct TCP_Server_Info *, void *,
@@ -262,6 +263,12 @@ struct smb_version_operations {
262 /* open, rename and delete file */ 263 /* open, rename and delete file */
263 int (*rename_pending_delete)(const char *, struct dentry *, 264 int (*rename_pending_delete)(const char *, struct dentry *,
264 const unsigned int); 265 const unsigned int);
266 /* open a file for non-posix mounts */
267 int (*open)(const unsigned int, struct cifs_tcon *, const char *, int,
268 int, int, struct cifs_fid *, __u32 *, FILE_ALL_INFO *,
269 struct cifs_sb_info *);
270 /* set fid protocol-specific info */
271 void (*set_fid)(struct cifsFileInfo *, struct cifs_fid *, __u32);
265}; 272};
266 273
267struct smb_version_values { 274struct smb_version_values {
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 79c088469757..b67f7758f422 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -121,9 +121,10 @@ extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
121 int offset); 121 int offset);
122extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock); 122extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock);
123 123
124extern struct cifsFileInfo *cifs_new_fileinfo(__u16 fileHandle, 124extern struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid,
125 struct file *file, struct tcon_link *tlink, 125 struct file *file,
126 __u32 oplock); 126 struct tcon_link *tlink,
127 __u32 oplock);
127extern int cifs_posix_open(char *full_path, struct inode **inode, 128extern int cifs_posix_open(char *full_path, struct inode **inode,
128 struct super_block *sb, int mode, 129 struct super_block *sb, int mode,
129 unsigned int f_flags, __u32 *oplock, __u16 *netfid, 130 unsigned int f_flags, __u32 *oplock, __u16 *netfid,
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 781025be48bc..70823dc4f960 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -377,11 +377,12 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
377 unsigned int xid; 377 unsigned int xid;
378 struct tcon_link *tlink; 378 struct tcon_link *tlink;
379 struct cifs_tcon *tcon; 379 struct cifs_tcon *tcon;
380 __u16 fileHandle; 380 struct cifs_fid fid;
381 __u32 oplock; 381 __u32 oplock;
382 struct cifsFileInfo *pfile_info; 382 struct cifsFileInfo *file_info;
383 383
384 /* Posix open is only called (at lookup time) for file create now. For 384 /*
385 * Posix open is only called (at lookup time) for file create now. For
385 * opens (rather than creates), because we do not know if it is a file 386 * opens (rather than creates), because we do not know if it is a file
386 * or directory yet, and current Samba no longer allows us to do posix 387 * or directory yet, and current Samba no longer allows us to do posix
387 * open on dirs, we could end up wasting an open call on what turns out 388 * open on dirs, we could end up wasting an open call on what turns out
@@ -415,20 +416,20 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
415 tcon = tlink_tcon(tlink); 416 tcon = tlink_tcon(tlink);
416 417
417 rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, 418 rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
418 &oplock, &fileHandle, opened); 419 &oplock, &fid.netfid, opened);
419 420
420 if (rc) 421 if (rc)
421 goto out; 422 goto out;
422 423
423 rc = finish_open(file, direntry, generic_file_open, opened); 424 rc = finish_open(file, direntry, generic_file_open, opened);
424 if (rc) { 425 if (rc) {
425 CIFSSMBClose(xid, tcon, fileHandle); 426 CIFSSMBClose(xid, tcon, fid.netfid);
426 goto out; 427 goto out;
427 } 428 }
428 429
429 pfile_info = cifs_new_fileinfo(fileHandle, file, tlink, oplock); 430 file_info = cifs_new_fileinfo(&fid, file, tlink, oplock);
430 if (pfile_info == NULL) { 431 if (file_info == NULL) {
431 CIFSSMBClose(xid, tcon, fileHandle); 432 CIFSSMBClose(xid, tcon, fid.netfid);
432 rc = -ENOMEM; 433 rc = -ENOMEM;
433 } 434 }
434 435
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 712f2a4d0d49..1246cf74e1fb 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -169,16 +169,19 @@ posix_open_ret:
169 169
170static int 170static int
171cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb, 171cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
172 struct cifs_tcon *tcon, unsigned int f_flags, __u32 *poplock, 172 struct cifs_tcon *tcon, unsigned int f_flags, __u32 *oplock,
173 __u16 *pnetfid, unsigned int xid) 173 struct cifs_fid *fid, unsigned int xid)
174{ 174{
175 int rc; 175 int rc;
176 int desiredAccess; 176 int desired_access;
177 int disposition; 177 int disposition;
178 int create_options = CREATE_NOT_DIR; 178 int create_options = CREATE_NOT_DIR;
179 FILE_ALL_INFO *buf; 179 FILE_ALL_INFO *buf;
180 180
181 desiredAccess = cifs_convert_flags(f_flags); 181 if (!tcon->ses->server->ops->open)
182 return -ENOSYS;
183
184 desired_access = cifs_convert_flags(f_flags);
182 185
183/********************************************************************* 186/*********************************************************************
184 * open flag mapping table: 187 * open flag mapping table:
@@ -215,16 +218,9 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
215 if (backup_cred(cifs_sb)) 218 if (backup_cred(cifs_sb))
216 create_options |= CREATE_OPEN_BACKUP_INTENT; 219 create_options |= CREATE_OPEN_BACKUP_INTENT;
217 220
218 if (tcon->ses->capabilities & CAP_NT_SMBS) 221 rc = tcon->ses->server->ops->open(xid, tcon, full_path, disposition,
219 rc = CIFSSMBOpen(xid, tcon, full_path, disposition, 222 desired_access, create_options, fid,
220 desiredAccess, create_options, pnetfid, poplock, buf, 223 oplock, buf, cifs_sb);
221 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
222 & CIFS_MOUNT_MAP_SPECIAL_CHR);
223 else
224 rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
225 desiredAccess, CREATE_NOT_DIR, pnetfid, poplock, buf,
226 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
227 & CIFS_MOUNT_MAP_SPECIAL_CHR);
228 224
229 if (rc) 225 if (rc)
230 goto out; 226 goto out;
@@ -234,7 +230,7 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
234 xid); 230 xid);
235 else 231 else
236 rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb, 232 rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb,
237 xid, pnetfid); 233 xid, &fid->netfid);
238 234
239out: 235out:
240 kfree(buf); 236 kfree(buf);
@@ -242,7 +238,7 @@ out:
242} 238}
243 239
244struct cifsFileInfo * 240struct cifsFileInfo *
245cifs_new_fileinfo(__u16 fileHandle, struct file *file, 241cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
246 struct tcon_link *tlink, __u32 oplock) 242 struct tcon_link *tlink, __u32 oplock)
247{ 243{
248 struct dentry *dentry = file->f_path.dentry; 244 struct dentry *dentry = file->f_path.dentry;
@@ -255,7 +251,6 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
255 return cfile; 251 return cfile;
256 252
257 cfile->count = 1; 253 cfile->count = 1;
258 cfile->fid.netfid = fileHandle;
259 cfile->pid = current->tgid; 254 cfile->pid = current->tgid;
260 cfile->uid = current_fsuid(); 255 cfile->uid = current_fsuid();
261 cfile->dentry = dget(dentry); 256 cfile->dentry = dget(dentry);
@@ -265,6 +260,7 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
265 mutex_init(&cfile->fh_mutex); 260 mutex_init(&cfile->fh_mutex);
266 INIT_WORK(&cfile->oplock_break, cifs_oplock_break); 261 INIT_WORK(&cfile->oplock_break, cifs_oplock_break);
267 INIT_LIST_HEAD(&cfile->llist); 262 INIT_LIST_HEAD(&cfile->llist);
263 tlink_tcon(tlink)->ses->server->ops->set_fid(cfile, fid, oplock);
268 264
269 spin_lock(&cifs_file_list_lock); 265 spin_lock(&cifs_file_list_lock);
270 list_add(&cfile->tlist, &(tlink_tcon(tlink)->openFileList)); 266 list_add(&cfile->tlist, &(tlink_tcon(tlink)->openFileList));
@@ -275,9 +271,6 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
275 list_add_tail(&cfile->flist, &cinode->openFileList); 271 list_add_tail(&cfile->flist, &cinode->openFileList);
276 spin_unlock(&cifs_file_list_lock); 272 spin_unlock(&cifs_file_list_lock);
277 273
278 cifs_set_oplock_level(cinode, oplock);
279 cinode->can_cache_brlcks = cinode->clientCanCacheAll;
280
281 file->private_data = cfile; 274 file->private_data = cfile;
282 return cfile; 275 return cfile;
283} 276}
@@ -364,10 +357,10 @@ int cifs_open(struct inode *inode, struct file *file)
364 struct cifs_sb_info *cifs_sb; 357 struct cifs_sb_info *cifs_sb;
365 struct cifs_tcon *tcon; 358 struct cifs_tcon *tcon;
366 struct tcon_link *tlink; 359 struct tcon_link *tlink;
367 struct cifsFileInfo *pCifsFile = NULL; 360 struct cifsFileInfo *cfile = NULL;
368 char *full_path = NULL; 361 char *full_path = NULL;
369 bool posix_open_ok = false; 362 bool posix_open_ok = false;
370 __u16 netfid; 363 struct cifs_fid fid;
371 364
372 xid = get_xid(); 365 xid = get_xid();
373 366
@@ -399,7 +392,7 @@ int cifs_open(struct inode *inode, struct file *file)
399 /* can not refresh inode info since size could be stale */ 392 /* can not refresh inode info since size could be stale */
400 rc = cifs_posix_open(full_path, &inode, inode->i_sb, 393 rc = cifs_posix_open(full_path, &inode, inode->i_sb,
401 cifs_sb->mnt_file_mode /* ignored */, 394 cifs_sb->mnt_file_mode /* ignored */,
402 file->f_flags, &oplock, &netfid, xid); 395 file->f_flags, &oplock, &fid.netfid, xid);
403 if (rc == 0) { 396 if (rc == 0) {
404 cFYI(1, "posix open succeeded"); 397 cFYI(1, "posix open succeeded");
405 posix_open_ok = true; 398 posix_open_ok = true;
@@ -415,20 +408,22 @@ int cifs_open(struct inode *inode, struct file *file)
415 } else if ((rc != -EIO) && (rc != -EREMOTE) && 408 } else if ((rc != -EIO) && (rc != -EREMOTE) &&
416 (rc != -EOPNOTSUPP)) /* path not found or net err */ 409 (rc != -EOPNOTSUPP)) /* path not found or net err */
417 goto out; 410 goto out;
418 /* else fallthrough to retry open the old way on network i/o 411 /*
419 or DFS errors */ 412 * Else fallthrough to retry open the old way on network i/o
413 * or DFS errors.
414 */
420 } 415 }
421 416
422 if (!posix_open_ok) { 417 if (!posix_open_ok) {
423 rc = cifs_nt_open(full_path, inode, cifs_sb, tcon, 418 rc = cifs_nt_open(full_path, inode, cifs_sb, tcon,
424 file->f_flags, &oplock, &netfid, xid); 419 file->f_flags, &oplock, &fid, xid);
425 if (rc) 420 if (rc)
426 goto out; 421 goto out;
427 } 422 }
428 423
429 pCifsFile = cifs_new_fileinfo(netfid, file, tlink, oplock); 424 cfile = cifs_new_fileinfo(&fid, file, tlink, oplock);
430 if (pCifsFile == NULL) { 425 if (cfile == NULL) {
431 CIFSSMBClose(xid, tcon, netfid); 426 CIFSSMBClose(xid, tcon, fid.netfid);
432 rc = -ENOMEM; 427 rc = -ENOMEM;
433 goto out; 428 goto out;
434 } 429 }
@@ -436,8 +431,10 @@ int cifs_open(struct inode *inode, struct file *file)
436 cifs_fscache_set_inode_cookie(inode, file); 431 cifs_fscache_set_inode_cookie(inode, file);
437 432
438 if ((oplock & CIFS_CREATE_ACTION) && !posix_open_ok && tcon->unix_ext) { 433 if ((oplock & CIFS_CREATE_ACTION) && !posix_open_ok && tcon->unix_ext) {
439 /* time to set mode which we can not set earlier due to 434 /*
440 problems creating new read-only files */ 435 * Time to set mode which we can not set earlier due to
436 * problems creating new read-only files.
437 */
441 struct cifs_unix_set_info_args args = { 438 struct cifs_unix_set_info_args args = {
442 .mode = inode->i_mode, 439 .mode = inode->i_mode,
443 .uid = NO_CHANGE_64, 440 .uid = NO_CHANGE_64,
@@ -447,8 +444,8 @@ int cifs_open(struct inode *inode, struct file *file)
447 .mtime = NO_CHANGE_64, 444 .mtime = NO_CHANGE_64,
448 .device = 0, 445 .device = 0,
449 }; 446 };
450 CIFSSMBUnixSetFileInfo(xid, tcon, &args, netfid, 447 CIFSSMBUnixSetFileInfo(xid, tcon, &args, fid.netfid,
451 pCifsFile->pid); 448 cfile->pid);
452 } 449 }
453 450
454out: 451out:
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index b170da0a882d..907b30865000 100644
--- a/fs/cifs/smb1ops.c
+++ b/fs/cifs/smb1ops.c
@@ -607,6 +607,33 @@ cifs_mkdir_setinfo(struct inode *inode, const char *full_path,
607 cifsInode->cifsAttrs = dosattrs; 607 cifsInode->cifsAttrs = dosattrs;
608} 608}
609 609
610static int
611cifs_open_file(const unsigned int xid, struct cifs_tcon *tcon, const char *path,
612 int disposition, int desired_access, int create_options,
613 struct cifs_fid *fid, __u32 *oplock, FILE_ALL_INFO *buf,
614 struct cifs_sb_info *cifs_sb)
615{
616 if (!(tcon->ses->capabilities & CAP_NT_SMBS))
617 return SMBLegacyOpen(xid, tcon, path, disposition,
618 desired_access, CREATE_NOT_DIR,
619 &fid->netfid, oplock, buf,
620 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
621 & CIFS_MOUNT_MAP_SPECIAL_CHR);
622 return CIFSSMBOpen(xid, tcon, path, disposition, desired_access,
623 create_options, &fid->netfid, oplock, buf,
624 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
625 CIFS_MOUNT_MAP_SPECIAL_CHR);
626}
627
628static void
629cifs_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock)
630{
631 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
632 cfile->fid.netfid = fid->netfid;
633 cifs_set_oplock_level(cinode, oplock);
634 cinode->can_cache_brlcks = cinode->clientCanCacheAll;
635}
636
610struct smb_version_operations smb1_operations = { 637struct smb_version_operations smb1_operations = {
611 .send_cancel = send_nt_cancel, 638 .send_cancel = send_nt_cancel,
612 .compare_fids = cifs_compare_fids, 639 .compare_fids = cifs_compare_fids,
@@ -646,6 +673,8 @@ struct smb_version_operations smb1_operations = {
646 .rmdir = CIFSSMBRmDir, 673 .rmdir = CIFSSMBRmDir,
647 .unlink = CIFSSMBDelFile, 674 .unlink = CIFSSMBDelFile,
648 .rename_pending_delete = cifs_rename_pending_delete, 675 .rename_pending_delete = cifs_rename_pending_delete,
676 .open = cifs_open_file,
677 .set_fid = cifs_set_fid,
649}; 678};
650 679
651struct smb_version_values smb1_values = { 680struct smb_version_values smb1_values = {