Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
[linux-2.6-microblaze.git] / fs / cifs / cifsglob.h
index 8de977c..68da230 100644 (file)
  * CIFS vfs client Status information (based on what we know.)
  */
 
-/* associated with each tcp and smb session */
+/* associated with each connection */
 enum statusEnum {
        CifsNew = 0,
        CifsGood,
@@ -114,8 +114,15 @@ enum statusEnum {
        CifsNeedReconnect,
        CifsNeedNegotiate,
        CifsInNegotiate,
-       CifsNeedSessSetup,
-       CifsInSessSetup,
+};
+
+/* associated with each smb session */
+enum ses_status_enum {
+       SES_NEW = 0,
+       SES_GOOD,
+       SES_EXITING,
+       SES_NEED_RECON,
+       SES_IN_SETUP
 };
 
 /* associated with each tree connection to the server */
@@ -915,6 +922,7 @@ struct cifs_server_iface {
 };
 
 struct cifs_chan {
+       unsigned int in_reconnect : 1; /* if session setup in progress for this channel */
        struct TCP_Server_Info *server;
        __u8 signkey[SMB3_SIGN_KEY_SIZE];
 };
@@ -930,7 +938,7 @@ struct cifs_ses {
        struct mutex session_mutex;
        struct TCP_Server_Info *server; /* pointer to server info */
        int ses_count;          /* reference counter */
-       enum statusEnum status;  /* updates protected by cifs_tcp_ses_lock */
+       enum ses_status_enum ses_status;  /* updates protected by cifs_tcp_ses_lock */
        unsigned overrideSecFlg;  /* if non-zero override global sec flags */
        char *serverOS;         /* name of operating system underlying server */
        char *serverNOS;        /* name of network operating system of server */
@@ -944,7 +952,7 @@ struct cifs_ses {
                                   and after mount option parsing we fill it */
        char *domainName;
        char *password;
-       char *workstation_name;
+       char workstation_name[CIFS_MAX_WORKSTATION_LEN];
        struct session_key auth_key;
        struct ntlmssp_auth *ntlmssp; /* ciphertext, flags, server challenge */
        enum securityEnum sectype; /* what security flavor was specified? */
@@ -977,12 +985,16 @@ struct cifs_ses {
 #define CIFS_MAX_CHANNELS 16
 #define CIFS_ALL_CHANNELS_SET(ses)     \
        ((1UL << (ses)->chan_count) - 1)
+#define CIFS_ALL_CHANS_GOOD(ses)               \
+       (!(ses)->chans_need_reconnect)
 #define CIFS_ALL_CHANS_NEED_RECONNECT(ses)     \
        ((ses)->chans_need_reconnect == CIFS_ALL_CHANNELS_SET(ses))
 #define CIFS_SET_ALL_CHANS_NEED_RECONNECT(ses) \
        ((ses)->chans_need_reconnect = CIFS_ALL_CHANNELS_SET(ses))
 #define CIFS_CHAN_NEEDS_RECONNECT(ses, index)  \
        test_bit((index), &(ses)->chans_need_reconnect)
+#define CIFS_CHAN_IN_RECONNECT(ses, index)     \
+       ((ses)->chans[(index)].in_reconnect)
 
        struct cifs_chan chans[CIFS_MAX_CHANNELS];
        size_t chan_count;
@@ -1009,6 +1021,58 @@ cap_unix(struct cifs_ses *ses)
        return ses->server->vals->cap_unix & ses->capabilities;
 }
 
+/*
+ * common struct for holding inode info when searching for or updating an
+ * inode with new info
+ */
+
+#define CIFS_FATTR_DFS_REFERRAL                0x1
+#define CIFS_FATTR_DELETE_PENDING      0x2
+#define CIFS_FATTR_NEED_REVAL          0x4
+#define CIFS_FATTR_INO_COLLISION       0x8
+#define CIFS_FATTR_UNKNOWN_NLINK       0x10
+#define CIFS_FATTR_FAKE_ROOT_INO       0x20
+
+struct cifs_fattr {
+       u32             cf_flags;
+       u32             cf_cifsattrs;
+       u64             cf_uniqueid;
+       u64             cf_eof;
+       u64             cf_bytes;
+       u64             cf_createtime;
+       kuid_t          cf_uid;
+       kgid_t          cf_gid;
+       umode_t         cf_mode;
+       dev_t           cf_rdev;
+       unsigned int    cf_nlink;
+       unsigned int    cf_dtype;
+       struct timespec64 cf_atime;
+       struct timespec64 cf_mtime;
+       struct timespec64 cf_ctime;
+       u32             cf_cifstag;
+};
+
+struct cached_dirent {
+       struct list_head entry;
+       char *name;
+       int namelen;
+       loff_t pos;
+
+       struct cifs_fattr fattr;
+};
+
+struct cached_dirents {
+       bool is_valid:1;
+       bool is_failed:1;
+       struct dir_context *ctx; /*
+                                 * Only used to make sure we only take entries
+                                 * from a single context. Never dereferenced.
+                                 */
+       struct mutex de_mutex;
+       int pos;                 /* Expected ctx->pos */
+       struct list_head entries;
+};
+
 struct cached_fid {
        bool is_valid:1;        /* Do we have a useable root fid */
        bool file_all_info_is_valid:1;
@@ -1021,6 +1085,7 @@ struct cached_fid {
        struct dentry *dentry;
        struct work_struct lease_break;
        struct smb2_file_all_info file_all_info;
+       struct cached_dirents dirents;
 };
 
 /*
@@ -1641,37 +1706,6 @@ struct file_list {
        struct cifsFileInfo *cfile;
 };
 
-/*
- * common struct for holding inode info when searching for or updating an
- * inode with new info
- */
-
-#define CIFS_FATTR_DFS_REFERRAL                0x1
-#define CIFS_FATTR_DELETE_PENDING      0x2
-#define CIFS_FATTR_NEED_REVAL          0x4
-#define CIFS_FATTR_INO_COLLISION       0x8
-#define CIFS_FATTR_UNKNOWN_NLINK       0x10
-#define CIFS_FATTR_FAKE_ROOT_INO       0x20
-
-struct cifs_fattr {
-       u32             cf_flags;
-       u32             cf_cifsattrs;
-       u64             cf_uniqueid;
-       u64             cf_eof;
-       u64             cf_bytes;
-       u64             cf_createtime;
-       kuid_t          cf_uid;
-       kgid_t          cf_gid;
-       umode_t         cf_mode;
-       dev_t           cf_rdev;
-       unsigned int    cf_nlink;
-       unsigned int    cf_dtype;
-       struct timespec64 cf_atime;
-       struct timespec64 cf_mtime;
-       struct timespec64 cf_ctime;
-       u32             cf_cifstag;
-};
-
 static inline void free_dfs_info_param(struct dfs_info3_param *param)
 {
        if (param) {
@@ -1979,4 +2013,22 @@ static inline bool cifs_is_referral_server(struct cifs_tcon *tcon,
        return is_tcon_dfs(tcon) || (ref && (ref->flags & DFSREF_REFERRAL_SERVER));
 }
 
+static inline u64 cifs_flock_len(struct file_lock *fl)
+{
+       return fl->fl_end == OFFSET_MAX ? 0 : fl->fl_end - fl->fl_start + 1;
+}
+
+static inline size_t ntlmssp_workstation_name_size(const struct cifs_ses *ses)
+{
+       if (WARN_ON_ONCE(!ses || !ses->server))
+               return 0;
+       /*
+        * Make workstation name no more than 15 chars when using insecure dialects as some legacy
+        * servers do require it during NTLMSSP.
+        */
+       if (ses->server->dialect <= SMB20_PROT_ID)
+               return min_t(size_t, sizeof(ses->workstation_name), RFC1001_NAME_LEN_WITH_NULL);
+       return sizeof(ses->workstation_name);
+}
+
 #endif /* _CIFS_GLOB_H */