-
Notifications
You must be signed in to change notification settings - Fork 1
/
diff.patch
198 lines (198 loc) · 4.94 KB
/
diff.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
15c15,16
< static int ovl_copy_up_truncate(struct dentry *dentry)
---
> static int ovl_copy_up_last(struct dentry *dentry, struct iattr *attr,
> bool no_data)
32,33c33,36
< stat.size = 0;
< err = ovl_copy_up_one(parent, dentry, &lowerpath, &stat);
---
> if (no_data)
> stat.size = 0;
>
> err = ovl_copy_up_one(parent, dentry, &lowerpath, &stat, attr);
45,57d47
< /*
< * Check for permissions before trying to copy-up. This is redundant
< * since it will be rechecked later by ->setattr() on upper dentry. But
< * without this, copy-up can be triggered by just about anybody.
< *
< * We don't initialize inode->size, which just means that
< * inode_newsize_ok() will always check against MAX_LFS_FILESIZE and not
< * check for a swapfile (which this won't be anyway).
< */
< err = inode_change_ok(dentry->d_inode, attr);
< if (err)
< return err;
<
62,66c52,54
< err = ovl_copy_up(dentry);
< if (!err) {
< upperdentry = ovl_dentry_upper(dentry);
<
< inode_lock(upperdentry->d_inode);
---
> upperdentry = ovl_dentry_upper(dentry);
> if (upperdentry) {
> mutex_lock(&upperdentry->d_inode->i_mutex);
68,70c56,58
< if (!err)
< ovl_copyattr(upperdentry->d_inode, dentry->d_inode);
< inode_unlock(upperdentry->d_inode);
---
> mutex_unlock(&upperdentry->d_inode->i_mutex);
> } else {
> err = ovl_copy_up_last(dentry, attr, false);
113,135d100
< if (ovl_is_default_permissions(inode)) {
< struct kstat stat;
< struct path realpath = { .dentry = realdentry };
<
< if (mask & MAY_NOT_BLOCK)
< return -ECHILD;
<
< realpath.mnt = ovl_entry_mnt_real(oe, inode, is_upper);
<
< err = vfs_getattr(&realpath, &stat);
< if (err)
< return err;
<
< if ((stat.mode ^ inode->i_mode) & S_IFMT)
< return -ESTALE;
<
< inode->i_mode = stat.mode;
< inode->i_uid = stat.uid;
< inode->i_gid = stat.gid;
<
< return generic_permission(inode, mask);
< }
<
172,174c137,143
< static const char *ovl_get_link(struct dentry *dentry,
< struct inode *inode,
< struct delayed_call *done)
---
>
> struct ovl_link_data {
> struct dentry *realdentry;
> void *cookie;
> };
>
> static void *ovl_follow_link(struct dentry *dentry, struct nameidata *nd)
175a145
> void *ret;
179,181d148
< if (!dentry)
< return ERR_PTR(-ECHILD);
<
185c152
< if (WARN_ON(!realinode->i_op->get_link))
---
> if (WARN_ON(!realinode->i_op->follow_link))
188c155,186
< return realinode->i_op->get_link(realdentry, realinode, done);
---
> ret = realinode->i_op->follow_link(realdentry, nd);
> if (IS_ERR(ret))
> return ret;
>
> if (realinode->i_op->put_link) {
> struct ovl_link_data *data;
>
> data = kmalloc(sizeof(struct ovl_link_data), GFP_KERNEL);
> if (!data) {
> realinode->i_op->put_link(realdentry, nd, ret);
> return ERR_PTR(-ENOMEM);
> }
> data->realdentry = realdentry;
> data->cookie = ret;
>
> return data;
> } else {
> return NULL;
> }
> }
>
> static void ovl_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
> {
> struct inode *realinode;
> struct ovl_link_data *data = c;
>
> if (!data)
> return;
>
> realinode = data->realdentry->d_inode;
> realinode->i_op->put_link(data->realdentry, nd, data->cookie);
> kfree(data);
210c208
< return strncmp(name, OVL_XATTR_PRE_NAME, OVL_XATTR_PRE_LEN) == 0;
---
> return strncmp(name, "trusted.overlay.", 14) == 0;
243,246c241
< if ((type & (__OVL_PATH_PURE | __OVL_PATH_UPPER)) == __OVL_PATH_UPPER)
< return S_ISDIR(dentry->d_inode->i_mode);
< else
< return false;
---
> return type == OVL_PATH_UPPER && S_ISDIR(dentry->d_inode->i_mode);
307c302
< if (!OVL_TYPE_UPPER(type)) {
---
> if (type == OVL_PATH_LOWER) {
329c324
< if (OVL_TYPE_UPPER(type))
---
> if (type != OVL_PATH_LOWER)
341c336,337
< struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags)
---
> static int ovl_dentry_open(struct dentry *dentry, struct file *file,
> const struct cred *cred)
346,348c342
<
< if (d_is_dir(dentry))
< return d_backing_inode(dentry);
---
> bool want_write = false;
351c345,346
< if (ovl_open_need_copy_up(file_flags, type, realpath.dentry)) {
---
> if (ovl_open_need_copy_up(file->f_flags, type, realpath.dentry)) {
> want_write = true;
354c349
< return ERR_PTR(err);
---
> goto out;
356,357c351,352
< if (file_flags & O_TRUNC)
< err = ovl_copy_up_truncate(dentry);
---
> if (file->f_flags & O_TRUNC)
> err = ovl_copy_up_last(dentry, NULL, true);
360d354
< ovl_drop_write(dentry);
362c356
< return ERR_PTR(err);
---
> goto out_drop_write;
367,370c361,366
< if (realpath.dentry->d_flags & DCACHE_OP_SELECT_INODE)
< return realpath.dentry->d_op->d_select_inode(realpath.dentry, file_flags);
<
< return d_backing_inode(realpath.dentry);
---
> err = vfs_open(&realpath, file, cred);
> out_drop_write:
> if (want_write)
> ovl_drop_write(dentry);
> out:
> return err;
380a377
> .dentry_open = ovl_dentry_open,
385c382,383
< .get_link = ovl_get_link,
---
> .follow_link = ovl_follow_link,
> .put_link = ovl_put_link,
434a433
>