Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
3d1ab40f
Commit
3d1ab40f
authored
Mar 18, 2006
by
Al Viro
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] elevator_t lifetime rules and sysfs fixes
parent
1cc9be68
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
160 additions
and
202 deletions
+160
-202
block/as-iosched.c
block/as-iosched.c
+15
-54
block/cfq-iosched.c
block/cfq-iosched.c
+17
-57
block/deadline-iosched.c
block/deadline-iosched.c
+12
-52
block/elevator.c
block/elevator.c
+108
-38
include/linux/elevator.h
include/linux/elevator.h
+8
-1
No files found.
block/as-iosched.c
View file @
3d1ab40f
...
...
@@ -1709,11 +1709,6 @@ static int as_init_queue(request_queue_t *q, elevator_t *e)
/*
* sysfs parts below
*/
struct
as_fs_entry
{
struct
attribute
attr
;
ssize_t
(
*
show
)(
struct
as_data
*
,
char
*
);
ssize_t
(
*
store
)(
struct
as_data
*
,
const
char
*
,
size_t
);
};
static
ssize_t
as_var_show
(
unsigned
int
var
,
char
*
page
)
...
...
@@ -1730,8 +1725,9 @@ as_var_store(unsigned long *var, const char *page, size_t count)
return
count
;
}
static
ssize_t
as_est_show
(
struct
as_data
*
ad
,
char
*
page
)
static
ssize_t
as_est_show
(
elevator_t
*
e
,
char
*
page
)
{
struct
as_data
*
ad
=
e
->
elevator_data
;
int
pos
=
0
;
pos
+=
sprintf
(
page
+
pos
,
"%lu %% exit probability
\n
"
,
...
...
@@ -1747,8 +1743,9 @@ static ssize_t as_est_show(struct as_data *ad, char *page)
}
#define SHOW_FUNCTION(__FUNC, __VAR) \
static ssize_t __FUNC(
struct as_data *ad
, char *page) \
static ssize_t __FUNC(
elevator_t *e
, char *page) \
{ \
struct as_data *ad = e->elevator_data; \
return as_var_show(jiffies_to_msecs((__VAR)), (page)); \
}
SHOW_FUNCTION
(
as_readexpire_show
,
ad
->
fifo_expire
[
REQ_SYNC
]);
...
...
@@ -1759,8 +1756,9 @@ SHOW_FUNCTION(as_write_batchexpire_show, ad->batch_expire[REQ_ASYNC]);
#undef SHOW_FUNCTION
#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX) \
static ssize_t __FUNC(
struct as_data *ad
, const char *page, size_t count) \
static ssize_t __FUNC(
elevator_t *e
, const char *page, size_t count) \
{ \
struct as_data *ad = e->elevator_data; \
int ret = as_var_store(__PTR, (page), count); \
if (*(__PTR) < (MIN)) \
*(__PTR) = (MIN); \
...
...
@@ -1778,37 +1776,37 @@ STORE_FUNCTION(as_write_batchexpire_store,
&
ad
->
batch_expire
[
REQ_ASYNC
],
0
,
INT_MAX
);
#undef STORE_FUNCTION
static
struct
as
_fs_entry
as_est_entry
=
{
static
struct
elv
_fs_entry
as_est_entry
=
{
.
attr
=
{.
name
=
"est_time"
,
.
mode
=
S_IRUGO
},
.
show
=
as_est_show
,
};
static
struct
as
_fs_entry
as_readexpire_entry
=
{
static
struct
elv
_fs_entry
as_readexpire_entry
=
{
.
attr
=
{.
name
=
"read_expire"
,
.
mode
=
S_IRUGO
|
S_IWUSR
},
.
show
=
as_readexpire_show
,
.
store
=
as_readexpire_store
,
};
static
struct
as
_fs_entry
as_writeexpire_entry
=
{
static
struct
elv
_fs_entry
as_writeexpire_entry
=
{
.
attr
=
{.
name
=
"write_expire"
,
.
mode
=
S_IRUGO
|
S_IWUSR
},
.
show
=
as_writeexpire_show
,
.
store
=
as_writeexpire_store
,
};
static
struct
as
_fs_entry
as_anticexpire_entry
=
{
static
struct
elv
_fs_entry
as_anticexpire_entry
=
{
.
attr
=
{.
name
=
"antic_expire"
,
.
mode
=
S_IRUGO
|
S_IWUSR
},
.
show
=
as_anticexpire_show
,
.
store
=
as_anticexpire_store
,
};
static
struct
as
_fs_entry
as_read_batchexpire_entry
=
{
static
struct
elv
_fs_entry
as_read_batchexpire_entry
=
{
.
attr
=
{.
name
=
"read_batch_expire"
,
.
mode
=
S_IRUGO
|
S_IWUSR
},
.
show
=
as_read_batchexpire_show
,
.
store
=
as_read_batchexpire_store
,
};
static
struct
as
_fs_entry
as_write_batchexpire_entry
=
{
static
struct
elv
_fs_entry
as_write_batchexpire_entry
=
{
.
attr
=
{.
name
=
"write_batch_expire"
,
.
mode
=
S_IRUGO
|
S_IWUSR
},
.
show
=
as_write_batchexpire_show
,
.
store
=
as_write_batchexpire_store
,
};
static
struct
attribute
*
default
_attrs
[]
=
{
static
struct
attribute
*
as
_attrs
[]
=
{
&
as_est_entry
.
attr
,
&
as_readexpire_entry
.
attr
,
&
as_writeexpire_entry
.
attr
,
...
...
@@ -1818,43 +1816,6 @@ static struct attribute *default_attrs[] = {
NULL
,
};
#define to_as(atr) container_of((atr), struct as_fs_entry, attr)
static
ssize_t
as_attr_show
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
char
*
page
)
{
elevator_t
*
e
=
container_of
(
kobj
,
elevator_t
,
kobj
);
struct
as_fs_entry
*
entry
=
to_as
(
attr
);
if
(
!
entry
->
show
)
return
-
EIO
;
return
entry
->
show
(
e
->
elevator_data
,
page
);
}
static
ssize_t
as_attr_store
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
const
char
*
page
,
size_t
length
)
{
elevator_t
*
e
=
container_of
(
kobj
,
elevator_t
,
kobj
);
struct
as_fs_entry
*
entry
=
to_as
(
attr
);
if
(
!
entry
->
store
)
return
-
EIO
;
return
entry
->
store
(
e
->
elevator_data
,
page
,
length
);
}
static
struct
sysfs_ops
as_sysfs_ops
=
{
.
show
=
as_attr_show
,
.
store
=
as_attr_store
,
};
static
struct
kobj_type
as_ktype
=
{
.
sysfs_ops
=
&
as_sysfs_ops
,
.
default_attrs
=
default_attrs
,
};
static
struct
elevator_type
iosched_as
=
{
.
ops
=
{
.
elevator_merge_fn
=
as_merge
,
...
...
@@ -1876,7 +1837,7 @@ static struct elevator_type iosched_as = {
.
trim
=
as_trim
,
},
.
elevator_
ktype
=
&
as_ktype
,
.
elevator_
attrs
=
as_attrs
,
.
elevator_name
=
"anticipatory"
,
.
elevator_owner
=
THIS_MODULE
,
};
...
...
block/cfq-iosched.c
View file @
3d1ab40f
...
...
@@ -2275,11 +2275,6 @@ static int __init cfq_slab_setup(void)
/*
* sysfs parts below -->
*/
struct
cfq_fs_entry
{
struct
attribute
attr
;
ssize_t
(
*
show
)(
struct
cfq_data
*
,
char
*
);
ssize_t
(
*
store
)(
struct
cfq_data
*
,
const
char
*
,
size_t
);
};
static
ssize_t
cfq_var_show
(
unsigned
int
var
,
char
*
page
)
...
...
@@ -2297,8 +2292,9 @@ cfq_var_store(unsigned int *var, const char *page, size_t count)
}
#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \
static ssize_t __FUNC(
struct cfq_data *cfqd, char *page)
\
static ssize_t __FUNC(
elevator_t *e, char *page)
\
{ \
struct cfq_data *cfqd = e->elevator_data; \
unsigned int __data = __VAR; \
if (__CONV) \
__data = jiffies_to_msecs(__data); \
...
...
@@ -2318,8 +2314,9 @@ SHOW_FUNCTION(cfq_max_depth_show, cfqd->cfq_max_depth, 0);
#undef SHOW_FUNCTION
#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \
static ssize_t __FUNC(
struct cfq_data *cfqd
, const char *page, size_t count) \
static ssize_t __FUNC(
elevator_t *e
, const char *page, size_t count) \
{ \
struct cfq_data *cfqd = e->elevator_data; \
unsigned int __data; \
int ret = cfq_var_store(&__data, (page), count); \
if (__data < (MIN)) \
...
...
@@ -2345,63 +2342,63 @@ STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1, UINT_MAX,
STORE_FUNCTION
(
cfq_max_depth_store
,
&
cfqd
->
cfq_max_depth
,
1
,
UINT_MAX
,
0
);
#undef STORE_FUNCTION
static
struct
cfq
_fs_entry
cfq_quantum_entry
=
{
static
struct
elv
_fs_entry
cfq_quantum_entry
=
{
.
attr
=
{.
name
=
"quantum"
,
.
mode
=
S_IRUGO
|
S_IWUSR
},
.
show
=
cfq_quantum_show
,
.
store
=
cfq_quantum_store
,
};
static
struct
cfq
_fs_entry
cfq_queued_entry
=
{
static
struct
elv
_fs_entry
cfq_queued_entry
=
{
.
attr
=
{.
name
=
"queued"
,
.
mode
=
S_IRUGO
|
S_IWUSR
},
.
show
=
cfq_queued_show
,
.
store
=
cfq_queued_store
,
};
static
struct
cfq
_fs_entry
cfq_fifo_expire_sync_entry
=
{
static
struct
elv
_fs_entry
cfq_fifo_expire_sync_entry
=
{
.
attr
=
{.
name
=
"fifo_expire_sync"
,
.
mode
=
S_IRUGO
|
S_IWUSR
},
.
show
=
cfq_fifo_expire_sync_show
,
.
store
=
cfq_fifo_expire_sync_store
,
};
static
struct
cfq
_fs_entry
cfq_fifo_expire_async_entry
=
{
static
struct
elv
_fs_entry
cfq_fifo_expire_async_entry
=
{
.
attr
=
{.
name
=
"fifo_expire_async"
,
.
mode
=
S_IRUGO
|
S_IWUSR
},
.
show
=
cfq_fifo_expire_async_show
,
.
store
=
cfq_fifo_expire_async_store
,
};
static
struct
cfq
_fs_entry
cfq_back_max_entry
=
{
static
struct
elv
_fs_entry
cfq_back_max_entry
=
{
.
attr
=
{.
name
=
"back_seek_max"
,
.
mode
=
S_IRUGO
|
S_IWUSR
},
.
show
=
cfq_back_max_show
,
.
store
=
cfq_back_max_store
,
};
static
struct
cfq
_fs_entry
cfq_back_penalty_entry
=
{
static
struct
elv
_fs_entry
cfq_back_penalty_entry
=
{
.
attr
=
{.
name
=
"back_seek_penalty"
,
.
mode
=
S_IRUGO
|
S_IWUSR
},
.
show
=
cfq_back_penalty_show
,
.
store
=
cfq_back_penalty_store
,
};
static
struct
cfq
_fs_entry
cfq_slice_sync_entry
=
{
static
struct
elv
_fs_entry
cfq_slice_sync_entry
=
{
.
attr
=
{.
name
=
"slice_sync"
,
.
mode
=
S_IRUGO
|
S_IWUSR
},
.
show
=
cfq_slice_sync_show
,
.
store
=
cfq_slice_sync_store
,
};
static
struct
cfq
_fs_entry
cfq_slice_async_entry
=
{
static
struct
elv
_fs_entry
cfq_slice_async_entry
=
{
.
attr
=
{.
name
=
"slice_async"
,
.
mode
=
S_IRUGO
|
S_IWUSR
},
.
show
=
cfq_slice_async_show
,
.
store
=
cfq_slice_async_store
,
};
static
struct
cfq
_fs_entry
cfq_slice_async_rq_entry
=
{
static
struct
elv
_fs_entry
cfq_slice_async_rq_entry
=
{
.
attr
=
{.
name
=
"slice_async_rq"
,
.
mode
=
S_IRUGO
|
S_IWUSR
},
.
show
=
cfq_slice_async_rq_show
,
.
store
=
cfq_slice_async_rq_store
,
};
static
struct
cfq
_fs_entry
cfq_slice_idle_entry
=
{
static
struct
elv
_fs_entry
cfq_slice_idle_entry
=
{
.
attr
=
{.
name
=
"slice_idle"
,
.
mode
=
S_IRUGO
|
S_IWUSR
},
.
show
=
cfq_slice_idle_show
,
.
store
=
cfq_slice_idle_store
,
};
static
struct
cfq
_fs_entry
cfq_max_depth_entry
=
{
static
struct
elv
_fs_entry
cfq_max_depth_entry
=
{
.
attr
=
{.
name
=
"max_depth"
,
.
mode
=
S_IRUGO
|
S_IWUSR
},
.
show
=
cfq_max_depth_show
,
.
store
=
cfq_max_depth_store
,
};
static
struct
attribute
*
default
_attrs
[]
=
{
static
struct
attribute
*
cfq
_attrs
[]
=
{
&
cfq_quantum_entry
.
attr
,
&
cfq_queued_entry
.
attr
,
&
cfq_fifo_expire_sync_entry
.
attr
,
...
...
@@ -2416,43 +2413,6 @@ static struct attribute *default_attrs[] = {
NULL
,
};
#define to_cfq(atr) container_of((atr), struct cfq_fs_entry, attr)
static
ssize_t
cfq_attr_show
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
char
*
page
)
{
elevator_t
*
e
=
container_of
(
kobj
,
elevator_t
,
kobj
);
struct
cfq_fs_entry
*
entry
=
to_cfq
(
attr
);
if
(
!
entry
->
show
)
return
-
EIO
;
return
entry
->
show
(
e
->
elevator_data
,
page
);
}
static
ssize_t
cfq_attr_store
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
const
char
*
page
,
size_t
length
)
{
elevator_t
*
e
=
container_of
(
kobj
,
elevator_t
,
kobj
);
struct
cfq_fs_entry
*
entry
=
to_cfq
(
attr
);
if
(
!
entry
->
store
)
return
-
EIO
;
return
entry
->
store
(
e
->
elevator_data
,
page
,
length
);
}
static
struct
sysfs_ops
cfq_sysfs_ops
=
{
.
show
=
cfq_attr_show
,
.
store
=
cfq_attr_store
,
};
static
struct
kobj_type
cfq_ktype
=
{
.
sysfs_ops
=
&
cfq_sysfs_ops
,
.
default_attrs
=
default_attrs
,
};
static
struct
elevator_type
iosched_cfq
=
{
.
ops
=
{
.
elevator_merge_fn
=
cfq_merge
,
...
...
@@ -2473,7 +2433,7 @@ static struct elevator_type iosched_cfq = {
.
elevator_exit_fn
=
cfq_exit_queue
,
.
trim
=
cfq_trim
,
},
.
elevator_
ktype
=
&
cfq_ktype
,
.
elevator_
attrs
=
cfq_attrs
,
.
elevator_name
=
"cfq"
,
.
elevator_owner
=
THIS_MODULE
,
};
...
...
block/deadline-iosched.c
View file @
3d1ab40f
...
...
@@ -694,11 +694,6 @@ deadline_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
/*
* sysfs parts below
*/
struct
deadline_fs_entry
{
struct
attribute
attr
;
ssize_t
(
*
show
)(
struct
deadline_data
*
,
char
*
);
ssize_t
(
*
store
)(
struct
deadline_data
*
,
const
char
*
,
size_t
);
};
static
ssize_t
deadline_var_show
(
int
var
,
char
*
page
)
...
...
@@ -716,8 +711,9 @@ deadline_var_store(int *var, const char *page, size_t count)
}
#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \
static ssize_t __FUNC(
struct deadline_data *dd, char *page)
\
static ssize_t __FUNC(
elevator_t *e, char *page)
\
{ \
struct deadline_data *dd = e->elevator_data; \
int __data = __VAR; \
if (__CONV) \
__data = jiffies_to_msecs(__data); \
...
...
@@ -731,8 +727,9 @@ SHOW_FUNCTION(deadline_fifobatch_show, dd->fifo_batch, 0);
#undef SHOW_FUNCTION
#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \
static ssize_t __FUNC(
struct deadline_data *dd
, const char *page, size_t count) \
static ssize_t __FUNC(
elevator_t *e
, const char *page, size_t count) \
{ \
struct deadline_data *dd = e->elevator_data; \
int __data; \
int ret = deadline_var_store(&__data, (page), count); \
if (__data < (MIN)) \
...
...
@@ -752,33 +749,33 @@ STORE_FUNCTION(deadline_frontmerges_store, &dd->front_merges, 0, 1, 0);
STORE_FUNCTION
(
deadline_fifobatch_store
,
&
dd
->
fifo_batch
,
0
,
INT_MAX
,
0
);
#undef STORE_FUNCTION
static
struct
deadline
_fs_entry
deadline_readexpire_entry
=
{
static
struct
elv
_fs_entry
deadline_readexpire_entry
=
{
.
attr
=
{.
name
=
"read_expire"
,
.
mode
=
S_IRUGO
|
S_IWUSR
},
.
show
=
deadline_readexpire_show
,
.
store
=
deadline_readexpire_store
,
};
static
struct
deadline
_fs_entry
deadline_writeexpire_entry
=
{
static
struct
elv
_fs_entry
deadline_writeexpire_entry
=
{
.
attr
=
{.
name
=
"write_expire"
,
.
mode
=
S_IRUGO
|
S_IWUSR
},
.
show
=
deadline_writeexpire_show
,
.
store
=
deadline_writeexpire_store
,
};
static
struct
deadline
_fs_entry
deadline_writesstarved_entry
=
{
static
struct
elv
_fs_entry
deadline_writesstarved_entry
=
{
.
attr
=
{.
name
=
"writes_starved"
,
.
mode
=
S_IRUGO
|
S_IWUSR
},
.
show
=
deadline_writesstarved_show
,
.
store
=
deadline_writesstarved_store
,
};
static
struct
deadline
_fs_entry
deadline_frontmerges_entry
=
{
static
struct
elv
_fs_entry
deadline_frontmerges_entry
=
{
.
attr
=
{.
name
=
"front_merges"
,
.
mode
=
S_IRUGO
|
S_IWUSR
},
.
show
=
deadline_frontmerges_show
,
.
store
=
deadline_frontmerges_store
,
};
static
struct
deadline
_fs_entry
deadline_fifobatch_entry
=
{
static
struct
elv
_fs_entry
deadline_fifobatch_entry
=
{
.
attr
=
{.
name
=
"fifo_batch"
,
.
mode
=
S_IRUGO
|
S_IWUSR
},
.
show
=
deadline_fifobatch_show
,
.
store
=
deadline_fifobatch_store
,
};
static
struct
attribute
*
de
fault
_attrs
[]
=
{
static
struct
attribute
*
de
adline
_attrs
[]
=
{
&
deadline_readexpire_entry
.
attr
,
&
deadline_writeexpire_entry
.
attr
,
&
deadline_writesstarved_entry
.
attr
,
...
...
@@ -787,43 +784,6 @@ static struct attribute *default_attrs[] = {
NULL
,
};
#define to_deadline(atr) container_of((atr), struct deadline_fs_entry, attr)
static
ssize_t
deadline_attr_show
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
char
*
page
)
{
elevator_t
*
e
=
container_of
(
kobj
,
elevator_t
,
kobj
);
struct
deadline_fs_entry
*
entry
=
to_deadline
(
attr
);
if
(
!
entry
->
show
)
return
-
EIO
;
return
entry
->
show
(
e
->
elevator_data
,
page
);
}
static
ssize_t
deadline_attr_store
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
const
char
*
page
,
size_t
length
)
{
elevator_t
*
e
=
container_of
(
kobj
,
elevator_t
,
kobj
);
struct
deadline_fs_entry
*
entry
=
to_deadline
(
attr
);
if
(
!
entry
->
store
)
return
-
EIO
;
return
entry
->
store
(
e
->
elevator_data
,
page
,
length
);
}
static
struct
sysfs_ops
deadline_sysfs_ops
=
{
.
show
=
deadline_attr_show
,
.
store
=
deadline_attr_store
,
};
static
struct
kobj_type
deadline_ktype
=
{
.
sysfs_ops
=
&
deadline_sysfs_ops
,
.
default_attrs
=
default_attrs
,
};
static
struct
elevator_type
iosched_deadline
=
{
.
ops
=
{
.
elevator_merge_fn
=
deadline_merge
,
...
...
@@ -840,7 +800,7 @@ static struct elevator_type iosched_deadline = {
.
elevator_exit_fn
=
deadline_exit_queue
,
},
.
elevator_
ktype
=
&
deadline_ktype
,
.
elevator_
attrs
=
deadline_attrs
,
.
elevator_name
=
"deadline"
,
.
elevator_owner
=
THIS_MODULE
,
};
...
...
block/elevator.c
View file @
3d1ab40f
...
...
@@ -120,15 +120,10 @@ static struct elevator_type *elevator_get(const char *name)
return
e
;
}
static
int
elevator_attach
(
request_queue_t
*
q
,
struct
elevator_type
*
e
,
struct
elevator_queue
*
eq
)
static
int
elevator_attach
(
request_queue_t
*
q
,
struct
elevator_queue
*
eq
)
{
int
ret
=
0
;
memset
(
eq
,
0
,
sizeof
(
*
eq
));
eq
->
ops
=
&
e
->
ops
;
eq
->
elevator_type
=
e
;
q
->
elevator
=
eq
;
if
(
eq
->
ops
->
elevator_init_fn
)
...
...
@@ -154,6 +149,32 @@ static int __init elevator_setup(char *str)
__setup
(
"elevator="
,
elevator_setup
);
static
struct
kobj_type
elv_ktype
;
static
elevator_t
*
elevator_alloc
(
struct
elevator_type
*
e
)
{
elevator_t
*
eq
=
kmalloc
(
sizeof
(
elevator_t
),
GFP_KERNEL
);
if
(
eq
)
{
memset
(
eq
,
0
,
sizeof
(
*
eq
));
eq
->
ops
=
&
e
->
ops
;
eq
->
elevator_type
=
e
;
kobject_init
(
&
eq
->
kobj
);
snprintf
(
eq
->
kobj
.
name
,
KOBJ_NAME_LEN
,
"%s"
,
"iosched"
);
eq
->
kobj
.
ktype
=
&
elv_ktype
;
mutex_init
(
&
eq
->
sysfs_lock
);
}
else
{
elevator_put
(
e
);
}
return
eq
;
}
static
void
elevator_release
(
struct
kobject
*
kobj
)
{
elevator_t
*
e
=
container_of
(
kobj
,
elevator_t
,
kobj
);
elevator_put
(
e
->
elevator_type
);
kfree
(
e
);
}
int
elevator_init
(
request_queue_t
*
q
,
char
*
name
)
{
struct
elevator_type
*
e
=
NULL
;
...
...
@@ -176,29 +197,26 @@ int elevator_init(request_queue_t *q, char *name)
e
=
elevator_get
(
"noop"
);
}
eq
=
kmalloc
(
sizeof
(
struct
elevator_queue
),
GFP_KERNEL
);
if
(
!
eq
)
{
elevator_put
(
e
);
eq
=
elevator_alloc
(
e
);
if
(
!
eq
)
return
-
ENOMEM
;
}
ret
=
elevator_attach
(
q
,
e
,
eq
);
if
(
ret
)
{
kfree
(
eq
);
elevator_put
(
e
);
}
ret
=
elevator_attach
(
q
,
eq
);
if
(
ret
)
kobject_put
(
&
eq
->
kobj
);
return
ret
;
}
void
elevator_exit
(
elevator_t
*
e
)
{
mutex_lock
(
&
e
->
sysfs_lock
);
if
(
e
->
ops
->
elevator_exit_fn
)
e
->
ops
->
elevator_exit_fn
(
e
);
e
->
ops
=
NULL
;
mutex_unlock
(
&
e
->
sysfs_lock
);
elevator_put
(
e
->
elevator_type
);
e
->
elevator_type
=
NULL
;
kfree
(
e
);
kobject_put
(
&
e
->
kobj
);
}
/*
...
...
@@ -627,26 +645,78 @@ void elv_completed_request(request_queue_t *q, struct request *rq)
}
}
#define to_elv(atr) container_of((atr), struct elv_fs_entry, attr)
static
ssize_t
elv_attr_show
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
char
*
page
)
{
elevator_t
*
e
=
container_of
(
kobj
,
elevator_t
,
kobj
);
struct
elv_fs_entry
*
entry
=
to_elv
(
attr
);
ssize_t
error
;
if
(
!
entry
->
show
)
return
-
EIO
;
mutex_lock
(
&
e
->
sysfs_lock
);
error
=
e
->
ops
?
entry
->
show
(
e
,
page
)
:
-
ENOENT
;
mutex_unlock
(
&
e
->
sysfs_lock
);
return
error
;
}
static
ssize_t
elv_attr_store
(
struct
kobject
*
kobj
,
struct
attribute
*
attr
,
const
char
*
page
,
size_t
length
)
{
elevator_t
*
e
=
container_of
(
kobj
,
elevator_t
,
kobj
);
struct
elv_fs_entry
*
entry
=
to_elv
(
attr
);
ssize_t
error
;
if
(
!
entry
->
store
)
return
-
EIO
;
mutex_lock
(
&
e
->
sysfs_lock
);
error
=
e
->
ops
?
entry
->
store
(
e
,
page
,
length
)
:
-
ENOENT
;
mutex_unlock
(
&
e
->
sysfs_lock
);
return
error
;
}
static
struct
sysfs_ops
elv_sysfs_ops
=
{
.
show
=
elv_attr_show
,
.
store
=
elv_attr_store
,
};
static
struct
kobj_type
elv_ktype
=
{
.
sysfs_ops
=
&
elv_sysfs_ops
,
.
release
=
elevator_release
,
};
int
elv_register_queue
(
struct
request_queue
*
q
)
{
elevator_t
*
e
=
q
->
elevator
;
int
error
;
e
->
kobj
.
parent
=
kobject_get
(
&
q
->
kobj
);
if
(
!
e
->
kobj
.
parent
)
return
-
EBUSY
;
snprintf
(
e
->
kobj
.
name
,
KOBJ_NAME_LEN
,
"%s"
,
"iosched"
);
e
->
kobj
.
ktype
=
e
->
elevator_type
->
elevator_ktype
;
e
->
kobj
.
parent
=
&
q
->
kobj
;
return
kobject_register
(
&
e
->
kobj
);
error
=
kobject_add
(
&
e
->
kobj
);
if
(
!
error
)
{
struct
attribute
**
attr
=
e
->
elevator_type
->
elevator_attrs
;
if
(
attr
)
{
while
(
*
attr
)
{
if
(
sysfs_create_file
(
&
e
->
kobj
,
*
attr
++
))
break
;
}
}
kobject_uevent
(
&
e
->
kobj
,
KOBJ_ADD
);
}
return
error
;
}
void
elv_unregister_queue
(
struct
request_queue
*
q
)
{
if
(
q
)
{
elevator_t
*
e
=
q
->
elevator
;
kobject_u
nregister
(
&
e
->
kobj
);
kobject_
put
(
&
q
->
kobj
);
kobject_u
event
(
&
e
->
kobj
,
KOBJ_REMOVE
);
kobject_
del
(
&
e
->
kobj
);
}
}
...
...
@@ -697,16 +767,16 @@ EXPORT_SYMBOL_GPL(elv_unregister);
* need for the new one. this way we have a chance of going back to the old
* one, if the new one fails init for some reason.
*/
static
void
elevator_switch
(
request_queue_t
*
q
,
struct
elevator_type
*
new_e
)
static
int
elevator_switch
(
request_queue_t
*
q
,
struct
elevator_type
*
new_e
)
{
elevator_t
*
old_elevator
,
*
e
;
/*
* Allocate new elevator
*/
e
=
kmalloc
(
sizeof
(
elevator_t
),
GFP_KERNEL
);
e
=
elevator_alloc
(
new_e
);
if
(
!
e
)
goto
error
;
return
0
;
/*
* Turn on BYPASS and drain all requests w/ elevator private data
...
...
@@ -737,7 +807,7 @@ static void elevator_switch(request_queue_t *q, struct elevator_type *new_e)
/*
* attach and start new elevator
*/
if
(
elevator_attach
(
q
,
new_e
,
e
))
if
(
elevator_attach
(
q
,
e
))
goto
fail
;
if
(
elv_register_queue
(
q
))
...
...
@@ -748,7 +818,7 @@ static void elevator_switch(request_queue_t *q, struct elevator_type *new_e)
*/
elevator_exit
(
old_elevator
);
clear_bit
(
QUEUE_FLAG_ELVSWITCH
,
&
q
->
queue_flags
);
return
;
return
1
;
fail_register:
/*
...
...
@@ -761,10 +831,9 @@ static void elevator_switch(request_queue_t *q, struct elevator_type *new_e)
q
->
elevator
=
old_elevator
;
elv_register_queue
(
q
);
clear_bit
(
QUEUE_FLAG_ELVSWITCH
,
&
q
->
queue_flags
);
kfree
(
e
);
error:
elevator_put
(
new_e
);
printk
(
KERN_ERR
"elevator: switch to %s failed
\n
"
,
new_e
->
elevator_name
);
if
(
e
)
kobject_put
(
&
e
->
kobj
);
return
0
;
}
ssize_t
elv_iosched_store
(
request_queue_t
*
q
,
const
char
*
name
,
size_t
count
)
...
...
@@ -791,7 +860,8 @@ ssize_t elv_iosched_store(request_queue_t *q, const char *name, size_t count)
return
count
;
}
elevator_switch
(
q
,
e
);
if
(
!
elevator_switch
(
q
,
e
))
printk
(
KERN_ERR
"elevator: switch to %s failed
\n
"
,
elevator_name
);
return
count
;
}
...
...
include/linux/elevator.h
View file @
3d1ab40f
...
...
@@ -61,7 +61,7 @@ struct elevator_type
struct
list_head
list
;
struct
elevator_ops
ops
;
struct
elevator_type
*
elevator_type
;
struct
kobj_type
*
elevator_ktype
;
struct
attribute
**
elevator_attrs
;
char
elevator_name
[
ELV_NAME_MAX
];
struct
module
*
elevator_owner
;
};
...
...
@@ -75,6 +75,7 @@ struct elevator_queue
void
*
elevator_data
;
struct
kobject
kobj
;
struct
elevator_type
*
elevator_type
;
struct
mutex
sysfs_lock
;
};
/*
...
...
@@ -141,6 +142,12 @@ enum {
ELV_MQUEUE_MUST
,
};
struct
elv_fs_entry
{
struct
attribute
attr
;
ssize_t
(
*
show
)(
elevator_t
*
,
char
*
);
ssize_t
(
*
store
)(
elevator_t
*
,
const
char
*
,
size_t
);
};
#define rq_end_sector(rq) ((rq)->sector + (rq)->nr_sectors)
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment