diff options
author | Pavel Shilovsky <pshilovsky@samba.org> | 2012-09-18 19:20:26 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2012-09-24 22:46:26 -0400 |
commit | fb1214e48f735cdb68446adb77ec37aa3de60697 (patch) | |
tree | 158dbfbedaf396f013e70f5288fdc906e990391c | |
parent | 4b4de76e35518fc0c636f628abca8c1b19ad6689 (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.h | 7 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 7 | ||||
-rw-r--r-- | fs/cifs/dir.c | 17 | ||||
-rw-r--r-- | fs/cifs/file.c | 63 | ||||
-rw-r--r-- | fs/cifs/smb1ops.c | 29 |
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; | |||
171 | struct dfs_info3_param; | 171 | struct dfs_info3_param; |
172 | struct cifs_fattr; | 172 | struct cifs_fattr; |
173 | struct smb_vol; | 173 | struct smb_vol; |
174 | struct cifs_fid; | ||
174 | 175 | ||
175 | struct smb_version_operations { | 176 | struct 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 | ||
267 | struct smb_version_values { | 274 | struct 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); |
122 | extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock); | 122 | extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock); |
123 | 123 | ||
124 | extern struct cifsFileInfo *cifs_new_fileinfo(__u16 fileHandle, | 124 | extern 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); | ||
127 | extern int cifs_posix_open(char *full_path, struct inode **inode, | 128 | extern 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 | ||
170 | static int | 170 | static int |
171 | cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb, | 171 | cifs_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 | ||
239 | out: | 235 | out: |
240 | kfree(buf); | 236 | kfree(buf); |
@@ -242,7 +238,7 @@ out: | |||
242 | } | 238 | } |
243 | 239 | ||
244 | struct cifsFileInfo * | 240 | struct cifsFileInfo * |
245 | cifs_new_fileinfo(__u16 fileHandle, struct file *file, | 241 | cifs_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 | ||
454 | out: | 451 | out: |
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 | ||
610 | static int | ||
611 | cifs_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 | |||
628 | static void | ||
629 | cifs_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 | |||
610 | struct smb_version_operations smb1_operations = { | 637 | struct 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 | ||
651 | struct smb_version_values smb1_values = { | 680 | struct smb_version_values smb1_values = { |