]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - fs/cifs/cifsglob.h
cifs: have cifsFileInfo hold a reference to a tlink rather than tcon pointer
[mirror_ubuntu-artful-kernel.git] / fs / cifs / cifsglob.h
index 0cdfb8c32ac68c34a98f5cdf412250c0eacdec2b..d5324853203b31489d2cb6875f3d8ade3ca65a77 100644 (file)
@@ -97,7 +97,7 @@ enum protocolEnum {
        /* Netbios frames protocol not supported at this time */
 };
 
-struct mac_key {
+struct session_key {
        unsigned int len;
        union {
                char ntlm[CIFS_SESS_KEY_SIZE + 16];
@@ -139,6 +139,7 @@ struct TCP_Server_Info {
                struct sockaddr_in sockAddr;
                struct sockaddr_in6 sockAddr6;
        } addr;
+       struct sockaddr_storage srcaddr; /* locally bind to this IP */
        wait_queue_head_t response_q;
        wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/
        struct list_head pending_mid_q;
@@ -182,7 +183,7 @@ struct TCP_Server_Info {
        /* 16th byte of RFC1001 workstation name is always null */
        char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
        __u32 sequence_number; /* needed for CIFS PDU signature */
-       struct mac_key mac_signing_key;
+       struct session_key session_key;
        char ntlmv2_hash[16];
        unsigned long lstrp; /* when we got last response from this server */
        u16 dialect; /* dialect index that server chose */
@@ -222,6 +223,8 @@ struct cifsSesInfo {
        char userName[MAX_USERNAME_SIZE + 1];
        char *domainName;
        char *password;
+       unsigned int tilen; /* length of the target info blob */
+       unsigned char *tiblob; /* target info blob in challenge response */
        bool need_reconnect:1; /* connection reset, uid now invalid */
 };
 /* no more than one of the following three session flags may be set */
@@ -307,6 +310,50 @@ struct cifsTconInfo {
        /* BB add field for back pointer to sb struct(s)? */
 };
 
+/*
+ * This is a refcounted and timestamped container for a tcon pointer. The
+ * container holds a tcon reference. It is considered safe to free one of
+ * these when the tl_count goes to 0. The tl_time is the time of the last
+ * "get" on the container.
+ */
+struct tcon_link {
+       spinlock_t              tl_lock;
+       u32                     tl_count;
+       u64                     tl_time;
+       struct cifsTconInfo     *tl_tcon;
+};
+
+static inline struct tcon_link *
+cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
+{
+       return (struct tcon_link *)cifs_sb->ptcon;
+}
+
+static inline struct cifsTconInfo *
+tlink_tcon(struct tcon_link *tlink)
+{
+       return (struct cifsTconInfo *)tlink;
+}
+
+static inline void
+cifs_put_tlink(struct tcon_link *tlink)
+{
+       return;
+}
+
+static inline struct tcon_link *
+cifs_get_tlink(struct tcon_link *tlink)
+{
+       return tlink;
+}
+
+/* This function is always expected to succeed */
+static inline struct cifsTconInfo *
+cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb)
+{
+       return cifs_sb->ptcon;
+}
+
 /*
  * This info hangs off the cifsFileInfo structure, pointed to by llist.
  * This is used to track byte stream locks on the file
@@ -348,6 +395,7 @@ struct cifsFileInfo {
        struct file *pfile; /* needed for writepage */
        struct inode *pInode; /* needed for oplock break */
        struct vfsmount *mnt;
+       struct tcon_link *tlink;
        struct mutex lock_mutex;
        struct list_head llist; /* list of byte range locks we have. */
        bool closePend:1;       /* file is marked to close */
@@ -369,6 +417,7 @@ static inline void cifsFileInfo_get(struct cifsFileInfo *cifs_file)
 static inline void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
 {
        if (atomic_dec_and_test(&cifs_file->count)) {
+               cifs_put_tlink(cifs_file->tlink);
                iput(cifs_file->pInode);
                kfree(cifs_file);
        }