1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3 * Copyright (C) 2019 Samsung Electronics Co., Ltd.
4 */
5
6 #ifndef __VFS_CACHE_H__
7 #define __VFS_CACHE_H__
8
9 #include <linux/file.h>
10 #include <linux/fs.h>
11 #include <linux/mutex.h>
12 #include <linux/rwsem.h>
13 #include <linux/spinlock.h>
14 #include <linux/idr.h>
15 #include <linux/workqueue.h>
16
17 #include "vfs.h"
18 #include "mgmt/share_config.h"
19
20 /* Windows style file permissions for extended response */
21 #define FILE_GENERIC_ALL 0x1F01FF
22 #define FILE_GENERIC_READ 0x120089
23 #define FILE_GENERIC_WRITE 0x120116
24 #define FILE_GENERIC_EXECUTE 0X1200a0
25
26 /*
27 * Start volatile/persistent file id allocation at 1. A file id of 0 yields an
28 * SMB2 FileId of {0, 0}, which clients (e.g. Windows, Samba) treat as a null
29 * handle and never close, leaking the open on the server.
30 */
31 #define KSMBD_START_FID 1
32 #define KSMBD_NO_FID (INT_MAX)
33 #define SMB2_NO_FID (0xFFFFFFFFFFFFFFFFULL)
34
35 struct ksmbd_conn;
36 struct ksmbd_session;
37
38 struct ksmbd_lock {
39 struct file_lock *fl;
40 struct ksmbd_conn *conn;
41 struct list_head clist;
42 struct list_head flist;
43 struct list_head llist;
44 unsigned int flags;
45 int cmd;
46 int zero_len;
47 unsigned long long start;
48 unsigned long long end;
49 };
50
51 struct stream {
52 char *name;
53 ssize_t size;
54 loff_t pos;
55 };
56
57 struct ksmbd_inode {
58 struct rw_semaphore m_lock;
59 atomic_t m_count;
60 atomic_t op_count;
61 /* opinfo count for streams */
62 atomic_t sop_count;
63 struct dentry *m_de;
64 unsigned int m_flags;
65 struct hlist_node m_hash;
66 struct list_head m_fp_list;
67 struct list_head m_op_list;
68 struct oplock_info *m_opinfo;
69 __le32 m_fattr;
70 };
71
72 enum {
73 FP_NEW = 0,
74 FP_INITED,
75 FP_CLOSED
76 };
77
78 /* Owner information for durable handle reconnect */
79 struct durable_owner {
80 unsigned int uid;
81 unsigned int gid;
82 char *name;
83 };
84
85 struct ksmbd_file {
86 struct file *filp;
87 u64 persistent_id;
88 u64 volatile_id;
89 u64 durable_volatile_id;
90
91 spinlock_t f_lock;
92
93 struct ksmbd_inode *f_ci;
94 struct ksmbd_inode *f_parent_ci;
95 struct oplock_info __rcu *f_opinfo;
96 struct ksmbd_conn *conn;
97 struct ksmbd_tree_connect *tcon;
98
99 atomic_t refcount;
100 __le32 daccess;
101 __le32 saccess;
102 __le32 coption;
103 __le32 cdoption;
104 __u64 create_time;
105 __u64 change_time;
106 __u64 allocation_size;
107 __u64 itime;
108 __u64 open_mtime;
109
110 bool is_nt_open;
111 bool attrib_only;
112
113 char client_guid[16];
114 char create_guid[16];
115 char app_instance_id[16];
116
117 struct stream stream;
118 struct list_head node;
119 struct list_head blocked_works;
120 struct list_head lock_list;
121
122 unsigned int durable_timeout;
123 unsigned int durable_scavenger_timeout;
124
125 /* if ls is happening on directory, below is valid*/
126 struct ksmbd_readdir_data readdir_data;
127 struct mutex readdir_lock;
128 int dot_dotdot[2];
129 unsigned int f_state;
130 bool reserve_lease_break;
131 bool is_durable;
132 bool is_persistent;
133 bool is_resilient;
134 bool durable_reconnect_disabled;
135
136 bool is_posix_ctxt;
137 struct durable_owner owner;
138 };
139
set_ctx_actor(struct dir_context * ctx,filldir_t actor)140 static inline void set_ctx_actor(struct dir_context *ctx,
141 filldir_t actor)
142 {
143 ctx->actor = actor;
144 }
145
146 #define KSMBD_NR_OPEN_DEFAULT BITS_PER_LONG
147
148 struct ksmbd_file_table {
149 rwlock_t lock;
150 struct idr *idr;
151 };
152
has_file_id(u64 id)153 static inline bool has_file_id(u64 id)
154 {
155 return id < KSMBD_NO_FID;
156 }
157
ksmbd_stream_fd(struct ksmbd_file * fp)158 static inline bool ksmbd_stream_fd(struct ksmbd_file *fp)
159 {
160 return fp->stream.name != NULL;
161 }
162
163 int ksmbd_init_file_table(struct ksmbd_file_table *ft);
164 void ksmbd_destroy_file_table(struct ksmbd_session *sess);
165 int ksmbd_close_fd(struct ksmbd_work *work, u64 id);
166 struct ksmbd_file *ksmbd_lookup_fd_fast(struct ksmbd_work *work, u64 id);
167 struct ksmbd_file *ksmbd_lookup_foreign_fd(struct ksmbd_work *work, u64 id);
168 struct ksmbd_file *ksmbd_lookup_fd_slow(struct ksmbd_work *work, u64 id,
169 u64 pid);
170 void ksmbd_fd_put(struct ksmbd_work *work, struct ksmbd_file *fp);
171 struct ksmbd_inode *ksmbd_inode_lookup_lock(struct dentry *d);
172 void ksmbd_inode_put(struct ksmbd_inode *ci);
173 bool ksmbd_close_disconnected_durable_delete_on_close(struct dentry *dentry);
174 struct ksmbd_file *ksmbd_lookup_global_fd(unsigned long long id);
175 struct ksmbd_file *ksmbd_lookup_durable_fd(unsigned long long id);
176 void ksmbd_put_durable_fd(struct ksmbd_file *fp);
177 int ksmbd_invalidate_durable_fd(unsigned long long id);
178 bool ksmbd_has_other_active_fd(struct ksmbd_file *fp);
179 bool ksmbd_has_stream_without_delete_share(struct ksmbd_file *fp);
180 int ksmbd_close_fd_app_instance_id(char *app_instance_id);
181 struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid);
182 struct ksmbd_file *ksmbd_lookup_fd_inode(struct dentry *dentry);
183 bool ksmbd_has_open_files(struct dentry *dentry);
184 unsigned int ksmbd_open_durable_fd(struct ksmbd_file *fp);
185 struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp);
186 void ksmbd_launch_ksmbd_durable_scavenger(void);
187 void ksmbd_stop_durable_scavenger(void);
188 void ksmbd_close_tree_conn_fds(struct ksmbd_work *work);
189 void ksmbd_close_session_fds(struct ksmbd_work *work);
190 int ksmbd_close_inode_fds(struct ksmbd_work *work, struct inode *inode);
191 int ksmbd_init_global_file_table(void);
192 void ksmbd_free_global_file_table(void);
193 void ksmbd_set_fd_limit(unsigned long limit);
194 int ksmbd_update_fstate(struct ksmbd_file_table *ft, struct ksmbd_file *fp,
195 unsigned int state);
196 bool ksmbd_vfs_compare_durable_owner(struct ksmbd_file *fp,
197 struct ksmbd_user *user);
198
199 /*
200 * INODE hash
201 */
202 int __init ksmbd_inode_hash_init(void);
203 void ksmbd_release_inode_hash(void);
204
205 enum KSMBD_INODE_STATUS {
206 KSMBD_INODE_STATUS_OK,
207 KSMBD_INODE_STATUS_UNKNOWN,
208 KSMBD_INODE_STATUS_PENDING_DELETE,
209 };
210
211 int ksmbd_query_inode_status(struct dentry *dentry);
212 bool ksmbd_inode_pending_delete(struct ksmbd_file *fp);
213 void ksmbd_set_inode_pending_delete(struct ksmbd_file *fp);
214 void ksmbd_clear_inode_pending_delete(struct ksmbd_file *fp);
215 void ksmbd_fd_set_delete_on_close(struct ksmbd_file *fp,
216 int file_info);
217 int ksmbd_reopen_durable_fd(struct ksmbd_work *work, struct ksmbd_file *fp);
218 int ksmbd_validate_name_reconnect(struct ksmbd_share_config *share,
219 struct ksmbd_file *fp, char *name);
220 int ksmbd_init_file_cache(void);
221 void ksmbd_exit_file_cache(void);
222 #endif /* __VFS_CACHE_H__ */
223