Skip to content

Commit 354c179

Browse files
Zhihao Chengrichardweinberger
authored andcommitted
ubifs: Don't add xattr inode into orphan area
Now, the entire inode with its' xattrs are removed while replaying orphan nodes. There is no need to add xattr inodes into orphan area, which is based on the fact that xattr entries won't be cleared from disk before deleting xattr inodes, in another words, current logic can make sure that xattr inode be deleted in any cases even UBIFS not record xattr inode into orphan area. Let's looking for possible paths that could clear xattr entries from disk but leave the xattr inode on TNC: 1. unlink/tmpfile -> ubifs_jnl_update: inode(nlink=0) is written into bud LEB and added into orphan list, then: a. powercut: ubifs_tnc_remove_ino(xattr entry/inode can be found from TNC and being deleted) is invoked in replaying journal. b. commit + powercut: inode is written into orphan area, and ubifs_tnc_remove_ino is invoked in replaying orphan nodes. c. evicting + powercut: xattr inode(nlink=0) is written on disk, xattr is removed from TNC, gc could clear xattr entries from disk. ubifs_tnc_remove_ino will apply on inode and xattr inode in replaying journal, so lost xattr entries will make no influence. d. evicting + commit + powercut: xattr inode/entry are removed from index tree(on disk) by ubifs_jnl_write_inode, xattr inode is cleared from orphan area by ubifs_jnl_write_inode + commit. e. commit + evicting + powercut: inode is written into orphan area, then equivalent to c. 2. remove xattr -> ubifs_jnl_delete_xattr: xattr entry(inum=0) and xattr inode(nlink=0) is written into bud LEB, xattr entry/inode are removed from TNC, then: a. powercut: gc could clear xattr entries from disk, which won't affect deleting xattr entry from TNC. ubifs_tnc_remove_ino will apply on xattr inode in replaying journal, ubifs_tnc_remove_nm will apply on xattr entry in replaying journal. b. commit + powercut: xattr entry/inode are removed from index tree (on disk). Tracking xattr inode in orphan list is imported by commit 988bec4 ("ubifs: orphan: Handle xattrs like files"), it aims to fix the similar problem described in commit 7959cf3 ("ubifs: journal: Handle xattrs like files"). Actually, the problem only exist in journal case but not the orphan case. So, we can remove the orphan tracking for xattr inodes. Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com> Signed-off-by: Richard Weinberger <richard@nod.at>
1 parent 02eb184 commit 354c179

File tree

2 files changed

+14
-74
lines changed

2 files changed

+14
-74
lines changed

fs/ubifs/orphan.c

Lines changed: 14 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -42,24 +42,30 @@
4242

4343
static int dbg_check_orphans(struct ubifs_info *c);
4444

45-
static struct ubifs_orphan *orphan_add(struct ubifs_info *c, ino_t inum,
46-
struct ubifs_orphan *parent_orphan)
45+
/**
46+
* ubifs_add_orphan - add an orphan.
47+
* @c: UBIFS file-system description object
48+
* @inum: orphan inode number
49+
*
50+
* Add an orphan. This function is called when an inodes link count drops to
51+
* zero.
52+
*/
53+
int ubifs_add_orphan(struct ubifs_info *c, ino_t inum)
4754
{
4855
struct ubifs_orphan *orphan, *o;
4956
struct rb_node **p, *parent = NULL;
5057

5158
orphan = kzalloc(sizeof(struct ubifs_orphan), GFP_NOFS);
5259
if (!orphan)
53-
return ERR_PTR(-ENOMEM);
60+
return -ENOMEM;
5461
orphan->inum = inum;
5562
orphan->new = 1;
56-
INIT_LIST_HEAD(&orphan->child_list);
5763

5864
spin_lock(&c->orphan_lock);
5965
if (c->tot_orphans >= c->max_orphans) {
6066
spin_unlock(&c->orphan_lock);
6167
kfree(orphan);
62-
return ERR_PTR(-ENFILE);
68+
return -ENFILE;
6369
}
6470
p = &c->orph_tree.rb_node;
6571
while (*p) {
@@ -73,7 +79,7 @@ static struct ubifs_orphan *orphan_add(struct ubifs_info *c, ino_t inum,
7379
ubifs_err(c, "orphaned twice");
7480
spin_unlock(&c->orphan_lock);
7581
kfree(orphan);
76-
return ERR_PTR(-EINVAL);
82+
return -EINVAL;
7783
}
7884
}
7985
c->tot_orphans += 1;
@@ -83,14 +89,9 @@ static struct ubifs_orphan *orphan_add(struct ubifs_info *c, ino_t inum,
8389
list_add_tail(&orphan->list, &c->orph_list);
8490
list_add_tail(&orphan->new_list, &c->orph_new);
8591

86-
if (parent_orphan) {
87-
list_add_tail(&orphan->child_list,
88-
&parent_orphan->child_list);
89-
}
90-
9192
spin_unlock(&c->orphan_lock);
9293
dbg_gen("ino %lu", (unsigned long)inum);
93-
return orphan;
94+
return 0;
9495
}
9596

9697
static struct ubifs_orphan *lookup_orphan(struct ubifs_info *c, ino_t inum)
@@ -144,59 +145,6 @@ static void orphan_delete(struct ubifs_info *c, struct ubifs_orphan *orph)
144145
__orphan_drop(c, orph);
145146
}
146147

