forked from namjaejeon/ksmbd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoplock.h
137 lines (119 loc) · 4.14 KB
/
oplock.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2016 Namjae Jeon <[email protected]>
* Copyright (C) 2018 Samsung Electronics Co., Ltd.
*/
#ifndef __CIFSD_OPLOCK_H
#define __CIFSD_OPLOCK_H
#define OPLOCK_WAIT_TIME (35*HZ)
/* SMB Oplock levels */
#define OPLOCK_NONE 0
#define OPLOCK_EXCLUSIVE 1
#define OPLOCK_BATCH 2
#define OPLOCK_READ 3 /* level 2 oplock */
/* SMB2 Oplock levels */
#define SMB2_OPLOCK_LEVEL_NONE 0x00
#define SMB2_OPLOCK_LEVEL_II 0x01
#define SMB2_OPLOCK_LEVEL_EXCLUSIVE 0x08
#define SMB2_OPLOCK_LEVEL_BATCH 0x09
#define SMB2_OPLOCK_LEVEL_LEASE 0xFF
/* Oplock states */
#define OPLOCK_STATE_NONE 0x00
#define OPLOCK_ACK_WAIT 0x01
#define OPLOCK_CLOSING 0x02
#define OPLOCK_WRITE_TO_READ 0x01
#define OPLOCK_READ_HANDLE_TO_READ 0x02
#define OPLOCK_WRITE_TO_NONE 0x04
#define OPLOCK_READ_TO_NONE 0x08
#define SMB2_LEASE_KEY_SIZE 16
struct lease_ctx_info {
__u8 lease_key[SMB2_LEASE_KEY_SIZE];
__le32 req_state;
__le32 flags;
__le64 duration;
int dlease;
};
struct lease_table {
char client_guid[SMB2_CLIENT_GUID_SIZE];
struct list_head lease_list;
struct list_head l_entry;
spinlock_t lb_lock;
};
struct lease {
__u8 lease_key[SMB2_LEASE_KEY_SIZE];
__le32 state;
__le32 new_state;
__le32 flags;
__le64 duration;
struct lease_table *l_lb;
};
struct oplock_info {
struct cifsd_tcp_conn *conn;
struct cifsd_session *sess;
struct cifsd_work *work;
bool is_smb2;
struct cifsd_file *o_fp;
int level;
int op_state;
uint64_t fid;
__u16 Tid;
atomic_t breaking_cnt;
atomic_t refcount;
bool is_lease;
struct lease *o_lease;
struct list_head interim_list;
struct list_head op_entry;
struct list_head lease_entry;
wait_queue_head_t oplock_q; /* Other server threads */
wait_queue_head_t oplock_brk; /* oplock breaking wait */
bool open_trunc:1; /* truncate on open */
struct rcu_head rcu_head;
};
struct lease_break_info {
int curr_state;
int new_state;
char lease_key[SMB2_LEASE_KEY_SIZE];
};
struct oplock_break_info {
int level;
int open_trunc;
int fid;
};
extern int smb_grant_oplock(struct cifsd_work *work, int req_op_level,
uint64_t id, struct cifsd_file *fp, __u16 Tid,
struct lease_ctx_info *lctx, int share_ret);
extern void smb1_send_oplock_break_notification(struct work_struct *wk);
extern void smb2_send_oplock_break_notification(struct work_struct *wk);
extern void smb_break_all_levII_oplock(struct cifsd_tcp_conn *conn,
struct cifsd_file *fp, int is_trunc);
int opinfo_write_to_read(struct oplock_info *opinfo);
int opinfo_read_handle_to_read(struct oplock_info *opinfo);
int opinfo_write_to_none(struct oplock_info *opinfo);
int opinfo_read_to_none(struct oplock_info *opinfo);
void close_id_del_oplock(struct cifsd_file *fp);
void smb_break_all_oplock(struct cifsd_work *work, struct cifsd_file *fp);
struct oplock_info *opinfo_get(struct cifsd_file *fp);
void opinfo_put(struct oplock_info *opinfo);
/* Lease related functions */
void create_lease_buf(u8 *rbuf, struct lease *lease);
struct lease_ctx_info *parse_lease_state(void *open_req);
__u8 smb2_map_lease_to_oplock(__le32 lease_state);
int lease_read_to_write(struct oplock_info *opinfo);
/* Durable related functions */
void create_durable_rsp_buf(char *buf);
void create_durable_v2_rsp_buf(char *cc, struct cifsd_file *fp);
void create_mxac_rsp_buf(char *cc, int maximal_access);
void create_disk_id_rsp_buf(char *cc, __u64 file_id, __u64 vol_id);
struct create_context *smb2_find_context_vals(void *open_req, char *str);
int cifsd_durable_verify_and_del_oplock(struct cifsd_session *curr_sess,
struct cifsd_session *prev_sess,
int fid, struct file **filp,
uint64_t sess_id);
struct oplock_info *lookup_lease_in_table(struct cifsd_tcp_conn *conn,
char *lease_key);
int find_same_lease_key(struct cifsd_session *sess, struct cifsd_inode *ci,
struct lease_ctx_info *lctx);
void destroy_lease_table(struct cifsd_tcp_conn *conn);
int smb2_check_durable_oplock(struct cifsd_file *fp,
struct lease_ctx_info *lctx, char *name);
#endif /* __CIFSD_OPLOCK_H */