aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-04-19 15:36:27 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-04-19 15:36:27 -0400
commit7e38180e207c8707691c12395e990a5d583c5e71 (patch)
tree50fc0973873f7bc9455a1faf536a5a5b4681fe56
parent236454dfffb64a95ee01c50a215153f5de61c475 (diff)
Btrfs: directory inode index is back
Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/TODO4
-rw-r--r--fs/btrfs/ctree.h58
-rw-r--r--fs/btrfs/dir-item.c204
-rw-r--r--fs/btrfs/super.c302
4 files changed, 206 insertions, 362 deletions
diff --git a/fs/btrfs/TODO b/fs/btrfs/TODO
index 1c3acfcf146e..8d7e5a3ed629 100644
--- a/fs/btrfs/TODO
+++ b/fs/btrfs/TODO
@@ -1,12 +1,12 @@
1* cleanup, add more error checking, get rid of BUG_ONs 1* cleanup, add more error checking, get rid of BUG_ONs
2* Fix ENOSPC handling 2* Fix ENOSPC handling
3* Add block mapping tree (simple dm layer)
4* Make allocator smarter 3* Make allocator smarter
5* add a block group to struct inode 4* add a block group to struct inode
6* Make sure nobh stuff is working properly for cows
7* Do actual block accounting 5* Do actual block accounting
8* Check compat and incompat flags on the inode 6* Check compat and incompat flags on the inode
9* Get rid of struct ctree_path, limiting tree levels held at one time 7* Get rid of struct ctree_path, limiting tree levels held at one time
8* Add generation number to key pointer in nodes
9* Add parent pointer back to extent map.
10* Release 10* Release
11* Do real tree locking 11* Do real tree locking
12* Add extent mirroring (backup copies of blocks) 12* Add extent mirroring (backup copies of blocks)
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index f1800008be34..d628a3b9441c 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -185,11 +185,6 @@ struct btrfs_inode_item {
185 struct btrfs_inode_timespec otime; 185 struct btrfs_inode_timespec otime;
186} __attribute__ ((__packed__)); 186} __attribute__ ((__packed__));
187 187
188/* inline data is just a blob of bytes */
189struct btrfs_inline_data_item {
190 u8 data;
191} __attribute__ ((__packed__));
192
193struct btrfs_dir_item { 188struct btrfs_dir_item {
194 struct btrfs_disk_key location; 189 struct btrfs_disk_key location;
195 __le16 flags; 190 __le16 flags;
@@ -293,9 +288,6 @@ struct btrfs_root {
293#define BTRFS_KEY_TYPE_MASK (((u32)BTRFS_KEY_TYPE_MAX - 1) << \ 288#define BTRFS_KEY_TYPE_MASK (((u32)BTRFS_KEY_TYPE_MAX - 1) << \
294 BTRFS_KEY_TYPE_SHIFT) 289 BTRFS_KEY_TYPE_SHIFT)
295 290
296#define BTRFS_KEY_OVERFLOW_MAX 128
297#define BTRFS_KEY_OVERFLOW_MASK ((u32)BTRFS_KEY_OVERFLOW_MAX - 1)
298
299/* 291/*
300 * inode items have the data typically returned from stat and store other 292 * inode items have the data typically returned from stat and store other
301 * info about object characteristics. There is one for every file and dir in 293 * info about object characteristics. There is one for every file and dir in
@@ -621,31 +613,6 @@ static inline void btrfs_set_key_type(struct btrfs_key *key, u32 val)
621 key->flags = (key->flags & ~(BTRFS_KEY_TYPE_MASK)) | val; 613 key->flags = (key->flags & ~(BTRFS_KEY_TYPE_MASK)) | val;
622} 614}
623 615
624static inline u32 btrfs_key_overflow(struct btrfs_key *key)
625{
626 return key->flags & BTRFS_KEY_OVERFLOW_MASK;
627}
628
629static inline void btrfs_set_key_overflow(struct btrfs_key *key, u32 over)
630{
631 BUG_ON(over >= BTRFS_KEY_OVERFLOW_MAX);
632 key->flags = (key->flags & ~BTRFS_KEY_OVERFLOW_MASK) | over;
633}
634
635static inline u32 btrfs_disk_key_overflow(struct btrfs_disk_key *key)
636{
637 return le32_to_cpu(key->flags) & BTRFS_KEY_OVERFLOW_MASK;
638}
639
640static inline void btrfs_set_disk_key_overflow(struct btrfs_disk_key *key,
641 u32 over)
642{
643 u32 flags = btrfs_disk_key_flags(key);
644 BUG_ON(over >= BTRFS_KEY_OVERFLOW_MAX);
645 flags = (flags & ~BTRFS_KEY_OVERFLOW_MASK) | over;
646 btrfs_set_disk_key_flags(key, flags);
647}
648
649static inline u64 btrfs_header_blocknr(struct btrfs_header *h) 616static inline u64 btrfs_header_blocknr(struct btrfs_header *h)
650{ 617{
651 return le64_to_cpu(h->blocknr); 618 return le64_to_cpu(h->blocknr);
@@ -1079,15 +1046,24 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, struct
1079int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root 1046int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
1080 *root, const char *name, int name_len, u64 dir, 1047 *root, const char *name, int name_len, u64 dir,
1081 struct btrfs_key *location, u8 type); 1048 struct btrfs_key *location, u8 type);
1082int btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root 1049struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans,
1083 *root, struct btrfs_path *path, u64 dir, 1050 struct btrfs_root *root,
1084 const char *name, int name_len, int mod); 1051 struct btrfs_path *path, u64 dir,
1085int btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans, 1052 const char *name, int name_len,
1086 struct btrfs_root *root, 1053 int mod);
1087 struct btrfs_path *path, u64 dir, 1054struct btrfs_dir_item *
1088 u64 objectid, int mod); 1055btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans,
1089int btrfs_match_dir_item_name(struct btrfs_root *root, struct btrfs_path *path, 1056 struct btrfs_root *root,
1057 struct btrfs_path *path, u64 dir,
1058 u64 objectid, const char *name, int name_len,
1059 int mod);
1060struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root,
1061 struct btrfs_path *path,
1090 const char *name, int name_len); 1062 const char *name, int name_len);
1063int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans,
1064 struct btrfs_root *root,
1065 struct btrfs_path *path,
1066 struct btrfs_dir_item *di);
1091/* inode-map.c */ 1067/* inode-map.c */
1092int btrfs_find_free_objectid(struct btrfs_trans_handle *trans, 1068int btrfs_find_free_objectid(struct btrfs_trans_handle *trans,
1093 struct btrfs_root *fs_root, 1069 struct btrfs_root *fs_root,
diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c
index a43deb726486..7a7e9846860a 100644
--- a/fs/btrfs/dir-item.c
+++ b/fs/btrfs/dir-item.c
@@ -4,24 +4,31 @@
4#include "hash.h" 4#include "hash.h"
5#include "transaction.h" 5#include "transaction.h"
6 6
7int insert_with_overflow(struct btrfs_trans_handle *trans, struct btrfs_root 7struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle *trans,
8 *root, struct btrfs_path *path, struct btrfs_key 8 struct btrfs_root *root,
9 *cpu_key, u32 data_size) 9 struct btrfs_path *path,
10 struct btrfs_key *cpu_key,
11 u32 data_size)
10{ 12{
11 int overflow;
12 int ret; 13 int ret;
14 char *ptr;
15 struct btrfs_item *item;
16 struct btrfs_leaf *leaf;
13 17
14 ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size); 18 ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size);
15 overflow = btrfs_key_overflow(cpu_key); 19 if (ret == -EEXIST) {
16 20 ret = btrfs_extend_item(trans, root, path, data_size);
17 while(ret == -EEXIST && overflow < BTRFS_KEY_OVERFLOW_MAX) { 21 WARN_ON(ret > 0);
18 overflow++; 22 if (ret)
19 btrfs_set_key_overflow(cpu_key, overflow); 23 return ERR_PTR(ret);
20 btrfs_release_path(root, path);
21 ret = btrfs_insert_empty_item(trans, root, path, cpu_key,
22 data_size);
23 } 24 }
24 return ret; 25 WARN_ON(ret > 0);
26 leaf = btrfs_buffer_leaf(path->nodes[0]);
27 item = leaf->items + path->slots[0];
28 ptr = btrfs_item_ptr(leaf, path->slots[0], char);
29 BUG_ON(data_size > btrfs_item_size(item));
30 ptr += btrfs_item_size(item) - data_size;
31 return (struct btrfs_dir_item *)ptr;
25} 32}
26 33
27int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root 34int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
@@ -43,13 +50,12 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
43 path = btrfs_alloc_path(); 50 path = btrfs_alloc_path();
44 btrfs_init_path(path); 51 btrfs_init_path(path);
45 data_size = sizeof(*dir_item) + name_len; 52 data_size = sizeof(*dir_item) + name_len;
46 ret = insert_with_overflow(trans, root, path, &key, data_size); 53 dir_item = insert_with_overflow(trans, root, path, &key, data_size);
47 if (ret) 54 if (IS_ERR(dir_item)) {
55 ret = PTR_ERR(dir_item);
48 goto out; 56 goto out;
57 }
49 58
50 dir_item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]),
51 path->slots[0],
52 struct btrfs_dir_item);
53 btrfs_cpu_key_to_disk(&dir_item->location, location); 59 btrfs_cpu_key_to_disk(&dir_item->location, location);
54 btrfs_set_dir_type(dir_item, type); 60 btrfs_set_dir_type(dir_item, type);
55 btrfs_set_dir_flags(dir_item, 0); 61 btrfs_set_dir_flags(dir_item, 0);
@@ -58,15 +64,39 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
58 64
59 btrfs_memcpy(root, path->nodes[0]->b_data, name_ptr, name, name_len); 65 btrfs_memcpy(root, path->nodes[0]->b_data, name_ptr, name, name_len);
60 btrfs_mark_buffer_dirty(path->nodes[0]); 66 btrfs_mark_buffer_dirty(path->nodes[0]);
61out: 67
68 /* FIXME, use some real flag for selecting the extra index */
69 if (root == root->fs_info->tree_root) {
70 ret = 0;
71 goto out;
72 }
73
62 btrfs_release_path(root, path); 74 btrfs_release_path(root, path);
75
76 btrfs_set_key_type(&key, BTRFS_DIR_INDEX_KEY);
77 key.offset = location->objectid;
78 dir_item = insert_with_overflow(trans, root, path, &key, data_size);
79 if (IS_ERR(dir_item)) {
80 ret = PTR_ERR(dir_item);
81 goto out;
82 }
83 btrfs_cpu_key_to_disk(&dir_item->location, location);
84 btrfs_set_dir_type(dir_item, type);
85 btrfs_set_dir_flags(dir_item, 0);
86 btrfs_set_dir_name_len(dir_item, name_len);
87 name_ptr = (char *)(dir_item + 1);
88 btrfs_memcpy(root, path->nodes[0]->b_data, name_ptr, name, name_len);
89 btrfs_mark_buffer_dirty(path->nodes[0]);
90out:
63 btrfs_free_path(path); 91 btrfs_free_path(path);
64 return ret; 92 return ret;
65} 93}
66 94
67int btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root 95struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans,
68 *root, struct btrfs_path *path, u64 dir, 96 struct btrfs_root *root,
69 const char *name, int name_len, int mod) 97 struct btrfs_path *path, u64 dir,
98 const char *name, int name_len,
99 int mod)
70{ 100{
71 int ret; 101 int ret;
72 struct btrfs_key key; 102 struct btrfs_key key;
@@ -74,57 +104,111 @@ int btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
74 int cow = mod != 0; 104 int cow = mod != 0;
75 struct btrfs_disk_key *found_key; 105 struct btrfs_disk_key *found_key;
76 struct btrfs_leaf *leaf; 106 struct btrfs_leaf *leaf;
77 u32 overflow;
78 107
79 key.objectid = dir; 108 key.objectid = dir;
80 key.flags = 0; 109 key.flags = 0;
81 btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); 110 btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
82 // btrfs_set_key_overflow(&key, BTRFS_KEY_OVERFLOW_MAX - 1);
83 ret = btrfs_name_hash(name, name_len, &key.offset); 111 ret = btrfs_name_hash(name, name_len, &key.offset);
84 BUG_ON(ret); 112 BUG_ON(ret);
85 while(1) { 113 ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
86 ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow); 114 if (ret < 0)
87 if (ret < 0) 115 return ERR_PTR(ret);
88 return ret; 116 if (ret > 0) {
89 if (ret > 0) { 117 if (path->slots[0] == 0)
90 if (path->slots[0] == 0) 118 return NULL;
91 return 1; 119 path->slots[0]--;
92 path->slots[0]--;
93 }
94 leaf = btrfs_buffer_leaf(path->nodes[0]);
95 found_key = &leaf->items[path->slots[0]].key;
96
97 if (btrfs_disk_key_objectid(found_key) != dir ||
98 btrfs_disk_key_type(found_key) != BTRFS_DIR_ITEM_KEY ||
99 btrfs_disk_key_offset(found_key) != key.offset)
100 return 1;
101
102 if (btrfs_match_dir_item_name(root, path, name, name_len))
103 return 0;
104
105 overflow = btrfs_disk_key_overflow(found_key);
106 if (overflow == 0)
107 return 1;
108 btrfs_set_key_overflow(&key, overflow - 1);
109 btrfs_release_path(root, path);
110 } 120 }
111 return 1; 121 leaf = btrfs_buffer_leaf(path->nodes[0]);
122 found_key = &leaf->items[path->slots[0]].key;
123
124 if (btrfs_disk_key_objectid(found_key) != dir ||
125 btrfs_disk_key_type(found_key) != BTRFS_DIR_ITEM_KEY ||
126 btrfs_disk_key_offset(found_key) != key.offset)
127 return NULL;
128
129 return btrfs_match_dir_item_name(root, path, name, name_len);
112} 130}
113 131
114int btrfs_match_dir_item_name(struct btrfs_root *root, 132struct btrfs_dir_item *
133btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans,
134 struct btrfs_root *root,
135 struct btrfs_path *path, u64 dir,
136 u64 objectid, const char *name, int name_len,
137 int mod)
138{
139 int ret;
140 struct btrfs_key key;
141 int ins_len = mod < 0 ? -1 : 0;
142 int cow = mod != 0;
143
144 key.objectid = dir;
145 key.flags = 0;
146 btrfs_set_key_type(&key, BTRFS_DIR_INDEX_KEY);
147 key.offset = objectid;
148
149 ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
150 if (ret < 0)
151 return ERR_PTR(ret);
152 if (ret > 0)
153 return ERR_PTR(-ENOENT);
154 return btrfs_match_dir_item_name(root, path, name, name_len);
155}
156
157struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root,
115 struct btrfs_path *path, 158 struct btrfs_path *path,
116 const char *name, int name_len) 159 const char *name, int name_len)
117{ 160{
118 struct btrfs_dir_item *dir_item; 161 struct btrfs_dir_item *dir_item;
119 char *name_ptr; 162 char *name_ptr;
163 u32 total_len;
164 u32 cur = 0;
165 u32 this_len;
166 struct btrfs_leaf *leaf;
120 167
121 dir_item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), 168 leaf = btrfs_buffer_leaf(path->nodes[0]);
122 path->slots[0], 169 dir_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item);
123 struct btrfs_dir_item); 170 total_len = btrfs_item_size(leaf->items + path->slots[0]);
124 if (btrfs_dir_name_len(dir_item) != name_len) 171 while(cur < total_len) {
125 return 0; 172 this_len = sizeof(*dir_item) + btrfs_dir_name_len(dir_item);
126 name_ptr = (char *)(dir_item + 1); 173 name_ptr = (char *)(dir_item + 1);
127 if (memcmp(name_ptr, name, name_len)) 174
128 return 0; 175 if (btrfs_dir_name_len(dir_item) == name_len &&
129 return 1; 176 memcmp(name_ptr, name, name_len) == 0)
177 return dir_item;
178
179 cur += this_len;
180 dir_item = (struct btrfs_dir_item *)((char *)dir_item +
181 this_len);
182 }
183 return NULL;
130} 184}
185
186int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans,
187 struct btrfs_root *root,
188 struct btrfs_path *path,
189 struct btrfs_dir_item *di)
190{
191
192 struct btrfs_leaf *leaf;
193 u32 sub_item_len;
194 u32 item_len;
195 int ret;
196
197 leaf = btrfs_buffer_leaf(path->nodes[0]);
198 sub_item_len = sizeof(*di) + btrfs_dir_name_len(di);
199 item_len = btrfs_item_size(leaf->items + path->slots[0]);
200 if (sub_item_len == btrfs_item_size(leaf->items + path->slots[0])) {
201 ret = btrfs_del_item(trans, root, path);
202 BUG_ON(ret);
203 } else {
204 char *ptr = (char *)di;
205 char *start = btrfs_item_ptr(leaf, path->slots[0], char);
206 btrfs_memmove(root, leaf, ptr, ptr + sub_item_len,
207 item_len - (ptr + sub_item_len - start));
208 ret = btrfs_truncate_item(trans, root, path,
209 item_len - sub_item_len);
210 BUG_ON(ret);
211 }
212 return 0;
213}
214
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 1b286bb26f12..dff2db0d1dc2 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -127,32 +127,43 @@ static int btrfs_unlink_trans(struct btrfs_trans_handle *trans,
127 struct btrfs_path *path; 127 struct btrfs_path *path;
128 const char *name = dentry->d_name.name; 128 const char *name = dentry->d_name.name;
129 int name_len = dentry->d_name.len; 129 int name_len = dentry->d_name.len;
130 int ret; 130 int ret = 0;
131 u64 objectid; 131 u64 objectid;
132 struct btrfs_dir_item *di; 132 struct btrfs_dir_item *di;
133 133
134 path = btrfs_alloc_path(); 134 path = btrfs_alloc_path();
135 BUG_ON(!path); 135 BUG_ON(!path);
136 btrfs_init_path(path); 136 btrfs_init_path(path);
137 ret = btrfs_lookup_dir_item(trans, root, path, dir->i_ino, 137 di = btrfs_lookup_dir_item(trans, root, path, dir->i_ino,
138 name, name_len, -1); 138 name, name_len, -1);
139 if (ret < 0) 139 if (IS_ERR(di)) {
140 ret = PTR_ERR(di);
140 goto err; 141 goto err;
141 if (ret > 0) { 142 }
143 if (!di) {
142 ret = -ENOENT; 144 ret = -ENOENT;
143 goto err; 145 goto err;
144 } 146 }
145 di = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0],
146 struct btrfs_dir_item);
147 objectid = btrfs_disk_key_objectid(&di->location); 147 objectid = btrfs_disk_key_objectid(&di->location);
148 ret = btrfs_delete_one_dir_name(trans, root, path, di);
149 BUG_ON(ret);
150 btrfs_release_path(root, path);
148 151
149 ret = btrfs_del_item(trans, root, path); 152 di = btrfs_lookup_dir_index_item(trans, root, path, dir->i_ino,
153 objectid, name, name_len, -1);
154 if (IS_ERR(di)) {
155 ret = PTR_ERR(di);
156 goto err;
157 }
158 if (!di) {
159 ret = -ENOENT;
160 goto err;
161 }
162 ret = btrfs_delete_one_dir_name(trans, root, path, di);
150 BUG_ON(ret); 163 BUG_ON(ret);
151 164
152 btrfs_release_path(root, path);
153 dentry->d_inode->i_ctime = dir->i_ctime; 165 dentry->d_inode->i_ctime = dir->i_ctime;
154err: 166err:
155 btrfs_release_path(root, path);
156 btrfs_free_path(path); 167 btrfs_free_path(path);
157 if (ret == 0) { 168 if (ret == 0) {
158 inode_dec_link_count(dentry->d_inode); 169 inode_dec_link_count(dentry->d_inode);
@@ -388,15 +399,13 @@ static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry,
388 path = btrfs_alloc_path(); 399 path = btrfs_alloc_path();
389 BUG_ON(!path); 400 BUG_ON(!path);
390 btrfs_init_path(path); 401 btrfs_init_path(path);
391 ret = btrfs_lookup_dir_item(NULL, root, path, dir->i_ino, name, 402 di = btrfs_lookup_dir_item(NULL, root, path, dir->i_ino, name,
392 namelen, 0); 403 namelen, 0);
393 if (ret || !btrfs_match_dir_item_name(root, path, name, namelen)) { 404 if (!di || IS_ERR(di)) {
394 location->objectid = 0; 405 location->objectid = 0;
395 ret = 0; 406 ret = 0;
396 goto out; 407 goto out;
397 } 408 }
398 di = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0],
399 struct btrfs_dir_item);
400 btrfs_disk_key_to_cpu(location, &di->location); 409 btrfs_disk_key_to_cpu(location, &di->location);
401out: 410out:
402 btrfs_release_path(root, path); 411 btrfs_release_path(root, path);
@@ -523,7 +532,10 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
523 int advance; 532 int advance;
524 unsigned char d_type = DT_UNKNOWN; 533 unsigned char d_type = DT_UNKNOWN;
525 int over = 0; 534 int over = 0;
526 int key_type = BTRFS_DIR_ITEM_KEY; 535 u32 di_cur;
536 u32 di_total;
537 u32 di_len;
538 int key_type = BTRFS_DIR_INDEX_KEY;
527 539
528 /* FIXME, use a real flag for deciding about the key type */ 540 /* FIXME, use a real flag for deciding about the key type */
529 if (root->fs_info->tree_root == root) 541 if (root->fs_info->tree_root == root)
@@ -567,12 +579,20 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
567 filp->f_pos = btrfs_disk_key_offset(&item->key); 579 filp->f_pos = btrfs_disk_key_offset(&item->key);
568 advance = 1; 580 advance = 1;
569 di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item); 581 di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
570 over = filldir(dirent, (const char *)(di + 1), 582 di_cur = 0;
571 btrfs_dir_name_len(di), 583 di_total = btrfs_item_size(leaf->items + slot);
572 btrfs_disk_key_offset(&item->key), 584 while(di_cur < di_total) {
573 btrfs_disk_key_objectid(&di->location), d_type); 585 over = filldir(dirent, (const char *)(di + 1),
574 if (over) 586 btrfs_dir_name_len(di),
575 goto nopos; 587 btrfs_disk_key_offset(&item->key),
588 btrfs_disk_key_objectid(&di->location),
589 d_type);
590 if (over)
591 goto nopos;
592 di_len = btrfs_dir_name_len(di) + sizeof(*di);
593 di_cur += di_len;
594 di = (struct btrfs_dir_item *)((char *)di + di_len);
595 }
576 } 596 }
577 filp->f_pos++; 597 filp->f_pos++;
578nopos: 598nopos:
@@ -935,75 +955,6 @@ printk("btrfs sync_fs\n");
935 return 0; 955 return 0;
936} 956}
937 957
938#if 0
939static int btrfs_get_block_inline(struct inode *inode, sector_t iblock,
940 struct buffer_head *result, int create)
941{
942 struct btrfs_root *root = btrfs_sb(inode->i_sb);
943 struct btrfs_path *path;
944 struct btrfs_key key;
945 struct btrfs_leaf *leaf;
946 int num_bytes = result->b_size;
947 int item_size;
948 int ret;
949 u64 pos;
950 char *ptr;
951 int copy_size;
952 int err = 0;
953 char *safe_ptr;
954 char *data_ptr;
955
956 path = btrfs_alloc_path();
957 BUG_ON(!path);
958
959 WARN_ON(create);
960 if (create) {
961 return 0;
962 }
963 pos = iblock << inode->i_blkbits;
964 key.objectid = inode->i_ino;
965 key.flags = 0;
966 btrfs_set_key_type(&key, BTRFS_INLINE_DATA_KEY);
967 ptr = kmap(result->b_page);
968 safe_ptr = ptr;
969 ptr += (pos & (PAGE_CACHE_SIZE -1));
970again:
971 key.offset = pos;
972 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
973 if (ret) {
974 if (ret < 0)
975 err = ret;
976 else
977 err = 0;
978 goto out;
979 }
980 leaf = btrfs_buffer_leaf(path->nodes[0]);
981 item_size = btrfs_item_size(leaf->items + path->slots[0]);
982 copy_size = min(num_bytes, item_size);
983 data_ptr = btrfs_item_ptr(leaf, path->slots[0], char);
984 WARN_ON(safe_ptr + PAGE_CACHE_SIZE < ptr + copy_size);
985 memcpy(ptr, data_ptr, copy_size);
986 pos += copy_size;
987 num_bytes -= copy_size;
988 WARN_ON(num_bytes < 0);
989 ptr += copy_size;
990 btrfs_release_path(root, path);
991 if (num_bytes != 0) {
992 if (pos >= i_size_read(inode))
993 memset(ptr, 0, num_bytes);
994 else
995 goto again;
996 }
997 set_buffer_uptodate(result);
998 map_bh(result, inode->i_sb, 0);
999 err = 0;
1000out:
1001 btrfs_free_path(path);
1002 kunmap(result->b_page);
1003 return err;
1004}
1005#endif
1006
1007static int btrfs_get_block_lock(struct inode *inode, sector_t iblock, 958static int btrfs_get_block_lock(struct inode *inode, sector_t iblock,
1008 struct buffer_head *result, int create) 959 struct buffer_head *result, int create)
1009{ 960{
@@ -1907,174 +1858,6 @@ out:
1907 return num_written ? num_written : err; 1858 return num_written ? num_written : err;
1908} 1859}
1909 1860
1910#if 0
1911static ssize_t inline_one_page(struct btrfs_root *root, struct inode *inode,
1912 struct page *page, loff_t pos,
1913 size_t offset, size_t write_bytes)
1914{
1915 struct btrfs_path *path;
1916 struct btrfs_trans_handle *trans;
1917 struct btrfs_key key;
1918 struct btrfs_leaf *leaf;
1919 struct btrfs_key found_key;
1920 int ret;
1921 size_t copy_size = 0;
1922 char *dst = NULL;
1923 int err = 0;
1924 size_t num_written = 0;
1925
1926 path = btrfs_alloc_path();
1927 BUG_ON(!path);
1928 mutex_lock(&root->fs_info->fs_mutex);
1929 trans = btrfs_start_transaction(root, 1);
1930 key.objectid = inode->i_ino;
1931 key.flags = 0;
1932 btrfs_set_key_type(&key, BTRFS_INLINE_DATA_KEY);
1933
1934again:
1935 key.offset = pos;
1936 ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
1937 if (ret < 0) {
1938 err = ret;
1939 goto out;
1940 }
1941 if (ret == 0) {
1942 leaf = btrfs_buffer_leaf(path->nodes[0]);
1943 btrfs_disk_key_to_cpu(&found_key,
1944 &leaf->items[path->slots[0]].key);
1945 copy_size = btrfs_item_size(leaf->items + path->slots[0]);
1946 dst = btrfs_item_ptr(leaf, path->slots[0], char);
1947 copy_size = min(write_bytes, copy_size);
1948 goto copyit;
1949 } else {
1950 int slot = path->slots[0];
1951 if (slot > 0) {
1952 slot--;
1953 }
1954 // FIXME find max key
1955 leaf = btrfs_buffer_leaf(path->nodes[0]);
1956 btrfs_disk_key_to_cpu(&found_key,
1957 &leaf->items[slot].key);
1958 if (found_key.objectid != inode->i_ino)
1959 goto insert;
1960 if (btrfs_key_type(&found_key) != BTRFS_INLINE_DATA_KEY)
1961 goto insert;
1962 copy_size = btrfs_item_size(leaf->items + slot);
1963 if (found_key.offset + copy_size <= pos)
1964 goto insert;
1965 dst = btrfs_item_ptr(leaf, path->slots[0], char);
1966 dst += pos - found_key.offset;
1967 copy_size = copy_size - (pos - found_key.offset);
1968 BUG_ON(copy_size < 0);
1969 copy_size = min(write_bytes, copy_size);
1970 WARN_ON(copy_size == 0);
1971 goto copyit;
1972 }
1973insert:
1974 btrfs_release_path(root, path);
1975 copy_size = min(write_bytes,
1976 (size_t)BTRFS_LEAF_DATA_SIZE(root) -
1977 sizeof(struct btrfs_item) * 4);
1978 ret = btrfs_insert_empty_item(trans, root, path, &key, copy_size);
1979 BUG_ON(ret);
1980 dst = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]),
1981 path->slots[0], char);
1982copyit:
1983 WARN_ON(copy_size == 0);
1984 WARN_ON(dst + copy_size >
1985 btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]),
1986 path->slots[0], char) +
1987 btrfs_item_size(btrfs_buffer_leaf(path->nodes[0])->items +
1988 path->slots[0]));
1989 btrfs_memcpy(root, path->nodes[0]->b_data, dst,
1990 page_address(page) + offset, copy_size);
1991 mark_buffer_dirty(path->nodes[0]);
1992 btrfs_release_path(root, path);
1993 pos += copy_size;
1994 offset += copy_size;
1995 num_written += copy_size;
1996 write_bytes -= copy_size;
1997 if (write_bytes)
1998 goto again;
1999out:
2000 btrfs_free_path(path);
2001 ret = btrfs_end_transaction(trans, root);
2002 BUG_ON(ret);
2003 mutex_unlock(&root->fs_info->fs_mutex);
2004 return num_written ? num_written : err;
2005}
2006
2007static ssize_t btrfs_file_inline_write(struct file *file,
2008 const char __user *buf,
2009 size_t count, loff_t *ppos)
2010{
2011 loff_t pos;
2012 size_t num_written = 0;
2013 int err = 0;
2014 int ret = 0;
2015 struct inode *inode = file->f_path.dentry->d_inode;
2016 struct btrfs_root *root = BTRFS_I(inode)->root;
2017 unsigned long page_index;
2018
2019 if (file->f_flags & O_DIRECT)
2020 return -EINVAL;
2021 pos = *ppos;
2022
2023 vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
2024 current->backing_dev_info = inode->i_mapping->backing_dev_info;
2025 err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode));
2026 if (err)
2027 goto out;
2028 if (count == 0)
2029 goto out;
2030 err = remove_suid(file->f_path.dentry);
2031 if (err)
2032 goto out;
2033 file_update_time(file);
2034 mutex_lock(&inode->i_mutex);
2035 while(count > 0) {
2036 size_t offset = pos & (PAGE_CACHE_SIZE - 1);
2037 size_t write_bytes = min(count, PAGE_CACHE_SIZE - offset);
2038 struct page *page;
2039
2040 page_index = pos >> PAGE_CACHE_SHIFT;
2041 page = grab_cache_page(inode->i_mapping, page_index);
2042 if (!PageUptodate(page)) {
2043 ret = mpage_readpage(page, btrfs_get_block);
2044 BUG_ON(ret);
2045 lock_page(page);
2046 }
2047 ret = btrfs_copy_from_user(pos, 1,
2048 write_bytes, &page, buf);
2049 BUG_ON(ret);
2050 write_bytes = inline_one_page(root, inode, page, pos,
2051 offset, write_bytes);
2052 SetPageUptodate(page);
2053 if (write_bytes > 0 && pos + write_bytes > inode->i_size) {
2054 i_size_write(inode, pos + write_bytes);
2055 mark_inode_dirty(inode);
2056 }
2057 page_cache_release(page);
2058 unlock_page(page);
2059 if (write_bytes < 0)
2060 goto out_unlock;
2061 buf += write_bytes;
2062 count -= write_bytes;
2063 pos += write_bytes;
2064 num_written += write_bytes;
2065
2066 balance_dirty_pages_ratelimited(inode->i_mapping);
2067 cond_resched();
2068 }
2069out_unlock:
2070 mutex_unlock(&inode->i_mutex);
2071out:
2072 *ppos = pos;
2073 current->backing_dev_info = NULL;
2074 return num_written ? num_written : err;
2075}
2076#endif
2077
2078static int btrfs_read_actor(read_descriptor_t *desc, struct page *page, 1861static int btrfs_read_actor(read_descriptor_t *desc, struct page *page,
2079 unsigned long offset, unsigned long size) 1862 unsigned long offset, unsigned long size)
2080{ 1863{
@@ -2422,6 +2205,7 @@ static int btrfs_ioctl(struct inode *inode, struct file *filp, unsigned int
2422 struct btrfs_root *root = BTRFS_I(inode)->root; 2205 struct btrfs_root *root = BTRFS_I(inode)->root;
2423 struct btrfs_ioctl_vol_args vol_args; 2206 struct btrfs_ioctl_vol_args vol_args;
2424 int ret = 0; 2207 int ret = 0;
2208 struct btrfs_dir_item *di;
2425 int namelen; 2209 int namelen;
2426 struct btrfs_path *path; 2210 struct btrfs_path *path;
2427 u64 root_dirid; 2211 u64 root_dirid;
@@ -2440,12 +2224,12 @@ static int btrfs_ioctl(struct inode *inode, struct file *filp, unsigned int
2440 return -ENOMEM; 2224 return -ENOMEM;
2441 root_dirid = root->fs_info->sb->s_root->d_inode->i_ino, 2225 root_dirid = root->fs_info->sb->s_root->d_inode->i_ino,
2442 mutex_lock(&root->fs_info->fs_mutex); 2226 mutex_lock(&root->fs_info->fs_mutex);
2443 ret = btrfs_lookup_dir_item(NULL, root->fs_info->tree_root, 2227 di = btrfs_lookup_dir_item(NULL, root->fs_info->tree_root,
2444 path, root_dirid, 2228 path, root_dirid,
2445 vol_args.name, namelen, 0); 2229 vol_args.name, namelen, 0);
2446 mutex_unlock(&root->fs_info->fs_mutex); 2230 mutex_unlock(&root->fs_info->fs_mutex);
2447 btrfs_free_path(path); 2231 btrfs_free_path(path);
2448 if (ret == 0) 2232 if (di && !IS_ERR(di))
2449 return -EEXIST; 2233 return -EEXIST;
2450 2234
2451 if (root == root->fs_info->tree_root) 2235 if (root == root->fs_info->tree_root)