?? inode.c
字號:
"mounting %s read only.\n",mapidx,htonl(bm[i]), kdevname(dev)); s->s_flags |= MS_RDONLY; } /* Mark unused bits in the last word as allocated */ if (size <= s->s_blocksize * 8 - 32) { /* last bitmap */ ptype = size / 32 + 1; /* word number */ key = size & 0x1F; /* used bits */ if (key) { chksum = ntohl(0x7FFFFFFF >> (31 - key)); ((__u32 *)bb->b_data)[ptype] &= chksum; affs_fix_checksum(s->s_blocksize,bb->b_data,0); mark_buffer_dirty(bb,1); } ptype = (size + 31) & ~0x1F; size = 0; if (!(s->s_flags & MS_RDONLY)) s->u.affs_sb.s_flags |= SF_BM_VALID; } else { ptype = s->s_blocksize * 8 - 32; size -= ptype; } s->u.affs_sb.s_bitmap[mapidx].bm_firstblk = offset; s->u.affs_sb.s_bitmap[mapidx].bm_bh = NULL; s->u.affs_sb.s_bitmap[mapidx].bm_key = htonl(bm[i]); s->u.affs_sb.s_bitmap[mapidx].bm_count = 0; offset += ptype; for (j = 0; ptype > 0; j++, az_no++, ptype -= key) { key = MIN(ptype,AFFS_ZONE_SIZE); /* size in bits */ s->u.affs_sb.s_alloc[az_no].az_size = key / 32; s->u.affs_sb.s_alloc[az_no].az_free = affs_count_free_bits(key / 8,bb->b_data + j * (AFFS_ZONE_SIZE / 8) + 4); } affs_brelse(bb); } else { printk("AFFS: Can't read bitmap.\n"); goto out; } } key = htonl(bm[stype]); /* Next block of bitmap pointers */ ptype = 0; stype = s->s_blocksize / 4 - 1; affs_brelse(bh); if (key) { if (!(bh = affs_bread(s->s_dev,key,s->s_blocksize))) { printk("AFFS: Can't read bitmap extension.\n"); goto out; } } else bh = NULL; } if (mapidx != num_bm) { printk("AFFS: Got only %d bitmap blocks, expected %d\n",mapidx,num_bm); goto out; }nobitmap: s->u.affs_sb.s_bm_count = mapidx; /* set up enough so that it can read an inode */ s->s_dev = dev; s->s_op = &affs_sops; s->s_mounted = iget(s,root_block); s->s_dirt = 1; unlock_super(s); if (!(s->s_mounted)) { s->s_dev = 0; printk("AFFS: get root inode failed\n"); MOD_DEC_USE_COUNT; return NULL; } /* create data zones if the fs is mounted r/w */ if (!(s->s_flags & MS_RDONLY)) { ROOT_END(s->u.affs_sb.s_root_bh->b_data,s->s_mounted)->bm_flag = 0; secs_to_datestamp(CURRENT_TIME,&ROOT_END(s->u.affs_sb.s_root_bh->b_data, s->s_mounted)->disk_altered); affs_fix_checksum(s->s_blocksize,s->u.affs_sb.s_root_bh->b_data,5); mark_buffer_dirty(s->u.affs_sb.s_root_bh,1); affs_make_zones(s); } pr_debug("AFFS: s_flags=%lX\n",s->s_flags); return s; out: /* Kick out for various error conditions */ affs_brelse (bh); affs_brelse(s->u.affs_sb.s_root_bh); if (s->u.affs_sb.s_bitmap) kfree(s->u.affs_sb.s_bitmap); set_blocksize(dev,BLOCK_SIZE); s->s_dev = 0; unlock_super(s); MOD_DEC_USE_COUNT; return NULL;}voidaffs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz){ int free; struct statfs tmp; pr_debug("AFFS: statfs() partsize=%d, reserved=%d\n",sb->u.affs_sb.s_partition_size, sb->u.affs_sb.s_reserved); free = affs_count_free_blocks(sb); tmp.f_type = AFFS_SUPER_MAGIC; tmp.f_bsize = sb->s_blocksize; tmp.f_blocks = sb->u.affs_sb.s_partition_size - sb->u.affs_sb.s_reserved; tmp.f_bfree = free; tmp.f_bavail = free; tmp.f_files = 0; tmp.f_ffree = 0; memcpy_tofs(buf,&tmp,bufsiz);}voidaffs_read_inode(struct inode *inode){ struct buffer_head *bh, *lbh; struct file_front *file_front; struct file_end *file_end; int block; unsigned long prot; int ptype, stype; unsigned short id; pr_debug("AFFS: read_inode(%lu)\n",inode->i_ino); lbh = NULL; block = inode->i_ino; if (!(bh = affs_bread(inode->i_dev,block,AFFS_I2BSIZE(inode)))) { printk("AFFS: unable to read i-node block %d\n",block); return; } if (affs_checksum_block(AFFS_I2BSIZE(inode),bh->b_data,&ptype,&stype) || ptype != T_SHORT) { printk("AFFS: read_inode(): checksum or type (ptype=%d) error on inode %d\n", ptype,block); affs_brelse(bh); return; } file_front = (struct file_front *)bh->b_data; file_end = GET_END_PTR(struct file_end, bh->b_data,AFFS_I2BSIZE(inode)); prot = (htonl(file_end->protect) & ~0x10) ^ FIBF_OWNER; inode->u.affs_i.i_protect = prot; inode->u.affs_i.i_parent = htonl(file_end->parent); inode->u.affs_i.i_original = 0; inode->u.affs_i.i_zone = 0; inode->u.affs_i.i_hlink = 0; inode->u.affs_i.i_pa_cnt = 0; inode->u.affs_i.i_pa_next = 0; inode->u.affs_i.i_pa_last = 0; inode->u.affs_i.i_ext[0] = 0; inode->u.affs_i.i_max_ext = 0; inode->u.affs_i.i_lastblock = -1; inode->i_nlink = 1; inode->i_mode = 0; if (inode->i_sb->u.affs_sb.s_flags & SF_SETMODE) inode->i_mode = inode->i_sb->u.affs_sb.s_mode; else inode->i_mode = prot_to_mode(prot); if (inode->i_sb->u.affs_sb.s_flags & SF_SETUID) inode->i_uid = inode->i_sb->u.affs_sb.s_uid; else { id = htons(file_end->owner_uid); if (inode->i_sb->u.affs_sb.s_flags & SF_MUFS) { if (id == 0 || id == 0xFFFF) id ^= ~0; } inode->i_uid = id; } if (inode->i_sb->u.affs_sb.s_flags & SF_SETGID) inode->i_gid = inode->i_sb->u.affs_sb.s_gid; else { id = htons(file_end->owner_gid); if (inode->i_sb->u.affs_sb.s_flags & SF_MUFS) { if (id == 0 || id == 0xFFFF) id ^= ~0; } inode->i_gid = id; } switch (htonl(file_end->secondary_type)) { case ST_ROOT: inode->i_uid = inode->i_sb->u.affs_sb.s_uid; inode->i_gid = inode->i_sb->u.affs_sb.s_gid; case ST_USERDIR: if (htonl(file_end->secondary_type) == ST_USERDIR || inode->i_sb->u.affs_sb.s_flags & SF_SETMODE) { if (inode->i_mode & S_IRUSR) inode->i_mode |= S_IXUSR; if (inode->i_mode & S_IRGRP) inode->i_mode |= S_IXGRP; if (inode->i_mode & S_IROTH) inode->i_mode |= S_IXOTH; inode->i_mode |= S_IFDIR; } else inode->i_mode = S_IRUGO | S_IXUGO | S_IWUSR | S_IFDIR; inode->i_size = 0; break; case ST_LINKDIR: inode->u.affs_i.i_original = htonl(file_end->original); inode->u.affs_i.i_hlink = 1; inode->i_mode |= S_IFDIR; inode->i_size = 0; break; case ST_LINKFILE: inode->u.affs_i.i_original = htonl(file_end->original); inode->u.affs_i.i_hlink = 1; if (!(lbh = affs_bread(inode->i_dev,inode->u.affs_i.i_original, AFFS_I2BSIZE(inode)))) { affs_brelse(bh); printk("AFFS: unable to read i-node block %ld\n",inode->i_ino); return; } file_end = GET_END_PTR(struct file_end,lbh->b_data,AFFS_I2BSIZE(inode)); case ST_FILE: inode->i_mode |= S_IFREG; inode->i_size = htonl(file_end->byte_size); if (inode->i_sb->u.affs_sb.s_flags & SF_OFS) block = AFFS_I2BSIZE(inode) - 24; else block = AFFS_I2BSIZE(inode); inode->u.affs_i.i_lastblock = ((inode->i_size + block - 1) / block) - 1; break; case ST_SOFTLINK: inode->i_mode |= S_IFLNK; inode->i_size = 0; break; } inode->i_mtime = inode->i_atime = inode->i_ctime = (htonl(file_end->created.ds_Days) * (24 * 60 * 60) + htonl(file_end->created.ds_Minute) * 60 + htonl(file_end->created.ds_Tick) / 50 + ((8 * 365 + 2) * 24 * 60 * 60)) + sys_tz.tz_minuteswest * 60; affs_brelse(bh); affs_brelse(lbh); inode->i_op = NULL; if (S_ISREG(inode->i_mode)) { if (inode->i_sb->u.affs_sb.s_flags & SF_OFS) { inode->i_op = &affs_file_inode_operations_ofs; } else { inode->i_op = &affs_file_inode_operations; } } else if (S_ISDIR(inode->i_mode)) inode->i_op = &affs_dir_inode_operations; else if (S_ISLNK(inode->i_mode)) inode->i_op = &affs_symlink_inode_operations;}voidaffs_write_inode(struct inode *inode){ struct buffer_head *bh; struct file_end *file_end; short uid, gid; pr_debug("AFFS: write_inode(%lu)\n",inode->i_ino); inode->i_dirt = 0; if (!inode->i_nlink) return; if (!(bh = bread(inode->i_dev,inode->i_ino,AFFS_I2BSIZE(inode)))) { printk("AFFS: Unable to read block of inode %ld on %s\n", inode->i_ino,kdevname(inode->i_dev)); return; } file_end = GET_END_PTR(struct file_end, bh->b_data,AFFS_I2BSIZE(inode)); if (file_end->secondary_type == htonl(ST_ROOT)) { secs_to_datestamp(inode->i_mtime,&ROOT_END(bh->b_data,inode)->disk_altered); } else { file_end->protect = ntohl(inode->u.affs_i.i_protect ^ FIBF_OWNER); file_end->byte_size = ntohl(inode->i_size); secs_to_datestamp(inode->i_mtime,&file_end->created); if (!(inode->i_ino == inode->i_sb->u.affs_sb.s_root_block)) { uid = inode->i_uid; gid = inode->i_gid; if (inode->i_sb->u.affs_sb.s_flags & SF_MUFS) { if (inode->i_uid == 0 || inode->i_uid == 0xFFFF) uid = inode->i_uid ^ ~0; if (inode->i_gid == 0 || inode->i_gid == 0xFFFF) gid = inode->i_gid ^ ~0; } if (!(inode->i_sb->u.affs_sb.s_flags & SF_SETUID)) file_end->owner_uid = ntohs(uid); if (!(inode->i_sb->u.affs_sb.s_flags & SF_SETGID)) file_end->owner_gid = ntohs(gid); } } affs_fix_checksum(AFFS_I2BSIZE(inode),bh->b_data,5); mark_buffer_dirty(bh,1); brelse(bh);}intaffs_notify_change(struct inode *inode, struct iattr *attr){ int error; pr_debug("AFFS: notify_change(%lu,0x%x)\n",inode->i_ino,attr->ia_valid); error = inode_change_ok(inode,attr); if (error) return error; if (((attr->ia_valid & ATTR_UID) && (inode->i_sb->u.affs_sb.s_flags & SF_SETUID)) || ((attr->ia_valid & ATTR_GID) && (inode->i_sb->u.affs_sb.s_flags & SF_SETGID)) || ((attr->ia_valid & ATTR_MODE) && (inode->i_sb->u.affs_sb.s_flags & (SF_SETMODE | SF_IMMUTABLE)))) error = -EPERM; if (error) return (inode->i_sb->u.affs_sb.s_flags & SF_QUIET) ? 0 : error; if (attr->ia_valid & ATTR_MODE) inode->u.affs_i.i_protect = mode_to_prot(attr->ia_mode); inode_setattr(inode,attr); return 0;}voidaffs_put_inode(struct inode *inode){ pr_debug("AFFS: put_inode(ino=%lu, nlink=%u)\n",inode->i_ino,inode->i_nlink); if (inode->i_nlink) { return; } inode->i_size = 0; if (S_ISREG(inode->i_mode) && !inode->u.affs_i.i_hlink) affs_truncate(inode); affs_free_block(inode->i_sb,inode->i_ino); clear_inode(inode);}struct inode *affs_new_inode(const struct inode *dir){ struct inode *inode; struct super_block *sb; int block; if (!dir || !(inode = get_empty_inode())) return NULL; sb = dir->i_sb; inode->i_sb = sb; inode->i_flags = sb->s_flags; if (!(block = affs_new_header((struct inode *)dir))) { iput(inode); return NULL; } inode->i_count = 1; inode->i_nlink = 1; inode->i_dev = sb->s_dev; inode->i_uid = current->fsuid; inode->i_gid = current->fsgid; inode->i_dirt = 1; inode->i_ino = block; inode->i_op = NULL; inode->i_blocks = 0; inode->i_size = 0; inode->i_mode = 0; inode->i_blksize = 0; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->u.affs_i.i_original = 0; inode->u.affs_i.i_parent = dir->i_ino; inode->u.affs_i.i_zone = 0; inode->u.affs_i.i_hlink = 0; inode->u.affs_i.i_pa_cnt = 0; inode->u.affs_i.i_pa_next = 0; inode->u.affs_i.i_pa_last = 0; inode->u.affs_i.i_ext[0] = 0; inode->u.affs_i.i_max_ext = 0; inode->u.affs_i.i_lastblock = -1; insert_inode_hash(inode); return inode;}intaffs_add_entry(struct inode *dir, struct inode *link, struct inode *inode, const char *name, int len, int type){ struct buffer_head *dir_bh; struct buffer_head *inode_bh; struct buffer_head *link_bh; int hash; pr_debug("AFFS: add_entry(dir=%lu,inode=%lu,\"%*s\",type=%d\n",dir->i_ino,inode->i_ino, len,name,type); dir_bh = affs_bread(dir->i_dev,dir->i_ino,AFFS_I2BSIZE(dir)); inode_bh = affs_bread(inode->i_dev,inode->i_ino,AFFS_I2BSIZE(inode)); link_bh = NULL; if (!dir_bh || !inode_bh) { affs_brelse(dir_bh); affs_brelse(inode_bh); return -ENOSPC; } if (link) { link_bh = affs_bread(link->i_dev,link->i_ino,AFFS_I2BSIZE(link)); if (!link_bh) { affs_brelse(dir_bh); affs_brelse(inode_bh); return -EINVAL; } } ((struct dir_front *)inode_bh->b_data)->primary_type = ntohl(T_SHORT); ((struct dir_front *)inode_bh->b_data)->own_key = ntohl(inode->i_ino); if (len > 30) /* truncate name quietly */ len = 30; DIR_END(inode_bh->b_data,inode)->dir_name[0] = len; strncpy(DIR_END(inode_bh->b_data,inode)->dir_name + 1,name,len); DIR_END(inode_bh->b_data,inode)->secondary_type = ntohl(type); DIR_END(inode_bh->b_data,inode)->parent = ntohl(dir->i_ino); hash = affs_hash_name(name,len,AFFS_I2FSTYPE(dir),AFFS_I2HSIZE(dir)); lock_super(inode->i_sb); DIR_END(inode_bh->b_data,inode)->hash_chain = ((struct dir_front *)dir_bh->b_data)->hashtable[hash]; ((struct dir_front *)dir_bh->b_data)->hashtable[hash] = ntohl(inode->i_ino); if (link_bh) { LINK_END(inode_bh->b_data,inode)->original = ntohl(link->i_ino); LINK_END(inode_bh->b_data,inode)->link_chain = FILE_END(link_bh->b_data,link)->link_chain; FILE_END(link_bh->b_data,link)->link_chain = ntohl(inode->i_ino); affs_fix_checksum(AFFS_I2BSIZE(link),link_bh->b_data,5); link->i_version = ++event; link->i_dirt = 1; mark_buffer_dirty(link_bh,1); } affs_fix_checksum(AFFS_I2BSIZE(inode),inode_bh->b_data,5); affs_fix_checksum(AFFS_I2BSIZE(dir),dir_bh->b_data,5); dir->i_version = ++event; dir->i_mtime = dir->i_atime = dir->i_ctime = CURRENT_TIME; unlock_super(inode->i_sb); dir->i_dirt = 1; inode->i_dirt = 1; mark_buffer_dirty(dir_bh,1); mark_buffer_dirty(inode_bh,1); affs_brelse(dir_bh); affs_brelse(inode_bh); affs_brelse(link_bh); return 0;}static struct file_system_type affs_fs_type = { affs_read_super, "affs", 1, NULL};intinit_affs_fs(void){ return register_filesystem(&affs_fs_type);}#ifdef MODULEintinit_module(void){ int status; if ((status = init_affs_fs()) == 0) register_symtab(0); return status;}voidcleanup_module(void){ unregister_filesystem(&affs_fs_type);}#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -