aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c90
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h8
-rw-r--r--fs/xfs/xfs_dir2.c121
-rw-r--r--fs/xfs/xfs_dir2.h19
-rw-r--r--fs/xfs/xfs_dir2_block.c63
-rw-r--r--fs/xfs/xfs_dir2_block.h5
-rw-r--r--fs/xfs/xfs_dir2_leaf.c76
-rw-r--r--fs/xfs/xfs_dir2_leaf.h6
-rw-r--r--fs/xfs/xfs_dir2_sf.c121
-rw-r--r--fs/xfs/xfs_dir2_sf.h5
-rw-r--r--fs/xfs/xfs_types.h12
-rw-r--r--fs/xfs/xfs_vnodeops.c31
12 files changed, 151 insertions, 406 deletions
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 4fc0f58edacf..3678f6912d04 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -233,74 +233,30 @@ xfs_file_readdir(
233 void *dirent, 233 void *dirent,
234 filldir_t filldir) 234 filldir_t filldir)
235{ 235{
236 int error = 0; 236 struct inode *inode = filp->f_path.dentry->d_inode;
237 bhv_vnode_t *vp = vn_from_inode(filp->f_path.dentry->d_inode); 237 bhv_vnode_t *vp = vn_from_inode(inode);
238 uio_t uio; 238 int error;
239 iovec_t iov; 239 size_t bufsize;
240 int eof = 0; 240
241 caddr_t read_buf; 241 /*
242 int namelen, size = 0; 242 * The Linux API doesn't pass down the total size of the buffer
243 size_t rlen = PAGE_CACHE_SIZE; 243 * we read into down to the filesystem. With the filldir concept
244 xfs_off_t start_offset, curr_offset; 244 * it's not needed for correct information, but the XFS dir2 leaf
245 xfs_dirent_t *dbp = NULL; 245 * code wants an estimate of the buffer size to calculate it's
246 246 * readahead window and size the buffers used for mapping to
247 /* Try fairly hard to get memory */ 247 * physical blocks.
248 do { 248 *
249 if ((read_buf = kmalloc(rlen, GFP_KERNEL))) 249 * Try to give it an estimate that's good enough, maybe at some
250 break; 250 * point we can change the ->readdir prototype to include the
251 rlen >>= 1; 251 * buffer size.
252 } while (rlen >= 1024); 252 */
253 253 bufsize = (size_t)min_t(loff_t, PAGE_SIZE, inode->i_size);
254 if (read_buf == NULL)
255 return -ENOMEM;
256
257 uio.uio_iov = &iov;
258 uio.uio_segflg = UIO_SYSSPACE;
259 curr_offset = filp->f_pos;
260 if (filp->f_pos != 0x7fffffff)
261 uio.uio_offset = filp->f_pos;
262 else
263 uio.uio_offset = 0xffffffff;
264
265 while (!eof) {
266 uio.uio_resid = iov.iov_len = rlen;
267 iov.iov_base = read_buf;
268 uio.uio_iovcnt = 1;
269
270 start_offset = uio.uio_offset;
271
272 error = bhv_vop_readdir(vp, &uio, NULL, &eof);
273 if ((uio.uio_offset == start_offset) || error) {
274 size = 0;
275 break;
276 }
277
278 size = rlen - uio.uio_resid;
279 dbp = (xfs_dirent_t *)read_buf;
280 while (size > 0) {
281 namelen = strlen(dbp->d_name);
282
283 if (filldir(dirent, dbp->d_name, namelen,
284 (loff_t) curr_offset & 0x7fffffff,
285 (ino_t) dbp->d_ino,
286 DT_UNKNOWN)) {
287 goto done;
288 }
289 size -= dbp->d_reclen;
290 curr_offset = (loff_t)dbp->d_off /* & 0x7fffffff */;
291 dbp = (xfs_dirent_t *)((char *)dbp + dbp->d_reclen);
292 }
293 }
294done:
295 if (!error) {
296 if (size == 0)
297 filp->f_pos = uio.uio_offset & 0x7fffffff;
298 else if (dbp)
299 filp->f_pos = curr_offset;
300 }
301 254
302 kfree(read_buf); 255 error = bhv_vop_readdir(vp, dirent, bufsize,
303 return -error; 256 (xfs_off_t *)&filp->f_pos, filldir);
257 if (error)
258 return -error;
259 return 0;
304} 260}
305 261
306STATIC int 262STATIC int
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index 5742d65f0785..146c84ba6941 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -161,8 +161,8 @@ typedef int (*vop_rename_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t *,
161typedef int (*vop_mkdir_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *, 161typedef int (*vop_mkdir_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *,
162 bhv_vnode_t **, struct cred *); 162 bhv_vnode_t **, struct cred *);
163typedef int (*vop_rmdir_t)(bhv_desc_t *, bhv_vname_t *, struct cred *); 163typedef int (*vop_rmdir_t)(bhv_desc_t *, bhv_vname_t *, struct cred *);
164typedef int (*vop_readdir_t)(bhv_desc_t *, struct uio *, struct cred *, 164typedef int (*vop_readdir_t)(bhv_desc_t *, void *dirent, size_t bufsize,
165 int *); 165 xfs_off_t *offset, filldir_t filldir);
166typedef int (*vop_symlink_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr*, 166typedef int (*vop_symlink_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr*,
167 char *, bhv_vnode_t **, struct cred *); 167 char *, bhv_vnode_t **, struct cred *);
168typedef int (*vop_readlink_t)(bhv_desc_t *, struct uio *, int, 168typedef int (*vop_readlink_t)(bhv_desc_t *, struct uio *, int,
@@ -267,8 +267,8 @@ typedef struct bhv_vnodeops {
267#define bhv_vop_mkdir(dp,d,vap,vpp,cr) \ 267#define bhv_vop_mkdir(dp,d,vap,vpp,cr) \
268 VOP(vop_mkdir, dp)(VNHEAD(dp),d,vap,vpp,cr) 268 VOP(vop_mkdir, dp)(VNHEAD(dp),d,vap,vpp,cr)
269#define bhv_vop_rmdir(dp,d,cr) VOP(vop_rmdir, dp)(VNHEAD(dp),d,cr) 269#define bhv_vop_rmdir(dp,d,cr) VOP(vop_rmdir, dp)(VNHEAD(dp),d,cr)
270#define bhv_vop_readdir(vp,uiop,cr,eofp) \ 270#define bhv_vop_readdir(vp,dirent,bufsize,offset,filldir) \
271 VOP(vop_readdir, vp)(VNHEAD(vp),uiop,cr,eofp) 271 VOP(vop_readdir, vp)(VNHEAD(vp),dirent,bufsize,offset,filldir)
272#define bhv_vop_symlink(dvp,d,vap,tnm,vpp,cr) \ 272#define bhv_vop_symlink(dvp,d,vap,tnm,vpp,cr) \
273 VOP(vop_symlink, dvp)(VNHEAD(dvp),d,vap,tnm,vpp,cr) 273 VOP(vop_symlink, dvp)(VNHEAD(dvp),d,vap,tnm,vpp,cr)
274#define bhv_vop_readlink(vp,uiop,fl,cr) \ 274#define bhv_vop_readlink(vp,uiop,fl,cr) \
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c
index 29e091914df4..c2d2bef26cbd 100644
--- a/fs/xfs/xfs_dir2.c
+++ b/fs/xfs/xfs_dir2.c
@@ -43,8 +43,6 @@
43#include "xfs_dir2_trace.h" 43#include "xfs_dir2_trace.h"
44#include "xfs_error.h" 44#include "xfs_error.h"
45 45
46static int xfs_dir2_put_dirent64_direct(xfs_dir2_put_args_t *pa);
47static int xfs_dir2_put_dirent64_uio(xfs_dir2_put_args_t *pa);
48 46
49void 47void
50xfs_dir_mount( 48xfs_dir_mount(
@@ -293,47 +291,35 @@ xfs_dir_removename(
293 * Read a directory. 291 * Read a directory.
294 */ 292 */
295int 293int
296xfs_dir_getdents( 294xfs_readdir(
297 xfs_trans_t *tp, 295 bhv_desc_t *dir_bdp,
298 xfs_inode_t *dp, 296 void *dirent,
299 uio_t *uio, /* caller's buffer control */ 297 size_t bufsize,
300 int *eofp) /* out: eof reached */ 298 xfs_off_t *offset,
299 filldir_t filldir)
301{ 300{
302 int alignment; /* alignment required for ABI */ 301 xfs_inode_t *dp = XFS_BHVTOI(dir_bdp);
303 xfs_dirent_t *dbp; /* malloc'ed buffer */
304 xfs_dir2_put_t put; /* entry formatting routine */
305 int rval; /* return value */ 302 int rval; /* return value */
306 int v; /* type-checking value */ 303 int v; /* type-checking value */
307 304
305 vn_trace_entry(BHV_TO_VNODE(dir_bdp), __FUNCTION__,
306 (inst_t *)__return_address);
307
308 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
309 return XFS_ERROR(EIO);
310
308 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 311 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
309 XFS_STATS_INC(xs_dir_getdents); 312 XFS_STATS_INC(xs_dir_getdents);
310 /*
311 * If our caller has given us a single contiguous aligned memory buffer,
312 * just work directly within that buffer. If it's in user memory,
313 * lock it down first.
314 */
315 alignment = sizeof(xfs_off_t) - 1;
316 if ((uio->uio_iovcnt == 1) &&
317 (((__psint_t)uio->uio_iov[0].iov_base & alignment) == 0) &&
318 ((uio->uio_iov[0].iov_len & alignment) == 0)) {
319 dbp = NULL;
320 put = xfs_dir2_put_dirent64_direct;
321 } else {
322 dbp = kmem_alloc(sizeof(*dbp) + MAXNAMELEN, KM_SLEEP);
323 put = xfs_dir2_put_dirent64_uio;
324 }
325 313
326 *eofp = 0;
327 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 314 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
328 rval = xfs_dir2_sf_getdents(dp, uio, eofp, dbp, put); 315 rval = xfs_dir2_sf_getdents(dp, dirent, offset, filldir);
329 else if ((rval = xfs_dir2_isblock(tp, dp, &v))) 316 else if ((rval = xfs_dir2_isblock(NULL, dp, &v)))
330 ; 317 ;
331 else if (v) 318 else if (v)
332 rval = xfs_dir2_block_getdents(tp, dp, uio, eofp, dbp, put); 319 rval = xfs_dir2_block_getdents(dp, dirent, offset, filldir);
333 else 320 else
334 rval = xfs_dir2_leaf_getdents(tp, dp, uio, eofp, dbp, put); 321 rval = xfs_dir2_leaf_getdents(dp, dirent, bufsize, offset,
335 if (dbp != NULL) 322 filldir);
336 kmem_free(dbp, sizeof(*dbp) + MAXNAMELEN);
337 return rval; 323 return rval;
338} 324}
339 325
@@ -613,77 +599,6 @@ xfs_dir2_isleaf(
613} 599}
614 600
615/* 601/*
616 * Getdents put routine for 64-bit ABI, direct form.
617 */
618static int
619xfs_dir2_put_dirent64_direct(
620 xfs_dir2_put_args_t *pa)
621{
622 xfs_dirent_t *idbp; /* dirent pointer */
623 iovec_t *iovp; /* io vector */
624 int namelen; /* entry name length */
625 int reclen; /* entry total length */
626 uio_t *uio; /* I/O control */
627
628 namelen = pa->namelen;
629 reclen = DIRENTSIZE(namelen);
630 uio = pa->uio;
631 /*
632 * Won't fit in the remaining space.
633 */
634 if (reclen > uio->uio_resid) {
635 pa->done = 0;
636 return 0;
637 }
638 iovp = uio->uio_iov;
639 idbp = (xfs_dirent_t *)iovp->iov_base;
640 iovp->iov_base = (char *)idbp + reclen;
641 iovp->iov_len -= reclen;
642 uio->uio_resid -= reclen;
643 idbp->d_reclen = reclen;
644 idbp->d_ino = pa->ino;
645 idbp->d_off = pa->cook;
646 idbp->d_name[namelen] = '\0';
647 pa->done = 1;
648 memcpy(idbp->d_name, pa->name, namelen);
649 return 0;
650}
651
652/*
653 * Getdents put routine for 64-bit ABI, uio form.
654 */
655static int
656xfs_dir2_put_dirent64_uio(
657 xfs_dir2_put_args_t *pa)
658{
659 xfs_dirent_t *idbp; /* dirent pointer */
660 int namelen; /* entry name length */
661 int reclen; /* entry total length */
662 int rval; /* return value */
663 uio_t *uio; /* I/O control */
664
665 namelen = pa->namelen;
666 reclen = DIRENTSIZE(namelen);
667 uio = pa->uio;
668 /*
669 * Won't fit in the remaining space.
670 */
671 if (reclen > uio->uio_resid) {
672 pa->done = 0;
673 return 0;
674 }
675 idbp = pa->dbp;
676 idbp->d_reclen = reclen;
677 idbp->d_ino = pa->ino;
678 idbp->d_off = pa->cook;
679 idbp->d_name[namelen] = '\0';
680 memcpy(idbp->d_name, pa->name, namelen);
681 rval = xfs_uio_read((caddr_t)idbp, reclen, uio);
682 pa->done = (rval == 0);
683 return rval;
684}
685
686/*
687 * Remove the given block from the directory. 602 * Remove the given block from the directory.
688 * This routine is used for data and free blocks, leaf/node are done 603 * This routine is used for data and free blocks, leaf/node are done
689 * by xfs_da_shrink_inode. 604 * by xfs_da_shrink_inode.
diff --git a/fs/xfs/xfs_dir2.h b/fs/xfs/xfs_dir2.h
index 86560b6f794c..fa5a533a3427 100644
--- a/fs/xfs/xfs_dir2.h
+++ b/fs/xfs/xfs_dir2.h
@@ -60,21 +60,6 @@ typedef __uint32_t xfs_dir2_db_t;
60typedef xfs_off_t xfs_dir2_off_t; 60typedef xfs_off_t xfs_dir2_off_t;
61 61
62/* 62/*
63 * For getdents, argument struct for put routines.
64 */
65typedef int (*xfs_dir2_put_t)(struct xfs_dir2_put_args *pa);
66typedef struct xfs_dir2_put_args {
67 xfs_off_t cook; /* cookie of (next) entry */
68 xfs_intino_t ino; /* inode number */
69 xfs_dirent_t *dbp; /* buffer pointer */
70 char *name; /* directory entry name */
71 int namelen; /* length of name */
72 int done; /* output: set if value was stored */
73 xfs_dir2_put_t put; /* put function ptr (i/o) */
74 struct uio *uio; /* uio control structure */
75} xfs_dir2_put_args_t;
76
77/*
78 * Generic directory interface routines 63 * Generic directory interface routines
79 */ 64 */
80extern void xfs_dir_startup(void); 65extern void xfs_dir_startup(void);
@@ -92,8 +77,6 @@ extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp,
92 char *name, int namelen, xfs_ino_t ino, 77 char *name, int namelen, xfs_ino_t ino,
93 xfs_fsblock_t *first, 78 xfs_fsblock_t *first,
94 struct xfs_bmap_free *flist, xfs_extlen_t tot); 79 struct xfs_bmap_free *flist, xfs_extlen_t tot);
95extern int xfs_dir_getdents(struct xfs_trans *tp, struct xfs_inode *dp,
96 uio_t *uio, int *eofp);
97extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp, 80extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp,
98 char *name, int namelen, xfs_ino_t inum, 81 char *name, int namelen, xfs_ino_t inum,
99 xfs_fsblock_t *first, 82 xfs_fsblock_t *first,
@@ -101,6 +84,8 @@ extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp,
101extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp, 84extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp,
102 char *name, int namelen); 85 char *name, int namelen);
103extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino); 86extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
87extern int xfs_readdir(bhv_desc_t *dir_bdp, void *dirent, size_t bufsize,
88 xfs_off_t *offset, filldir_t filldir);
104 89
105/* 90/*
106 * Utility routines for v2 directories. 91 * Utility routines for v2 directories.
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index e4df1aaae2a2..f6b919af7b82 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -432,12 +432,10 @@ xfs_dir2_block_addname(
432 */ 432 */
433int /* error */ 433int /* error */
434xfs_dir2_block_getdents( 434xfs_dir2_block_getdents(
435 xfs_trans_t *tp, /* transaction (NULL) */
436 xfs_inode_t *dp, /* incore inode */ 435 xfs_inode_t *dp, /* incore inode */
437 uio_t *uio, /* caller's buffer control */ 436 void *dirent,
438 int *eofp, /* eof reached? (out) */ 437 xfs_off_t *offset,
439 xfs_dirent_t *dbp, /* caller's buffer */ 438 filldir_t filldir)
440 xfs_dir2_put_t put) /* abi's formatting function */
441{ 439{
442 xfs_dir2_block_t *block; /* directory block structure */ 440 xfs_dir2_block_t *block; /* directory block structure */
443 xfs_dabuf_t *bp; /* buffer for block */ 441 xfs_dabuf_t *bp; /* buffer for block */
@@ -447,31 +445,32 @@ xfs_dir2_block_getdents(
447 char *endptr; /* end of the data entries */ 445 char *endptr; /* end of the data entries */
448 int error; /* error return value */ 446 int error; /* error return value */
449 xfs_mount_t *mp; /* filesystem mount point */ 447 xfs_mount_t *mp; /* filesystem mount point */
450 xfs_dir2_put_args_t p; /* arg package for put rtn */
451 char *ptr; /* current data entry */ 448 char *ptr; /* current data entry */
452 int wantoff; /* starting block offset */ 449 int wantoff; /* starting block offset */
450 xfs_ino_t ino;
451 xfs_off_t cook;
453 452
454 mp = dp->i_mount; 453 mp = dp->i_mount;
455 /* 454 /*
456 * If the block number in the offset is out of range, we're done. 455 * If the block number in the offset is out of range, we're done.
457 */ 456 */
458 if (xfs_dir2_dataptr_to_db(mp, uio->uio_offset) > mp->m_dirdatablk) { 457 if (xfs_dir2_dataptr_to_db(mp, *offset) > mp->m_dirdatablk) {
459 *eofp = 1;
460 return 0; 458 return 0;
461 } 459 }
462 /* 460 /*
463 * Can't read the block, give up, else get dabuf in bp. 461 * Can't read the block, give up, else get dabuf in bp.
464 */ 462 */
465 if ((error = 463 error = xfs_da_read_buf(NULL, dp, mp->m_dirdatablk, -1,
466 xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &bp, XFS_DATA_FORK))) { 464 &bp, XFS_DATA_FORK);
465 if (error)
467 return error; 466 return error;
468 } 467
469 ASSERT(bp != NULL); 468 ASSERT(bp != NULL);
470 /* 469 /*
471 * Extract the byte offset we start at from the seek pointer. 470 * Extract the byte offset we start at from the seek pointer.
472 * We'll skip entries before this. 471 * We'll skip entries before this.
473 */ 472 */
474 wantoff = xfs_dir2_dataptr_to_off(mp, uio->uio_offset); 473 wantoff = xfs_dir2_dataptr_to_off(mp, *offset);
475 block = bp->data; 474 block = bp->data;
476 xfs_dir2_data_check(dp, bp); 475 xfs_dir2_data_check(dp, bp);
477 /* 476 /*
@@ -480,9 +479,7 @@ xfs_dir2_block_getdents(
480 btp = xfs_dir2_block_tail_p(mp, block); 479 btp = xfs_dir2_block_tail_p(mp, block);
481 ptr = (char *)block->u; 480 ptr = (char *)block->u;
482 endptr = (char *)xfs_dir2_block_leaf_p(btp); 481 endptr = (char *)xfs_dir2_block_leaf_p(btp);
483 p.dbp = dbp; 482
484 p.put = put;
485 p.uio = uio;
486 /* 483 /*
487 * Loop over the data portion of the block. 484 * Loop over the data portion of the block.
488 * Each object is a real entry (dep) or an unused one (dup). 485 * Each object is a real entry (dep) or an unused one (dup).
@@ -508,33 +505,24 @@ xfs_dir2_block_getdents(
508 */ 505 */
509 if ((char *)dep - (char *)block < wantoff) 506 if ((char *)dep - (char *)block < wantoff)
510 continue; 507 continue;
511 /*
512 * Set up argument structure for put routine.
513 */
514 p.namelen = dep->namelen;
515 508
516 p.cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 509 cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
517 ptr - (char *)block); 510 ptr - (char *)block);
518 p.ino = be64_to_cpu(dep->inumber); 511 ino = be64_to_cpu(dep->inumber);
519#if XFS_BIG_INUMS 512#if XFS_BIG_INUMS
520 p.ino += mp->m_inoadd; 513 ino += mp->m_inoadd;
521#endif 514#endif
522 p.name = (char *)dep->name;
523
524 /*
525 * Put the entry in the caller's buffer.
526 */
527 error = p.put(&p);
528 515
529 /* 516 /*
530 * If it didn't fit, set the final offset to here & return. 517 * If it didn't fit, set the final offset to here & return.
531 */ 518 */
532 if (!p.done) { 519 if (filldir(dirent, dep->name, dep->namelen, cook,
533 uio->uio_offset = 520 ino, DT_UNKNOWN)) {
534 xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 521 *offset = xfs_dir2_db_off_to_dataptr(mp,
522 mp->m_dirdatablk,
535 (char *)dep - (char *)block); 523 (char *)dep - (char *)block);
536 xfs_da_brelse(tp, bp); 524 xfs_da_brelse(NULL, bp);
537 return error; 525 return 0;
538 } 526 }
539 } 527 }
540 528
@@ -542,13 +530,8 @@ xfs_dir2_block_getdents(
542 * Reached the end of the block. 530 * Reached the end of the block.
543 * Set the offset to a non-existent block 1 and return. 531 * Set the offset to a non-existent block 1 and return.
544 */ 532 */
545 *eofp = 1; 533 *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0);
546 534 xfs_da_brelse(NULL, bp);
547 uio->uio_offset =
548 xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0);
549
550 xfs_da_brelse(tp, bp);
551
552 return 0; 535 return 0;
553} 536}
554 537
diff --git a/fs/xfs/xfs_dir2_block.h b/fs/xfs/xfs_dir2_block.h
index e7c2606161e9..10e689676382 100644
--- a/fs/xfs/xfs_dir2_block.h
+++ b/fs/xfs/xfs_dir2_block.h
@@ -80,9 +80,8 @@ xfs_dir2_block_leaf_p(xfs_dir2_block_tail_t *btp)
80 * Function declarations. 80 * Function declarations.
81 */ 81 */
82extern int xfs_dir2_block_addname(struct xfs_da_args *args); 82extern int xfs_dir2_block_addname(struct xfs_da_args *args);
83extern int xfs_dir2_block_getdents(struct xfs_trans *tp, struct xfs_inode *dp, 83extern int xfs_dir2_block_getdents(struct xfs_inode *dp, void *dirent,
84 struct uio *uio, int *eofp, 84 xfs_off_t *offset, filldir_t filldir);
85 struct xfs_dirent *dbp, xfs_dir2_put_t put);
86extern int xfs_dir2_block_lookup(struct xfs_da_args *args); 85extern int xfs_dir2_block_lookup(struct xfs_da_args *args);
87extern int xfs_dir2_block_removename(struct xfs_da_args *args); 86extern int xfs_dir2_block_removename(struct xfs_da_args *args);
88extern int xfs_dir2_block_replace(struct xfs_da_args *args); 87extern int xfs_dir2_block_replace(struct xfs_da_args *args);
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index 1b73c9ad646a..e7c12fa1303e 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -749,12 +749,11 @@ xfs_dir2_leaf_compact_x1(
749 */ 749 */
750int /* error */ 750int /* error */
751xfs_dir2_leaf_getdents( 751xfs_dir2_leaf_getdents(
752 xfs_trans_t *tp, /* transaction pointer */
753 xfs_inode_t *dp, /* incore directory inode */ 752 xfs_inode_t *dp, /* incore directory inode */
754 uio_t *uio, /* I/O control & vectors */ 753 void *dirent,
755 int *eofp, /* out: reached end of dir */ 754 size_t bufsize,
756 xfs_dirent_t *dbp, /* caller's buffer */ 755 xfs_off_t *offset,
757 xfs_dir2_put_t put) /* ABI formatting routine */ 756 filldir_t filldir)
758{ 757{
759 xfs_dabuf_t *bp; /* data block buffer */ 758 xfs_dabuf_t *bp; /* data block buffer */
760 int byteoff; /* offset in current block */ 759 int byteoff; /* offset in current block */
@@ -763,7 +762,6 @@ xfs_dir2_leaf_getdents(
763 xfs_dir2_data_t *data; /* data block structure */ 762 xfs_dir2_data_t *data; /* data block structure */
764 xfs_dir2_data_entry_t *dep; /* data entry */ 763 xfs_dir2_data_entry_t *dep; /* data entry */
765 xfs_dir2_data_unused_t *dup; /* unused entry */ 764 xfs_dir2_data_unused_t *dup; /* unused entry */
766 int eof; /* reached end of directory */
767 int error = 0; /* error return value */ 765 int error = 0; /* error return value */
768 int i; /* temporary loop index */ 766 int i; /* temporary loop index */
769 int j; /* temporary loop index */ 767 int j; /* temporary loop index */
@@ -776,46 +774,38 @@ xfs_dir2_leaf_getdents(
776 xfs_mount_t *mp; /* filesystem mount point */ 774 xfs_mount_t *mp; /* filesystem mount point */
777 xfs_dir2_off_t newoff; /* new curoff after new blk */ 775 xfs_dir2_off_t newoff; /* new curoff after new blk */
778 int nmap; /* mappings to ask xfs_bmapi */ 776 int nmap; /* mappings to ask xfs_bmapi */
779 xfs_dir2_put_args_t *p; /* formatting arg bundle */
780 char *ptr = NULL; /* pointer to current data */ 777 char *ptr = NULL; /* pointer to current data */
781 int ra_current; /* number of read-ahead blks */ 778 int ra_current; /* number of read-ahead blks */
782 int ra_index; /* *map index for read-ahead */ 779 int ra_index; /* *map index for read-ahead */
783 int ra_offset; /* map entry offset for ra */ 780 int ra_offset; /* map entry offset for ra */
784 int ra_want; /* readahead count wanted */ 781 int ra_want; /* readahead count wanted */
782 xfs_ino_t ino;
785 783
786 /* 784 /*
787 * If the offset is at or past the largest allowed value, 785 * If the offset is at or past the largest allowed value,
788 * give up right away, return eof. 786 * give up right away.
789 */ 787 */
790 if (uio->uio_offset >= XFS_DIR2_MAX_DATAPTR) { 788 if (*offset >= XFS_DIR2_MAX_DATAPTR)
791 *eofp = 1;
792 return 0; 789 return 0;
793 } 790
794 mp = dp->i_mount; 791 mp = dp->i_mount;
795 /* 792
796 * Setup formatting arguments.
797 */
798 p = kmem_alloc(sizeof(*p), KM_SLEEP);
799 p->dbp = dbp;
800 p->put = put;
801 p->uio = uio;
802 /* 793 /*
803 * Set up to bmap a number of blocks based on the caller's 794 * Set up to bmap a number of blocks based on the caller's
804 * buffer size, the directory block size, and the filesystem 795 * buffer size, the directory block size, and the filesystem
805 * block size. 796 * block size.
806 */ 797 */
807 map_size = 798 map_size = howmany(bufsize + mp->m_dirblksize, mp->m_sb.sb_blocksize);
808 howmany(uio->uio_resid + mp->m_dirblksize,
809 mp->m_sb.sb_blocksize);
810 map = kmem_alloc(map_size * sizeof(*map), KM_SLEEP); 799 map = kmem_alloc(map_size * sizeof(*map), KM_SLEEP);
811 map_valid = ra_index = ra_offset = ra_current = map_blocks = 0; 800 map_valid = ra_index = ra_offset = ra_current = map_blocks = 0;
812 bp = NULL; 801 bp = NULL;
813 eof = 1; 802
814 /* 803 /*
815 * Inside the loop we keep the main offset value as a byte offset 804 * Inside the loop we keep the main offset value as a byte offset
816 * in the directory file. 805 * in the directory file.
817 */ 806 */
818 curoff = xfs_dir2_dataptr_to_byte(mp, uio->uio_offset); 807 curoff = xfs_dir2_dataptr_to_byte(mp, *offset);
808
819 /* 809 /*
820 * Force this conversion through db so we truncate the offset 810 * Force this conversion through db so we truncate the offset
821 * down to get the start of the data block. 811 * down to get the start of the data block.
@@ -836,7 +826,7 @@ xfs_dir2_leaf_getdents(
836 * take it out of the mapping. 826 * take it out of the mapping.
837 */ 827 */
838 if (bp) { 828 if (bp) {
839 xfs_da_brelse(tp, bp); 829 xfs_da_brelse(NULL, bp);
840 bp = NULL; 830 bp = NULL;
841 map_blocks -= mp->m_dirblkfsbs; 831 map_blocks -= mp->m_dirblkfsbs;
842 /* 832 /*
@@ -862,8 +852,9 @@ xfs_dir2_leaf_getdents(
862 /* 852 /*
863 * Recalculate the readahead blocks wanted. 853 * Recalculate the readahead blocks wanted.
864 */ 854 */
865 ra_want = howmany(uio->uio_resid + mp->m_dirblksize, 855 ra_want = howmany(bufsize + mp->m_dirblksize,
866 mp->m_sb.sb_blocksize) - 1; 856 mp->m_sb.sb_blocksize) - 1;
857
867 /* 858 /*
868 * If we don't have as many as we want, and we haven't 859 * If we don't have as many as we want, and we haven't
869 * run out of data blocks, get some more mappings. 860 * run out of data blocks, get some more mappings.
@@ -876,7 +867,7 @@ xfs_dir2_leaf_getdents(
876 * we already have in the table. 867 * we already have in the table.
877 */ 868 */
878 nmap = map_size - map_valid; 869 nmap = map_size - map_valid;
879 error = xfs_bmapi(tp, dp, 870 error = xfs_bmapi(NULL, dp,
880 map_off, 871 map_off,
881 xfs_dir2_byte_to_da(mp, 872 xfs_dir2_byte_to_da(mp,
882 XFS_DIR2_LEAF_OFFSET) - map_off, 873 XFS_DIR2_LEAF_OFFSET) - map_off,
@@ -939,7 +930,7 @@ xfs_dir2_leaf_getdents(
939 * mapping. 930 * mapping.
940 */ 931 */
941 curdb = xfs_dir2_da_to_db(mp, map->br_startoff); 932 curdb = xfs_dir2_da_to_db(mp, map->br_startoff);
942 error = xfs_da_read_buf(tp, dp, map->br_startoff, 933 error = xfs_da_read_buf(NULL, dp, map->br_startoff,
943 map->br_blockcount >= mp->m_dirblkfsbs ? 934 map->br_blockcount >= mp->m_dirblkfsbs ?
944 XFS_FSB_TO_DADDR(mp, map->br_startblock) : 935 XFS_FSB_TO_DADDR(mp, map->br_startblock) :
945 -1, 936 -1,
@@ -982,7 +973,7 @@ xfs_dir2_leaf_getdents(
982 * is a very rare case. 973 * is a very rare case.
983 */ 974 */
984 else if (i > ra_current) { 975 else if (i > ra_current) {
985 (void)xfs_da_reada_buf(tp, dp, 976 (void)xfs_da_reada_buf(NULL, dp,
986 map[ra_index].br_startoff + 977 map[ra_index].br_startoff +
987 ra_offset, XFS_DATA_FORK); 978 ra_offset, XFS_DATA_FORK);
988 ra_current = i; 979 ra_current = i;
@@ -1089,46 +1080,39 @@ xfs_dir2_leaf_getdents(
1089 */ 1080 */
1090 dep = (xfs_dir2_data_entry_t *)ptr; 1081 dep = (xfs_dir2_data_entry_t *)ptr;
1091 1082
1092 p->namelen = dep->namelen; 1083 length = xfs_dir2_data_entsize(dep->namelen);
1093
1094 length = xfs_dir2_data_entsize(p->namelen);
1095
1096 p->cook = xfs_dir2_byte_to_dataptr(mp, curoff + length);
1097 1084
1098 p->ino = be64_to_cpu(dep->inumber); 1085 ino = be64_to_cpu(dep->inumber);
1099#if XFS_BIG_INUMS 1086#if XFS_BIG_INUMS
1100 p->ino += mp->m_inoadd; 1087 ino += mp->m_inoadd;
1101#endif 1088#endif
1102 p->name = (char *)dep->name;
1103
1104 error = p->put(p);
1105 1089
1106 /* 1090 /*
1107 * Won't fit. Return to caller. 1091 * Won't fit. Return to caller.
1108 */ 1092 */
1109 if (!p->done) { 1093 if (filldir(dirent, dep->name, dep->namelen,
1110 eof = 0; 1094 xfs_dir2_byte_to_dataptr(mp, curoff + length),
1095 ino, DT_UNKNOWN))
1111 break; 1096 break;
1112 } 1097
1113 /* 1098 /*
1114 * Advance to next entry in the block. 1099 * Advance to next entry in the block.
1115 */ 1100 */
1116 ptr += length; 1101 ptr += length;
1117 curoff += length; 1102 curoff += length;
1103 bufsize -= length;
1118 } 1104 }
1119 1105
1120 /* 1106 /*
1121 * All done. Set output offset value to current offset. 1107 * All done. Set output offset value to current offset.
1122 */ 1108 */
1123 *eofp = eof;
1124 if (curoff > xfs_dir2_dataptr_to_byte(mp, XFS_DIR2_MAX_DATAPTR)) 1109 if (curoff > xfs_dir2_dataptr_to_byte(mp, XFS_DIR2_MAX_DATAPTR))
1125 uio->uio_offset = XFS_DIR2_MAX_DATAPTR; 1110 *offset = XFS_DIR2_MAX_DATAPTR;
1126 else 1111 else
1127 uio->uio_offset = xfs_dir2_byte_to_dataptr(mp, curoff); 1112 *offset = xfs_dir2_byte_to_dataptr(mp, curoff);
1128 kmem_free(map, map_size * sizeof(*map)); 1113 kmem_free(map, map_size * sizeof(*map));
1129 kmem_free(p, sizeof(*p));
1130 if (bp) 1114 if (bp)
1131 xfs_da_brelse(tp, bp); 1115 xfs_da_brelse(NULL, bp);
1132 return error; 1116 return error;
1133} 1117}
1134 1118
diff --git a/fs/xfs/xfs_dir2_leaf.h b/fs/xfs/xfs_dir2_leaf.h
index 70c97f3f815e..6c9539f06987 100644
--- a/fs/xfs/xfs_dir2_leaf.h
+++ b/fs/xfs/xfs_dir2_leaf.h
@@ -232,9 +232,9 @@ extern void xfs_dir2_leaf_compact(struct xfs_da_args *args,
232extern void xfs_dir2_leaf_compact_x1(struct xfs_dabuf *bp, int *indexp, 232extern void xfs_dir2_leaf_compact_x1(struct xfs_dabuf *bp, int *indexp,
233 int *lowstalep, int *highstalep, 233 int *lowstalep, int *highstalep,
234 int *lowlogp, int *highlogp); 234 int *lowlogp, int *highlogp);
235extern int xfs_dir2_leaf_getdents(struct xfs_trans *tp, struct xfs_inode *dp, 235extern int xfs_dir2_leaf_getdents(struct xfs_inode *dp, void *dirent,
236 struct uio *uio, int *eofp, 236 size_t bufsize, xfs_off_t *offset,
237 struct xfs_dirent *dbp, xfs_dir2_put_t put); 237 filldir_t filldir);
238extern int xfs_dir2_leaf_init(struct xfs_da_args *args, xfs_dir2_db_t bno, 238extern int xfs_dir2_leaf_init(struct xfs_da_args *args, xfs_dir2_db_t bno,
239 struct xfs_dabuf **bpp, int magic); 239 struct xfs_dabuf **bpp, int magic);
240extern void xfs_dir2_leaf_log_ents(struct xfs_trans *tp, struct xfs_dabuf *bp, 240extern void xfs_dir2_leaf_log_ents(struct xfs_trans *tp, struct xfs_dabuf *bp,
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c
index 38fc4f22b76d..c67d73572905 100644
--- a/fs/xfs/xfs_dir2_sf.c
+++ b/fs/xfs/xfs_dir2_sf.c
@@ -695,19 +695,18 @@ xfs_dir2_sf_create(
695int /* error */ 695int /* error */
696xfs_dir2_sf_getdents( 696xfs_dir2_sf_getdents(
697 xfs_inode_t *dp, /* incore directory inode */ 697 xfs_inode_t *dp, /* incore directory inode */
698 uio_t *uio, /* caller's buffer control */ 698 void *dirent,
699 int *eofp, /* eof reached? (out) */ 699 xfs_off_t *offset,
700 xfs_dirent_t *dbp, /* caller's buffer */ 700 filldir_t filldir)
701 xfs_dir2_put_t put) /* abi's formatting function */
702{ 701{
703 int error; /* error return value */
704 int i; /* shortform entry number */ 702 int i; /* shortform entry number */
705 xfs_mount_t *mp; /* filesystem mount point */ 703 xfs_mount_t *mp; /* filesystem mount point */
706 xfs_dir2_dataptr_t off; /* current entry's offset */ 704 xfs_dir2_dataptr_t off; /* current entry's offset */
707 xfs_dir2_put_args_t p; /* arg package for put rtn */
708 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ 705 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */
709 xfs_dir2_sf_t *sfp; /* shortform structure */ 706 xfs_dir2_sf_t *sfp; /* shortform structure */
710 xfs_off_t dir_offset; 707 xfs_dir2_dataptr_t dot_offset;
708 xfs_dir2_dataptr_t dotdot_offset;
709 xfs_ino_t ino;
711 710
712 mp = dp->i_mount; 711 mp = dp->i_mount;
713 712
@@ -720,8 +719,6 @@ xfs_dir2_sf_getdents(
720 return XFS_ERROR(EIO); 719 return XFS_ERROR(EIO);
721 } 720 }
722 721
723 dir_offset = uio->uio_offset;
724
725 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); 722 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
726 ASSERT(dp->i_df.if_u1.if_data != NULL); 723 ASSERT(dp->i_df.if_u1.if_data != NULL);
727 724
@@ -732,108 +729,78 @@ xfs_dir2_sf_getdents(
732 /* 729 /*
733 * If the block number in the offset is out of range, we're done. 730 * If the block number in the offset is out of range, we're done.
734 */ 731 */
735 if (xfs_dir2_dataptr_to_db(mp, dir_offset) > mp->m_dirdatablk) { 732 if (xfs_dir2_dataptr_to_db(mp, *offset) > mp->m_dirdatablk)
736 *eofp = 1;
737 return 0; 733 return 0;
738 }
739 734
740 /* 735 /*
741 * Set up putargs structure. 736 * Precalculate offsets for . and .. as we will always need them.
737 *
738 * XXX(hch): the second argument is sometimes 0 and sometimes
739 * mp->m_dirdatablk.
742 */ 740 */
743 p.dbp = dbp; 741 dot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
744 p.put = put; 742 XFS_DIR2_DATA_DOT_OFFSET);
745 p.uio = uio; 743 dotdot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
744 XFS_DIR2_DATA_DOTDOT_OFFSET);
745
746 /* 746 /*
747 * Put . entry unless we're starting past it. 747 * Put . entry unless we're starting past it.
748 */ 748 */
749 if (dir_offset <= 749 if (*offset <= dot_offset) {
750 xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 750 ino = dp->i_ino;
751 XFS_DIR2_DATA_DOT_OFFSET)) {
752 p.cook = xfs_dir2_db_off_to_dataptr(mp, 0,
753 XFS_DIR2_DATA_DOTDOT_OFFSET);
754 p.ino = dp->i_ino;
755#if XFS_BIG_INUMS 751#if XFS_BIG_INUMS
756 p.ino += mp->m_inoadd; 752 ino += mp->m_inoadd;
757#endif 753#endif
758 p.name = "."; 754 if (filldir(dirent, ".", 1, dotdot_offset, ino, DT_DIR)) {
759 p.namelen = 1; 755 *offset = dot_offset;
760 756 return 0;
761 error = p.put(&p);
762
763 if (!p.done) {
764 uio->uio_offset =
765 xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
766 XFS_DIR2_DATA_DOT_OFFSET);
767 return error;
768 } 757 }
769 } 758 }
770 759
771 /* 760 /*
772 * Put .. entry unless we're starting past it. 761 * Put .. entry unless we're starting past it.
773 */ 762 */
774 if (dir_offset <= 763 if (*offset <= dotdot_offset) {
775 xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 764 off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
776 XFS_DIR2_DATA_DOTDOT_OFFSET)) { 765 XFS_DIR2_DATA_FIRST_OFFSET);
777 p.cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 766 ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent);
778 XFS_DIR2_DATA_FIRST_OFFSET);
779 p.ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent);
780#if XFS_BIG_INUMS 767#if XFS_BIG_INUMS
781 p.ino += mp->m_inoadd; 768 ino += mp->m_inoadd;
782#endif 769#endif
783 p.name = ".."; 770 if (filldir(dirent, "..", 2, off, ino, DT_DIR)) {
784 p.namelen = 2; 771 *offset = dotdot_offset;
785 772 return 0;
786 error = p.put(&p);
787
788 if (!p.done) {
789 uio->uio_offset =
790 xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
791 XFS_DIR2_DATA_DOTDOT_OFFSET);
792 return error;
793 } 773 }
794 } 774 }
795 775
796 /* 776 /*
797 * Loop while there are more entries and put'ing works. 777 * Loop while there are more entries and put'ing works.
798 */ 778 */
799 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); 779 sfep = xfs_dir2_sf_firstentry(sfp);
800 i < sfp->hdr.count; 780 for (i = 0; i < sfp->hdr.count; i++) {
801 i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) {
802
803 off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 781 off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
804 xfs_dir2_sf_get_offset(sfep)); 782 xfs_dir2_sf_get_offset(sfep));
805 783
806 if (dir_offset > off) 784 if (*offset > off) {
785 sfep = xfs_dir2_sf_nextentry(sfp, sfep);
807 continue; 786 continue;
787 }
808 788
809 p.namelen = sfep->namelen; 789 ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep));
810
811 p.cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
812 xfs_dir2_sf_get_offset(sfep) +
813 xfs_dir2_data_entsize(p.namelen));
814
815 p.ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep));
816#if XFS_BIG_INUMS 790#if XFS_BIG_INUMS
817 p.ino += mp->m_inoadd; 791 ino += mp->m_inoadd;
818#endif 792#endif
819 p.name = (char *)sfep->name;
820
821 error = p.put(&p);
822 793
823 if (!p.done) { 794 if (filldir(dirent, sfep->name, sfep->namelen,
824 uio->uio_offset = off; 795 off + xfs_dir2_data_entsize(sfep->namelen),
825 return error; 796 ino, DT_UNKNOWN)) {
797 *offset = off;
798 return 0;
826 } 799 }
800 sfep = xfs_dir2_sf_nextentry(sfp, sfep);
827 } 801 }
828 802
829 /* 803 *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0);
830 * They all fit.
831 */
832 *eofp = 1;
833
834 uio->uio_offset =
835 xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0);
836
837 return 0; 804 return 0;
838} 805}
839 806
diff --git a/fs/xfs/xfs_dir2_sf.h b/fs/xfs/xfs_dir2_sf.h
index 11e503209afa..005629d702d2 100644
--- a/fs/xfs/xfs_dir2_sf.h
+++ b/fs/xfs/xfs_dir2_sf.h
@@ -169,9 +169,8 @@ extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_dabuf *bp,
169 int size, xfs_dir2_sf_hdr_t *sfhp); 169 int size, xfs_dir2_sf_hdr_t *sfhp);
170extern int xfs_dir2_sf_addname(struct xfs_da_args *args); 170extern int xfs_dir2_sf_addname(struct xfs_da_args *args);
171extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino); 171extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino);
172extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, struct uio *uio, 172extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, void *dirent,
173 int *eofp, struct xfs_dirent *dbp, 173 xfs_off_t *offset, filldir_t filldir);
174 xfs_dir2_put_t put);
175extern int xfs_dir2_sf_lookup(struct xfs_da_args *args); 174extern int xfs_dir2_sf_lookup(struct xfs_da_args *args);
176extern int xfs_dir2_sf_removename(struct xfs_da_args *args); 175extern int xfs_dir2_sf_removename(struct xfs_da_args *args);
177extern int xfs_dir2_sf_replace(struct xfs_da_args *args); 176extern int xfs_dir2_sf_replace(struct xfs_da_args *args);
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h
index 104f64a98790..5c89be475464 100644
--- a/fs/xfs/xfs_types.h
+++ b/fs/xfs/xfs_types.h
@@ -151,18 +151,6 @@ typedef __uint8_t xfs_arch_t; /* architecture of an xfs fs */
151 */ 151 */
152#define MAXNAMELEN 256 152#define MAXNAMELEN 256
153 153
154typedef struct xfs_dirent { /* data from readdir() */
155 xfs_ino_t d_ino; /* inode number of entry */
156 xfs_off_t d_off; /* offset of disk directory entry */
157 unsigned short d_reclen; /* length of this record */
158 char d_name[1]; /* name of file */
159} xfs_dirent_t;
160
161#define DIRENTBASESIZE (((xfs_dirent_t *)0)->d_name - (char *)0)
162#define DIRENTSIZE(namelen) \
163 ((DIRENTBASESIZE + (namelen) + \
164 sizeof(xfs_off_t)) & ~(sizeof(xfs_off_t) - 1))
165
166typedef enum { 154typedef enum {
167 XFS_LOOKUP_EQi, XFS_LOOKUP_LEi, XFS_LOOKUP_GEi 155 XFS_LOOKUP_EQi, XFS_LOOKUP_LEi, XFS_LOOKUP_GEi
168} xfs_lookup_t; 156} xfs_lookup_t;
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 0116ce1ad59e..36318c66a7bf 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -3284,37 +3284,6 @@ xfs_rmdir(
3284 goto std_return; 3284 goto std_return;
3285} 3285}
3286 3286
3287
3288/*
3289 * Read dp's entries starting at uiop->uio_offset and translate them into
3290 * bufsize bytes worth of struct dirents starting at bufbase.
3291 */
3292STATIC int
3293xfs_readdir(
3294 bhv_desc_t *dir_bdp,
3295 uio_t *uiop,
3296 cred_t *credp,
3297 int *eofp)
3298{
3299 xfs_inode_t *dp;
3300 xfs_trans_t *tp = NULL;
3301 int error = 0;
3302 uint lock_mode;
3303
3304 vn_trace_entry(BHV_TO_VNODE(dir_bdp), __FUNCTION__,
3305 (inst_t *)__return_address);
3306 dp = XFS_BHVTOI(dir_bdp);
3307
3308 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
3309 return XFS_ERROR(EIO);
3310
3311 lock_mode = xfs_ilock_map_shared(dp);
3312 error = xfs_dir_getdents(tp, dp, uiop, eofp);
3313 xfs_iunlock_map_shared(dp, lock_mode);
3314 return error;
3315}
3316
3317
3318STATIC int 3287STATIC int
3319xfs_symlink( 3288xfs_symlink(
3320 bhv_desc_t *dir_bdp, 3289 bhv_desc_t *dir_bdp,