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