📄 misc.c
字号:
nl_day = day; month = 2; } else { nl_day = (year & 3) || day <= 59 ? day : day-1; for (month = 0; month < 12; month++) if (day_n[month] > nl_day) break; } *date = nl_day-day_n[month-1]+1+(month << 5)+(year << 9);}/* Returns the inode number of the directory entry at offset pos. If bh is non-NULL, it is brelse'd before. Pos is incremented. The buffer header is returned in bh. */int fat_get_entry(struct inode *dir, loff_t *pos,struct buffer_head **bh, struct msdos_dir_entry **de){ struct super_block *sb = dir->i_sb; int sector, offset; while (1) { offset = *pos; PRINTK (("get_entry offset %d\n",offset)); if ((sector = fat_smap(dir,offset >> SECTOR_BITS)) == -1) return -1; PRINTK (("get_entry sector %d %p\n",sector,*bh)); if (!sector) return -1; /* beyond EOF */ *pos += sizeof(struct msdos_dir_entry); if (*bh) fat_brelse(sb, *bh); PRINTK (("get_entry sector apres brelse\n")); if (!(*bh = fat_bread(sb, sector))) { printk("Directory sread (sector 0x%x) failed\n",sector); continue; } PRINTK (("get_entry apres sread\n")); *de = (struct msdos_dir_entry *) ((*bh)->b_data+(offset & (SECTOR_SIZE-1))); return (sector << MSDOS_DPS_BITS)+((offset & (SECTOR_SIZE-1)) >> MSDOS_DIR_BITS); }}/* * Now an ugly part: this set of directory scan routines works on clusters * rather than on inodes and sectors. They are necessary to locate the '..' * directory "inode". raw_scan_sector operates in four modes: * * name number ino action * -------- -------- -------- ------------------------------------------------- * non-NULL - X Find an entry with that name * NULL non-NULL non-NULL Find an entry whose data starts at *number * NULL non-NULL NULL Count subdirectories in *number. (*) * NULL NULL non-NULL Find an empty entry * * (*) The return code should be ignored. It DOES NOT indicate success or * failure. *number has to be initialized to zero. * * - = not used, X = a value is returned unless NULL * * If res_bh is non-NULL, the buffer is not deallocated but returned to the * caller on success. res_de is set accordingly. * * If cont is non-zero, raw_found continues with the entry after the one * res_bh/res_de point to. */#define RSS_NAME /* search for name */ \ done = !strncmp(data[entry].name,name,MSDOS_NAME) && \ !(data[entry].attr & ATTR_VOLUME);#define RSS_START /* search for start cluster */ \ done = !IS_FREE(data[entry].name) \ && ( \ ( \ (MSDOS_SB(sb)->fat_bits != 32) ? 0 : (CF_LE_W(data[entry].starthi) << 16) \ ) \ | CF_LE_W(data[entry].start) \ ) == *number;#define RSS_FREE /* search for free entry */ \ { \ done = IS_FREE(data[entry].name); \ if (done) { \ inode = iget(sb,sector*MSDOS_DPS+entry); \ if (inode) { \ /* Directory slots of busy deleted files aren't available yet. */ \ done = !MSDOS_I(inode)->i_busy; \ iput(inode); \ } \ } \ }#define RSS_COUNT /* count subdirectories */ \ { \ done = 0; \ if (!IS_FREE(data[entry].name) && (data[entry].attr & ATTR_DIR)) \ (*number)++; \ }static int raw_scan_sector(struct super_block *sb,int sector,const char *name, int *number,int *ino,struct buffer_head **res_bh, struct msdos_dir_entry **res_de,char scantype){ struct buffer_head *bh; struct msdos_dir_entry *data; struct inode *inode; int entry,start,done; if (!(bh = fat_bread(sb,sector))) return -EIO; data = (struct msdos_dir_entry *) bh->b_data; for (entry = 0; entry < MSDOS_DPS; entry++) {/* RSS_COUNT: if (data[entry].name == name) done=true else done=false. */ if (name) { RSS_NAME if (done && scantype) { /* scantype != SCAN_ANY */ done = (data[entry].attr & ATTR_HIDDEN) ? (scantype==SCAN_HID) : (scantype==SCAN_NOTHID); } } else { if (!ino) RSS_COUNT else { if (number) RSS_START else RSS_FREE } } if (done) { if (ino) *ino = sector*MSDOS_DPS+entry; start = CF_LE_W(data[entry].start); if (MSDOS_SB(sb)->fat_bits == 32) { start |= (CF_LE_W(data[entry].starthi) << 16); } if (!res_bh) fat_brelse(sb, bh); else { *res_bh = bh; *res_de = &data[entry]; } return start; } } fat_brelse(sb, bh); return -ENOENT;}/* * raw_scan_root performs raw_scan_sector on the root directory until the * requested entry is found or the end of the directory is reached. */static int raw_scan_root(struct super_block *sb,const char *name,int *number,int *ino, struct buffer_head **res_bh,struct msdos_dir_entry **res_de,char scantype){ int count,cluster; for (count = 0; count < MSDOS_SB(sb)->dir_entries/MSDOS_DPS; count++) { if ((cluster = raw_scan_sector(sb,MSDOS_SB(sb)->dir_start+count, name,number,ino,res_bh,res_de,scantype)) >= 0) return cluster; } return -ENOENT;}/* * raw_scan_nonroot performs raw_scan_sector on a non-root directory until the * requested entry is found or the end of the directory is reached. */static int raw_scan_nonroot(struct super_block *sb,int start,const char *name, int *number,int *ino,struct buffer_head **res_bh,struct msdos_dir_entry **res_de,char scantype){ int count,cluster;#ifdef DEBUG printk("raw_scan_nonroot: start=%d\n",start);#endif do { for (count = 0; count < MSDOS_SB(sb)->cluster_size; count++) { if ((cluster = raw_scan_sector(sb,(start-2)* MSDOS_SB(sb)->cluster_size+MSDOS_SB(sb)->data_start+ count,name,number,ino,res_bh,res_de,scantype)) >= 0) return cluster; } if (!(start = fat_access(sb,start,-1))) { fat_fs_panic(sb,"FAT error"); break; }#ifdef DEBUG printk("next start: %d\n",start);#endif } while (start != -1); return -ENOENT;}/* * raw_scan performs raw_scan_sector on any sector. * * NOTE: raw_scan must not be used on a directory that is is the process of * being created. */static int raw_scan(struct super_block *sb, int start, const char *name, int *number, int *ino, struct buffer_head **res_bh, struct msdos_dir_entry **res_de, char scantype){ if (start) return raw_scan_nonroot (sb,start,name,number,ino,res_bh,res_de,scantype); else return raw_scan_root (sb,name,number,ino,res_bh,res_de,scantype);}/* * fat_parent_ino returns the inode number of the parent directory of dir. * File creation has to be deferred while fat_parent_ino is running to * prevent renames. */int fat_parent_ino(struct inode *dir,int locked){ static int zero = 0; int error,curr,prev,nr; PRINTK(("fat_parent_ino: Debug 0\n")); if (!S_ISDIR(dir->i_mode)) panic("Non-directory fed to m_p_i"); if (dir->i_ino == MSDOS_ROOT_INO) return dir->i_ino; if (!locked) fat_lock_creation(); /* prevent renames */ if ((curr = raw_scan(dir->i_sb,MSDOS_I(dir)->i_start,MSDOS_DOTDOT, &zero,NULL,NULL,NULL,SCAN_ANY)) < 0) { if (!locked) fat_unlock_creation(); return curr; } PRINTK(("fat_parent_ino: Debug 1 curr=%d\n", curr)); if (!curr) nr = MSDOS_ROOT_INO; else { PRINTK(("fat_parent_ino: Debug 2\n")); if ((prev = raw_scan(dir->i_sb,curr,MSDOS_DOTDOT,&zero,NULL, NULL,NULL,SCAN_ANY)) < 0) { PRINTK(("fat_parent_ino: Debug 3 prev=%d\n", prev)); if (!locked) fat_unlock_creation(); return prev; } PRINTK(("fat_parent_ino: Debug 4 prev=%d\n", prev)); if (prev == 0 && MSDOS_SB(dir->i_sb)->fat_bits == 32) { prev = MSDOS_SB(dir->i_sb)->root_cluster; } if ((error = raw_scan(dir->i_sb,prev,NULL,&curr,&nr,NULL, NULL,SCAN_ANY)) < 0) { PRINTK(("fat_parent_ino: Debug 5 error=%d\n", error)); if (!locked) fat_unlock_creation(); return error; } PRINTK(("fat_parent_ino: Debug 6 nr=%d\n", nr)); } if (!locked) fat_unlock_creation(); return nr;}/* * fat_subdirs counts the number of sub-directories of dir. It can be run * on directories being created. */int fat_subdirs(struct inode *dir){ int count; count = 0; if ((dir->i_ino == MSDOS_ROOT_INO) && (MSDOS_SB(dir->i_sb)->fat_bits != 32)) { (void) raw_scan_root(dir->i_sb,NULL,&count,NULL,NULL,NULL,SCAN_ANY); } else { if ((dir->i_ino != MSDOS_ROOT_INO) && !MSDOS_I(dir)->i_start) return 0; /* in mkdir */ else (void) raw_scan_nonroot(dir->i_sb,MSDOS_I(dir)->i_start, NULL,&count,NULL,NULL,NULL,SCAN_ANY); } return count;}/* * Scans a directory for a given file (name points to its formatted name) or * for an empty directory slot (name is NULL). Returns an error code or zero. */int fat_scan(struct inode *dir,const char *name,struct buffer_head **res_bh, struct msdos_dir_entry **res_de,int *ino, char scantype){ int res; res = raw_scan(dir->i_sb,MSDOS_I(dir)->i_start, name, NULL, ino, res_bh, res_de, scantype); return res<0 ? res : 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -