/** * disk_part_iter_next - proceed iterator to the next partition and return it * @piter: iterator of interest * * Proceed @piter to the next partition and return it. * * CONTEXT: * Don't care. */ struct hd_struct *disk_part_iter_next(struct disk_part_iter *piter) { struct disk_part_tbl *ptbl; int inc, end; /* put the last partition */ disk_put_part(piter->part); piter->part = NULL; /* get part_tbl */ rcu_read_lock(); ptbl = rcu_dereference(piter->disk->part_tbl); /* determine iteration parameters */ if (piter->flags & DISK_PITER_REVERSE) { inc = -1; if (piter->flags & (DISK_PITER_INCL_PART0 | DISK_PITER_INCL_EMPTY_PART0)) end = -1; else end = 0; } else { inc = 1; end = ptbl->len; } /* iterate to the next partition */ for (; piter->idx != end; piter->idx += inc) { struct hd_struct *part; part = rcu_dereference(ptbl->part[piter->idx]); if (!part) continue; if (!part_nr_sects_read(part) && !(piter->flags & DISK_PITER_INCL_EMPTY) && !(piter->flags & DISK_PITER_INCL_EMPTY_PART0 && piter->idx == 0)) continue; get_device(part_to_dev(part)); piter->part = part; piter->idx += inc; break; } rcu_read_unlock(); return piter->part; }
static inline int sector_in_part(struct hd_struct *part, sector_t sector) { return part->start_sect <= sector && sector < part->start_sect + part_nr_sects_read(part); }
int ssd_register(char *path) { struct ssd_info *ssd; int ret = -1; mutex_lock(&gctx.ctl_mtx); do { ssd = _alloc_ssd(path); if (!ssd) { ERR("iostash: Could not allocate ssd_info struct.\n"); break; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) ssd->bdev = blkdev_get_by_path(path, FMODE_READ | FMODE_WRITE | FMODE_EXCL, &gctx.ssdtbl); #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) ssd->bdev = open_bdev_exclusive(path, FMODE_READ | FMODE_WRITE | FMODE_EXCL, &gctx.ssdtbl); #else ERR("Kernel version < 2.6.28 currently not supported.\n"); ssd->bdev = ERR_PTR(-ENOENT); #endif if (IS_ERR(ssd->bdev)) { ERR("iostash: SSD device lookup failed.\n"); ssd->bdev = NULL; break; } rmb(); if (1 < ssd->bdev->bd_openers) { ERR("iostash: the SSD device is in use, cannot open it exclusively.\n"); break; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) ssd->nr_sctr = get_capacity(ssd->bdev->bd_disk); #elif LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) ssd->nr_sctr = ssd->bdev->bd_part->nr_sects; #else ssd->nr_sctr = part_nr_sects_read(ssd->bdev->bd_part); #endif if (ssd->nr_sctr < IOSTASH_HEADERSCT) { ERR("SSD capacity less than minimum size of %uB", IOSTASH_HEADERSIZE); break; } ssd->nr_sctr -= IOSTASH_HEADERSCT; DBG("iostash: ssd->nr_sctr = %ld\n", (long)ssd->nr_sctr); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) ssd->queue_max_hw_sectors = queue_max_hw_sectors(bdev_get_queue(ssd->bdev)); #else /* 2.6.29 and 2.6.30 */ ssd->queue_max_hw_sectors = (bdev_get_queue(ssd->bdev))->max_hw_sectors; #endif ssd->cdev = sce_addcdev(gctx.sce, ssd->nr_sctr, ssd); if (ssd->cdev == NULL) { ERR("iostash: sce_add_device() failed.\n"); break; } ret = _ssd_create_kobj(ssd); if (ret) { ERR("ssd_create_kobj failed with %d.\n", ret); break; } /* insert it to our ssd hash table, it is ready to service requests */ _insert_ssd(ssd); ssd->online = 1; gctx.nr_ssd++; DBG("iostash: SSD %s has been added successfully.\n", path); ret = 0; } while (0); if (ret) _destroy_ssd(ssd); mutex_unlock(&gctx.ctl_mtx); return ret; }
ssize_t part_size_show(struct device *dev, struct device_attribute *attr, char *buf) { struct hd_struct *p = dev_to_part(dev); return sprintf(buf, "%llu\n",(unsigned long long)part_nr_sects_read(p)); }