Skip to content

Commit

Permalink
block: add internal hd part table references
Browse files Browse the repository at this point in the history
We can't use krefs since it's apparently restricted to very basic
reference counting.

This reverts commit e4a683c.

Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
  • Loading branch information
Jens Axboe committed Jan 7, 2011
1 parent 09e099d commit 6c23a96
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 25 deletions.
6 changes: 3 additions & 3 deletions block/blk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ static void drive_stat_acct(struct request *rq, int new_io)
part_stat_inc(cpu, part, merges[rw]);
} else {
part = disk_map_sector_rcu(rq->rq_disk, blk_rq_pos(rq));
if (!kref_test_and_get(&part->ref)) {
if (!hd_struct_try_get(part)) {
/*
* The partition is already being removed,
* the request will be accounted on the disk only
Expand All @@ -80,7 +80,7 @@ static void drive_stat_acct(struct request *rq, int new_io)
* it as any other partition.
*/
part = &rq->rq_disk->part0;
kref_get(&part->ref);
hd_struct_get(part);
}
part_round_stats(cpu, part);
part_inc_in_flight(part, rw);
Expand Down Expand Up @@ -1818,7 +1818,7 @@ static void blk_account_io_done(struct request *req)
part_round_stats(cpu, part);
part_dec_in_flight(part, rw);

kref_put(&part->ref, __delete_partition);
hd_struct_put(part);
part_stat_unlock();
}
}
Expand Down
2 changes: 1 addition & 1 deletion block/blk-merge.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ static void blk_account_io_merge(struct request *req)
part_round_stats(cpu, part);
part_dec_in_flight(part, rq_data_dir(req));

kref_put(&part->ref, __delete_partition);
hd_struct_put(part);
part_stat_unlock();
}
}
Expand Down
3 changes: 2 additions & 1 deletion block/genhd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1192,7 +1192,8 @@ struct gendisk *alloc_disk_node(int minors, int node_id)
return NULL;
}
disk->part_tbl->part[0] = &disk->part0;
kref_init(&disk->part0.ref);

hd_ref_init(&disk->part0);

disk->minors = minors;
rand_initialize_disk(disk);
Expand Down
8 changes: 3 additions & 5 deletions fs/partitions/check.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,10 +381,8 @@ static void delete_partition_rcu_cb(struct rcu_head *head)
put_device(part_to_dev(part));
}

void __delete_partition(struct kref *ref)
void __delete_partition(struct hd_struct *part)
{
struct hd_struct *part = container_of(ref, struct hd_struct, ref);

call_rcu(&part->rcu_head, delete_partition_rcu_cb);
}

Expand All @@ -406,7 +404,7 @@ void delete_partition(struct gendisk *disk, int partno)
kobject_put(part->holder_dir);
device_del(part_to_dev(part));

kref_put(&part->ref, __delete_partition);
hd_struct_put(part);
}

static ssize_t whole_disk_show(struct device *dev,
Expand Down Expand Up @@ -505,7 +503,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
if (!dev_get_uevent_suppress(ddev))
kobject_uevent(&pdev->kobj, KOBJ_ADD);

kref_init(&p->ref);
hd_ref_init(p);
return p;

out_free_info:
Expand Down
27 changes: 25 additions & 2 deletions include/linux/genhd.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ struct hd_struct {
#else
struct disk_stats dkstats;
#endif
atomic_t ref;
struct rcu_head rcu_head;
struct kref ref;
};

#define GENHD_FL_REMOVABLE 1
Expand Down Expand Up @@ -584,7 +584,7 @@ extern struct hd_struct * __must_check add_partition(struct gendisk *disk,
sector_t len, int flags,
struct partition_meta_info
*info);
extern void __delete_partition(struct kref *ref);
extern void __delete_partition(struct hd_struct *);
extern void delete_partition(struct gendisk *, int);
extern void printk_all_partitions(void);

Expand Down Expand Up @@ -613,6 +613,29 @@ extern ssize_t part_fail_store(struct device *dev,
const char *buf, size_t count);
#endif /* CONFIG_FAIL_MAKE_REQUEST */

static inline void hd_ref_init(struct hd_struct *part)
{
atomic_set(&part->ref, 1);
smp_mb();
}

static inline void hd_struct_get(struct hd_struct *part)
{
atomic_inc(&part->ref);
smp_mb__after_atomic_inc();
}

static inline int hd_struct_try_get(struct hd_struct *part)
{
return atomic_inc_not_zero(&part->ref);
}

static inline void hd_struct_put(struct hd_struct *part)
{
if (atomic_dec_and_test(&part->ref))
__delete_partition(part);
}

#else /* CONFIG_BLOCK */

static inline void printk_all_partitions(void) { }
Expand Down
1 change: 0 additions & 1 deletion include/linux/kref.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ struct kref {

void kref_init(struct kref *kref);
void kref_get(struct kref *kref);
int kref_test_and_get(struct kref *kref);
int kref_put(struct kref *kref, void (*release) (struct kref *kref));

#endif /* _KREF_H_ */
12 changes: 0 additions & 12 deletions lib/kref.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,6 @@ void kref_get(struct kref *kref)
smp_mb__after_atomic_inc();
}

/**
* kref_test_and_get - increment refcount for object only if refcount is not
* zero.
* @kref: object.
*
* Return non-zero if the refcount was incremented, 0 otherwise
*/
int kref_test_and_get(struct kref *kref)
{
return atomic_inc_not_zero(&kref->refcount);
}

/**
* kref_put - decrement refcount for object.
* @kref: object.
Expand Down

0 comments on commit 6c23a96

Please sign in to comment.