Skip to content

Commit cb4931a

Browse files
committed
fs: Enhanced error notification mechanism for read-only filesystems
- Added handling for the two paths that need to be reported in the rename system call. - Introduced a new macro `deepin_should_notify_ro_fs_err` to simplify error-checking code. - Collect more detailed information when an error occurs. - Replaced the `/proc/sys/fs/deepin-err-notify-enable` file with multiple netlink commands. - Reverted modifications to overlayfs; the `deepin_err_notify` mount option is no longer available. Link: #1268 Signed-off-by: electricface <[email protected]>
1 parent 4048893 commit cb4931a

File tree

10 files changed

+879
-201
lines changed

10 files changed

+879
-201
lines changed

fs/deepin_err_notify.c

Lines changed: 846 additions & 109 deletions
Large diffs are not rendered by default.

fs/internal.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,23 @@ int deepin_get_path_for_err_notify(int dfd, struct filename *name, struct path *
6868
* deepin_err_notify.c
6969
*/
7070
int deepin_err_notify_enabled(void);
71-
void deepin_check_and_notify_ro_fs_err(const struct path *path, const char *func_name);
72-
void deepin_send_ro_fs_err_notification(const char *filename, const char *func_name);
71+
void deepin_check_and_notify_ro_fs_err(const struct path *path,
72+
const char *func_name);
73+
void deepin_check_and_notify_ro_fs_err_paths(const struct path *path,
74+
const struct path *path_new,
75+
const char *func_name);
76+
void deepin_notify_rename_ro_fs_err(const struct qstr *old_last,
77+
const struct qstr *new_last,
78+
const struct path *old_path,
79+
const struct path *new_path);
80+
81+
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
82+
/* Check if error is EROFS and notification is enabled */
83+
#define deepin_should_notify_ro_fs_err(error) \
84+
unlikely((error) == -EROFS && deepin_err_notify_enabled())
85+
#else
86+
#define deepin_should_notify_ro_fs_err(error) 0
87+
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
7388

7489
/*
7590
* namespace.c

fs/ioctl.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -903,10 +903,8 @@ SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
903903
if (error == -ENOIOCTLCMD)
904904
error = vfs_ioctl(f.file, cmd, arg);
905905

906-
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
907-
if (unlikely((error == -EROFS) && deepin_err_notify_enabled()))
906+
if (deepin_should_notify_ro_fs_err(error))
908907
deepin_check_and_notify_ro_fs_err(&f.file->f_path, "ioctl");
909-
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
910908

911909
out:
912910
fdput(f);

fs/namei.c

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4073,8 +4073,7 @@ static int do_mknodat(int dfd, struct filename *name, umode_t mode,
40734073
goto retry;
40744074
}
40754075
out1:
4076-
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
4077-
if (unlikely((error == -EROFS) && deepin_err_notify_enabled())) {
4076+
if (deepin_should_notify_ro_fs_err(error)) {
40784077
struct path file_path;
40794078
int get_path_err;
40804079

@@ -4085,7 +4084,6 @@ static int do_mknodat(int dfd, struct filename *name, umode_t mode,
40854084
path_put(&file_path);
40864085
}
40874086
}
4088-
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
40894087
putname(name);
40904088
return error;
40914089
}
@@ -4169,8 +4167,7 @@ int do_mkdirat(int dfd, struct filename *name, umode_t mode)
41694167
goto retry;
41704168
}
41714169
out_putname:
4172-
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
4173-
if (unlikely((error == -EROFS) && deepin_err_notify_enabled())) {
4170+
if (deepin_should_notify_ro_fs_err(error)) {
41744171
struct path file_path;
41754172
int get_path_err;
41764173

@@ -4181,7 +4178,6 @@ int do_mkdirat(int dfd, struct filename *name, umode_t mode)
41814178
path_put(&file_path);
41824179
}
41834180
}
4184-
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
41854181
putname(name);
41864182
return error;
41874183
}
@@ -4299,8 +4295,7 @@ int do_rmdir(int dfd, struct filename *name)
42994295
inode_unlock(path.dentry->d_inode);
43004296
mnt_drop_write(path.mnt);
43014297
exit2:
4302-
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
4303-
if (unlikely((error == -EROFS) && deepin_err_notify_enabled())) {
4298+
if (deepin_should_notify_ro_fs_err(error)) {
43044299
dentry = lookup_one_qstr_excl(&last, path.dentry, 0);
43054300
if (!IS_ERR(dentry)) {
43064301
if (d_is_positive(dentry)) {
@@ -4313,7 +4308,6 @@ int do_rmdir(int dfd, struct filename *name)
43134308
dput(dentry);
43144309
}
43154310
}
4316-
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
43174311
path_put(&path);
43184312
if (retry_estale(error, lookup_flags)) {
43194313
lookup_flags |= LOOKUP_REVAL;
@@ -4459,8 +4453,7 @@ int do_unlinkat(int dfd, struct filename *name)
44594453
}
44604454
mnt_drop_write(path.mnt);
44614455
exit2:
4462-
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
4463-
if (unlikely((error == -EROFS) && deepin_err_notify_enabled())) {
4456+
if (deepin_should_notify_ro_fs_err(error)) {
44644457
dentry = lookup_one_qstr_excl(&last, path.dentry, 0);
44654458
if (!IS_ERR(dentry)) {
44664459
if (d_is_positive(dentry)) {
@@ -4473,7 +4466,6 @@ int do_unlinkat(int dfd, struct filename *name)
44734466
dput(dentry);
44744467
}
44754468
}
4476-
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
44774469
path_put(&path);
44784470
if (retry_estale(error, lookup_flags)) {
44794471
lookup_flags |= LOOKUP_REVAL;
@@ -4574,8 +4566,7 @@ int do_symlinkat(struct filename *from, int newdfd, struct filename *to)
45744566
goto retry;
45754567
}
45764568
out_putnames:
4577-
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
4578-
if (unlikely((error == -EROFS) && deepin_err_notify_enabled())) {
4569+
if (deepin_should_notify_ro_fs_err(error)) {
45794570
struct path file_path;
45804571
int get_path_err;
45814572

@@ -4587,7 +4578,6 @@ int do_symlinkat(struct filename *from, int newdfd, struct filename *to)
45874578
path_put(&file_path);
45884579
}
45894580
}
4590-
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
45914581
putname(to);
45924582
putname(from);
45934583
return error;
@@ -4766,8 +4756,7 @@ int do_linkat(int olddfd, struct filename *old, int newdfd,
47664756
goto retry;
47674757
}
47684758
out_putpath:
4769-
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
4770-
if (unlikely((error == -EROFS) && deepin_err_notify_enabled())) {
4759+
if (deepin_should_notify_ro_fs_err(error)) {
47714760
struct path file_path;
47724761
int get_path_err;
47734762

@@ -4778,7 +4767,6 @@ int do_linkat(int olddfd, struct filename *old, int newdfd,
47784767
path_put(&file_path);
47794768
}
47804769
}
4781-
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
47824770
path_put(&old_path);
47834771
out_putnames:
47844772
putname(old);
@@ -5133,22 +5121,8 @@ int do_renameat2(int olddfd, struct filename *from, int newdfd,
51335121
}
51345122
mnt_drop_write(old_path.mnt);
51355123
exit2:
5136-
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
5137-
if (unlikely((error == -EROFS) && deepin_err_notify_enabled())) {
5138-
old_dentry =
5139-
lookup_one_qstr_excl(&old_last, old_path.dentry, 0);
5140-
if (!IS_ERR(old_dentry)) {
5141-
if (d_is_positive(old_dentry)) {
5142-
struct path file_path = { .mnt = old_path.mnt,
5143-
.dentry =
5144-
old_dentry };
5145-
deepin_check_and_notify_ro_fs_err(&file_path,
5146-
"rename");
5147-
}
5148-
dput(old_dentry);
5149-
}
5150-
}
5151-
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
5124+
if (deepin_should_notify_ro_fs_err(error))
5125+
deepin_notify_rename_ro_fs_err(&old_last, &new_last, &old_path, &new_path);
51525126
if (retry_estale(error, lookup_flags))
51535127
should_retry = true;
51545128
path_put(&new_path);

fs/open.c

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,8 @@ long do_sys_truncate(const char __user *pathname, loff_t length)
136136
error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
137137
if (!error) {
138138
error = vfs_truncate(&path, length);
139-
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
140-
if (unlikely((error == -EROFS) && deepin_err_notify_enabled()))
139+
if (deepin_should_notify_ro_fs_err(error))
141140
deepin_check_and_notify_ro_fs_err(&path, "truncate");
142-
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
143141
path_put(&path);
144142
}
145143
if (retry_estale(error, lookup_flags)) {
@@ -717,10 +715,8 @@ static int do_fchmodat(int dfd, const char __user *filename, umode_t mode,
717715
error = user_path_at(dfd, filename, lookup_flags, &path);
718716
if (!error) {
719717
error = chmod_common(&path, mode);
720-
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
721-
if (unlikely((error == -EROFS) && deepin_err_notify_enabled()))
718+
if (deepin_should_notify_ro_fs_err(error))
722719
deepin_check_and_notify_ro_fs_err(&path, "chmod");
723-
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
724720
path_put(&path);
725721
if (retry_estale(error, lookup_flags)) {
726722
lookup_flags |= LOOKUP_REVAL;
@@ -846,10 +842,8 @@ int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group,
846842
error = chown_common(&path, user, group);
847843
mnt_drop_write(path.mnt);
848844
out_release:
849-
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
850-
if (unlikely((error == -EROFS) && deepin_err_notify_enabled()))
845+
if (deepin_should_notify_ro_fs_err(error))
851846
deepin_check_and_notify_ro_fs_err(&path, "chown");
852-
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
853847
path_put(&path);
854848
if (retry_estale(error, lookup_flags)) {
855849
lookup_flags |= LOOKUP_REVAL;
@@ -1456,9 +1450,7 @@ static long do_sys_openat2(int dfd, const char __user *filename,
14561450
if (IS_ERR(f)) {
14571451
put_unused_fd(fd);
14581452
fd = PTR_ERR(f);
1459-
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
1460-
if (unlikely(fd == -EROFS) &&
1461-
deepin_err_notify_enabled()) {
1453+
if (deepin_should_notify_ro_fs_err(fd)) {
14621454
struct path file_path;
14631455
int get_path_err;
14641456

@@ -1468,7 +1460,6 @@ static long do_sys_openat2(int dfd, const char __user *filename,
14681460
path_put(&file_path);
14691461
}
14701462
}
1471-
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
14721463
} else {
14731464
fd_install(fd, f);
14741465
}

fs/overlayfs/ovl_entry.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@ struct ovl_config {
1919
bool metacopy;
2020
bool userxattr;
2121
bool ovl_volatile;
22-
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
23-
bool deepin_err_notify;
24-
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
2522
};
2623

2724
struct ovl_sb {

fs/overlayfs/params.c

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,6 @@ enum ovl_opt {
5959
Opt_metacopy,
6060
Opt_verity,
6161
Opt_volatile,
62-
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
63-
Opt_deepin_err_notify,
64-
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
6562
};
6663

6764
static const struct constant_table ovl_parameter_bool[] = {
@@ -162,9 +159,6 @@ const struct fs_parameter_spec ovl_parameter_spec[] = {
162159
fsparam_enum("metacopy", Opt_metacopy, ovl_parameter_bool),
163160
fsparam_enum("verity", Opt_verity, ovl_parameter_verity),
164161
fsparam_flag("volatile", Opt_volatile),
165-
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
166-
fsparam_flag("deepin_err_notify", Opt_deepin_err_notify),
167-
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
168162
{}
169163
};
170164

@@ -606,11 +600,6 @@ static int ovl_parse_param(struct fs_context *fc, struct fs_parameter *param)
606600
case Opt_userxattr:
607601
config->userxattr = true;
608602
break;
609-
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
610-
case Opt_deepin_err_notify:
611-
config->deepin_err_notify = true;
612-
break;
613-
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
614603
default:
615604
pr_err("unrecognized mount option \"%s\" or missing value\n",
616605
param->key);
@@ -1022,9 +1011,5 @@ int ovl_show_options(struct seq_file *m, struct dentry *dentry)
10221011
if (ofs->config.verity_mode != ovl_verity_mode_def())
10231012
seq_printf(m, ",verity=%s",
10241013
ovl_verity_mode(&ofs->config));
1025-
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
1026-
if (ofs->config.deepin_err_notify)
1027-
seq_puts(m, ",deepin_err_notify");
1028-
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
10291014
return 0;
10301015
}

fs/overlayfs/super.c

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -267,16 +267,6 @@ static int ovl_statfs(struct dentry *dentry, struct kstatfs *buf)
267267
return err;
268268
}
269269

270-
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
271-
static bool ovl_deepin_should_notify_error(struct super_block *sb)
272-
{
273-
struct ovl_fs *ofs = OVL_FS(sb);
274-
275-
/* Return true if deepin_err_notify mount option was set */
276-
return ofs->config.deepin_err_notify;
277-
}
278-
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
279-
280270
static const struct super_operations ovl_super_operations = {
281271
.alloc_inode = ovl_alloc_inode,
282272
.free_inode = ovl_free_inode,
@@ -286,9 +276,6 @@ static const struct super_operations ovl_super_operations = {
286276
.sync_fs = ovl_sync_fs,
287277
.statfs = ovl_statfs,
288278
.show_options = ovl_show_options,
289-
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
290-
.deepin_should_notify_error = ovl_deepin_should_notify_error,
291-
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
292279
};
293280

294281
#define OVL_WORKDIR_NAME "work"

fs/utimes.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,8 @@ static int do_utimes_path(int dfd, const char __user *filename,
9999
return error;
100100

101101
error = vfs_utimes(&path, times);
102-
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
103-
if (unlikely((error == -EROFS) && deepin_err_notify_enabled()))
102+
if (deepin_should_notify_ro_fs_err(error))
104103
deepin_check_and_notify_ro_fs_err(&path, "utime");
105-
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
106104
path_put(&path);
107105
if (retry_estale(error, lookup_flags)) {
108106
lookup_flags |= LOOKUP_REVAL;

fs/xattr.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -658,10 +658,8 @@ static int path_setxattr(const char __user *pathname,
658658
if (!error) {
659659
error = do_setxattr(mnt_idmap(path.mnt), path.dentry, &ctx);
660660
mnt_drop_write(path.mnt);
661-
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
662-
} else if (unlikely((error == -EROFS) && deepin_err_notify_enabled())) {
661+
} else if (deepin_should_notify_ro_fs_err(error)) {
663662
deepin_check_and_notify_ro_fs_err(&path, "setxattr");
664-
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
665663
}
666664
path_put(&path);
667665
if (retry_estale(error, lookup_flags)) {
@@ -932,10 +930,8 @@ static int path_removexattr(const char __user *pathname,
932930
if (!error) {
933931
error = removexattr(mnt_idmap(path.mnt), path.dentry, kname);
934932
mnt_drop_write(path.mnt);
935-
#ifdef CONFIG_DEEPIN_ERR_NOTIFY
936-
} else if (unlikely((error == -EROFS) && deepin_err_notify_enabled())) {
933+
} else if (deepin_should_notify_ro_fs_err(error)) {
937934
deepin_check_and_notify_ro_fs_err(&path, "removexattr");
938-
#endif /* CONFIG_DEEPIN_ERR_NOTIFY */
939935
}
940936
path_put(&path);
941937
if (retry_estale(error, lookup_flags)) {

0 commit comments

Comments
 (0)