This is namei.c in view mode; [Download] [Up]
/* * linux/fs/ufs/namei.c * * Copyright (C) 1994 Yossi Gottlieb (yogo@math.tau.ac.il) * * Based on code and information: * BSD code, Copyright (c) 1982, 1986 Regents of the University of California. * All rights reserved. * linux/fs/minix Copyright (C) 1991, 1992, 1993 Linus Torvalds * */ #ifdef MODULE #include <linux/module.h> #endif #include <linux/fs.h> #include <linux/sched.h> #include <linux/kernel.h> #include <linux/mm.h> #include <linux/string.h> #include <linux/stat.h> #include <linux/locks.h> #include <asm/system.h> #include <asm/segment.h> #include <asm/bitops.h> #include <linux/ufs_fs.h> #include "ufs.h" /* * comment out this line if you want names > EXT2_NAME_LEN chars to be * truncated. Else they will be disallowed. */ /* #define NO_TRUNCATE */ static inline int ufs_match(struct ufs_sb_info * sb, int len, const char * name, struct buffer_head * bh, unsigned long * offset) { struct ufs_dir_entry *de; de = (struct ufs_dir_entry *) (bh->b_data + *offset); *offset += dtohs(sb,de->d_reclen); if (!de->d_ino || len != ufs_namlen(sb,de)) return 0; /* "" means "." ---> so paths like "/usr/lib//libc.a" work */ if (!len && (de->d_name[0]=='.') && (ufs_namlen(sb,de)==1)) return 1; return !memcmp(name,de->d_name, len); } /* * finds an entry in the specified directory with the wanted name. It * returns the cache buffer in which the entry was found, and the entry * itself (as a parameter - res_dir). It does NOT read the inode of the * entry - you'll have to do that yourself if you want to. */ static struct buffer_head * ufs_find_entry(struct inode * dir, const char * name, int namelen, struct ufs_dir_entry ** res_dir) { unsigned long block, offset; struct buffer_head * bh; struct ufs_sb_info * sb; *res_dir = NULL; if (!dir || !dir->i_sb) return NULL; sb = &dir->i_sb->u.ufs_sb; if (namelen > MAXNAMLEN) { #ifdef NO_TRUNCATE return NULL; #else namelen = MAXNAMLEN; #endif } bh = NULL; block = offset = 0; while (block*BLOCK_SIZE+offset < dir->i_size) { if (!bh) { bh = ufs_bread(dir, numfrags(sb, block*BLOCK_SIZE+offset)); if (!bh) { block++; continue; } } *res_dir = (struct ufs_dir_entry *) (bh->b_data + offset); if (ufs_match(sb,namelen,name,bh,&offset)) return bh; if (offset < bh->b_size) continue; brelse(bh); bh = NULL; offset = 0; block++; } brelse(bh); *res_dir = NULL; return NULL; } int ufs_lookup(struct inode * dir,const char * name, int len, struct inode ** result) { int ino; struct ufs_dir_entry * de; struct buffer_head * bh; *result = NULL; if (!dir) return -ENOENT; if (!S_ISDIR(dir->i_mode)) { iput(dir); return -ENOENT; } if (!(bh = ufs_find_entry(dir,name,len,&de))) { iput(dir); return -ENOENT; } ino = dtohl(&dir->i_sb->u.ufs_sb, de->d_ino); brelse(bh); if (!(*result = iget(dir->i_sb,ino))) { iput(dir); return -EACCES; } iput(dir); return 0; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.