Merge branch 'stable-3.2' into pandora-3.2
[pandora-kernel.git] / fs / cifs / cifsfs.c
index 8f1fe32..1d480aa 100644 (file)
@@ -54,6 +54,7 @@ int cifsFYI = 0;
 int cifsERROR = 1;
 int traceSMB = 0;
 bool enable_oplocks = true;
+bool no_serverino_autodisable = false;
 unsigned int linuxExtEnabled = 1;
 unsigned int lookupCacheEnabled = 1;
 unsigned int multiuser_mount = 0;
@@ -76,7 +77,7 @@ MODULE_PARM_DESC(cifs_min_small, "Small network buffers in pool. Default: 30 "
 unsigned int cifs_max_pending = CIFS_MAX_REQ;
 module_param(cifs_max_pending, int, 0444);
 MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server. "
-                                  "Default: 50 Range: 2 to 256");
+                                  "Default: 32767 Range: 2 to 32767.");
 unsigned short echo_retries = 5;
 module_param(echo_retries, ushort, 0644);
 MODULE_PARM_DESC(echo_retries, "Number of echo attempts before giving up and "
@@ -85,11 +86,36 @@ MODULE_PARM_DESC(echo_retries, "Number of echo attempts before giving up and "
 module_param(enable_oplocks, bool, 0644);
 MODULE_PARM_DESC(enable_oplocks, "Enable or disable oplocks (bool). Default:"
                                 "y/Y/1");
+module_param(no_serverino_autodisable, bool, 0644);
 
 extern mempool_t *cifs_sm_req_poolp;
 extern mempool_t *cifs_req_poolp;
 extern mempool_t *cifs_mid_poolp;
 
+/*
+ * Bumps refcount for cifs super block.
+ * Note that it should be only called if a referece to VFS super block is
+ * already held, e.g. in open-type syscalls context. Otherwise it can race with
+ * atomic_dec_and_test in deactivate_locked_super.
+ */
+void
+cifs_sb_active(struct super_block *sb)
+{
+       struct cifs_sb_info *server = CIFS_SB(sb);
+
+       if (atomic_inc_return(&server->active) == 1)
+               atomic_inc(&sb->s_active);
+}
+
+void
+cifs_sb_deactive(struct super_block *sb)
+{
+       struct cifs_sb_info *server = CIFS_SB(sb);
+
+       if (atomic_dec_and_test(&server->active))
+               deactivate_super(sb);
+}
+
 static int
 cifs_read_super(struct super_block *sb)
 {
@@ -357,10 +383,10 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)
                seq_printf(s, ",multiuser");
        else if (tcon->ses->user_name)
-               seq_printf(s, ",username=%s", tcon->ses->user_name);
+               seq_show_option(s, "username", tcon->ses->user_name);
 
        if (tcon->ses->domainName)
-               seq_printf(s, ",domain=%s", tcon->ses->domainName);
+               seq_show_option(s, "domain", tcon->ses->domainName);
 
        if (srcaddr->sa_family != AF_UNSPEC) {
                struct sockaddr_in *saddr4;
@@ -561,6 +587,11 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
                        dentry = ERR_PTR(-ENOENT);
                        break;
                }
+               if (!S_ISDIR(dir->i_mode)) {
+                       dput(dentry);
+                       dentry = ERR_PTR(-ENOTDIR);
+                       break;
+               }
 
                /* skip separators */
                while (*s == sep)
@@ -703,7 +734,7 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
         * origin == SEEK_END || SEEK_DATA || SEEK_HOLE => we must revalidate
         * the cached file length
         */
-       if (origin != SEEK_SET || origin != SEEK_CUR) {
+       if (origin != SEEK_SET && origin != SEEK_CUR) {
                int rc;
                struct inode *inode = file->f_path.dentry->d_inode;
 
@@ -1116,9 +1147,9 @@ init_cifs(void)
        if (cifs_max_pending < 2) {
                cifs_max_pending = 2;
                cFYI(1, "cifs_max_pending set to min of 2");
-       } else if (cifs_max_pending > 256) {
-               cifs_max_pending = 256;
-               cFYI(1, "cifs_max_pending set to max of 256");
+       } else if (cifs_max_pending > CIFS_MAX_REQ) {
+               cifs_max_pending = CIFS_MAX_REQ;
+               cFYI(1, "cifs_max_pending set to max of %u", CIFS_MAX_REQ);
        }
 
        rc = cifs_fscache_register();