struct inode *unionfs_iget(struct super_block *sb, unsigned long ino, int line, char *file) { struct inode *inode = iget(sb, ino); atomic_inc(&unionfs_iget_counter); if (inode) atomic_inc(&unionfs_igets_outstanding); printk("IG:%d:%d:%d:%p:%d:%s\n", atomic_read(&unionfs_iget_counter), atomic_read(&unionfs_igets_outstanding), inode ? atomic_read(&inode->i_count) : 0, inode, line, file); return inode; }
/* -------------------------------------------------------- do_pwd: * recursively follow a pathname back to a root * * base case: dir is a ROOT * if not base case: * (1) get_block and point DIR* dp to start of second block, which is .. * (2) use dp to get parent's ino * (3) load parent MINODE using iget * (4) Recusively call do_pwd(parent) * (5) print / and directory name -------------------------------------------------------------*/ void do_pwd(MINODE* dir) { MINODE* parent; int pino, ino; char* cp; DIR* dp; char buf[BLOCK_SIZE]; // (1) Base case: DIR is root if(dir == root) { printf("/"); return; } // Read in i_block[0], // which contains all of the directories contained in this DIR get_block(dir->dev, dir->INODE.i_block[0], buf); // Point to the beginning of the datablock cp = buf; dp = (DIR*) cp; // Get ino number of current directory ino = dp->inode; // go to second data block, get ino of .. cp += dp->rec_len; dp = (DIR* )cp; // dp now points to .., the parent's directory pino = dp->inode; // get parent's ino // Load the parent MINODE* parent = iget(dir->dev, pino); // Call pwd with parent's MINODE pointer do_pwd(parent); if(parent == NULL) { printf("Error: could not load MINODE %s", dp->name); return; } // (3) Print name followed by / // Search parent DIR for an entry with this ino // Get the name associated with this ino char* dirName = findmyname(parent, ino); printf("%s/", dirName); iput(parent); }
static super_block *read_devfs_sb(super_block *sb, void *data, int verbose) { if (devfs_sb) return 0; devfs_sb = sb; sb->s_op = &devfs_s_ops; sb->blocksize = 1; sb->blocksize_bits = 0; devfs_create_cache(); devfs_root = devfs_empty_dir(0, 0); sb->root = iget(sb, 0); return sb; }
// Mount root file system, establish / and CWDs int mount_root() { // Attempt to open disk for read/write int fd = open(disk, O_RDWR); if (fd < 0) { printf("\t...Open failed :(\n"); exit(1); } printf("\t...Open successful (with fd = %d)\n", fd); // Read super block get_block(fd, 1, buf); sp = (SUPER *) buf; printf("\t...Got superblock\n"); // Check if EXT2 if (sp->s_magic != 0xEF53) { printf("\t...Not an EXT2 file system\n"); exit(1); } printf("\t...EXT2 file system found\n"); // Root inode root = iget(fd, 2); // running->fd instead of dev // Processes current working directory procs[0].cwd = iget(fd, 2); procs[1].cwd = iget(fd, 2); // TODO do better; we probably don't want to use dev of cwd // Process file descriptors //procs[0].cwd.dev = fd; //procs[1].cwd.dev = fd; return 1; }
/* * Front-end to lookup the inode-cache maintained by the VFS using the PVFS2 * file handle instead of the inode number. * Problem with iget() is well-documented in that it can lead to possible * collissions especially for a file-system with 64 bit handles since inode->i_ino * is only a scalar field (32 bits). So the trick now is to use iget4_locked (OR) iget5_locked * if the kernel defines one and set inode number to be just a hash for the * handle * @sb: the file system super block instance * @ref: The PVFS2 object for which we are trying to locate an inode structure * @keep_locked : indicates whether the inode must be simply allocated and not filled * in with the results from a ->getattr. i.e. if keep_locked is set to 0, we do a getattr() and * unlock the inode and if set to 1, we do not issue a getattr() and keep it locked * * Boy, this function is so ugly with all these macros. I wish I could find a better * way to reduce the macro clutter. */ struct inode *pvfs2_iget_common(struct super_block *sb, PVFS_object_ref *ref, int keep_locked) { struct inode *inode = NULL; unsigned long hash; #if defined(HAVE_IGET5_LOCKED) || defined(HAVE_IGET4_LOCKED) hash = pvfs2_handle_hash(ref); #if defined(HAVE_IGET5_LOCKED) inode = iget5_locked(sb, hash, pvfs2_test_inode, pvfs2_set_inode, ref); #elif defined(HAVE_IGET4_LOCKED) inode = iget4_locked(sb, hash, pvfs2_test_inode, ref); #endif #else hash = (unsigned long) ref->handle; #ifdef HAVE_IGET_LOCKED inode = iget_locked(sb, hash); #else /* iget() internally issues a call to read_inode() */ inode = iget(sb, hash); #endif #endif if (!keep_locked) { #if defined(HAVE_IGET5_LOCKED) || defined(HAVE_IGET4_LOCKED) || defined(HAVE_IGET_LOCKED) if (inode && (inode->i_state & I_NEW)) { inode->i_ino = hash; /* needed for stat etc */ /* iget4_locked and iget_locked dont invoke the set_inode callback. * So we work around that by stashing the pvfs object reference * in the inode specific private part for 2.4 kernels and invoking * the setcallback explicitly for 2.6 kernels. */ #if defined(HAVE_IGET4_LOCKED) || defined(HAVE_IGET_LOCKED) if (PVFS2_I(inode)) { pvfs2_set_inode(inode, ref); } else { #ifdef PVFS2_LINUX_KERNEL_2_4 inode->u.generic_ip = (void *) ref; #endif } #endif /* issue a call to read the inode */ pvfs2_read_inode(inode); unlock_new_inode(inode); } #endif } gossip_debug(GOSSIP_INODE_DEBUG, "iget handle %llu, fsid %d hash %ld i_ino %lu\n", ref->handle, ref->fs_id, hash, inode->i_ino); return inode; }
/* Verify that we are loading a valid orphan from disk */ struct inode *ext3_orphan_get (struct super_block * sb, ino_t ino) { ino_t max_ino = le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count); unsigned long block_group; int bit; int bitmap_nr; struct buffer_head *bh; struct inode *inode = NULL; /* Error cases - e2fsck has already cleaned up for us */ if (ino > max_ino) { ext3_warning(sb, __FUNCTION__, "bad orphan ino %ld! e2fsck was run?\n", ino); return NULL; } block_group = (ino - 1) / EXT3_INODES_PER_GROUP(sb); bit = (ino - 1) % EXT3_INODES_PER_GROUP(sb); if ((bitmap_nr = load_inode_bitmap(sb, block_group)) < 0 || !(bh = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr])) { ext3_warning(sb, __FUNCTION__, "inode bitmap error for orphan %ld\n", ino); return NULL; } /* Having the inode bit set should be a 100% indicator that this * is a valid orphan (no e2fsck run on fs). Orphans also include * inodes that were being truncated, so we can't check i_nlink==0. */ if (!ext3_test_bit(bit, bh->b_data) || !(inode = iget(sb, ino)) || is_bad_inode(inode) || NEXT_ORPHAN(inode) > max_ino) { ext3_warning(sb, __FUNCTION__, "bad orphan inode %ld! e2fsck was run?\n", ino); printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%ld) = %d\n", bit, bh->b_blocknr, ext3_test_bit(bit, bh->b_data)); printk(KERN_NOTICE "inode=%p\n", inode); if (inode) { printk(KERN_NOTICE "is_bad_inode(inode)=%d\n", is_bad_inode(inode)); printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%d\n", NEXT_ORPHAN(inode)); printk(KERN_NOTICE "max_ino=%ld\n", max_ino); } /* Avoid freeing blocks if we got a bad deleted inode */ if (inode && inode->i_nlink == 0) inode->i_blocks = 0; iput(inode); return NULL; } return inode; }
/* * write to a open file */ void mwrite(int file_no, const char* content) { /* check the correctness of file_no */ if (file_no < 0 || file_no > 99) { printf("File has not been opened\n"); return; } /* ensure open */ if (open_file[file_no].count < 1) { printf("File has not been opened\n"); return; } /* find the inode pointer in open_file[] */ struct inode_t* pinode = open_file[file_no].pinode; pinode = iget(pinode->dino); /* calculate the length of the content */ int length; for (length=0; *(content + length) != '\0'; length++) ; /* 1023=>1, 1024=>1, 1025=>2 */ unsigned int block_num = length * sizeof(char) / SBLOCK; unsigned int offset = length * sizeof(char) % SBLOCK; if (offset != 0) block_num++; /* * before allocation, release the blocks that * the file has taken */ int i; for (i=0; i<pinode->size; i++) { bfree(pinode->addr[i]); } /* allocate the blocks for the file */ for (i=0; i < block_num; i++) { unsigned int block_no = balloc(); if (block_no == 0) return; pinode->addr[i]= block_no; pinode->size++; /* * write a block-size of content to the block */ fseek(fd, block_no * SBLOCK, 0); fwrite(content + i * SBLOCK, 1, SBLOCK, fd); } iput(pinode); return; }
/* alloc a inode with specific type */ struct inode* ialloc(uint16_t dev) { int ino; struct inode *ip; ino = _ialloc(dev); ip = iget(dev, ino); ip->nlinks = 0; ip->size = 0; ip->mode = S_RWX; memset(ip->zone, 0, sizeof(ip->zone)); return ip; }
int xiafs_rmdir(struct inode * dir, const char * name, int len) { int retval; struct inode * inode; struct buffer_head * bh; struct xiafs_direct * de, * de_pre; inode = NULL; bh = xiafs_find_entry(dir, name, len, &de, &de_pre); retval = -ENOENT; if (!bh) goto end_rmdir; retval = -EPERM; if (!(inode = iget(dir->i_sb, de->d_ino))) goto end_rmdir; if ((dir->i_mode & S_ISVTX) && !fsuser() && current->fsuid != inode->i_uid && current->fsuid != dir->i_uid) goto end_rmdir; if (inode->i_dev != dir->i_dev) goto end_rmdir; if (inode == dir) /* we may not delete ".", but "../dir" is ok */ goto end_rmdir; if (!S_ISDIR(inode->i_mode)) { retval = -ENOTDIR; goto end_rmdir; } if (!empty_dir(inode)) { retval = -ENOTEMPTY; goto end_rmdir; } if (inode->i_count > 1) { retval = -EBUSY; goto end_rmdir; } if (inode->i_nlink != 2) printk("XIA-FS: empty directory has nlink!=2 (%s %d)\n", WHERE_ERR); xiafs_rm_entry(de, de_pre); mark_buffer_dirty(bh, 1); inode->i_nlink=0; inode->i_dirt=1; dir->i_nlink--; inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; dir->i_dirt=1; retval = 0; end_rmdir: iput(dir); iput(inode); brelse(bh); return retval; }
static int complete_read_super(struct super_block *sb, int silent, int size) { struct sysv_sb_info *sbi = SYSV_SB(sb); struct inode *root_inode; char *found = flavour_names[sbi->s_type]; u_char n_bits = size+8; int bsize = 1 << n_bits; int bsize_4 = bsize >> 2; sbi->s_firstinodezone = 2; flavour_setup[sbi->s_type](sbi); sbi->s_truncate = 1; sbi->s_ndatazones = sbi->s_nzones - sbi->s_firstdatazone; sbi->s_inodes_per_block = bsize >> 6; sbi->s_inodes_per_block_1 = (bsize >> 6)-1; sbi->s_inodes_per_block_bits = n_bits-6; sbi->s_ind_per_block = bsize_4; sbi->s_ind_per_block_2 = bsize_4*bsize_4; sbi->s_toobig_block = 10 + bsize_4 * (1 + bsize_4 * (1 + bsize_4)); sbi->s_ind_per_block_bits = n_bits-2; sbi->s_ninodes = (sbi->s_firstdatazone - sbi->s_firstinodezone) << sbi->s_inodes_per_block_bits; if (!silent) printk("VFS: Found a %s FS (block size = %ld) on device %s\n", found, sb->s_blocksize, sb->s_id); sb->s_magic = SYSV_MAGIC_BASE + sbi->s_type; /* set up enough so that it can read an inode */ sb->s_op = &sysv_sops; root_inode = iget(sb,SYSV_ROOT_INO); if (!root_inode || is_bad_inode(root_inode)) { printk("SysV FS: get root inode failed\n"); return 0; } sb->s_root = d_alloc_root(root_inode); if (!sb->s_root) { iput(root_inode); printk("SysV FS: get root dentry failed\n"); return 0; } if (sbi->s_forced_ro) sb->s_flags |= MS_RDONLY; if (sbi->s_truncate) sb->s_root->d_op = &sysv_dentry_operations; sb->s_dirt = 1; return 1; }
/* Needed for ls. Fill out a VFS inode corresponding to the filename give by the dentry*/ struct dentry* lab5fs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *data) { int err = 0; struct inode *inode = NULL; ino_t ino; printk("lab5fs_lookup:: name: %s, len: %d\n", dentry->d_name.name, dentry->d_name.len); err = lab5fs_getfile(dir, dentry->d_name.name, dentry->d_name.len, &ino); if(!err && ino>0) { printk("lab5fs_lookup: inode %d\n",(int)ino); inode = iget(dir->i_sb, ino); } d_add(dentry, inode); return NULL; }
char* find_name(MINODE *mip) { int my_ino = 0; int parent_ino = 0; findino(mip, &my_ino, &parent_ino); MINODE* parent_mip = iget(running->cwd->device, parent_ino); char* my_name = NULL; findmyname(parent_mip, my_ino, &my_name); iput(parent_mip); return my_name; }
void * osi_UFSOpen(afs_int32 ainode) { register struct osi_file *afile = NULL; extern int cacheDiskType; afs_int32 code = 0; struct inode *tip = NULL; struct file *filp = NULL; AFS_STATCNT(osi_UFSOpen); if (cacheDiskType != AFS_FCACHE_TYPE_UFS) { osi_Panic("UFSOpen called for non-UFS cache\n"); } if (!afs_osicred_initialized) { /* valid for alpha_osf, SunOS, Ultrix */ memset((char *)&afs_osi_cred, 0, sizeof(struct AFS_UCRED)); crhold(&afs_osi_cred); /* don't let it evaporate, since it is static */ afs_osicred_initialized = 1; } afile = (struct osi_file *)osi_AllocLargeSpace(sizeof(struct osi_file)); AFS_GUNLOCK(); if (!afile) { osi_Panic("osi_UFSOpen: Failed to allocate %d bytes for osi_file.\n", sizeof(struct osi_file)); } memset(afile, 0, sizeof(struct osi_file)); filp = &afile->file; filp->f_dentry = &afile->dentry; tip = iget(afs_cacheSBp, (u_long) ainode); if (!tip) osi_Panic("Can't get inode %d\n", ainode); FILE_INODE(filp) = tip; tip->i_flags |= MS_NOATIME; /* Disable updating access times. */ filp->f_flags = O_RDWR; #if defined(AFS_LINUX24_ENV) filp->f_mode = FMODE_READ|FMODE_WRITE; filp->f_op = fops_get(tip->i_fop); #else filp->f_op = tip->i_op->default_file_ops; #endif if (filp->f_op && filp->f_op->open) code = filp->f_op->open(tip, filp); if (code) osi_Panic("Can't open inode %d\n", ainode); afile->size = i_size_read(tip); AFS_GLOCK(); afile->offset = 0; afile->proc = (int (*)())0; afile->inum = ainode; /* for hint validity checking */ return (void *)afile; }
/* ------------------------------------------------------- * make_dir: * must understand perfectly!!! * * Takes a pathname as parameter * * (1) set the device * (2) get parent MINODE by using dirname with * getino * Load MINODE using iget * (3) call my_mkdir(MINODE* parent, char* name) * --------------------------------------------------------*/ void make_dir(char* path) { MINODE* pip; // parent MINODE* int dev, pino; // device, parent ino // parent = path to parent directory, child = basename char* parent, *child; // (1) Set device according to relative or absolute path if(path[0] == '/') dev = root->dev; else dev = running->cwd->dev; // (2) Separate path into dirname and basename parent = strdup(Dirname(path)); // make copies child = strdup(Basename(path)); // Debug print //printf("parent: %s\n", parent); //printf("child: %s\n", child); // (3) get in memory MINODE of parent directory pino = getino(&dev, parent); // First, get parent ino pip = iget(dev, pino); // Then use it to load INODE into minode[] table // (4) Error checking on found MINODE if(pip == NULL) // (4.1) ensure the MINODE was found { printf("Error: unable to locate %s\n", parent); } else if(!isdir(pip)) // (4.2) is DIR { printf("Error: %s is not a directory\n", parent); } else if(search(pip, child) != 0) // (4.3) child does not already exist { // the child was already found printf("Error: %s already exists in %s\n", child, parent); } // (5) We've verified that parent path exists, is a directory // and child does not exist in it, so add to it else my_mkdir(pip,child); // No matter what, dont forget to write back! // Release parent from minode[] table and write back to disk iput(pip); }
static struct dentry * befs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { struct inode *inode = NULL; struct super_block *sb = dir->i_sb; befs_data_stream *ds = &BEFS_I(dir)->i_data.ds; befs_off_t offset; int ret; int utfnamelen; char *utfname; const char *name = dentry->d_name.name; befs_debug(sb, "---> befs_lookup() " "name %s inode %ld", dentry->d_name.name, dir->i_ino); /* Convert to UTF-8 */ if (BEFS_SB(sb)->nls) { ret = befs_nls2utf(sb, name, strlen(name), &utfname, &utfnamelen); if (ret < 0) { befs_debug(sb, "<--- befs_lookup() ERROR"); return ERR_PTR(ret); } ret = befs_btree_find(sb, ds, utfname, &offset); kfree(utfname); } else { ret = befs_btree_find(sb, ds, dentry->d_name.name, &offset); } if (ret == BEFS_BT_NOT_FOUND) { befs_debug(sb, "<--- befs_lookup() %s not found", dentry->d_name.name); return ERR_PTR(-ENOENT); } else if (ret != BEFS_OK || offset == 0) { befs_warning(sb, "<--- befs_lookup() Error"); return ERR_PTR(-ENODATA); } inode = iget(dir->i_sb, (ino_t) offset); if (!inode) return ERR_PTR(-EACCES); d_add(dentry, inode); befs_debug(sb, "<--- befs_lookup()"); return NULL; }
struct inode * proc_get_inode(struct super_block * sb, int ino, struct proc_dir_entry * de) { struct inode * inode; /* * Increment the use count so the dir entry can't disappear. */ de_get(de); #if 1 /* shouldn't ever happen */ if (de && de->deleted) printk("proc_iget: using deleted entry %s, count=%d\n", de->name, atomic_read(&de->count)); #endif inode = iget(sb, ino); if (!inode) goto out_fail; inode->u.generic_ip = (void *) de; if (de) { if (de->mode) { inode->i_mode = de->mode; inode->i_uid = de->uid; inode->i_gid = de->gid; } if (de->size) inode->i_size = de->size; if (de->nlink) inode->i_nlink = de->nlink; if (de->owner) __MOD_INC_USE_COUNT(de->owner); if (S_ISBLK(de->mode)||S_ISCHR(de->mode)||S_ISFIFO(de->mode)) init_special_inode(inode,de->mode,kdev_t_to_nr(de->rdev)); else { if (de->proc_iops) inode->i_op = de->proc_iops; if (de->proc_fops) inode->i_fop = de->proc_fops; } } out: return inode; out_fail: de_put(de); goto out; }
static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, struct nameidata *nd) { struct btstack btstack; ino_t inum; struct inode *ip; struct component_name key; const char *name = dentry->d_name.name; int len = dentry->d_name.len; int rc; jfs_info("jfs_lookup: name = %s", name); if ((name[0] == '.') && (len == 1)) inum = dip->i_ino; else if (strcmp(name, "..") == 0) inum = PARENT(dip); else { if ((rc = get_UCSname(&key, dentry))) return ERR_PTR(rc); rc = dtSearch(dip, &key, &inum, &btstack, JFS_LOOKUP); free_UCSname(&key); if (rc == -ENOENT) { d_add(dentry, NULL); return ERR_PTR(0); } else if (rc) { jfs_err("jfs_lookup: dtSearch returned %d", rc); return ERR_PTR(rc); } } ip = iget(dip->i_sb, inum); if (ip == NULL || is_bad_inode(ip)) { jfs_err("jfs_lookup: iget failed on inum %d", (uint) inum); if (ip) iput(ip); return ERR_PTR(-EACCES); } if (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2) dentry->d_op = &jfs_ci_dentry_operations; dentry = d_splice_alias(ip, dentry); if (dentry && (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2)) dentry->d_op = &jfs_ci_dentry_operations; return dentry; }
/* * Unlink system call. * Hard to avoid races here, especially * in unlinking directories. */ unlink() { register struct inode *ip, *pp; struct a { char *fname; }; pp = namei(uchar, 2); if(pp == NULL) return; /* * Check for unlink(".") * to avoid hanging on the iget */ if (pp->i_number == u.u_dent.d_ino) { ip = pp; ip->i_count++; } else ip = iget(pp->i_dev, u.u_dent.d_ino); if(ip == NULL) goto out1; if((ip->i_mode&IFMT)==IFDIR && !suser()) goto out; /* * Don't unlink a mounted file. */ if (ip->i_dev != pp->i_dev) { u.u_error = EBUSY; goto out; } if (ip->i_flag&ITEXT) xrele(ip); /* try once to free text */ if (ip->i_flag&ITEXT && ip->i_nlink==1) { u.u_error = ETXTBSY; goto out; } u.u_offset -= sizeof(struct direct); u.u_base = (caddr_t)&u.u_dent; u.u_count = sizeof(struct direct); u.u_dent.d_ino = 0; writei(pp); ip->i_nlink--; ip->i_flag |= ICHG; out: iput(ip); out1: iput(pp); }
struct super_block *proc_read_super(struct super_block *s,void *data, int silent) { lock_super(s); s->s_blocksize = 1024; s->s_magic = PROC_SUPER_MAGIC; s->s_op = &proc_sops; unlock_super(s); if (!(s->s_mounted = iget(s,PROC_ROOT_INO))) { s->s_dev = 0; printk("get root inode failed\n"); return NULL; } return s; }
static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry) { struct btstack btstack; ino_t inum; struct inode *ip; struct component_name key; const char *name = dentry->d_name.name; int len = dentry->d_name.len; int rc; jfs_info("jfs_lookup: name = %s", name); if ((name[0] == '.') && (len == 1)) inum = dip->i_ino; else if (strcmp(name, "..") == 0) inum = PARENT(dip); else { if ((rc = get_UCSname(&key, dentry, JFS_SBI(dip->i_sb)->nls_tab))) return ERR_PTR(rc); rc = dtSearch(dip, &key, &inum, &btstack, JFS_LOOKUP); free_UCSname(&key); if (rc == -ENOENT) { d_add(dentry, NULL); return ERR_PTR(0); } else if (rc) { jfs_err("jfs_lookup: dtSearch returned %d", rc); return ERR_PTR(rc); } } ip = iget(dip->i_sb, inum); if (ip == NULL) { jfs_err("jfs_lookup: iget failed on inum %d", (uint) inum); return ERR_PTR(-EACCES); } if (is_bad_inode(ip)) { jfs_err("jfs_lookup: iget returned bad inode, inum = %d", (uint) inum); iput(ip); return ERR_PTR(-EACCES); } d_add(dentry, ip); return ERR_PTR(0); }
/********************************************************************* 函数:creat 功能:创建文件,存在且可写则覆盖,否则申请i节点,并打开该文件,返回文件指针 **********************************************************************/ int creat(unsigned int user_id, char *filename, unsigned short mode){ struct inode *inode; int dirid,di_ith; int i,j; dirid = namei(filename);//查找文件在当前目录下对应的内存目录项的标号 if (dirid != -1){//如果存在同名文件/目录 inode = iget(dir.direct[dirid].d_ino); if(!(inode->di_mode&DIFILE)){//如果不是文件 printf("存在同名目录!\n"); } if (access(user_id,inode,WRITE) == 0){//判断用户对该文件能否进行写操作 iput(inode); printf("\n creat access not allowed \n"); return -1; } //释放旧文件的block组更新当前文件系统的指针 j = inode->di_size%512?1:0; for (i=0; i<inode->di_size/BLOCKSIZ+j; i++) bfree(inode->di_addr[i]); for (i=0; i<SYSOPENFILE; i++){ if (sys_ofile[i].f_count != 0 && sys_ofile[i].f_inode == inode){ sys_ofile[i].f_off = 0; } } iput(inode);//回收内存节点 return open(user_id,filename,WRITE); } else{ inode = ialloc();//分配磁盘节点 返回相应的内存节点指针 di_ith = iname(filename);//为当前文件分配目录项 dir.size++; //当前目录大小加1 dir.direct[di_ith].d_ino = inode->i_ino;//将磁盘节点赋值给存储目录项的信息节点 //更改磁盘节点的相关数据项的信息 inode->di_mode = mode; inode->di_uid = user[user_id].u_uid; inode->di_gid = user[user_id].u_gid; inode->di_size = 0; inode->di_number = 1; //liwen change to 1 iput(inode); return open(user_id,filename,WRITE); } return 0; }
// ls => ls <cwd> // ls dir => ls <cwd>/dir // ls a/b/c // ls a/b/c e/f/g /h/i/j int my_ls(int argc, char* argv[]) { result_t result = NONE; const int device = running->cwd->device; // If given no path, ls cwd if(argc < 2) { list_dir(running->cwd); return SUCCESS; } // ls each path given by user int i = 1; while(i < argc) { int ino = getino(device, argv[i]); MINODE* mip = iget(device, ino); if(!mip) { result = DOES_NOT_EXIST; printf("ls: cannot access '%s':" " No such file or directory\n", argv[i]); goto clean_up; } // If printing multiple lists label each one if(argc > 2) printf("%s:\n", argv[i]); if(S_ISDIR(mip->inode.i_mode)) list_dir(mip); else list_file(mip, argv[i]); clean_up: // Move parent inode from memory to disk iput(mip); if(result != NONE) return result; i++; } return SUCCESS; }
/* * Look up the inode by super block and fattr->fileid. * * Note carefully the special handling of busy inodes (i_count > 1). * With the kernel 2.1.xx dcache all inodes except hard links must * have i_count == 1 after iget(). Otherwise, it indicates that the * server has reused a fileid (i_ino) and we have a stale inode. */ static struct inode * __nfs_fhget(struct super_block *sb, struct nfs_fattr *fattr) { struct inode *inode; int max_count, stale_inode, unhashed = 0; retry: inode = iget(sb, fattr->fileid); if (!inode) goto out_no_inode; /* N.B. This should be impossible ... */ if (inode->i_ino != fattr->fileid) goto out_bad_id; /* * Check for busy inodes, and attempt to get rid of any * unused local references. If successful, we release the * inode and try again. * * Note that the busy test uses the values in the fattr, * as the inode may have become a different object. * (We can probably handle modes changes here, too.) */ stale_inode = inode->i_mode && ((fattr->mode ^ inode->i_mode) & S_IFMT); stale_inode |= inode->i_count && inode->i_count == unhashed; max_count = S_ISDIR(fattr->mode) ? 1 : fattr->nlink; if (stale_inode || inode->i_count > max_count + unhashed) { dprintk("__nfs_fhget: inode %ld busy, i_count=%d, i_nlink=%d\n", inode->i_ino, inode->i_count, inode->i_nlink); unhashed = nfs_free_dentries(inode); if (stale_inode || inode->i_count > max_count + unhashed) { printk("__nfs_fhget: inode %ld still busy, i_count=%d\n", inode->i_ino, inode->i_count); if (!list_empty(&inode->i_dentry)) { struct dentry *dentry; dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias); printk("__nfs_fhget: killing %s/%s filehandle\n", dentry->d_parent->d_name.name, dentry->d_name.name); memset(dentry->d_fsdata, 0, sizeof(struct nfs_fh)); } remove_inode_hash(inode); nfs_invalidate_inode(inode); unhashed = 0; }
static struct inode * getinode(struct vfs *vfsp, dev_t dev, ino_t inode, int *perror) { struct mount *mp = (vfsp ? VFSTOM(vfsp) : 0); struct inode *pip; *perror = 0; if (!mp && !(mp = getmp(dev))) { u.u_error = ENXIO; return (NULL); } pip = iget(dev, mp, inode); if (!pip) *perror = BAD_IGET; return (pip); }
void populate(char *name) { Fileinf f; replete = 0; tapefile = open(name, OREAD); if (tapefile<0) error("Can't open argument file"); f = iget(VROOT); ram->perm = f.mode; ram->mtime = f.mdate; ram->addr = f.addr; ram->data = f.data; ram->ndata = f.size; }
/* the CONTROL inode is made without asking attributes from Venus */ int coda_cnode_makectl(struct inode **inode, struct super_block *sb) { int error = 0; *inode = iget(sb, CTL_INO); if ( *inode ) { (*inode)->i_op = &coda_ioctl_inode_operations; (*inode)->i_fop = &coda_ioctl_operations; (*inode)->i_mode = 0444; error = 0; } else { error = -ENOMEM; } return error; }
int do_unlink(char *name) { char *basename; int namelen; struct m_inode *dir,*inode; // struct buffer_head *bh; struct dir_entry *de; if(!(dir = dir_namei(name,&basename,&namelen))) { //no such file or direntry return -ENOENT; } if(!namelen) { iput(dir); return -ENOENT; } //删除目录项 if((del_entry(dir,basename,namelen,&de)) != 0) { printk("no such file"); iput(dir); return -ENOENT; } if(!(inode = iget(dir->i_dev,de->inode_num))) { iput(dir); return -ENOENT; } //not permit to del direntry if(S_ISDIR(inode->i_mode)) { iput(inode); iput(dir); return -EPERM; } if(--(inode->i_count)) { printk("deleting using file\n"); return -EMLINK; } de->inode_num = 0; inode->i_dirt = 1; iput(inode); iput(dir); printk("delete file successful\n"); return 0; }
static struct inode *_name(char *p, int nameiparent, char *dirname) { struct inode *in, *next; char *name; char arr[64]; char *path = arr; strcpy(arr, p); if(*path == '/') { in = iget(0, 1); while(*++path == '/') ; } else in = idup(current_proc->cwd); name = strtok(path, "/"); while(name) { // printk("File system search:%s\n", name); ilock(in); if(!ISDIR(in->mode)) { iunlock(in); iput(in); return NULL; } if(nameiparent && !tok_hasnext()) { iunlock(in); if(dirname) strcpy(dirname, name); return in; } if(!(next = dirlookup(in, name, 0))) { iunlock(in); iput(in); return NULL; } iunlock(in); iput(in); in = next; if(!tok_hasnext() && dirname) strcpy(dirname, name); name = strtok(NULL, "/"); } return in; }
//mount root file system, establish / and CWDs mount_root(char device_name[64]) { char buf[1024]; //open device for RW dev = open(device_name, O_RDWR); //check if open() worked if(dev < 0) { printf("ERROR: failed cannot open %s\n", device_name); exit(0); } //read super block to verify it's an EXT2 FS get_block(dev, SUPERBLOCK, buf); sp = (SUPER *)buf; //verify if it's an EXT2 FS if(sp->s_magic != 0xEF53) { printf("NOT AN EXT2 FS\n"); exit(1); } //set some vars ninodes = sp->s_inodes_count; nblocks = sp->s_blocks_count; //read group block for info get_block(dev, GDBLOCK, buf); gp = (GD *)buf; imap = gp->bg_inode_bitmap; bmap = gp->bg_block_bitmap; inodeBeginBlock = gp->bg_inode_table; //get root inode root = iget(dev, 2); //let cwd of both p0 and p1 point at the root minode (refCount=3) proc[0].cwd = root; proc[1].cwd = root; root->refCount = 3; printf("%s mounted\n", device_name); }
struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { efs_ino_t inodenum; struct inode * inode = NULL; lock_kernel(); inodenum = efs_find_entry(dir, dentry->d_name.name, dentry->d_name.len); if (inodenum) { if (!(inode = iget(dir->i_sb, inodenum))) { unlock_kernel(); return ERR_PTR(-EACCES); } } unlock_kernel(); d_add(dentry, inode); return NULL; }