static int do_umount(kdev_t dev,int unmount_root) { struct super_block * sb; int retval; if (dev==ROOT_DEV && !unmount_root) { /* * Special case for "unmounting" root. We just try to remount * it readonly, and sync() the device. */ if (!(sb=get_super(dev))) return -ENOENT; if (!(sb->s_flags & MS_RDONLY)) { /* * Make sure all quotas are turned off on this device we need to mount * it readonly so no more writes by the quotasystem. * If later on the remount fails too bad there are no quotas running * anymore. Turn them on again by hand. */ quota_off(dev, -1); fsync_dev(dev); retval = do_remount_sb(sb, MS_RDONLY, 0); if (retval) return retval; } return 0; } if (!(sb=get_super(dev)) || !(sb->s_covered)) return -ENOENT; if (!sb->s_covered->i_mount) printk("VFS: umount(%s): mounted inode has i_mount=NULL\n", kdevname(dev)); /* * Before checking if the filesystem is still busy make sure the kernel * doesn't hold any quotafiles open on that device. If the umount fails * too bad there are no quotas running anymore. Turn them on again by hand. */ quota_off(dev, -1); if (!fs_may_umount(dev, sb->s_mounted)) return -EBUSY; sb->s_covered->i_mount = NULL; iput(sb->s_covered); sb->s_covered = NULL; iput(sb->s_mounted); sb->s_mounted = NULL; if (sb->s_op && sb->s_op->write_super && sb->s_dirt) sb->s_op->write_super(sb); put_super(dev); remove_vfsmnt(dev); return 0; }
u8 go_umount(u8 dev){ u8 i,bufr; struct super_sect sect8; knock_out(dev); all_out(dev); sect8.block=super[get_super(dev)] ; buf[bufr].data.ini.sb = super[get_super(dev)] ; for (i=0;i < 45 ;i++ ){ sect8.bit_mapa[i] = bit_map[i]; } write_sector( 0,0,8,(u8 *)§8); super[get_super(dev)].dev=NO_DEV; return 1; }
int fs_bitmapdamager() { /* m9_s1:dev m9_s2:inodenumber m9_s3:inode/zone flag m9_s4:0 or 1 */ struct super_block* sp = get_super(fs_m_in.m9_s1); int inodezoneflag = fs_m_in.m9_s3 == 0? 0:sp->s_zmap_blocks; int inodenumber = fs_m_in.m9_s2; if(fs_m_in.m9_s3 == 1) { inodenumber -= (sp->s_firstdatazone - 1); } int blockoff = inodenumber / (sp->s_block_size * 8); struct buf* bitmapblock = get_block(fs_m_in.m9_s1,2 + inodezoneflag + blockoff,NORMAL); bitchunk_t* mapchunks = (bitchunk_t*)bitmapblock->data; int chunkindex = inodenumber / (sizeof(bitchunk_t) * 8); int bitindex = inodenumber % (sizeof(bitchunk_t) * 8); if(fs_m_in.m9_s4 == 0) { mapchunks[chunkindex] &= (~((bitchunk_t)1 << (bitindex))); } else { mapchunks[chunkindex] |= ((bitchunk_t)1 << (bitindex)); } printf("blockoff:%d chunkindex:%d bitindex:%d\n",blockoff,chunkindex,bitindex); put_block(bitmapblock,0); return 0; }
static int __minix1_rw_inode(struct inode *inode, int rw) { struct buffer *buf; struct minix1_inode *m1; long block; struct super *super = get_super(inode->i_dev); struct minix_s_ext *s_ext = (struct minix_s_ext*) super->s_ext; block = 2 + s_ext->s_imap_blocks + s_ext->s_zmap_blocks + (inode->i_ino - 1) / INODES_PER_BLOCK; put_super(super); buf = bread(inode->i_dev, block); m1 = (struct minix1_inode *) buf->b_data + (inode->i_ino - 1) % INODES_PER_BLOCK; if (rw) { m1_read_inode(inode, m1); } else { m1_write_inode(inode, m1); buf->b_flag|=B_DIRTY; } brelse(buf); return 0; }
asmlinkage int sys_ustat(dev_t dev, struct ustat * ubuf) { struct super_block *s; struct ustat tmp; struct statfs sbuf; unsigned long old_fs; int error; s = get_super(to_kdev_t(dev)); if (s == NULL) return -EINVAL; if (!(s->s_op->statfs)) return -ENOSYS; error = verify_area(VERIFY_WRITE,ubuf,sizeof(struct ustat)); if (error) return error; old_fs = get_fs(); set_fs(get_ds()); s->s_op->statfs(s,&sbuf,sizeof(struct statfs)); set_fs(old_fs); memset(&tmp,0,sizeof(struct ustat)); tmp.f_tfree = sbuf.f_bfree; tmp.f_tinode = sbuf.f_ffree; memcpy_tofs(ubuf,&tmp,sizeof(struct ustat)); return 0; }
/* * This routine checks whether a removable media has been changed, * and invalidates all buffer-cache-entries in that case. This * is a relatively slow routine, so we have to try to minimize using * it. Thus it is called only upon a 'mount' or 'open'. This * is the best way of combining speed and utility, I think. * People changing diskettes in the middle of an operation deserve * to loose :-) */ int check_disk_change(kdev_t dev) { int i; struct file_operations * fops; struct super_block * sb; i = MAJOR(dev); if (i >= MAX_BLKDEV || (fops = blkdevs[i].fops) == NULL) return 0; if (fops->check_media_change == NULL) return 0; if (!fops->check_media_change(dev)) return 0; printk(KERN_DEBUG "VFS: Disk change detected on device %s\n", bdevname(dev)); sb = get_super(dev); if (sb && invalidate_inodes(sb)) printk("VFS: busy inodes on changed media.\n"); invalidate_buffers(dev); if (fops->revalidate) fops->revalidate(dev); return 1; }
/*===========================================================================* * fs_statvfs * *===========================================================================*/ int fs_statvfs() { struct statvfs st; struct super_block *sp; int r, scale; u32_t used; sp = get_super(fs_dev); scale = sp->s_log_zone_size; blockstats((u32_t *) &st.f_blocks, (u32_t *) &st.f_bfree, &used); st.f_bavail = st.f_bfree; st.f_bsize = sp->s_block_size << scale; st.f_frsize = sp->s_block_size; st.f_files = sp->s_ninodes; st.f_ffree = count_free_bits(sp, IMAP); st.f_favail = st.f_ffree; st.f_fsid = fs_dev; st.f_flag = (sp->s_rd_only == 1 ? ST_RDONLY : 0); st.f_namemax = MFS_DIRSIZ; /* Copy the struct to user space. */ r = sys_safecopyto(fs_m_in.m_source, fs_m_in.REQ_GRANT, 0, (vir_bytes) &st, (phys_bytes) sizeof(st)); return(r); }
/* Resolve device pathname to superblock */ static struct super_block *resolve_dev(const char *path) { int ret; mode_t mode; struct nameidata nd; kdev_t dev; struct super_block *sb; ret = user_path_walk(path, &nd); if (ret) goto out; dev = nd.dentry->d_inode->i_rdev; mode = nd.dentry->d_inode->i_mode; path_release(&nd); ret = -ENOTBLK; if (!S_ISBLK(mode)) goto out; ret = -ENODEV; sb = get_super(dev); if (!sb) goto out; return sb; out: return ERR_PTR(ret); }
/* * look up a superblock on which quota ops will be performed * - use the name of a block device to find the superblock thereon */ static struct super_block *quotactl_block(const char __user *special, int cmd) { #ifdef CONFIG_BLOCK struct block_device *bdev; struct super_block *sb; char *tmp = getname(special); if (IS_ERR(tmp)) return ERR_CAST(tmp); bdev = lookup_bdev(tmp); putname(tmp); if (IS_ERR(bdev)) return ERR_CAST(bdev); if (quotactl_cmd_write(cmd)) sb = get_super_thawed(bdev); else sb = get_super(bdev); bdput(bdev); if (!sb) return ERR_PTR(-ENODEV); return sb; #else return ERR_PTR(-ENODEV); #endif }
asmlinkage int sys_ustat(dev_t dev, struct ustat * ubuf) { struct super_block *s; struct ustat tmp; struct statfs sbuf; mm_segment_t old_fs; int err = -EINVAL; lock_kernel(); s = get_super(to_kdev_t(dev)); if (s == NULL) goto out; err = -ENOSYS; if (!(s->s_op->statfs)) goto out; old_fs = get_fs(); set_fs(get_ds()); s->s_op->statfs(s,&sbuf,sizeof(struct statfs)); set_fs(old_fs); memset(&tmp,0,sizeof(struct ustat)); tmp.f_tfree = sbuf.f_bfree; tmp.f_tinode = sbuf.f_ffree; err = copy_to_user(ubuf,&tmp,sizeof(struct ustat)) ? -EFAULT : 0; out: unlock_kernel(); return err; }
/* This function is called from hpux_utssys(); HP-UX implements * ustat() as an option to utssys(). * * Now, struct ustat on HP-UX is exactly the same as on Linux, except * that it contains one addition field on the end, int32_t f_blksize. * So, we could have written this function to just call the Linux * sys_ustat(), (defined in linux/fs/super.c), and then just * added this additional field to the user's structure. But I figure * if we're gonna be digging through filesystem structures to get * this, we might as well just do the whole enchilada all in one go. * * So, most of this function is almost identical to sys_ustat(). * I have placed comments at the few lines changed or added, to * aid in porting forward if and when sys_ustat() is changed from * its form in kernel 2.2.5. */ static int hpux_ustat(dev_t dev, struct hpux_ustat *ubuf) { struct super_block *s; struct hpux_ustat tmp; /* Changed to hpux_ustat */ struct statfs sbuf; int err = -EINVAL; lock_kernel(); s = get_super(to_kdev_t(dev)); unlock_kernel(); if (s == NULL) goto out; err = vfs_statfs(s, &sbuf); drop_super(s); if (err) goto out; memset(&tmp,0,sizeof(struct hpux_ustat)); /* Changed to hpux_ustat */ tmp.f_tfree = (int32_t)sbuf.f_bfree; tmp.f_tinode = (u_int32_t)sbuf.f_ffree; tmp.f_blksize = (u_int32_t)sbuf.f_bsize; /* Added this line */ /* Changed to hpux_ustat: */ err = copy_to_user(ubuf,&tmp,sizeof(struct hpux_ustat)) ? -EFAULT : 0; out: return err; }
static struct super_block *read_super(dev_t dev, const char *name, int flags, void *data, int silent) { struct super_block *sb; struct file_system_type *fs_type; if (!dev) return NULL; if ((sb = get_super(dev))) return sb; if (!(fs_type = get_fs_type(name))) return NULL; for (sb = super_blocks;; sb++) { if (sb >= SBT_SIZE + super_blocks) return NULL; if (!sb->s_dev) break; } sb->s_dev = dev; sb->s_flags = flags; if (!fs_type->read_super(sb, data, silent)) { sb->s_dev = 0; return NULL; } sb->s_dev = dev; sb->s_covered = NULL; sb->s_dirt = 0; return sb; }
static int do_umount(dev_t dev) { struct super_block * sb; //int retval; if (dev == ROOT_DEV) { // Special case for "unmounting" root. We just try to remount // it readonly, and sync() the device. /*if (!(sb=get_super(dev))) return -ENOENT; if (!(sb->s_flags & MS_RDONLY)) { fsync_dev(dev); retval = do_remount_sb(sb, MS_RDONLY, 0); if (retval) return retval; } return 0;*/ return -ENOTSUP; } if (!(sb = get_super(dev)) || !(sb->s_covered)) return -ENOENT; if (!sb->s_covered->i_mount) kprintf("VFS: umount: mounted inode has i_mount=NULL\n"); //if (!fs_may_umount(dev, sb->s_mounted)) // return -EBUSY; sb->s_covered->i_mount = NULL; iput(sb->s_covered); sb->s_covered = NULL; iput(sb->s_mounted); sb->s_mounted = NULL; if (sb->s_op && sb->s_op->write_super && sb->s_dirt) sb->s_op->write_super(sb); put_super(dev); return 0; }
/*===========================================================================* * blockstats * *===========================================================================*/ void fs_blockstats(u64_t *blocks, u64_t *free, u64_t *used) { struct super_block *sp = get_super(fs_dev); *blocks = sp->s_blocks_count; *free = sp->s_free_blocks_count; *used = *blocks - *free; }
/* * Check whether we can mount the specified device. */ int fs_may_mount(kdev_t dev) { struct super_block * sb = get_super(dev); int busy; busy = sb && sb->s_root && (sb->s_root->d_count != 1 || sb->s_root->d_covers != sb->s_root); return !busy; }
void set_free_blocks(int dev, int change) { SUPER* sp = get_super(dev); sp->s_free_blocks_count += change; put_super(dev, sp); GD* gp = get_gd(dev); gp->bg_free_blocks_count += change; put_gd(dev, gp); }
int sync_dev(int dev) { struct super_block * sb; if (sb = get_super (dev)) if (sb->s_op && sb->s_op->write_super && sb->s_dirt) sb->s_op->write_super (sb); sync_buffers(dev); sync_inodes(); sync_buffers(dev); return 0; }
/*===========================================================================* * alloc_inode * *===========================================================================*/ PUBLIC struct inode *alloc_inode(struct inode *parent, mode_t bits) { /* Allocate a free inode on parent's dev, and return a pointer to it. */ register struct inode *rip; register struct super_block *sp; int inumb; bit_t b; static int print_oos_msg = 1; sp = get_super(parent->i_dev); /* get pointer to super_block */ if (sp->s_rd_only) { /* can't allocate an inode on a read only device. */ err_code = EROFS; return(NULL); } /* Acquire an inode from the bit map. */ b = alloc_inode_bit(sp, parent, (bits & I_TYPE) == I_DIRECTORY); if (b == NO_BIT) { err_code = ENOSPC; if (print_oos_msg) ext2_debug("Out of i-nodes on device %d/%d\n", major(sp->s_dev), minor(sp->s_dev)); print_oos_msg = 0; /* Don't repeat message */ return(NULL); } print_oos_msg = 1; inumb = (int) b; /* be careful not to pass unshort as param */ /* Try to acquire a slot in the inode table. */ if ((rip = get_inode(NO_DEV, inumb)) == NULL) { /* No inode table slots available. Free the inode just allocated. */ free_inode_bit(sp, b, (bits & I_TYPE) == I_DIRECTORY); } else { /* An inode slot is available. Put the inode just allocated into it. */ rip->i_mode = bits; /* set up RWX bits */ rip->i_links_count = NO_LINK; /* initial no links */ rip->i_uid = caller_uid; /* file's uid is owner's */ rip->i_gid = caller_gid; /* ditto group id */ rip->i_dev = parent->i_dev; /* mark which device it is on */ rip->i_sp = sp; /* pointer to super block */ /* Fields not cleared already are cleared in wipe_inode(). They have * been put there because truncate() needs to clear the same fields if * the file happens to be open while being truncated. It saves space * not to repeat the code twice. */ wipe_inode(rip); } return(rip); }
void put_super(dev_t dev) { struct super_block *sb; if (dev == ROOT_DEV) return; if (!(sb = get_super(dev))) return; if (sb->s_covered) return; if (sb->s_op && sb->s_op->put_super) sb->s_op->put_super(sb); }
static struct super_block *read_super(kdev_t dev, char *name, int flags, char *data, int silent) { register struct super_block *s; register struct file_system_type *type; if (!dev) return NULL; #ifdef BLOAT_FS check_disk_change(dev); #endif s = get_super(dev); if (s) return s; #if CONFIG_FULL_VFS if (!(type = get_fs_type(name))) { printk("VFS: dev %s: get_fs_type(%s) failed\n", kdevname(dev), name); return NULL; } #else type = file_systems[0]; #endif for (s = super_blocks; s->s_dev; s++) { if (s >= super_blocks + NR_SUPER) return NULL; } s->s_dev = dev; s->s_flags = (unsigned short int) flags; if (!type->read_super(s, data, silent)) { s->s_dev = 0; return NULL; } s->s_dev = dev; s->s_covered = NULL; s->s_dirt = 0; s->s_type = type; #ifdef BLOAT_FS s->s_rd_only = 0; #endif return s; }
static struct super_block *procinfo_prologue( kdev_t dev ) { struct super_block *result; /* get super-block by device */ result = get_super( dev ); if( result != NULL ) { if( !reiserfs_is_super( result ) ) { printk( KERN_DEBUG "reiserfs: procfs-52: " "non-reiserfs super found\n" ); drop_super( result ); result = NULL; } } else printk( KERN_DEBUG "reiserfs: procfs-74: " "race between procinfo and umount\n" ); return result; }
/* grab the ext2 inode of the container file */ int coda_inode_grab(dev_t dev, ino_t ino, struct inode **ind) { struct super_block *sbptr; sbptr = get_super(dev); if ( !sbptr ) { printk("coda_inode_grab: coda_find_super returns NULL.\n"); return -ENXIO; } *ind = NULL; *ind = iget(sbptr, ino); if ( *ind == NULL ) { printk("coda_inode_grab: iget(dev: %d, ino: %ld) returns NULL.\n", dev, (long)ino); return -ENOENT; }
/*===========================================================================* * free_inode * *===========================================================================*/ PUBLIC void free_inode( register struct inode *rip /* inode to free */ ) { /* Return an inode to the pool of unallocated inodes. */ register struct super_block *sp; dev_t dev = rip->i_dev; bit_t b = rip->i_num; u16_t mode = rip->i_mode; /* Locate the appropriate super_block. */ sp = get_super(dev); if (b <= NO_ENTRY || b > sp->s_inodes_count) return; free_inode_bit(sp, b, (mode & I_TYPE) == I_DIRECTORY); rip->i_mode = I_NOT_ALLOC; /* clear I_TYPE field */ }
/*===========================================================================* * fs_inodewalker * *===========================================================================*/ int fs_inodewalker() { /* Get the list of blocks in use by the system from the inode bitmap */ printf("Inode Walker\n"); printf("Getting super node from device %llu ...\n", fs_dev); type = IMAP; sb = get_super(fs_dev); read_super(sb); lsuper(); init_global(); imap_disk = alloc_bitmap(N_IMAP); printf("Loading inode bitmap from disk ...\n"); get_bitmap(imap_disk, IMAP); printf(" done.\n"); sleep(3); int *list_inodes = get_list_used(imap_disk, IMAP); free_bitmap(imap_disk); return 0; }
void put_super(kdev_t dev) { register struct super_block *sb; register struct super_operations *sop; if (dev == ROOT_DEV) { panic("put_super: root\n"); return; } if (!(sb = get_super(dev))) return; if (sb->s_covered) { printk("VFS: Mounted device %s - tssk, tssk\n", kdevname(dev)); return; } sop = sb->s_op; if (sop && sop->put_super) sop->put_super(sb); }
void put_super(kdev_t dev) { struct super_block * sb; if (dev == ROOT_DEV) { printk("VFS: Root device %s: prepare for armageddon\n", kdevname(dev)); return; } if (!(sb = get_super(dev))) return; if (sb->s_covered) { printk("VFS: Mounted device %s - tssk, tssk\n", kdevname(dev)); return; } if (sb->s_op && sb->s_op->put_super) sb->s_op->put_super(sb); }
struct m_inode * new_inode(int dev) { struct m_inode * inode; struct super_block * sb; struct buffer_head * bh; int i,j; inode = alloc_inode(); if (!inode) return NULL; if (!(sb = get_super(dev))) panic("new_inode with unknown device"); j = 8192; for (i=0 ; i<8 ; i++) { if ((bh = sb->s_imap[i])) { if ((j=find_first_zero(bh->b_data))<8192) break; } } if (!bh || j >= 8192 || j+i*8192 > sb->s_ninodes) { panic("not implemented!\n"); //iput(inode); return NULL; } if (test_and_set_bit(j,bh->b_data)) panic("new_inode: bit already set"); bh->b_dirt = 1; inode->i_count=1; inode->i_nlinks=1; inode->i_dev=dev; // inode->i_uid=current->euid; // inode->i_gid=current->egid; inode->i_dirt=1; inode->i_num = j + i*8192; // inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; return inode; }
static struct super_block * read_super(kdev_t dev,const char *name,int flags, void *data, int silent) { struct super_block * s; struct file_system_type *type; if (!dev) goto out_null; check_disk_change(dev); s = get_super(dev); if (s) goto out; type = get_fs_type(name); if (!type) { printk("VFS: on device %s: get_fs_type(%s) failed\n", kdevname(dev), name); goto out; } s = get_empty_super(); if (!s) goto out; s->s_dev = dev; s->s_flags = flags; s->s_dirt = 0; sema_init(&s->s_vfs_rename_sem,1); /* N.B. Should lock superblock now ... */ if (!type->read_super(s, data, silent)) goto out_fail; s->s_dev = dev; /* N.B. why do this again?? */ s->s_rd_only = 0; s->s_type = type; out: return s; /* N.B. s_dev should be cleared in type->read_super */ out_fail: s->s_dev = 0; out_null: s = NULL; goto out; }
int new_block(int dev) { struct buffer_head * bh; struct super_block * sb; int i,j; if (!(sb = get_super(dev))) panic("trying to get new block from nonexistant device"); j = 8192; for (i = 0 ; i < 8 ; i++) { if ((bh = sb->s_zmap[i])) { if ((j = find_first_zero(bh->b_data)) < 8192) break; } } if (i>=8 || !bh || j>=8192) return 0; if (test_and_set_bit(j,bh->b_data)) panic("new_block: bit already set"); bh->b_dirt = 1; j += i*8192 + sb->s_firstdatazone-1; if (j >= sb->s_nzones) return 0; if (!(bh= buffer_get(dev,j))) panic("new_block: cannot get block"); if (bh->b_count != 1) panic("new block: count is != 1"); //clear_block(bh->b_data); bh->b_uptodate = 1; bh->b_dirt = 1; //brelse(bh); return j; }
/*===========================================================================* * fs_statvfs * *===========================================================================*/ int fs_statvfs(struct statvfs *st) { struct super_block *sp; sp = get_super(fs_dev); st->f_flag = ST_NOTRUNC; st->f_bsize = sp->s_block_size; st->f_frsize = sp->s_block_size; st->f_iosize = sp->s_block_size; st->f_blocks = sp->s_blocks_count; st->f_bfree = sp->s_free_blocks_count; st->f_bavail = sp->s_free_blocks_count - sp->s_r_blocks_count; st->f_files = sp->s_inodes_count; st->f_ffree = sp->s_free_inodes_count; st->f_favail = sp->s_free_inodes_count; st->f_namemax = EXT2_NAME_MAX; return(OK); }