Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xiphi1978
linux
提交
77acfa29
L
linux
项目概览
xiphi1978
/
linux
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
77acfa29
编写于
5月 17, 2013
作者:
A
Al Viro
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[readdir] convert ceph
Signed-off-by:
N
Al Viro
<
viro@zeniv.linux.org.uk
>
上级
23db8620
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
48 addition
and
51 deletion
+48
-51
fs/ceph/dir.c
fs/ceph/dir.c
+48
-51
未找到文件。
fs/ceph/dir.c
浏览文件 @
77acfa29
...
...
@@ -111,11 +111,10 @@ static unsigned fpos_off(loff_t p)
* defined IFF we hold CEPH_CAP_FILE_SHARED (which will be revoked by
* the MDS if/when the directory is modified).
*/
static
int
__dcache_readdir
(
struct
file
*
filp
,
void
*
dirent
,
filldir_t
filldir
)
static
int
__dcache_readdir
(
struct
file
*
file
,
struct
dir_context
*
ctx
)
{
struct
ceph_file_info
*
fi
=
fil
p
->
private_data
;
struct
dentry
*
parent
=
fil
p
->
f_dentry
;
struct
ceph_file_info
*
fi
=
fil
e
->
private_data
;
struct
dentry
*
parent
=
fil
e
->
f_dentry
;
struct
inode
*
dir
=
parent
->
d_inode
;
struct
list_head
*
p
;
struct
dentry
*
dentry
,
*
last
;
...
...
@@ -126,14 +125,14 @@ static int __dcache_readdir(struct file *filp,
last
=
fi
->
dentry
;
fi
->
dentry
=
NULL
;
dout
(
"__dcache_readdir %p at %llu (last %p)
\n
"
,
dir
,
filp
->
f_
pos
,
dout
(
"__dcache_readdir %p at %llu (last %p)
\n
"
,
dir
,
ctx
->
pos
,
last
);
spin_lock
(
&
parent
->
d_lock
);
/* start at beginning? */
if
(
filp
->
f_
pos
==
2
||
last
==
NULL
||
filp
->
f_
pos
<
ceph_dentry
(
last
)
->
offset
)
{
if
(
ctx
->
pos
==
2
||
last
==
NULL
||
ctx
->
pos
<
ceph_dentry
(
last
)
->
offset
)
{
if
(
list_empty
(
&
parent
->
d_subdirs
))
goto
out_unlock
;
p
=
parent
->
d_subdirs
.
prev
;
...
...
@@ -157,11 +156,11 @@ static int __dcache_readdir(struct file *filp,
if
(
!
d_unhashed
(
dentry
)
&&
dentry
->
d_inode
&&
ceph_snap
(
dentry
->
d_inode
)
!=
CEPH_SNAPDIR
&&
ceph_ino
(
dentry
->
d_inode
)
!=
CEPH_INO_CEPH
&&
filp
->
f_
pos
<=
di
->
offset
)
ctx
->
pos
<=
di
->
offset
)
break
;
dout
(
" skipping %p %.*s at %llu (%llu)%s%s
\n
"
,
dentry
,
dentry
->
d_name
.
len
,
dentry
->
d_name
.
name
,
di
->
offset
,
filp
->
f_
pos
,
d_unhashed
(
dentry
)
?
" unhashed"
:
""
,
ctx
->
pos
,
d_unhashed
(
dentry
)
?
" unhashed"
:
""
,
!
dentry
->
d_inode
?
" null"
:
""
);
spin_unlock
(
&
dentry
->
d_lock
);
p
=
p
->
prev
;
...
...
@@ -173,29 +172,27 @@ static int __dcache_readdir(struct file *filp,
spin_unlock
(
&
dentry
->
d_lock
);
spin_unlock
(
&
parent
->
d_lock
);
dout
(
" %llu (%llu) dentry %p %.*s %p
\n
"
,
di
->
offset
,
filp
->
f_
pos
,
dout
(
" %llu (%llu) dentry %p %.*s %p
\n
"
,
di
->
offset
,
ctx
->
pos
,
dentry
,
dentry
->
d_name
.
len
,
dentry
->
d_name
.
name
,
dentry
->
d_inode
);
filp
->
f_
pos
=
di
->
offset
;
err
=
filldir
(
dirent
,
dentry
->
d_name
.
name
,
dentry
->
d_name
.
len
,
di
->
offset
,
ctx
->
pos
=
di
->
offset
;
if
(
!
dir_emit
(
ctx
,
dentry
->
d_name
.
name
,
dentry
->
d_name
.
len
,
ceph_translate_ino
(
dentry
->
d_sb
,
dentry
->
d_inode
->
i_ino
),
dentry
->
d_inode
->
i_mode
>>
12
);
if
(
last
)
{
if
(
err
<
0
)
{
dentry
->
d_inode
->
i_mode
>>
12
))
{
if
(
last
)
{
/* remember our position */
fi
->
dentry
=
last
;
fi
->
next_offset
=
di
->
offset
;
}
else
{
dput
(
last
);
}
dput
(
dentry
);
return
0
;
}
last
=
dentry
;
if
(
err
<
0
)
goto
out
;
if
(
last
)
dput
(
last
);
last
=
dentry
;
filp
->
f_
pos
++
;
ctx
->
pos
++
;
/* make sure a dentry wasn't dropped while we didn't have parent lock */
if
(
!
ceph_dir_is_complete
(
dir
))
{
...
...
@@ -235,59 +232,59 @@ static int note_last_dentry(struct ceph_file_info *fi, const char *name,
return
0
;
}
static
int
ceph_readdir
(
struct
file
*
fil
p
,
void
*
dirent
,
filldir_t
filldir
)
static
int
ceph_readdir
(
struct
file
*
fil
e
,
struct
dir_context
*
ctx
)
{
struct
ceph_file_info
*
fi
=
fil
p
->
private_data
;
struct
inode
*
inode
=
file_inode
(
fil
p
);
struct
ceph_file_info
*
fi
=
fil
e
->
private_data
;
struct
inode
*
inode
=
file_inode
(
fil
e
);
struct
ceph_inode_info
*
ci
=
ceph_inode
(
inode
);
struct
ceph_fs_client
*
fsc
=
ceph_inode_to_client
(
inode
);
struct
ceph_mds_client
*
mdsc
=
fsc
->
mdsc
;
unsigned
frag
=
fpos_frag
(
filp
->
f_
pos
);
int
off
=
fpos_off
(
filp
->
f_
pos
);
unsigned
frag
=
fpos_frag
(
ctx
->
pos
);
int
off
=
fpos_off
(
ctx
->
pos
);
int
err
;
u32
ftype
;
struct
ceph_mds_reply_info_parsed
*
rinfo
;
const
int
max_entries
=
fsc
->
mount_options
->
max_readdir
;
const
int
max_bytes
=
fsc
->
mount_options
->
max_readdir_bytes
;
dout
(
"readdir %p fil
p %p frag %u off %u
\n
"
,
inode
,
filp
,
frag
,
off
);
dout
(
"readdir %p fil
e %p frag %u off %u
\n
"
,
inode
,
file
,
frag
,
off
);
if
(
fi
->
flags
&
CEPH_F_ATEND
)
return
0
;
/* always start with . and .. */
if
(
filp
->
f_
pos
==
0
)
{
if
(
ctx
->
pos
==
0
)
{
/* note dir version at start of readdir so we can tell
* if any dentries get dropped */
fi
->
dir_release_count
=
atomic_read
(
&
ci
->
i_release_count
);
dout
(
"readdir off 0 -> '.'
\n
"
);
if
(
filldir
(
dirent
,
"."
,
1
,
ceph_make_fpos
(
0
,
0
),
if
(
!
dir_emit
(
ctx
,
"."
,
1
,
ceph_translate_ino
(
inode
->
i_sb
,
inode
->
i_ino
),
inode
->
i_mode
>>
12
)
<
0
)
inode
->
i_mode
>>
12
))
return
0
;
filp
->
f_
pos
=
1
;
ctx
->
pos
=
1
;
off
=
1
;
}
if
(
filp
->
f_
pos
==
1
)
{
ino_t
ino
=
parent_ino
(
fil
p
->
f_dentry
);
if
(
ctx
->
pos
==
1
)
{
ino_t
ino
=
parent_ino
(
fil
e
->
f_dentry
);
dout
(
"readdir off 1 -> '..'
\n
"
);
if
(
filldir
(
dirent
,
".."
,
2
,
ceph_make_fpos
(
0
,
1
)
,
if
(
!
dir_emit
(
ctx
,
".."
,
2
,
ceph_translate_ino
(
inode
->
i_sb
,
ino
),
inode
->
i_mode
>>
12
)
<
0
)
inode
->
i_mode
>>
12
))
return
0
;
filp
->
f_
pos
=
2
;
ctx
->
pos
=
2
;
off
=
2
;
}
/* can we use the dcache? */
spin_lock
(
&
ci
->
i_ceph_lock
);
if
((
filp
->
f_
pos
==
2
||
fi
->
dentry
)
&&
if
((
ctx
->
pos
==
2
||
fi
->
dentry
)
&&
!
ceph_test_mount_opt
(
fsc
,
NOASYNCREADDIR
)
&&
ceph_snap
(
inode
)
!=
CEPH_SNAPDIR
&&
__ceph_dir_is_complete
(
ci
)
&&
__ceph_caps_issued_mask
(
ci
,
CEPH_CAP_FILE_SHARED
,
1
))
{
spin_unlock
(
&
ci
->
i_ceph_lock
);
err
=
__dcache_readdir
(
fil
p
,
dirent
,
filldir
);
err
=
__dcache_readdir
(
fil
e
,
ctx
);
if
(
err
!=
-
EAGAIN
)
return
err
;
}
else
{
...
...
@@ -327,7 +324,7 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir)
return
PTR_ERR
(
req
);
req
->
r_inode
=
inode
;
ihold
(
inode
);
req
->
r_dentry
=
dget
(
fil
p
->
f_dentry
);
req
->
r_dentry
=
dget
(
fil
e
->
f_dentry
);
/* hints to request -> mds selection code */
req
->
r_direct_mode
=
USE_AUTH_MDS
;
req
->
r_direct_hash
=
ceph_frag_value
(
frag
);
...
...
@@ -379,15 +376,16 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir)
rinfo
=
&
fi
->
last_readdir
->
r_reply_info
;
dout
(
"readdir frag %x num %d off %d chunkoff %d
\n
"
,
frag
,
rinfo
->
dir_nr
,
off
,
fi
->
offset
);
ctx
->
pos
=
ceph_make_fpos
(
frag
,
off
);
while
(
off
>=
fi
->
offset
&&
off
-
fi
->
offset
<
rinfo
->
dir_nr
)
{
u64
pos
=
ceph_make_fpos
(
frag
,
off
);
struct
ceph_mds_reply_inode
*
in
=
rinfo
->
dir_in
[
off
-
fi
->
offset
].
in
;
struct
ceph_vino
vino
;
ino_t
ino
;
dout
(
"readdir off %d (%d/%d) -> %lld '%.*s' %p
\n
"
,
off
,
off
-
fi
->
offset
,
rinfo
->
dir_nr
,
pos
,
off
,
off
-
fi
->
offset
,
rinfo
->
dir_nr
,
ctx
->
pos
,
rinfo
->
dir_dname_len
[
off
-
fi
->
offset
],
rinfo
->
dir_dname
[
off
-
fi
->
offset
],
in
);
BUG_ON
(
!
in
);
...
...
@@ -395,16 +393,15 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir)
vino
.
ino
=
le64_to_cpu
(
in
->
ino
);
vino
.
snap
=
le64_to_cpu
(
in
->
snapid
);
ino
=
ceph_vino_to_ino
(
vino
);
if
(
filldir
(
dirent
,
if
(
!
dir_emit
(
ctx
,
rinfo
->
dir_dname
[
off
-
fi
->
offset
],
rinfo
->
dir_dname_len
[
off
-
fi
->
offset
],
pos
,
ceph_translate_ino
(
inode
->
i_sb
,
ino
),
ftype
)
<
0
)
{
ceph_translate_ino
(
inode
->
i_sb
,
ino
),
ftype
))
{
dout
(
"filldir stopping us...
\n
"
);
return
0
;
}
off
++
;
filp
->
f_pos
=
pos
+
1
;
ctx
->
pos
++
;
}
if
(
fi
->
last_name
)
{
...
...
@@ -417,7 +414,7 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir)
if
(
!
ceph_frag_is_rightmost
(
frag
))
{
frag
=
ceph_frag_next
(
frag
);
off
=
0
;
filp
->
f_
pos
=
ceph_make_fpos
(
frag
,
off
);
ctx
->
pos
=
ceph_make_fpos
(
frag
,
off
);
dout
(
"readdir next frag is %x
\n
"
,
frag
);
goto
more
;
}
...
...
@@ -432,11 +429,11 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir)
if
(
atomic_read
(
&
ci
->
i_release_count
)
==
fi
->
dir_release_count
)
{
dout
(
" marking %p complete
\n
"
,
inode
);
__ceph_dir_set_complete
(
ci
,
fi
->
dir_release_count
);
ci
->
i_max_offset
=
filp
->
f_
pos
;
ci
->
i_max_offset
=
ctx
->
pos
;
}
spin_unlock
(
&
ci
->
i_ceph_lock
);
dout
(
"readdir %p fil
p %p done.
\n
"
,
inode
,
filp
);
dout
(
"readdir %p fil
e %p done.
\n
"
,
inode
,
file
);
return
0
;
}
...
...
@@ -1268,7 +1265,7 @@ unsigned ceph_dentry_hash(struct inode *dir, struct dentry *dn)
const
struct
file_operations
ceph_dir_fops
=
{
.
read
=
ceph_read_dir
,
.
readdir
=
ceph_readdir
,
.
iterate
=
ceph_readdir
,
.
llseek
=
ceph_dir_llseek
,
.
open
=
ceph_open
,
.
release
=
ceph_release
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录