aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/exofs/exofs.h104
-rw-r--r--fs/exofs/inode.c59
-rw-r--r--fs/exofs/ios.c102
-rw-r--r--fs/exofs/super.c136
4 files changed, 218 insertions, 183 deletions
diff --git a/fs/exofs/exofs.h b/fs/exofs/exofs.h
index 5a77fc76433f..39ad50165162 100644
--- a/fs/exofs/exofs.h
+++ b/fs/exofs/exofs.h
@@ -52,9 +52,12 @@
52/* u64 has problems with printk this will cast it to unsigned long long */ 52/* u64 has problems with printk this will cast it to unsigned long long */
53#define _LLU(x) (unsigned long long)(x) 53#define _LLU(x) (unsigned long long)(x)
54 54
55struct exofs_layout { 55struct exofs_comp {
56 osd_id s_pid; /* partition ID of file system*/ 56 struct osd_obj_id obj;
57 u8 cred[OSD_CAP_LEN];
58};
57 59
60struct exofs_layout {
58 /* Our way of looking at the data_map */ 61 /* Our way of looking at the data_map */
59 unsigned stripe_unit; 62 unsigned stripe_unit;
60 unsigned mirrors_p1; 63 unsigned mirrors_p1;
@@ -62,11 +65,18 @@ struct exofs_layout {
62 unsigned group_width; 65 unsigned group_width;
63 u64 group_depth; 66 u64 group_depth;
64 unsigned group_count; 67 unsigned group_count;
68};
65 69
66 enum exofs_inode_layout_gen_functions lay_func; 70struct exofs_components {
67 71 unsigned numdevs; /* Num of devices in array */
68 unsigned s_numdevs; /* Num of devices in array */ 72 /* If @single_comp == EC_SINGLE_COMP, @comps points to a single
69 struct osd_dev **s_ods; /* osd_dev array */ 73 * component. else there are @numdevs components
74 */
75 enum EC_COMP_USAGE {
76 EC_SINGLE_COMP = 0, EC_MULTPLE_COMPS = 0xffffffff
77 } single_comp;
78 struct exofs_comp *comps;
79 struct osd_dev **ods; /* osd_dev array */
70}; 80};
71 81
72/* 82/*
@@ -81,12 +91,13 @@ struct exofs_sb_info {
81 spinlock_t s_next_gen_lock; /* spinlock for gen # update */ 91 spinlock_t s_next_gen_lock; /* spinlock for gen # update */
82 u32 s_next_generation; /* next gen # to use */ 92 u32 s_next_generation; /* next gen # to use */
83 atomic_t s_curr_pending; /* number of pending commands */ 93 atomic_t s_curr_pending; /* number of pending commands */
84 uint8_t s_cred[OSD_CAP_LEN]; /* credential for the fscb */
85 94
86 struct pnfs_osd_data_map data_map; /* Default raid to use 95 struct pnfs_osd_data_map data_map; /* Default raid to use
87 * FIXME: Needed ? 96 * FIXME: Needed ?
88 */ 97 */
89 struct exofs_layout layout; /* Default files layout */ 98 struct exofs_layout layout; /* Default files layout */
99 struct exofs_comp one_comp; /* id & cred of partition id=0*/
100 struct exofs_components comps; /* comps for the partition */
90 struct osd_dev *_min_one_dev[1]; /* Place holder for one dev */ 101 struct osd_dev *_min_one_dev[1]; /* Place holder for one dev */
91}; 102};
92 103
@@ -100,7 +111,8 @@ struct exofs_i_info {
100 uint32_t i_data[EXOFS_IDATA];/*short symlink names and device #s*/ 111 uint32_t i_data[EXOFS_IDATA];/*short symlink names and device #s*/
101 uint32_t i_dir_start_lookup; /* which page to start lookup */ 112 uint32_t i_dir_start_lookup; /* which page to start lookup */
102 uint64_t i_commit_size; /* the object's written length */ 113 uint64_t i_commit_size; /* the object's written length */
103 uint8_t i_cred[OSD_CAP_LEN];/* all-powerful credential */ 114 struct exofs_comp one_comp; /* same component for all devices */
115 struct exofs_components comps; /* inode view of the device table */
104}; 116};
105 117
106static inline osd_id exofs_oi_objno(struct exofs_i_info *oi) 118static inline osd_id exofs_oi_objno(struct exofs_i_info *oi)
@@ -118,8 +130,7 @@ struct exofs_io_state {
118 exofs_io_done_fn done; 130 exofs_io_done_fn done;
119 131
120 struct exofs_layout *layout; 132 struct exofs_layout *layout;
121 struct osd_obj_id obj; 133 struct exofs_components *comps;
122 u8 *cred;
123 134
124 /* Global read/write IO*/ 135 /* Global read/write IO*/
125 loff_t offset; 136 loff_t offset;
@@ -200,20 +211,6 @@ static inline struct exofs_i_info *exofs_i(struct inode *inode)
200} 211}
201 212
202/* 213/*
203 * Given a layout, object_number and stripe_index return the associated global
204 * dev_index
205 */
206unsigned exofs_layout_od_id(struct exofs_layout *layout,
207 osd_id obj_no, unsigned layout_index);
208
209static inline struct osd_dev *exofs_ios_od(struct exofs_io_state *ios,
210 unsigned layout_index)
211{
212 return ios->layout->s_ods[
213 exofs_layout_od_id(ios->layout, ios->obj.id, layout_index)];
214}
215
216/*
217 * Maximum count of links to a file 214 * Maximum count of links to a file
218 */ 215 */
219#define EXOFS_LINK_MAX 32000 216#define EXOFS_LINK_MAX 32000
@@ -223,10 +220,13 @@ static inline struct osd_dev *exofs_ios_od(struct exofs_io_state *ios,
223 *************************/ 220 *************************/
224 221
225/* ios.c */ 222/* ios.c */
226int exofs_get_rw_state(struct exofs_layout *layout, bool is_reading, 223int exofs_get_rw_state(struct exofs_layout *layout,
227 u64 offset, u64 length, struct exofs_io_state **ios); 224 struct exofs_components *comps,
228int exofs_get_io_state(struct exofs_layout *layout, 225 bool is_reading, u64 offset, u64 length,
229 struct exofs_io_state **ios); 226 struct exofs_io_state **ios);
227int exofs_get_io_state(struct exofs_layout *layout,
228 struct exofs_components *comps,
229 struct exofs_io_state **ios);
230void exofs_put_io_state(struct exofs_io_state *ios); 230void exofs_put_io_state(struct exofs_io_state *ios);
231 231
232int exofs_check_io(struct exofs_io_state *ios, u64 *resid); 232int exofs_check_io(struct exofs_io_state *ios, u64 *resid);
@@ -235,27 +235,12 @@ int exofs_sbi_create(struct exofs_io_state *ios);
235int exofs_sbi_remove(struct exofs_io_state *ios); 235int exofs_sbi_remove(struct exofs_io_state *ios);
236int exofs_sbi_write(struct exofs_io_state *ios); 236int exofs_sbi_write(struct exofs_io_state *ios);
237int exofs_sbi_read(struct exofs_io_state *ios); 237int exofs_sbi_read(struct exofs_io_state *ios);
238int exofs_truncate(struct exofs_layout *layout, struct exofs_components *comps,
239 u64 size);
238 240
239int extract_attr_from_ios(struct exofs_io_state *ios, struct osd_attr *attr); 241int extract_attr_from_ios(struct exofs_io_state *ios, struct osd_attr *attr);
240extern const struct osd_attr g_attr_logical_length; 242extern const struct osd_attr g_attr_logical_length;
241 243
242int exofs_oi_truncate(struct exofs_i_info *oi, u64 new_len);
243static inline int exofs_oi_write(struct exofs_i_info *oi,
244 struct exofs_io_state *ios)
245{
246 ios->obj.id = exofs_oi_objno(oi);
247 ios->cred = oi->i_cred;
248 return exofs_sbi_write(ios);
249}
250
251static inline int exofs_oi_read(struct exofs_i_info *oi,
252 struct exofs_io_state *ios)
253{
254 ios->obj.id = exofs_oi_objno(oi);
255 ios->cred = oi->i_cred;
256 return exofs_sbi_read(ios);
257}
258
259/* inode.c */ 244/* inode.c */
260unsigned exofs_max_io_pages(struct exofs_layout *layout, 245unsigned exofs_max_io_pages(struct exofs_layout *layout,
261 unsigned expected_pages); 246 unsigned expected_pages);
@@ -307,4 +292,33 @@ extern const struct inode_operations exofs_special_inode_operations;
307extern const struct inode_operations exofs_symlink_inode_operations; 292extern const struct inode_operations exofs_symlink_inode_operations;
308extern const struct inode_operations exofs_fast_symlink_inode_operations; 293extern const struct inode_operations exofs_fast_symlink_inode_operations;
309 294
295/* exofs_init_comps will initialize an exofs_components device array
296 * pointing to a single exofs_comp struct, and a round-robin view
297 * of the device table.
298 * The first device of each inode is the [inode->ino % num_devices]
299 * and the rest of the devices sequentially following where the
300 * first device is after the last device.
301 * It is assumed that the global device array at @sbi is twice
302 * bigger and that the device table repeats twice.
303 * See: exofs_read_lookup_dev_table()
304 */
305static inline void exofs_init_comps(struct exofs_components *comps,
306 struct exofs_comp *one_comp,
307 struct exofs_sb_info *sbi, osd_id oid)
308{
309 unsigned dev_mod = (unsigned)oid, first_dev;
310
311 one_comp->obj.partition = sbi->one_comp.obj.partition;
312 one_comp->obj.id = oid;
313 exofs_make_credential(one_comp->cred, &one_comp->obj);
314
315 comps->numdevs = sbi->comps.numdevs;
316 comps->single_comp = EC_SINGLE_COMP;
317 comps->comps = one_comp;
318
319 /* Round robin device view of the table */
320 first_dev = (dev_mod * sbi->layout.mirrors_p1) % sbi->comps.numdevs;
321 comps->ods = sbi->comps.ods + first_dev;
322}
323
310#endif 324#endif
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c
index abcdac993039..3cc24f25844d 100644
--- a/fs/exofs/inode.c
+++ b/fs/exofs/inode.c
@@ -270,7 +270,7 @@ static int read_exec(struct page_collect *pcol)
270 return 0; 270 return 0;
271 271
272 if (!pcol->ios) { 272 if (!pcol->ios) {
273 int ret = exofs_get_rw_state(&pcol->sbi->layout, true, 273 int ret = exofs_get_rw_state(&pcol->sbi->layout, &oi->comps, true,
274 pcol->pg_first << PAGE_CACHE_SHIFT, 274 pcol->pg_first << PAGE_CACHE_SHIFT,
275 pcol->length, &pcol->ios); 275 pcol->length, &pcol->ios);
276 276
@@ -283,7 +283,7 @@ static int read_exec(struct page_collect *pcol)
283 ios->nr_pages = pcol->nr_pages; 283 ios->nr_pages = pcol->nr_pages;
284 284
285 if (pcol->read_4_write) { 285 if (pcol->read_4_write) {
286 exofs_oi_read(oi, pcol->ios); 286 exofs_sbi_read(pcol->ios);
287 return __readpages_done(pcol); 287 return __readpages_done(pcol);
288 } 288 }
289 289
@@ -296,14 +296,14 @@ static int read_exec(struct page_collect *pcol)
296 *pcol_copy = *pcol; 296 *pcol_copy = *pcol;
297 ios->done = readpages_done; 297 ios->done = readpages_done;
298 ios->private = pcol_copy; 298 ios->private = pcol_copy;
299 ret = exofs_oi_read(oi, ios); 299 ret = exofs_sbi_read(ios);
300 if (unlikely(ret)) 300 if (unlikely(ret))
301 goto err; 301 goto err;
302 302
303 atomic_inc(&pcol->sbi->s_curr_pending); 303 atomic_inc(&pcol->sbi->s_curr_pending);
304 304
305 EXOFS_DBGMSG2("read_exec obj=0x%llx start=0x%llx length=0x%lx\n", 305 EXOFS_DBGMSG2("read_exec obj=0x%llx start=0x%llx length=0x%lx\n",
306 ios->obj.id, _LLU(ios->offset), pcol->length); 306 oi->one_comp.obj.id, _LLU(ios->offset), pcol->length);
307 307
308 /* pages ownership was passed to pcol_copy */ 308 /* pages ownership was passed to pcol_copy */
309 _pcol_reset(pcol); 309 _pcol_reset(pcol);
@@ -516,7 +516,7 @@ static int write_exec(struct page_collect *pcol)
516 return 0; 516 return 0;
517 517
518 BUG_ON(pcol->ios); 518 BUG_ON(pcol->ios);
519 ret = exofs_get_rw_state(&pcol->sbi->layout, false, 519 ret = exofs_get_rw_state(&pcol->sbi->layout, &oi->comps, false,
520 pcol->pg_first << PAGE_CACHE_SHIFT, 520 pcol->pg_first << PAGE_CACHE_SHIFT,
521 pcol->length, &pcol->ios); 521 pcol->length, &pcol->ios);
522 522
@@ -538,9 +538,9 @@ static int write_exec(struct page_collect *pcol)
538 ios->done = writepages_done; 538 ios->done = writepages_done;
539 ios->private = pcol_copy; 539 ios->private = pcol_copy;
540 540
541 ret = exofs_oi_write(oi, ios); 541 ret = exofs_sbi_write(ios);
542 if (unlikely(ret)) { 542 if (unlikely(ret)) {
543 EXOFS_ERR("write_exec: exofs_oi_write() Failed\n"); 543 EXOFS_ERR("write_exec: exofs_sbi_write() Failed\n");
544 goto err; 544 goto err;
545 } 545 }
546 546
@@ -855,11 +855,12 @@ static inline int exofs_inode_is_fast_symlink(struct inode *inode)
855static int _do_truncate(struct inode *inode, loff_t newsize) 855static int _do_truncate(struct inode *inode, loff_t newsize)
856{ 856{
857 struct exofs_i_info *oi = exofs_i(inode); 857 struct exofs_i_info *oi = exofs_i(inode);
858 struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
858 int ret; 859 int ret;
859 860
860 inode->i_mtime = inode->i_ctime = CURRENT_TIME; 861 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
861 862
862 ret = exofs_oi_truncate(oi, (u64)newsize); 863 ret = exofs_truncate(&sbi->layout, &oi->comps, (u64)newsize);
863 if (likely(!ret)) 864 if (likely(!ret))
864 truncate_setsize(inode, newsize); 865 truncate_setsize(inode, newsize);
865 866
@@ -926,18 +927,14 @@ static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi,
926 struct exofs_on_disk_inode_layout *layout; 927 struct exofs_on_disk_inode_layout *layout;
927 int ret; 928 int ret;
928 929
929 ret = exofs_get_io_state(&sbi->layout, &ios); 930 ret = exofs_get_io_state(&sbi->layout, &oi->comps, &ios);
930 if (unlikely(ret)) { 931 if (unlikely(ret)) {
931 EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__); 932 EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__);
932 return ret; 933 return ret;
933 } 934 }
934 935
935 ios->obj.id = exofs_oi_objno(oi); 936 attrs[1].len = exofs_on_disk_inode_layout_size(sbi->comps.numdevs);
936 exofs_make_credential(oi->i_cred, &ios->obj); 937 attrs[2].len = exofs_on_disk_inode_layout_size(sbi->comps.numdevs);
937 ios->cred = oi->i_cred;
938
939 attrs[1].len = exofs_on_disk_inode_layout_size(sbi->layout.s_numdevs);
940 attrs[2].len = exofs_on_disk_inode_layout_size(sbi->layout.s_numdevs);
941 938
942 ios->in_attr = attrs; 939 ios->in_attr = attrs;
943 ios->in_attr_len = ARRAY_SIZE(attrs); 940 ios->in_attr_len = ARRAY_SIZE(attrs);
@@ -945,7 +942,7 @@ static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi,
945 ret = exofs_sbi_read(ios); 942 ret = exofs_sbi_read(ios);
946 if (unlikely(ret)) { 943 if (unlikely(ret)) {
947 EXOFS_ERR("object(0x%llx) corrupted, return empty file=>%d\n", 944 EXOFS_ERR("object(0x%llx) corrupted, return empty file=>%d\n",
948 _LLU(ios->obj.id), ret); 945 _LLU(oi->one_comp.obj.id), ret);
949 memset(inode, 0, sizeof(*inode)); 946 memset(inode, 0, sizeof(*inode));
950 inode->i_mode = 0040000 | (0777 & ~022); 947 inode->i_mode = 0040000 | (0777 & ~022);
951 /* If object is lost on target we might as well enable it's 948 /* If object is lost on target we might as well enable it's
@@ -1021,6 +1018,8 @@ struct inode *exofs_iget(struct super_block *sb, unsigned long ino)
1021 return inode; 1018 return inode;
1022 oi = exofs_i(inode); 1019 oi = exofs_i(inode);
1023 __oi_init(oi); 1020 __oi_init(oi);
1021 exofs_init_comps(&oi->comps, &oi->one_comp, sb->s_fs_info,
1022 exofs_oi_objno(oi));
1024 1023
1025 /* read the inode from the osd */ 1024 /* read the inode from the osd */
1026 ret = exofs_get_inode(sb, oi, &fcb); 1025 ret = exofs_get_inode(sb, oi, &fcb);
@@ -1126,7 +1125,8 @@ static void create_done(struct exofs_io_state *ios, void *p)
1126 1125
1127 if (unlikely(ret)) { 1126 if (unlikely(ret)) {
1128 EXOFS_ERR("object=0x%llx creation failed in pid=0x%llx", 1127 EXOFS_ERR("object=0x%llx creation failed in pid=0x%llx",
1129 _LLU(exofs_oi_objno(oi)), _LLU(sbi->layout.s_pid)); 1128 _LLU(exofs_oi_objno(oi)),
1129 _LLU(oi->one_comp.obj.partition));
1130 /*TODO: When FS is corrupted creation can fail, object already 1130 /*TODO: When FS is corrupted creation can fail, object already
1131 * exist. Get rid of this asynchronous creation, if exist 1131 * exist. Get rid of this asynchronous creation, if exist
1132 * increment the obj counter and try the next object. Until we 1132 * increment the obj counter and try the next object. Until we
@@ -1145,14 +1145,13 @@ static void create_done(struct exofs_io_state *ios, void *p)
1145 */ 1145 */
1146struct inode *exofs_new_inode(struct inode *dir, int mode) 1146struct inode *exofs_new_inode(struct inode *dir, int mode)
1147{ 1147{
1148 struct super_block *sb; 1148 struct super_block *sb = dir->i_sb;
1149 struct exofs_sb_info *sbi = sb->s_fs_info;
1149 struct inode *inode; 1150 struct inode *inode;
1150 struct exofs_i_info *oi; 1151 struct exofs_i_info *oi;
1151 struct exofs_sb_info *sbi;
1152 struct exofs_io_state *ios; 1152 struct exofs_io_state *ios;
1153 int ret; 1153 int ret;
1154 1154
1155 sb = dir->i_sb;
1156 inode = new_inode(sb); 1155 inode = new_inode(sb);
1157 if (!inode) 1156 if (!inode)
1158 return ERR_PTR(-ENOMEM); 1157 return ERR_PTR(-ENOMEM);
@@ -1162,8 +1161,6 @@ struct inode *exofs_new_inode(struct inode *dir, int mode)
1162 1161
1163 set_obj_2bcreated(oi); 1162 set_obj_2bcreated(oi);
1164 1163
1165 sbi = sb->s_fs_info;
1166
1167 inode->i_mapping->backing_dev_info = sb->s_bdi; 1164 inode->i_mapping->backing_dev_info = sb->s_bdi;
1168 inode_init_owner(inode, dir, mode); 1165 inode_init_owner(inode, dir, mode);
1169 inode->i_ino = sbi->s_nextid++; 1166 inode->i_ino = sbi->s_nextid++;
@@ -1175,22 +1172,21 @@ struct inode *exofs_new_inode(struct inode *dir, int mode)
1175 spin_unlock(&sbi->s_next_gen_lock); 1172 spin_unlock(&sbi->s_next_gen_lock);
1176 insert_inode_hash(inode); 1173 insert_inode_hash(inode);
1177 1174
1175 exofs_init_comps(&oi->comps, &oi->one_comp, sb->s_fs_info,
1176 exofs_oi_objno(oi));
1178 exofs_sbi_write_stats(sbi); /* Make sure new sbi->s_nextid is on disk */ 1177 exofs_sbi_write_stats(sbi); /* Make sure new sbi->s_nextid is on disk */
1179 1178
1180 mark_inode_dirty(inode); 1179 mark_inode_dirty(inode);
1181 1180
1182 ret = exofs_get_io_state(&sbi->layout, &ios); 1181 ret = exofs_get_io_state(&sbi->layout, &oi->comps, &ios);
1183 if (unlikely(ret)) { 1182 if (unlikely(ret)) {
1184 EXOFS_ERR("exofs_new_inode: exofs_get_io_state failed\n"); 1183 EXOFS_ERR("exofs_new_inode: exofs_get_io_state failed\n");
1185 return ERR_PTR(ret); 1184 return ERR_PTR(ret);
1186 } 1185 }
1187 1186
1188 ios->obj.id = exofs_oi_objno(oi);
1189 exofs_make_credential(oi->i_cred, &ios->obj);
1190
1191 ios->done = create_done; 1187 ios->done = create_done;
1192 ios->private = inode; 1188 ios->private = inode;
1193 ios->cred = oi->i_cred; 1189
1194 ret = exofs_sbi_create(ios); 1190 ret = exofs_sbi_create(ios);
1195 if (ret) { 1191 if (ret) {
1196 exofs_put_io_state(ios); 1192 exofs_put_io_state(ios);
@@ -1271,7 +1267,7 @@ static int exofs_update_inode(struct inode *inode, int do_sync)
1271 } else 1267 } else
1272 memcpy(fcb->i_data, oi->i_data, sizeof(fcb->i_data)); 1268 memcpy(fcb->i_data, oi->i_data, sizeof(fcb->i_data));
1273 1269
1274 ret = exofs_get_io_state(&sbi->layout, &ios); 1270 ret = exofs_get_io_state(&sbi->layout, &oi->comps, &ios);
1275 if (unlikely(ret)) { 1271 if (unlikely(ret)) {
1276 EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__); 1272 EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__);
1277 goto free_args; 1273 goto free_args;
@@ -1290,7 +1286,7 @@ static int exofs_update_inode(struct inode *inode, int do_sync)
1290 ios->private = args; 1286 ios->private = args;
1291 } 1287 }
1292 1288
1293 ret = exofs_oi_write(oi, ios); 1289 ret = exofs_sbi_write(ios);
1294 if (!do_sync && !ret) { 1290 if (!do_sync && !ret) {
1295 atomic_inc(&sbi->s_curr_pending); 1291 atomic_inc(&sbi->s_curr_pending);
1296 goto out; /* deallocation in updatei_done */ 1292 goto out; /* deallocation in updatei_done */
@@ -1354,16 +1350,15 @@ void exofs_evict_inode(struct inode *inode)
1354 /* ignore the error, attempt a remove anyway */ 1350 /* ignore the error, attempt a remove anyway */
1355 1351
1356 /* Now Remove the OSD objects */ 1352 /* Now Remove the OSD objects */
1357 ret = exofs_get_io_state(&sbi->layout, &ios); 1353 ret = exofs_get_io_state(&sbi->layout, &oi->comps, &ios);
1358 if (unlikely(ret)) { 1354 if (unlikely(ret)) {
1359 EXOFS_ERR("%s: exofs_get_io_state failed\n", __func__); 1355 EXOFS_ERR("%s: exofs_get_io_state failed\n", __func__);
1360 return; 1356 return;
1361 } 1357 }
1362 1358
1363 ios->obj.id = exofs_oi_objno(oi);
1364 ios->done = delete_done; 1359 ios->done = delete_done;
1365 ios->private = sbi; 1360 ios->private = sbi;
1366 ios->cred = oi->i_cred; 1361
1367 ret = exofs_sbi_remove(ios); 1362 ret = exofs_sbi_remove(ios);
1368 if (ret) { 1363 if (ret) {
1369 EXOFS_ERR("%s: exofs_sbi_remove failed\n", __func__); 1364 EXOFS_ERR("%s: exofs_sbi_remove failed\n", __func__);
diff --git a/fs/exofs/ios.c b/fs/exofs/ios.c
index 21d6130b462e..f9d5c5a823fb 100644
--- a/fs/exofs/ios.c
+++ b/fs/exofs/ios.c
@@ -31,24 +31,41 @@
31#define EXOFS_DBGMSG2(M...) do {} while (0) 31#define EXOFS_DBGMSG2(M...) do {} while (0)
32/* #define EXOFS_DBGMSG2 EXOFS_DBGMSG */ 32/* #define EXOFS_DBGMSG2 EXOFS_DBGMSG */
33 33
34int exofs_get_rw_state(struct exofs_layout *layout, bool is_reading, 34static u8 *_ios_cred(struct exofs_io_state *ios, unsigned index)
35 u64 offset, u64 length, struct exofs_io_state **pios) 35{
36 return ios->comps->comps[index & ios->comps->single_comp].cred;
37}
38
39static struct osd_obj_id *_ios_obj(struct exofs_io_state *ios, unsigned index)
40{
41 return &ios->comps->comps[index & ios->comps->single_comp].obj;
42}
43
44static struct osd_dev *_ios_od(struct exofs_io_state *ios, unsigned index)
45{
46 return ios->comps->ods[index];
47}
48
49int exofs_get_rw_state(struct exofs_layout *layout,
50 struct exofs_components *comps,
51 bool is_reading, u64 offset, u64 length,
52 struct exofs_io_state **pios)
36{ 53{
37 struct exofs_io_state *ios; 54 struct exofs_io_state *ios;
38 55
39 /*TODO: Maybe use kmem_cach per sbi of size 56 /*TODO: Maybe use kmem_cach per sbi of size
40 * exofs_io_state_size(layout->s_numdevs) 57 * exofs_io_state_size(layout->s_numdevs)
41 */ 58 */
42 ios = kzalloc(exofs_io_state_size(layout->s_numdevs), GFP_KERNEL); 59 ios = kzalloc(exofs_io_state_size(comps->numdevs), GFP_KERNEL);
43 if (unlikely(!ios)) { 60 if (unlikely(!ios)) {
44 EXOFS_DBGMSG("Failed kzalloc bytes=%d\n", 61 EXOFS_DBGMSG("Failed kzalloc bytes=%d\n",
45 exofs_io_state_size(layout->s_numdevs)); 62 exofs_io_state_size(comps->numdevs));
46 *pios = NULL; 63 *pios = NULL;
47 return -ENOMEM; 64 return -ENOMEM;
48 } 65 }
49 66
50 ios->layout = layout; 67 ios->layout = layout;
51 ios->obj.partition = layout->s_pid; 68 ios->comps = comps;
52 ios->offset = offset; 69 ios->offset = offset;
53 ios->length = length; 70 ios->length = length;
54 ios->reading = is_reading; 71 ios->reading = is_reading;
@@ -58,9 +75,10 @@ int exofs_get_rw_state(struct exofs_layout *layout, bool is_reading,
58} 75}
59 76
60int exofs_get_io_state(struct exofs_layout *layout, 77int exofs_get_io_state(struct exofs_layout *layout,
78 struct exofs_components *comps,
61 struct exofs_io_state **ios) 79 struct exofs_io_state **ios)
62{ 80{
63 return exofs_get_rw_state(layout, true, 0, 0, ios); 81 return exofs_get_rw_state(layout, comps, true, 0, 0, ios);
64} 82}
65 83
66void exofs_put_io_state(struct exofs_io_state *ios) 84void exofs_put_io_state(struct exofs_io_state *ios)
@@ -119,7 +137,7 @@ static int exofs_io_execute(struct exofs_io_state *ios)
119 if (unlikely(!or)) 137 if (unlikely(!or))
120 continue; 138 continue;
121 139
122 ret = osd_finalize_request(or, 0, ios->cred, NULL); 140 ret = osd_finalize_request(or, 0, _ios_cred(ios, i), NULL);
123 if (unlikely(ret)) { 141 if (unlikely(ret)) {
124 EXOFS_DBGMSG("Failed to osd_finalize_request() => %d\n", 142 EXOFS_DBGMSG("Failed to osd_finalize_request() => %d\n",
125 ret); 143 ret);
@@ -300,7 +318,7 @@ static int _add_stripe_unit(struct exofs_io_state *ios, unsigned *cur_pg,
300{ 318{
301 unsigned pg = *cur_pg; 319 unsigned pg = *cur_pg;
302 struct request_queue *q = 320 struct request_queue *q =
303 osd_request_queue(exofs_ios_od(ios, per_dev->dev)); 321 osd_request_queue(_ios_od(ios, per_dev->dev));
304 322
305 per_dev->length += cur_len; 323 per_dev->length += cur_len;
306 324
@@ -440,10 +458,10 @@ int exofs_sbi_create(struct exofs_io_state *ios)
440{ 458{
441 int i, ret; 459 int i, ret;
442 460
443 for (i = 0; i < ios->layout->s_numdevs; i++) { 461 for (i = 0; i < ios->comps->numdevs; i++) {
444 struct osd_request *or; 462 struct osd_request *or;
445 463
446 or = osd_start_request(exofs_ios_od(ios, i), GFP_KERNEL); 464 or = osd_start_request(_ios_od(ios, i), GFP_KERNEL);
447 if (unlikely(!or)) { 465 if (unlikely(!or)) {
448 EXOFS_ERR("%s: osd_start_request failed\n", __func__); 466 EXOFS_ERR("%s: osd_start_request failed\n", __func__);
449 ret = -ENOMEM; 467 ret = -ENOMEM;
@@ -452,7 +470,7 @@ int exofs_sbi_create(struct exofs_io_state *ios)
452 ios->per_dev[i].or = or; 470 ios->per_dev[i].or = or;
453 ios->numdevs++; 471 ios->numdevs++;
454 472
455 osd_req_create_object(or, &ios->obj); 473 osd_req_create_object(or, _ios_obj(ios, i));
456 } 474 }
457 ret = exofs_io_execute(ios); 475 ret = exofs_io_execute(ios);
458 476
@@ -464,10 +482,10 @@ int exofs_sbi_remove(struct exofs_io_state *ios)
464{ 482{
465 int i, ret; 483 int i, ret;
466 484
467 for (i = 0; i < ios->layout->s_numdevs; i++) { 485 for (i = 0; i < ios->comps->numdevs; i++) {
468 struct osd_request *or; 486 struct osd_request *or;
469 487
470 or = osd_start_request(exofs_ios_od(ios, i), GFP_KERNEL); 488 or = osd_start_request(_ios_od(ios, i), GFP_KERNEL);
471 if (unlikely(!or)) { 489 if (unlikely(!or)) {
472 EXOFS_ERR("%s: osd_start_request failed\n", __func__); 490 EXOFS_ERR("%s: osd_start_request failed\n", __func__);
473 ret = -ENOMEM; 491 ret = -ENOMEM;
@@ -476,7 +494,7 @@ int exofs_sbi_remove(struct exofs_io_state *ios)
476 ios->per_dev[i].or = or; 494 ios->per_dev[i].or = or;
477 ios->numdevs++; 495 ios->numdevs++;
478 496
479 osd_req_remove_object(or, &ios->obj); 497 osd_req_remove_object(or, _ios_obj(ios, i));
480 } 498 }
481 ret = exofs_io_execute(ios); 499 ret = exofs_io_execute(ios);
482 500
@@ -498,7 +516,7 @@ static int _sbi_write_mirror(struct exofs_io_state *ios, int cur_comp)
498 struct exofs_per_dev_state *per_dev = &ios->per_dev[cur_comp]; 516 struct exofs_per_dev_state *per_dev = &ios->per_dev[cur_comp];
499 struct osd_request *or; 517 struct osd_request *or;
500 518
501 or = osd_start_request(exofs_ios_od(ios, dev), GFP_KERNEL); 519 or = osd_start_request(_ios_od(ios, dev), GFP_KERNEL);
502 if (unlikely(!or)) { 520 if (unlikely(!or)) {
503 EXOFS_ERR("%s: osd_start_request failed\n", __func__); 521 EXOFS_ERR("%s: osd_start_request failed\n", __func__);
504 ret = -ENOMEM; 522 ret = -ENOMEM;
@@ -533,25 +551,29 @@ static int _sbi_write_mirror(struct exofs_io_state *ios, int cur_comp)
533 bio->bi_rw |= REQ_WRITE; 551 bio->bi_rw |= REQ_WRITE;
534 } 552 }
535 553
536 osd_req_write(or, &ios->obj, per_dev->offset, bio, 554 osd_req_write(or, _ios_obj(ios, dev), per_dev->offset,
537 per_dev->length); 555 bio, per_dev->length);
538 EXOFS_DBGMSG("write(0x%llx) offset=0x%llx " 556 EXOFS_DBGMSG("write(0x%llx) offset=0x%llx "
539 "length=0x%llx dev=%d\n", 557 "length=0x%llx dev=%d\n",
540 _LLU(ios->obj.id), _LLU(per_dev->offset), 558 _LLU(_ios_obj(ios, dev)->id),
559 _LLU(per_dev->offset),
541 _LLU(per_dev->length), dev); 560 _LLU(per_dev->length), dev);
542 } else if (ios->kern_buff) { 561 } else if (ios->kern_buff) {
543 ret = osd_req_write_kern(or, &ios->obj, per_dev->offset, 562 ret = osd_req_write_kern(or, _ios_obj(ios, dev),
544 ios->kern_buff, ios->length); 563 per_dev->offset,
564 ios->kern_buff, ios->length);
545 if (unlikely(ret)) 565 if (unlikely(ret))
546 goto out; 566 goto out;
547 EXOFS_DBGMSG2("write_kern(0x%llx) offset=0x%llx " 567 EXOFS_DBGMSG2("write_kern(0x%llx) offset=0x%llx "
548 "length=0x%llx dev=%d\n", 568 "length=0x%llx dev=%d\n",
549 _LLU(ios->obj.id), _LLU(per_dev->offset), 569 _LLU(_ios_obj(ios, dev)->id),
570 _LLU(per_dev->offset),
550 _LLU(ios->length), dev); 571 _LLU(ios->length), dev);
551 } else { 572 } else {
552 osd_req_set_attributes(or, &ios->obj); 573 osd_req_set_attributes(or, _ios_obj(ios, dev));
553 EXOFS_DBGMSG2("obj(0x%llx) set_attributes=%d dev=%d\n", 574 EXOFS_DBGMSG2("obj(0x%llx) set_attributes=%d dev=%d\n",
554 _LLU(ios->obj.id), ios->out_attr_len, dev); 575 _LLU(_ios_obj(ios, dev)->id),
576 ios->out_attr_len, dev);
555 } 577 }
556 578
557 if (ios->out_attr) 579 if (ios->out_attr)
@@ -590,13 +612,14 @@ static int _sbi_read_mirror(struct exofs_io_state *ios, unsigned cur_comp)
590{ 612{
591 struct osd_request *or; 613 struct osd_request *or;
592 struct exofs_per_dev_state *per_dev = &ios->per_dev[cur_comp]; 614 struct exofs_per_dev_state *per_dev = &ios->per_dev[cur_comp];
593 unsigned first_dev = (unsigned)ios->obj.id; 615 struct osd_obj_id *obj = _ios_obj(ios, cur_comp);
616 unsigned first_dev = (unsigned)obj->id;
594 617
595 if (ios->pages && !per_dev->length) 618 if (ios->pages && !per_dev->length)
596 return 0; /* Just an empty slot */ 619 return 0; /* Just an empty slot */
597 620
598 first_dev = per_dev->dev + first_dev % ios->layout->mirrors_p1; 621 first_dev = per_dev->dev + first_dev % ios->layout->mirrors_p1;
599 or = osd_start_request(exofs_ios_od(ios, first_dev), GFP_KERNEL); 622 or = osd_start_request(_ios_od(ios, first_dev), GFP_KERNEL);
600 if (unlikely(!or)) { 623 if (unlikely(!or)) {
601 EXOFS_ERR("%s: osd_start_request failed\n", __func__); 624 EXOFS_ERR("%s: osd_start_request failed\n", __func__);
602 return -ENOMEM; 625 return -ENOMEM;
@@ -604,25 +627,26 @@ static int _sbi_read_mirror(struct exofs_io_state *ios, unsigned cur_comp)
604 per_dev->or = or; 627 per_dev->or = or;
605 628
606 if (ios->pages) { 629 if (ios->pages) {
607 osd_req_read(or, &ios->obj, per_dev->offset, 630 osd_req_read(or, obj, per_dev->offset,
608 per_dev->bio, per_dev->length); 631 per_dev->bio, per_dev->length);
609 EXOFS_DBGMSG("read(0x%llx) offset=0x%llx length=0x%llx" 632 EXOFS_DBGMSG("read(0x%llx) offset=0x%llx length=0x%llx"
610 " dev=%d\n", _LLU(ios->obj.id), 633 " dev=%d\n", _LLU(obj->id),
611 _LLU(per_dev->offset), _LLU(per_dev->length), 634 _LLU(per_dev->offset), _LLU(per_dev->length),
612 first_dev); 635 first_dev);
613 } else if (ios->kern_buff) { 636 } else if (ios->kern_buff) {
614 int ret = osd_req_read_kern(or, &ios->obj, per_dev->offset, 637 int ret = osd_req_read_kern(or, obj, per_dev->offset,
615 ios->kern_buff, ios->length); 638 ios->kern_buff, ios->length);
616 EXOFS_DBGMSG2("read_kern(0x%llx) offset=0x%llx " 639 EXOFS_DBGMSG2("read_kern(0x%llx) offset=0x%llx "
617 "length=0x%llx dev=%d ret=>%d\n", 640 "length=0x%llx dev=%d ret=>%d\n",
618 _LLU(ios->obj.id), _LLU(per_dev->offset), 641 _LLU(obj->id), _LLU(per_dev->offset),
619 _LLU(ios->length), first_dev, ret); 642 _LLU(ios->length), first_dev, ret);
620 if (unlikely(ret)) 643 if (unlikely(ret))
621 return ret; 644 return ret;
622 } else { 645 } else {
623 osd_req_get_attributes(or, &ios->obj); 646 osd_req_get_attributes(or, obj);
624 EXOFS_DBGMSG2("obj(0x%llx) get_attributes=%d dev=%d\n", 647 EXOFS_DBGMSG2("obj(0x%llx) get_attributes=%d dev=%d\n",
625 _LLU(ios->obj.id), ios->in_attr_len, first_dev); 648 _LLU(obj->id),
649 ios->in_attr_len, first_dev);
626 } 650 }
627 if (ios->out_attr) 651 if (ios->out_attr)
628 osd_req_add_set_attr_list(or, ios->out_attr, ios->out_attr_len); 652 osd_req_add_set_attr_list(or, ios->out_attr, ios->out_attr_len);
@@ -682,14 +706,14 @@ static int _truncate_mirrors(struct exofs_io_state *ios, unsigned cur_comp,
682 struct exofs_per_dev_state *per_dev = &ios->per_dev[cur_comp]; 706 struct exofs_per_dev_state *per_dev = &ios->per_dev[cur_comp];
683 struct osd_request *or; 707 struct osd_request *or;
684 708
685 or = osd_start_request(exofs_ios_od(ios, cur_comp), GFP_KERNEL); 709 or = osd_start_request(_ios_od(ios, cur_comp), GFP_KERNEL);
686 if (unlikely(!or)) { 710 if (unlikely(!or)) {
687 EXOFS_ERR("%s: osd_start_request failed\n", __func__); 711 EXOFS_ERR("%s: osd_start_request failed\n", __func__);
688 return -ENOMEM; 712 return -ENOMEM;
689 } 713 }
690 per_dev->or = or; 714 per_dev->or = or;
691 715
692 osd_req_set_attributes(or, &ios->obj); 716 osd_req_set_attributes(or, _ios_obj(ios, cur_comp));
693 osd_req_add_set_attr_list(or, attr, 1); 717 osd_req_add_set_attr_list(or, attr, 1);
694 } 718 }
695 719
@@ -721,9 +745,9 @@ void _calc_trunk_info(struct exofs_layout *layout, u64 file_offset,
721 ti->max_devs = layout->group_width * layout->group_count; 745 ti->max_devs = layout->group_width * layout->group_count;
722} 746}
723 747
724int exofs_oi_truncate(struct exofs_i_info *oi, u64 size) 748int exofs_truncate(struct exofs_layout *layout, struct exofs_components *comps,
749 u64 size)
725{ 750{
726 struct exofs_sb_info *sbi = oi->vfs_inode.i_sb->s_fs_info;
727 struct exofs_io_state *ios; 751 struct exofs_io_state *ios;
728 struct exofs_trunc_attr { 752 struct exofs_trunc_attr {
729 struct osd_attr attr; 753 struct osd_attr attr;
@@ -732,7 +756,7 @@ int exofs_oi_truncate(struct exofs_i_info *oi, u64 size)
732 struct _trunc_info ti; 756 struct _trunc_info ti;
733 int i, ret; 757 int i, ret;
734 758
735 ret = exofs_get_io_state(&sbi->layout, &ios); 759 ret = exofs_get_io_state(layout, comps, &ios);
736 if (unlikely(ret)) 760 if (unlikely(ret))
737 return ret; 761 return ret;
738 762
@@ -745,9 +769,7 @@ int exofs_oi_truncate(struct exofs_i_info *oi, u64 size)
745 goto out; 769 goto out;
746 } 770 }
747 771
748 ios->obj.id = exofs_oi_objno(oi); 772 ios->numdevs = ios->comps->numdevs;
749 ios->cred = oi->i_cred;
750 ios->numdevs = ios->layout->s_numdevs;
751 773
752 for (i = 0; i < ti.max_devs; ++i) { 774 for (i = 0; i < ti.max_devs; ++i) {
753 struct exofs_trunc_attr *size_attr = &size_attrs[i]; 775 struct exofs_trunc_attr *size_attr = &size_attrs[i];
@@ -770,7 +792,7 @@ int exofs_oi_truncate(struct exofs_i_info *oi, u64 size)
770 size_attr->attr.val_ptr = &size_attr->newsize; 792 size_attr->attr.val_ptr = &size_attr->newsize;
771 793
772 EXOFS_DBGMSG("trunc(0x%llx) obj_offset=0x%llx dev=%d\n", 794 EXOFS_DBGMSG("trunc(0x%llx) obj_offset=0x%llx dev=%d\n",
773 _LLU(ios->obj.id), _LLU(obj_size), i); 795 _LLU(comps->comps->obj.id), _LLU(obj_size), i);
774 ret = _truncate_mirrors(ios, i * ios->layout->mirrors_p1, 796 ret = _truncate_mirrors(ios, i * ios->layout->mirrors_p1,
775 &size_attr->attr); 797 &size_attr->attr);
776 if (unlikely(ret)) 798 if (unlikely(ret))
diff --git a/fs/exofs/super.c b/fs/exofs/super.c
index 8783f3d33c4a..4d6877967c87 100644
--- a/fs/exofs/super.c
+++ b/fs/exofs/super.c
@@ -253,22 +253,6 @@ out:
253 return ret; 253 return ret;
254} 254}
255 255
256unsigned exofs_layout_od_id(struct exofs_layout *layout,
257 osd_id obj_no, unsigned layout_index)
258{
259/* switch (layout->lay_func) {
260 case LAYOUT_MOVING_WINDOW:
261 {*/
262 unsigned dev_mod = obj_no;
263
264 return (layout_index + dev_mod * layout->mirrors_p1) %
265 layout->s_numdevs;
266/* }
267 case LAYOUT_FUNC_IMPLICT:
268 return layout->devs[layout_index];
269 }*/
270}
271
272static const struct osd_attr g_attr_sb_stats = ATTR_DEF( 256static const struct osd_attr g_attr_sb_stats = ATTR_DEF(
273 EXOFS_APAGE_SB_DATA, 257 EXOFS_APAGE_SB_DATA,
274 EXOFS_ATTR_SB_STATS, 258 EXOFS_ATTR_SB_STATS,
@@ -282,14 +266,12 @@ static int __sbi_read_stats(struct exofs_sb_info *sbi)
282 struct exofs_io_state *ios; 266 struct exofs_io_state *ios;
283 int ret; 267 int ret;
284 268
285 ret = exofs_get_io_state(&sbi->layout, &ios); 269 ret = exofs_get_io_state(&sbi->layout, &sbi->comps, &ios);
286 if (unlikely(ret)) { 270 if (unlikely(ret)) {
287 EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__); 271 EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__);
288 return ret; 272 return ret;
289 } 273 }
290 274
291 ios->cred = sbi->s_cred;
292
293 ios->in_attr = attrs; 275 ios->in_attr = attrs;
294 ios->in_attr_len = ARRAY_SIZE(attrs); 276 ios->in_attr_len = ARRAY_SIZE(attrs);
295 277
@@ -339,7 +321,7 @@ int exofs_sbi_write_stats(struct exofs_sb_info *sbi)
339 struct exofs_io_state *ios; 321 struct exofs_io_state *ios;
340 int ret; 322 int ret;
341 323
342 ret = exofs_get_io_state(&sbi->layout, &ios); 324 ret = exofs_get_io_state(&sbi->layout, &sbi->comps, &ios);
343 if (unlikely(ret)) { 325 if (unlikely(ret)) {
344 EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__); 326 EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__);
345 return ret; 327 return ret;
@@ -349,7 +331,7 @@ int exofs_sbi_write_stats(struct exofs_sb_info *sbi)
349 sbi->s_ess.s_numfiles = cpu_to_le64(sbi->s_numfiles); 331 sbi->s_ess.s_numfiles = cpu_to_le64(sbi->s_numfiles);
350 attrs[0].val_ptr = &sbi->s_ess; 332 attrs[0].val_ptr = &sbi->s_ess;
351 333
352 ios->cred = sbi->s_cred; 334
353 ios->done = stats_done; 335 ios->done = stats_done;
354 ios->private = sbi; 336 ios->private = sbi;
355 ios->out_attr = attrs; 337 ios->out_attr = attrs;
@@ -377,6 +359,8 @@ int exofs_sync_fs(struct super_block *sb, int wait)
377{ 359{
378 struct exofs_sb_info *sbi; 360 struct exofs_sb_info *sbi;
379 struct exofs_fscb *fscb; 361 struct exofs_fscb *fscb;
362 struct exofs_comp one_comp;
363 struct exofs_components comps;
380 struct exofs_io_state *ios; 364 struct exofs_io_state *ios;
381 int ret = -ENOMEM; 365 int ret = -ENOMEM;
382 366
@@ -393,7 +377,10 @@ int exofs_sync_fs(struct super_block *sb, int wait)
393 * version). Otherwise the exofs_fscb is read-only from mkfs time. All 377 * version). Otherwise the exofs_fscb is read-only from mkfs time. All
394 * the writeable info is set in exofs_sbi_write_stats() above. 378 * the writeable info is set in exofs_sbi_write_stats() above.
395 */ 379 */
396 ret = exofs_get_io_state(&sbi->layout, &ios); 380
381 exofs_init_comps(&comps, &one_comp, sbi, EXOFS_SUPER_ID);
382
383 ret = exofs_get_io_state(&sbi->layout, &comps, &ios);
397 if (unlikely(ret)) 384 if (unlikely(ret))
398 goto out; 385 goto out;
399 386
@@ -407,10 +394,8 @@ int exofs_sync_fs(struct super_block *sb, int wait)
407 fscb->s_newfs = 0; 394 fscb->s_newfs = 0;
408 fscb->s_version = EXOFS_FSCB_VER; 395 fscb->s_version = EXOFS_FSCB_VER;
409 396
410 ios->obj.id = EXOFS_SUPER_ID;
411 ios->offset = 0; 397 ios->offset = 0;
412 ios->kern_buff = fscb; 398 ios->kern_buff = fscb;
413 ios->cred = sbi->s_cred;
414 399
415 ret = exofs_sbi_write(ios); 400 ret = exofs_sbi_write(ios);
416 if (unlikely(ret)) 401 if (unlikely(ret))
@@ -446,17 +431,17 @@ static void _exofs_print_device(const char *msg, const char *dev_path,
446 431
447void exofs_free_sbi(struct exofs_sb_info *sbi) 432void exofs_free_sbi(struct exofs_sb_info *sbi)
448{ 433{
449 while (sbi->layout.s_numdevs) { 434 while (sbi->comps.numdevs) {
450 int i = --sbi->layout.s_numdevs; 435 int i = --sbi->comps.numdevs;
451 struct osd_dev *od = sbi->layout.s_ods[i]; 436 struct osd_dev *od = sbi->comps.ods[i];
452 437
453 if (od) { 438 if (od) {
454 sbi->layout.s_ods[i] = NULL; 439 sbi->comps.ods[i] = NULL;
455 osduld_put_device(od); 440 osduld_put_device(od);
456 } 441 }
457 } 442 }
458 if (sbi->layout.s_ods != sbi->_min_one_dev) 443 if (sbi->comps.ods != sbi->_min_one_dev)
459 kfree(sbi->layout.s_ods); 444 kfree(sbi->comps.ods);
460 kfree(sbi); 445 kfree(sbi);
461} 446}
462 447
@@ -483,8 +468,8 @@ static void exofs_put_super(struct super_block *sb)
483 msecs_to_jiffies(100)); 468 msecs_to_jiffies(100));
484 } 469 }
485 470
486 _exofs_print_device("Unmounting", NULL, sbi->layout.s_ods[0], 471 _exofs_print_device("Unmounting", NULL, sbi->comps.ods[0],
487 sbi->layout.s_pid); 472 sbi->one_comp.obj.partition);
488 473
489 bdi_destroy(&sbi->bdi); 474 bdi_destroy(&sbi->bdi);
490 exofs_free_sbi(sbi); 475 exofs_free_sbi(sbi);
@@ -624,8 +609,7 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info *sbi,
624 struct osd_dev *fscb_od, 609 struct osd_dev *fscb_od,
625 unsigned table_count) 610 unsigned table_count)
626{ 611{
627 struct osd_obj_id obj = {.partition = sbi->layout.s_pid, 612 struct exofs_comp comp;
628 .id = EXOFS_DEVTABLE_ID};
629 struct exofs_device_table *dt; 613 struct exofs_device_table *dt;
630 unsigned table_bytes = table_count * sizeof(dt->dt_dev_table[0]) + 614 unsigned table_bytes = table_count * sizeof(dt->dt_dev_table[0]) +
631 sizeof(*dt); 615 sizeof(*dt);
@@ -639,8 +623,14 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info *sbi,
639 return -ENOMEM; 623 return -ENOMEM;
640 } 624 }
641 625
642 sbi->layout.s_numdevs = 0; 626 sbi->comps.numdevs = 0;
643 ret = exofs_read_kern(fscb_od, sbi->s_cred, &obj, 0, dt, table_bytes); 627
628 comp.obj.partition = sbi->one_comp.obj.partition;
629 comp.obj.id = EXOFS_DEVTABLE_ID;
630 exofs_make_credential(comp.cred, &comp.obj);
631
632 ret = exofs_read_kern(fscb_od, comp.cred, &comp.obj, 0, dt,
633 table_bytes);
644 if (unlikely(ret)) { 634 if (unlikely(ret)) {
645 EXOFS_ERR("ERROR: reading device table\n"); 635 EXOFS_ERR("ERROR: reading device table\n");
646 goto out; 636 goto out;
@@ -658,10 +648,13 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info *sbi,
658 goto out; 648 goto out;
659 649
660 if (likely(numdevs > 1)) { 650 if (likely(numdevs > 1)) {
661 unsigned size = numdevs * sizeof(sbi->layout.s_ods[0]); 651 unsigned size = numdevs * sizeof(sbi->comps.ods[0]);
662 652
663 sbi->layout.s_ods = kzalloc(size, GFP_KERNEL); 653 /* Twice bigger table: See exofs_init_comps() and below
664 if (unlikely(!sbi->layout.s_ods)) { 654 * comment
655 */
656 sbi->comps.ods = kzalloc(size + size - 1, GFP_KERNEL);
657 if (unlikely(!sbi->comps.ods)) {
665 EXOFS_ERR("ERROR: faild allocating Device array[%d]\n", 658 EXOFS_ERR("ERROR: faild allocating Device array[%d]\n",
666 numdevs); 659 numdevs);
667 ret = -ENOMEM; 660 ret = -ENOMEM;
@@ -688,8 +681,8 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info *sbi,
688 * line. We always keep them in device-table order. 681 * line. We always keep them in device-table order.
689 */ 682 */
690 if (fscb_od && osduld_device_same(fscb_od, &odi)) { 683 if (fscb_od && osduld_device_same(fscb_od, &odi)) {
691 sbi->layout.s_ods[i] = fscb_od; 684 sbi->comps.ods[i] = fscb_od;
692 ++sbi->layout.s_numdevs; 685 ++sbi->comps.numdevs;
693 fscb_od = NULL; 686 fscb_od = NULL;
694 continue; 687 continue;
695 } 688 }
@@ -702,13 +695,13 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info *sbi,
702 goto out; 695 goto out;
703 } 696 }
704 697
705 sbi->layout.s_ods[i] = od; 698 sbi->comps.ods[i] = od;
706 ++sbi->layout.s_numdevs; 699 ++sbi->comps.numdevs;
707 700
708 /* Read the fscb of the other devices to make sure the FS 701 /* Read the fscb of the other devices to make sure the FS
709 * partition is there. 702 * partition is there.
710 */ 703 */
711 ret = exofs_read_kern(od, sbi->s_cred, &obj, 0, &fscb, 704 ret = exofs_read_kern(od, comp.cred, &comp.obj, 0, &fscb,
712 sizeof(fscb)); 705 sizeof(fscb));
713 if (unlikely(ret)) { 706 if (unlikely(ret)) {
714 EXOFS_ERR("ERROR: Malformed participating device " 707 EXOFS_ERR("ERROR: Malformed participating device "
@@ -725,13 +718,22 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info *sbi,
725 718
726out: 719out:
727 kfree(dt); 720 kfree(dt);
728 if (unlikely(!ret && fscb_od)) { 721 if (likely(!ret)) {
729 EXOFS_ERR( 722 unsigned numdevs = sbi->comps.numdevs;
730 "ERROR: Bad device-table container device not present\n");
731 osduld_put_device(fscb_od);
732 ret = -EINVAL;
733 }
734 723
724 if (unlikely(fscb_od)) {
725 EXOFS_ERR("ERROR: Bad device-table container device not present\n");
726 osduld_put_device(fscb_od);
727 return -EINVAL;
728 }
729 /* exofs round-robins the device table view according to inode
730 * number. We hold a: twice bigger table hence inodes can point
731 * to any device and have a sequential view of the table
732 * starting at this device. See exofs_init_comps()
733 */
734 for (i = 0; i < numdevs - 1; ++i)
735 sbi->comps.ods[i + numdevs] = sbi->comps.ods[i];
736 }
735 return ret; 737 return ret;
736} 738}
737 739
@@ -745,7 +747,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
745 struct exofs_sb_info *sbi; /*extended info */ 747 struct exofs_sb_info *sbi; /*extended info */
746 struct osd_dev *od; /* Master device */ 748 struct osd_dev *od; /* Master device */
747 struct exofs_fscb fscb; /*on-disk superblock info */ 749 struct exofs_fscb fscb; /*on-disk superblock info */
748 struct osd_obj_id obj; 750 struct exofs_comp comp;
749 unsigned table_count; 751 unsigned table_count;
750 int ret; 752 int ret;
751 753
@@ -776,11 +778,16 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
776 sbi->layout.group_width = 1; 778 sbi->layout.group_width = 1;
777 sbi->layout.group_depth = -1; 779 sbi->layout.group_depth = -1;
778 sbi->layout.group_count = 1; 780 sbi->layout.group_count = 1;
779 sbi->layout.s_ods = sbi->_min_one_dev;
780 sbi->layout.s_numdevs = 1;
781 sbi->layout.s_pid = opts->pid;
782 sbi->s_timeout = opts->timeout; 781 sbi->s_timeout = opts->timeout;
783 782
783 sbi->one_comp.obj.partition = opts->pid;
784 sbi->one_comp.obj.id = 0;
785 exofs_make_credential(sbi->one_comp.cred, &sbi->one_comp.obj);
786 sbi->comps.numdevs = 1;
787 sbi->comps.single_comp = EC_SINGLE_COMP;
788 sbi->comps.comps = &sbi->one_comp;
789 sbi->comps.ods = sbi->_min_one_dev;
790
784 /* fill in some other data by hand */ 791 /* fill in some other data by hand */
785 memset(sb->s_id, 0, sizeof(sb->s_id)); 792 memset(sb->s_id, 0, sizeof(sb->s_id));
786 strcpy(sb->s_id, "exofs"); 793 strcpy(sb->s_id, "exofs");
@@ -791,11 +798,11 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
791 sb->s_bdev = NULL; 798 sb->s_bdev = NULL;
792 sb->s_dev = 0; 799 sb->s_dev = 0;
793 800
794 obj.partition = sbi->layout.s_pid; 801 comp.obj.partition = sbi->one_comp.obj.partition;
795 obj.id = EXOFS_SUPER_ID; 802 comp.obj.id = EXOFS_SUPER_ID;
796 exofs_make_credential(sbi->s_cred, &obj); 803 exofs_make_credential(comp.cred, &comp.obj);
797 804
798 ret = exofs_read_kern(od, sbi->s_cred, &obj, 0, &fscb, sizeof(fscb)); 805 ret = exofs_read_kern(od, comp.cred, &comp.obj, 0, &fscb, sizeof(fscb));
799 if (unlikely(ret)) 806 if (unlikely(ret))
800 goto free_sbi; 807 goto free_sbi;
801 808
@@ -828,7 +835,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
828 if (unlikely(ret)) 835 if (unlikely(ret))
829 goto free_sbi; 836 goto free_sbi;
830 } else { 837 } else {
831 sbi->layout.s_ods[0] = od; 838 sbi->comps.ods[0] = od;
832 } 839 }
833 840
834 __sbi_read_stats(sbi); 841 __sbi_read_stats(sbi);
@@ -868,13 +875,13 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
868 goto free_sbi; 875 goto free_sbi;
869 } 876 }
870 877
871 _exofs_print_device("Mounting", opts->dev_name, sbi->layout.s_ods[0], 878 _exofs_print_device("Mounting", opts->dev_name, sbi->comps.ods[0],
872 sbi->layout.s_pid); 879 sbi->one_comp.obj.partition);
873 return 0; 880 return 0;
874 881
875free_sbi: 882free_sbi:
876 EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n", 883 EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n",
877 opts->dev_name, sbi->layout.s_pid, ret); 884 opts->dev_name, sbi->one_comp.obj.partition, ret);
878 exofs_free_sbi(sbi); 885 exofs_free_sbi(sbi);
879 return ret; 886 return ret;
880} 887}
@@ -915,17 +922,14 @@ static int exofs_statfs(struct dentry *dentry, struct kstatfs *buf)
915 }; 922 };
916 uint64_t capacity = ULLONG_MAX; 923 uint64_t capacity = ULLONG_MAX;
917 uint64_t used = ULLONG_MAX; 924 uint64_t used = ULLONG_MAX;
918 uint8_t cred_a[OSD_CAP_LEN];
919 int ret; 925 int ret;
920 926
921 ret = exofs_get_io_state(&sbi->layout, &ios); 927 ret = exofs_get_io_state(&sbi->layout, &sbi->comps, &ios);
922 if (ret) { 928 if (ret) {
923 EXOFS_DBGMSG("exofs_get_io_state failed.\n"); 929 EXOFS_DBGMSG("exofs_get_io_state failed.\n");
924 return ret; 930 return ret;
925 } 931 }
926 932
927 exofs_make_credential(cred_a, &ios->obj);
928 ios->cred = sbi->s_cred;
929 ios->in_attr = attrs; 933 ios->in_attr = attrs;
930 ios->in_attr_len = ARRAY_SIZE(attrs); 934 ios->in_attr_len = ARRAY_SIZE(attrs);
931 935