aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exofs
diff options
context:
space:
mode:
authorBoaz Harrosh <bharrosh@panasas.com>2011-08-05 18:06:04 -0400
committerBoaz Harrosh <bharrosh@panasas.com>2011-08-06 22:35:32 -0400
commit9e9db45649eb5d3ee5622fdad741914ecf1016a0 (patch)
tree19ab9e1431e3d6535cef3f2cba6fcff12bb6ba6c /fs/exofs
parent85e44df4748670a1a7d8441b2d75843cdebc478a (diff)
exofs: ios: Move to a per inode components & device-table
Exofs raid engine was saving on memory space by having a single layout-info, single pid, and a single device-table, global to the filesystem. Then passing a credential and object_id info at the io_state level, private for each inode. It would also devise this contraption of rotating the device table view for each inode->ino to spread out the device usage. This is not compatible with the pnfs-objects standard, demanding that each inode can have it's own layout-info, device-table, and each object component it's own pid, oid and creds. So: Bring exofs raid engine to be usable for generic pnfs-objects use by: * Define an exofs_comp structure that holds obj_id and credential info. * Break up exofs_layout struct to an exofs_components structure that holds a possible array of exofs_comp and the array of devices + the size of the arrays. * Add a "comps" parameter to get_io_state() that specifies the ids creds and device array to use for each IO. This enables to keep the layout global, but the device-table view, creds and IDs at the inode level. It only adds two 64bit to each inode, since some of these members already existed in another form. * ios raid engine now access layout-info and comps-info through the passed pointers. Everything is pre-prepared by caller for generic access of these structures and arrays. At the exofs Level: * Super block holds an exofs_components struct that holds the device array, previously in layout. The devices there are in device-table order. The device-array is twice bigger and repeats the device-table twice so now each inode's device array can point to a random device and have a round-robin view of the table, making it compatible to previous exofs versions. * Each inode has an exofs_components struct that is initialized at load time, with it's own view of the device table IDs and creds. When doing IO this gets passed to the io_state together with the layout. While preforming this change. Bugs where found where credentials with the wrong IDs where used to access the different SB objects (super.c). As well as some dead code. It was never noticed because the target we use does not check the credentials. Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
Diffstat (limited to 'fs/exofs')
-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