1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * fs/hmdfs/inode_cloud.c
4 *
5 * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
6 */
7
8 #include <linux/fs_stack.h>
9 #include <linux/namei.h>
10 #include <linux/xattr.h>
11 #include <linux/string.h>
12
13 #include "comm/socket_adapter.h"
14 #include "hmdfs.h"
15 #include "hmdfs_client.h"
16 #include "hmdfs_dentryfile.h"
17 #include "hmdfs_dentryfile_cloud.h"
18 #include "hmdfs_share.h"
19 #include "hmdfs_trace.h"
20 #include "authority/authentication.h"
21 #include "stash.h"
22
make_ino_raw_cloud(uint8_t *cloud_id)23 uint32_t make_ino_raw_cloud(uint8_t *cloud_id)
24 {
25 struct qstr str;
26
27 str.len = CLOUD_RECORD_ID_LEN;
28 str.name = cloud_id;
29 return hmdfs_dentry_hash(&str, CLOUD_RECORD_ID_LEN);
30 }
31
lookup_cloud_dentry(struct dentry *child_dentry, const struct qstr *qstr, uint64_t dev_id)32 struct hmdfs_lookup_cloud_ret *lookup_cloud_dentry(struct dentry *child_dentry,
33 const struct qstr *qstr,
34 uint64_t dev_id)
35 {
36 struct hmdfs_lookup_cloud_ret *lookup_ret;
37 struct hmdfs_dentry_cloud *dentry = NULL;
38 struct clearcache_item *cache_item = NULL;
39 struct hmdfs_dcache_lookup_ctx_cloud ctx;
40 struct hmdfs_sb_info *sbi = hmdfs_sb(child_dentry->d_sb);
41
42 get_cloud_cache_file(child_dentry->d_parent, sbi);
43 cache_item = hmdfs_find_cache_item(dev_id, child_dentry->d_parent);
44 if (!cache_item)
45 return NULL;
46
47 lookup_ret = kmalloc(sizeof(*lookup_ret), GFP_KERNEL);
48 if (!lookup_ret)
49 goto out;
50
51 hmdfs_init_dcache_lookup_ctx_cloud(&ctx, sbi, qstr, cache_item->filp);
52 dentry = hmdfs_find_dentry_cloud(child_dentry, &ctx);
53 if (!dentry) {
54 kfree(lookup_ret);
55 lookup_ret = NULL;
56 goto out;
57 }
58
59 lookup_ret->i_mode = le16_to_cpu(dentry->i_mode);
60 lookup_ret->i_size = le64_to_cpu(dentry->i_size);
61 lookup_ret->i_mtime = le64_to_cpu(dentry->i_mtime);
62 memcpy(lookup_ret->record_id, dentry->record_id, CLOUD_RECORD_ID_LEN);
63 memcpy(lookup_ret->reserved, dentry->reserved, CLOUD_DENTRY_RESERVED_LENGTH);
64
65 hmdfs_unlock_file(ctx.filp, get_dentry_group_pos(ctx.bidx),
66 DENTRYGROUP_SIZE);
67 kfree(ctx.page);
68 out:
69 kref_put(&cache_item->ref, release_cache_item);
70 return lookup_ret;
71 }
72
73 static struct hmdfs_lookup_cloud_ret *
hmdfs_lookup_by_cloud(struct dentry *dentry, unsigned int flags)74 hmdfs_lookup_by_cloud(struct dentry *dentry, unsigned int flags)
75 {
76 struct hmdfs_lookup_cloud_ret *result = NULL;
77 char *file_name = NULL;
78 struct qstr qstr;
79 int file_name_len = dentry->d_name.len;
80
81 file_name = kzalloc(NAME_MAX + 1, GFP_KERNEL);
82 if (!file_name)
83 return NULL;
84 strncpy(file_name, dentry->d_name.name, file_name_len);
85 qstr.name = file_name;
86 qstr.len = strlen(file_name);
87
88 result = lookup_cloud_dentry(dentry, &qstr, CLOUD_DEVICE);
89
90 kfree(file_name);
91 return result;
92 }
93
94 /*
95 * hmdfs_update_inode_size - update inode size when finding aready existed
96 * inode.
97 *
98 * First of all, if the file is opened for writing, we don't update inode size
99 * here, because inode size is about to be changed after writing.
100 *
101 * If the file is not opened, simply update getattr_isize(not actual inode size,
102 * just a value showed to user). This is safe because inode size will be
103 * up-to-date after open.
104 *
105 * If the file is opened for read:
106 * a. getattr_isize == HMDFS_STALE_REMOTE_ISIZE
107 * 1) i_size == new_size, nothing need to be done.
108 * 2) i_size > new_size, we keep the i_size and set getattr_isize to new_size,
109 * stale data might be readed in this case, which is fine because file is
110 * opened before remote truncate the file.
111 * 3) i_size < new_size, we drop the last page of the file if i_size is not
112 * aligned to PAGE_SIZE, clear getattr_isize, and update i_size to
113 * new_size.
114 * b. getattr_isize != HMDFS_STALE_REMOTE_ISIZE, getattr_isize will only be set
115 * after 2).
116 * 4) getattr_isize > i_size, this situation is impossible.
117 * 5) i_size >= new_size, this case is the same as 2).
118 * 6) i_size < new_size, this case is the same as 3).
119 */
hmdfs_update_inode_size(struct inode *inode, uint64_t new_size)120 static void hmdfs_update_inode_size(struct inode *inode, uint64_t new_size)
121 {
122 struct hmdfs_inode_info *info = hmdfs_i(inode);
123 int writecount;
124 uint64_t size;
125
126 inode_lock(inode);
127 size = info->getattr_isize;
128 if (size == HMDFS_STALE_REMOTE_ISIZE)
129 size = i_size_read(inode);
130 if (size == new_size) {
131 inode_unlock(inode);
132 return;
133 }
134
135 writecount = atomic_read(&inode->i_writecount);
136 /* check if writing is in progress */
137 if (writecount > 0) {
138 info->getattr_isize = HMDFS_STALE_REMOTE_ISIZE;
139 inode_unlock(inode);
140 return;
141 }
142
143 /* check if there is no one who opens the file */
144 if (kref_read(&info->ref) == 0)
145 goto update_info;
146
147 /* check if there is someone who opens the file for read */
148 if (writecount == 0) {
149 uint64_t aligned_size;
150
151 /* use inode size here instead of getattr_isize */
152 size = i_size_read(inode);
153 if (new_size <= size)
154 goto update_info;
155 /*
156 * if the old inode size is not aligned to HMDFS_PAGE_SIZE, we
157 * need to drop the last page of the inode, otherwise zero will
158 * be returned while reading the new range in the page after
159 * chaning inode size.
160 */
161 aligned_size = round_down(size, HMDFS_PAGE_SIZE);
162 if (aligned_size != size)
163 truncate_inode_pages(inode->i_mapping, aligned_size);
164 i_size_write(inode, new_size);
165 info->getattr_isize = HMDFS_STALE_REMOTE_ISIZE;
166 inode_unlock(inode);
167 return;
168 }
169
170 update_info:
171 info->getattr_isize = new_size;
172 inode_unlock(inode);
173 }
174
hmdfs_update_inode(struct inode *inode, struct hmdfs_lookup_cloud_ret *lookup_result)175 static void hmdfs_update_inode(struct inode *inode,
176 struct hmdfs_lookup_cloud_ret *lookup_result)
177 {
178 struct hmdfs_time_t remote_mtime = {
179 .tv_sec = lookup_result->i_mtime,
180 .tv_nsec = 0,
181 };
182
183 /*
184 * We only update mtime if the file is not opened for writing. If we do
185 * update it before writing is about to start, user might see the mtime
186 * up-and-down if system time in server and client do not match. However
187 * mtime in client will eventually match server after timeout without
188 * writing.
189 */
190 if (!inode_is_open_for_write(inode))
191 inode->i_mtime = remote_mtime;
192
193 /*
194 * We don't care i_size of dir, and lock inode for dir
195 * might cause deadlock.
196 */
197 if (S_ISREG(inode->i_mode))
198 hmdfs_update_inode_size(inode, lookup_result->i_size);
199 }
200
hmdfs_fill_inode_permission(struct inode *inode, struct inode *dir, umode_t mode)201 static void hmdfs_fill_inode_permission(struct inode *inode, struct inode *dir,
202 umode_t mode)
203 {
204 #ifdef CONFIG_HMDFS_FS_PERMISSION
205 inode->i_uid = dir->i_uid;
206 inode->i_gid = dir->i_gid;
207 #endif
208 }
209
210 struct hmdfs_peer peer;
211
fill_inode_cloud(struct super_block *sb, struct hmdfs_lookup_cloud_ret *res, struct inode *dir)212 struct inode *fill_inode_cloud(struct super_block *sb, struct hmdfs_lookup_cloud_ret *res, struct inode *dir)
213 {
214 int ret = 0;
215 struct inode *inode = NULL;
216 struct hmdfs_inode_info *info;
217 umode_t mode = res->i_mode;
218 peer.device_id = CLOUD_DEVICE;
219
220 inode = hmdfs_iget5_locked_cloud(sb, &peer, res);
221 if (!inode)
222 return ERR_PTR(-ENOMEM);
223
224 info = hmdfs_i(inode);
225 info->inode_type = HMDFS_LAYER_OTHER_CLOUD;
226 /* the inode was found in cache */
227 if (!(inode->i_state & I_NEW)) {
228 hmdfs_fill_inode_permission(inode, dir, mode);
229 hmdfs_update_inode(inode, res);
230 return inode;
231 }
232
233 inode->__i_ctime.tv_sec = 0;
234 inode->__i_ctime.tv_nsec = 0;
235 inode->i_mtime.tv_sec = res->i_mtime;
236 inode->i_mtime.tv_nsec = 0;
237
238 inode->i_uid = USER_DATA_RW_UID;
239 inode->i_gid = USER_DATA_RW_GID;
240
241 if (S_ISDIR(mode))
242 inode->i_mode = S_IFDIR | S_IRWXU | S_IRWXG | S_IXOTH;
243 else if (S_ISREG(mode))
244 inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
245 else {
246 ret = -EIO;
247 goto bad_inode;
248 }
249
250 if (S_ISREG(mode)) {
251 inode->i_op = &hmdfs_dev_file_iops_cloud;
252 inode->i_fop = &hmdfs_dev_file_fops_cloud;
253 inode->i_size = res->i_size;
254 set_nlink(inode, 1);
255 } else if (S_ISDIR(mode)) {
256 inode->i_op = &hmdfs_dev_dir_inode_ops_cloud;
257 inode->i_fop = &hmdfs_dev_dir_ops_cloud;
258 set_nlink(inode, 2);
259 } else {
260 ret = -EIO;
261 goto bad_inode;
262 }
263
264 inode->i_mapping->a_ops = &hmdfs_dev_file_aops_cloud;
265
266 hmdfs_fill_inode_permission(inode, dir, mode);
267 unlock_new_inode(inode);
268 return inode;
269 bad_inode:
270 iget_failed(inode);
271 return ERR_PTR(ret);
272 }
273
hmdfs_lookup_cloud_dentry(struct inode *parent_inode, struct dentry *child_dentry, int flags)274 static struct dentry *hmdfs_lookup_cloud_dentry(struct inode *parent_inode,
275 struct dentry *child_dentry,
276 int flags)
277 {
278 struct dentry *ret = NULL;
279 struct inode *inode = NULL;
280 struct super_block *sb = parent_inode->i_sb;
281 struct hmdfs_lookup_cloud_ret *lookup_result = NULL;
282 struct hmdfs_dentry_info *gdi = hmdfs_d(child_dentry);
283
284 lookup_result = hmdfs_lookup_by_cloud(child_dentry, flags);
285 if (lookup_result != NULL) {
286 if (in_share_dir(child_dentry))
287 gdi->file_type = HM_SHARE;
288 inode = fill_inode_cloud(sb, lookup_result, parent_inode);
289 if (IS_ERR(inode)) {
290 ret = ERR_CAST(inode);
291 goto out;
292 }
293
294 check_and_fixup_ownership_remote(parent_inode,
295 inode,
296 child_dentry);
297 ret = d_splice_alias(inode, child_dentry);
298 if (!IS_ERR_OR_NULL(ret))
299 child_dentry = ret;
300 } else {
301 ret = ERR_PTR(-ENOENT);
302 }
303 out:
304 kfree(lookup_result);
305 return ret;
306 }
307
hmdfs_lookup_cloud(struct inode *parent_inode, struct dentry *child_dentry, unsigned int flags)308 struct dentry *hmdfs_lookup_cloud(struct inode *parent_inode,
309 struct dentry *child_dentry,
310 unsigned int flags)
311 {
312 int err = 0;
313 struct dentry *ret = NULL;
314 struct hmdfs_dentry_info *gdi = NULL;
315 struct hmdfs_sb_info *sbi = hmdfs_sb(child_dentry->d_sb);
316
317 trace_hmdfs_lookup_remote(parent_inode, child_dentry, flags);
318 if (child_dentry->d_name.len > NAME_MAX) {
319 err = -ENAMETOOLONG;
320 ret = ERR_PTR(-ENAMETOOLONG);
321 goto out;
322 }
323
324 err = init_hmdfs_dentry_info(sbi, child_dentry,
325 HMDFS_LAYER_OTHER_CLOUD);
326 if (err) {
327 ret = ERR_PTR(err);
328 goto out;
329 }
330 gdi = hmdfs_d(child_dentry);
331 gdi->device_id = hmdfs_d(child_dentry->d_parent)->device_id;
332
333 ret = hmdfs_lookup_cloud_dentry(parent_inode, child_dentry, flags);
334 /*
335 * don't return error if inode do not exist, so that vfs can continue
336 * to create it.
337 */
338 if (IS_ERR_OR_NULL(ret)) {
339 err = PTR_ERR(ret);
340 if (err == -ENOENT)
341 ret = NULL;
342 } else {
343 child_dentry = ret;
344 }
345
346 out:
347 if (!err)
348 hmdfs_set_time(child_dentry, jiffies);
349 trace_hmdfs_lookup_remote_end(parent_inode, child_dentry, err);
350 return ret;
351 }
352
hmdfs_mkdir_cloud(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode)353 int hmdfs_mkdir_cloud(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode)
354 {
355 return -EPERM;
356 }
357
hmdfs_create_cloud(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode, bool want_excl)358 int hmdfs_create_cloud(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode,
359 bool want_excl)
360 {
361 return -EPERM;
362 }
363
hmdfs_rmdir_cloud(struct inode *dir, struct dentry *dentry)364 int hmdfs_rmdir_cloud(struct inode *dir, struct dentry *dentry)
365 {
366 return -EPERM;
367 }
368
hmdfs_unlink_cloud(struct inode *dir, struct dentry *dentry)369 int hmdfs_unlink_cloud(struct inode *dir, struct dentry *dentry)
370 {
371 return 0;
372 }
373
hmdfs_rename_cloud(struct mnt_idmap *idmap, struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags)374 int hmdfs_rename_cloud(struct mnt_idmap *idmap, struct inode *old_dir, struct dentry *old_dentry,
375 struct inode *new_dir, struct dentry *new_dentry,
376 unsigned int flags)
377 {
378 return -EPERM;
379 }
380
hmdfs_dir_setattr_cloud(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *ia)381 static int hmdfs_dir_setattr_cloud(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *ia)
382 {
383 // Do not support dir setattr
384 return 0;
385 }
386
387 const struct inode_operations hmdfs_dev_dir_inode_ops_cloud = {
388 .lookup = hmdfs_lookup_cloud,
389 .mkdir = hmdfs_mkdir_cloud,
390 .create = hmdfs_create_cloud,
391 .rmdir = hmdfs_rmdir_cloud,
392 .unlink = hmdfs_unlink_cloud,
393 .rename = hmdfs_rename_cloud,
394 .setattr = hmdfs_dir_setattr_cloud,
395 .permission = hmdfs_permission,
396 };
397
hmdfs_setattr_cloud(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *ia)398 static int hmdfs_setattr_cloud(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *ia)
399 {
400 struct hmdfs_inode_info *info = hmdfs_i(d_inode(dentry));
401 struct inode *inode = d_inode(dentry);
402 int err = 0;
403
404 if (hmdfs_inode_is_stashing(info))
405 return -EAGAIN;
406
407 if (ia->ia_valid & ATTR_SIZE) {
408 err = inode_newsize_ok(inode, ia->ia_size);
409 if (err)
410 return err;
411 truncate_setsize(inode, ia->ia_size);
412 info->getattr_isize = HMDFS_STALE_REMOTE_ISIZE;
413 }
414 if (ia->ia_valid & ATTR_MTIME)
415 inode->i_mtime = ia->ia_mtime;
416
417 return err;
418 }
419
420
hmdfs_get_cached_attr_cloud(struct mnt_idmap *idmap, const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags)421 static int hmdfs_get_cached_attr_cloud(struct mnt_idmap *idmap, const struct path *path,
422 struct kstat *stat, u32 request_mask,
423 unsigned int flags)
424 {
425 struct inode *inode = d_inode(path->dentry);
426 struct hmdfs_inode_info *info = hmdfs_i(inode);
427 uint64_t size = info->getattr_isize;
428
429 stat->ino = inode->i_ino;
430 stat->mtime = inode->i_mtime;
431 stat->mode = inode->i_mode;
432 stat->uid.val = inode->i_uid.val;
433 stat->gid.val = inode->i_gid.val;
434 if (size == HMDFS_STALE_REMOTE_ISIZE)
435 size = i_size_read(inode);
436
437 stat->size = size;
438 return 0;
439 }
440
441 const struct inode_operations hmdfs_dev_file_iops_cloud = {
442 .setattr = hmdfs_setattr_cloud,
443 .permission = hmdfs_permission,
444 .getattr = hmdfs_get_cached_attr_cloud,
445 .listxattr = NULL,
446 };
447