kernel: update kernel 4.4 to version 4.4.31
[openwrt/staging/yousong.git] / target / linux / generic / patches-4.4 / 052-02-ubifs-Implement-RENAME_WHITEOUT.patch
1 From: Richard Weinberger <richard@nod.at>
2 Date: Tue, 13 Sep 2016 16:18:56 +0200
3 Subject: [PATCH] ubifs: Implement RENAME_WHITEOUT
4
5 Adds RENAME_WHITEOUT support to UBIFS, we implement
6 it in the same way as ext4 and xfs do.
7 For an overview of other ways to implement it please
8 refere to commit 7dcf5c3e4527 ("xfs: add RENAME_WHITEOUT support").
9
10 Signed-off-by: Richard Weinberger <richard@nod.at>
11 ---
12
13 --- a/fs/ubifs/dir.c
14 +++ b/fs/ubifs/dir.c
15 @@ -301,8 +301,8 @@ out_budg:
16 return err;
17 }
18
19 -static int ubifs_tmpfile(struct inode *dir, struct dentry *dentry,
20 - umode_t mode)
21 +static int do_tmpfile(struct inode *dir, struct dentry *dentry,
22 + umode_t mode, struct inode **whiteout)
23 {
24 struct inode *inode;
25 struct ubifs_info *c = dir->i_sb->s_fs_info;
26 @@ -336,14 +336,27 @@ static int ubifs_tmpfile(struct inode *d
27 }
28 ui = ubifs_inode(inode);
29
30 + if (whiteout) {
31 + init_special_inode(inode, inode->i_mode, WHITEOUT_DEV);
32 + ubifs_assert(inode->i_op == &ubifs_file_inode_operations);
33 + }
34 +
35 err = ubifs_init_security(dir, inode, &dentry->d_name);
36 if (err)
37 goto out_inode;
38
39 mutex_lock(&ui->ui_mutex);
40 insert_inode_hash(inode);
41 - d_tmpfile(dentry, inode);
42 +
43 + if (whiteout) {
44 + mark_inode_dirty(inode);
45 + drop_nlink(inode);
46 + *whiteout = inode;
47 + } else {
48 + d_tmpfile(dentry, inode);
49 + }
50 ubifs_assert(ui->dirty);
51 +
52 instantiated = 1;
53 mutex_unlock(&ui->ui_mutex);
54
55 @@ -371,6 +384,12 @@ out_budg:
56 return err;
57 }
58
59 +static int ubifs_tmpfile(struct inode *dir, struct dentry *dentry,
60 + umode_t mode)
61 +{
62 + return do_tmpfile(dir, dentry, mode, NULL);
63 +}
64 +
65 /**
66 * vfs_dent_type - get VFS directory entry type.
67 * @type: UBIFS directory entry type
68 @@ -1003,37 +1022,43 @@ out_budg:
69 }
70
71 /**
72 - * lock_3_inodes - a wrapper for locking three UBIFS inodes.
73 + * lock_4_inodes - a wrapper for locking three UBIFS inodes.
74 * @inode1: first inode
75 * @inode2: second inode
76 * @inode3: third inode
77 + * @inode4: fouth inode
78 *
79 * This function is used for 'ubifs_rename()' and @inode1 may be the same as
80 - * @inode2 whereas @inode3 may be %NULL.
81 + * @inode2 whereas @inode3 and @inode4 may be %NULL.
82 *
83 * We do not implement any tricks to guarantee strict lock ordering, because
84 * VFS has already done it for us on the @i_mutex. So this is just a simple
85 * wrapper function.
86 */
87 -static void lock_3_inodes(struct inode *inode1, struct inode *inode2,
88 - struct inode *inode3)
89 +static void lock_4_inodes(struct inode *inode1, struct inode *inode2,
90 + struct inode *inode3, struct inode *inode4)
91 {
92 mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_1);
93 if (inode2 != inode1)
94 mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_2);
95 if (inode3)
96 mutex_lock_nested(&ubifs_inode(inode3)->ui_mutex, WB_MUTEX_3);
97 + if (inode4)
98 + mutex_lock_nested(&ubifs_inode(inode4)->ui_mutex, WB_MUTEX_4);
99 }
100
101 /**
102 - * unlock_3_inodes - a wrapper for unlocking three UBIFS inodes for rename.
103 + * unlock_4_inodes - a wrapper for unlocking three UBIFS inodes for rename.
104 * @inode1: first inode
105 * @inode2: second inode
106 * @inode3: third inode
107 + * @inode4: fouth inode
108 */
109 -static void unlock_3_inodes(struct inode *inode1, struct inode *inode2,
110 - struct inode *inode3)
111 +static void unlock_4_inodes(struct inode *inode1, struct inode *inode2,
112 + struct inode *inode3, struct inode *inode4)
113 {
114 + if (inode4)
115 + mutex_unlock(&ubifs_inode(inode4)->ui_mutex);
116 if (inode3)
117 mutex_unlock(&ubifs_inode(inode3)->ui_mutex);
118 if (inode1 != inode2)
119 @@ -1042,12 +1067,15 @@ static void unlock_3_inodes(struct inode
120 }
121
122 static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry,
123 - struct inode *new_dir, struct dentry *new_dentry)
124 + struct inode *new_dir, struct dentry *new_dentry,
125 + unsigned int flags)
126 {
127 struct ubifs_info *c = old_dir->i_sb->s_fs_info;
128 struct inode *old_inode = d_inode(old_dentry);
129 struct inode *new_inode = d_inode(new_dentry);
130 + struct inode *whiteout = NULL;
131 struct ubifs_inode *old_inode_ui = ubifs_inode(old_inode);
132 + struct ubifs_inode *whiteout_ui = NULL;
133 int err, release, sync = 0, move = (new_dir != old_dir);
134 int is_dir = S_ISDIR(old_inode->i_mode);
135 int unlink = !!new_inode;
136 @@ -1069,9 +1097,13 @@ static int ubifs_rename(struct inode *ol
137 * separately.
138 */
139
140 - dbg_gen("dent '%pd' ino %lu in dir ino %lu to dent '%pd' in dir ino %lu",
141 + dbg_gen("dent '%pd' ino %lu in dir ino %lu to dent '%pd' in dir ino %lu flags 0x%x",
142 old_dentry, old_inode->i_ino, old_dir->i_ino,
143 - new_dentry, new_dir->i_ino);
144 + new_dentry, new_dir->i_ino, flags);
145 +
146 + if (flags & ~(RENAME_NOREPLACE | RENAME_WHITEOUT))
147 + return -EINVAL;
148 +
149 ubifs_assert(mutex_is_locked(&old_dir->i_mutex));
150 ubifs_assert(mutex_is_locked(&new_dir->i_mutex));
151 if (unlink)
152 @@ -1093,7 +1125,32 @@ static int ubifs_rename(struct inode *ol
153 return err;
154 }
155
156 - lock_3_inodes(old_dir, new_dir, new_inode);
157 + if (flags & RENAME_WHITEOUT) {
158 + union ubifs_dev_desc *dev = NULL;
159 +
160 + dev = kmalloc(sizeof(union ubifs_dev_desc), GFP_NOFS);
161 + if (!dev) {
162 + ubifs_release_budget(c, &req);
163 + ubifs_release_budget(c, &ino_req);
164 + return -ENOMEM;
165 + }
166 +
167 + err = do_tmpfile(old_dir, old_dentry, S_IFCHR | WHITEOUT_MODE, &whiteout);
168 + if (err) {
169 + ubifs_release_budget(c, &req);
170 + ubifs_release_budget(c, &ino_req);
171 + kfree(dev);
172 + return err;
173 + }
174 +
175 + whiteout->i_state |= I_LINKABLE;
176 + whiteout_ui = ubifs_inode(whiteout);
177 + whiteout_ui->data = dev;
178 + whiteout_ui->data_len = ubifs_encode_dev(dev, MKDEV(0, 0));
179 + ubifs_assert(!whiteout_ui->dirty);
180 + }
181 +
182 + lock_4_inodes(old_dir, new_dir, new_inode, whiteout);
183
184 /*
185 * Like most other Unix systems, set the @i_ctime for inodes on a
186 @@ -1163,12 +1220,34 @@ static int ubifs_rename(struct inode *ol
187 if (unlink && IS_SYNC(new_inode))
188 sync = 1;
189 }
190 - err = ubifs_jnl_rename(c, old_dir, old_dentry, new_dir, new_dentry,
191 +
192 + if (whiteout) {
193 + struct ubifs_budget_req wht_req = { .dirtied_ino = 1,
194 + .dirtied_ino_d = \
195 + ALIGN(ubifs_inode(whiteout)->data_len, 8) };
196 +
197 + err = ubifs_budget_space(c, &wht_req);
198 + if (err) {
199 + ubifs_release_budget(c, &req);
200 + ubifs_release_budget(c, &ino_req);
201 + kfree(whiteout_ui->data);
202 + whiteout_ui->data_len = 0;
203 + iput(whiteout);
204 + return err;
205 + }
206 +
207 + inc_nlink(whiteout);
208 + mark_inode_dirty(whiteout);
209 + whiteout->i_state &= ~I_LINKABLE;
210 + iput(whiteout);
211 + }
212 +
213 + err = ubifs_jnl_rename(c, old_dir, old_dentry, new_dir, new_dentry, whiteout,
214 sync);
215 if (err)
216 goto out_cancel;
217
218 - unlock_3_inodes(old_dir, new_dir, new_inode);
219 + unlock_4_inodes(old_dir, new_dir, new_inode, whiteout);
220 ubifs_release_budget(c, &req);
221
222 mutex_lock(&old_inode_ui->ui_mutex);
223 @@ -1201,7 +1280,11 @@ out_cancel:
224 inc_nlink(old_dir);
225 }
226 }
227 - unlock_3_inodes(old_dir, new_dir, new_inode);
228 + if (whiteout) {
229 + drop_nlink(whiteout);
230 + iput(whiteout);
231 + }
232 + unlock_4_inodes(old_dir, new_dir, new_inode, whiteout);
233 ubifs_release_budget(c, &ino_req);
234 ubifs_release_budget(c, &req);
235 return err;
236 @@ -1255,7 +1338,7 @@ const struct inode_operations ubifs_dir_
237 .mkdir = ubifs_mkdir,
238 .rmdir = ubifs_rmdir,
239 .mknod = ubifs_mknod,
240 - .rename = ubifs_rename,
241 + .rename2 = ubifs_rename,
242 .setattr = ubifs_setattr,
243 .getattr = ubifs_getattr,
244 .setxattr = ubifs_setxattr,
245 --- a/fs/ubifs/journal.c
246 +++ b/fs/ubifs/journal.c
247 @@ -917,14 +917,15 @@ int ubifs_jnl_delete_inode(struct ubifs_
248 * @sync: non-zero if the write-buffer has to be synchronized
249 *
250 * This function implements the re-name operation which may involve writing up
251 - * to 3 inodes and 2 directory entries. It marks the written inodes as clean
252 + * to 4 inodes and 2 directory entries. It marks the written inodes as clean
253 * and returns zero on success. In case of failure, a negative error code is
254 * returned.
255 */
256 int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
257 const struct dentry *old_dentry,
258 const struct inode *new_dir,
259 - const struct dentry *new_dentry, int sync)
260 + const struct dentry *new_dentry,
261 + const struct inode *whiteout, int sync)
262 {
263 void *p;
264 union ubifs_key key;
265 @@ -980,13 +981,19 @@ int ubifs_jnl_rename(struct ubifs_info *
266 zero_dent_node_unused(dent);
267 ubifs_prep_grp_node(c, dent, dlen1, 0);
268
269 - /* Make deletion dent */
270 dent2 = (void *)dent + aligned_dlen1;
271 dent2->ch.node_type = UBIFS_DENT_NODE;
272 dent_key_init_flash(c, &dent2->key, old_dir->i_ino,
273 &old_dentry->d_name);
274 - dent2->inum = 0;
275 - dent2->type = DT_UNKNOWN;
276 +
277 + if (whiteout) {
278 + dent2->inum = cpu_to_le64(whiteout->i_ino);
279 + dent2->type = get_dent_type(whiteout->i_mode);
280 + } else {
281 + /* Make deletion dent */
282 + dent2->inum = 0;
283 + dent2->type = DT_UNKNOWN;
284 + }
285 dent2->nlen = cpu_to_le16(old_dentry->d_name.len);
286 memcpy(dent2->name, old_dentry->d_name.name, old_dentry->d_name.len);
287 dent2->name[old_dentry->d_name.len] = '\0';
288 @@ -1035,16 +1042,26 @@ int ubifs_jnl_rename(struct ubifs_info *
289 if (err)
290 goto out_ro;
291
292 - err = ubifs_add_dirt(c, lnum, dlen2);
293 - if (err)
294 - goto out_ro;
295 -
296 - dent_key_init(c, &key, old_dir->i_ino, &old_dentry->d_name);
297 - err = ubifs_tnc_remove_nm(c, &key, &old_dentry->d_name);
298 - if (err)
299 - goto out_ro;
300 + offs += aligned_dlen1;
301 + if (whiteout) {
302 + dent_key_init(c, &key, old_dir->i_ino, &old_dentry->d_name);
303 + err = ubifs_tnc_add_nm(c, &key, lnum, offs, dlen2, &old_dentry->d_name);
304 + if (err)
305 + goto out_ro;
306 +
307 + ubifs_delete_orphan(c, whiteout->i_ino);
308 + } else {
309 + err = ubifs_add_dirt(c, lnum, dlen2);
310 + if (err)
311 + goto out_ro;
312 +
313 + dent_key_init(c, &key, old_dir->i_ino, &old_dentry->d_name);
314 + err = ubifs_tnc_remove_nm(c, &key, &old_dentry->d_name);
315 + if (err)
316 + goto out_ro;
317 + }
318
319 - offs += aligned_dlen1 + aligned_dlen2;
320 + offs += aligned_dlen2;
321 if (new_inode) {
322 ino_key_init(c, &key, new_inode->i_ino);
323 err = ubifs_tnc_add(c, &key, lnum, offs, ilen);
324 --- a/fs/ubifs/ubifs.h
325 +++ b/fs/ubifs/ubifs.h
326 @@ -180,6 +180,7 @@ enum {
327 WB_MUTEX_1 = 0,
328 WB_MUTEX_2 = 1,
329 WB_MUTEX_3 = 2,
330 + WB_MUTEX_4 = 3,
331 };
332
333 /*
334 @@ -1546,7 +1547,8 @@ int ubifs_jnl_delete_inode(struct ubifs_
335 int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
336 const struct dentry *old_dentry,
337 const struct inode *new_dir,
338 - const struct dentry *new_dentry, int sync);
339 + const struct dentry *new_dentry,
340 + const struct inode *whiteout, int sync);
341 int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode,
342 loff_t old_size, loff_t new_size);
343 int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host,