示例#1
0
文件: inode.c 项目: lkundrak/elks
void iput(register struct inode *inode)
{
    if (inode) {
	wait_on_inode(inode);
	if (!inode->i_count) {
	    printk("VFS: iput: trying to free free inode\n");
	    printk("VFS: device %s, inode %lu, mode=0%07o\n",
		   kdevname(inode->i_rdev), inode->i_ino, inode->i_mode);
	    return;
	}
#ifdef NOT_YET
	if (inode->i_pipe)
	    wake_up_interruptible(&PIPE_WAIT(*inode));
#endif
      repeat:
	if (inode->i_count > 1) {
	    inode->i_count--;
	    return;
	}

	wake_up(&inode_wait);
#ifdef NOT_YET
	if (inode->i_pipe) {
	    /* Free up any memory allocated to the pipe */
	}
#endif

	if (inode->i_sb) {
	    struct super_operations *sop = inode->i_sb->s_op;
	    if (sop && sop->put_inode) {
		sop->put_inode(inode);
		if (!inode->i_nlink)
		    return;
	    }
	}

	if (inode->i_dirt) {
	    write_inode(inode);	/* we can sleep - so do again */
	    wait_on_inode(inode);
	    goto repeat;
	}
	inode->i_count--;
	nr_free_inodes++;
    }

    return;
}
示例#2
0
/* return 1 if this is not super block */
static int print_super_block (struct buffer_head * bh)
{
    struct reiserfs_super_block * rs = (struct reiserfs_super_block *)(bh->b_data);
    int skipped, data_blocks;
    char *version;
    

    if (strncmp (rs->s_magic,  REISERFS_SUPER_MAGIC_STRING,
                 strlen ( REISERFS_SUPER_MAGIC_STRING)) == 0) {
        version = "3.5";
    } else if( strncmp (rs->s_magic,  REISER2FS_SUPER_MAGIC_STRING,
                        strlen ( REISER2FS_SUPER_MAGIC_STRING)) == 0) {
        version = "3.6";
    } else {
	return 1;
    }

    printk ("%s\'s super block in block %ld\n======================\n",
            kdevname (bh->b_dev), bh->b_blocknr);
    printk ("Reiserfs version %s\n", version );
    printk ("Block count %u\n", sb_block_count(rs));
    printk ("Blocksize %d\n", sb_blocksize(rs));
    printk ("Free blocks %u\n", sb_free_blocks(rs));
    // FIXME: this would be confusing if
    // someone stores reiserfs super block in some data block ;)
//    skipped = (bh->b_blocknr * bh->b_size) / sb_blocksize(rs);
    skipped = bh->b_blocknr;
    data_blocks = sb_block_count(rs) - skipped - 1 -
                  sb_bmap_nr(rs) - (sb_orig_journal_size(rs) + 1) -
                  sb_free_blocks(rs);
    printk ("Busy blocks (skipped %d, bitmaps - %d, journal blocks - %d\n"
	    "1 super blocks, %d data blocks\n", 
	    skipped, sb_bmap_nr(rs), 
	    (sb_orig_journal_size(rs) + 1), data_blocks);
    printk ("Root block %u\n", sb_root_block(rs));
    printk ("Journal block (first) %d\n", sb_journal_block(rs));
    printk ("Journal dev %d\n", sb_journal_dev(rs));
    printk ("Journal orig size %d\n", sb_orig_journal_size(rs));
    printk ("Filesystem state %s\n", 
	    (sb_state(rs) == REISERFS_VALID_FS) ? "VALID" : "ERROR");
    printk ("Hash function \"%s\"\n",
            sb_hash_function_code(rs) == TEA_HASH ? "tea" :
	    ( sb_hash_function_code(rs) == YURA_HASH ? "rupasov" : (sb_hash_function_code(rs) == R5_HASH ? "r5" : "unknown")));

    printk ("Tree height %d\n", sb_tree_height(rs));
    return 0;
}
示例#3
0
文件: super.c 项目: lithoxs/elks
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;
}
示例#4
0
static int mcdx_media_changed(struct cdrom_device_info * cdi, int disc_nr) 
/*	Return: 1 if media changed since last call to this function
			0 otherwise */
{
    struct s_drive_stuff *stuffp;

    xinfo("mcdx_media_changed called for device %s\n",
	  kdevname(cdi->dev));

	stuffp = mcdx_stuffp[MINOR(cdi->dev)];
	mcdx_getstatus(stuffp, 1);

	if (stuffp->yyy == 0) return 0;

	stuffp->yyy = 0;
	return 1;
}
示例#5
0
int sysv_unlink(struct inode * dir, struct dentry * dentry)
{
	int retval;
	struct inode * inode;
	struct buffer_head * bh;
	struct sysv_dir_entry * de;

repeat:
	retval = -ENOENT;
	inode = NULL;
	bh = sysv_find_entry(dir, dentry->d_name.name,
                             dentry->d_name.len, &de);
	if (!bh)
		goto end_unlink;
	inode = dentry->d_inode;

	retval = -EPERM;
	if (de->inode != inode->i_ino) {
		brelse(bh);
		current->counter = 0;
		schedule();
		goto repeat;
	}
	if (de->inode != inode->i_ino) {
		retval = -ENOENT;
		goto end_unlink;
	}
	if (!inode->i_nlink) {
		printk("Deleting nonexistent file (%s:%lu), %d\n",
		        kdevname(inode->i_dev), inode->i_ino, inode->i_nlink);
		inode->i_nlink=1;
	}
	de->inode = 0;
	mark_buffer_dirty(bh, 1);
	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
	mark_inode_dirty(dir);
	inode->i_nlink--;
	inode->i_ctime = dir->i_ctime;
	mark_inode_dirty(inode);
	d_delete(dentry);
	retval = 0;
end_unlink:
	brelse(bh);
	return retval;
}
示例#6
0
文件: inode.c 项目: lkundrak/elks
void invalidate_inodes(kdev_t dev)
{
    register struct inode *inode, *next;
    int i;

    next = first_inode;
    for (i = nr_inodes; i > 0; i--) {
	inode = next;
	next = inode->i_next;	/* clear_inode() changes the queues.. */
	if (inode->i_dev != dev)
	    continue;
	if (inode->i_count || inode->i_dirt || inode->i_lock) {
	    printk("VFS: inode busy on removed device %s\n", kdevname(dev));
	    continue;
	}
	clear_inode(inode);
    }
}
示例#7
0
文件: super.c 项目: lithoxs/elks
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);
}
示例#8
0
/*
 * Function:    scsi_end_request()
 *
 * Purpose:     Post-processing of completed commands called from interrupt
 *              handler or a bottom-half handler.
 *
 * Arguments:   SCpnt    - command that is complete.
 *              uptodate - 1 if I/O indicates success, 0 for I/O error.
 *              sectors  - number of sectors we want to mark.
 *		requeue  - indicates whether we should requeue leftovers.
 *		frequeue - indicates that if we release the command block
 *			   that the queue request function should be called.
 *
 * Lock status: Assumed that lock is not held upon entry.
 *
 * Returns:     Nothing
 *
 * Notes:       This is called for block device requests in order to
 *              mark some number of sectors as complete.
 * 
 *		We are guaranteeing that the request queue will be goosed
 *		at some point during this call.
 */
