aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exofs/super.c
diff options
context:
space:
mode:
authorBoaz Harrosh <bharrosh@panasas.com>2009-11-08 07:54:08 -0500
committerBoaz Harrosh <bharrosh@panasas.com>2009-12-10 02:59:22 -0500
commit06886a5a3dc5a5abe0a4d257c26317bde7047be8 (patch)
tree858ac56e120c0473d764fc64a2660e6d79729c8c /fs/exofs/super.c
parent8ce9bdd1fbe962933736d7977e972972cd5d754c (diff)
exofs: Move all operations to an io_engine
In anticipation for multi-device operations, we separate osd operations into an abstract I/O API. Currently only one device is used but later when adding more devices, we will drive all devices in parallel according to a "data_map" that describes how data is arranged on multiple devices. The file system level operates, like before, as if there is one object (inode-number) and an i_size. The io engine will split this to the same object-number but on multiple device. At first we introduce Mirror (raid 1) layout. But at the final outcome we intend to fully implement the pNFS-Objects data-map, including raid 0,4,5,6 over mirrored devices, over multiple device-groups. And more. See: http://tools.ietf.org/html/draft-ietf-nfsv4-pnfs-obj-12 * Define an io_state based API for accessing osd storage devices in an abstract way. Usage: First a caller allocates an io state with: exofs_get_io_state(struct exofs_sb_info *sbi, struct exofs_io_state** ios); Then calles one of: exofs_sbi_create(struct exofs_io_state *ios); exofs_sbi_remove(struct exofs_io_state *ios); exofs_sbi_write(struct exofs_io_state *ios); exofs_sbi_read(struct exofs_io_state *ios); exofs_oi_truncate(struct exofs_i_info *oi, u64 new_len); And when done exofs_put_io_state(struct exofs_io_state *ios); * Convert all source files to use this new API * Convert from bio_alloc to bio_kmalloc * In io engine we make use of the now fixed osd_req_decode_sense There are no functional changes or on disk additions after this patch. Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
Diffstat (limited to 'fs/exofs/super.c')
-rw-r--r--fs/exofs/super.c120
1 files changed, 43 insertions, 77 deletions
diff --git a/fs/exofs/super.c b/fs/exofs/super.c
index 28add3eac0a4..4cd97f526d49 100644
--- a/fs/exofs/super.c
+++ b/fs/exofs/super.c
@@ -203,49 +203,40 @@ int exofs_sync_fs(struct super_block *sb, int wait)
203{ 203{
204 struct exofs_sb_info *sbi; 204 struct exofs_sb_info *sbi;
205 struct exofs_fscb *fscb; 205 struct exofs_fscb *fscb;
206 struct osd_request *or; 206 struct exofs_io_state *ios;
207 struct osd_obj_id obj;
208 int ret = -ENOMEM; 207 int ret = -ENOMEM;
209 208
210 fscb = kzalloc(sizeof(struct exofs_fscb), GFP_KERNEL);
211 if (!fscb) {
212 EXOFS_ERR("exofs_write_super: memory allocation failed.\n");
213 return -ENOMEM;
214 }
215
216 lock_super(sb); 209 lock_super(sb);
217 sbi = sb->s_fs_info; 210 sbi = sb->s_fs_info;
211 fscb = &sbi->s_fscb;
212
213 ret = exofs_get_io_state(sbi, &ios);
214 if (ret)
215 goto out;
216
217 ios->length = sizeof(*fscb);
218 memset(fscb, 0, ios->length);
218 fscb->s_nextid = cpu_to_le64(sbi->s_nextid); 219 fscb->s_nextid = cpu_to_le64(sbi->s_nextid);
219 fscb->s_numfiles = cpu_to_le32(sbi->s_numfiles); 220 fscb->s_numfiles = cpu_to_le32(sbi->s_numfiles);
220 fscb->s_magic = cpu_to_le16(sb->s_magic); 221 fscb->s_magic = cpu_to_le16(sb->s_magic);
221 fscb->s_newfs = 0; 222 fscb->s_newfs = 0;
222 223
223 or = osd_start_request(sbi->s_dev, GFP_KERNEL); 224 ios->obj.id = EXOFS_SUPER_ID;
224 if (unlikely(!or)) { 225 ios->offset = 0;
225 EXOFS_ERR("exofs_write_super: osd_start_request failed.\n"); 226 ios->kern_buff = fscb;
226 goto out; 227 ios->cred = sbi->s_cred;
227 }
228
229 obj.partition = sbi->s_pid;
230 obj.id = EXOFS_SUPER_ID;
231 ret = osd_req_write_kern(or, &obj, 0, fscb, sizeof(*fscb));
232 if (unlikely(ret)) {
233 EXOFS_ERR("exofs_write_super: osd_req_write_kern failed.\n");
234 goto out;
235 }
236 228
237 ret = exofs_sync_op(or, sbi->s_timeout, sbi->s_cred); 229 ret = exofs_sbi_write(ios);
238 if (unlikely(ret)) { 230 if (unlikely(ret)) {
239 EXOFS_ERR("exofs_write_super: exofs_sync_op failed.\n"); 231 EXOFS_ERR("%s: exofs_sbi_write failed.\n", __func__);
240 goto out; 232 goto out;
241 } 233 }
242 sb->s_dirt = 0; 234 sb->s_dirt = 0;
243 235
244out: 236out:
245 if (or) 237 EXOFS_DBGMSG("s_nextid=0x%llx ret=%d\n", _LLU(sbi->s_nextid), ret);
246 osd_end_request(or); 238 exofs_put_io_state(ios);
247 unlock_super(sb); 239 unlock_super(sb);
248 kfree(fscb);
249 return ret; 240 return ret;
250} 241}
251 242
@@ -302,24 +293,23 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
302 struct inode *root; 293 struct inode *root;
303 struct exofs_mountopt *opts = data; 294 struct exofs_mountopt *opts = data;
304 struct exofs_sb_info *sbi; /*extended info */ 295 struct exofs_sb_info *sbi; /*extended info */
296 struct osd_dev *od; /* Master device */
305 struct exofs_fscb fscb; /*on-disk superblock info */ 297 struct exofs_fscb fscb; /*on-disk superblock info */
306 struct osd_request *or = NULL;
307 struct osd_obj_id obj; 298 struct osd_obj_id obj;
308 int ret; 299 int ret;
309 300
310 sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); 301 sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
311 if (!sbi) 302 if (!sbi)
312 return -ENOMEM; 303 return -ENOMEM;
313 sb->s_fs_info = sbi;
314 304
315 /* use mount options to fill superblock */ 305 /* use mount options to fill superblock */
316 sbi->s_dev = osduld_path_lookup(opts->dev_name); 306 od = osduld_path_lookup(opts->dev_name);
317 if (IS_ERR(sbi->s_dev)) { 307 if (IS_ERR(od)) {
318 ret = PTR_ERR(sbi->s_dev); 308 ret = PTR_ERR(od);
319 sbi->s_dev = NULL;
320 goto free_sbi; 309 goto free_sbi;
321 } 310 }
322 311
312 sbi->s_dev = od;
323 sbi->s_pid = opts->pid; 313 sbi->s_pid = opts->pid;
324 sbi->s_timeout = opts->timeout; 314 sbi->s_timeout = opts->timeout;
325 315
@@ -333,35 +323,13 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
333 sb->s_bdev = NULL; 323 sb->s_bdev = NULL;
334 sb->s_dev = 0; 324 sb->s_dev = 0;
335 325
336 /* read data from on-disk superblock object */
337 obj.partition = sbi->s_pid; 326 obj.partition = sbi->s_pid;
338 obj.id = EXOFS_SUPER_ID; 327 obj.id = EXOFS_SUPER_ID;
339 exofs_make_credential(sbi->s_cred, &obj); 328 exofs_make_credential(sbi->s_cred, &obj);
340 329
341 or = osd_start_request(sbi->s_dev, GFP_KERNEL); 330 ret = exofs_read_kern(od, sbi->s_cred, &obj, 0, &fscb, sizeof(fscb));
342 if (unlikely(!or)) { 331 if (unlikely(ret))
343 if (!silent)
344 EXOFS_ERR(
345 "exofs_fill_super: osd_start_request failed.\n");
346 ret = -ENOMEM;
347 goto free_sbi;
348 }
349 ret = osd_req_read_kern(or, &obj, 0, &fscb, sizeof(fscb));
350 if (unlikely(ret)) {
351 if (!silent)
352 EXOFS_ERR(
353 "exofs_fill_super: osd_req_read_kern failed.\n");
354 ret = -ENOMEM;
355 goto free_sbi;
356 }
357
358 ret = exofs_sync_op(or, sbi->s_timeout, sbi->s_cred);
359 if (unlikely(ret)) {
360 if (!silent)
361 EXOFS_ERR("exofs_fill_super: exofs_sync_op failed.\n");
362 ret = -EIO;
363 goto free_sbi; 332 goto free_sbi;
364 }
365 333
366 sb->s_magic = le16_to_cpu(fscb.s_magic); 334 sb->s_magic = le16_to_cpu(fscb.s_magic);
367 sbi->s_nextid = le64_to_cpu(fscb.s_nextid); 335 sbi->s_nextid = le64_to_cpu(fscb.s_nextid);
@@ -380,6 +348,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
380 spin_lock_init(&sbi->s_next_gen_lock); 348 spin_lock_init(&sbi->s_next_gen_lock);
381 349
382 /* set up operation vectors */ 350 /* set up operation vectors */
351 sb->s_fs_info = sbi;
383 sb->s_op = &exofs_sops; 352 sb->s_op = &exofs_sops;
384 sb->s_export_op = &exofs_export_ops; 353 sb->s_export_op = &exofs_export_ops;
385 root = exofs_iget(sb, EXOFS_ROOT_ID - EXOFS_OBJ_OFF); 354 root = exofs_iget(sb, EXOFS_ROOT_ID - EXOFS_OBJ_OFF);
@@ -406,16 +375,14 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
406 } 375 }
407 376
408 _exofs_print_device("Mounting", opts->dev_name, sbi->s_dev, sbi->s_pid); 377 _exofs_print_device("Mounting", opts->dev_name, sbi->s_dev, sbi->s_pid);
409 ret = 0; 378 return 0;
410out:
411 if (or)
412 osd_end_request(or);
413 return ret;
414 379
415free_sbi: 380free_sbi:
381 EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n",
382 opts->dev_name, sbi->s_pid, ret);
416 osduld_put_device(sbi->s_dev); /* NULL safe */ 383 osduld_put_device(sbi->s_dev); /* NULL safe */
417 kfree(sbi); 384 kfree(sbi);
418 goto out; 385 return ret;
419} 386}
420 387
421/* 388/*
@@ -444,7 +411,7 @@ static int exofs_statfs(struct dentry *dentry, struct kstatfs *buf)
444{ 411{
445 struct super_block *sb = dentry->d_sb; 412 struct super_block *sb = dentry->d_sb;
446 struct exofs_sb_info *sbi = sb->s_fs_info; 413 struct exofs_sb_info *sbi = sb->s_fs_info;
447 struct osd_obj_id obj = {sbi->s_pid, 0}; 414 struct exofs_io_state *ios;
448 struct osd_attr attrs[] = { 415 struct osd_attr attrs[] = {
449 ATTR_DEF(OSD_APAGE_PARTITION_QUOTAS, 416 ATTR_DEF(OSD_APAGE_PARTITION_QUOTAS,
450 OSD_ATTR_PQ_CAPACITY_QUOTA, sizeof(__be64)), 417 OSD_ATTR_PQ_CAPACITY_QUOTA, sizeof(__be64)),
@@ -453,26 +420,25 @@ static int exofs_statfs(struct dentry *dentry, struct kstatfs *buf)
453 }; 420 };
454 uint64_t capacity = ULLONG_MAX; 421 uint64_t capacity = ULLONG_MAX;
455 uint64_t used = ULLONG_MAX; 422 uint64_t used = ULLONG_MAX;
456 struct osd_request *or;
457 uint8_t cred_a[OSD_CAP_LEN]; 423 uint8_t cred_a[OSD_CAP_LEN];
458 int ret; 424 int ret;
459 425
460 /* get used/capacity attributes */ 426 ret = exofs_get_io_state(sbi, &ios);
461 exofs_make_credential(cred_a, &obj); 427 if (ret) {
462 428 EXOFS_DBGMSG("exofs_get_io_state failed.\n");
463 or = osd_start_request(sbi->s_dev, GFP_KERNEL); 429 return ret;
464 if (unlikely(!or)) {
465 EXOFS_DBGMSG("exofs_statfs: osd_start_request failed.\n");
466 return -ENOMEM;
467 } 430 }
468 431
469 osd_req_get_attributes(or, &obj); 432 exofs_make_credential(cred_a, &ios->obj);
470 osd_req_add_get_attr_list(or, attrs, ARRAY_SIZE(attrs)); 433 ios->cred = sbi->s_cred;
471 ret = exofs_sync_op(or, sbi->s_timeout, cred_a); 434 ios->in_attr = attrs;
435 ios->in_attr_len = ARRAY_SIZE(attrs);
436
437 ret = exofs_sbi_read(ios);
472 if (unlikely(ret)) 438 if (unlikely(ret))
473 goto out; 439 goto out;
474 440
475 ret = extract_attr_from_req(or, &attrs[0]); 441 ret = extract_attr_from_ios(ios, &attrs[0]);
476 if (likely(!ret)) { 442 if (likely(!ret)) {
477 capacity = get_unaligned_be64(attrs[0].val_ptr); 443 capacity = get_unaligned_be64(attrs[0].val_ptr);
478 if (unlikely(!capacity)) 444 if (unlikely(!capacity))
@@ -480,7 +446,7 @@ static int exofs_statfs(struct dentry *dentry, struct kstatfs *buf)
480 } else 446 } else
481 EXOFS_DBGMSG("exofs_statfs: get capacity failed.\n"); 447 EXOFS_DBGMSG("exofs_statfs: get capacity failed.\n");
482 448
483 ret = extract_attr_from_req(or, &attrs[1]); 449 ret = extract_attr_from_ios(ios, &attrs[1]);
484 if (likely(!ret)) 450 if (likely(!ret))
485 used = get_unaligned_be64(attrs[1].val_ptr); 451 used = get_unaligned_be64(attrs[1].val_ptr);
486 else 452 else
@@ -497,7 +463,7 @@ static int exofs_statfs(struct dentry *dentry, struct kstatfs *buf)
497 buf->f_namelen = EXOFS_NAME_LEN; 463 buf->f_namelen = EXOFS_NAME_LEN;
498 464
499out: 465out:
500 osd_end_request(or); 466 exofs_put_io_state(ios);
501 return ret; 467 return ret;
502} 468}
503 469