147-
/**
148-
* ubifs_add_orphan - add an orphan.
149-
* @c: UBIFS file-system description object
150-
* @inum: orphan inode number
151-
*
152-
* Add an orphan. This function is called when an inodes link count drops to
153-
* zero.
154-
*/
155-
int ubifs_add_orphan(struct ubifs_info *c, ino_t inum)
156-
{
157-
int err = 0;
158-
ino_t xattr_inum;
159-
union ubifs_key key;
160-
struct ubifs_dent_node *xent, *pxent = NULL;
161-
struct fscrypt_name nm = {0};
162-
struct ubifs_orphan *xattr_orphan;
163-
struct ubifs_orphan *orphan;
164-
165-
orphan = orphan_add(c, inum, NULL);
166-
if (IS_ERR(orphan))
167-
return PTR_ERR(orphan);
168-
169-
lowest_xent_key(c, &key, inum);
170-
while (1) {
171-
xent = ubifs_tnc_next_ent(c, &key, &nm);
172-
if (IS_ERR(xent)) {
173-
err = PTR_ERR(xent);
174-
if (err == -ENOENT)
175-
break;
176-
kfree(pxent);
177-
return err;
178-
}
179-
180-
fname_name(&nm) = xent->name;
181-
fname_len(&nm) = le16_to_cpu(xent->nlen);
182-
xattr_inum = le64_to_cpu(xent->inum);
183-
184-
xattr_orphan = orphan_add(c, xattr_inum, orphan);
185-
if (IS_ERR(xattr_orphan)) {
186-
kfree(pxent);
187-
kfree(xent);
188-
return PTR_ERR(xattr_orphan);
189-
}
190-
191-
kfree(pxent);
192-
pxent = xent;
193-
key_read(c, &xent->key, &key);
194-
}
195-
kfree(pxent);
196-
197-
return 0;
198-
}
199-
200148
/**
201149
* ubifs_delete_orphan - delete an orphan.
202150
* @c: UBIFS file-system description object
@@ -206,7 +154,7 @@ int ubifs_add_orphan(struct ubifs_info *c, ino_t inum)
206154
*/
207155
void ubifs_delete_orphan(struct ubifs_info *c, ino_t inum)
208156
{
209-
struct ubifs_orphan *orph, *child_orph, *tmp_o;
157+
struct ubifs_orphan *orph;
210158

211159
spin_lock(&c->orphan_lock);
212160

@@ -219,11 +167,6 @@ void ubifs_delete_orphan(struct ubifs_info *c, ino_t inum)
219167
return;
220168
}
221169

222-
list_for_each_entry_safe(child_orph, tmp_o, &orph->child_list, child_list) {
223-
list_del(&child_orph->child_list);
224-
orphan_delete(c, child_orph);
225-
}
226-
227170
orphan_delete(c, orph);
228171

229172
spin_unlock(&c->orphan_lock);

fs/ubifs/ubifs.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -923,8 +923,6 @@ struct ubifs_budget_req {
923923
* @rb: rb-tree node of rb-tree of orphans sorted by inode number
924924
* @list: list head of list of orphans in order added
925925
* @new_list: list head of list of orphans added since the last commit
926-
* @child_list: list of xattr children if this orphan hosts xattrs, list head
927-
* if this orphan is a xattr, not used otherwise.
928926
* @cnext: next orphan to commit
929927
* @dnext: next orphan to delete
930928
* @inum: inode number
@@ -936,7 +934,6 @@ struct ubifs_orphan {
936934
struct rb_node rb;
937935
struct list_head list;
938936
struct list_head new_list;
939-
struct list_head child_list;
940937
struct ubifs_orphan *cnext;
941938
struct ubifs_orphan *dnext;
942939
ino_t inum;

0 commit comments

Comments
 (0)