aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-05-17 16:52:26 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-06-29 04:56:41 -0400
commit77acfa29e10cc859cc165963093a83f754598b03 (patch)
tree1b72a5d24a8b4de1be2522532d0fa46a0c1e34b0 /fs/ceph
parent23db862060e05e52363aa872c50e518db9c94f6d (diff)
[readdir] convert ceph
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/dir.c99
1 files changed, 48 insertions, 51 deletions
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index f02d82b7933e..a40ceda47a32 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -111,11 +111,10 @@ static unsigned fpos_off(loff_t p)
111 * defined IFF we hold CEPH_CAP_FILE_SHARED (which will be revoked by 111 * defined IFF we hold CEPH_CAP_FILE_SHARED (which will be revoked by
112 * the MDS if/when the directory is modified). 112 * the MDS if/when the directory is modified).
113 */ 113 */
114static int __dcache_readdir(struct file *filp, 114static int __dcache_readdir(struct file *file, struct dir_context *ctx)
115 void *dirent, filldir_t filldir)
116{ 115{
117 struct ceph_file_info *fi = filp->private_data; 116 struct ceph_file_info *fi = file->private_data;
118 struct dentry *parent = filp->f_dentry; 117 struct dentry *parent = file->f_dentry;
119 struct inode *dir = parent->d_inode; 118 struct inode *dir = parent->d_inode;
120 struct list_head *p; 119 struct list_head *p;
121 struct dentry *dentry, *last; 120 struct dentry *dentry, *last;
@@ -126,14 +125,14 @@ static int __dcache_readdir(struct file *filp,
126 last = fi->dentry; 125 last = fi->dentry;
127 fi->dentry = NULL; 126 fi->dentry = NULL;
128 127
129 dout("__dcache_readdir %p at %llu (last %p)\n", dir, filp->f_pos, 128 dout("__dcache_readdir %p at %llu (last %p)\n", dir, ctx->pos,
130 last); 129 last);
131 130
132 spin_lock(&parent->d_lock); 131 spin_lock(&parent->d_lock);
133 132
134 /* start at beginning? */ 133 /* start at beginning? */
135 if (filp->f_pos == 2 || last == NULL || 134 if (ctx->pos == 2 || last == NULL ||
136 filp->f_pos < ceph_dentry(last)->offset) { 135 ctx->pos < ceph_dentry(last)->offset) {
137 if (list_empty(&parent->d_subdirs)) 136 if (list_empty(&parent->d_subdirs))
138 goto out_unlock; 137 goto out_unlock;
139 p = parent->d_subdirs.prev; 138 p = parent->d_subdirs.prev;
@@ -157,11 +156,11 @@ more:
157 if (!d_unhashed(dentry) && dentry->d_inode && 156 if (!d_unhashed(dentry) && dentry->d_inode &&
158 ceph_snap(dentry->d_inode) != CEPH_SNAPDIR && 157 ceph_snap(dentry->d_inode) != CEPH_SNAPDIR &&
159 ceph_ino(dentry->d_inode) != CEPH_INO_CEPH && 158 ceph_ino(dentry->d_inode) != CEPH_INO_CEPH &&
160 filp->f_pos <= di->offset) 159 ctx->pos <= di->offset)
161 break; 160 break;
162 dout(" skipping %p %.*s at %llu (%llu)%s%s\n", dentry, 161 dout(" skipping %p %.*s at %llu (%llu)%s%s\n", dentry,
163 dentry->d_name.len, dentry->d_name.name, di->offset, 162 dentry->d_name.len, dentry->d_name.name, di->offset,
164 filp->f_pos, d_unhashed(dentry) ? " unhashed" : "", 163 ctx->pos, d_unhashed(dentry) ? " unhashed" : "",
165 !dentry->d_inode ? " null" : ""); 164 !dentry->d_inode ? " null" : "");
166 spin_unlock(&dentry->d_lock); 165 spin_unlock(&dentry->d_lock);
167 p = p->prev; 166 p = p->prev;
@@ -173,29 +172,27 @@ more:
173 spin_unlock(&dentry->d_lock); 172 spin_unlock(&dentry->d_lock);
174 spin_unlock(&parent->d_lock); 173 spin_unlock(&parent->d_lock);
175 174
176 dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, filp->f_pos, 175 dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, ctx->pos,
177 dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode); 176 dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode);
178 filp->f_pos = di->offset; 177 ctx->pos = di->offset;
179 err = filldir(dirent, dentry->d_name.name, 178 if (!dir_emit(ctx, dentry->d_name.name,
180 dentry->d_name.len, di->offset, 179 dentry->d_name.len,
181 ceph_translate_ino(dentry->d_sb, dentry->d_inode->i_ino), 180 ceph_translate_ino(dentry->d_sb, dentry->d_inode->i_ino),
182 dentry->d_inode->i_mode >> 12); 181 dentry->d_inode->i_mode >> 12)) {
183 182 if (last) {
184 if (last) {
185 if (err < 0) {
186 /* remember our position */ 183 /* remember our position */
187 fi->dentry = last; 184 fi->dentry = last;
188 fi->next_offset = di->offset; 185 fi->next_offset = di->offset;
189 } else {
190 dput(last);
191 } 186 }
187 dput(dentry);
188 return 0;
192 } 189 }
193 last = dentry;
194 190
195 if (err < 0) 191 if (last)
196 goto out; 192 dput(last);
193 last = dentry;
197 194
198 filp->f_pos++; 195 ctx->pos++;
199 196
200 /* make sure a dentry wasn't dropped while we didn't have parent lock */ 197 /* make sure a dentry wasn't dropped while we didn't have parent lock */
201 if (!ceph_dir_is_complete(dir)) { 198 if (!ceph_dir_is_complete(dir)) {
@@ -235,59 +232,59 @@ static int note_last_dentry(struct ceph_file_info *fi, const char *name,
235 return 0; 232 return 0;
236} 233}
237 234
238static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir) 235static int ceph_readdir(struct file *file, struct dir_context *ctx)
239{ 236{
240 struct ceph_file_info *fi = filp->private_data; 237 struct ceph_file_info *fi = file->private_data;
241 struct inode *inode = file_inode(filp); 238 struct inode *inode = file_inode(file);
242 struct ceph_inode_info *ci = ceph_inode(inode); 239 struct ceph_inode_info *ci = ceph_inode(inode);
243 struct ceph_fs_client *fsc = ceph_inode_to_client(inode); 240 struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
244 struct ceph_mds_client *mdsc = fsc->mdsc; 241 struct ceph_mds_client *mdsc = fsc->mdsc;
245 unsigned frag = fpos_frag(filp->f_pos); 242 unsigned frag = fpos_frag(ctx->pos);
246 int off = fpos_off(filp->f_pos); 243 int off = fpos_off(ctx->pos);
247 int err; 244 int err;
248 u32 ftype; 245 u32 ftype;
249 struct ceph_mds_reply_info_parsed *rinfo; 246 struct ceph_mds_reply_info_parsed *rinfo;
250 const int max_entries = fsc->mount_options->max_readdir; 247 const int max_entries = fsc->mount_options->max_readdir;
251 const int max_bytes = fsc->mount_options->max_readdir_bytes; 248 const int max_bytes = fsc->mount_options->max_readdir_bytes;
252 249
253 dout("readdir %p filp %p frag %u off %u\n", inode, filp, frag, off); 250 dout("readdir %p file %p frag %u off %u\n", inode, file, frag, off);
254 if (fi->flags & CEPH_F_ATEND) 251 if (fi->flags & CEPH_F_ATEND)
255 return 0; 252 return 0;
256 253
257 /* always start with . and .. */ 254 /* always start with . and .. */
258 if (filp->f_pos == 0) { 255 if (ctx->pos == 0) {
259 /* note dir version at start of readdir so we can tell 256 /* note dir version at start of readdir so we can tell
260 * if any dentries get dropped */ 257 * if any dentries get dropped */
261 fi->dir_release_count = atomic_read(&ci->i_release_count); 258 fi->dir_release_count = atomic_read(&ci->i_release_count);
262 259
263 dout("readdir off 0 -> '.'\n"); 260 dout("readdir off 0 -> '.'\n");
264 if (filldir(dirent, ".", 1, ceph_make_fpos(0, 0), 261 if (!dir_emit(ctx, ".", 1,
265 ceph_translate_ino(inode->i_sb, inode->i_ino), 262 ceph_translate_ino(inode->i_sb, inode->i_ino),
266 inode->i_mode >> 12) < 0) 263 inode->i_mode >> 12))
267 return 0; 264 return 0;
268 filp->f_pos = 1; 265 ctx->pos = 1;
269 off = 1; 266 off = 1;
270 } 267 }
271 if (filp->f_pos == 1) { 268 if (ctx->pos == 1) {
272 ino_t ino = parent_ino(filp->f_dentry); 269 ino_t ino = parent_ino(file->f_dentry);
273 dout("readdir off 1 -> '..'\n"); 270 dout("readdir off 1 -> '..'\n");
274 if (filldir(dirent, "..", 2, ceph_make_fpos(0, 1), 271 if (!dir_emit(ctx, "..", 2,
275 ceph_translate_ino(inode->i_sb, ino), 272 ceph_translate_ino(inode->i_sb, ino),
276 inode->i_mode >> 12) < 0) 273 inode->i_mode >> 12))
277 return 0; 274 return 0;
278 filp->f_pos = 2; 275 ctx->pos = 2;
279 off = 2; 276 off = 2;
280 } 277 }
281 278
282 /* can we use the dcache? */ 279 /* can we use the dcache? */
283 spin_lock(&ci->i_ceph_lock); 280 spin_lock(&ci->i_ceph_lock);
284 if ((filp->f_pos == 2 || fi->dentry) && 281 if ((ctx->pos == 2 || fi->dentry) &&
285 !ceph_test_mount_opt(fsc, NOASYNCREADDIR) && 282 !ceph_test_mount_opt(fsc, NOASYNCREADDIR) &&
286 ceph_snap(inode) != CEPH_SNAPDIR && 283 ceph_snap(inode) != CEPH_SNAPDIR &&
287 __ceph_dir_is_complete(ci) && 284 __ceph_dir_is_complete(ci) &&
288 __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) { 285 __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) {
289 spin_unlock(&ci->i_ceph_lock); 286 spin_unlock(&ci->i_ceph_lock);
290 err = __dcache_readdir(filp, dirent, filldir); 287 err = __dcache_readdir(file, ctx);
291 if (err != -EAGAIN) 288 if (err != -EAGAIN)
292 return err; 289 return err;
293 } else { 290 } else {
@@ -327,7 +324,7 @@ more:
327 return PTR_ERR(req); 324 return PTR_ERR(req);
328 req->r_inode = inode; 325 req->r_inode = inode;
329 ihold(inode); 326 ihold(inode);
330 req->r_dentry = dget(filp->f_dentry); 327 req->r_dentry = dget(file->f_dentry);
331 /* hints to request -> mds selection code */ 328 /* hints to request -> mds selection code */
332 req->r_direct_mode = USE_AUTH_MDS; 329 req->r_direct_mode = USE_AUTH_MDS;
333 req->r_direct_hash = ceph_frag_value(frag); 330 req->r_direct_hash = ceph_frag_value(frag);
@@ -379,15 +376,16 @@ more:
379 rinfo = &fi->last_readdir->r_reply_info; 376 rinfo = &fi->last_readdir->r_reply_info;
380 dout("readdir frag %x num %d off %d chunkoff %d\n", frag, 377 dout("readdir frag %x num %d off %d chunkoff %d\n", frag,
381 rinfo->dir_nr, off, fi->offset); 378 rinfo->dir_nr, off, fi->offset);
379
380 ctx->pos = ceph_make_fpos(frag, off);
382 while (off >= fi->offset && off - fi->offset < rinfo->dir_nr) { 381 while (off >= fi->offset && off - fi->offset < rinfo->dir_nr) {
383 u64 pos = ceph_make_fpos(frag, off);
384 struct ceph_mds_reply_inode *in = 382 struct ceph_mds_reply_inode *in =
385 rinfo->dir_in[off - fi->offset].in; 383 rinfo->dir_in[off - fi->offset].in;
386 struct ceph_vino vino; 384 struct ceph_vino vino;
387 ino_t ino; 385 ino_t ino;
388 386
389 dout("readdir off %d (%d/%d) -> %lld '%.*s' %p\n", 387 dout("readdir off %d (%d/%d) -> %lld '%.*s' %p\n",
390 off, off - fi->offset, rinfo->dir_nr, pos, 388 off, off - fi->offset, rinfo->dir_nr, ctx->pos,
391 rinfo->dir_dname_len[off - fi->offset], 389 rinfo->dir_dname_len[off - fi->offset],
392 rinfo->dir_dname[off - fi->offset], in); 390 rinfo->dir_dname[off - fi->offset], in);
393 BUG_ON(!in); 391 BUG_ON(!in);
@@ -395,16 +393,15 @@ more:
395 vino.ino = le64_to_cpu(in->ino); 393 vino.ino = le64_to_cpu(in->ino);
396 vino.snap = le64_to_cpu(in->snapid); 394 vino.snap = le64_to_cpu(in->snapid);
397 ino = ceph_vino_to_ino(vino); 395 ino = ceph_vino_to_ino(vino);
398 if (filldir(dirent, 396 if (!dir_emit(ctx,
399 rinfo->dir_dname[off - fi->offset], 397 rinfo->dir_dname[off - fi->offset],
400 rinfo->dir_dname_len[off - fi->offset], 398 rinfo->dir_dname_len[off - fi->offset],
401 pos, 399 ceph_translate_ino(inode->i_sb, ino), ftype)) {
402 ceph_translate_ino(inode->i_sb, ino), ftype) < 0) {
403 dout("filldir stopping us...\n"); 400 dout("filldir stopping us...\n");
404 return 0; 401 return 0;
405 } 402 }
406 off++; 403 off++;
407 filp->f_pos = pos + 1; 404 ctx->pos++;
408 } 405 }
409 406
410 if (fi->last_name) { 407 if (fi->last_name) {
@@ -417,7 +414,7 @@ more:
417 if (!ceph_frag_is_rightmost(frag)) { 414 if (!ceph_frag_is_rightmost(frag)) {
418 frag = ceph_frag_next(frag); 415 frag = ceph_frag_next(frag);
419 off = 0; 416 off = 0;
420 filp->f_pos = ceph_make_fpos(frag, off); 417 ctx->pos = ceph_make_fpos(frag, off);
421 dout("readdir next frag is %x\n", frag); 418 dout("readdir next frag is %x\n", frag);
422 goto more; 419 goto more;
423 } 420 }
@@ -432,11 +429,11 @@ more:
432 if (atomic_read(&ci->i_release_count) == fi->dir_release_count) { 429 if (atomic_read(&ci->i_release_count) == fi->dir_release_count) {
433 dout(" marking %p complete\n", inode); 430 dout(" marking %p complete\n", inode);
434 __ceph_dir_set_complete(ci, fi->dir_release_count); 431 __ceph_dir_set_complete(ci, fi->dir_release_count);
435 ci->i_max_offset = filp->f_pos; 432 ci->i_max_offset = ctx->pos;
436 } 433 }
437 spin_unlock(&ci->i_ceph_lock); 434 spin_unlock(&ci->i_ceph_lock);
438 435
439 dout("readdir %p filp %p done.\n", inode, filp); 436 dout("readdir %p file %p done.\n", inode, file);
440 return 0; 437 return 0;
441} 438}
442 439
@@ -1268,7 +1265,7 @@ unsigned ceph_dentry_hash(struct inode *dir, struct dentry *dn)
1268 1265
1269const struct file_operations ceph_dir_fops = { 1266const struct file_operations ceph_dir_fops = {
1270 .read = ceph_read_dir, 1267 .read = ceph_read_dir,
1271 .readdir = ceph_readdir, 1268 .iterate = ceph_readdir,
1272 .llseek = ceph_dir_llseek, 1269 .llseek = ceph_dir_llseek,
1273 .open = ceph_open, 1270 .open = ceph_open,
1274 .release = ceph_release, 1271 .release = ceph_release,