📄 patch.c
字号:
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 + -