static Scsi_Cmnd *__scsi_end_request(Scsi_Cmnd * SCpnt, 
				     int uptodate, 
				     int sectors,
				     int requeue,
				     int frequeue)
{
	request_queue_t *q = &SCpnt->device->request_queue;
	struct request *req;
	struct buffer_head *bh;
	unsigned long flags;
	int nsect;

	ASSERT_LOCK(&io_request_lock, 0);

	req = &SCpnt->request;
	req->errors = 0;
	if (!uptodate) {
		printk(" I/O error: dev %s, sector %lu\n",
		       kdevname(req->rq_dev), req->sector);
	}
	do {
		if ((bh = req->bh) != NULL) {
			nsect = bh->b_size >> 9;
			blk_finished_io(nsect);
			blk_finished_sectors(req, nsect);
			req->bh = bh->b_reqnext;
			bh->b_reqnext = NULL;
			sectors -= nsect;
			bh->b_end_io(bh, uptodate);
			if ((bh = req->bh) != NULL) {
				req->hard_sector += nsect;
				req->hard_nr_sectors -= nsect;
				req->sector += nsect;
				req->nr_sectors -= nsect;

				req->current_nr_sectors = bh->b_size >> 9;
				req->hard_cur_sectors = req->current_nr_sectors;
				if (req->nr_sectors < req->current_nr_sectors) {
					req->nr_sectors = req->current_nr_sectors;
					printk("scsi_end_request: buffer-list destroyed\n");
				}
			}
		}
示例#9
0
文件: inode.c 项目: lithoxs/elks
void iput(register struct inode *inode)
{
    register struct super_operations *sop;

    if (inode) {
	wait_on_inode(inode);
	if (!inode->i_count) {
	    printk("VFS: iput: trying to free free inode\n");
	    printk("VFS: device %s, inode %lu, mode=0%07o\n",
		   kdevname(inode->i_rdev), inode->i_ino, inode->i_mode);
	    return;
	}
#ifdef NOT_YET
	if ((inode->i_mode & S_IFMT) == S_IFIFO)
	    wake_up_interruptible(&PIPE_WAIT(*inode));
#endif
	goto ini_loop;
	do {
	    write_inode(inode);	/* we can sleep - so do again */
	    wait_on_inode(inode);
      ini_loop:
	    if (inode->i_count > 1) {
		inode->i_count--;
		return;
	    }

	    wake_up(&inode_wait);

	    if (inode->i_sb) {
		sop = inode->i_sb->s_op;
		if (sop && sop->put_inode) {
		    sop->put_inode(inode);
		    if (!inode->i_nlink)
			return;
		}
	    }

	} while (inode->i_dirt);
	inode->i_count--;
	nr_free_inodes++;
    }
}
示例#10
0
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;
}
示例#11
0
NORET_TYPE void ext2_panic (struct super_block * sb, const char * function,
			    const char * fmt, ...)
{
	va_list args;

	if (!(sb->s_flags & MS_RDONLY)) {
		sb->u.ext2_sb.s_mount_state |= EXT2_ERROR_FS;
		sb->u.ext2_sb.s_es->s_state |= EXT2_ERROR_FS;
		mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1);
		sb->s_dirt = 1;
	}
	va_start (args, fmt);
	vsprintf (error_buf, fmt, args);
	va_end (args);
	/* this is to prevent panic from syncing this filesystem */
	if (sb->s_lock)
		sb->s_lock=0;
	sb->s_flags |= MS_RDONLY;
	panic ("EXT2-fs panic (device %s): %s: %s\n",
	       kdevname(sb->s_dev), function, error_buf);
}
示例#12
0
/*
 * Swap partitions are now read via brw_page.  ll_rw_page is an
 * asynchronous function now --- we must call wait_on_page afterwards
 * if synchronous IO is required.  
 */
void ll_rw_page(int rw, kdev_t dev, unsigned long page, char * buffer)
{
	int block = page;

	switch (rw) {
		case READ:
			break;
		case WRITE:
			if (is_read_only(dev)) {
				printk("Can't page to read-only device %s\n",
					kdevname(dev));
				return;
			}
			break;
		default:
			panic("ll_rw_page: bad block dev cmd, must be R/W");
	}
	if (set_bit(PG_locked, &mem_map[MAP_NR(buffer)].flags))
		panic ("ll_rw_page: page already locked");
	brw_page(rw, (unsigned long) buffer, dev, &block, PAGE_SIZE, 0);
}
示例#13
0
/* do_emergency_sync helper function */
static void go_sync(struct super_block *sb, int remount_flag)
{
	int orig_loglevel;
	orig_loglevel = console_loglevel;
	console_loglevel = 7;
	printk(KERN_INFO "%sing device %s ... ",
	       remount_flag ? "Remount" : "Sync",
	       kdevname(sb->s_dev));

	if (remount_flag) { /* Remount R/O */
		int ret, flags;
		struct list_head *p;

		if (sb->s_flags & MS_RDONLY) {
			printk("R/O\n");
			return;
		}

		file_list_lock();
		for (p = sb->s_files.next; p != &sb->s_files; p = p->next) {
			struct file *file = list_entry(p, struct file, f_list);
			if (file->f_dentry && file_count(file)
				&& S_ISREG(file->f_dentry->d_inode->i_mode))
				file->f_mode &= ~2;
		}
		file_list_unlock();
		DQUOT_OFF(sb);
		fsync_dev(sb->s_dev);
		flags = MS_RDONLY;
		if (sb->s_op && sb->s_op->remount_fs) {
			ret = sb->s_op->remount_fs(sb, &flags, NULL);
			if (ret)
				printk("error %d\n", ret);
			else {
				sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
				printk("OK\n");
			}
		} else
			printk("nothing to do\n");
	} else { /* Sync only */
示例#14
0
文件: super.c 项目: hugh712/Jollen
void ufs_panic (struct super_block * sb, const char * function,
	const char * fmt, ...)
{
	struct ufs_sb_private_info * uspi;
	struct ufs_super_block_first * usb1;
	va_list args;
	
	uspi = sb->u.ufs_sb.s_uspi;
	usb1 = ubh_get_usb_first(USPI_UBH);
	
	if (!(sb->s_flags & MS_RDONLY)) {
		usb1->fs_clean = UFS_FSBAD;
		ubh_mark_buffer_dirty(USPI_UBH);
		sb->s_dirt = 1;
	}
	va_start (args, fmt);
	vsprintf (error_buf, fmt, args);
	va_end (args);
	sb->s_flags |= MS_RDONLY;
	printk (KERN_CRIT "UFS-fs panic (device %s): %s: %s\n",
		kdevname(sb->s_dev), function, error_buf);
}
示例#15
0
static void go_sync(kdev_t dev, int remount_flag)
{
	printk(KERN_INFO "%sing device %s ... ",
	       remount_flag ? "Remount" : "Sync",
	       kdevname(dev));

	if (remount_flag) {				    /* Remount R/O */
		struct super_block *sb = get_super(dev);
		struct vfsmount *vfsmnt;
		int ret, flags;

		if (!sb) {
			printk("Superblock not found\n");
			return;
		}
		if (sb->s_flags & MS_RDONLY) {
			printk("R/O\n");
			return;
		}
		DQUOT_OFF(dev);
		fsync_dev(dev);
		flags = MS_RDONLY;
		if (sb->s_op && sb->s_op->remount_fs) {
			ret = sb->s_op->remount_fs(sb, &flags, NULL);
			if (ret)
				printk("error %d\n", ret);
			else {
				sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
				if ((vfsmnt = lookup_vfsmnt(sb->s_dev)))
					vfsmnt->mnt_flags = sb->s_flags;
				printk("OK\n");
			}
		} else
			printk("nothing to do\n");
	} else {
		fsync_dev(dev);				    /* Sync only */
		printk("OK\n");
	}
}
示例#16
0
static char *lock_get_status(struct file_lock *fl, char *p, int id, char *pfx)
{
	struct wait_queue *wt;

	p += sprintf(p, "%d:%s ", id, pfx);
	if (fl->fl_flags & F_POSIX) {
#ifdef CONFIG_LOCK_MANDATORY	 
		p += sprintf(p, "%s %s ",
			     (fl->fl_flags & F_BROKEN) ? "BROKEN" : "POSIX ",
			     ((fl->fl_file->f_inode->i_mode & (S_IXGRP | S_ISGID))
			      == S_ISGID) ? "MANDATORY" : "ADVISORY ");
#else
		p += sprintf(p, "%s ADVISORY ",
			     (fl->fl_flags & F_BROKEN) ? "BROKEN" : "POSIX ");
#endif
	}
	else {
		p += sprintf(p, "FLOCK  ADVISORY  ");
	}
	p += sprintf(p, "%s ", (fl->fl_type == F_RDLCK) ? "READ " : "WRITE");
	p += sprintf(p, "%d %s:%ld %ld %ld ",
		     fl->fl_owner ? fl->fl_owner->pid : 0,
		     kdevname(fl->fl_file->f_inode->i_dev),
		     fl->fl_file->f_inode->i_ino, fl->fl_start,
		     fl->fl_end);
	p += sprintf(p, "%08lx %08lx %08lx %08lx %08lx\n%d:%s",
		     (long)fl, (long)fl->fl_prevlink, (long)fl->fl_nextlink,
		     (long)fl->fl_next, (long)fl->fl_block, id, pfx);
	if ((wt = fl->fl_wait) != NULL) {
		do {
			p += sprintf(p, " %d", wt->task->pid);
			wt = wt->next;
		} while (wt != fl->fl_wait);
	}
	p += sprintf(p, "\n");
	return (p);
}
示例#17
0
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)
		return NULL;
	check_disk_change(dev);
	s = get_super(dev);
	if (s)
		return s;
	if (!(type = get_fs_type(name))) {
		printk("VFS: on device %s: get_fs_type(%s) failed\n",
		       kdevname(dev), name);
		return NULL;
	}
	for (s = 0+super_blocks ;; s++) {
		if (s >= NR_SUPER+super_blocks)
			return NULL;
		if (!(s->s_dev))
			break;
	}
	s->s_dev = dev;
	s->s_flags = flags;
	if (!type->read_super(s,data, silent)) {
		s->s_dev = 0;
		return NULL;
	}
	s->s_dev = dev;
	s->s_covered = NULL;
	s->s_rd_only = 0;
	s->s_dirt = 0;
	s->s_type = type;
	return s;
}
示例#18
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 lose :-)
 */
int check_disk_change(kdev_t dev)
{
    register struct file_operations *fops;
    int i;

    i = MAJOR(dev);
    if (i >= MAX_BLKDEV || (fops = blkdevs[i].ds_fops) == NULL)
	return 0;
    if (fops->check_media_change == NULL)
	return 0;
    if (!fops->check_media_change(dev))
	return 0;

    printk("VFS: Disk change detected on device %s\n", kdevname(dev));
    for (i = 0; i < NR_SUPER; i++)
	if (super_blocks[i].s_dev == dev)
	    put_super(super_blocks[i].s_dev);
    invalidate_inodes(dev);
    invalidate_buffers(dev);

    if (fops->revalidate)
	fops->revalidate(dev);
    return 1;
}
示例#19
0
文件: inode-v23.c 项目: nhanh0/hah
/* This function is called when the file system is umounted.  */
static void
jffs_put_super(struct super_block *sb)
{
	struct jffs_control *c = (struct jffs_control *) sb->u.generic_sbp;
	D1(kdev_t dev = sb->s_dev);

	D2(printk("jffs_put_super()\n"));

#ifdef CONFIG_JFFS_PROC_FS
	jffs_unregister_jffs_proc_dir(c);
#endif

	if (c->gc_task) {
		D1(printk (KERN_NOTICE "jffs_put_super(): Telling gc thread to die.\n"));
		send_sig(SIGKILL, c->gc_task, 1);
	}
	wait_for_completion(&c->gc_thread_comp);

	D1(printk (KERN_NOTICE "jffs_put_super(): Successfully waited on thread.\n"));

	jffs_cleanup_control((struct jffs_control *)sb->u.generic_sbp);
	D1(printk(KERN_NOTICE "JFFS: Successfully unmounted device %s.\n",
	       kdevname(dev)));
}
示例#20
0
void nftl_request(RQFUNC_ARG)
{
	unsigned int dev, block, nsect;
	struct NFTLrecord *nftl;
	char *buffer;
	struct request *req;
	int res;

	while (1) {
		INIT_REQUEST;	/* blk.h */
		req = CURRENT;
		
		/* We can do this because the generic code knows not to
		   touch the request at the head of the queue */
		spin_unlock_irq(&io_request_lock);

		DEBUG(MTD_DEBUG_LEVEL2, "NFTL_request\n");
		DEBUG(MTD_DEBUG_LEVEL3, "NFTL %s request, from sector 0x%04lx for 0x%04lx sectors\n",
		      (req->cmd == READ) ? "Read " : "Write",
		      req->sector, req->current_nr_sectors);

		dev = MINOR(req->rq_dev);
		block = req->sector;
		nsect = req->current_nr_sectors;
		buffer = req->buffer;
		res = 1; /* succeed */

		if (dev >= MAX_NFTLS * (1<<NFTL_PARTN_BITS)) {
			/* there is no such partition */
			printk("nftl: bad minor number: device = %s\n",
			       kdevname(req->rq_dev));
			res = 0; /* fail */
			goto repeat;
		}
		
		nftl = NFTLs[dev / (1<<NFTL_PARTN_BITS)];
		DEBUG(MTD_DEBUG_LEVEL3, "Waiting for mutex\n");
		down(&nftl->mutex);
		DEBUG(MTD_DEBUG_LEVEL3, "Got mutex\n");

		if (block + nsect > part_table[dev].nr_sects) {
			/* access past the end of device */
			printk("nftl%c%d: bad access: block = %d, count = %d\n",
			       (MINOR(req->rq_dev)>>6)+'a', dev & 0xf, block, nsect);
			up(&nftl->mutex);
			res = 0; /* fail */
			goto repeat;
		}
		
		block += part_table[dev].start_sect;
		
		if (req->cmd == READ) {
			DEBUG(MTD_DEBUG_LEVEL2, "NFTL read request of 0x%x sectors @ %x "
			      "(req->nr_sectors == %lx)\n", nsect, block, req->nr_sectors);
	
			for ( ; nsect > 0; nsect-- , block++, buffer += 512) {
				/* Read a single sector to req->buffer + (512 * i) */
				if (NFTL_readblock(nftl, block, buffer)) {
					DEBUG(MTD_DEBUG_LEVEL2, "NFTL read request failed\n");
					up(&nftl->mutex);
					res = 0;
					goto repeat;
				}
			}

			DEBUG(MTD_DEBUG_LEVEL2,"NFTL read request completed OK\n");
			up(&nftl->mutex);
			goto repeat;
		} else if (req->cmd == WRITE) {
			DEBUG(MTD_DEBUG_LEVEL2, "NFTL write request of 0x%x sectors @ %x "
			      "(req->nr_sectors == %lx)\n", nsect, block,
			      req->nr_sectors);
#ifdef CONFIG_NFTL_RW
			for ( ; nsect > 0; nsect-- , block++, buffer += 512) {
				/* Read a single sector to req->buffer + (512 * i) */
				if (NFTL_writeblock(nftl, block, buffer)) {
					DEBUG(MTD_DEBUG_LEVEL1,"NFTL write request failed\n");
					up(&nftl->mutex);
					res = 0;
					goto repeat;
				}
			}
			DEBUG(MTD_DEBUG_LEVEL2,"NFTL write request completed OK\n");
#else
			res = 0; /* Writes always fail */
#endif /* CONFIG_NFTL_RW */
			up(&nftl->mutex);
			goto repeat;
		} else {
			DEBUG(MTD_DEBUG_LEVEL0, "NFTL unknown request\n");
			up(&nftl->mutex);
			res = 0;
			goto repeat;
		}
	repeat: 
		DEBUG(MTD_DEBUG_LEVEL3, "end_request(%d)\n", res);
		spin_lock_irq(&io_request_lock);
		end_request(res);
	}
示例#21
0
int reiserfs_unlink (struct inode * dir, struct dentry *dentry)
{
  int retval;
  struct inode * inode;
  struct reiserfs_dir_entry de;
  struct path path;
  int windex ;
  int call_journal_end = 1 ;
  struct reiserfs_transaction_handle th ;
  int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 

  init_path (&path);

  retval = -ENOENT;
	
  journal_begin(&th, dir->i_sb, jbegin_count) ;
  windex = push_journal_writer("reiserfs_unlink") ;
  /* free preserve list if we should */
/*  maybe_free_preserve_list (dir->i_sb);*/
	
  de.de_gen_number_bit_string = 0;
  if (reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path, &de) == POSITION_NOT_FOUND) {
    goto end_unlink;
  }

  inode = dentry->d_inode;

  reiserfs_update_inode_transaction(inode) ;
  reiserfs_update_inode_transaction(dir) ;

  retval = -EPERM;
  if (S_ISDIR (inode->i_mode)) {
    goto end_unlink;
  }
  if ((dir->i_mode & S_ISVTX) && !fsuser() &&
      current->fsuid != inode->i_uid &&
      current->fsuid != dir->i_uid) {
    goto end_unlink;
  }

  retval = -ENOENT;
  if (comp_short_keys ((struct key *)&(de.de_dir_id), INODE_PKEY (inode))) {
    goto end_unlink;
  }
  
  if (!inode->i_nlink) {
    printk("reiserfs_unlink: deleting nonexistent file (%s:%lu), %d\n",
	   kdevname(inode->i_dev), inode->i_ino, inode->i_nlink);
    inode->i_nlink = 1;
  }
  if (reiserfs_cut_from_item (&th, dir, dir->i_sb, &path, &(de.de_entry_num), &(de.de_entry_key), 0, NOTHING_SPECIAL) == 0) {
    retval = -ENOENT;
    goto end_unlink;
  }

  inode->i_nlink--;
  inode->i_ctime = CURRENT_TIME;
  if_in_ram_update_sd (&th, inode);

  dir->i_size -= (de.de_entrylen + DEH_SIZE);
  dir->i_ctime = dir->i_mtime = CURRENT_TIME;
  if_in_ram_update_sd (&th, dir) ;
  pop_journal_writer(windex) ;
  journal_end(&th, dir->i_sb, jbegin_count) ;
  call_journal_end = 0 ;
  d_delete(dentry); 
  retval = 0;

end_unlink:
  pathrelse (&path);
  pop_journal_writer(windex) ;
  if (call_journal_end) 
    journal_end(&th, dir->i_sb, jbegin_count) ;
  return retval;
}
示例#22
0
static void do_mount_root(void)
{
	struct file_system_type * fs_type;
	struct super_block * sb;
	struct vfsmount *vfsmnt;
	struct inode * inode, d_inode;
	struct file filp;
	int retval;
  
#ifdef CONFIG_ROOT_NFS
	if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR)
		if (nfs_root_init(nfs_root_name, nfs_root_addrs) < 0) {
			printk(KERN_ERR "Root-NFS: Unable to contact NFS "
			    "server for root fs, using /dev/fd0 instead\n");
			ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
		}
	if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
		ROOT_DEV = 0;
		if ((fs_type = get_fs_type("nfs"))) {
			sb = &super_blocks[0];
			while (sb->s_dev) sb++;
			sb->s_dev = get_unnamed_dev();
			sb->s_flags = root_mountflags & ~MS_RDONLY;
			if (nfs_root_mount(sb) >= 0) {
				inode = sb->s_mounted;
				inode->i_count += 3 ;
				sb->s_covered = inode;
				sb->s_rd_only = 0;
				sb->s_dirt = 0;
				sb->s_type = fs_type;
				current->fs->pwd = inode;
				current->fs->root = inode;
				ROOT_DEV = sb->s_dev;
				printk (KERN_NOTICE "VFS: Mounted root (nfs filesystem).\n");
				vfsmnt = add_vfsmnt(ROOT_DEV, "rootfs", "/");
				if (!vfsmnt)
					panic("VFS: add_vfsmnt failed for NFS root.\n");
				vfsmnt->mnt_sb = sb;
				vfsmnt->mnt_flags = sb->s_flags;
				return;
			}
			sb->s_dev = 0;
		}
		if (!ROOT_DEV) {
			printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
			ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
		}
	}
