Update to 3.4-final.
[linux-flexiantxendom0-3.2.10.git] / include / linux / genhd.h
index 56e17ed..017a7fb 100644 (file)
@@ -109,12 +109,13 @@ struct hd_struct {
        int make_it_fail;
 #endif
        unsigned long stamp;
-       int in_flight[2];
+       atomic_t in_flight[2];
 #ifdef CONFIG_SMP
        struct disk_stats __percpu *dkstats;
 #else
        struct disk_stats dkstats;
 #endif
+       atomic_t ref;
        struct rcu_head rcu_head;
 };
 
@@ -126,6 +127,13 @@ struct hd_struct {
 #define GENHD_FL_SUPPRESS_PARTITION_INFO       32
 #define GENHD_FL_EXT_DEVT                      64 /* allow extended devt */
 #define GENHD_FL_NATIVE_CAPACITY               128
+#define GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE    256
+#define GENHD_FL_NO_PART_SCAN                  512
+
+enum {
+       DISK_EVENT_MEDIA_CHANGE                 = 1 << 0, /* media changed */
+       DISK_EVENT_EJECT_REQUEST                = 1 << 1, /* eject requested */
+};
 
 #define BLK_SCSI_MAX_CMDS      (256)
 #define BLK_SCSI_CMD_PER_LONG  (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8))
@@ -143,6 +151,8 @@ struct disk_part_tbl {
        struct hd_struct __rcu *part[];
 };
 
+struct disk_events;
+
 struct gendisk {
        /* major, first_minor and minors are input parameters only,
         * don't use directly.  Use disk_devt() and disk_max_parts().
@@ -153,7 +163,11 @@ struct gendisk {
                                          * disks that can't be partitioned. */
 
        char disk_name[DISK_NAME_LEN];  /* name of major driver */
-       char *(*devnode)(struct gendisk *gd, mode_t *mode);
+       char *(*devnode)(struct gendisk *gd, umode_t *mode);
+
+       unsigned int events;            /* supported events */
+       unsigned int async_events;      /* async events, subset of all */
+
        /* Array of pointers to partitions indexed by partno.
         * Protected with matching bdev lock but stat and other
         * non-critical accesses use RCU.  Always access through
@@ -171,8 +185,8 @@ struct gendisk {
        struct kobject *slave_dir;
 
        struct timer_rand_state *random;
-
        atomic_t sync_io;               /* RAID */
+       struct disk_events *ev;
 #ifdef  CONFIG_BLK_DEV_INTEGRITY
        struct blk_integrity *integrity;
 #endif
@@ -208,12 +222,6 @@ static inline void part_pack_uuid(const u8 *uuid_str, u8 *to)
        }
 }
 
-static inline char *part_unpack_uuid(const u8 *uuid, char *out)
-{
-       sprintf(out, "%pU", uuid);
-       return out;
-}
-
 static inline int disk_max_parts(struct gendisk *disk)
 {
        if (disk->flags & GENHD_FL_EXT_DEVT)
@@ -221,9 +229,10 @@ static inline int disk_max_parts(struct gendisk *disk)
        return disk->minors;
 }
 
-static inline bool disk_partitionable(struct gendisk *disk)
+static inline bool disk_part_scan_enabled(struct gendisk *disk)
 {
-       return disk_max_parts(disk) > 1;
+       return disk_max_parts(disk) > 1 &&
+               !(disk->flags & GENHD_FL_NO_PART_SCAN);
 }
 
 static inline dev_t disk_devt(struct gendisk *disk)
@@ -358,21 +367,21 @@ static inline void free_part_stats(struct hd_struct *part)
 
 static inline void part_inc_in_flight(struct hd_struct *part, int rw)
 {
-       part->in_flight[rw]++;
+       atomic_inc(&part->in_flight[rw]);
        if (part->partno)
-               part_to_disk(part)->part0.in_flight[rw]++;
+               atomic_inc(&part_to_disk(part)->part0.in_flight[rw]);
 }
 
 static inline void part_dec_in_flight(struct hd_struct *part, int rw)
 {
-       part->in_flight[rw]--;
+       atomic_dec(&part->in_flight[rw]);
        if (part->partno)
-               part_to_disk(part)->part0.in_flight[rw]--;
+               atomic_dec(&part_to_disk(part)->part0.in_flight[rw]);
 }
 
 static inline int part_in_flight(struct hd_struct *part)
 {
-       return part->in_flight[0] + part->in_flight[1];
+       return atomic_read(&part->in_flight[0]) + atomic_read(&part->in_flight[1]);
 }
 
 static inline struct partition_meta_info *alloc_part_info(struct gendisk *disk)
@@ -405,6 +414,11 @@ static inline int get_disk_ro(struct gendisk *disk)
        return disk->part0.policy;
 }
 
+extern void disk_block_events(struct gendisk *disk);
+extern void disk_unblock_events(struct gendisk *disk);
+extern void disk_flush_events(struct gendisk *disk, unsigned int mask);
+extern unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask);
+
 /* drivers/char/random.c */
 extern void add_disk_randomness(struct gendisk *disk);
 extern void rand_initialize_disk(struct gendisk *disk);
@@ -576,11 +590,13 @@ extern char *disk_name (struct gendisk *hd, int partno, char *buf);
 
 extern int disk_expand_part_tbl(struct gendisk *disk, int target);
 extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev);
+extern int invalidate_partitions(struct gendisk *disk, struct block_device *bdev);
 extern struct hd_struct * __must_check add_partition(struct gendisk *disk,
                                                     int partno, sector_t start,
                                                     sector_t len, int flags,
                                                     struct partition_meta_info
                                                       *info);
+extern void __delete_partition(struct hd_struct *);
 extern void delete_partition(struct gendisk *, int);
 extern void printk_all_partitions(void);
 
@@ -609,6 +625,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) { }