⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 patch.c

📁 一个简单的操作系统minix的核心代码
💻 C
📖 第 1 页 / 共 2 页
字号:
24884	  if (dirp == fp->fp_rootdir && strcmp(string, "..") == 0 && string != dot2)
24885	                return(get_inode(dirp->i_dev, (int) dirp->i_num));
24886	
24887	  /* The component has been found in the directory.  Get inode. */
24888	  if ( (rip = get_inode(dirp->i_dev, (int) numb)) == NIL_INODE) 
24889	        return(NIL_INODE);
24890	
24891	  if (rip->i_num == ROOT_INODE)
24892	        if (dirp->i_num == ROOT_INODE) {
24893	            if (string[1] == '.') {
24894	                for (sp = &super_block[1]; sp < &super_block[NR_SUPERS]; sp++){
24895	                        if (sp->s_dev == rip->i_dev) {
24896	                                /* Release the root inode.  Replace by the
24897	                                 * inode mounted on.
24898	                                 */
24899	                                put_inode(rip);
24900	                                mnt_dev = sp->s_imount->i_dev;
24901	                                inumb = (int) sp->s_imount->i_num;
24902	                                rip2 = get_inode(mnt_dev, inumb);
24903	                                rip = advance(rip2, string);
24904	                                put_inode(rip2);
24905	                                break;
24906	                        }
24907	                }
24908	            }
24909	        }
24910	  if (rip == NIL_INODE) return(NIL_INODE);
24911	
24912	  /* See if the inode is mounted on.  If so, switch to root directory of the
24913	   * mounted file system.  The super_block provides the linkage between the
24914	   * inode mounted on and the root directory of the mounted file system.
24915	   */
24916	  while (rip != NIL_INODE && rip->i_mount == I_MOUNT) {
24917	        /* The inode is indeed mounted on. */
24918	        for (sp = &super_block[0]; sp < &super_block[NR_SUPERS]; sp++) {
24919	                if (sp->s_imount == rip) {
24920	                        /* Release the inode mounted on.  Replace by the
24921	                         * inode of the root inode of the mounted device.
24922	                         */
24923	                        put_inode(rip);
24924	                        rip = get_inode(sp->s_dev, ROOT_INODE);
24925	                        break;
24926	                }
24927	        }
24928	  }
24929	  return(rip);          /* return pointer to inode's component */
24930	}
	
	
24933	/*===========================================================================*
24934	 *                              search_dir                                   *
24935	 *===========================================================================*/
24936	PUBLIC int search_dir(ldir_ptr, string, numb, flag)
24937	register struct inode *ldir_ptr;        /* ptr to inode for dir to search */
24938	char string[NAME_MAX];          /* component to search for */
24939	ino_t *numb;                    /* pointer to inode number */
24940	int flag;                       /* LOOK_UP, ENTER, DELETE or IS_EMPTY */
24941	{
24942	/* This function searches the directory whose inode is pointed to by 'ldip':
24943	 * if (flag == ENTER)  enter 'string' in the directory with inode # '*numb';
24944	 * if (flag == DELETE) delete 'string' from the directory;
24945	 * if (flag == LOOK_UP) search for 'string' and return inode # in 'numb';
24946	 * if (flag == IS_EMPTY) return OK if only . and .. in dir else ENOTEMPTY;
24947	 *
24948	 *    if 'string' is dot1 or dot2, no access permissions are checked.
24949	 */
24950	
24951	  register struct direct *dp;
24952	  register struct buf *bp;
24953	  int i, r, e_hit, t, match;
24954	  mode_t bits;
24955	  off_t pos;
24956	  unsigned new_slots, old_slots;
24957	  block_t b;
24958	  struct super_block *sp;
24959	  int extended = 0;
24960	
24961	  /* If 'ldir_ptr' is not a pointer to a dir inode, error. */
24962	  if ( (ldir_ptr->i_mode & I_TYPE) != I_DIRECTORY) return(ENOTDIR);
24963	
24964	  r = OK;
24965	
24966	  if (flag != IS_EMPTY) {
24967	        bits = (flag == LOOK_UP ? X_BIT : W_BIT | X_BIT);
24968	
24969	        if (string == dot1 || string == dot2) {
24970	                if (flag != LOOK_UP) r = read_only(ldir_ptr);
24971	                                     /* only a writable device is required. */
24972	        }
24973	        else r = forbidden(ldir_ptr, bits); /* check access permissions */
24974	  }
24975	  if (r != OK) return(r);
24976	  
24977	  /* Step through the directory one block at a time. */
24978	  old_slots = (unsigned) (ldir_ptr->i_size/DIR_ENTRY_SIZE);
24979	  new_slots = 0;
24980	  e_hit = FALSE;
24981	  match = 0;                    /* set when a string match occurs */
24982	
24983	  for (pos = 0; pos < ldir_ptr->i_size; pos += BLOCK_SIZE) {
24984	        b = read_map(ldir_ptr, pos);    /* get block number */
24985	
24986	        /* Since directories don't have holes, 'b' cannot be NO_BLOCK. */
24987	        bp = get_block(ldir_ptr->i_dev, b, NORMAL);     /* get a dir block */
24988	
24989	        /* Search a directory block. */
24990	        for (dp = &bp->b_dir[0]; dp < &bp->b_dir[NR_DIR_ENTRIES]; dp++) {
24991	                if (++new_slots > old_slots) { /* not found, but room left */
24992	                        if (flag == ENTER) e_hit = TRUE;
24993	                        break;
24994	                }
24995	
24996	                /* Match occurs if string found. */
24997	                if (flag != ENTER && dp->d_ino != 0) {
24998	                        if (flag == IS_EMPTY) {
24999	                                /* If this test succeeds, dir is not empty. */
25000	                                if (strcmp(dp->d_name, "." ) != 0 &&
25001	                                    strcmp(dp->d_name, "..") != 0) match = 1;
25002	                        } else {
25003	                                if (strncmp(dp->d_name, string, NAME_MAX) == 0)
25004	                                        match = 1;
25005	                        }
25006	                }
25007	
25008	                if (match) {
25009	                        /* LOOK_UP or DELETE found what it wanted. */
25010	                        r = OK;
25011	                        if (flag == IS_EMPTY) r = ENOTEMPTY;
25012	                        else if (flag == DELETE) {
25013	                                /* Save d_ino for recovery. */
25014	                                t = NAME_MAX - sizeof(ino_t);
25015	                                *((ino_t *) &dp->d_name[t]) = dp->d_ino;
25016	                                dp->d_ino = 0;  /* erase entry */
25017	                                bp->b_dirt = DIRTY;
25018	                                ldir_ptr->i_update |= CTIME | MTIME;
25019	                                ldir_ptr->i_dirt = DIRTY;
25020	                        } else {
25021	                                sp = ldir_ptr->i_sp;    /* 'flag' is LOOK_UP */
25022	                                *numb = conv2(sp->s_native, (int) dp->d_ino);
25023	                        }
25024	                        put_block(bp, DIRECTORY_BLOCK);
25025	                        return(r);
25026	                }
25027	
25028	
25029	                /* Check for free slot for the benefit of ENTER. */
25030	                if (flag == ENTER && dp->d_ino == 0) {
25031	                        e_hit = TRUE;   /* we found a free slot */
25032	                        break;
25033	                }
25034	        }
25035	
25036	        /* The whole block has been searched or ENTER has a free slot. */
25037	        if (e_hit) break;       /* e_hit set if ENTER can be performed now */
25038	        put_block(bp, DIRECTORY_BLOCK); /* otherwise, continue searching dir */
25039	  }
25040	
25041	  /* The whole directory has now been searched. */
25042	  if (flag != ENTER) return(flag == IS_EMPTY ? OK : ENOENT);
25043	
25044	  /* This call is for ENTER.  If no free slot has been found so far, try to
25045	   * extend directory.
25046	   */
25047	  if (e_hit == FALSE) { /* directory is full and no room left in last block */
25048	        new_slots++;            /* increase directory size by 1 entry */
25049	        if (new_slots == 0) return(EFBIG); /* dir size limited by slot count */
25050	        if ( (bp = new_block(ldir_ptr, ldir_ptr->i_size)) == NIL_BUF)
25051	                return(err_code);
25052	        dp = &bp->b_dir[0];
25053	        extended = 1;
25054	  }
25055	
25056	  /* 'bp' now points to a directory block with space. 'dp' points to slot. */
25057	  (void) memset(dp->d_name, 0, (size_t) NAME_MAX); /* clear entry */
25058	  for (i = 0; string[i] && i < NAME_MAX; i++) dp->d_name[i] = string[i];
25059	  sp = ldir_ptr->i_sp; 
25060	  dp->d_ino = conv2(sp->s_native, (int) *numb);
25061	  bp->b_dirt = DIRTY;
25062	  put_block(bp, DIRECTORY_BLOCK);
25063	  ldir_ptr->i_update |= CTIME | MTIME;  /* mark mtime for update later */
25064	  ldir_ptr->i_dirt = DIRTY;
25065	  if (new_slots > old_slots) {
25066	        ldir_ptr->i_size = (off_t) new_slots * DIR_ENTRY_SIZE;
25067	        /* Send the change to disk if the directory is extended. */
25068	        if (extended) rw_inode(ldir_ptr, WRITING);
25069	  }
25070	  return(OK);
25071	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -