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 #define KSMBD_LOCK_SEQ_ARRAY_SIZE 64 86 87 struct ksmbd_lock_sequence { 88 bool valid; 89 u8 sequence; 90 }; 91 92 struct ksmbd_file { 93 struct file *filp; 94 u64 persistent_id; 95 u64 volatile_id; 96 u64 durable_volatile_id; 97 98 spinlock_t f_lock; 99 100 struct ksmbd_inode *f_ci; 101 struct ksmbd_inode *f_parent_ci; 102 struct oplock_info __rcu *f_opinfo; 103 struct ksmbd_conn *conn; 104 struct ksmbd_tree_connect *tcon; 105 106 atomic_t refcount; 107 __le32 daccess; 108 __le32 saccess; 109 __le32 coption; 110 __le32 cdoption; 111 __le32 create_file_attributes; 112 __u64 create_time; 113 __u64 change_time; 114 __u64 allocation_size; 115 __u64 itime; 116 __u64 open_mtime; 117 118 bool is_nt_open; 119 bool attrib_only; 120 bool allocation_size_set; 121 122 char client_guid[16]; 123 char create_guid[16]; 124 char app_instance_id[16]; 125 126 struct stream stream; 127 struct list_head node; 128 struct list_head blocked_works; 129 struct list_head lock_list; 130 /* 131 * Per-handle FileDispositionInformation delete-pending state for a 132 * stream handle -- separate from ksmbd_inode's inode-wide m_flags, 133 * which have no way to record which stream on a multi-stream file 134 * was actually marked for deletion. See ksmbd_fd_set_delete_pending(). 135 */ 136 bool stream_del_pending; 137 138 unsigned int durable_timeout; 139 unsigned int durable_scavenger_timeout; 140 /* CREATE action returned when this durable handle was established. */ 141 __le32 create_action; 142 143 /* if ls is happening on directory, below is valid*/ 144 struct ksmbd_readdir_data readdir_data; 145 struct mutex readdir_lock; 146 int dot_dotdot[2]; 147 unsigned int f_state; 148 bool reserve_lease_break; 149 bool is_durable; 150 bool is_persistent; 151 bool is_resilient; 152 bool has_app_instance_id; 153 bool app_instance_version_valid; 154 u64 app_instance_version_high; 155 u64 app_instance_version_low; 156 bool durable_reconnect_disabled; 157 bool durable_replay_consumed; 158 159 bool is_posix_ctxt; 160 struct durable_owner owner; 161 __le16 channel_sequence; 162 unsigned int outstanding_requests; 163 unsigned int outstanding_pre_requests; 164 struct ksmbd_lock_sequence lock_seq[KSMBD_LOCK_SEQ_ARRAY_SIZE]; 165 166 /* 167 * Pending CHANGE_NOTIFY completions for this handle, sent with 168 * STATUS_NOTIFY_CLEANUP when the handle is closed. 169 */ 170 struct list_head notify_pendings; 171 }; 172 173 static inline void set_ctx_actor(struct dir_context *ctx, 174 filldir_t actor) 175 { 176 ctx->actor = actor; 177 } 178 179 #define KSMBD_NR_OPEN_DEFAULT BITS_PER_LONG 180 181 struct ksmbd_file_table { 182 rwlock_t lock; 183 struct idr *idr; 184 }; 185 186 static inline bool has_file_id(u64 id) 187 { 188 return id < KSMBD_NO_FID; 189 } 190 191 static inline bool ksmbd_stream_fd(struct ksmbd_file *fp) 192 { 193 return fp->stream.name != NULL; 194 } 195 196 int ksmbd_init_file_table(struct ksmbd_file_table *ft); 197 void ksmbd_destroy_file_table(struct ksmbd_session *sess); 198 int ksmbd_close_fd(struct ksmbd_work *work, u64 id); 199 struct ksmbd_file *ksmbd_lookup_fd_fast(struct ksmbd_work *work, u64 id); 200 struct ksmbd_file *ksmbd_lookup_foreign_fd(struct ksmbd_work *work, u64 id); 201 struct ksmbd_file *ksmbd_lookup_fd_slow(struct ksmbd_work *work, u64 id, 202 u64 pid); 203 int ksmbd_vfs_set_durable_owner(struct ksmbd_file *fp, 204 struct ksmbd_user *user); 205 struct ksmbd_file *ksmbd_file_get(struct ksmbd_file *fp); 206 void ksmbd_fd_put(struct ksmbd_work *work, struct ksmbd_file *fp); 207 struct ksmbd_inode *ksmbd_inode_lookup_lock(struct dentry *d); 208 void ksmbd_inode_put(struct ksmbd_inode *ci); 209 bool ksmbd_close_disconnected_durable_delete_on_close(struct dentry *dentry); 210 struct ksmbd_file *ksmbd_lookup_global_fd(unsigned long long id); 211 struct ksmbd_file *ksmbd_lookup_durable_fd(unsigned long long id); 212 void ksmbd_put_durable_fd(struct ksmbd_file *fp); 213 int ksmbd_invalidate_durable_fd(unsigned long long id); 214 bool ksmbd_has_other_active_fd(struct ksmbd_file *fp); 215 bool ksmbd_has_stream_without_delete_share(struct ksmbd_file *fp); 216 struct ksmbd_file *ksmbd_lookup_fd_app_instance_id(char *app_instance_id); 217 int ksmbd_close_fd_app_instance_id(char *app_instance_id); 218 struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid); 219 struct ksmbd_file *ksmbd_lookup_fd_inode(struct dentry *dentry); 220 bool ksmbd_has_other_nonposix_open(struct dentry *dentry); 221 bool ksmbd_has_nonposix_open_child(struct ksmbd_file *old_fp); 222 unsigned int ksmbd_open_durable_fd(struct ksmbd_file *fp); 223 struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp); 224 void ksmbd_launch_ksmbd_durable_scavenger(void); 225 void ksmbd_stop_durable_scavenger(void); 226 bool ksmbd_durable_scavenger_active(void); 227 void ksmbd_close_tree_conn_fds(struct ksmbd_work *work); 228 void ksmbd_close_session_fds(struct ksmbd_work *work); 229 void ksmbd_wake_session_blocked_works(struct ksmbd_session *sess); 230 int ksmbd_close_inode_fds(struct ksmbd_work *work, struct inode *inode); 231 int ksmbd_init_global_file_table(void); 232 void ksmbd_free_global_file_table(void); 233 void ksmbd_set_fd_limit(unsigned long limit); 234 int ksmbd_update_fstate(struct ksmbd_file_table *ft, struct ksmbd_file *fp, 235 unsigned int state); 236 bool ksmbd_vfs_compare_durable_owner(struct ksmbd_file *fp, 237 struct ksmbd_user *user); 238 239 /* 240 * INODE hash 241 */ 242 int __init ksmbd_inode_hash_init(void); 243 void ksmbd_release_inode_hash(void); 244 245 enum KSMBD_INODE_STATUS { 246 KSMBD_INODE_STATUS_OK, 247 KSMBD_INODE_STATUS_UNKNOWN, 248 KSMBD_INODE_STATUS_PENDING_DELETE, 249 }; 250 251 int ksmbd_query_inode_status(struct dentry *dentry); 252 bool ksmbd_inode_pending_delete(struct ksmbd_file *fp); 253 void ksmbd_set_inode_pending_delete(struct ksmbd_file *fp); 254 void ksmbd_clear_inode_pending_delete(struct ksmbd_file *fp); 255 void ksmbd_fd_set_delete_on_close(struct ksmbd_file *fp, 256 int file_info); 257 void ksmbd_fd_set_delete_pending(struct ksmbd_file *fp); 258 void ksmbd_fd_clear_delete_pending(struct ksmbd_file *fp); 259 int ksmbd_reopen_durable_fd(struct ksmbd_work *work, struct ksmbd_file *fp); 260 int ksmbd_validate_name_reconnect(struct ksmbd_share_config *share, 261 struct ksmbd_file *fp, char *name); 262 int ksmbd_init_file_cache(void); 263 void ksmbd_exit_file_cache(void); 264 #endif /* __VFS_CACHE_H__ */ 265