aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/dir.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2010-09-29 19:51:11 -0400
committerSteve French <sfrench@us.ibm.com>2010-10-06 12:12:44 -0400
commit7ffec372458d163492e56e663a1b3a2d7be0a0a2 (patch)
treee404e3d1000ff41e9b27d0ecb4d6a47187e110d7 /fs/cifs/dir.c
parentf3983c2133e9bea9c8b4f690737d15e3e9b02491 (diff)
cifs: add refcounted and timestamped container for holding tcons
Eventually, we'll need to track the use of tcons on a per-sb basis, so that we know when it's ok to tear them down. Begin this conversion by adding a new "tcon_link" struct and accessors that get it. For now, the core data structures are untouched -- cifs_sb still just points to a single tcon and the pointers are just cast to deal with the accessor functions. A later patch will flesh this out. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/dir.c')
-rw-r--r--fs/cifs/dir.c65
1 files changed, 48 insertions, 17 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 23ec28a4c11f..bb3ea06ca6f4 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -137,7 +137,6 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, struct file *file,
137{ 137{
138 struct cifsFileInfo *pCifsFile; 138 struct cifsFileInfo *pCifsFile;
139 struct cifsInodeInfo *pCifsInode; 139 struct cifsInodeInfo *pCifsInode;
140 struct cifs_sb_info *cifs_sb = CIFS_SB(mnt->mnt_sb);
141 140
142 pCifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); 141 pCifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
143 if (pCifsFile == NULL) 142 if (pCifsFile == NULL)
@@ -191,7 +190,8 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
191 __u32 posix_flags = 0; 190 __u32 posix_flags = 0;
192 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 191 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
193 struct cifs_fattr fattr; 192 struct cifs_fattr fattr;
194 struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb); 193 struct tcon_link *tlink;
194 struct cifsTconInfo *tcon;
195 195
196 cFYI(1, "posix open %s", full_path); 196 cFYI(1, "posix open %s", full_path);
197 197
@@ -226,10 +226,20 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
226 posix_flags |= SMB_O_DIRECT; 226 posix_flags |= SMB_O_DIRECT;
227 227
228 mode &= ~current_umask(); 228 mode &= ~current_umask();
229
230 tlink = cifs_sb_tlink(cifs_sb);
231 if (IS_ERR(tlink)) {
232 rc = PTR_ERR(tlink);
233 goto posix_open_ret;
234 }
235
236 tcon = tlink_tcon(tlink);
229 rc = CIFSPOSIXCreate(xid, tcon, posix_flags, mode, pnetfid, presp_data, 237 rc = CIFSPOSIXCreate(xid, tcon, posix_flags, mode, pnetfid, presp_data,
230 poplock, full_path, cifs_sb->local_nls, 238 poplock, full_path, cifs_sb->local_nls,
231 cifs_sb->mnt_cifs_flags & 239 cifs_sb->mnt_cifs_flags &
232 CIFS_MOUNT_MAP_SPECIAL_CHR); 240 CIFS_MOUNT_MAP_SPECIAL_CHR);
241 cifs_put_tlink(tlink);
242
233 if (rc) 243 if (rc)
234 goto posix_open_ret; 244 goto posix_open_ret;
235 245
@@ -290,6 +300,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
290 int desiredAccess = GENERIC_READ | GENERIC_WRITE; 300 int desiredAccess = GENERIC_READ | GENERIC_WRITE;
291 __u16 fileHandle; 301 __u16 fileHandle;
292 struct cifs_sb_info *cifs_sb; 302 struct cifs_sb_info *cifs_sb;
303 struct tcon_link *tlink;
293 struct cifsTconInfo *tcon; 304 struct cifsTconInfo *tcon;
294 char *full_path = NULL; 305 char *full_path = NULL;
295 FILE_ALL_INFO *buf = NULL; 306 FILE_ALL_INFO *buf = NULL;
@@ -299,13 +310,12 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
299 xid = GetXid(); 310 xid = GetXid();
300 311
301 cifs_sb = CIFS_SB(inode->i_sb); 312 cifs_sb = CIFS_SB(inode->i_sb);
302 tcon = cifs_sb_tcon(cifs_sb); 313 tlink = cifs_sb_tlink(cifs_sb);
303 314 if (IS_ERR(tlink)) {
304 full_path = build_path_from_dentry(direntry); 315 FreeXid(xid);
305 if (full_path == NULL) { 316 return PTR_ERR(tlink);
306 rc = -ENOMEM;
307 goto cifs_create_out;
308 } 317 }
318 tcon = tlink_tcon(tlink);
309 319
310 if (oplockEnabled) 320 if (oplockEnabled)
311 oplock = REQ_OPLOCK; 321 oplock = REQ_OPLOCK;
@@ -315,6 +325,12 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
315 else 325 else
316 oflags = FMODE_READ | SMB_O_CREAT; 326 oflags = FMODE_READ | SMB_O_CREAT;
317 327
328 full_path = build_path_from_dentry(direntry);
329 if (full_path == NULL) {
330 rc = -ENOMEM;
331 goto cifs_create_out;
332 }
333
318 if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) && 334 if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
319 (CIFS_UNIX_POSIX_PATH_OPS_CAP & 335 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
320 le64_to_cpu(tcon->fsUnixInfo.Capability))) { 336 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
@@ -481,6 +497,7 @@ cifs_create_set_dentry:
481cifs_create_out: 497cifs_create_out:
482 kfree(buf); 498 kfree(buf);
483 kfree(full_path); 499 kfree(full_path);
500 cifs_put_tlink(tlink);
484 FreeXid(xid); 501 FreeXid(xid);
485 return rc; 502 return rc;
486} 503}
@@ -491,6 +508,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
491 int rc = -EPERM; 508 int rc = -EPERM;
492 int xid; 509 int xid;
493 struct cifs_sb_info *cifs_sb; 510 struct cifs_sb_info *cifs_sb;
511 struct tcon_link *tlink;
494 struct cifsTconInfo *pTcon; 512 struct cifsTconInfo *pTcon;
495 char *full_path = NULL; 513 char *full_path = NULL;
496 struct inode *newinode = NULL; 514 struct inode *newinode = NULL;
@@ -503,10 +521,14 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
503 if (!old_valid_dev(device_number)) 521 if (!old_valid_dev(device_number))
504 return -EINVAL; 522 return -EINVAL;
505 523
506 xid = GetXid();
507
508 cifs_sb = CIFS_SB(inode->i_sb); 524 cifs_sb = CIFS_SB(inode->i_sb);
509 pTcon = cifs_sb_tcon(cifs_sb); 525 tlink = cifs_sb_tlink(cifs_sb);
526 if (IS_ERR(tlink))
527 return PTR_ERR(tlink);
528
529 pTcon = tlink_tcon(tlink);
530
531 xid = GetXid();
510 532
511 full_path = build_path_from_dentry(direntry); 533 full_path = build_path_from_dentry(direntry);
512 if (full_path == NULL) { 534 if (full_path == NULL) {
@@ -606,6 +628,7 @@ mknod_out:
606 kfree(full_path); 628 kfree(full_path);
607 kfree(buf); 629 kfree(buf);
608 FreeXid(xid); 630 FreeXid(xid);
631 cifs_put_tlink(tlink);
609 return rc; 632 return rc;
610} 633}
611 634
@@ -619,6 +642,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
619 __u16 fileHandle = 0; 642 __u16 fileHandle = 0;
620 bool posix_open = false; 643 bool posix_open = false;
621 struct cifs_sb_info *cifs_sb; 644 struct cifs_sb_info *cifs_sb;
645 struct tcon_link *tlink;
622 struct cifsTconInfo *pTcon; 646 struct cifsTconInfo *pTcon;
623 struct cifsFileInfo *cfile; 647 struct cifsFileInfo *cfile;
624 struct inode *newInode = NULL; 648 struct inode *newInode = NULL;
@@ -633,7 +657,12 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
633 /* check whether path exists */ 657 /* check whether path exists */
634 658
635 cifs_sb = CIFS_SB(parent_dir_inode->i_sb); 659 cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
636 pTcon = cifs_sb_tcon(cifs_sb); 660 tlink = cifs_sb_tlink(cifs_sb);
661 if (IS_ERR(tlink)) {
662 FreeXid(xid);
663 return (struct dentry *)tlink;
664 }
665 pTcon = tlink_tcon(tlink);
637 666
638 /* 667 /*
639 * Don't allow the separator character in a path component. 668 * Don't allow the separator character in a path component.
@@ -644,8 +673,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
644 for (i = 0; i < direntry->d_name.len; i++) 673 for (i = 0; i < direntry->d_name.len; i++)
645 if (direntry->d_name.name[i] == '\\') { 674 if (direntry->d_name.name[i] == '\\') {
646 cFYI(1, "Invalid file name"); 675 cFYI(1, "Invalid file name");
647 FreeXid(xid); 676 rc = -EINVAL;
648 return ERR_PTR(-EINVAL); 677 goto lookup_out;
649 } 678 }
650 } 679 }
651 680
@@ -655,7 +684,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
655 */ 684 */
656 if (nd && (nd->flags & LOOKUP_EXCL)) { 685 if (nd && (nd->flags & LOOKUP_EXCL)) {
657 d_instantiate(direntry, NULL); 686 d_instantiate(direntry, NULL);
658 return NULL; 687 rc = 0;
688 goto lookup_out;
659 } 689 }
660 690
661 /* can not grab the rename sem here since it would 691 /* can not grab the rename sem here since it would
@@ -663,8 +693,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
663 in which we already have the sb rename sem */ 693 in which we already have the sb rename sem */
664 full_path = build_path_from_dentry(direntry); 694 full_path = build_path_from_dentry(direntry);
665 if (full_path == NULL) { 695 if (full_path == NULL) {
666 FreeXid(xid); 696 rc = -ENOMEM;
667 return ERR_PTR(-ENOMEM); 697 goto lookup_out;
668 } 698 }
669 699
670 if (direntry->d_inode != NULL) { 700 if (direntry->d_inode != NULL) {
@@ -760,6 +790,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
760 790
761lookup_out: 791lookup_out:
762 kfree(full_path); 792 kfree(full_path);
793 cifs_put_tlink(tlink);
763 FreeXid(xid); 794 FreeXid(xid);
764 return ERR_PTR(rc); 795 return ERR_PTR(rc);
765} 796}