diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-13 13:25:24 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-13 13:25:24 -0500 |
commit | a1703154200c390ab03c10224c586e815d3e31e8 (patch) | |
tree | df90865eed3cfdf7af8664b5453a90e09d17480a /fs | |
parent | 67b5ad9a63caa2ce56ddd2b22b802dae00d72c13 (diff) | |
parent | 766fc43973b16f9becb6b7402b3e052dbb84adee (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client:
rbd: fix cleanup when trying to mount inexistent image
net/ceph: make ceph_msgr_wq non-reentrant
ceph: fsc->*_wq's aren't used in memory reclaim path
ceph: Always free allocated memory in osdmap_decode()
ceph: Makefile: Remove unnessary code
ceph: associate requests with opening sessions
ceph: drop redundant r_mds field
ceph: implement DIRLAYOUTHASH feature to get dir layout from MDS
ceph: add dir_layout to inode
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ceph/Makefile | 23 | ||||
-rw-r--r-- | fs/ceph/debugfs.c | 9 | ||||
-rw-r--r-- | fs/ceph/dir.c | 20 | ||||
-rw-r--r-- | fs/ceph/export.c | 2 | ||||
-rw-r--r-- | fs/ceph/inode.c | 4 | ||||
-rw-r--r-- | fs/ceph/mds_client.c | 56 | ||||
-rw-r--r-- | fs/ceph/mds_client.h | 2 | ||||
-rw-r--r-- | fs/ceph/super.c | 13 | ||||
-rw-r--r-- | fs/ceph/super.h | 2 |
9 files changed, 80 insertions, 51 deletions
diff --git a/fs/ceph/Makefile b/fs/ceph/Makefile index 9e6c4f2e8ff1..bd352125e829 100644 --- a/fs/ceph/Makefile +++ b/fs/ceph/Makefile | |||
@@ -2,31 +2,10 @@ | |||
2 | # Makefile for CEPH filesystem. | 2 | # Makefile for CEPH filesystem. |
3 | # | 3 | # |
4 | 4 | ||
5 | ifneq ($(KERNELRELEASE),) | ||
6 | |||
7 | obj-$(CONFIG_CEPH_FS) += ceph.o | 5 | obj-$(CONFIG_CEPH_FS) += ceph.o |
8 | 6 | ||
9 | ceph-objs := super.o inode.o dir.o file.o locks.o addr.o ioctl.o \ | 7 | ceph-y := super.o inode.o dir.o file.o locks.o addr.o ioctl.o \ |
10 | export.o caps.o snap.o xattr.o \ | 8 | export.o caps.o snap.o xattr.o \ |
11 | mds_client.o mdsmap.o strings.o ceph_frag.o \ | 9 | mds_client.o mdsmap.o strings.o ceph_frag.o \ |
12 | debugfs.o | 10 | debugfs.o |
13 | 11 | ||
14 | else | ||
15 | #Otherwise we were called directly from the command | ||
16 | # line; invoke the kernel build system. | ||
17 | |||
18 | KERNELDIR ?= /lib/modules/$(shell uname -r)/build | ||
19 | PWD := $(shell pwd) | ||
20 | |||
21 | default: all | ||
22 | |||
23 | all: | ||
24 | $(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_CEPH_FS=m modules | ||
25 | |||
26 | modules_install: | ||
27 | $(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_CEPH_FS=m modules_install | ||
28 | |||
29 | clean: | ||
30 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean | ||
31 | |||
32 | endif | ||
diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index 7ae1b3d55b58..08f65faac112 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c | |||
@@ -60,10 +60,13 @@ static int mdsc_show(struct seq_file *s, void *p) | |||
60 | for (rp = rb_first(&mdsc->request_tree); rp; rp = rb_next(rp)) { | 60 | for (rp = rb_first(&mdsc->request_tree); rp; rp = rb_next(rp)) { |
61 | req = rb_entry(rp, struct ceph_mds_request, r_node); | 61 | req = rb_entry(rp, struct ceph_mds_request, r_node); |
62 | 62 | ||
63 | if (req->r_request) | 63 | if (req->r_request && req->r_session) |
64 | seq_printf(s, "%lld\tmds%d\t", req->r_tid, req->r_mds); | 64 | seq_printf(s, "%lld\tmds%d\t", req->r_tid, |
65 | else | 65 | req->r_session->s_mds); |
66 | else if (!req->r_request) | ||
66 | seq_printf(s, "%lld\t(no request)\t", req->r_tid); | 67 | seq_printf(s, "%lld\t(no request)\t", req->r_tid); |
68 | else | ||
69 | seq_printf(s, "%lld\t(no session)\t", req->r_tid); | ||
67 | 70 | ||
68 | seq_printf(s, "%s", ceph_mds_op_name(req->r_op)); | 71 | seq_printf(s, "%s", ceph_mds_op_name(req->r_op)); |
69 | 72 | ||
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index fa7ca04ee816..0bc68de8edd7 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -1224,6 +1224,26 @@ void ceph_dentry_lru_del(struct dentry *dn) | |||
1224 | } | 1224 | } |
1225 | } | 1225 | } |
1226 | 1226 | ||
1227 | /* | ||
1228 | * Return name hash for a given dentry. This is dependent on | ||
1229 | * the parent directory's hash function. | ||
1230 | */ | ||
1231 | unsigned ceph_dentry_hash(struct dentry *dn) | ||
1232 | { | ||
1233 | struct inode *dir = dn->d_parent->d_inode; | ||
1234 | struct ceph_inode_info *dci = ceph_inode(dir); | ||
1235 | |||
1236 | switch (dci->i_dir_layout.dl_dir_hash) { | ||
1237 | case 0: /* for backward compat */ | ||
1238 | case CEPH_STR_HASH_LINUX: | ||
1239 | return dn->d_name.hash; | ||
1240 | |||
1241 | default: | ||
1242 | return ceph_str_hash(dci->i_dir_layout.dl_dir_hash, | ||
1243 | dn->d_name.name, dn->d_name.len); | ||
1244 | } | ||
1245 | } | ||
1246 | |||
1227 | const struct file_operations ceph_dir_fops = { | 1247 | const struct file_operations ceph_dir_fops = { |
1228 | .read = ceph_read_dir, | 1248 | .read = ceph_read_dir, |
1229 | .readdir = ceph_readdir, | 1249 | .readdir = ceph_readdir, |
diff --git a/fs/ceph/export.c b/fs/ceph/export.c index 2297d9426992..e41056174bf8 100644 --- a/fs/ceph/export.c +++ b/fs/ceph/export.c | |||
@@ -59,7 +59,7 @@ static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len, | |||
59 | dout("encode_fh %p connectable\n", dentry); | 59 | dout("encode_fh %p connectable\n", dentry); |
60 | cfh->ino = ceph_ino(dentry->d_inode); | 60 | cfh->ino = ceph_ino(dentry->d_inode); |
61 | cfh->parent_ino = ceph_ino(parent->d_inode); | 61 | cfh->parent_ino = ceph_ino(parent->d_inode); |
62 | cfh->parent_name_hash = parent->d_name.hash; | 62 | cfh->parent_name_hash = ceph_dentry_hash(parent); |
63 | *max_len = connected_handle_length; | 63 | *max_len = connected_handle_length; |
64 | type = 2; | 64 | type = 2; |
65 | } else if (*max_len >= handle_length) { | 65 | } else if (*max_len >= handle_length) { |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index e61de4f7b99d..e835eff551e3 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -297,6 +297,8 @@ struct inode *ceph_alloc_inode(struct super_block *sb) | |||
297 | ci->i_release_count = 0; | 297 | ci->i_release_count = 0; |
298 | ci->i_symlink = NULL; | 298 | ci->i_symlink = NULL; |
299 | 299 | ||
300 | memset(&ci->i_dir_layout, 0, sizeof(ci->i_dir_layout)); | ||
301 | |||
300 | ci->i_fragtree = RB_ROOT; | 302 | ci->i_fragtree = RB_ROOT; |
301 | mutex_init(&ci->i_fragtree_mutex); | 303 | mutex_init(&ci->i_fragtree_mutex); |
302 | 304 | ||
@@ -689,6 +691,8 @@ static int fill_inode(struct inode *inode, | |||
689 | inode->i_op = &ceph_dir_iops; | 691 | inode->i_op = &ceph_dir_iops; |
690 | inode->i_fop = &ceph_dir_fops; | 692 | inode->i_fop = &ceph_dir_fops; |
691 | 693 | ||
694 | ci->i_dir_layout = iinfo->dir_layout; | ||
695 | |||
692 | ci->i_files = le64_to_cpu(info->files); | 696 | ci->i_files = le64_to_cpu(info->files); |
693 | ci->i_subdirs = le64_to_cpu(info->subdirs); | 697 | ci->i_subdirs = le64_to_cpu(info->subdirs); |
694 | ci->i_rbytes = le64_to_cpu(info->rbytes); | 698 | ci->i_rbytes = le64_to_cpu(info->rbytes); |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index a50fca1e03be..1e30d194a8e3 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -60,7 +60,8 @@ static const struct ceph_connection_operations mds_con_ops; | |||
60 | * parse individual inode info | 60 | * parse individual inode info |
61 | */ | 61 | */ |
62 | static int parse_reply_info_in(void **p, void *end, | 62 | static int parse_reply_info_in(void **p, void *end, |
63 | struct ceph_mds_reply_info_in *info) | 63 | struct ceph_mds_reply_info_in *info, |
64 | int features) | ||
64 | { | 65 | { |
65 | int err = -EIO; | 66 | int err = -EIO; |
66 | 67 | ||
@@ -74,6 +75,12 @@ static int parse_reply_info_in(void **p, void *end, | |||
74 | info->symlink = *p; | 75 | info->symlink = *p; |
75 | *p += info->symlink_len; | 76 | *p += info->symlink_len; |
76 | 77 | ||
78 | if (features & CEPH_FEATURE_DIRLAYOUTHASH) | ||
79 | ceph_decode_copy_safe(p, end, &info->dir_layout, | ||
80 | sizeof(info->dir_layout), bad); | ||
81 | else | ||
82 | memset(&info->dir_layout, 0, sizeof(info->dir_layout)); | ||
83 | |||
77 | ceph_decode_32_safe(p, end, info->xattr_len, bad); | 84 | ceph_decode_32_safe(p, end, info->xattr_len, bad); |
78 | ceph_decode_need(p, end, info->xattr_len, bad); | 85 | ceph_decode_need(p, end, info->xattr_len, bad); |
79 | info->xattr_data = *p; | 86 | info->xattr_data = *p; |
@@ -88,12 +95,13 @@ bad: | |||
88 | * target inode. | 95 | * target inode. |
89 | */ | 96 | */ |
90 | static int parse_reply_info_trace(void **p, void *end, | 97 | static int parse_reply_info_trace(void **p, void *end, |
91 | struct ceph_mds_reply_info_parsed *info) | 98 | struct ceph_mds_reply_info_parsed *info, |
99 | int features) | ||
92 | { | 100 | { |
93 | int err; | 101 | int err; |
94 | 102 | ||
95 | if (info->head->is_dentry) { | 103 | if (info->head->is_dentry) { |
96 | err = parse_reply_info_in(p, end, &info->diri); | 104 | err = parse_reply_info_in(p, end, &info->diri, features); |
97 | if (err < 0) | 105 | if (err < 0) |
98 | goto out_bad; | 106 | goto out_bad; |
99 | 107 | ||
@@ -114,7 +122,7 @@ static int parse_reply_info_trace(void **p, void *end, | |||
114 | } | 122 | } |
115 | 123 | ||
116 | if (info->head->is_target) { | 124 | if (info->head->is_target) { |
117 | err = parse_reply_info_in(p, end, &info->targeti); | 125 | err = parse_reply_info_in(p, end, &info->targeti, features); |
118 | if (err < 0) | 126 | if (err < 0) |
119 | goto out_bad; | 127 | goto out_bad; |
120 | } | 128 | } |
@@ -134,7 +142,8 @@ out_bad: | |||
134 | * parse readdir results | 142 | * parse readdir results |
135 | */ | 143 | */ |
136 | static int parse_reply_info_dir(void **p, void *end, | 144 | static int parse_reply_info_dir(void **p, void *end, |
137 | struct ceph_mds_reply_info_parsed *info) | 145 | struct ceph_mds_reply_info_parsed *info, |
146 | int features) | ||
138 | { | 147 | { |
139 | u32 num, i = 0; | 148 | u32 num, i = 0; |
140 | int err; | 149 | int err; |
@@ -182,7 +191,7 @@ static int parse_reply_info_dir(void **p, void *end, | |||
182 | *p += sizeof(struct ceph_mds_reply_lease); | 191 | *p += sizeof(struct ceph_mds_reply_lease); |
183 | 192 | ||
184 | /* inode */ | 193 | /* inode */ |
185 | err = parse_reply_info_in(p, end, &info->dir_in[i]); | 194 | err = parse_reply_info_in(p, end, &info->dir_in[i], features); |
186 | if (err < 0) | 195 | if (err < 0) |
187 | goto out_bad; | 196 | goto out_bad; |
188 | i++; | 197 | i++; |
@@ -205,7 +214,8 @@ out_bad: | |||
205 | * parse fcntl F_GETLK results | 214 | * parse fcntl F_GETLK results |
206 | */ | 215 | */ |
207 | static int parse_reply_info_filelock(void **p, void *end, | 216 | static int parse_reply_info_filelock(void **p, void *end, |
208 | struct ceph_mds_reply_info_parsed *info) | 217 | struct ceph_mds_reply_info_parsed *info, |
218 | int features) | ||
209 | { | 219 | { |
210 | if (*p + sizeof(*info->filelock_reply) > end) | 220 | if (*p + sizeof(*info->filelock_reply) > end) |
211 | goto bad; | 221 | goto bad; |
@@ -225,19 +235,21 @@ bad: | |||
225 | * parse extra results | 235 | * parse extra results |
226 | */ | 236 | */ |
227 | static int parse_reply_info_extra(void **p, void *end, | 237 | static int parse_reply_info_extra(void **p, void *end, |
228 | struct ceph_mds_reply_info_parsed *info) | 238 | struct ceph_mds_reply_info_parsed *info, |
239 | int features) | ||
229 | { | 240 | { |
230 | if (info->head->op == CEPH_MDS_OP_GETFILELOCK) | 241 | if (info->head->op == CEPH_MDS_OP_GETFILELOCK) |
231 | return parse_reply_info_filelock(p, end, info); | 242 | return parse_reply_info_filelock(p, end, info, features); |
232 | else | 243 | else |
233 | return parse_reply_info_dir(p, end, info); | 244 | return parse_reply_info_dir(p, end, info, features); |
234 | } | 245 | } |
235 | 246 | ||
236 | /* | 247 | /* |
237 | * parse entire mds reply | 248 | * parse entire mds reply |
238 | */ | 249 | */ |
239 | static int parse_reply_info(struct ceph_msg *msg, | 250 | static int parse_reply_info(struct ceph_msg *msg, |
240 | struct ceph_mds_reply_info_parsed *info) | 251 | struct ceph_mds_reply_info_parsed *info, |
252 | int features) | ||
241 | { | 253 | { |
242 | void *p, *end; | 254 | void *p, *end; |
243 | u32 len; | 255 | u32 len; |
@@ -250,7 +262,7 @@ static int parse_reply_info(struct ceph_msg *msg, | |||
250 | /* trace */ | 262 | /* trace */ |
251 | ceph_decode_32_safe(&p, end, len, bad); | 263 | ceph_decode_32_safe(&p, end, len, bad); |
252 | if (len > 0) { | 264 | if (len > 0) { |
253 | err = parse_reply_info_trace(&p, p+len, info); | 265 | err = parse_reply_info_trace(&p, p+len, info, features); |
254 | if (err < 0) | 266 | if (err < 0) |
255 | goto out_bad; | 267 | goto out_bad; |
256 | } | 268 | } |
@@ -258,7 +270,7 @@ static int parse_reply_info(struct ceph_msg *msg, | |||
258 | /* extra */ | 270 | /* extra */ |
259 | ceph_decode_32_safe(&p, end, len, bad); | 271 | ceph_decode_32_safe(&p, end, len, bad); |
260 | if (len > 0) { | 272 | if (len > 0) { |
261 | err = parse_reply_info_extra(&p, p+len, info); | 273 | err = parse_reply_info_extra(&p, p+len, info, features); |
262 | if (err < 0) | 274 | if (err < 0) |
263 | goto out_bad; | 275 | goto out_bad; |
264 | } | 276 | } |
@@ -654,7 +666,7 @@ static int __choose_mds(struct ceph_mds_client *mdsc, | |||
654 | } else { | 666 | } else { |
655 | /* dir + name */ | 667 | /* dir + name */ |
656 | inode = dir; | 668 | inode = dir; |
657 | hash = req->r_dentry->d_name.hash; | 669 | hash = ceph_dentry_hash(req->r_dentry); |
658 | is_hash = true; | 670 | is_hash = true; |
659 | } | 671 | } |
660 | } | 672 | } |
@@ -1693,7 +1705,6 @@ static int __prepare_send_request(struct ceph_mds_client *mdsc, | |||
1693 | struct ceph_msg *msg; | 1705 | struct ceph_msg *msg; |
1694 | int flags = 0; | 1706 | int flags = 0; |
1695 | 1707 | ||
1696 | req->r_mds = mds; | ||
1697 | req->r_attempts++; | 1708 | req->r_attempts++; |
1698 | if (req->r_inode) { | 1709 | if (req->r_inode) { |
1699 | struct ceph_cap *cap = | 1710 | struct ceph_cap *cap = |
@@ -1780,6 +1791,8 @@ static int __do_request(struct ceph_mds_client *mdsc, | |||
1780 | goto finish; | 1791 | goto finish; |
1781 | } | 1792 | } |
1782 | 1793 | ||
1794 | put_request_session(req); | ||
1795 | |||
1783 | mds = __choose_mds(mdsc, req); | 1796 | mds = __choose_mds(mdsc, req); |
1784 | if (mds < 0 || | 1797 | if (mds < 0 || |
1785 | ceph_mdsmap_get_state(mdsc->mdsmap, mds) < CEPH_MDS_STATE_ACTIVE) { | 1798 | ceph_mdsmap_get_state(mdsc->mdsmap, mds) < CEPH_MDS_STATE_ACTIVE) { |
@@ -1797,6 +1810,8 @@ static int __do_request(struct ceph_mds_client *mdsc, | |||
1797 | goto finish; | 1810 | goto finish; |
1798 | } | 1811 | } |
1799 | } | 1812 | } |
1813 | req->r_session = get_session(session); | ||
1814 | |||
1800 | dout("do_request mds%d session %p state %s\n", mds, session, | 1815 | dout("do_request mds%d session %p state %s\n", mds, session, |
1801 | session_state_name(session->s_state)); | 1816 | session_state_name(session->s_state)); |
1802 | if (session->s_state != CEPH_MDS_SESSION_OPEN && | 1817 | if (session->s_state != CEPH_MDS_SESSION_OPEN && |
@@ -1809,7 +1824,6 @@ static int __do_request(struct ceph_mds_client *mdsc, | |||
1809 | } | 1824 | } |
1810 | 1825 | ||
1811 | /* send request */ | 1826 | /* send request */ |
1812 | req->r_session = get_session(session); | ||
1813 | req->r_resend_mds = -1; /* forget any previous mds hint */ | 1827 | req->r_resend_mds = -1; /* forget any previous mds hint */ |
1814 | 1828 | ||
1815 | if (req->r_request_started == 0) /* note request start time */ | 1829 | if (req->r_request_started == 0) /* note request start time */ |
@@ -1863,7 +1877,6 @@ static void kick_requests(struct ceph_mds_client *mdsc, int mds) | |||
1863 | if (req->r_session && | 1877 | if (req->r_session && |
1864 | req->r_session->s_mds == mds) { | 1878 | req->r_session->s_mds == mds) { |
1865 | dout(" kicking tid %llu\n", req->r_tid); | 1879 | dout(" kicking tid %llu\n", req->r_tid); |
1866 | put_request_session(req); | ||
1867 | __do_request(mdsc, req); | 1880 | __do_request(mdsc, req); |
1868 | } | 1881 | } |
1869 | } | 1882 | } |
@@ -2056,8 +2069,11 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) | |||
2056 | goto out; | 2069 | goto out; |
2057 | } else { | 2070 | } else { |
2058 | struct ceph_inode_info *ci = ceph_inode(req->r_inode); | 2071 | struct ceph_inode_info *ci = ceph_inode(req->r_inode); |
2059 | struct ceph_cap *cap = | 2072 | struct ceph_cap *cap = NULL; |
2060 | ceph_get_cap_for_mds(ci, req->r_mds);; | 2073 | |
2074 | if (req->r_session) | ||
2075 | cap = ceph_get_cap_for_mds(ci, | ||
2076 | req->r_session->s_mds); | ||
2061 | 2077 | ||
2062 | dout("already using auth"); | 2078 | dout("already using auth"); |
2063 | if ((!cap || cap != ci->i_auth_cap) || | 2079 | if ((!cap || cap != ci->i_auth_cap) || |
@@ -2101,7 +2117,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) | |||
2101 | 2117 | ||
2102 | dout("handle_reply tid %lld result %d\n", tid, result); | 2118 | dout("handle_reply tid %lld result %d\n", tid, result); |
2103 | rinfo = &req->r_reply_info; | 2119 | rinfo = &req->r_reply_info; |
2104 | err = parse_reply_info(msg, rinfo); | 2120 | err = parse_reply_info(msg, rinfo, session->s_con.peer_features); |
2105 | mutex_unlock(&mdsc->mutex); | 2121 | mutex_unlock(&mdsc->mutex); |
2106 | 2122 | ||
2107 | mutex_lock(&session->s_mutex); | 2123 | mutex_lock(&session->s_mutex); |
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index aabe563b54db..4e3a9cc0bba6 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h | |||
@@ -35,6 +35,7 @@ struct ceph_cap; | |||
35 | */ | 35 | */ |
36 | struct ceph_mds_reply_info_in { | 36 | struct ceph_mds_reply_info_in { |
37 | struct ceph_mds_reply_inode *in; | 37 | struct ceph_mds_reply_inode *in; |
38 | struct ceph_dir_layout dir_layout; | ||
38 | u32 symlink_len; | 39 | u32 symlink_len; |
39 | char *symlink; | 40 | char *symlink; |
40 | u32 xattr_len; | 41 | u32 xattr_len; |
@@ -165,7 +166,6 @@ struct ceph_mds_request { | |||
165 | struct ceph_mds_client *r_mdsc; | 166 | struct ceph_mds_client *r_mdsc; |
166 | 167 | ||
167 | int r_op; /* mds op code */ | 168 | int r_op; /* mds op code */ |
168 | int r_mds; | ||
169 | 169 | ||
170 | /* operation on what? */ | 170 | /* operation on what? */ |
171 | struct inode *r_inode; /* arg1 */ | 171 | struct inode *r_inode; /* arg1 */ |
diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 08b460ae0539..bf6f0f34082a 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c | |||
@@ -428,7 +428,8 @@ struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt, | |||
428 | goto fail; | 428 | goto fail; |
429 | } | 429 | } |
430 | fsc->client->extra_mon_dispatch = extra_mon_dispatch; | 430 | fsc->client->extra_mon_dispatch = extra_mon_dispatch; |
431 | fsc->client->supported_features |= CEPH_FEATURE_FLOCK; | 431 | fsc->client->supported_features |= CEPH_FEATURE_FLOCK | |
432 | CEPH_FEATURE_DIRLAYOUTHASH; | ||
432 | fsc->client->monc.want_mdsmap = 1; | 433 | fsc->client->monc.want_mdsmap = 1; |
433 | 434 | ||
434 | fsc->mount_options = fsopt; | 435 | fsc->mount_options = fsopt; |
@@ -443,13 +444,17 @@ struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt, | |||
443 | goto fail_client; | 444 | goto fail_client; |
444 | 445 | ||
445 | err = -ENOMEM; | 446 | err = -ENOMEM; |
446 | fsc->wb_wq = create_workqueue("ceph-writeback"); | 447 | /* |
448 | * The number of concurrent works can be high but they don't need | ||
449 | * to be processed in parallel, limit concurrency. | ||
450 | */ | ||
451 | fsc->wb_wq = alloc_workqueue("ceph-writeback", 0, 1); | ||
447 | if (fsc->wb_wq == NULL) | 452 | if (fsc->wb_wq == NULL) |
448 | goto fail_bdi; | 453 | goto fail_bdi; |
449 | fsc->pg_inv_wq = create_singlethread_workqueue("ceph-pg-invalid"); | 454 | fsc->pg_inv_wq = alloc_workqueue("ceph-pg-invalid", 0, 1); |
450 | if (fsc->pg_inv_wq == NULL) | 455 | if (fsc->pg_inv_wq == NULL) |
451 | goto fail_wb_wq; | 456 | goto fail_wb_wq; |
452 | fsc->trunc_wq = create_singlethread_workqueue("ceph-trunc"); | 457 | fsc->trunc_wq = alloc_workqueue("ceph-trunc", 0, 1); |
453 | if (fsc->trunc_wq == NULL) | 458 | if (fsc->trunc_wq == NULL) |
454 | goto fail_pg_inv_wq; | 459 | goto fail_pg_inv_wq; |
455 | 460 | ||
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 4553d8829edb..20b907d76ae2 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -239,6 +239,7 @@ struct ceph_inode_info { | |||
239 | unsigned i_ceph_flags; | 239 | unsigned i_ceph_flags; |
240 | unsigned long i_release_count; | 240 | unsigned long i_release_count; |
241 | 241 | ||
242 | struct ceph_dir_layout i_dir_layout; | ||
242 | struct ceph_file_layout i_layout; | 243 | struct ceph_file_layout i_layout; |
243 | char *i_symlink; | 244 | char *i_symlink; |
244 | 245 | ||
@@ -768,6 +769,7 @@ extern void ceph_dentry_lru_add(struct dentry *dn); | |||
768 | extern void ceph_dentry_lru_touch(struct dentry *dn); | 769 | extern void ceph_dentry_lru_touch(struct dentry *dn); |
769 | extern void ceph_dentry_lru_del(struct dentry *dn); | 770 | extern void ceph_dentry_lru_del(struct dentry *dn); |
770 | extern void ceph_invalidate_dentry_lease(struct dentry *dentry); | 771 | extern void ceph_invalidate_dentry_lease(struct dentry *dentry); |
772 | extern unsigned ceph_dentry_hash(struct dentry *dn); | ||
771 | 773 | ||
772 | /* | 774 | /* |
773 | * our d_ops vary depending on whether the inode is live, | 775 | * our d_ops vary depending on whether the inode is live, |