#endif

#ifdef CONFIG_BLK_DEV_FD
	if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
		floppy_eject();
		printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n");
		wait_for_keypress();
	}
#endif

	memset(&filp, 0, sizeof(filp));
	memset(&d_inode, 0, sizeof(d_inode));
	d_inode.i_rdev = ROOT_DEV;
	filp.f_inode = &d_inode;
	if ( root_mountflags & MS_RDONLY)
		filp.f_mode = 1; /* read only */
	else
		filp.f_mode = 3; /* read write */
	retval = blkdev_open(&d_inode, &filp);
	if (retval == -EROFS) {
		root_mountflags |= MS_RDONLY;
		filp.f_mode = 1;
		retval = blkdev_open(&d_inode, &filp);
	}
	if (retval)
	        /*
		 * Allow the user to distinguish between failed open
		 * and bad superblock on root device.
		 */
		printk("VFS: Cannot open root device %s\n",
		       kdevname(ROOT_DEV));
	else for (fs_type = file_systems ; fs_type ; fs_type = fs_type->next) {
  		if (!fs_type->requires_dev)
  			continue;
  		sb = read_super(ROOT_DEV,fs_type->name,root_mountflags,NULL,1);
		if (sb) {
			inode = sb->s_mounted;
			inode->i_count += 3 ;	/* NOTE! it is logically used 4 times, not 1 */
			sb->s_covered = inode;
			sb->s_flags = root_mountflags;
			current->fs->pwd = inode;
			current->fs->root = inode;
			printk ("VFS: Mounted root (%s filesystem)%s.\n",
				fs_type->name,
				(sb->s_flags & MS_RDONLY) ? " readonly" : "");
			vfsmnt = add_vfsmnt(ROOT_DEV, "rootfs", "/");
			if (!vfsmnt)
				panic("VFS: add_vfsmnt failed for root fs");
			vfsmnt->mnt_sb = sb;
			vfsmnt->mnt_flags = root_mountflags;
			return;
		}
	}
	panic("VFS: Unable to mount root fs on %s",
		kdevname(ROOT_DEV));
}
示例#23
0
int mac_partition(struct gendisk *hd, kdev_t dev, unsigned long fsec, int first_part_minor)
{
	struct buffer_head *bh;
	int blk, blocks_in_map;
	int dev_bsize, dev_pos, pos;
	unsigned secsize;
#ifdef CONFIG_PPC
	int found_root = 0;
	int found_root_goodness = 0;
#endif
	struct mac_partition *part;
	struct mac_driver_desc *md;

	dev_bsize = get_ptable_blocksize(dev);
	dev_pos = 0;
	/* Get 0th block and look at the first partition map entry. */
	if ((bh = bread(dev, 0, dev_bsize)) == 0) {
	    printk("%s: error reading partition table\n",
		   kdevname(dev));
	    return -1;
	}
	md = (struct mac_driver_desc *) bh->b_data;
	if (be16_to_cpu(md->signature) != MAC_DRIVER_MAGIC) {
		brelse(bh);
		return 0;
	}
	secsize = be16_to_cpu(md->block_size);
	if (secsize >= dev_bsize) {
		brelse(bh);
		dev_pos = secsize;
		if ((bh = bread(dev, secsize/dev_bsize, dev_bsize)) == 0) {
			printk("%s: error reading partition table\n",
			       kdevname(dev));
			return -1;
		}
	}
	part = (struct mac_partition *) (bh->b_data + secsize - dev_pos);
	if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) {
		brelse(bh);
		return 0;		/* not a MacOS disk */
	}
	blocks_in_map = be32_to_cpu(part->map_count);
	for (blk = 1; blk <= blocks_in_map; ++blk) {
		pos = blk * secsize;
		if (pos >= dev_pos + dev_bsize) {
			brelse(bh);
			dev_pos = pos;
			if ((bh = bread(dev, pos/dev_bsize, dev_bsize)) == 0) {
				printk("%s: error reading partition table\n",
				       kdevname(dev));
				return -1;
			}
		}
		part = (struct mac_partition *) (bh->b_data + pos - dev_pos);
		if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC)
			break;
		blocks_in_map = be32_to_cpu(part->map_count);
		add_gd_partition(hd, first_part_minor,
			fsec + be32_to_cpu(part->start_block) * (secsize/512),
			be32_to_cpu(part->block_count) * (secsize/512), 0);

