diff options
Diffstat (limited to 'fs/cifs/cifsfs.c')
-rw-r--r-- | fs/cifs/cifsfs.c | 92 |
1 files changed, 67 insertions, 25 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 50208c15309a..34371637f210 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
36 | #include <linux/kthread.h> | 36 | #include <linux/kthread.h> |
37 | #include <linux/freezer.h> | 37 | #include <linux/freezer.h> |
38 | #include <net/ipv6.h> | ||
38 | #include "cifsfs.h" | 39 | #include "cifsfs.h" |
39 | #include "cifspdu.h" | 40 | #include "cifspdu.h" |
40 | #define DECLARE_GLOBALS_HERE | 41 | #define DECLARE_GLOBALS_HERE |
@@ -81,6 +82,24 @@ extern mempool_t *cifs_sm_req_poolp; | |||
81 | extern mempool_t *cifs_req_poolp; | 82 | extern mempool_t *cifs_req_poolp; |
82 | extern mempool_t *cifs_mid_poolp; | 83 | extern mempool_t *cifs_mid_poolp; |
83 | 84 | ||
85 | void | ||
86 | cifs_sb_active(struct super_block *sb) | ||
87 | { | ||
88 | struct cifs_sb_info *server = CIFS_SB(sb); | ||
89 | |||
90 | if (atomic_inc_return(&server->active) == 1) | ||
91 | atomic_inc(&sb->s_active); | ||
92 | } | ||
93 | |||
94 | void | ||
95 | cifs_sb_deactive(struct super_block *sb) | ||
96 | { | ||
97 | struct cifs_sb_info *server = CIFS_SB(sb); | ||
98 | |||
99 | if (atomic_dec_and_test(&server->active)) | ||
100 | deactivate_super(sb); | ||
101 | } | ||
102 | |||
84 | static int | 103 | static int |
85 | cifs_read_super(struct super_block *sb, void *data, | 104 | cifs_read_super(struct super_block *sb, void *data, |
86 | const char *devname, int silent) | 105 | const char *devname, int silent) |
@@ -96,6 +115,9 @@ cifs_read_super(struct super_block *sb, void *data, | |||
96 | if (cifs_sb == NULL) | 115 | if (cifs_sb == NULL) |
97 | return -ENOMEM; | 116 | return -ENOMEM; |
98 | 117 | ||
118 | spin_lock_init(&cifs_sb->tlink_tree_lock); | ||
119 | INIT_RADIX_TREE(&cifs_sb->tlink_tree, GFP_KERNEL); | ||
120 | |||
99 | rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); | 121 | rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); |
100 | if (rc) { | 122 | if (rc) { |
101 | kfree(cifs_sb); | 123 | kfree(cifs_sb); |
@@ -135,9 +157,6 @@ cifs_read_super(struct super_block *sb, void *data, | |||
135 | sb->s_magic = CIFS_MAGIC_NUMBER; | 157 | sb->s_magic = CIFS_MAGIC_NUMBER; |
136 | sb->s_op = &cifs_super_ops; | 158 | sb->s_op = &cifs_super_ops; |
137 | sb->s_bdi = &cifs_sb->bdi; | 159 | sb->s_bdi = &cifs_sb->bdi; |
138 | /* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512) | ||
139 | sb->s_blocksize = | ||
140 | cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */ | ||
141 | sb->s_blocksize = CIFS_MAX_MSGSIZE; | 160 | sb->s_blocksize = CIFS_MAX_MSGSIZE; |
142 | sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */ | 161 | sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */ |
143 | inode = cifs_root_iget(sb, ROOT_I); | 162 | inode = cifs_root_iget(sb, ROOT_I); |
@@ -219,7 +238,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
219 | { | 238 | { |
220 | struct super_block *sb = dentry->d_sb; | 239 | struct super_block *sb = dentry->d_sb; |
221 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 240 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
222 | struct cifsTconInfo *tcon = cifs_sb->tcon; | 241 | struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); |
223 | int rc = -EOPNOTSUPP; | 242 | int rc = -EOPNOTSUPP; |
224 | int xid; | 243 | int xid; |
225 | 244 | ||
@@ -361,14 +380,36 @@ static int | |||
361 | cifs_show_options(struct seq_file *s, struct vfsmount *m) | 380 | cifs_show_options(struct seq_file *s, struct vfsmount *m) |
362 | { | 381 | { |
363 | struct cifs_sb_info *cifs_sb = CIFS_SB(m->mnt_sb); | 382 | struct cifs_sb_info *cifs_sb = CIFS_SB(m->mnt_sb); |
364 | struct cifsTconInfo *tcon = cifs_sb->tcon; | 383 | struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); |
384 | struct sockaddr *srcaddr; | ||
385 | srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr; | ||
365 | 386 | ||
366 | seq_printf(s, ",unc=%s", tcon->treeName); | 387 | seq_printf(s, ",unc=%s", tcon->treeName); |
367 | if (tcon->ses->userName) | 388 | |
389 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) | ||
390 | seq_printf(s, ",multiuser"); | ||
391 | else if (tcon->ses->userName) | ||
368 | seq_printf(s, ",username=%s", tcon->ses->userName); | 392 | seq_printf(s, ",username=%s", tcon->ses->userName); |
393 | |||
369 | if (tcon->ses->domainName) | 394 | if (tcon->ses->domainName) |
370 | seq_printf(s, ",domain=%s", tcon->ses->domainName); | 395 | seq_printf(s, ",domain=%s", tcon->ses->domainName); |
371 | 396 | ||
397 | if (srcaddr->sa_family != AF_UNSPEC) { | ||
398 | struct sockaddr_in *saddr4; | ||
399 | struct sockaddr_in6 *saddr6; | ||
400 | saddr4 = (struct sockaddr_in *)srcaddr; | ||
401 | saddr6 = (struct sockaddr_in6 *)srcaddr; | ||
402 | if (srcaddr->sa_family == AF_INET6) | ||
403 | seq_printf(s, ",srcaddr=%pI6c", | ||
404 | &saddr6->sin6_addr); | ||
405 | else if (srcaddr->sa_family == AF_INET) | ||
406 | seq_printf(s, ",srcaddr=%pI4", | ||
407 | &saddr4->sin_addr.s_addr); | ||
408 | else | ||
409 | seq_printf(s, ",srcaddr=BAD-AF:%i", | ||
410 | (int)(srcaddr->sa_family)); | ||
411 | } | ||
412 | |||
372 | seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); | 413 | seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); |
373 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) | 414 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) |
374 | seq_printf(s, ",forceuid"); | 415 | seq_printf(s, ",forceuid"); |
@@ -417,6 +458,8 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) | |||
417 | seq_printf(s, ",dynperm"); | 458 | seq_printf(s, ",dynperm"); |
418 | if (m->mnt_sb->s_flags & MS_POSIXACL) | 459 | if (m->mnt_sb->s_flags & MS_POSIXACL) |
419 | seq_printf(s, ",acl"); | 460 | seq_printf(s, ",acl"); |
461 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) | ||
462 | seq_printf(s, ",mfsymlinks"); | ||
420 | 463 | ||
421 | seq_printf(s, ",rsize=%d", cifs_sb->rsize); | 464 | seq_printf(s, ",rsize=%d", cifs_sb->rsize); |
422 | seq_printf(s, ",wsize=%d", cifs_sb->wsize); | 465 | seq_printf(s, ",wsize=%d", cifs_sb->wsize); |
@@ -432,20 +475,18 @@ static void cifs_umount_begin(struct super_block *sb) | |||
432 | if (cifs_sb == NULL) | 475 | if (cifs_sb == NULL) |
433 | return; | 476 | return; |
434 | 477 | ||
435 | tcon = cifs_sb->tcon; | 478 | tcon = cifs_sb_master_tcon(cifs_sb); |
436 | if (tcon == NULL) | ||
437 | return; | ||
438 | 479 | ||
439 | read_lock(&cifs_tcp_ses_lock); | 480 | spin_lock(&cifs_tcp_ses_lock); |
440 | if ((tcon->tc_count > 1) || (tcon->tidStatus == CifsExiting)) { | 481 | if ((tcon->tc_count > 1) || (tcon->tidStatus == CifsExiting)) { |
441 | /* we have other mounts to same share or we have | 482 | /* we have other mounts to same share or we have |
442 | already tried to force umount this and woken up | 483 | already tried to force umount this and woken up |
443 | all waiting network requests, nothing to do */ | 484 | all waiting network requests, nothing to do */ |
444 | read_unlock(&cifs_tcp_ses_lock); | 485 | spin_unlock(&cifs_tcp_ses_lock); |
445 | return; | 486 | return; |
446 | } else if (tcon->tc_count == 1) | 487 | } else if (tcon->tc_count == 1) |
447 | tcon->tidStatus = CifsExiting; | 488 | tcon->tidStatus = CifsExiting; |
448 | read_unlock(&cifs_tcp_ses_lock); | 489 | spin_unlock(&cifs_tcp_ses_lock); |
449 | 490 | ||
450 | /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */ | 491 | /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */ |
451 | /* cancel_notify_requests(tcon); */ | 492 | /* cancel_notify_requests(tcon); */ |
@@ -565,6 +606,7 @@ static int cifs_setlease(struct file *file, long arg, struct file_lock **lease) | |||
565 | /* note that this is called by vfs setlease with lock_flocks held | 606 | /* note that this is called by vfs setlease with lock_flocks held |
566 | to protect *lease from going away */ | 607 | to protect *lease from going away */ |
567 | struct inode *inode = file->f_path.dentry->d_inode; | 608 | struct inode *inode = file->f_path.dentry->d_inode; |
609 | struct cifsFileInfo *cfile = file->private_data; | ||
568 | 610 | ||
569 | if (!(S_ISREG(inode->i_mode))) | 611 | if (!(S_ISREG(inode->i_mode))) |
570 | return -EINVAL; | 612 | return -EINVAL; |
@@ -575,8 +617,8 @@ static int cifs_setlease(struct file *file, long arg, struct file_lock **lease) | |||
575 | ((arg == F_WRLCK) && | 617 | ((arg == F_WRLCK) && |
576 | (CIFS_I(inode)->clientCanCacheAll))) | 618 | (CIFS_I(inode)->clientCanCacheAll))) |
577 | return generic_setlease(file, arg, lease); | 619 | return generic_setlease(file, arg, lease); |
578 | else if (CIFS_SB(inode->i_sb)->tcon->local_lease && | 620 | else if (tlink_tcon(cfile->tlink)->local_lease && |
579 | !CIFS_I(inode)->clientCanCacheRead) | 621 | !CIFS_I(inode)->clientCanCacheRead) |
580 | /* If the server claims to support oplock on this | 622 | /* If the server claims to support oplock on this |
581 | file, then we still need to check oplock even | 623 | file, then we still need to check oplock even |
582 | if the local_lease mount option is set, but there | 624 | if the local_lease mount option is set, but there |
@@ -895,8 +937,8 @@ init_cifs(void) | |||
895 | GlobalTotalActiveXid = 0; | 937 | GlobalTotalActiveXid = 0; |
896 | GlobalMaxActiveXid = 0; | 938 | GlobalMaxActiveXid = 0; |
897 | memset(Local_System_Name, 0, 15); | 939 | memset(Local_System_Name, 0, 15); |
898 | rwlock_init(&GlobalSMBSeslock); | 940 | spin_lock_init(&cifs_tcp_ses_lock); |
899 | rwlock_init(&cifs_tcp_ses_lock); | 941 | spin_lock_init(&cifs_file_list_lock); |
900 | spin_lock_init(&GlobalMid_Lock); | 942 | spin_lock_init(&GlobalMid_Lock); |
901 | 943 | ||
902 | if (cifs_max_pending < 2) { | 944 | if (cifs_max_pending < 2) { |
@@ -909,11 +951,11 @@ init_cifs(void) | |||
909 | 951 | ||
910 | rc = cifs_fscache_register(); | 952 | rc = cifs_fscache_register(); |
911 | if (rc) | 953 | if (rc) |
912 | goto out; | 954 | goto out_clean_proc; |
913 | 955 | ||
914 | rc = cifs_init_inodecache(); | 956 | rc = cifs_init_inodecache(); |
915 | if (rc) | 957 | if (rc) |
916 | goto out_clean_proc; | 958 | goto out_unreg_fscache; |
917 | 959 | ||
918 | rc = cifs_init_mids(); | 960 | rc = cifs_init_mids(); |
919 | if (rc) | 961 | if (rc) |
@@ -935,19 +977,19 @@ init_cifs(void) | |||
935 | return 0; | 977 | return 0; |
936 | 978 | ||
937 | #ifdef CONFIG_CIFS_UPCALL | 979 | #ifdef CONFIG_CIFS_UPCALL |
938 | out_unregister_filesystem: | 980 | out_unregister_filesystem: |
939 | unregister_filesystem(&cifs_fs_type); | 981 | unregister_filesystem(&cifs_fs_type); |
940 | #endif | 982 | #endif |
941 | out_destroy_request_bufs: | 983 | out_destroy_request_bufs: |
942 | cifs_destroy_request_bufs(); | 984 | cifs_destroy_request_bufs(); |
943 | out_destroy_mids: | 985 | out_destroy_mids: |
944 | cifs_destroy_mids(); | 986 | cifs_destroy_mids(); |
945 | out_destroy_inodecache: | 987 | out_destroy_inodecache: |
946 | cifs_destroy_inodecache(); | 988 | cifs_destroy_inodecache(); |
947 | out_clean_proc: | 989 | out_unreg_fscache: |
948 | cifs_proc_clean(); | ||
949 | cifs_fscache_unregister(); | 990 | cifs_fscache_unregister(); |
950 | out: | 991 | out_clean_proc: |
992 | cifs_proc_clean(); | ||
951 | return rc; | 993 | return rc; |
952 | } | 994 | } |
953 | 995 | ||