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
Kirill Smelkov
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
Hide 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,9 +1756,10 @@ 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) \
{ \
int ret = as_var_store(__PTR, (page), count); \
struct as_data *ad = e->elevator_data; \
int ret = as_var_store(__PTR, (page), count); \
if (*(__PTR) < (MIN)) \
*(__PTR) = (MIN); \
else if (*(__PTR) > (MAX)) \
...
...
@@ -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,9 +711,10 @@ 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)
\
{ \
int __data = __VAR; \
struct deadline_data *dd = e->elevator_data; \
int __data = __VAR; \
if (__CONV) \
__data = jiffies_to_msecs(__data); \
return deadline_var_show(__data, (page)); \
...
...
@@ -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)
}
}
int
elv_register_queue
(
struct
request_queue
*
q
)
#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
=
q
->
elevator
;
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
;
}
e
->
kobj
.
parent
=
kobject_get
(
&
q
->
kobj
);
if
(
!
e
->
kobj
.
parent
)
return
-
EBUSY
;
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
;
snprintf
(
e
->
kobj
.
name
,
KOBJ_NAME_LEN
,
"%s"
,
"iosched"
);
e
->
kobj
.
ktype
=
e
->
elevator_type
->
elevator_ktype
;
if
(
!
entry
->
store
)
return
-
EIO
;
return
kobject_register
(
&
e
->
kobj
);
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
=
&
q
->
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