#ifdef CONFIG_PPC
		/*
		 * If this is the first bootable partition, tell the
		 * setup code, in case it wants to make this the root.
		 */
		if (_machine == _MACH_Pmac) {
			int goodness = 0;
		    
			if ((be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE)
			    && strcasecmp(part->processor, "powerpc") == 0)
				goodness++;

			if (strcasecmp(part->type, "Apple_UNIX_SVR2") == 0) {
				goodness++;
				if ((strcmp(part->name, "/") == 0) ||
				    (strstr(part->name, "root") != 0)) {
					goodness++;
				}
				if (strncmp(part->name, "swap", 4) == 0)
					goodness--;
			}

			if (goodness > found_root_goodness) {
				found_root = blk;
				found_root_goodness = goodness;
			}
		}
#endif /* CONFIG_PPC */

		++first_part_minor;
	}
#ifdef CONFIG_PPC
	if (found_root_goodness)
		note_bootable_part(dev, found_root);
#endif
	brelse(bh);
	printk("\n");
	return 1;
}
示例#24
0
static int read_super_block (struct super_block * s, int size, int offset)
{
    struct buffer_head * bh;
    struct reiserfs_super_block * rs;
 

    bh = bread (s->s_dev, offset / size, size);
    if (!bh) {
      printk ("read_super_block: "
              "bread failed (dev %s, block %d, size %d)\n",
              kdevname (s->s_dev), offset / size, size);
      return 1;
    }
 
    rs = (struct reiserfs_super_block *)bh->b_data;
    if (!is_reiserfs_magic_string (rs)) {
      printk ("read_super_block: "
              "can't find a reiserfs filesystem on (dev %s, block %lu, size %d)\n",
              kdevname(s->s_dev), bh->b_blocknr, size);
      brelse (bh);
      return 1;
    }
 
    //
    // ok, reiserfs signature (old or new) found in at the given offset
    //    
    s->s_blocksize = sb_blocksize(rs);
    s->s_blocksize_bits = 0;
    while ((1 << s->s_blocksize_bits) != s->s_blocksize)
	s->s_blocksize_bits ++;

    brelse (bh);
    
    if (s->s_blocksize != size)
	set_blocksize (s->s_dev, s->s_blocksize);

    bh = reiserfs_bread (s, offset / s->s_blocksize, s->s_blocksize);
    if (!bh) {
	printk("read_super_block: "
                "bread failed (dev %s, block %d, size %d)\n",
                kdevname (s->s_dev), offset / size, size);
	return 1;
    }
    
    rs = (struct reiserfs_super_block *)bh->b_data;
    if (!is_reiserfs_magic_string (rs) ||
	sb_blocksize(rs) != s->s_blocksize) {
	printk ("read_super_block: "
		"can't find a reiserfs filesystem on (dev %s, block %lu, size %d)\n",
		kdevname(s->s_dev), bh->b_blocknr, size);
	brelse (bh);
	printk ("read_super_block: can't find a reiserfs filesystem on dev %s.\n", kdevname(s->s_dev));
	return 1;
    }
    /* must check to be sure we haven't pulled an old format super out
    ** of the old format's log.  This is a kludge of a check, but it
    ** will work.  If block we've just read in is inside the
    ** journal for that super, it can't be valid.  
    */
    if (bh->b_blocknr >= sb_journal_block(rs) && 
	bh->b_blocknr < (sb_journal_block(rs) + JOURNAL_BLOCK_COUNT)) {
	brelse(bh) ;
	printk("super-459: read_super_block: "
	       "super found at block %lu is within its own log. "
	       "It must not be of this format type.\n", bh->b_blocknr) ;
	return 1 ;
    }

    if ( rs->s_root_block == -1 ) {
	brelse(bh) ;
	printk("dev %s: Unfinished reiserfsck --rebuild-tree run detected. Please run\n"
	       "reiserfsck --rebuild-tree and wait for a completion. If that fails\n"
	       "get newer reiserfsprogs package\n", kdevname (s->s_dev));
	return 1;
    }

    SB_BUFFER_WITH_SB (s) = bh;
    SB_DISK_SUPER_BLOCK (s) = rs;

    s->s_op = &reiserfs_sops;

    /* new format is limited by the 32 bit wide i_blocks field, want to
    ** be one full block below that.
    */
    s->s_maxbytes = (512LL << 32) - s->s_blocksize ;
    return 0;
}
示例#25
0
struct super_block *
affs_read_super(struct super_block *s,void *data, int silent)
{
	struct buffer_head	*bh = NULL;
	struct buffer_head	*bb;
	kdev_t			 dev = s->s_dev;
	int			 root_block;
	int			 size;
	__u32			 chksum;
	__u32			*bm;
	int			 ptype, stype;
	int			 mapidx;
	int			 num_bm;
	int			 i, j;
	int			 key;
	int			 blocksize;
	uid_t			 uid;
	gid_t			 gid;
	int			 reserved;
	int			 az_no;
	unsigned long		 mount_flags;
	unsigned long		 offset;

	pr_debug("affs_read_super(%s)\n",data ? (const char *)data : "no options");

	MOD_INC_USE_COUNT;

	if (!parse_options(data,&uid,&gid,&i,&reserved,&root_block,
	    &blocksize,&s->u.affs_sb.s_prefix,s->u.affs_sb.s_volume,&mount_flags)) {
		s->s_dev = 0;
		printk("AFFS: error parsing options.\n");
		MOD_DEC_USE_COUNT;
		return NULL;
	}
	lock_super(s);

	/* Get the size of the device in 512-byte blocks.
	 * If we later see that the partition uses bigger
	 * blocks, we will have to change it.
	 */

	size = blksize_size[MAJOR(dev)][MINOR(dev)];
	size = (size ? size : BLOCK_SIZE) / 512 * blk_size[MAJOR(dev)][MINOR(dev)];

	s->u.affs_sb.s_bitmap  = NULL;
	s->u.affs_sb.s_root_bh = NULL;
	s->u.affs_sb.s_flags   = mount_flags;
	s->u.affs_sb.s_mode    = i;
	s->u.affs_sb.s_uid     = uid;
	s->u.affs_sb.s_gid     = gid;

	if (size == 0) {
		s->s_dev = 0;
		unlock_super(s);
		printk("affs_read_super: could not determine device size\n");
		goto out;
	}
	s->u.affs_sb.s_partition_size = size;
	s->u.affs_sb.s_reserved       = reserved;

	/* Try to find root block. Its location may depend on the block size. */

	s->u.affs_sb.s_hashsize = 0;
	if (blocksize > 0) {
		i = blocksize;
		j = blocksize;
	} else {
		i = 512;
		j = 4096;
	}
	for (blocksize = i, key = 0; blocksize <= j; blocksize <<= 1, size >>= 1) {
		if (root_block < 0)
			s->u.affs_sb.s_root_block = (reserved + size - 1) / 2;
		else
			s->u.affs_sb.s_root_block = root_block;
		set_blocksize(dev,blocksize);

		/* The root block location that was calculated above is not
		 * correct if the partition size is an odd number of 512-
		 * byte blocks, which will be rounded down to a number of
		 * 1024-byte blocks, and if there were an even number of
		 * reserved blocks. Ideally, all partition checkers should
		 * report the real number of blocks of the real blocksize,
		 * but since this just cannot be done, we have to try to
		 * find the root block anyways. In the above case, it is one
		 * block behind the calculated one. So we check this one, too.
		 */
		for (num_bm = 0; num_bm < 2; num_bm++) {
			pr_debug("AFFS: Dev %s - trying bs=%d bytes, root at %d, "
				 "size=%d blocks, %d reserved\n",kdevname(dev),blocksize,
				 s->u.affs_sb.s_root_block + num_bm,size,reserved);
			bh = affs_bread(dev,s->u.affs_sb.s_root_block + num_bm,blocksize);
			if (!bh) {
				printk("AFFS: unable to read root block\n");
				goto out;
			}
			if (!affs_checksum_block(blocksize,bh->b_data,&ptype,&stype) &&
			    ptype == T_SHORT && stype == ST_ROOT) {
				s->s_blocksize             = blocksize;
				s->u.affs_sb.s_hashsize    = blocksize / 4 - 56;
				s->u.affs_sb.s_root_block += num_bm;
				key                        = 1;
				break;
			}
		}
		if (key)
			break;
		affs_brelse(bh);
		bh = NULL;
	}
	if (!key) {
		affs_brelse(bh);
		if (!silent)
			printk("AFFS: Can't find a valid root block on device %s\n",kdevname(dev));
		goto out;
	}
	root_block = s->u.affs_sb.s_root_block;

	s->u.affs_sb.s_partition_size   = size;
	s->s_blocksize_bits             = blocksize == 512 ? 9 :
					  blocksize == 1024 ? 10 :
					  blocksize == 2048 ? 11 : 12;

	/* Find out which kind of FS we have */
	bb = affs_bread(dev,0,s->s_blocksize);
	if (bb) {
		chksum = htonl(*(__u32 *)bb->b_data);
		switch (chksum) {
			case MUFS_FS:
			case MUFS_INTLFFS:
				s->u.affs_sb.s_flags |= SF_MUFS;
				/* fall thru */
			case FS_INTLFFS:
				s->u.affs_sb.s_flags |= SF_INTL;
				break;
			case MUFS_DCFFS:
			case MUFS_FFS:
				s->u.affs_sb.s_flags |= SF_MUFS;
				break;
			case FS_DCFFS:
			case FS_FFS:
				break;
			case MUFS_OFS:
				s->u.affs_sb.s_flags |= SF_MUFS;
				/* fall thru */
			case FS_OFS:
				s->u.affs_sb.s_flags |= SF_OFS;
				break;
			case MUFS_DCOFS:
				if (!(s->s_flags & MS_RDONLY)) {
					printk("AFFS: Dircache FS - mounting %s read only.\n",
					       kdevname(dev));
				}
				/* fall thru */
			case MUFS_INTLOFS:
				s->u.affs_sb.s_flags |= SF_MUFS;
				if (0)
				/* fall thru */
			case FS_DCOFS:
				if (!(s->s_flags & MS_RDONLY)) {
					printk("AFFS: Dircache FS - mounting %s read only.\n",
					       kdevname(dev));
				}
				/* fall thru */
			case FS_INTLOFS:
				s->u.affs_sb.s_flags |= SF_INTL | SF_OFS;
				break;
			default:
				printk("AFFS: Unknown filesystem on device %s: %08X\n",
				       kdevname(dev),chksum);
				affs_brelse(bb);
				goto out;
		}
		affs_brelse(bb);
	} else {
		printk("AFFS: Can't get boot block.\n");
		goto out;
	}
	if (mount_flags & SF_VERBOSE) {
		chksum = ntohl(chksum);
		printk("AFFS: Mounting volume \"%*s\": Type=%.3s\\%c, Blocksize=%d\n",
		       GET_END_PTR(struct root_end,bh->b_data,blocksize)->disk_name[0],
		       &GET_END_PTR(struct root_end,bh->b_data,blocksize)->disk_name[1],
		       (char *)&chksum,((char *)&chksum)[3] + '0',blocksize);
	}
示例#26
0
struct super_block *sysv_read_super(struct super_block *sb,void *data,
				     int silent)
{
	struct buffer_head *bh;
	const char *found;
	kdev_t dev = sb->s_dev;
	struct inode *root_inode;
	unsigned long blocknr;
	
	if (1024 != sizeof (struct xenix_super_block))
		panic("Xenix FS: bad super-block size");
	if ((512 != sizeof (struct sysv4_super_block))
            || (512 != sizeof (struct sysv2_super_block)))
		panic("SystemV FS: bad super-block size");
	if (500 != sizeof (struct coh_super_block))
		panic("Coherent FS: bad super-block size");
	if (64 != sizeof (struct sysv_inode))
		panic("sysv fs: bad i-node size");
	MOD_INC_USE_COUNT;
	lock_super(sb);
	set_blocksize(dev,BLOCK_SIZE);
	sb->sv_block_base = 0;

	/* Try to read Xenix superblock */
	if ((bh = bread(dev, 1, BLOCK_SIZE)) != NULL) {
		if ((found = detect_xenix(sb,bh)) != NULL)
			goto ok;
		brelse(bh);
	}
	if ((bh = bread(dev, 0, BLOCK_SIZE)) != NULL) {
		/* Try to recognize SystemV superblock */
		if ((found = detect_sysv4(sb,bh)) != NULL)
			goto ok;
		if ((found = detect_sysv2(sb,bh)) != NULL)
			goto ok;
		/* Try to recognize Coherent superblock */
		if ((found = detect_coherent(sb,bh)) != NULL)
			goto ok;
		brelse(bh);
	}
	/* Try to recognize SystemV superblock */
	/* Offset by 1 track, i.e. most probably 9, 15, or 18 kilobytes. */
	/* 2kB blocks with offset of 9 and 15 kilobytes are not supported. */
	/* Maybe we should also check the device geometry ? */
	{	static int offsets[] = { 9, 15, 18, };
		int i;
		for (i = 0; i < sizeof(offsets)/sizeof(offsets[0]); i++)
			if ((bh = bread(dev, offsets[i], BLOCK_SIZE)) != NULL) {
				/* Try to recognize SystemV superblock */
				if ((found = detect_sysv4(sb,bh)) != NULL) {
					if (sb->sv_block_size>BLOCK_SIZE && (offsets[i] % 2))
						goto bad_shift;
					sb->sv_block_base = (offsets[i] << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
					goto ok;
				}
				if ((found = detect_sysv2(sb,bh)) != NULL) {
					if (sb->sv_block_size>BLOCK_SIZE && (offsets[i] % 2))
						goto bad_shift;
					sb->sv_block_base = (offsets[i] << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
					goto ok;
				}
				brelse(bh);
			}
	}
	bad_shift:
	sb->s_dev = 0;
	unlock_super(sb);
	if (!silent)
		printk("VFS: unable to read Xenix/SystemV/Coherent superblock on device "
		       "%s\n", kdevname(dev));
	failed:
	MOD_DEC_USE_COUNT;
	return NULL;

	ok:
	if (sb->sv_block_size >= BLOCK_SIZE) {
		if (sb->sv_block_size != BLOCK_SIZE) {
			brelse(bh);
			set_blocksize(dev, sb->sv_block_size);
			blocknr = (bh->b_blocknr << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
			if ((bh = bread(dev, blocknr, sb->sv_block_size)) == NULL)
				goto bad_superblock;
		}
		switch (sb->sv_type) {
			case FSTYPE_XENIX:
				if (!detected_xenix(sb,bh,bh))
					goto bad_superblock;
				break;
			case FSTYPE_SYSV4:
				if (!detected_sysv4(sb,bh))
					goto bad_superblock;
				break;
			case FSTYPE_SYSV2:
				if (!detected_sysv2(sb,bh))
					goto bad_superblock;
				break;
			default: goto bad_superblock;
		goto superblock_ok;
		bad_superblock:
			brelse(bh);
			sb->s_dev = 0;
			unlock_super(sb);
			printk("SysV FS: cannot read superblock in %d byte mode\n", sb->sv_block_size);
			goto failed;
		superblock_ok:
		}
	} else {
示例#27
0
文件: inode-v23.c 项目: nhanh0/hah
/* Called by the VFS at mount time to initialize the whole file system.  */
static struct super_block *
jffs_read_super(struct super_block *sb, void *data, int silent)
{
	kdev_t dev = sb->s_dev;
	struct inode *root_inode;
	struct jffs_control *c;

	D1(printk(KERN_NOTICE "JFFS: Trying to mount device %s.\n",
		  kdevname(dev)));

	if (MAJOR(dev) != MTD_BLOCK_MAJOR) {
		printk(KERN_WARNING "JFFS: Trying to mount a "
		       "non-mtd device.\n");
		return 0;
	}

	sb->s_blocksize = PAGE_CACHE_SIZE;
	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
	sb->u.generic_sbp = (void *) 0;
	sb->s_maxbytes = 0xFFFFFFFF;

	/* Build the file system.  */
	if (jffs_build_fs(sb) < 0) {
		goto jffs_sb_err1;
	}

	/*
	 * set up enough so that we can read an inode
	 */
	sb->s_magic = JFFS_MAGIC_SB_BITMASK;
	sb->s_op = &jffs_ops;

	root_inode = iget(sb, JFFS_MIN_INO);
	if (!root_inode)
	        goto jffs_sb_err2;

	/* Get the root directory of this file system.  */
	if (!(sb->s_root = d_alloc_root(root_inode))) {
		goto jffs_sb_err3;
	}

	c = (struct jffs_control *) sb->u.generic_sbp;

#ifdef CONFIG_JFFS_PROC_FS
	/* Set up the jffs proc file system.  */
	if (jffs_register_jffs_proc_dir(dev, c) < 0) {
		printk(KERN_WARNING "JFFS: Failed to initialize the JFFS "
			"proc file system for device %s.\n",
			kdevname(dev));
	}
#endif

	/* Set the Garbage Collection thresholds */

	/* GC if free space goes below 5% of the total size */
	c->gc_minfree_threshold = c->fmc->flash_size / 20;

	if (c->gc_minfree_threshold < c->fmc->sector_size)
		c->gc_minfree_threshold = c->fmc->sector_size;

	/* GC if dirty space exceeds 33% of the total size. */
	c->gc_maxdirty_threshold = c->fmc->flash_size / 3;

	if (c->gc_maxdirty_threshold < c->fmc->sector_size)
		c->gc_maxdirty_threshold = c->fmc->sector_size;


	c->thread_pid = kernel_thread (jffs_garbage_collect_thread, 
				        (void *) c, 
				        CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
	D1(printk(KERN_NOTICE "JFFS: GC thread pid=%d.\n", (int) c->thread_pid));

	D1(printk(KERN_NOTICE "JFFS: Successfully mounted device %s.\n",
	       kdevname(dev)));
	return sb;

jffs_sb_err3:
	iput(root_inode);
jffs_sb_err2:
	jffs_cleanup_control((struct jffs_control *)sb->u.generic_sbp);
jffs_sb_err1:
	printk(KERN_WARNING "JFFS: Failed to mount device %s.\n",
	       kdevname(dev));
	return 0;
}
示例#28
0
文件: super.c 项目: hugh712/Jollen
/*
 * hfs_read_super()
 *
 * This is the function that is responsible for mounting an HFS
 * filesystem.	It performs all the tasks necessary to get enough data
 * from the disk to read the root inode.  This includes parsing the
 * mount options, dealing with Macintosh partitions, reading the
 * superblock and the allocation bitmap blocks, calling
 * hfs_btree_init() to get the necessary data about the extents and
 * catalog B-trees and, finally, reading the root inode into memory.
 */
struct super_block *hfs_read_super(struct super_block *s, void *data,
				   int silent)
{
	struct hfs_mdb *mdb;
	struct hfs_cat_key key;
	kdev_t dev = s->s_dev;
	hfs_s32 part_size, part_start;
	struct inode *root_inode;
	int part;

	if (!parse_options((char *)data, HFS_SB(s), &part)) {
		hfs_warn("hfs_fs: unable to parse mount options.\n");
		goto bail3;
	}

	/* set the device driver to 512-byte blocks */
	set_blocksize(dev, HFS_SECTOR_SIZE);
	s->s_blocksize_bits = HFS_SECTOR_SIZE_BITS;
	s->s_blocksize = HFS_SECTOR_SIZE;

#ifdef CONFIG_MAC_PARTITION
	/* check to see if we're in a partition */
	mdb = hfs_mdb_get(s, s->s_flags & MS_RDONLY, 0);

	/* erk. try parsing the partition table ourselves */
	if (!mdb) {
		if (hfs_part_find(s, part, silent, &part_size, &part_start)) {
	    		goto bail2;
	  	}
	  	mdb = hfs_mdb_get(s, s->s_flags & MS_RDONLY, part_start);
	}
#else
	if (hfs_part_find(s, part, silent, &part_size, &part_start)) {
		goto bail2;
	}

	mdb = hfs_mdb_get(s, s->s_flags & MS_RDONLY, part_start);
#endif

	if (!mdb) {
		if (!silent) {
			hfs_warn("VFS: Can't find a HFS filesystem on dev %s.\n",
			       kdevname(dev));
		}
		goto bail2;
	}

	HFS_SB(s)->s_mdb = mdb;
	if (HFS_ITYPE(mdb->next_id) != 0) {
		hfs_warn("hfs_fs: too many files.\n");
		goto bail1;
	}

	s->s_magic = HFS_SUPER_MAGIC;
	s->s_op = &hfs_super_operations;

	/* try to get the root inode */
	hfs_cat_build_key(htonl(HFS_POR_CNID),
			  (struct hfs_name *)(mdb->vname), &key);

	root_inode = hfs_iget(hfs_cat_get(mdb, &key), HFS_ITYPE_NORM, NULL);
	if (!root_inode) 
		goto bail_no_root;
	  
	s->s_root = d_alloc_root(root_inode);
	if (!s->s_root) 
		goto bail_no_root;

	/* fix up pointers. */
	HFS_I(root_inode)->entry->sys_entry[HFS_ITYPE_TO_INT(HFS_ITYPE_NORM)] =
	  s->s_root;
	s->s_root->d_op = &hfs_dentry_operations;

	/* everything's okay */
	return s;

bail_no_root: 
	hfs_warn("hfs_fs: get root inode failed.\n");
	iput(root_inode);
bail1:
	hfs_mdb_put(mdb, s->s_flags & MS_RDONLY);
bail2:
	set_blocksize(dev, BLOCK_SIZE);
bail3:
	return NULL;	
}
示例#29
0
int dosetopt(int minor, struct psdev_opt *opt)
{
	int retval = 0;
	int newval = opt->optval;

	ENTRY;

	switch(opt->optname) {

	case PSDEV_TIMEOUT:
		izo_channels[minor].uc_timeout = newval;
		break;

	case PSDEV_HARD:
		izo_channels[minor].uc_hard = newval;
		break;

	case PSDEV_NO_FILTER:
		izo_channels[minor].uc_no_filter = newval;
		break;

	case PSDEV_NO_JOURNAL:
		izo_channels[minor].uc_no_journal = newval;
		break;

	case PSDEV_NO_UPCALL:
		izo_channels[minor].uc_no_upcall = newval;
		break;

#ifdef PRESTO_DEBUG
	case PSDEV_ERRORVAL: {
		/* If we have a positive arg, set a breakpoint for that
		 * value.  If we have a negative arg, make that device
		 * read-only.  FIXME  It would be much better to only
		 * allow setting the underlying device read-only for the
		 * current presto cache.
		 */
		int errorval = izo_channels[minor].uc_errorval;
		if (errorval < 0) {
			if (newval == 0)
				set_device_ro(-errorval, 0);
			else
				CERROR("device %s already read only\n",
				       kdevname(-errorval));
		} else {
			if (newval < 0)
				set_device_ro(-newval, 1);
			izo_channels[minor].uc_errorval = newval;
			CDEBUG(D_PSDEV, "setting errorval to %d\n", newval);
		}

		break;
	}
#endif

	case PSDEV_TRACE:
	case PSDEV_DEBUG:
	case PSDEV_BYTES_TO_CLOSE:
	default:
		CDEBUG(D_PSDEV,
		       "ioctl: dosetopt: minor %d, bad optname 0x%x, \n",
		       minor, opt->optname);

		retval = -EINVAL;
	}

	EXIT;
	return retval;
}
示例#30
0
static struct super_block *
affs_read_super(struct super_block *sb, void *data, int silent)
{
	struct buffer_head	*root_bh = NULL;
	struct buffer_head	*boot_bh;
	struct inode		*root_inode = NULL;
	kdev_t			 dev = sb->s_dev;
	s32			 root_block;
	int			 blocks, size, blocksize;
	u32			 chksum;
	int			 num_bm;
	int			 i, j;
	s32			 key;
	uid_t			 uid;
	gid_t			 gid;
	int			 reserved;
	unsigned long		 mount_flags;

	pr_debug("AFFS: read_super(%s)\n",data ? (const char *)data : "no options");

	sb->s_magic             = AFFS_SUPER_MAGIC;
	sb->s_op                = &affs_sops;
	memset(AFFS_SB, 0, sizeof(struct affs_sb_info));
	init_MUTEX(&AFFS_SB->s_bmlock);

	if (!parse_options(data,&uid,&gid,&i,&reserved,&root_block,
				&blocksize,&AFFS_SB->s_prefix,
				AFFS_SB->s_volume, &mount_flags)) {
		printk(KERN_ERR "AFFS: Error parsing options\n");
		return NULL;
	}
	/* N.B. after this point s_prefix must be released */

	AFFS_SB->s_flags   = mount_flags;
	AFFS_SB->s_mode    = i;
	AFFS_SB->s_uid     = uid;
	AFFS_SB->s_gid     = gid;
	AFFS_SB->s_reserved= reserved;

	/* Get the size of the device in 512-byte blocks.
	 * If we later see that the partition uses bigger
	 * blocks, we will have to change it.
	 */

	blocks = blk_size[MAJOR(dev)] ? blk_size[MAJOR(dev)][MINOR(dev)] : 0;
	if (!blocks) {
		printk(KERN_ERR "AFFS: Could not determine device size\n");
		goto out_error;
	}
	size = (BLOCK_SIZE / 512) * blocks;
	pr_debug("AFFS: initial blksize=%d, blocks=%d\n", 512, blocks);

	affs_set_blocksize(sb, PAGE_SIZE);
	/* Try to find root block. Its location depends on the block size. */

	i = 512;
	j = 4096;
	if (blocksize > 0) {
		i = j = blocksize;
		size = size / (blocksize / 512);
	}
	for (blocksize = i, key = 0; blocksize <= j; blocksize <<= 1, size >>= 1) {
		AFFS_SB->s_root_block = root_block;
		if (root_block < 0)
			AFFS_SB->s_root_block = (reserved + size - 1) / 2;
		pr_debug("AFFS: setting blocksize to %d\n", blocksize);
		affs_set_blocksize(sb, blocksize);
		AFFS_SB->s_partition_size = size;

		/* The root block location that was calculated above is not
		 * correct if the partition size is an odd number of 512-
		 * byte blocks, which will be rounded down to a number of
		 * 1024-byte blocks, and if there were an even number of
		 * reserved blocks. Ideally, all partition checkers should
		 * report the real number of blocks of the real blocksize,
		 * but since this just cannot be done, we have to try to
		 * find the root block anyways. In the above case, it is one
		 * block behind the calculated one. So we check this one, too.
		 */
		for (num_bm = 0; num_bm < 2; num_bm++) {
			pr_debug("AFFS: Dev %s, trying root=%u, bs=%d, "
				"size=%d, reserved=%d\n",
				kdevname(dev),
				AFFS_SB->s_root_block + num_bm,
				blocksize, size, reserved);
			root_bh = affs_bread(sb, AFFS_SB->s_root_block + num_bm);
			if (!root_bh)
				continue;
			if (!affs_checksum_block(sb, root_bh) &&
			    be32_to_cpu(AFFS_ROOT_HEAD(root_bh)->ptype) == T_SHORT &&
			    be32_to_cpu(AFFS_ROOT_TAIL(sb, root_bh)->stype) == ST_ROOT) {
				AFFS_SB->s_hashsize    = blocksize / 4 - 56;
				AFFS_SB->s_root_block += num_bm;
				key                        = 1;
				goto got_root;
			}
			affs_brelse(root_bh);
			root_bh = NULL;
		}
	}
	if (!silent)
		printk(KERN_ERR "AFFS: No valid root block on device %s\n",
			kdevname(dev));
	goto out_error;

	/* N.B. after this point bh must be released */
got_root:
	root_block = AFFS_SB->s_root_block;

	sb->s_blocksize_bits = blocksize == 512 ? 9 :
			       blocksize == 1024 ? 10 :
			       blocksize == 2048 ? 11 : 12;

	/* Find out which kind of FS we have */
	boot_bh = bread(sb->s_dev, 0, sb->s_blocksize);
	if (!boot_bh) {
		printk(KERN_ERR "AFFS: Cannot read boot block\n");
		goto out_error;
	}
	chksum = be32_to_cpu(*(u32 *)boot_bh->b_data);
	brelse(boot_bh);

	/* Dircache filesystems are compatible with non-dircache ones
	 * when reading. As long as they aren't supported, writing is
	 * not recommended.
	 */
	if ((chksum == FS_DCFFS || chksum == MUFS_DCFFS || chksum == FS_DCOFS
	     || chksum == MUFS_DCOFS) && !(sb->s_flags & MS_RDONLY)) {
		printk(KERN_NOTICE "AFFS: Dircache FS - mounting %s read only\n",
			kdevname(dev));
		sb->s_flags |= MS_RDONLY;
		AFFS_SB->s_flags |= SF_READONLY;
	}
	switch (chksum) {
		case MUFS_FS:
		case MUFS_INTLFFS:
		case MUFS_DCFFS:
			AFFS_SB->s_flags |= SF_MUFS;
			/* fall thru */
		case FS_INTLFFS:
		case FS_DCFFS:
			AFFS_SB->s_flags |= SF_INTL;
			break;
		case MUFS_FFS:
			AFFS_SB->s_flags |= SF_MUFS;
			break;
		case FS_FFS:
			break;
		case MUFS_OFS:
			AFFS_SB->s_flags |= SF_MUFS;
			/* fall thru */
		case FS_OFS:
			AFFS_SB->s_flags |= SF_OFS;
			sb->s_flags |= MS_NOEXEC;
			break;
		case MUFS_DCOFS:
		case MUFS_INTLOFS:
			AFFS_SB->s_flags |= SF_MUFS;
		case FS_DCOFS:
		case FS_INTLOFS:
			AFFS_SB->s_flags |= SF_INTL | SF_OFS;
			sb->s_flags |= MS_NOEXEC;
			break;
		default:
			printk(KERN_ERR "AFFS: Unknown filesystem on device %s: %08X\n",
				kdevname(dev), chksum);
			goto out_error;
	}

	if (mount_flags & SF_VERBOSE) {
		chksum = cpu_to_be32(chksum);
		printk(KERN_NOTICE "AFFS: Mounting volume \"%*s\": Type=%.3s\\%c, Blocksize=%d\n",
			AFFS_ROOT_TAIL(sb, root_bh)->disk_name[0],
			AFFS_ROOT_TAIL(sb, root_bh)->disk_name + 1,
			(char *)&chksum,((char *)&chksum)[3] + '0',blocksize);
	}

	sb->s_flags |= MS_NODEV | MS_NOSUID;

	AFFS_SB->s_data_blksize = sb->s_blocksize;
	if (AFFS_SB->s_flags & SF_OFS)
		AFFS_SB->s_data_blksize -= 24;

	/* Keep super block in cache */
	AFFS_SB->s_root_bh = root_bh;
	/* N.B. after this point s_root_bh must be released */

	if (affs_init_bitmap(sb))
		goto out_error;

	/* set up enough so that it can read an inode */

	root_inode = iget(sb, root_block);
	sb->s_root = d_alloc_root(root_inode);
	if (!sb->s_root) {
		printk(KERN_ERR "AFFS: Get root inode failed\n");
		goto out_error;
	}
	sb->s_root->d_op = &affs_dentry_operations;

	pr_debug("AFFS: s_flags=%lX\n",sb->s_flags);
	return sb;

	/*
	 * Begin the cascaded cleanup ...
	 */
out_error:
	if (root_inode)
		iput(root_inode);
	if (AFFS_SB->s_bitmap)
		kfree(AFFS_SB->s_bitmap);
	affs_brelse(root_bh);
	if (AFFS_SB->s_prefix)
		kfree(AFFS_SB->s_prefix);
	return NULL;
}