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