root/fs/ufs/ufs_namei.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ufs_match
  2. ufs_lookup

   1 /*
   2  *  linux/fs/ufs/ufs_namei.c
   3  *
   4  * Copyright (C) 1996
   5  * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu)
   6  * Laboratory for Computer Science Research Computing Facility
   7  * Rutgers, The State University of New Jersey
   8  *
   9  * $Id: ufs_namei.c,v 1.1 1996/04/21 14:41:15 davem Exp $
  10  *
  11  */
  12 
  13 #include <linux/fs.h>
  14 
  15 extern unsigned int ufs_bmap(struct inode * inode, int block); /* XXX */
  16 
  17 /*
  18  * NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure.
  19  * stolen from ext2fs
  20  */
  21 static int ufs_match (int len, const char * const name, struct direct * d)
     /* [previous][next][first][last][top][bottom][index][help] */
  22 {
  23         if (!d || len > MAXNAMLEN) /* XXX - name space */
  24                 return 0;
  25         /*
  26          * "" means "." ---> so paths like "/usr/lib//libc.a" work
  27          */
  28         if (!len && (d->d_namlen == 1) && (d->d_name[0] == '.') &&
  29            (d->d_name[1] == '\0'))
  30                 return 1;
  31         if (len != d->d_namlen)
  32                 return 0;
  33         return !memcmp(name, d->d_name, len);
  34 }
  35 
  36 /* XXX - this is a mess, especially for endianity */
  37 int ufs_lookup (struct inode * dir, const char * name, int len,
     /* [previous][next][first][last][top][bottom][index][help] */
  38                 struct inode ** result)
  39 {
  40         unsigned long int lfragno, fragno;
  41         struct buffer_head * bh;
  42         struct direct * d;
  43 
  44         /*
  45          * Touching /xyzzy in a filesystem toggles debugging messages.
  46          */
  47         if ((len == 5) && !(memcmp(name, "xyzzy", len)) &&
  48             (dir->i_ino == UFS_ROOTINO)) {
  49                 dir->i_sb->u.ufs_sb.s_flags ^= UFS_DEBUG;
  50                 printk("UFS debugging %s\n",
  51                        (dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) ?
  52                        "on": "off");
  53                 return(-ENOENT);
  54         }
  55 
  56         /*
  57          * Touching /xyzzy.i in a filesystem toggles debugging for ufs_inode.c.
  58          */
  59         if ((len == 7) && !(memcmp(name, "xyzzy.i", len)) &&
  60             (dir->i_ino == UFS_ROOTINO)) {
  61                 dir->i_sb->u.ufs_sb.s_flags ^= UFS_DEBUG_INODE;
  62                 printk("UFS inode debugging %s\n",
  63                        (dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG_INODE) ?
  64                        "on": "off");
  65                 return(-ENOENT);
  66         }
  67 
  68         if ((len == 7) && !(memcmp(name, "xyzzy.n", len)) &&
  69             (dir->i_ino == UFS_ROOTINO)) {
  70                 dir->i_sb->u.ufs_sb.s_flags ^= UFS_DEBUG_NAMEI;
  71                 printk("UFS namei debugging %s\n",
  72                        (dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG_NAMEI) ?
  73                        "on": "off");
  74                 return(-ENOENT);
  75         }
  76 
  77         if ((len == 7) && !(memcmp(name, "xyzzy.l", len)) &&
  78             (dir->i_ino == UFS_ROOTINO)) {
  79                 dir->i_sb->u.ufs_sb.s_flags ^= UFS_DEBUG_LINKS;
  80                 printk("UFS symlink debugging %s\n",
  81                        (dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG_LINKS) ?
  82                        "on": "off");
  83                 return(-ENOENT);
  84         }
  85 
  86         if (dir->i_sb->u.ufs_sb.s_flags & (UFS_DEBUG|UFS_DEBUG_NAMEI)) {
  87                 printk("ufs_lookup: called for ino %lu  name %s\n",
  88                        dir->i_ino, name);
  89         }
  90 
  91         /* XXX - do I want i_blocks in 512-blocks or 1024-blocks? */
  92         for (lfragno = 0; lfragno < (dir->i_blocks)>>1; lfragno++) {
  93                 fragno = ufs_bmap(dir, lfragno);
  94                 /* XXX - ufs_bmap() call needs error checking */
  95                 /* XXX - s_blocksize is actually the UFS frag size */
  96                 if (dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) {
  97                         printk("ufs_lookup: ino %lu lfragno %lu  fragno %lu\n",
  98                                dir->i_ino, lfragno, fragno);
  99                 }
 100                 if (fragno == 0) {
 101                         /* XXX - bug bug bug */
 102                         return(-ENOENT);
 103                 }
 104                 bh = bread(dir->i_dev, fragno, dir->i_sb->s_blocksize);
 105                 if (bh == NULL) {
 106                         printk("ufs_lookup: bread failed: ino %lu, lfragno %u",
 107                                dir->i_ino, lfragno);
 108                         return(-EIO);
 109                 }
 110                 d = (struct direct *)(bh->b_data);
 111                 while (((char *)d - bh->b_data + d->d_reclen) <=
 112                        dir->i_sb->s_blocksize) {
 113                         /* XXX - skip block if d_reclen or d_namlen is 0 */
 114                         if ((d->d_reclen == 0) || (d->d_namlen == 0)) {
 115                                 if (dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) {
 116                                         printk("ufs_lookup: skipped space in directory, ino %lu\n",
 117                                                dir->i_ino);
 118                                 }
 119                                 break;
 120                         }
 121                         if (dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) {
 122                                 printk("lfragno 0x%x  direct d 0x%x  d_ino %u  d_reclen %u  d_namlen %u  d_name `%s'\n",
 123                                        lfragno, (unsigned int)d, d->d_ino, d->d_reclen, d->d_namlen, d->d_name);
 124                         }
 125                         if ((d->d_namlen == len) &&
 126                             /* XXX - don't use strncmp() - see ext2fs */
 127                             (ufs_match(len, name, d))) {
 128                                 /* We have a match */
 129                                 *result = iget(dir->i_sb, d->d_ino);
 130                                 brelse(bh);
 131                                 return(0);
 132                         } else {
 133                                 /* XXX - bounds checking */
 134                                 if (dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) {
 135                                         printk("ufs_lookup: wanted (%s,%d) got (%s,%d)\n",
 136                                                name, len, d->d_name, d->d_namlen);
 137                                 }
 138                         }
 139                         d = (struct direct *)((char *)d + d->d_reclen);
 140                 }
 141                 brelse(bh);
 142         }
 143         return(-ENOENT);
 144 }
 145 
 146 /*
 147  * Local Variables: ***
 148  * c-indent-level: 8 ***
 149  * c-continued-statement-offset: 8 ***
 150  * c-brace-offset: -8 ***
 151  * c-argdecl-indent: 0 ***
 152  * c-label-offset: -8 ***
 153  * End: ***
 154  */

/* [previous][next][first][last][top][bottom][index][help] */