1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * fs/hmdfs/inode_remote.c
4 *
5 * Copyright (c) 2020-2021 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_trace.h"
18 #include "authority/authentication.h"
19 #include "stash.h"
20
lookup_remote_dentry(struct dentry * child_dentry,const struct qstr * qstr,uint64_t dev_id)21 struct hmdfs_lookup_ret *lookup_remote_dentry(struct dentry *child_dentry,
22 const struct qstr *qstr,
23 uint64_t dev_id)
24 {
25 struct hmdfs_lookup_ret *lookup_ret;
26 struct hmdfs_dentry *dentry = NULL;
27 struct clearcache_item *cache_item = NULL;
28 struct hmdfs_dcache_lookup_ctx ctx;
29 struct hmdfs_sb_info *sbi = hmdfs_sb(child_dentry->d_sb);
30
31 cache_item = hmdfs_find_cache_item(dev_id, child_dentry->d_parent);
32 if (!cache_item)
33 return NULL;
34
35 lookup_ret = kmalloc(sizeof(*lookup_ret), GFP_KERNEL);
36 if (!lookup_ret)
37 goto out;
38
39 hmdfs_init_dcache_lookup_ctx(&ctx, sbi, qstr, cache_item->filp);
40 dentry = hmdfs_find_dentry(child_dentry, &ctx);
41 if (!dentry) {
42 kfree(lookup_ret);
43 lookup_ret = NULL;
44 goto out;
45 }
46
47 lookup_ret->i_mode = le16_to_cpu(dentry->i_mode);
48 lookup_ret->i_size = le64_to_cpu(dentry->i_size);
49 lookup_ret->i_mtime = le64_to_cpu(dentry->i_mtime);
50 lookup_ret->i_mtime_nsec = le32_to_cpu(dentry->i_mtime_nsec);
51 lookup_ret->i_ino = le64_to_cpu(dentry->i_ino);
52
53 hmdfs_unlock_file(ctx.filp, get_dentry_group_pos(ctx.bidx),
54 DENTRYGROUP_SIZE);
55 kfree(ctx.page);
56 out:
57 kref_put(&cache_item->ref, release_cache_item);
58 return lookup_ret;
59 }
60
61 /* get_remote_inode_info - fill hmdfs_lookup_ret by info from remote getattr
62 *
63 * @dentry: local dentry
64 * @hmdfs_peer: which remote devcie
65 * @flags: lookup flags
66 *
67 * return allocaed and initialized hmdfs_lookup_ret on success, and NULL on
68 * failure.
69 */
get_remote_inode_info(struct hmdfs_peer * con,struct dentry * dentry,unsigned int flags)70 struct hmdfs_lookup_ret *get_remote_inode_info(struct hmdfs_peer *con,
71 struct dentry *dentry,
72 unsigned int flags)
73 {
74 int err = 0;
75 struct hmdfs_lookup_ret *lookup_ret = NULL;
76 struct hmdfs_getattr_ret *getattr_ret = NULL;
77 unsigned int expected_flags = 0;
78
79 lookup_ret = kmalloc(sizeof(*lookup_ret), GFP_KERNEL);
80 if (!lookup_ret)
81 return NULL;
82
83 err = hmdfs_remote_getattr(con, dentry, flags, &getattr_ret);
84 if (err) {
85 hmdfs_debug("inode info get failed with err %d", err);
86 kfree(lookup_ret);
87 return NULL;
88 }
89 /* make sure we got everything we need */
90 expected_flags = STATX_INO | STATX_SIZE | STATX_MODE | STATX_MTIME;
91 if ((getattr_ret->stat.result_mask & expected_flags) !=
92 expected_flags) {
93 hmdfs_debug("remote getattr failed with flag %x",
94 getattr_ret->stat.result_mask);
95 kfree(lookup_ret);
96 kfree(getattr_ret);
97 return NULL;
98 }
99
100 lookup_ret->i_mode = getattr_ret->stat.mode;
101 lookup_ret->i_size = getattr_ret->stat.size;
102 lookup_ret->i_mtime = getattr_ret->stat.mtime.tv_sec;
103 lookup_ret->i_mtime_nsec = getattr_ret->stat.mtime.tv_nsec;
104 lookup_ret->i_ino = getattr_ret->stat.ino;
105 kfree(getattr_ret);
106 return lookup_ret;
107 }
108
hmdfs_remote_readdir_work(struct work_struct * work)109 static void hmdfs_remote_readdir_work(struct work_struct *work)
110 {
111 struct hmdfs_readdir_work *rw =
112 container_of(to_delayed_work(work), struct hmdfs_readdir_work,
113 dwork);
114 struct dentry *dentry = rw->dentry;
115 struct hmdfs_peer *con = rw->con;
116 const struct cred *old_cred = hmdfs_override_creds(con->sbi->cred);
117 bool empty = false;
118
119 get_remote_dentry_file(dentry, con);
120 hmdfs_d(dentry)->async_readdir_in_progress = 0;
121 hmdfs_revert_creds(old_cred);
122
123 dput(dentry);
124 peer_put(con);
125 spin_lock(&con->sbi->async_readdir_work_lock);
126 list_del(&rw->head);
127 empty = list_empty(&con->sbi->async_readdir_work_list);
128 spin_unlock(&con->sbi->async_readdir_work_lock);
129 kfree(rw);
130
131 if (empty)
132 wake_up_interruptible(&con->sbi->async_readdir_wq);
133 }
134
get_remote_dentry_file_in_wq(struct dentry * dentry,struct hmdfs_peer * con)135 static void get_remote_dentry_file_in_wq(struct dentry *dentry,
136 struct hmdfs_peer *con)
137 {
138 struct hmdfs_readdir_work *rw = NULL;
139
140 /* do nothing if async readdir is already in progress */
141 if (cmpxchg_relaxed(&hmdfs_d(dentry)->async_readdir_in_progress, 0,
142 1))
143 return;
144
145 rw = kmalloc(sizeof(*rw), GFP_KERNEL);
146 if (!rw) {
147 hmdfs_d(dentry)->async_readdir_in_progress = 0;
148 return;
149 }
150
151 dget(dentry);
152 peer_get(con);
153 rw->dentry = dentry;
154 rw->con = con;
155 spin_lock(&con->sbi->async_readdir_work_lock);
156 INIT_DELAYED_WORK(&rw->dwork, hmdfs_remote_readdir_work);
157 list_add(&rw->head, &con->sbi->async_readdir_work_list);
158 spin_unlock(&con->sbi->async_readdir_work_lock);
159 queue_delayed_work(con->dentry_wq, &rw->dwork, 0);
160 }
161
get_remote_dentry_file_sync(struct dentry * dentry,struct hmdfs_peer * con)162 void get_remote_dentry_file_sync(struct dentry *dentry, struct hmdfs_peer *con)
163 {
164 get_remote_dentry_file_in_wq(dentry, con);
165 flush_workqueue(con->dentry_wq);
166 }
167
hmdfs_lookup_by_con(struct hmdfs_peer * con,struct dentry * dentry,struct qstr * qstr,unsigned int flags,const char * relative_path)168 struct hmdfs_lookup_ret *hmdfs_lookup_by_con(struct hmdfs_peer *con,
169 struct dentry *dentry,
170 struct qstr *qstr,
171 unsigned int flags,
172 const char *relative_path)
173 {
174 struct hmdfs_lookup_ret *result = NULL;
175
176 if (con->version > USERSPACE_MAX_VER) {
177 /*
178 * LOOKUP_REVAL means we found stale info from dentry file, thus
179 * we need to use remote getattr.
180 */
181 if (flags & LOOKUP_REVAL) {
182 /*
183 * HMDFS_LOOKUP_REVAL means we need to skip dentry cache
184 * in lookup, because dentry cache in server might have
185 * stale data.
186 */
187 result = get_remote_inode_info(con, dentry,
188 HMDFS_LOOKUP_REVAL);
189 get_remote_dentry_file_in_wq(dentry->d_parent, con);
190 return result;
191 }
192
193 /* If cache file is still valid */
194 if (hmdfs_cache_revalidate(READ_ONCE(con->conn_time),
195 con->device_id, dentry->d_parent)) {
196 result = lookup_remote_dentry(dentry, qstr,
197 con->device_id);
198 /*
199 * If lookup from cache file failed, use getattr to see
200 * if remote have created the file.
201 */
202 if (!(flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)) &&
203 !result)
204 result = get_remote_inode_info(con, dentry, 0);
205 /* If cache file expired, use getattr directly
206 * except create and rename opt
207 */
208 } else {
209 result = get_remote_inode_info(con, dentry, 0);
210 get_remote_dentry_file_in_wq(dentry->d_parent, con);
211 }
212 } else {
213 if (!relative_path)
214 return NULL;
215
216 result = con->conn_operations->remote_lookup(
217 con, relative_path, dentry->d_name.name);
218 }
219
220 return result;
221 }
222
223 /*
224 * hmdfs_update_inode_size - update inode size when finding aready existed
225 * inode.
226 *
227 * First of all, if the file is opened for writing, we don't update inode size
228 * here, because inode size is about to be changed after writing.
229 *
230 * If the file is not opened, simply update getattr_isize(not actual inode size,
231 * just a value showed to user). This is safe because inode size will be
232 * up-to-date after open.
233 *
234 * If the file is opened for read:
235 * a. getattr_isize == HMDFS_STALE_REMOTE_ISIZE
236 * 1) i_size == new_size, nothing need to be done.
237 * 2) i_size > new_size, we keep the i_size and set getattr_isize to new_size,
238 * stale data might be readed in this case, which is fine because file is
239 * opened before remote truncate the file.
240 * 3) i_size < new_size, we drop the last page of the file if i_size is not
241 * aligned to PAGE_SIZE, clear getattr_isize, and update i_size to
242 * new_size.
243 * b. getattr_isize != HMDFS_STALE_REMOTE_ISIZE, getattr_isize will only be set
244 * after 2).
245 * 4) getattr_isize > i_size, this situation is impossible.
246 * 5) i_size >= new_size, this case is the same as 2).
247 * 6) i_size < new_size, this case is the same as 3).
248 */
hmdfs_update_inode_size(struct inode * inode,uint64_t new_size)249 static void hmdfs_update_inode_size(struct inode *inode, uint64_t new_size)
250 {
251 struct hmdfs_inode_info *info = hmdfs_i(inode);
252 int writecount;
253 uint64_t size;
254
255 inode_lock(inode);
256 size = info->getattr_isize;
257 if (size == HMDFS_STALE_REMOTE_ISIZE)
258 size = i_size_read(inode);
259 if (size == new_size) {
260 inode_unlock(inode);
261 return;
262 }
263
264 writecount = atomic_read(&inode->i_writecount);
265 /* check if writing is in progress */
266 if (writecount > 0) {
267 info->getattr_isize = HMDFS_STALE_REMOTE_ISIZE;
268 inode_unlock(inode);
269 return;
270 }
271
272 /* check if there is no one who opens the file */
273 if (kref_read(&info->ref) == 0)
274 goto update_info;
275
276 /* check if there is someone who opens the file for read */
277 if (writecount == 0) {
278 uint64_t aligned_size;
279
280 /* use inode size here instead of getattr_isize */
281 size = i_size_read(inode);
282 if (new_size <= size)
283 goto update_info;
284 /*
285 * if the old inode size is not aligned to HMDFS_PAGE_SIZE, we
286 * need to drop the last page of the inode, otherwise zero will
287 * be returned while reading the new range in the page after
288 * chaning inode size.
289 */
290 aligned_size = round_down(size, HMDFS_PAGE_SIZE);
291 if (aligned_size != size)
292 truncate_inode_pages(inode->i_mapping, aligned_size);
293 i_size_write(inode, new_size);
294 info->getattr_isize = HMDFS_STALE_REMOTE_ISIZE;
295 inode_unlock(inode);
296 return;
297 }
298
299 update_info:
300 info->getattr_isize = new_size;
301 inode_unlock(inode);
302 }
303
hmdfs_update_inode(struct inode * inode,struct hmdfs_lookup_ret * lookup_result)304 static void hmdfs_update_inode(struct inode *inode,
305 struct hmdfs_lookup_ret *lookup_result)
306 {
307 struct hmdfs_time_t remote_mtime = {
308 .tv_sec = lookup_result->i_mtime,
309 .tv_nsec = lookup_result->i_mtime_nsec,
310 };
311
312 /*
313 * We only update mtime if the file is not opened for writing. If we do
314 * update it before writing is about to start, user might see the mtime
315 * up-and-down if system time in server and client do not match. However
316 * mtime in client will eventually match server after timeout without
317 * writing.
318 */
319 if (!inode_is_open_for_write(inode))
320 inode->i_mtime = remote_mtime;
321
322 /*
323 * We don't care i_size of dir, and lock inode for dir
324 * might cause deadlock.
325 */
326 if (S_ISREG(inode->i_mode))
327 hmdfs_update_inode_size(inode, lookup_result->i_size);
328 }
329
hmdfs_fill_inode_android(struct inode * inode,struct inode * dir,umode_t mode)330 static void hmdfs_fill_inode_android(struct inode *inode, struct inode *dir,
331 umode_t mode)
332 {
333 #ifdef CONFIG_HMDFS_FS_PERMISSION
334 inode->i_uid = dir->i_uid;
335 inode->i_gid = dir->i_gid;
336 #endif
337 }
338
fill_inode_remote(struct super_block * sb,struct hmdfs_peer * con,struct hmdfs_lookup_ret * res,struct inode * dir)339 struct inode *fill_inode_remote(struct super_block *sb, struct hmdfs_peer *con,
340 struct hmdfs_lookup_ret *res, struct inode *dir)
341 {
342 int ret = 0;
343 struct inode *inode = NULL;
344 struct hmdfs_inode_info *info;
345 umode_t mode = res->i_mode;
346
347 inode = hmdfs_iget5_locked_remote(sb, con, res->i_ino);
348 if (!inode)
349 return ERR_PTR(-ENOMEM);
350
351 info = hmdfs_i(inode);
352 info->inode_type = HMDFS_LAYER_OTHER_REMOTE;
353 if (con->version > USERSPACE_MAX_VER) {
354 /* the inode was found in cache */
355 if (!(inode->i_state & I_NEW)) {
356 hmdfs_fill_inode_android(inode, dir, mode);
357 hmdfs_update_inode(inode, res);
358 return inode;
359 }
360
361 hmdfs_remote_init_stash_status(con, inode, mode);
362 }
363
364 inode->i_ctime.tv_sec = 0;
365 inode->i_ctime.tv_nsec = 0;
366 inode->i_mtime.tv_sec = res->i_mtime;
367 inode->i_mtime.tv_nsec = res->i_mtime_nsec;
368
369 inode->i_uid = KUIDT_INIT((uid_t)1000);
370 inode->i_gid = KGIDT_INIT((gid_t)1000);
371
372 if (S_ISDIR(mode))
373 inode->i_mode = S_IFDIR | S_IRWXU | S_IRWXG | S_IXOTH;
374 else if (S_ISREG(mode))
375 inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
376 else {
377 ret = -EIO;
378 goto bad_inode;
379 }
380
381 if (S_ISREG(mode)) {
382 inode->i_op = con->conn_operations->remote_file_iops;
383 inode->i_fop = con->conn_operations->remote_file_fops;
384 inode->i_size = res->i_size;
385 set_nlink(inode, 1);
386 } else if (S_ISDIR(mode)) {
387 inode->i_op = &hmdfs_dev_dir_inode_ops_remote;
388 inode->i_fop = &hmdfs_dev_dir_ops_remote;
389 set_nlink(inode, 2);
390 } else {
391 ret = -EIO;
392 goto bad_inode;
393 }
394
395 inode->i_mapping->a_ops = con->conn_operations->remote_file_aops;
396
397 hmdfs_fill_inode_android(inode, dir, mode);
398 unlock_new_inode(inode);
399 return inode;
400 bad_inode:
401 iget_failed(inode);
402 return ERR_PTR(ret);
403 }
404
in_share_dir(struct dentry * child_dentry)405 static bool in_share_dir(struct dentry *child_dentry)
406 {
407 struct dentry *parent_dentry = dget_parent(child_dentry);
408 bool ret = false;
409 const char *share_dir = ".share";
410
411 if (!strncmp(parent_dentry->d_name.name, share_dir, strlen(share_dir)))
412 ret = true;
413
414 dput(parent_dentry);
415 return ret;
416 }
417
hmdfs_lookup_remote_dentry(struct inode * parent_inode,struct dentry * child_dentry,int flags)418 static struct dentry *hmdfs_lookup_remote_dentry(struct inode *parent_inode,
419 struct dentry *child_dentry,
420 int flags)
421 {
422 struct dentry *ret = NULL;
423 struct inode *inode = NULL;
424 struct super_block *sb = parent_inode->i_sb;
425 struct hmdfs_sb_info *sbi = sb->s_fs_info;
426 struct hmdfs_lookup_ret *lookup_result = NULL;
427 struct hmdfs_peer *con = NULL;
428 char *file_name = NULL;
429 int file_name_len = child_dentry->d_name.len;
430 struct qstr qstr;
431 struct hmdfs_dentry_info *gdi = hmdfs_d(child_dentry);
432 uint64_t device_id = 0;
433 char *relative_path = NULL;
434
435 file_name = kzalloc(NAME_MAX + 1, GFP_KERNEL);
436 if (!file_name)
437 return ERR_PTR(-ENOMEM);
438 strncpy(file_name, child_dentry->d_name.name, file_name_len);
439
440 qstr.name = file_name;
441 qstr.len = strlen(file_name);
442
443 device_id = gdi->device_id;
444 con = hmdfs_lookup_from_devid(sbi, device_id);
445 if (!con) {
446 ret = ERR_PTR(-ESHUTDOWN);
447 goto done;
448 }
449
450 relative_path = hmdfs_get_dentry_relative_path(child_dentry->d_parent);
451 if (unlikely(!relative_path)) {
452 ret = ERR_PTR(-ENOMEM);
453 hmdfs_err("get relative path failed %d", -ENOMEM);
454 goto done;
455 }
456
457 lookup_result = hmdfs_lookup_by_con(con, child_dentry, &qstr, flags,
458 relative_path);
459 if (lookup_result != NULL) {
460 if (in_share_dir(child_dentry))
461 gdi->file_type = HM_SHARE;
462 inode = fill_inode_remote(sb, con, lookup_result, parent_inode);
463 ret = d_splice_alias(inode, child_dentry);
464 if (!IS_ERR_OR_NULL(ret))
465 child_dentry = ret;
466 if (!IS_ERR(ret))
467 check_and_fixup_ownership_remote(parent_inode,
468 child_dentry);
469 } else {
470 ret = ERR_PTR(-ENOENT);
471 }
472
473 done:
474 if (con)
475 peer_put(con);
476 kfree(relative_path);
477 kfree(lookup_result);
478 kfree(file_name);
479 return ret;
480 }
481
hmdfs_lookup_remote(struct inode * parent_inode,struct dentry * child_dentry,unsigned int flags)482 struct dentry *hmdfs_lookup_remote(struct inode *parent_inode,
483 struct dentry *child_dentry,
484 unsigned int flags)
485 {
486 int err = 0;
487 struct dentry *ret = NULL;
488 struct hmdfs_dentry_info *gdi = NULL;
489 struct hmdfs_sb_info *sbi = hmdfs_sb(child_dentry->d_sb);
490
491 trace_hmdfs_lookup_remote(parent_inode, child_dentry, flags);
492 if (child_dentry->d_name.len > NAME_MAX) {
493 err = -ENAMETOOLONG;
494 ret = ERR_PTR(-ENAMETOOLONG);
495 goto out;
496 }
497
498 err = init_hmdfs_dentry_info(sbi, child_dentry,
499 HMDFS_LAYER_OTHER_REMOTE);
500 if (err) {
501 ret = ERR_PTR(err);
502 goto out;
503 }
504 gdi = hmdfs_d(child_dentry);
505 gdi->device_id = hmdfs_d(child_dentry->d_parent)->device_id;
506
507 if (is_current_hmdfs_server_ctx())
508 goto out;
509
510 ret = hmdfs_lookup_remote_dentry(parent_inode, child_dentry, flags);
511 /*
512 * don't return error if inode do not exist, so that vfs can continue
513 * to create it.
514 */
515 if (IS_ERR_OR_NULL(ret)) {
516 err = PTR_ERR(ret);
517 if (err == -ENOENT)
518 ret = NULL;
519 } else {
520 child_dentry = ret;
521 }
522
523 out:
524 if (!err)
525 hmdfs_set_time(child_dentry, jiffies);
526 trace_hmdfs_lookup_remote_end(parent_inode, child_dentry, err);
527 return ret;
528 }
529
530 /* delete dentry in cache file */
delete_in_cache_file(uint64_t dev_id,struct dentry * dentry)531 void delete_in_cache_file(uint64_t dev_id, struct dentry *dentry)
532 {
533 struct clearcache_item *item = NULL;
534
535 item = hmdfs_find_cache_item(dev_id, dentry->d_parent);
536 if (item) {
537 hmdfs_delete_dentry(dentry, item->filp);
538 kref_put(&item->ref, release_cache_item);
539 } else {
540 hmdfs_info("find cache item failed, con:%llu", dev_id);
541 }
542 }
543
hmdfs_mkdir_remote_dentry(struct hmdfs_peer * conn,struct dentry * dentry,umode_t mode)544 int hmdfs_mkdir_remote_dentry(struct hmdfs_peer *conn, struct dentry *dentry,
545 umode_t mode)
546 {
547 int err = 0;
548 char *dir_path = NULL;
549 struct dentry *parent_dentry = dentry->d_parent;
550 struct inode *parent_inode = d_inode(parent_dentry);
551 struct super_block *sb = parent_inode->i_sb;
552 const unsigned char *d_name = dentry->d_name.name;
553 struct hmdfs_lookup_ret *mkdir_ret = NULL;
554 struct inode *inode = NULL;
555
556 mkdir_ret = kmalloc(sizeof(*mkdir_ret), GFP_KERNEL);
557 if (!mkdir_ret) {
558 err = -ENOMEM;
559 return err;
560 }
561 dir_path = hmdfs_get_dentry_relative_path(parent_dentry);
562 if (!dir_path) {
563 err = -EACCES;
564 goto mkdir_out;
565 }
566 err = hmdfs_client_start_mkdir(conn, dir_path, d_name, mode, mkdir_ret);
567 if (err) {
568 hmdfs_err("hmdfs_client_start_mkdir failed err = %d", err);
569 goto mkdir_out;
570 }
571 if (mkdir_ret) {
572 inode = fill_inode_remote(sb, conn, mkdir_ret, parent_inode);
573 if (!IS_ERR(inode))
574 d_add(dentry, inode);
575 else
576 err = PTR_ERR(inode);
577 check_and_fixup_ownership_remote(parent_inode, dentry);
578 } else {
579 err = -ENOENT;
580 }
581
582 mkdir_out:
583 kfree(dir_path);
584 kfree(mkdir_ret);
585 return err;
586 }
587
hmdfs_mkdir_remote(struct inode * dir,struct dentry * dentry,umode_t mode)588 int hmdfs_mkdir_remote(struct inode *dir, struct dentry *dentry, umode_t mode)
589 {
590 int err = 0;
591 struct hmdfs_inode_info *info = hmdfs_i(dir);
592 struct hmdfs_peer *con = info->conn;
593
594 if (!con) {
595 hmdfs_warning("qpb_debug: con is null!");
596 goto out;
597 }
598 if (con->version <= USERSPACE_MAX_VER) {
599 err = -EPERM;
600 goto out;
601 }
602 err = hmdfs_mkdir_remote_dentry(con, dentry, mode);
603 if (!err)
604 create_in_cache_file(con->device_id, dentry);
605 else
606 hmdfs_err("remote mkdir failed err = %d", err);
607
608 out:
609 trace_hmdfs_mkdir_remote(dir, dentry, err);
610 return err;
611 }
612
hmdfs_create_remote_dentry(struct hmdfs_peer * conn,struct dentry * dentry,umode_t mode,bool want_excl)613 int hmdfs_create_remote_dentry(struct hmdfs_peer *conn, struct dentry *dentry,
614 umode_t mode, bool want_excl)
615 {
616 int err = 0;
617 char *dir_path = NULL;
618 struct dentry *parent_dentry = dentry->d_parent;
619 struct inode *parent_inode = d_inode(parent_dentry);
620 struct super_block *sb = parent_inode->i_sb;
621 const unsigned char *d_name = dentry->d_name.name;
622 struct hmdfs_lookup_ret *create_ret = NULL;
623 struct inode *inode = NULL;
624
625 create_ret = kmalloc(sizeof(*create_ret), GFP_KERNEL);
626 if (!create_ret) {
627 err = -ENOMEM;
628 return err;
629 }
630 dir_path = hmdfs_get_dentry_relative_path(parent_dentry);
631 if (!dir_path) {
632 err = -EACCES;
633 goto create_out;
634 }
635 err = hmdfs_client_start_create(conn, dir_path, d_name, mode,
636 want_excl, create_ret);
637 if (err) {
638 hmdfs_err("hmdfs_client_start_create failed err = %d", err);
639 goto create_out;
640 }
641 if (create_ret) {
642 inode = fill_inode_remote(sb, conn, create_ret, parent_inode);
643 if (!IS_ERR(inode))
644 d_add(dentry, inode);
645 else
646 err = PTR_ERR(inode);
647 check_and_fixup_ownership_remote(parent_inode, dentry);
648 } else {
649 err = -ENOENT;
650 hmdfs_err("get remote inode info failed err = %d", err);
651 }
652
653 create_out:
654 kfree(dir_path);
655 kfree(create_ret);
656 return err;
657 }
658
hmdfs_create_remote(struct inode * dir,struct dentry * dentry,umode_t mode,bool want_excl)659 int hmdfs_create_remote(struct inode *dir, struct dentry *dentry, umode_t mode,
660 bool want_excl)
661 {
662 int err = 0;
663 struct hmdfs_inode_info *info = hmdfs_i(dir);
664 struct hmdfs_peer *con = info->conn;
665
666 if (!con) {
667 hmdfs_warning("qpb_debug: con is null!");
668 goto out;
669 }
670 if (con->version <= USERSPACE_MAX_VER) {
671 err = -EPERM;
672 goto out;
673 }
674 err = hmdfs_create_remote_dentry(con, dentry, mode, want_excl);
675 if (!err)
676 create_in_cache_file(con->device_id, dentry);
677 else
678 hmdfs_err("remote create failed err = %d", err);
679
680 out:
681 trace_hmdfs_create_remote(dir, dentry, err);
682 return err;
683 }
684
hmdfs_rmdir_remote_dentry(struct hmdfs_peer * conn,struct dentry * dentry)685 int hmdfs_rmdir_remote_dentry(struct hmdfs_peer *conn, struct dentry *dentry)
686 {
687 int error = 0;
688 char *dir_path = NULL;
689 const char *dentry_name = dentry->d_name.name;
690
691 dir_path = hmdfs_get_dentry_relative_path(dentry->d_parent);
692 if (!dir_path) {
693 error = -EACCES;
694 goto rmdir_out;
695 }
696
697 error = hmdfs_client_start_rmdir(conn, dir_path, dentry_name);
698 if (!error)
699 delete_in_cache_file(conn->device_id, dentry);
700
701 rmdir_out:
702 kfree(dir_path);
703 return error;
704 }
705
hmdfs_rmdir_remote(struct inode * dir,struct dentry * dentry)706 int hmdfs_rmdir_remote(struct inode *dir, struct dentry *dentry)
707 {
708 int err = 0;
709 struct hmdfs_inode_info *info = hmdfs_i(dentry->d_inode);
710 struct hmdfs_peer *con = info->conn;
711
712 if (!con)
713 goto out;
714
715 if (hmdfs_file_type(dentry->d_name.name) != HMDFS_TYPE_COMMON) {
716 err = -EACCES;
717 goto out;
718 }
719 if (con->version <= USERSPACE_MAX_VER) {
720 err = -EPERM;
721 goto out;
722 }
723 err = hmdfs_rmdir_remote_dentry(con, dentry);
724 /* drop dentry even remote failed
725 * it maybe cause that one remote devices disconnect
726 * when doing remote rmdir
727 */
728 d_drop(dentry);
729 out:
730 /* return connect device's errcode */
731 trace_hmdfs_rmdir_remote(dir, dentry, err);
732 return err;
733 }
734
hmdfs_dev_unlink_from_con(struct hmdfs_peer * conn,struct dentry * dentry)735 int hmdfs_dev_unlink_from_con(struct hmdfs_peer *conn, struct dentry *dentry)
736 {
737 int error = 0;
738 char *dir_path = NULL;
739 const char *dentry_name = dentry->d_name.name;
740
741 dir_path = hmdfs_get_dentry_relative_path(dentry->d_parent);
742 if (!dir_path) {
743 error = -EACCES;
744 goto unlink_out;
745 }
746 error = hmdfs_client_start_unlink(conn, dir_path, dentry_name);
747 if (!error) {
748 delete_in_cache_file(conn->device_id, dentry);
749 drop_nlink(d_inode(dentry));
750 d_drop(dentry);
751 }
752 unlink_out:
753 kfree(dir_path);
754 return error;
755 }
756
hmdfs_unlink_remote(struct inode * dir,struct dentry * dentry)757 int hmdfs_unlink_remote(struct inode *dir, struct dentry *dentry)
758 {
759 struct hmdfs_inode_info *info = hmdfs_i(dentry->d_inode);
760 struct hmdfs_peer *conn = info->conn;
761
762 if (hmdfs_file_type(dentry->d_name.name) != HMDFS_TYPE_COMMON)
763 return -EACCES;
764
765 if (!conn)
766 return 0;
767
768 if (conn->status != NODE_STAT_ONLINE)
769 return 0;
770
771 return conn->conn_operations->remote_unlink(conn, dentry);
772 }
773
774 /* rename dentry in cache file */
rename_in_cache_file(uint64_t dev_id,struct dentry * old_dentry,struct dentry * new_dentry)775 static void rename_in_cache_file(uint64_t dev_id, struct dentry *old_dentry,
776 struct dentry *new_dentry)
777 {
778 struct clearcache_item *old_item = NULL;
779 struct clearcache_item *new_item = NULL;
780
781 old_item = hmdfs_find_cache_item(dev_id, old_dentry->d_parent);
782 new_item = hmdfs_find_cache_item(dev_id, new_dentry->d_parent);
783 if (old_item != NULL && new_item != NULL) {
784 hmdfs_rename_dentry(old_dentry, new_dentry, old_item->filp,
785 new_item->filp);
786 } else if (old_item != NULL) {
787 hmdfs_err("new cache item find failed!");
788 } else if (new_item != NULL) {
789 hmdfs_err("old cache item find failed!");
790 } else {
791 hmdfs_err("both cache item find failed!");
792 }
793
794 if (old_item)
795 kref_put(&old_item->ref, release_cache_item);
796 if (new_item)
797 kref_put(&new_item->ref, release_cache_item);
798 }
799
hmdfs_rename_remote(struct inode * old_dir,struct dentry * old_dentry,struct inode * new_dir,struct dentry * new_dentry,unsigned int flags)800 int hmdfs_rename_remote(struct inode *old_dir, struct dentry *old_dentry,
801 struct inode *new_dir, struct dentry *new_dentry,
802 unsigned int flags)
803 {
804 int err = 0;
805 int ret = 0;
806 const char *old_dentry_d_name = old_dentry->d_name.name;
807 char *relative_old_dir_path = 0;
808 const char *new_dentry_d_name = new_dentry->d_name.name;
809 char *relative_new_dir_path = 0;
810 struct hmdfs_inode_info *info = hmdfs_i(old_dentry->d_inode);
811 struct hmdfs_peer *con = info->conn;
812
813 trace_hmdfs_rename_remote(old_dir, old_dentry, new_dir, new_dentry,
814 flags);
815
816 if (flags & ~RENAME_NOREPLACE)
817 return -EINVAL;
818
819 if (hmdfs_file_type(old_dentry->d_name.name) != HMDFS_TYPE_COMMON ||
820 hmdfs_file_type(new_dentry->d_name.name) != HMDFS_TYPE_COMMON) {
821 return -EACCES;
822 }
823
824 relative_old_dir_path =
825 hmdfs_get_dentry_relative_path(old_dentry->d_parent);
826 relative_new_dir_path =
827 hmdfs_get_dentry_relative_path(new_dentry->d_parent);
828 if (!relative_old_dir_path || !relative_new_dir_path) {
829 err = -EACCES;
830 goto rename_out;
831 }
832 if (S_ISREG(old_dentry->d_inode->i_mode)) {
833 if (con->version > USERSPACE_MAX_VER) {
834 hmdfs_debug("send MSG to remote devID %llu",
835 con->device_id);
836 err = hmdfs_client_start_rename(
837 con, relative_old_dir_path, old_dentry_d_name,
838 relative_new_dir_path, new_dentry_d_name,
839 flags);
840 if (!err)
841 rename_in_cache_file(con->device_id, old_dentry,
842 new_dentry);
843 }
844 } else if (S_ISDIR(old_dentry->d_inode->i_mode)) {
845 if ((con->status == NODE_STAT_ONLINE) &&
846 (con->version > USERSPACE_MAX_VER)) {
847 ret = hmdfs_client_start_rename(
848 con, relative_old_dir_path, old_dentry_d_name,
849 relative_new_dir_path, new_dentry_d_name,
850 flags);
851 if (!ret)
852 rename_in_cache_file(con->device_id, old_dentry,
853 new_dentry);
854 else
855 err = ret;
856 }
857 }
858 if (!err)
859 d_invalidate(old_dentry);
860 rename_out:
861 kfree(relative_old_dir_path);
862 kfree(relative_new_dir_path);
863 return err;
864 }
865
hmdfs_dir_setattr_remote(struct dentry * dentry,struct iattr * ia)866 static int hmdfs_dir_setattr_remote(struct dentry *dentry, struct iattr *ia)
867 {
868 // Do not support dir setattr
869 return 0;
870 }
871
872 const struct inode_operations hmdfs_dev_dir_inode_ops_remote = {
873 .lookup = hmdfs_lookup_remote,
874 .mkdir = hmdfs_mkdir_remote,
875 .create = hmdfs_create_remote,
876 .rmdir = hmdfs_rmdir_remote,
877 .unlink = hmdfs_unlink_remote,
878 .rename = hmdfs_rename_remote,
879 .setattr = hmdfs_dir_setattr_remote,
880 .permission = hmdfs_permission,
881 };
882
hmdfs_setattr_remote(struct dentry * dentry,struct iattr * ia)883 static int hmdfs_setattr_remote(struct dentry *dentry, struct iattr *ia)
884 {
885 struct hmdfs_inode_info *info = hmdfs_i(d_inode(dentry));
886 struct hmdfs_peer *conn = info->conn;
887 struct inode *inode = d_inode(dentry);
888 char *send_buf = NULL;
889 int err = 0;
890
891 if (hmdfs_inode_is_stashing(info))
892 return -EAGAIN;
893
894 send_buf = hmdfs_get_dentry_relative_path(dentry);
895 if (!send_buf) {
896 err = -ENOMEM;
897 goto out_free;
898 }
899 if (ia->ia_valid & ATTR_SIZE) {
900 err = inode_newsize_ok(inode, ia->ia_size);
901 if (err)
902 goto out_free;
903 truncate_setsize(inode, ia->ia_size);
904 info->getattr_isize = HMDFS_STALE_REMOTE_ISIZE;
905 }
906 if (ia->ia_valid & ATTR_MTIME)
907 inode->i_mtime = ia->ia_mtime;
908
909 if ((ia->ia_valid & ATTR_SIZE) || (ia->ia_valid & ATTR_MTIME)) {
910 struct setattr_info send_setattr_info = {
911 .size = cpu_to_le64(ia->ia_size),
912 .valid = cpu_to_le32(ia->ia_valid),
913 .mtime = cpu_to_le64(ia->ia_mtime.tv_sec),
914 .mtime_nsec = cpu_to_le32(ia->ia_mtime.tv_nsec),
915 };
916 err = hmdfs_send_setattr(conn, send_buf, &send_setattr_info);
917 }
918 out_free:
919 kfree(send_buf);
920 return err;
921 }
922
hmdfs_remote_getattr(struct hmdfs_peer * conn,struct dentry * dentry,unsigned int lookup_flags,struct hmdfs_getattr_ret ** result)923 int hmdfs_remote_getattr(struct hmdfs_peer *conn, struct dentry *dentry,
924 unsigned int lookup_flags,
925 struct hmdfs_getattr_ret **result)
926 {
927 char *send_buf = NULL;
928 struct hmdfs_getattr_ret *attr = NULL;
929 int err = 0;
930
931 if (dentry->d_sb != conn->sbi->sb || !result)
932 return -EINVAL;
933
934 attr = kzalloc(sizeof(*attr), GFP_KERNEL);
935 if (!attr)
936 return -ENOMEM;
937
938 send_buf = hmdfs_get_dentry_relative_path(dentry);
939 if (!send_buf) {
940 kfree(attr);
941 return -ENOMEM;
942 }
943
944 err = hmdfs_send_getattr(conn, send_buf, lookup_flags, attr);
945 kfree(send_buf);
946
947 if (err) {
948 kfree(attr);
949 return err;
950 }
951
952 *result = attr;
953 return 0;
954 }
955
hmdfs_get_cached_attr_remote(const struct path * path,struct kstat * stat,u32 request_mask,unsigned int flags)956 static int hmdfs_get_cached_attr_remote(const struct path *path,
957 struct kstat *stat, u32 request_mask,
958 unsigned int flags)
959 {
960 struct inode *inode = d_inode(path->dentry);
961 struct hmdfs_inode_info *info = hmdfs_i(inode);
962 uint64_t size = info->getattr_isize;
963
964 stat->ino = inode->i_ino;
965 stat->mtime = inode->i_mtime;
966 stat->mode = inode->i_mode;
967 stat->uid.val = inode->i_uid.val;
968 stat->gid.val = inode->i_gid.val;
969 if (size == HMDFS_STALE_REMOTE_ISIZE)
970 size = i_size_read(inode);
971
972 stat->size = size;
973 return 0;
974 }
975
hmdfs_remote_listxattr(struct dentry * dentry,char * list,size_t size)976 ssize_t hmdfs_remote_listxattr(struct dentry *dentry, char *list, size_t size)
977 {
978 struct inode *inode = d_inode(dentry);
979 struct hmdfs_inode_info *info = hmdfs_i(inode);
980 struct hmdfs_peer *conn = info->conn;
981 char *send_buf = NULL;
982 ssize_t res = 0;
983 size_t r_size = size;
984
985 if (!hmdfs_support_xattr(dentry))
986 return -EOPNOTSUPP;
987
988 if (size > HMDFS_LISTXATTR_SIZE_MAX)
989 r_size = HMDFS_LISTXATTR_SIZE_MAX;
990
991 send_buf = hmdfs_get_dentry_relative_path(dentry);
992 if (!send_buf)
993 return -ENOMEM;
994
995 res = hmdfs_send_listxattr(conn, send_buf, list, r_size);
996 kfree(send_buf);
997
998 if (res == -ERANGE && r_size != size) {
999 hmdfs_info("no support listxattr size over than %d",
1000 HMDFS_LISTXATTR_SIZE_MAX);
1001 res = -E2BIG;
1002 }
1003
1004 return res;
1005 }
1006
1007 const struct inode_operations hmdfs_dev_file_iops_remote = {
1008 .setattr = hmdfs_setattr_remote,
1009 .permission = hmdfs_permission,
1010 .getattr = hmdfs_get_cached_attr_remote,
1011 .listxattr = hmdfs_remote_listxattr,
1012 };
1013