Exemplo n.º 1
0
static void
show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
{
	struct mm_struct *mm = vma->vm_mm;
	struct file *file = vma->vm_file;
	struct proc_maps_private *priv = m->private;
	vm_flags_t flags = vma->vm_flags;
	unsigned long ino = 0;
	unsigned long long pgoff = 0;
	unsigned long start, end;
	dev_t dev = 0;
	const char *name = NULL;

	if (file) {
		struct inode *inode = file_inode(vma->vm_file);
		dev = inode->i_sb->s_dev;
		ino = inode->i_ino;
		pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
	}

	/* We don't show the stack guard page in /proc/maps */
	start = vma->vm_start;
	if (stack_guard_page_start(vma, start))
		start += PAGE_SIZE;
	end = vma->vm_end;
	if (stack_guard_page_end(vma, end))
		end -= PAGE_SIZE;

	seq_setwidth(m, 25 + sizeof(void *) * 6 - 1);
	seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ",
			start,
			end,
			flags & VM_READ ? 'r' : '-',
			flags & VM_WRITE ? 'w' : '-',
			flags & VM_EXEC ? 'x' : '-',
			flags & VM_MAYSHARE ? 's' : 'p',
			pgoff,
			MAJOR(dev), MINOR(dev), ino);

	/*
	 * Print the dentry name for named mappings, and a
	 * special [heap] marker for the heap:
	 */
	if (file) {
		seq_pad(m, ' ');
		seq_path(m, &file->f_path, "\n");
		goto done;
	}

	if (vma->vm_ops && vma->vm_ops->name) {
		name = vma->vm_ops->name(vma);
		if (name)
			goto done;
	}

	name = arch_vma_name(vma);
	if (!name) {
		pid_t tid;

		if (!mm) {
			name = "[vdso]";
			goto done;
		}

		if (vma->vm_start <= mm->brk &&
		    vma->vm_end >= mm->start_brk) {
			name = "[heap]";
			goto done;
		}

		tid = pid_of_stack(priv, vma, is_pid);
		if (tid != 0) {
			/*
			 * Thread stack in /proc/PID/task/TID/maps or
			 * the main process stack.
			 */
			if (!is_pid || (vma->vm_start <= mm->start_stack &&
			    vma->vm_end >= mm->start_stack)) {
				name = "[stack]";
			} else {
				/* Thread stack in /proc/PID/maps */
				seq_pad(m, ' ');
				seq_printf(m, "[stack:%d]", tid);
			}
		}
	}

done:
	if (name) {
		seq_pad(m, ' ');
		seq_puts(m, name);
	}
	seq_putc(m, '\n');
}
Exemplo n.º 2
0
dev_t name_to_dev_t(char *name)
{
	char s[32];
	char *p;
	dev_t res = 0;
	int part;

	if (strncmp(name, "/dev/", 5) != 0) {
		unsigned maj, min;

		if (sscanf(name, "%u:%u", &maj, &min) == 2) {
			res = MKDEV(maj, min);
			if (maj != MAJOR(res) || min != MINOR(res))
				goto fail;
		} else {
			res = new_decode_dev(simple_strtoul(name, &p, 16));
			if (*p)
				goto fail;
		}
		goto done;
	}

	name += 5;
	res = Root_NFS;
	if (strcmp(name, "nfs") == 0)
		goto done;
	res = Root_RAM0;
	if (strcmp(name, "ram") == 0)
		goto done;

	if (strlen(name) > 31)
		goto fail;
	strcpy(s, name);
	for (p = s; *p; p++)
		if (*p == '/')
			*p = '!';
	res = blk_lookup_devt(s, 0);
	if (res)
		goto done;

	/*
	 * try non-existant, but valid partition, which may only exist
	 * after revalidating the disk, like partitioned md devices
	 */
	while (p > s && isdigit(p[-1]))
		p--;
	if (p == s || !*p || *p == '0')
		goto fail;

	/* try disk name without <part number> */
	part = simple_strtoul(p, NULL, 10);
	*p = '\0';
	res = blk_lookup_devt(s, part);
	if (res)
		goto done;

	/* try disk name without p<part number> */
	if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p')
		goto fail;
	p[-1] = '\0';
	res = blk_lookup_devt(s, part);
	if (res)
		goto done;

fail:
	return 0;
done:
	return res;
}
Exemplo n.º 3
0
/*
 * First routine called when the kernel module is loaded
 */
static int __init tf_device_register(void)
{
	int error;
	struct tf_device *dev = &g_tf_dev;

	dprintk(KERN_INFO "tf_device_register()\n");

	/*
	 * Initialize the device
	 */
	dev->dev_number = MKDEV(device_major_number,
		TF_DEVICE_MINOR_NUMBER);
	cdev_init(&dev->cdev, &g_tf_device_file_ops);
	dev->cdev.owner = THIS_MODULE;

	INIT_LIST_HEAD(&dev->connection_list);
	spin_lock_init(&dev->connection_list_lock);

#if defined(MODULE) && defined(CONFIG_TF_ZEBRA)
	error = (*tf_comm_early_init)();
	if (error)
		goto module_early_init_failed;

	error = tf_device_mshield_init(smc_mem);
	if (error)
		goto mshield_init_failed;

#ifdef CONFIG_TF_DRIVER_CRYPTO_FIPS
	error = tf_crypto_hmac_module_init();
	if (error)
		goto hmac_init_failed;

	error = tf_self_test_register_device();
	if (error)
		goto self_test_register_device_failed;
#endif
#endif

	/* register the sysfs object driver stats */
	error = kobject_init_and_add(&dev->kobj,  &tf_ktype, NULL, "%s",
		 TF_DEVICE_BASE_NAME);
	if (error) {
		printk(KERN_ERR "tf_device_register(): "
			"kobject_init_and_add failed (error %d)!\n", error);
		kobject_put(&dev->kobj);
		goto kobject_init_and_add_failed;
	}

	/*
	 * Register the system device.
	 */
	register_syscore_ops(&g_tf_device_syscore_ops);

	/*
	 * Register the char device.
	 */
	printk(KERN_INFO "Registering char device %s (%u:%u)\n",
		TF_DEVICE_BASE_NAME,
		MAJOR(dev->dev_number),
		MINOR(dev->dev_number));
	error = register_chrdev_region(dev->dev_number, 1,
		TF_DEVICE_BASE_NAME);
	if (error != 0) {
		printk(KERN_ERR "tf_device_register():"
			" register_chrdev_region failed (error %d)!\n",
			error);
		goto register_chrdev_region_failed;
	}

	error = cdev_add(&dev->cdev, dev->dev_number, 1);
	if (error != 0) {
		printk(KERN_ERR "tf_device_register(): "
			"cdev_add failed (error %d)!\n",
			error);
		goto cdev_add_failed;
	}

	/*
	 * Initialize the communication with the Secure World.
	 */
#ifdef CONFIG_TF_TRUSTZONE
	dev->sm.soft_int_irq = soft_interrupt;
#endif
	error = tf_init(&g_tf_dev.sm);
	if (error != S_SUCCESS) {
		dprintk(KERN_ERR "tf_device_register(): "
			"tf_init failed (error %d)!\n",
			error);
		goto init_failed;
	}

#ifdef CONFIG_TF_DRIVER_CRYPTO_FIPS
	error = tf_self_test_post_init(&(dev_stats->kobj));
	/* N.B. error > 0 indicates a POST failure, which will not
	   prevent the module from loading. */
	if (error < 0) {
		dprintk(KERN_ERR "tf_device_register(): "
			"tf_self_test_post_vectors failed (error %d)!\n",
			error);
		goto post_failed;
	}
#endif

#ifdef CONFIG_ANDROID
	tf_class = class_create(THIS_MODULE, TF_DEVICE_BASE_NAME);
	device_create(tf_class, NULL,
		dev->dev_number,
		NULL, TF_DEVICE_BASE_NAME);
#endif

#ifdef CONFIG_TF_ZEBRA
	/*
	 * Initializes the /dev/tf_ctrl device node.
	 */
	error = tf_ctrl_device_register();
	if (error)
		goto ctrl_failed;
#endif

#ifdef CONFIG_TF_DRIVER_DEBUG_SUPPORT
	address_cache_property((unsigned long) &tf_device_register);
#endif
	/*
	 * Successful completion.
	 */

	dprintk(KERN_INFO "tf_device_register(): Success\n");
	return 0;

	/*
	 * Error: undo all operations in the reverse order
	 */
#ifdef CONFIG_TF_ZEBRA
ctrl_failed:
#endif
#ifdef CONFIG_TF_DRIVER_CRYPTO_FIPS
	tf_self_test_post_exit();
post_failed:
#endif
init_failed:
	cdev_del(&dev->cdev);
cdev_add_failed:
	unregister_chrdev_region(dev->dev_number, 1);
register_chrdev_region_failed:
	unregister_syscore_ops(&g_tf_device_syscore_ops);
kobject_init_and_add_failed:
	kobject_del(&g_tf_dev.kobj);

#if defined(MODULE) && defined(CONFIG_TF_ZEBRA)
#ifdef CONFIG_TF_DRIVER_CRYPTO_FIPS
	tf_self_test_unregister_device();
self_test_register_device_failed:
	tf_crypto_hmac_module_exit();
hmac_init_failed:
#endif
	tf_device_mshield_exit();
mshield_init_failed:
module_early_init_failed:
#endif
	dprintk(KERN_INFO "tf_device_register(): Failure (error %d)\n",
		error);
	return error;
}
Exemplo n.º 4
0
Arquivo: blkmtd.c Projeto: nhanh0/hah
/* Startup */
static int __init init_blkmtd(void)
{
  struct file *file = NULL;
  struct inode *inode;
  mtd_raw_dev_data_t *rawdevice = NULL;
  int maj, min;
  int i, blocksize, blocksize_bits;
  loff_t size = 0;
  int readonly = 0;
  int erase_size = CONFIG_MTD_BLKDEV_ERASESIZE;
  kdev_t rdev;
  int err;
  int mode;
  int totalsize = 0, total_sectors = 0;
  int regions;

  mtd_info = NULL;

  // Check args
  if(device == 0) {
    printk("blkmtd: error, missing `device' name\n");
    return 1;
  }

  if(ro)
    readonly = 1;

  if(erasesz)
    erase_size = erasesz;

  DEBUG(1, "blkmtd: got device = `%s' erase size = %dK readonly = %s\n", device, erase_size, readonly ? "yes" : "no");
  // Get a handle on the device
  mode = (readonly) ? O_RDONLY : O_RDWR;
  file = filp_open(device, mode, 0);
  if(IS_ERR(file)) {
    DEBUG(2, "blkmtd: open_namei returned %ld\n", PTR_ERR(file));
    return 1;
  }
  
  /* determine is this is a block device and if so get its major and minor
     numbers */
  inode = file->f_dentry->d_inode;
  if(!S_ISBLK(inode->i_mode)) {
    printk("blkmtd: %s not a block device\n", device);
    filp_close(file, NULL);
    return 1;
  }
  rdev = inode->i_rdev;
  //filp_close(file, NULL);
  DEBUG(1, "blkmtd: found a block device major = %d, minor = %d\n",
	 MAJOR(rdev), MINOR(rdev));
  maj = MAJOR(rdev);
  min = MINOR(rdev);

  if(maj == MTD_BLOCK_MAJOR) {
    printk("blkmtd: attempting to use an MTD device as a block device\n");
    return 1;
  }

  DEBUG(1, "blkmtd: devname = %s\n", bdevname(rdev));
  blocksize = BLOCK_SIZE;

  if(bs) {
    blocksize = bs;
  } else {
    if (blksize_size[maj] && blksize_size[maj][min]) {
      DEBUG(2, "blkmtd: blksize_size = %d\n", blksize_size[maj][min]);
      blocksize = blksize_size[maj][min];
    }
  }
  i = blocksize;
  blocksize_bits = 0;
  while(i != 1) {
    blocksize_bits++;
    i >>= 1;
  }

  if(count) {
    size = count;
  } else {
    if (blk_size[maj]) {
      size = ((loff_t) blk_size[maj][min] << BLOCK_SIZE_BITS) >> blocksize_bits;
    }
  }
  total_sectors = size;
  size *= blocksize;
  totalsize = size;
  DEBUG(1, "blkmtd: size = %ld\n", (long int)size);

  if(size == 0) {
    printk("blkmtd: cant determine size\n");
    return 1;
  }
  rawdevice = (mtd_raw_dev_data_t *)kmalloc(sizeof(mtd_raw_dev_data_t), GFP_KERNEL);
  if(rawdevice == NULL) {
    err = -ENOMEM;
    goto init_err;
  }
  memset(rawdevice, 0, sizeof(mtd_raw_dev_data_t));
  // get the block device
  rawdevice->binding = bdget(kdev_t_to_nr(MKDEV(maj, min)));
  err = blkdev_get(rawdevice->binding, mode, 0, BDEV_RAW);
  if (err) {
    goto init_err;
  }
  rawdevice->totalsize = totalsize;
  rawdevice->total_sectors = total_sectors;
  rawdevice->sector_size = blocksize;
  rawdevice->sector_bits = blocksize_bits;
  rawdevice->readonly = readonly;

  DEBUG(2, "sector_size = %d, sector_bits = %d\n", rawdevice->sector_size, rawdevice->sector_bits);

  mtd_info = (struct mtd_info *)kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
  if (mtd_info == NULL) {
    err = -ENOMEM;
    goto init_err;
  }
  memset(mtd_info, 0, sizeof(*mtd_info));

  // Setup the MTD structure
  mtd_info->name = "blkmtd block device";
  if(readonly) {
    mtd_info->type = MTD_ROM;
    mtd_info->flags = MTD_CAP_ROM;
    mtd_info->erasesize = erase_size << 10;
  } else {
    mtd_info->type = MTD_RAM;
    mtd_info->flags = MTD_CAP_RAM;
    mtd_info->erasesize = erase_size << 10;
  }
  mtd_info->size = size;
  mtd_info->erase = blkmtd_erase;
  mtd_info->read = blkmtd_read;
  mtd_info->write = blkmtd_write;
  mtd_info->sync = blkmtd_sync;
  mtd_info->point = 0;
  mtd_info->unpoint = 0;

  mtd_info->priv = rawdevice;
  regions = calc_erase_regions(NULL, erase_size << 10, size);
  DEBUG(1, "blkmtd: init: found %d erase regions\n", regions);
  mtd_info->eraseregions = kmalloc(regions * sizeof(struct mtd_erase_region_info), GFP_KERNEL);
  if(mtd_info->eraseregions == NULL) {
  }
  mtd_info->numeraseregions = regions;
  calc_erase_regions(mtd_info->eraseregions, erase_size << 10, size);

  /* setup the page cache info */
  INIT_LIST_HEAD(&rawdevice->as.clean_pages);
  INIT_LIST_HEAD(&rawdevice->as.dirty_pages);
  INIT_LIST_HEAD(&rawdevice->as.locked_pages);
  rawdevice->as.nrpages = 0;
  rawdevice->as.a_ops = &blkmtd_aops;
  rawdevice->as.host = inode;
  rawdevice->as.i_mmap = NULL;
  rawdevice->as.i_mmap_shared = NULL;
  spin_lock_init(&rawdevice->as.i_shared_lock);
  rawdevice->as.gfp_mask = GFP_KERNEL;
  rawdevice->file = file;

  file->private_data = rawdevice;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
   mtd_info->module = THIS_MODULE;			
#endif
   if (add_mtd_device(mtd_info)) {
     err = -EIO;
     goto init_err;
   }
   init_waitqueue_head(&thr_wq);
   init_waitqueue_head(&mtbd_sync_wq);
   DEBUG(3, "blkmtd: init: kernel task @ %p\n", write_queue_task);
   DEBUG(2, "blkmtd: init: starting kernel task\n");
   kernel_thread(write_queue_task, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
   DEBUG(2, "blkmtd: init: started\n");
   printk("blkmtd loaded: version = %s using %s erase_size = %dK %s\n", VERSION, device, erase_size, (readonly) ? "(read-only)" : "");
   return 0;

 init_err:
   if(!rawdevice) {
     if(rawdevice->binding) 
       blkdev_put(rawdevice->binding, BDEV_RAW);

     kfree(rawdevice);
     rawdevice = NULL;
   }
   if(mtd_info) {
     if(mtd_info->eraseregions)
       kfree(mtd_info->eraseregions);
     kfree(mtd_info);
     mtd_info = NULL;
   }
   return err;
}
Exemplo n.º 5
0
static ssize_t resume_show(struct kobject *kobj, struct kobj_attribute *attr,
			   char *buf)
{
	return sprintf(buf,"%d:%d\n", MAJOR(swsusp_resume_device),
		       MINOR(swsusp_resume_device));
}
Exemplo n.º 6
0
Arquivo: main.c Projeto: kong123/STUDY
/**
 * <Ring 1> Make a available Orange'S FS in the disk. It will
 *          - Write a super block to sector 1.
 *          - Create three special files: dev_tty0, dev_tty1, dev_tty2
 *          - Create a file cmd.tar
 *          - Create the inode map
 *          - Create the sector map
 *          - Create the inodes of the files
 *          - Create `/', the root directory
 *****************************************************************************/
PRIVATE void mkfs()
{
    MESSAGE driver_msg;
    int i, j;

    /************************/
    /*      super block     */
    /************************/
    /* get the geometry of ROOTDEV */
    struct part_info geo;
    driver_msg.type		= DEV_IOCTL;
    driver_msg.DEVICE	= MINOR(ROOT_DEV);
    driver_msg.REQUEST	= DIOCTL_GET_GEO;
    driver_msg.BUF		= &geo;
    driver_msg.PROC_NR	= TASK_FS;
    assert(dd_map[MAJOR(ROOT_DEV)].driver_nr != INVALID_DRIVER);
    send_recv(BOTH, dd_map[MAJOR(ROOT_DEV)].driver_nr, &driver_msg);

    printl("{FS} dev size: 0x%x sectors\n", geo.size);

    int bits_per_sect = SECTOR_SIZE * 8; /* 8 bits per byte */
    /* generate a super block */
    struct super_block sb;
    sb.magic	  = MAGIC_V1; /* 0x111 */
    sb.nr_inodes	  = bits_per_sect;
    sb.nr_inode_sects = sb.nr_inodes * INODE_SIZE / SECTOR_SIZE;
    sb.nr_sects	  = geo.size; /* partition size in sector */
    sb.nr_imap_sects  = 1;
    sb.nr_smap_sects  = sb.nr_sects / bits_per_sect + 1;
    sb.n_1st_sect	  = 1 + 1 +   /* boot sector & super block */
                        sb.nr_imap_sects + sb.nr_smap_sects + sb.nr_inode_sects;
    sb.root_inode	  = ROOT_INODE;
    sb.inode_size	  = INODE_SIZE;
    struct inode x;
    sb.inode_isize_off= (int)&x.i_size - (int)&x;
    sb.inode_start_off= (int)&x.i_start_sect - (int)&x;
    sb.dir_ent_size	  = DIR_ENTRY_SIZE;
    struct dir_entry de;
    sb.dir_ent_inode_off = (int)&de.inode_nr - (int)&de;
    sb.dir_ent_fname_off = (int)&de.name - (int)&de;

    memset(fsbuf, 0x90, SECTOR_SIZE);
    memcpy(fsbuf, &sb, SUPER_BLOCK_SIZE);

    /* write the super block */
    WR_SECT(ROOT_DEV, 1);

    printl("{FS} devbase:0x%x00, sb:0x%x00, imap:0x%x00, smap:0x%x00\n"
           "        inodes:0x%x00, 1st_sector:0x%x00\n",
           geo.base * 2,
           (geo.base + 1) * 2,
           (geo.base + 1 + 1) * 2,
           (geo.base + 1 + 1 + sb.nr_imap_sects) * 2,
           (geo.base + 1 + 1 + sb.nr_imap_sects + sb.nr_smap_sects) * 2,
           (geo.base + sb.n_1st_sect) * 2);

    /************************/
    /*       inode map      */
    /************************/
    memset(fsbuf, 0, SECTOR_SIZE);
    for (i = 0; i < (NR_CONSOLES + 3); i++)
        fsbuf[0] |= 1 << i;

    assert(fsbuf[0] == 0x3F);/* 0011 1111 :
				  *   || ||||
				  *   || |||`--- bit 0 : reserved
				  *   || ||`---- bit 1 : the first inode,
				  *   || ||              which indicates `/'
				  *   || |`----- bit 2 : /dev_tty0
				  *   || `------ bit 3 : /dev_tty1
				  *   |`-------- bit 4 : /dev_tty2
				  *   `--------- bit 5 : /cmd.tar
				  */
    WR_SECT(ROOT_DEV, 2);

    /************************/
    /*      secter map      */
    /************************/
    memset(fsbuf, 0, SECTOR_SIZE);
    int nr_sects = NR_DEFAULT_FILE_SECTS + 1;
    /*             ~~~~~~~~~~~~~~~~~~~|~   |
     *                                |    `--- bit 0 is reserved
     *                                `-------- for `/'
     */
    for (i = 0; i < nr_sects / 8; i++)
        fsbuf[i] = 0xFF;

    for (j = 0; j < nr_sects % 8; j++)
        fsbuf[i] |= (1 << j);

    WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects);

    /* zeromemory the rest sector-map */
    memset(fsbuf, 0, SECTOR_SIZE);
    for (i = 1; i < sb.nr_smap_sects; i++)
        WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + i);

    /* cmd.tar */
    /* make sure it'll not be overwritten by the disk log */
    assert(INSTALL_START_SECT + INSTALL_NR_SECTS <
           sb.nr_sects - NR_SECTS_FOR_LOG);
    int bit_offset = INSTALL_START_SECT -
                     sb.n_1st_sect + 1; /* sect M <-> bit (M - sb.n_1stsect + 1) */
    int bit_off_in_sect = bit_offset % (SECTOR_SIZE * 8);
    int bit_left = INSTALL_NR_SECTS;
    int cur_sect = bit_offset / (SECTOR_SIZE * 8);
    RD_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect);
    while (bit_left) {
        int byte_off = bit_off_in_sect / 8;
        /* this line is ineffecient in a loop, but I don't care */
        fsbuf[byte_off] |= 1 << (bit_off_in_sect % 8);
        bit_left--;
        bit_off_in_sect++;
        if (bit_off_in_sect == (SECTOR_SIZE * 8)) {
            WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect);
            cur_sect++;
            RD_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect);
            bit_off_in_sect = 0;
        }
    }
    WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect);

    /************************/
    /*       inodes         */
    /************************/
    /* inode of `/' */
    memset(fsbuf, 0, SECTOR_SIZE);
    struct inode * pi = (struct inode*)fsbuf;
    pi->i_mode = I_DIRECTORY;
    pi->i_size = DIR_ENTRY_SIZE * 5; /* 5 files:
					  * `.',
					  * `dev_tty0', `dev_tty1', `dev_tty2',
					  * `cmd.tar'
					  */
    pi->i_start_sect = sb.n_1st_sect;
    pi->i_nr_sects = NR_DEFAULT_FILE_SECTS;
    /* inode of `/dev_tty0~2' */
    for (i = 0; i < NR_CONSOLES; i++) {
        pi = (struct inode*)(fsbuf + (INODE_SIZE * (i + 1)));
        pi->i_mode = I_CHAR_SPECIAL;
        pi->i_size = 0;
        pi->i_start_sect = MAKE_DEV(DEV_CHAR_TTY, i);
        pi->i_nr_sects = 0;
    }
    /* inode of `/cmd.tar' */
    pi = (struct inode*)(fsbuf + (INODE_SIZE * (NR_CONSOLES + 1)));
    pi->i_mode = I_REGULAR;
    pi->i_size = INSTALL_NR_SECTS * SECTOR_SIZE;
    pi->i_start_sect = INSTALL_START_SECT;
    pi->i_nr_sects = INSTALL_NR_SECTS;
    WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + sb.nr_smap_sects);

    /************************/
    /*          `/'         */
    /************************/
    memset(fsbuf, 0, SECTOR_SIZE);
    struct dir_entry * pde = (struct dir_entry *)fsbuf;

    pde->inode_nr = 1;
    strcpy(pde->name, ".");

    /* dir entries of `/dev_tty0~2' */
    for (i = 0; i < NR_CONSOLES; i++) {
        pde++;
        pde->inode_nr = i + 2; /* dev_tty0's inode_nr is 2 */
        sprintf(pde->name, "dev_tty%d", i);
    }
    (++pde)->inode_nr = NR_CONSOLES + 2;
    strcpy(pde->name, "cmd.tar");
    WR_SECT(ROOT_DEV, sb.n_1st_sect);
}
Exemplo n.º 7
0
static int show_vfsmnt(struct seq_file *m, struct vfsmount *mnt)
{
	struct mount *r = real_mount(mnt);
	int err = 0;
	struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
	struct super_block *sb = mnt_path.dentry->d_sb;

	if (sb->s_op->show_devname) {
		err = sb->s_op->show_devname(m, mnt_path.dentry);
		if (err)
			goto out;
	} else {
		mangle(m, r->mnt_devname ? r->mnt_devname : "none");
	}
	seq_putc(m, ' ');
	seq_path(m, &mnt_path, " \t\n\\");
	seq_putc(m, ' ');
	show_type(m, sb);
	seq_puts(m, __mnt_is_readonly(mnt) ? " ro" : " rw");
	err = show_sb_opts(m, sb);
	if (err)
		goto out;
	show_mnt_opts(m, mnt);
	if (sb->s_op->show_options2)
			err = sb->s_op->show_options2(mnt, m, mnt_path.dentry);
	else if (sb->s_op->show_options)
		err = sb->s_op->show_options(m, mnt_path.dentry);
	seq_puts(m, " 0 0\n");
out:
	return err;
}

static int show_mountinfo(struct seq_file *m, struct vfsmount *mnt)
{
	struct proc_mounts *p = proc_mounts(m);
	struct mount *r = real_mount(mnt);
	struct super_block *sb = mnt->mnt_sb;
	struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
	struct path root = p->root;
	int err = 0;

	seq_printf(m, "%i %i %u:%u ", r->mnt_id, r->mnt_parent->mnt_id,
		   MAJOR(sb->s_dev), MINOR(sb->s_dev));
	if (sb->s_op->show_path)
		err = sb->s_op->show_path(m, mnt->mnt_root);
	else
		seq_dentry(m, mnt->mnt_root, " \t\n\\");
	if (err)
		goto out;
	seq_putc(m, ' ');

	/* mountpoints outside of chroot jail will give SEQ_SKIP on this */
	err = seq_path_root(m, &mnt_path, &root, " \t\n\\");
	if (err)
		goto out;

	seq_puts(m, mnt->mnt_flags & MNT_READONLY ? " ro" : " rw");
	show_mnt_opts(m, mnt);

	/* Tagged fields ("foo:X" or "bar") */
	if (IS_MNT_SHARED(r))
		seq_printf(m, " shared:%i", r->mnt_group_id);
	if (IS_MNT_SLAVE(r)) {
		int master = r->mnt_master->mnt_group_id;
		int dom = get_dominating_id(r, &p->root);
		seq_printf(m, " master:%i", master);
		if (dom && dom != master)
			seq_printf(m, " propagate_from:%i", dom);
	}
	if (IS_MNT_UNBINDABLE(r))
		seq_puts(m, " unbindable");

	/* Filesystem specific data */
	seq_puts(m, " - ");
	show_type(m, sb);
	seq_putc(m, ' ');
	if (sb->s_op->show_devname)
		err = sb->s_op->show_devname(m, mnt->mnt_root);
	else
		mangle(m, r->mnt_devname ? r->mnt_devname : "none");
	if (err)
		goto out;
	seq_puts(m, sb->s_flags & MS_RDONLY ? " ro" : " rw");
	err = show_sb_opts(m, sb);
	if (err)
		goto out;
	if (sb->s_op->show_options2) {
		err = sb->s_op->show_options2(mnt, m, mnt->mnt_root);
	} else if (sb->s_op->show_options)
		err = sb->s_op->show_options(m, mnt->mnt_root);
	seq_putc(m, '\n');
out:
	return err;
}

static int show_vfsstat(struct seq_file *m, struct vfsmount *mnt)
{
	struct mount *r = real_mount(mnt);
	struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
	struct super_block *sb = mnt_path.dentry->d_sb;
	int err = 0;

	/* device */
	if (sb->s_op->show_devname) {
		seq_puts(m, "device ");
		err = sb->s_op->show_devname(m, mnt_path.dentry);
	} else {
		if (r->mnt_devname) {
			seq_puts(m, "device ");
			mangle(m, r->mnt_devname);
		} else
			seq_puts(m, "no device");
	}

	/* mount point */
	seq_puts(m, " mounted on ");
	seq_path(m, &mnt_path, " \t\n\\");
	seq_putc(m, ' ');

	/* file system type */
	seq_puts(m, "with fstype ");
	show_type(m, sb);

	/* optional statistics */
	if (sb->s_op->show_stats) {
		seq_putc(m, ' ');
		if (!err)
			err = sb->s_op->show_stats(m, mnt_path.dentry);
	}

	seq_putc(m, '\n');
	return err;
}

static int mounts_open_common(struct inode *inode, struct file *file,
			      int (*show)(struct seq_file *, struct vfsmount *))
{
	struct task_struct *task = get_proc_task(inode);
	struct nsproxy *nsp;
	struct mnt_namespace *ns = NULL;
	struct path root;
	struct proc_mounts *p;
	int ret = -EINVAL;

	if (!task)
		goto err;

	rcu_read_lock();
	nsp = task_nsproxy(task);
	if (!nsp) {
		rcu_read_unlock();
		put_task_struct(task);
		goto err;
	}
	ns = nsp->mnt_ns;
	if (!ns) {
		rcu_read_unlock();
		put_task_struct(task);
		goto err;
	}
	get_mnt_ns(ns);
	rcu_read_unlock();
	task_lock(task);
	if (!task->fs) {
		task_unlock(task);
		put_task_struct(task);
		ret = -ENOENT;
		goto err_put_ns;
	}
	get_fs_root(task->fs, &root);
	task_unlock(task);
	put_task_struct(task);

	ret = -ENOMEM;
	p = kmalloc(sizeof(struct proc_mounts), GFP_KERNEL);
	if (!p)
		goto err_put_path;

	file->private_data = &p->m;
	ret = seq_open(file, &mounts_op);
	if (ret)
		goto err_free;

	p->ns = ns;
	p->root = root;
	p->m.poll_event = ns->event;
	p->show = show;

	return 0;

 err_free:
	kfree(p);
 err_put_path:
	path_put(&root);
 err_put_ns:
	put_mnt_ns(ns);
 err:
	return ret;
}

static int mounts_release(struct inode *inode, struct file *file)
{
	struct proc_mounts *p = proc_mounts(file->private_data);
	path_put(&p->root);
	put_mnt_ns(p->ns);
	return seq_release(inode, file);
}

static int mounts_open(struct inode *inode, struct file *file)
{
	return mounts_open_common(inode, file, show_vfsmnt);
}

static int mountinfo_open(struct inode *inode, struct file *file)
{
	return mounts_open_common(inode, file, show_mountinfo);
}

static int mountstats_open(struct inode *inode, struct file *file)
{
	return mounts_open_common(inode, file, show_vfsstat);
}

const struct file_operations proc_mounts_operations = {
	.open		= mounts_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= mounts_release,
	.poll		= mounts_poll,
};

const struct file_operations proc_mountinfo_operations = {
	.open		= mountinfo_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= mounts_release,
	.poll		= mounts_poll,
};

const struct file_operations proc_mountstats_operations = {
	.open		= mountstats_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= mounts_release,
};
Exemplo n.º 8
0
struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info)
{
	struct ptp_clock *ptp;
	int err = 0, index, major = MAJOR(ptp_devt);

	if (info->n_alarm > PTP_MAX_ALARMS)
		return ERR_PTR(-EINVAL);

	/* Find a free clock slot and reserve it. */
	err = -EBUSY;
	mutex_lock(&ptp_clocks_mutex);
	index = find_first_zero_bit(ptp_clocks_map, PTP_MAX_CLOCKS);
	if (index < PTP_MAX_CLOCKS)
		set_bit(index, ptp_clocks_map);
	else
		goto no_slot;

	/* Initialize a clock structure. */
	err = -ENOMEM;
	ptp = kzalloc(sizeof(struct ptp_clock), GFP_KERNEL);
	if (ptp == NULL)
		goto no_memory;

	ptp->clock.ops = ptp_clock_ops;
	ptp->clock.release = delete_ptp_clock;
	ptp->info = info;
	ptp->devid = MKDEV(major, index);
	ptp->index = index;
	spin_lock_init(&ptp->tsevq.lock);
	mutex_init(&ptp->tsevq_mux);
	init_waitqueue_head(&ptp->tsev_wq);

	/* Create a new device in our class. */
	ptp->dev = device_create(ptp_class, NULL, ptp->devid, ptp,
				 "ptp%d", ptp->index);
	if (IS_ERR(ptp->dev))
		goto no_device;

	dev_set_drvdata(ptp->dev, ptp);

	err = ptp_populate_sysfs(ptp);
	if (err)
		goto no_sysfs;

	/* Register a new PPS source. */
	if (info->pps) {
		struct pps_source_info pps;
		memset(&pps, 0, sizeof(pps));
		snprintf(pps.name, PPS_MAX_NAME_LEN, "ptp%d", index);
		pps.mode = PTP_PPS_MODE;
		pps.owner = info->owner;
		ptp->pps_source = pps_register_source(&pps, PTP_PPS_DEFAULTS);
		if (!ptp->pps_source) {
			pr_err("failed to register pps source\n");
			goto no_pps;
		}
	}

	/* Create a posix clock. */
	err = posix_clock_register(&ptp->clock, ptp->devid);
	if (err) {
		pr_err("failed to create posix clock\n");
		goto no_clock;
	}

	mutex_unlock(&ptp_clocks_mutex);
	return ptp;

no_clock:
	if (ptp->pps_source)
		pps_unregister_source(ptp->pps_source);
no_pps:
	ptp_cleanup_sysfs(ptp);
no_sysfs:
	device_destroy(ptp_class, ptp->devid);
no_device:
	mutex_destroy(&ptp->tsevq_mux);
	kfree(ptp);
no_memory:
	clear_bit(index, ptp_clocks_map);
no_slot:
	mutex_unlock(&ptp_clocks_mutex);
	return ERR_PTR(err);
}
Exemplo n.º 9
0
STATIC int
xfs_vn_mknod(
	struct inode	*dir,
	struct dentry	*dentry,
	int		mode,
	dev_t		rdev)
{
	struct inode	*inode;
	struct xfs_inode *ip = NULL;
	struct posix_acl *default_acl = NULL;
	struct xfs_name	name;
	int		error;

	/*
	 * Irix uses Missed'em'V split, but doesn't want to see
	 * the upper 5 bits of (14bit) major.
	 */
	if (S_ISCHR(mode) || S_ISBLK(mode)) {
		if (unlikely(!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff))
			return -EINVAL;
		rdev = sysv_encode_dev(rdev);
	} else {
		rdev = 0;
	}

	if (IS_POSIXACL(dir)) {
		default_acl = xfs_get_acl(dir, ACL_TYPE_DEFAULT);
		if (IS_ERR(default_acl))
			return PTR_ERR(default_acl);

		if (!default_acl)
			mode &= ~current_umask();
	}

	xfs_dentry_to_name(&name, dentry);
	error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip);
	if (unlikely(error))
		goto out_free_acl;

	inode = VFS_I(ip);

	error = xfs_init_security(inode, dir, &dentry->d_name);
	if (unlikely(error))
		goto out_cleanup_inode;

	if (default_acl) {
		error = -xfs_inherit_acl(inode, default_acl);
		default_acl = NULL;
		if (unlikely(error))
			goto out_cleanup_inode;
	}


	d_instantiate(dentry, inode);
	return -error;

 out_cleanup_inode:
	xfs_cleanup_inode(dir, inode, dentry);
 out_free_acl:
	posix_acl_release(default_acl);
	return -error;
}
Exemplo n.º 10
0
static ssize_t id_show(struct gfs2_sbd *sdp, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%u:%u\n",
			MAJOR(sdp->sd_vfs->s_dev), MINOR(sdp->sd_vfs->s_dev));
}
Exemplo n.º 11
0
/*
 * There's very little reason to use this, you should really
 * have a struct block_device just about everywhere and use
 * bdevname() instead.
 */
const char *__bdevname(dev_t dev, char *buffer)
{
	scnprintf(buffer, BDEVNAME_SIZE, "unknown-block(%u,%u)",
				MAJOR(dev), MINOR(dev));
	return buffer;
}
Exemplo n.º 12
0
int  init_module(void) {
    int ret,cdev_ret;
    int counter;
    char tmp[512];
    printk("dev_init\n");

    mychardev=kmalloc( sizeof(struct my_char_dev) * num_of_dev, GFP_KERNEL );

    ret=alloc_chrdev_region(&mychardev[0].dev,0, num_of_dev,DEVICE_NAME);
    if (ret<0)
    {
        printk(KERN_ALERT "Registering char device failed\n");
        return -EFAULT;
    } 

	Major=MAJOR(mychardev[0].dev);

    for(counter=0; counter < num_of_dev; counter++) {
        cdev_init( &mychardev[counter].mycdev, &fops);
        
        dev=MKDEV(Major, MINOR(dev)+counter);
        mychardev[counter].dev_open_counter=0;
        sema_init(&mychardev[counter].sem,1);

    	cdev_ret=cdev_add( &mychardev[counter].mycdev, dev,1);
    }

    if(cdev_ret)
        goto cdev_error;

    printk(KERN_ALERT "cdev is added\n");

    charmodule_class=class_create(THIS_MODULE, DEVICE_NAME);

    if (IS_ERR(charmodule_class))
        goto class_create_error;
    printk(KERN_ALERT "%s class is created\n",DEVICE_NAME);
    for(counter=0; counter < num_of_dev; counter++) {
        memset(tmp,'\0',sizeof(tmp));
        //      sprintf(tmp,"%s",DEVICE_NAME);
        sprintf(tmp,"%s%d",DEVICE_NAME,counter);
        //    sprintf(&tmpchar,"%d",counter);
        //  strcat(tmp,&tmpchar);
        printk("device create %s\n",tmp);
        device_create(charmodule_class, NULL, MKDEV(Major,counter) , NULL,tmp);
    } 

    printk(KERN_INFO "I was assigned major number %d. To talk to\n", Major);
    printk(KERN_INFO "the driver, create a dev file at /dev/%s \n", DEVICE_NAME);
    printk(KERN_INFO "Try various minor numbers. Try to cat and echo to\n");
    printk(KERN_INFO "the device file.\n");
    printk(KERN_INFO "Remove the device file and module when done.\n");
    return SUCCESS;


class_create_error:
    for(counter=0; counter < num_of_dev; counter++) {
        cdev_del(&mychardev[counter].mycdev);
     } 
 
    kfree(mychardev);

cdev_error:
    unregister_chrdev_region(dev,num_of_dev);

    return -EFAULT;
}
Exemplo n.º 13
0
static dev_t try_name(char *name, int part)
{
	char path[64];
	char buf[32];
	int range;
	dev_t res;
	char *s;
	int len;
	int fd;
	unsigned int maj, min;

	/* read device number from .../dev */

	sprintf(path, "/sys/block/%s/dev", name);
	fd = sys_open(path, 0, 0);
	if (fd < 0)
		goto fail;
	len = sys_read(fd, buf, 32);
	sys_close(fd);
	if (len <= 0 || len == 32 || buf[len - 1] != '\n')
		goto fail;
	buf[len - 1] = '\0';
	if (sscanf(buf, "%u:%u", &maj, &min) == 2) {
		/*
		 * Try the %u:%u format -- see print_dev_t()
		 */
		res = MKDEV(maj, min);
		if (maj != MAJOR(res) || min != MINOR(res))
			goto fail;
	} else {
		/*
		 * Nope.  Try old-style "0321"
		 */
		res = new_decode_dev(simple_strtoul(buf, &s, 16));
		if (*s)
			goto fail;
	}

	/* if it's there and we are not looking for a partition - that's it */
	if (!part)
		return res;

	/* otherwise read range from .../range */
	sprintf(path, "/sys/block/%s/range", name);
	fd = sys_open(path, 0, 0);
	if (fd < 0)
		goto fail;
	len = sys_read(fd, buf, 32);
	sys_close(fd);
	if (len <= 0 || len == 32 || buf[len - 1] != '\n')
		goto fail;
	buf[len - 1] = '\0';
	range = simple_strtoul(buf, &s, 10);
	if (*s)
		goto fail;

	/* if partition is within range - we got it */
	if (part < range)
		return res + part;
fail:
	return 0;
}
Exemplo n.º 14
0
dev_t name_to_dev_t(char *name)
{
	char s[32];
	char *p;
	dev_t res = 0;
	int part;

#ifdef CONFIG_SYSFS
	int mkdir_err = sys_mkdir("/sys", 0700);
	if (sys_mount("sysfs", "/sys", "sysfs", 0, NULL) < 0)
		goto out;
#endif

	if (strncmp(name, "/dev/", 5) != 0) {
		unsigned maj, min;

		if (sscanf(name, "%u:%u", &maj, &min) == 2) {
			res = MKDEV(maj, min);
			if (maj != MAJOR(res) || min != MINOR(res))
				goto fail;
		} else {
			res = new_decode_dev(simple_strtoul(name, &p, 16));
			if (*p)
				goto fail;
		}
		goto done;
	}
	name += 5;
	res = Root_NFS;
	if (strcmp(name, "nfs") == 0)
		goto done;
	res = Root_RAM0;
	if (strcmp(name, "ram") == 0)
		goto done;

	if (strlen(name) > 31)
		goto fail;
	strcpy(s, name);
	for (p = s; *p; p++)
		if (*p == '/')
			*p = '!';
	res = try_name(s, 0);
	if (res)
		goto done;

	while (p > s && isdigit(p[-1]))
		p--;
	if (p == s || !*p || *p == '0')
		goto fail;
	part = simple_strtoul(p, NULL, 10);
	*p = '\0';
	res = try_name(s, part);
	if (res)
		goto done;

	if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p')
		goto fail;
	p[-1] = '\0';
	res = try_name(s, part);
done:
#ifdef CONFIG_SYSFS
	sys_umount("/sys", 0);
out:
	if (!mkdir_err)
		sys_rmdir("/sys");
#endif
	return res;
fail:
	res = 0;
	goto done;
}
Exemplo n.º 15
0
/**
 * tomoyo_update_path_number_acl - Update ioctl/chmod/chown/chgrp ACL.
 *
 * @perm:  Permission.
 * @param: Pointer to "struct tomoyo_acl_param".
 *
 * Returns 0 on success, negative value otherwise.
 */
static int tomoyo_update_path_number_acl(const u8 perm,
					 struct tomoyo_acl_param *param)
{
	struct tomoyo_path_number_acl e = {
		.head.type = TOMOYO_TYPE_PATH_NUMBER_ACL,
		.perm = perm
	};
	int error;
	if (!tomoyo_parse_name_union(param, &e.name) ||
	    !tomoyo_parse_number_union(param, &e.number))
		error = -EINVAL;
	else
		error = tomoyo_update_domain(&e.head, sizeof(e), param,
					     tomoyo_same_path_number_acl,
					     tomoyo_merge_path_number_acl);
	tomoyo_put_name_union(&e.name);
	tomoyo_put_number_union(&e.number);
	return error;
}

/**
 * tomoyo_path_number_perm - Check permission for "create", "mkdir", "mkfifo", "mksock", "ioctl", "chmod", "chown", "chgrp".
 *
 * @type:   Type of operation.
 * @path:   Pointer to "struct path".
 * @number: Number.
 *
 * Returns 0 on success, negative value otherwise.
 */
int tomoyo_path_number_perm(const u8 type, struct path *path,
			    unsigned long number)
{
	struct tomoyo_request_info r;
	struct tomoyo_obj_info obj = {
		.path1 = { .mnt = path->mnt, .dentry = path->dentry },
	};
	int error = -ENOMEM;
	struct tomoyo_path_info buf;
	int idx;

	if (tomoyo_init_request_info(&r, NULL, tomoyo_pn2mac[type])
	    == TOMOYO_CONFIG_DISABLED || !path->dentry)
		return 0;
	idx = tomoyo_read_lock();
	if (!tomoyo_get_realpath(&buf, path))
		goto out;
	r.obj = &obj;
	if (type == TOMOYO_TYPE_MKDIR)
		tomoyo_add_slash(&buf);
	r.param_type = TOMOYO_TYPE_PATH_NUMBER_ACL;
	r.param.path_number.operation = type;
	r.param.path_number.filename = &buf;
	r.param.path_number.number = number;
	do {
		tomoyo_check_acl(&r, tomoyo_check_path_number_acl);
		error = tomoyo_audit_path_number_log(&r);
	} while (error == TOMOYO_RETRY_REQUEST);
	kfree(buf.name);
 out:
	tomoyo_read_unlock(idx);
	if (r.mode != TOMOYO_CONFIG_ENFORCING)
		error = 0;
	return error;
}

/**
 * tomoyo_check_open_permission - Check permission for "read" and "write".
 *
 * @domain: Pointer to "struct tomoyo_domain_info".
 * @path:   Pointer to "struct path".
 * @flag:   Flags for open().
 *
 * Returns 0 on success, negative value otherwise.
 */
int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
				 struct path *path, const int flag)
{
	const u8 acc_mode = ACC_MODE(flag);
	int error = 0;
	struct tomoyo_path_info buf;
	struct tomoyo_request_info r;
	struct tomoyo_obj_info obj = {
		.path1 = { .mnt = path->mnt, .dentry = path->dentry },
	};
	int idx;

	buf.name = NULL;
	r.mode = TOMOYO_CONFIG_DISABLED;
	idx = tomoyo_read_lock();
	if (acc_mode &&
	    tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_OPEN)
	    != TOMOYO_CONFIG_DISABLED) {
		if (!tomoyo_get_realpath(&buf, path)) {
			error = -ENOMEM;
			goto out;
		}
		r.obj = &obj;
		if (acc_mode & MAY_READ)
			error = tomoyo_path_permission(&r, TOMOYO_TYPE_READ,
						       &buf);
		if (!error && (acc_mode & MAY_WRITE))
			error = tomoyo_path_permission(&r, (flag & O_APPEND) ?
						       TOMOYO_TYPE_APPEND :
						       TOMOYO_TYPE_WRITE,
						       &buf);
	}
 out:
	kfree(buf.name);
	tomoyo_read_unlock(idx);
	if (r.mode != TOMOYO_CONFIG_ENFORCING)
		error = 0;
	return error;
}

/**
 * tomoyo_path_perm - Check permission for "unlink", "rmdir", "truncate", "symlink", "append", "chroot" and "unmount".
 *
 * @operation: Type of operation.
 * @path:      Pointer to "struct path".
 * @target:    Symlink's target if @operation is TOMOYO_TYPE_SYMLINK,
 *             NULL otherwise.
 *
 * Returns 0 on success, negative value otherwise.
 */
int tomoyo_path_perm(const u8 operation, const struct path *path, const char *target)
{
	struct tomoyo_request_info r;
	struct tomoyo_obj_info obj = {
		.path1 = { .mnt = path->mnt, .dentry = path->dentry },
	};
	int error;
	struct tomoyo_path_info buf;
	bool is_enforce;
	struct tomoyo_path_info symlink_target;
	int idx;

	if (tomoyo_init_request_info(&r, NULL, tomoyo_p2mac[operation])
	    == TOMOYO_CONFIG_DISABLED)
		return 0;
	is_enforce = (r.mode == TOMOYO_CONFIG_ENFORCING);
	error = -ENOMEM;
	buf.name = NULL;
	idx = tomoyo_read_lock();
	if (!tomoyo_get_realpath(&buf, path))
		goto out;
	r.obj = &obj;
	switch (operation) {
	case TOMOYO_TYPE_RMDIR:
	case TOMOYO_TYPE_CHROOT:
		tomoyo_add_slash(&buf);
		break;
	case TOMOYO_TYPE_SYMLINK:
		symlink_target.name = tomoyo_encode(target);
		if (!symlink_target.name)
			goto out;
		tomoyo_fill_path_info(&symlink_target);
		obj.symlink_target = &symlink_target;
		break;
	}
	error = tomoyo_path_permission(&r, operation, &buf);
	if (operation == TOMOYO_TYPE_SYMLINK)
		kfree(symlink_target.name);
 out:
	kfree(buf.name);
	tomoyo_read_unlock(idx);
	if (!is_enforce)
		error = 0;
	return error;
}

/**
 * tomoyo_mkdev_perm - Check permission for "mkblock" and "mkchar".
 *
 * @operation: Type of operation. (TOMOYO_TYPE_MKCHAR or TOMOYO_TYPE_MKBLOCK)
 * @path:      Pointer to "struct path".
 * @mode:      Create mode.
 * @dev:       Device number.
 *
 * Returns 0 on success, negative value otherwise.
 */
int tomoyo_mkdev_perm(const u8 operation, struct path *path,
		      const unsigned int mode, unsigned int dev)
{
	struct tomoyo_request_info r;
	struct tomoyo_obj_info obj = {
		.path1 = { .mnt = path->mnt, .dentry = path->dentry },
	};
	int error = -ENOMEM;
	struct tomoyo_path_info buf;
	int idx;

	if (tomoyo_init_request_info(&r, NULL, tomoyo_pnnn2mac[operation])
	    == TOMOYO_CONFIG_DISABLED)
		return 0;
	idx = tomoyo_read_lock();
	error = -ENOMEM;
	if (tomoyo_get_realpath(&buf, path)) {
		r.obj = &obj;
		dev = new_decode_dev(dev);
		r.param_type = TOMOYO_TYPE_MKDEV_ACL;
		r.param.mkdev.filename = &buf;
		r.param.mkdev.operation = operation;
		r.param.mkdev.mode = mode;
		r.param.mkdev.major = MAJOR(dev);
		r.param.mkdev.minor = MINOR(dev);
		tomoyo_check_acl(&r, tomoyo_check_mkdev_acl);
		error = tomoyo_audit_mkdev_log(&r);
		kfree(buf.name);
	}
	tomoyo_read_unlock(idx);
	if (r.mode != TOMOYO_CONFIG_ENFORCING)
		error = 0;
	return error;
}

/**
 * tomoyo_path2_perm - Check permission for "rename", "link" and "pivot_root".
 *
 * @operation: Type of operation.
 * @path1:      Pointer to "struct path".
 * @path2:      Pointer to "struct path".
 *
 * Returns 0 on success, negative value otherwise.
 */
int tomoyo_path2_perm(const u8 operation, struct path *path1,
		      struct path *path2)
{
	int error = -ENOMEM;
	struct tomoyo_path_info buf1;
	struct tomoyo_path_info buf2;
	struct tomoyo_request_info r;
	struct tomoyo_obj_info obj = {
		.path1 = { .mnt = path1->mnt, .dentry = path1->dentry },
		.path2 = { .mnt = path2->mnt, .dentry = path2->dentry }
	};
Exemplo n.º 16
0
static int __init mount_nfs_root(void)
{
	char *root_dev, *root_data;
	unsigned int timeout;
	int try, err;

	err = nfs_root_data(&root_dev, &root_data);
	if (err != 0)
		return 0;

	/*
	 * The server or network may not be ready, so try several
	 * times.  Stop after a few tries in case the client wants
	 * to fall back to other boot methods.
	 */
	timeout = NFSROOT_TIMEOUT_MIN;
	for (try = 1; ; try++) {
		err = do_mount_root(root_dev, "nfs",
					root_mountflags, root_data);
		if (err == 0)
			return 1;
		if (try > NFSROOT_RETRY_MAX)
			break;

		/* Wait, in case the server refused us immediately */
		ssleep(timeout);
		timeout <<= 1;
		if (timeout > NFSROOT_TIMEOUT_MAX)
			timeout = NFSROOT_TIMEOUT_MAX;
	}
	return 0;
}
#endif

#if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_FD)
void __init change_floppy(char *fmt, ...)
{
	struct termios termios;
	char buf[80];
	char c;
	int fd;
	va_list args;
	va_start(args, fmt);
	vsprintf(buf, fmt, args);
	va_end(args);
	fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
	if (fd >= 0) {
		sys_ioctl(fd, FDEJECT, 0);
		sys_close(fd);
	}
	printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
	fd = sys_open("/dev/console", O_RDWR, 0);
	if (fd >= 0) {
		sys_ioctl(fd, TCGETS, (long)&termios);
		termios.c_lflag &= ~ICANON;
		sys_ioctl(fd, TCSETSF, (long)&termios);
		sys_read(fd, &c, 1);
		termios.c_lflag |= ICANON;
		sys_ioctl(fd, TCSETSF, (long)&termios);
		sys_close(fd);
	}
}
#endif

void __init mount_root(void)
{
#ifdef CONFIG_ROOT_NFS
	if (ROOT_DEV == Root_NFS) {
		if (mount_nfs_root())
			return;

		printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
		ROOT_DEV = Root_FD0;
	}
#endif
#ifdef CONFIG_BLK_DEV_FD
	if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
		/* rd_doload is 2 for a dual initrd/ramload setup */
		if (rd_doload==2) {
			if (rd_load_disk(1)) {
				ROOT_DEV = Root_RAM1;
				root_device_name = NULL;
			}
		} else
			change_floppy("root floppy");
	}
#endif
#ifdef CONFIG_BLOCK
	create_dev("/dev/root", ROOT_DEV);
	mount_block_root("/dev/root", root_mountflags);
#endif
}

/*
 * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
 */
void __init prepare_namespace(void)
{
	int is_floppy;

	if (root_delay) {
		printk(KERN_INFO "Waiting %d sec before mounting root device...\n",
		       root_delay);
		ssleep(root_delay);
	}

	/*
	 * wait for the known devices to complete their probing
	 *
	 * Note: this is a potential source of long boot delays.
	 * For example, it is not atypical to wait 5 seconds here
	 * for the touchpad of a laptop to initialize.
	 */
	wait_for_device_probe();

	md_run_setup();

	if (saved_root_name[0]) {
		root_device_name = saved_root_name;
		if (!strncmp(root_device_name, "mtd", 3) ||
		    !strncmp(root_device_name, "ubi", 3)) {
			mount_block_root(root_device_name, root_mountflags);
			goto out;
		}
		ROOT_DEV = name_to_dev_t(root_device_name);
		if (strncmp(root_device_name, "/dev/", 5) == 0)
			root_device_name += 5;
	}

	if (initrd_load())
		goto out;

	/* wait for any asynchronous scanning to complete */
	if ((ROOT_DEV == 0) && root_wait) {
		printk(KERN_INFO "Waiting for root device %s...\n",
			saved_root_name);
		while (driver_probe_done() != 0 ||
			(ROOT_DEV = name_to_dev_t(saved_root_name)) == 0)
			msleep(100);
		async_synchronize_full();
	}

	is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;

	if (is_floppy && rd_doload && rd_load_disk(0))
		ROOT_DEV = Root_RAM0;

	mount_root();
out:
	devtmpfs_mount("dev");
	sys_mount(".", "/", NULL, MS_MOVE, NULL);
	sys_chroot(".");
}
Exemplo n.º 17
0
static int rmidev_init_device(struct rmi_char_device *cd)
{
    struct rmi_device *rmi_dev = cd->rmi_dev;
    struct rmidev_data *data;
    dev_t dev_no;
    int retval;
    struct device *device_ptr;

    if (rmidev_major_num) {
        dev_no = MKDEV(rmidev_major_num, cd->rmi_dev->number);
        retval = register_chrdev_region(dev_no, 1, CHAR_DEVICE_NAME);
    } else {
        retval = alloc_chrdev_region(&dev_no, 0, 1, CHAR_DEVICE_NAME);
        /* let kernel allocate a major for us */
        rmidev_major_num = MAJOR(dev_no);
        printk( "DTUCH : Device(%s) major number of rmidev(%d)\n", dev_name( &rmi_dev->dev ), rmidev_major_num );
    }
    if (retval < 0) {
        printk( "DTUCH : Device(%s) failed to get minor dev number%d(%d)\n", dev_name( &rmi_dev->dev ), cd->rmi_dev->number, retval );
        return retval;
    } else
        printk( "DTUCH : Device(%s) allocated rmidev %d %d\n", dev_name( &rmi_dev->dev ), MAJOR( dev_no ), MINOR( dev_no ) );

    data = kzalloc(sizeof(struct rmidev_data), GFP_KERNEL);
    if (!data) {
        printk( "DTUCH : Device(%s) failed to allocate rmidev_data\n", dev_name( &rmi_dev->dev ) );
        /* unregister the char device region */
        __unregister_chrdev(rmidev_major_num, MINOR(dev_no), 1,
                            CHAR_DEVICE_NAME);
        return -ENOMEM;
    }

    mutex_init(&data->file_mutex);

    data->rmi_dev = cd->rmi_dev;
    cd->data = data;

    cdev_init(&data->main_dev, &rmidev_fops);

    retval = cdev_add(&data->main_dev, dev_no, 1);
    if (retval) {
        printk( "DTUCH : Device(%s) error %d adding rmi_char_dev\n", dev_name( &cd->rmi_dev->dev ), retval );
        rmidev_device_cleanup(data);
        return retval;
    }

    dev_set_name(&cd->dev, "rmidev%d", MINOR(dev_no));
    data->device_class = rmidev_device_class;
    device_ptr = device_create(
                     data->device_class,
                     NULL, dev_no, NULL,
                     CHAR_DEVICE_NAME"%d",
                     MINOR(dev_no));

    if (IS_ERR(device_ptr)) {
        printk( "DTUCH : Device(%s) failed to create rmi device\n", dev_name( &cd->rmi_dev->dev ) );
        rmidev_device_cleanup(data);
        return -ENODEV;
    }

    return 0;
}
Exemplo n.º 18
0
static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno)
{
	struct watchdog_core_data *wd_data;
	int err;

	wd_data = kzalloc(sizeof(struct watchdog_core_data), GFP_KERNEL);
	if (!wd_data)
		return -ENOMEM;
	kref_init(&wd_data->kref);
	mutex_init(&wd_data->lock);

	wd_data->wdd = wdd;
	wdd->wd_data = wd_data;

	if (IS_ERR_OR_NULL(watchdog_kworker))
		return -ENODEV;

	kthread_init_work(&wd_data->work, watchdog_ping_work);
	hrtimer_init(&wd_data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	wd_data->timer.function = watchdog_timer_expired;

	if (wdd->id == 0) {
		old_wd_data = wd_data;
		watchdog_miscdev.parent = wdd->parent;
		err = misc_register(&watchdog_miscdev);
		if (err != 0) {
			pr_err("%s: cannot register miscdev on minor=%d (err=%d).\n",
				wdd->info->identity, WATCHDOG_MINOR, err);
			if (err == -EBUSY)
				pr_err("%s: a legacy watchdog module is probably present.\n",
					wdd->info->identity);
			old_wd_data = NULL;
			kfree(wd_data);
			return err;
		}
	}

	/* Fill in the data structures */
	cdev_init(&wd_data->cdev, &watchdog_fops);
	wd_data->cdev.owner = wdd->ops->owner;

	/* Add the device */
	err = cdev_add(&wd_data->cdev, devno, 1);
	if (err) {
		pr_err("watchdog%d unable to add device %d:%d\n",
			wdd->id,  MAJOR(watchdog_devt), wdd->id);
		if (wdd->id == 0) {
			misc_deregister(&watchdog_miscdev);
			old_wd_data = NULL;
			kref_put(&wd_data->kref, watchdog_core_data_release);
		}
		return err;
	}

	/* Record time of most recent heartbeat as 'just before now'. */
	wd_data->last_hw_keepalive = ktime_sub(ktime_get(), 1);

	/*
	 * If the watchdog is running, prevent its driver from being unloaded,
	 * and schedule an immediate ping.
	 */
	if (watchdog_hw_running(wdd)) {
		__module_get(wdd->ops->owner);
		kref_get(&wd_data->kref);
		if (handle_boot_enabled)
			hrtimer_start(&wd_data->timer, 0, HRTIMER_MODE_REL);
		else
			pr_info("watchdog%d running and kernel based pre-userspace handler disabled\n",
				wdd->id);
	}

	return 0;
}
Exemplo n.º 19
0
static int
nfs3_proc_remove(struct inode *dir, struct qstr *name)
{
    struct nfs_removeargs arg = {
        .fh = NFS_FH(dir),
        .name.len = name->len,
        .name.name = name->name,
    };
    struct nfs_removeres res;
    struct rpc_message msg = {
        .rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE],
        .rpc_argp = &arg,
        .rpc_resp = &res,
    };
    int status = -ENOMEM;

    dprintk("NFS call  remove %s\n", name->name);
    res.dir_attr = nfs_alloc_fattr();
    if (res.dir_attr == NULL)
        goto out;

    status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
    nfs_post_op_update_inode(dir, res.dir_attr);
    nfs_free_fattr(res.dir_attr);
out:
    dprintk("NFS reply remove: %d\n", status);
    return status;
}

static void
nfs3_proc_unlink_setup(struct rpc_message *msg, struct inode *dir)
{
    msg->rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE];
}

static int
nfs3_proc_unlink_done(struct rpc_task *task, struct inode *dir)
{
    struct nfs_removeres *res;
    if (nfs3_async_handle_jukebox(task, dir))
        return 0;
    res = task->tk_msg.rpc_resp;
    nfs_post_op_update_inode(dir, res->dir_attr);
    return 1;
}

static void
nfs3_proc_rename_setup(struct rpc_message *msg, struct inode *dir)
{
    msg->rpc_proc = &nfs3_procedures[NFS3PROC_RENAME];
}

static int
nfs3_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
                      struct inode *new_dir)
{
    struct nfs_renameres *res;

    if (nfs3_async_handle_jukebox(task, old_dir))
        return 0;
    res = task->tk_msg.rpc_resp;

    nfs_post_op_update_inode(old_dir, res->old_fattr);
    nfs_post_op_update_inode(new_dir, res->new_fattr);
    return 1;
}

static int
nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name,
                 struct inode *new_dir, struct qstr *new_name)
{
    struct nfs_renameargs	arg = {
        .old_dir	= NFS_FH(old_dir),
        .old_name	= old_name,
        .new_dir	= NFS_FH(new_dir),
        .new_name	= new_name,
    };
    struct nfs_renameres res;
    struct rpc_message msg = {
        .rpc_proc	= &nfs3_procedures[NFS3PROC_RENAME],
        .rpc_argp	= &arg,
        .rpc_resp	= &res,
    };
    int status = -ENOMEM;

    dprintk("NFS call  rename %s -> %s\n", old_name->name, new_name->name);

    res.old_fattr = nfs_alloc_fattr();
    res.new_fattr = nfs_alloc_fattr();
    if (res.old_fattr == NULL || res.new_fattr == NULL)
        goto out;

    status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0);
    nfs_post_op_update_inode(old_dir, res.old_fattr);
    nfs_post_op_update_inode(new_dir, res.new_fattr);
out:
    nfs_free_fattr(res.old_fattr);
    nfs_free_fattr(res.new_fattr);
    dprintk("NFS reply rename: %d\n", status);
    return status;
}

static int
nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
{
    struct nfs3_linkargs	arg = {
        .fromfh		= NFS_FH(inode),
        .tofh		= NFS_FH(dir),
        .toname		= name->name,
        .tolen		= name->len
    };
    struct nfs3_linkres	res;
    struct rpc_message msg = {
        .rpc_proc	= &nfs3_procedures[NFS3PROC_LINK],
        .rpc_argp	= &arg,
        .rpc_resp	= &res,
    };
    int status = -ENOMEM;

    dprintk("NFS call  link %s\n", name->name);
    res.fattr = nfs_alloc_fattr();
    res.dir_attr = nfs_alloc_fattr();
    if (res.fattr == NULL || res.dir_attr == NULL)
        goto out;

    status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
    nfs_post_op_update_inode(dir, res.dir_attr);
    nfs_post_op_update_inode(inode, res.fattr);
out:
    nfs_free_fattr(res.dir_attr);
    nfs_free_fattr(res.fattr);
    dprintk("NFS reply link: %d\n", status);
    return status;
}

static int
nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
                  unsigned int len, struct iattr *sattr)
{
    struct nfs3_createdata *data;
    int status = -ENOMEM;

    if (len > NFS3_MAXPATHLEN)
        return -ENAMETOOLONG;

    dprintk("NFS call  symlink %s\n", dentry->d_name.name);

    data = nfs3_alloc_createdata();
    if (data == NULL)
        goto out;
    data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_SYMLINK];
    data->arg.symlink.fromfh = NFS_FH(dir);
    data->arg.symlink.fromname = dentry->d_name.name;
    data->arg.symlink.fromlen = dentry->d_name.len;
    data->arg.symlink.pages = &page;
    data->arg.symlink.pathlen = len;
    data->arg.symlink.sattr = sattr;

    status = nfs3_do_create(dir, dentry, data);

    nfs3_free_createdata(data);
out:
    dprintk("NFS reply symlink: %d\n", status);
    return status;
}

static int
nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
{
    struct nfs3_createdata *data;
    int mode = sattr->ia_mode;
    int status = -ENOMEM;

    dprintk("NFS call  mkdir %s\n", dentry->d_name.name);

    sattr->ia_mode &= ~current_umask();

    data = nfs3_alloc_createdata();
    if (data == NULL)
        goto out;

    data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_MKDIR];
    data->arg.mkdir.fh = NFS_FH(dir);
    data->arg.mkdir.name = dentry->d_name.name;
    data->arg.mkdir.len = dentry->d_name.len;
    data->arg.mkdir.sattr = sattr;

    status = nfs3_do_create(dir, dentry, data);
    if (status != 0)
        goto out;

    status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode);
out:
    nfs3_free_createdata(data);
    dprintk("NFS reply mkdir: %d\n", status);
    return status;
}

static int
nfs3_proc_rmdir(struct inode *dir, struct qstr *name)
{
    struct nfs_fattr	*dir_attr;
    struct nfs3_diropargs	arg = {
        .fh		= NFS_FH(dir),
        .name		= name->name,
        .len		= name->len
    };
    struct rpc_message msg = {
        .rpc_proc	= &nfs3_procedures[NFS3PROC_RMDIR],
        .rpc_argp	= &arg,
    };
    int status = -ENOMEM;

    dprintk("NFS call  rmdir %s\n", name->name);
    dir_attr = nfs_alloc_fattr();
    if (dir_attr == NULL)
        goto out;

    msg.rpc_resp = dir_attr;
    status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
    nfs_post_op_update_inode(dir, dir_attr);
    nfs_free_fattr(dir_attr);
out:
    dprintk("NFS reply rmdir: %d\n", status);
    return status;
}

/*
 * The READDIR implementation is somewhat hackish - we pass the user buffer
 * to the encode function, which installs it in the receive iovec.
 * The decode function itself doesn't perform any decoding, it just makes
 * sure the reply is syntactically correct.
 *
 * Also note that this implementation handles both plain readdir and
 * readdirplus.
 */
static int
nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
                  u64 cookie, struct page **pages, unsigned int count, int plus)
{
    struct inode		*dir = dentry->d_inode;
    __be32			*verf = NFS_I(dir)->cookieverf;
    struct nfs3_readdirargs	arg = {
        .fh		= NFS_FH(dir),
        .cookie		= cookie,
        .verf		= {verf[0], verf[1]},
        .plus		= plus,
        .count		= count,
        .pages		= pages
    };
    struct nfs3_readdirres	res = {
        .verf		= verf,
        .plus		= plus
    };
    struct rpc_message	msg = {
        .rpc_proc	= &nfs3_procedures[NFS3PROC_READDIR],
        .rpc_argp	= &arg,
        .rpc_resp	= &res,
        .rpc_cred	= cred
    };
    int status = -ENOMEM;

    if (plus)
        msg.rpc_proc = &nfs3_procedures[NFS3PROC_READDIRPLUS];

    dprintk("NFS call  readdir%s %d\n",
            plus? "plus" : "", (unsigned int) cookie);

    res.dir_attr = nfs_alloc_fattr();
    if (res.dir_attr == NULL)
        goto out;

    status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);

    nfs_invalidate_atime(dir);
    nfs_refresh_inode(dir, res.dir_attr);

    nfs_free_fattr(res.dir_attr);
out:
    dprintk("NFS reply readdir%s: %d\n",
            plus? "plus" : "", status);
    return status;
}

static int
nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
                dev_t rdev)
{
    struct nfs3_createdata *data;
    mode_t mode = sattr->ia_mode;
    int status = -ENOMEM;

    dprintk("NFS call  mknod %s %u:%u\n", dentry->d_name.name,
            MAJOR(rdev), MINOR(rdev));

    sattr->ia_mode &= ~current_umask();

    data = nfs3_alloc_createdata();
    if (data == NULL)
        goto out;

    data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_MKNOD];
    data->arg.mknod.fh = NFS_FH(dir);
    data->arg.mknod.name = dentry->d_name.name;
    data->arg.mknod.len = dentry->d_name.len;
    data->arg.mknod.sattr = sattr;
    data->arg.mknod.rdev = rdev;

    switch (sattr->ia_mode & S_IFMT) {
    case S_IFBLK:
        data->arg.mknod.type = NF3BLK;
        break;
    case S_IFCHR:
        data->arg.mknod.type = NF3CHR;
        break;
    case S_IFIFO:
        data->arg.mknod.type = NF3FIFO;
        break;
    case S_IFSOCK:
        data->arg.mknod.type = NF3SOCK;
        break;
    default:
        status = -EINVAL;
        goto out;
    }

    status = nfs3_do_create(dir, dentry, data);
    if (status != 0)
        goto out;
    status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode);
out:
    nfs3_free_createdata(data);
    dprintk("NFS reply mknod: %d\n", status);
    return status;
}

static int
nfs3_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
                 struct nfs_fsstat *stat)
{
    struct rpc_message msg = {
        .rpc_proc	= &nfs3_procedures[NFS3PROC_FSSTAT],
        .rpc_argp	= fhandle,
        .rpc_resp	= stat,
    };
    int	status;

    dprintk("NFS call  fsstat\n");
    nfs_fattr_init(stat->fattr);
    status = rpc_call_sync(server->client, &msg, 0);
    dprintk("NFS reply fsstat: %d\n", status);
    return status;
}

static int
do_proc_fsinfo(struct rpc_clnt *client, struct nfs_fh *fhandle,
               struct nfs_fsinfo *info)
{
    struct rpc_message msg = {
        .rpc_proc	= &nfs3_procedures[NFS3PROC_FSINFO],
        .rpc_argp	= fhandle,
        .rpc_resp	= info,
    };
    int	status;

    dprintk("NFS call  fsinfo\n");
    nfs_fattr_init(info->fattr);
    status = rpc_call_sync(client, &msg, 0);
    dprintk("NFS reply fsinfo: %d\n", status);
    return status;
}

/*
 * Bare-bones access to fsinfo: this is for nfs_get_root/nfs_get_sb via
 * nfs_create_server
 */
static int
nfs3_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
                 struct nfs_fsinfo *info)
{
    int	status;

    status = do_proc_fsinfo(server->client, fhandle, info);
    if (status && server->nfs_client->cl_rpcclient != server->client)
        status = do_proc_fsinfo(server->nfs_client->cl_rpcclient, fhandle, info);
    return status;
}

static int
nfs3_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
                   struct nfs_pathconf *info)
{
    struct rpc_message msg = {
        .rpc_proc	= &nfs3_procedures[NFS3PROC_PATHCONF],
        .rpc_argp	= fhandle,
        .rpc_resp	= info,
    };
    int	status;

    dprintk("NFS call  pathconf\n");
    nfs_fattr_init(info->fattr);
    status = rpc_call_sync(server->client, &msg, 0);
    dprintk("NFS reply pathconf: %d\n", status);
    return status;
}

static int nfs3_read_done(struct rpc_task *task, struct nfs_read_data *data)
{
    struct inode *inode = data->header->inode;

    if (nfs3_async_handle_jukebox(task, inode))
        return -EAGAIN;

    nfs_invalidate_atime(inode);
    nfs_refresh_inode(inode, &data->fattr);
    return 0;
}

static void nfs3_proc_read_setup(struct nfs_read_data *data, struct rpc_message *msg)
{
    msg->rpc_proc = &nfs3_procedures[NFS3PROC_READ];
}

static int nfs3_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_data *data)
{
    rpc_call_start(task);
    return 0;
}
Exemplo n.º 20
0
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/uio.h>
#include <sys/utsname.h>
#include <sys/vfs.h>
#include "os.h"
#include "user.h"
#include "kern_util.h"

static void copy_stat(struct uml_stat *dst, struct stat64 *src)
{
	*dst = ((struct uml_stat) {
		.ust_major   = MAJOR(src->st_dev),     /* device */
		.ust_minor   = MINOR(src->st_dev),
		.ust_ino     = src->st_ino,     /* inode */
		.ust_mode    = src->st_mode,    /* protection */
		.ust_nlink   = src->st_nlink,   /* number of hard links */
		.ust_uid     = src->st_uid,     /* user ID of owner */
		.ust_gid     = src->st_gid,     /* group ID of owner */
		.ust_size    = src->st_size,    /* total size, in bytes */
		.ust_blksize = src->st_blksize, /* blocksize for filesys I/O */
		.ust_blocks  = src->st_blocks,  /* number of blocks allocated */
		.ust_atime   = src->st_atime,   /* time of last access */
		.ust_mtime   = src->st_mtime,   /* time of last modification */
		.ust_ctime   = src->st_ctime,   /* time of last change */
		.ust_rmajor  = MAJOR(src->st_rdev),
		.ust_rminor  = MINOR(src->st_rdev),
	});
Exemplo n.º 21
0
static int frandom_init_module(void)
{
	int result;

	/* The buffer size MUST be at least 256 bytes, because we assume that
	   minimal length in init_rand_state().
	*/
	if (frandom_bufsize < 256) {
		pr_err("frandom: Invalid frandom_bufsize: %d\n",
			frandom_bufsize);
		return -EINVAL;
	}
	if ((frandom_chunklimit != 0) && (frandom_chunklimit < 256)) {
		pr_err("frandom: Invalid frandom_chunklimit: %d\n",
			frandom_chunklimit);
		return -EINVAL;
	}

	erandom_state = kmalloc(sizeof(struct frandom_state), GFP_KERNEL);
	if (!erandom_state)
		return -ENOMEM;

	/* This specific buffer is only used for seeding, so we need
	   256 bytes exactly */
	erandom_state->buf = kmalloc(256, GFP_KERNEL);
	if (!erandom_state->buf) {
		kfree(erandom_state);
		return -ENOMEM;
	}

	sema_init(&erandom_state->sem, 1); /* Init semaphore as a mutex */

	erandom_seeded = 0;

	frandom_class = class_create(THIS_MODULE, "fastrng");
	if (IS_ERR(frandom_class)) {
		result = PTR_ERR(frandom_class);
		pr_warn("frandom: Failed to register class fastrng\n");
		goto error0;
	}

	/*
	 * Register your major, and accept a dynamic number. This is the
	 * first thing to do, in order to avoid releasing other module's
	 * fops in frandom_cleanup_module()
	 */

	result = alloc_chrdev_region(&frandom_devt, 0, NR_FRANDOM_DEVS,
		"frandom");
	if (result < 0) {
		pr_warn("frandom: failed to alloc frandom region\n");
		goto error1;
	}

	frandom_minor = MINOR(frandom_devt);
	erandom_minor = frandom_minor + 1;
	erandom_devt = MKDEV(MAJOR(frandom_devt), erandom_minor);

	cdev_init(&frandom_cdev, &frandom_fops);
	frandom_cdev.owner = THIS_MODULE;
	result = cdev_add(&frandom_cdev, frandom_devt, 1);
	if (result) {
		pr_warn("frandom: Failed to add cdev for /dev/frandom\n");
		goto error2;
	}

	frandom_device = device_create(frandom_class, NULL, frandom_devt,
		NULL, "frandom");

	if (IS_ERR(frandom_device)) {
		pr_warn("frandom: Failed to create frandom device\n");
		goto error3;
	}

	cdev_init(&erandom_cdev, &frandom_fops);
	erandom_cdev.owner = THIS_MODULE;
	result = cdev_add(&erandom_cdev, erandom_devt, 1);
	if (result) {
		pr_warn("frandom: Failed to add cdev for /dev/erandom\n");
		goto error4;
	}

	erandom_device = device_create(frandom_class, NULL, erandom_devt,
		NULL, "erandom");

	if (IS_ERR(erandom_device)) {
		pr_warn("frandom: Failed to create erandom device\n");
		goto error5;
	}
	return 0; /* succeed */

error5:
	cdev_del(&erandom_cdev);
error4:
	device_destroy(frandom_class, frandom_devt);
error3:
	cdev_del(&frandom_cdev);
error2:
	unregister_chrdev_region(frandom_devt, NR_FRANDOM_DEVS);
error1:
	class_destroy(frandom_class);
error0:
	kfree(erandom_state->buf);
	kfree(erandom_state);

	return result;
}
STATIC int
linvfs_mknod(
	struct inode	*dir,
	struct dentry	*dentry,
	int		mode,
	dev_t		rdev)
{
	struct inode	*ip;
	vattr_t		va;
	vnode_t		*vp = NULL, *dvp = LINVFS_GET_VP(dir);
	xfs_acl_t	*default_acl = NULL;
	attrexists_t	test_default_acl = _ACL_DEFAULT_EXISTS;
	int		error;

	/*
	 * Irix uses Missed'em'V split, but doesn't want to see
	 * the upper 5 bits of (14bit) major.
	 */
	if (!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff)
		return -EINVAL;

	if (test_default_acl && test_default_acl(dvp)) {
		if (!_ACL_ALLOC(default_acl))
			return -ENOMEM;
		if (!_ACL_GET_DEFAULT(dvp, default_acl)) {
			_ACL_FREE(default_acl);
			default_acl = NULL;
		}
	}

	if (IS_POSIXACL(dir) && !default_acl && has_fs_struct(current))
		mode &= ~current->fs->umask;

	memset(&va, 0, sizeof(va));
	va.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
	va.va_mode = mode;

	switch (mode & S_IFMT) {
	case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK:
		va.va_rdev = sysv_encode_dev(rdev);
		va.va_mask |= XFS_AT_RDEV;
		/*FALLTHROUGH*/
	case S_IFREG:
		VOP_CREATE(dvp, dentry, &va, &vp, NULL, error);
		break;
	case S_IFDIR:
		VOP_MKDIR(dvp, dentry, &va, &vp, NULL, error);
		break;
	default:
		error = EINVAL;
		break;
	}

	if (!error)
	{
		error = linvfs_init_security(vp, dir);
		if (error)
			cleanup_inode(dvp, vp, dentry, mode);
	}

	if (default_acl) {
		if (!error) {
			error = _ACL_INHERIT(vp, &va, default_acl);
			if (!error) 
				VMODIFY(vp);
			else
				cleanup_inode(dvp, vp, dentry, mode);
		}
		_ACL_FREE(default_acl);
	}

	if (!error) {
		ASSERT(vp);
		ip = LINVFS_GET_IP(vp);

		if (S_ISCHR(mode) || S_ISBLK(mode))
			ip->i_rdev = rdev;
		else if (S_ISDIR(mode))
			validate_fields(ip);
		d_instantiate(dentry, ip);
		validate_fields(dir);
	}
	return -error;
}
Exemplo n.º 23
0
/**
 * software_resume - Resume from a saved hibernation image.
 *
 * This routine is called as a late initcall, when all devices have been
 * discovered and initialized already.
 *
 * The image reading code is called to see if there is a hibernation image
 * available for reading.  If that is the case, devices are quiesced and the
 * contents of memory is restored from the saved image.
 *
 * If this is successful, control reappears in the restored target kernel in
 * hibernation_snaphot() which returns to hibernate().  Otherwise, the routine
 * attempts to recover gracefully and make the kernel return to the normal mode
 * of operation.
 */
static int software_resume(void)
{
	int error;
	unsigned int flags;

	/*
	 * If the user said "noresume".. bail out early.
	 */
	if (noresume || !capable(CAP_COMPROMISE_KERNEL))
		return 0;

	/*
	 * name_to_dev_t() below takes a sysfs buffer mutex when sysfs
	 * is configured into the kernel. Since the regular hibernate
	 * trigger path is via sysfs which takes a buffer mutex before
	 * calling hibernate functions (which take pm_mutex) this can
	 * cause lockdep to complain about a possible ABBA deadlock
	 * which cannot happen since we're in the boot code here and
	 * sysfs can't be invoked yet. Therefore, we use a subclass
	 * here to avoid lockdep complaining.
	 */
	mutex_lock_nested(&pm_mutex, SINGLE_DEPTH_NESTING);

	if (swsusp_resume_device)
		goto Check_image;

	if (!strlen(resume_file)) {
		error = -ENOENT;
		goto Unlock;
	}

	pr_debug("PM: Checking hibernation image partition %s\n", resume_file);

	if (resume_delay) {
		printk(KERN_INFO "Waiting %dsec before reading resume device...\n",
			resume_delay);
		ssleep(resume_delay);
	}

	/* Check if the device is there */
	swsusp_resume_device = name_to_dev_t(resume_file);

	/*
	 * name_to_dev_t is ineffective to verify parition if resume_file is in
	 * integer format. (e.g. major:minor)
	 */
	if (isdigit(resume_file[0]) && resume_wait) {
		int partno;
		while (!get_gendisk(swsusp_resume_device, &partno))
			msleep(10);
	}

	if (!swsusp_resume_device) {
		/*
		 * Some device discovery might still be in progress; we need
		 * to wait for this to finish.
		 */
		wait_for_device_probe();

		if (resume_wait) {
			while ((swsusp_resume_device = name_to_dev_t(resume_file)) == 0)
				msleep(10);
			async_synchronize_full();
		}

		swsusp_resume_device = name_to_dev_t(resume_file);
		if (!swsusp_resume_device) {
			error = -ENODEV;
			goto Unlock;
		}
	}

 Check_image:
	pr_debug("PM: Hibernation image partition %d:%d present\n",
		MAJOR(swsusp_resume_device), MINOR(swsusp_resume_device));

	pr_debug("PM: Looking for hibernation image.\n");
	error = swsusp_check();
	if (error)
		goto Unlock;

	/* The snapshot device should not be opened while we're running */
	if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
		error = -EBUSY;
		swsusp_close(FMODE_READ);
		goto Unlock;
	}

	pm_prepare_console();
	error = pm_notifier_call_chain(PM_RESTORE_PREPARE);
	if (error)
		goto close_finish;

	error = create_basic_memory_bitmaps();
	if (error)
		goto close_finish;

	pr_debug("PM: Preparing processes for restore.\n");
	error = freeze_processes();
	if (error) {
		swsusp_close(FMODE_READ);
		goto Done;
	}

	pr_debug("PM: Loading hibernation image.\n");

	error = swsusp_read(&flags);
	swsusp_close(FMODE_READ);
	if (!error)
		hibernation_restore(flags & SF_PLATFORM_MODE);

	printk(KERN_ERR "PM: Failed to load hibernation image, recovering.\n");
	swsusp_free();
	thaw_processes();
 Done:
	free_basic_memory_bitmaps();
 Finish:
	pm_notifier_call_chain(PM_POST_RESTORE);
	pm_restore_console();
	atomic_inc(&snapshot_device_available);
	/* For success case, the suspend path will release the lock */
 Unlock:
	mutex_unlock(&pm_mutex);
	pr_debug("PM: Hibernation image not present or could not be loaded.\n");
	return error;
close_finish:
	swsusp_close(FMODE_READ);
	goto Finish;
}
Exemplo n.º 24
0
int
fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, struct svc_fh *ref_fh)
{
	/* ref_fh is a reference file handle.
	 * if it is non-null and for the same filesystem, then we should compose
	 * a filehandle which is of the same version, where possible.
	 * Currently, that means that if ref_fh->fh_handle.fh_version == 0xca
	 * Then create a 32byte filehandle using nfs_fhbase_old
	 *
	 */

	u8 ref_fh_version = 0;
	u8 ref_fh_fsid_type = 0;
	struct inode * inode = dentry->d_inode;
	struct dentry *parent = dentry->d_parent;
	__u32 *datap;
	dev_t ex_dev = exp->ex_dentry->d_inode->i_sb->s_dev;

	dprintk("nfsd: fh_compose(exp %02x:%02x/%ld %s/%s, ino=%ld)\n",
		MAJOR(ex_dev), MINOR(ex_dev),
		(long) exp->ex_dentry->d_inode->i_ino,
		parent->d_name.name, dentry->d_name.name,
		(inode ? inode->i_ino : 0));

	if (ref_fh && ref_fh->fh_export == exp) {
		ref_fh_version = ref_fh->fh_handle.fh_version;
		if (ref_fh_version == 0xca)
			ref_fh_fsid_type = 0;
		else
			ref_fh_fsid_type = ref_fh->fh_handle.fh_fsid_type;
		if (ref_fh_fsid_type > 3)
			ref_fh_fsid_type = 0;

		/* make sure ref_fh type works for given export */
		if (ref_fh_fsid_type == 1 &&
		    !(exp->ex_flags & NFSEXP_FSID)) {
			/* if we don't have an fsid, we cannot provide one... */
			ref_fh_fsid_type = 0;
		}
	} else if (exp->ex_flags & NFSEXP_FSID)
		ref_fh_fsid_type = 1;

	if (!old_valid_dev(ex_dev) && ref_fh_fsid_type == 0) {
		/* for newer device numbers, we must use a newer fsid format */
		ref_fh_version = 1;
		ref_fh_fsid_type = 3;
	}
	if (old_valid_dev(ex_dev) &&
	    (ref_fh_fsid_type == 2 || ref_fh_fsid_type == 3))
		/* must use type1 for smaller device numbers */
		ref_fh_fsid_type = 0;

	if (ref_fh == fhp)
		fh_put(ref_fh);

	if (fhp->fh_locked || fhp->fh_dentry) {
		printk(KERN_ERR "fh_compose: fh %s/%s not initialized!\n",
			parent->d_name.name, dentry->d_name.name);
	}
	if (fhp->fh_maxsize < NFS_FHSIZE)
		printk(KERN_ERR "fh_compose: called with maxsize %d! %s/%s\n",
		       fhp->fh_maxsize, parent->d_name.name, dentry->d_name.name);

	fhp->fh_dentry = dget(dentry); /* our internal copy */
	fhp->fh_export = exp;
	cache_get(&exp->h);

	if (ref_fh_version == 0xca) {
		/* old style filehandle please */
		memset(&fhp->fh_handle.fh_base, 0, NFS_FHSIZE);
		fhp->fh_handle.fh_size = NFS_FHSIZE;
		fhp->fh_handle.ofh_dcookie = 0xfeebbaca;
		fhp->fh_handle.ofh_dev =  old_encode_dev(ex_dev);
		fhp->fh_handle.ofh_xdev = fhp->fh_handle.ofh_dev;
		fhp->fh_handle.ofh_xino = ino_t_to_u32(exp->ex_dentry->d_inode->i_ino);
		fhp->fh_handle.ofh_dirino = ino_t_to_u32(parent_ino(dentry));
		if (inode)
			_fh_update_old(dentry, exp, &fhp->fh_handle);
	} else {
		int len;
		fhp->fh_handle.fh_version = 1;
		fhp->fh_handle.fh_auth_type = 0;
		datap = fhp->fh_handle.fh_auth+0;
		fhp->fh_handle.fh_fsid_type = ref_fh_fsid_type;
		switch (ref_fh_fsid_type) {
			case 0:
				/*
				 * fsid_type 0:
				 * 2byte major, 2byte minor, 4byte inode
				 */
				mk_fsid_v0(datap, ex_dev,
					exp->ex_dentry->d_inode->i_ino);
				break;
			case 1:
				/* fsid_type 1 == 4 bytes filesystem id */
				mk_fsid_v1(datap, exp->ex_fsid);
				break;
			case 2:
				/*
				 * fsid_type 2:
				 * 4byte major, 4byte minor, 4byte inode
				 */
				mk_fsid_v2(datap, ex_dev,
					exp->ex_dentry->d_inode->i_ino);
				break;
			case 3:
				/*
				 * fsid_type 3:
				 * 4byte devicenumber, 4byte inode
				 */
				mk_fsid_v3(datap, ex_dev,
					exp->ex_dentry->d_inode->i_ino);
				break;
		}
		len = key_len(ref_fh_fsid_type);
		datap += len/4;
		fhp->fh_handle.fh_size = 4 + len;

		if (inode) {
			int size = (fhp->fh_maxsize-len-4)/4;
			fhp->fh_handle.fh_fileid_type =
				_fh_update(dentry, exp, datap, &size);
			fhp->fh_handle.fh_size += size*4;
		}
		if (fhp->fh_handle.fh_fileid_type == 255)
			return nfserr_opnotsupp;
	}

	nfsd_nr_verified++;
	return 0;
}
Exemplo n.º 25
0
/* Write out a tar header for the specified file/directory/whatever */
static int
writeTarHeader(struct TarBallInfo *tbInfo, const char *header_name,
		const char *real_name, struct stat *statbuf)
{
	long chksum=0;
	struct TarHeader header;
	const unsigned char *cp = (const unsigned char *) &header;
	ssize_t size = sizeof(struct TarHeader);
		
	memset( &header, 0, size);

	strncpy(header.name, header_name, sizeof(header.name)); 

	putOctal(header.mode, sizeof(header.mode), statbuf->st_mode);
	putOctal(header.uid, sizeof(header.uid), statbuf->st_uid);
	putOctal(header.gid, sizeof(header.gid), statbuf->st_gid);
	putOctal(header.size, sizeof(header.size), 0); /* Regular file size is handled later */
	putOctal(header.mtime, sizeof(header.mtime), statbuf->st_mtime);
	strncpy(header.magic, TAR_MAGIC TAR_VERSION, 
			TAR_MAGIC_LEN + TAR_VERSION_LEN );

	/* Enter the user and group names (default to root if it fails) */
	my_getpwuid(header.uname, statbuf->st_uid);
	if (! *header.uname)
		strcpy(header.uname, "root");
	my_getgrgid(header.gname, statbuf->st_gid);
	if (! *header.uname)
		strcpy(header.uname, "root");

	if (tbInfo->hlInfo) {
		/* This is a hard link */
		header.typeflag = LNKTYPE;
		strncpy(header.linkname, tbInfo->hlInfo->name, sizeof(header.linkname));
	} else if (S_ISLNK(statbuf->st_mode)) {
		char *lpath = xreadlink(real_name);
		if (!lpath) /* Already printed err msg inside xreadlink() */
			return ( FALSE);
		header.typeflag  = SYMTYPE;
		strncpy(header.linkname, lpath, sizeof(header.linkname)); 
		free(lpath);
	} else if (S_ISDIR(statbuf->st_mode)) {
		header.typeflag  = DIRTYPE;
		strncat(header.name, "/", sizeof(header.name)); 
	} else if (S_ISCHR(statbuf->st_mode)) {
		header.typeflag  = CHRTYPE;
		putOctal(header.devmajor, sizeof(header.devmajor), MAJOR(statbuf->st_rdev));
		putOctal(header.devminor, sizeof(header.devminor), MINOR(statbuf->st_rdev));
	} else if (S_ISBLK(statbuf->st_mode)) {
		header.typeflag  = BLKTYPE;
		putOctal(header.devmajor, sizeof(header.devmajor), MAJOR(statbuf->st_rdev));
		putOctal(header.devminor, sizeof(header.devminor), MINOR(statbuf->st_rdev));
	} else if (S_ISFIFO(statbuf->st_mode)) {
		header.typeflag  = FIFOTYPE;
	} else if (S_ISREG(statbuf->st_mode)) {
		header.typeflag  = REGTYPE;
		putOctal(header.size, sizeof(header.size), statbuf->st_size);
	} else {
		error_msg("%s: Unknown file type", real_name);
		return ( FALSE);
	}

	/* Calculate and store the checksum (i.e., the sum of all of the bytes of
	 * the header).  The checksum field must be filled with blanks for the
	 * calculation.  The checksum field is formatted differently from the
	 * other fields: it has [6] digits, a null, then a space -- rather than
	 * digits, followed by a null like the other fields... */
	memset(header.chksum, ' ', sizeof(header.chksum));
	cp = (const unsigned char *) &header;
	while (size-- > 0)
		chksum += *cp++;
	putOctal(header.chksum, 7, chksum);
	
	/* Now write the header out to disk */
	if ((size=full_write(tbInfo->tarFd, (char*)&header, sizeof(struct TarHeader))) < 0) {
		error_msg(io_error, real_name, strerror(errno)); 
		return ( FALSE);
	}
	/* Pad the header up to the tar block size */
	for (; size<TAR_BLOCK_SIZE; size++) {
		write(tbInfo->tarFd, "\0", 1);
	}
	/* Now do the verbose thing (or not) */
	if (tbInfo->verboseFlag==TRUE) {
		FILE *vbFd = stdout;
		if (tbInfo->tarFd == fileno(stdout))	// If the archive goes to stdout, verbose to stderr
			vbFd = stderr;
		fprintf(vbFd, "%s\n", header.name);
	}

	return ( TRUE);
}
Exemplo n.º 26
0
static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
                        const struct gfs2_inum_host *inum, unsigned int mode,
                        unsigned int uid, unsigned int gid,
                        const u64 *generation, dev_t dev, const char *symname,
                        unsigned size, struct buffer_head **bhp)
{
    struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
    struct gfs2_dinode *di;
    struct buffer_head *dibh;
    struct timespec tv = CURRENT_TIME;

    dibh = gfs2_meta_new(gl, inum->no_addr);
    gfs2_trans_add_bh(gl, dibh, 1);
    gfs2_metatype_set(dibh, GFS2_METATYPE_DI, GFS2_FORMAT_DI);
    gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
    di = (struct gfs2_dinode *)dibh->b_data;

    di->di_num.no_formal_ino = cpu_to_be64(inum->no_formal_ino);
    di->di_num.no_addr = cpu_to_be64(inum->no_addr);
    di->di_mode = cpu_to_be32(mode);
    di->di_uid = cpu_to_be32(uid);
    di->di_gid = cpu_to_be32(gid);
    di->di_nlink = 0;
    di->di_size = cpu_to_be64(size);
    di->di_blocks = cpu_to_be64(1);
    di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec);
    di->di_major = cpu_to_be32(MAJOR(dev));
    di->di_minor = cpu_to_be32(MINOR(dev));
    di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr);
    di->di_generation = cpu_to_be64(*generation);
    di->di_flags = 0;
    di->__pad1 = 0;
    di->di_payload_format = cpu_to_be32(S_ISDIR(mode) ? GFS2_FORMAT_DE : 0);
    di->di_height = 0;
    di->__pad2 = 0;
    di->__pad3 = 0;
    di->di_depth = 0;
    di->di_entries = 0;
    memset(&di->__pad4, 0, sizeof(di->__pad4));
    di->di_eattr = 0;
    di->di_atime_nsec = cpu_to_be32(tv.tv_nsec);
    di->di_mtime_nsec = cpu_to_be32(tv.tv_nsec);
    di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec);
    memset(&di->di_reserved, 0, sizeof(di->di_reserved));

    switch(mode & S_IFMT) {
    case S_IFREG:
        if ((dip->i_diskflags & GFS2_DIF_INHERIT_JDATA) ||
                gfs2_tune_get(sdp, gt_new_files_jdata))
            di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA);
        break;
    case S_IFDIR:
        di->di_flags |= cpu_to_be32(dip->i_diskflags &
                                    GFS2_DIF_INHERIT_JDATA);
        di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA);
        di->di_size = cpu_to_be64(sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode));
        di->di_entries = cpu_to_be32(2);
        gfs2_init_dir(dibh, dip);
        break;
    case S_IFLNK:
        memcpy(dibh->b_data + sizeof(struct gfs2_dinode), symname, size);
        break;
    }

    set_buffer_uptodate(dibh);

    *bhp = dibh;
}
Exemplo n.º 27
0
/** Initialize the module - Register the character device	*/
static int qres_init_module(void) {

  qos_rv rv;
  kal_irq_state flags;

  //kal_spin_lock_irqsave(rres_get_spinlock(), &flags);

  qres_init();
  qos_log_debug("Initing QSUP");
  if ((rv = qsup_init_ks()) != QOS_OK) {
    qos_log_crit("qsup_init_ks() failed: %s", qos_strerror(rv));
    qres_cleanup();
    goto err;
  }

//  start_timer_thread();

#ifdef QSUP_DYNAMIC_RECLAIM
  write_lock(&hook_lock);
  old_block_hook = block_hook;
  old_unblock_hook = unblock_hook;
  old_stop_hook = stop_hook;
  old_continue_hook = continue_hook;
  block_hook = qres_block_hook;
  unblock_hook = qres_unblock_hook;
  stop_hook = qres_stop_hook;
  continue_hook = qres_continue_hook;
  write_unlock(&hook_lock);
#endif

  qos_log_debug("qres module initialization finished");

  //kal_spin_unlock_irqrestore(rres_get_spinlock(), &flags);

  /* Device registration should be done when kernel module is
   * already able to accept ioctl requests. Furthermore, spinlocks
   * cannot be held because it might sleep.
   */
  if (qos_dev_register(&qres_dev_info, QRES_DEV_NAME, QRES_MAJOR_NUM, &Fops) != QOS_OK) {
    qos_log_crit("Registration of device %s failed", QRES_DEV_NAME);
  } else {
    qos_log_info("Registered QRES device with major device number %d.", MAJOR(qres_dev_info.dev_num));
    qos_log_info("If you want to talk to the device driver,");
    qos_log_info("you'll have to create a device file. ");
    qos_log_info("We suggest you use:");
    qos_log_info("mknod %s c %d 0", QRES_DEV_NAME, MAJOR(qres_dev_info.dev_num));
  }

  qsup_dev_register();

  /** ProcFS-related functions may sleep, so no spinlock should be held **/
  if (qres_proc_register())
    qos_log_err("Failed to register qres module in /proc filesystem");

  return 0;

 err:

  //kal_spin_unlock_irqrestore(rres_get_spinlock(), &flags);
  return -1;
}
Exemplo n.º 28
0
int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
{
	sector_t sector_size = bdev_logical_block_size(bdev) / 512;
	Sector sect;
	unsigned char *data;
	struct partition *p;
	struct fat_boot_sector *fb;
	int slot;

	data = read_dev_sector(bdev, 0, &sect);
	if (!data)
		return -1;
	if (!msdos_magic_present(data + 510)) {
		put_dev_sector(sect);
		return 0;
	}

	if (aix_magic_present(data, bdev)) {
		put_dev_sector(sect);
		printk( " [AIX]");
		return 0;
	}

#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 
    if(179 == MAJOR(bdev->bd_dev))
    {
	    printk("\n%s..%d... ==== Begin to parse sdcard-partition.  ====xbw[mmc0]===\n",__FUNCTION__, __LINE__);
	}
#endif

	/*
	 * Now that the 55aa signature is present, this is probably
	 * either the boot sector of a FAT filesystem or a DOS-type
	 * partition table. Reject this in case the boot indicator
	 * is not 0 or 0x80.
	 */
	p = (struct partition *) (data + 0x1be);
	for (slot = 1; slot <= 4; slot++, p++) {
		if (p->boot_ind != 0 && p->boot_ind != 0x80) {
#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 
		    if(179 == MAJOR(bdev->bd_dev))
		    {
			    printk("%s..%d... ==== The sdcard has not MBR.  ====xbw[mmc0]===\n",__FUNCTION__, __LINE__);
			}
#endif
			/*
			 * Even without a valid boot inidicator value
			 * its still possible this is valid FAT filesystem
			 * without a partition table.
			 */
			fb = (struct fat_boot_sector *) data;
			if (slot == 1 && fb->reserved && fb->fats
				&& fat_valid_media(fb->media)) {
				printk("\n");
				put_dev_sector(sect);
#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 
				if(179 == MAJOR(bdev->bd_dev))
				{
				    printk("%s..%d... ==== The DBR(slot=%d) is valid. ====xbw[mmc0]===\n",__FUNCTION__, __LINE__, slot);
				}
#endif
				return 1;
			} else {
				put_dev_sector(sect);
#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 
				if(179 == MAJOR(bdev->bd_dev))
				{
				    printk("%s..%d... ==== The DBR is invalid. ====xbw[mmc0]===\n",__FUNCTION__, __LINE__);
				}
#endif
				return 0;
			}
		}
	}

#ifdef CONFIG_EFI_PARTITION
	p = (struct partition *) (data + 0x1be);
	for (slot = 1 ; slot <= 4 ; slot++, p++) {
		/* If this is an EFI GPT disk, msdos should ignore it. */
		if (SYS_IND(p) == EFI_PMBR_OSTYPE_EFI_GPT) {
			put_dev_sector(sect);
			return 0;
		}
	}
#endif
	p = (struct partition *) (data + 0x1be);

	/*
	 * Look for partitions in two passes:
	 * First find the primary and DOS-type extended partitions.
	 * On the second pass look inside *BSD, Unixware and Solaris partitions.
	 */
#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 
    if(179 == MAJOR(bdev->bd_dev))
    {
        printk("%s..%d... ==== The sdcard has MBR. ====xbw[mmc0]===\n", __FUNCTION__, __LINE__);
    }
#endif    
	state->next = 5;
	for (slot = 1 ; slot <= 4 ; slot++, p++) {
		sector_t start = start_sect(p)*sector_size;
		sector_t size = nr_sects(p)*sector_size;
		if (!size)
			continue;
#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 
	    if(179 == MAJOR(bdev->bd_dev))
	    {
		    printk("%s..%d... ==== partition-%d, size=%luKB  ====xbw[mmc0]===\n",\
		        __FUNCTION__, __LINE__, slot, size/2);
		}
#endif	
		if (is_extended_partition(p)) {
			/*
			 * prevent someone doing mkfs or mkswap on an
			 * extended partition, but leave room for LILO
			 * FIXME: this uses one logical sector for > 512b
			 * sector, although it may not be enough/proper.
			 */
			sector_t n = 2;
			n = min(size, max(sector_size, n));
#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 			
            if(179 == MAJOR(bdev->bd_dev))
            {
			    printk("%s...%d... ==== extend partition-%d....====xbw[mmc0]===\n",__FUNCTION__, __LINE__, slot);
			}
#endif			
			put_partition(state, slot, start, n);

			printk(" <");
			parse_extended(state, bdev, start, size);
			printk(" >");
			continue;
		}
#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) 
		if(179 == MAJOR(bdev->bd_dev))
		{
		    printk("%s..%d... ==== main partition-%d....====xbw[mmc0]===\n",__FUNCTION__, __LINE__, slot);
		}
#endif		
		put_partition(state, slot, start, size);
		if (SYS_IND(p) == LINUX_RAID_PARTITION)
			state->parts[slot].flags = 1;
		if (SYS_IND(p) == DM6_PARTITION)
			printk("[DM]");
		if (SYS_IND(p) == EZD_PARTITION)
			printk("[EZD]");
	}

	printk("\n");

	/* second pass - output for each on a separate line */
	p = (struct partition *) (0x1be + data);
	for (slot = 1 ; slot <= 4 ; slot++, p++) {
		unsigned char id = SYS_IND(p);
		int n;

		if (!nr_sects(p))
			continue;

		for (n = 0; subtypes[n].parse && id != subtypes[n].id; n++)
			;

		if (!subtypes[n].parse)
			continue;
		subtypes[n].parse(state, bdev, start_sect(p)*sector_size,
						nr_sects(p)*sector_size, slot);
	}
	put_dev_sector(sect);
	return 1;
}
Exemplo n.º 29
0
int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,
               dev_t device_number)
{
    int rc = -EPERM;
    unsigned int xid;
    int create_options = CREATE_NOT_DIR | CREATE_OPTION_SPECIAL;
    struct cifs_sb_info *cifs_sb;
    struct tcon_link *tlink;
    struct cifs_tcon *pTcon;
    struct cifs_io_parms io_parms;
    char *full_path = NULL;
    struct inode *newinode = NULL;
    int oplock = 0;
    u16 fileHandle;
    FILE_ALL_INFO *buf = NULL;
    unsigned int bytes_written;
    struct win_dev *pdev;

    if (!old_valid_dev(device_number))
        return -EINVAL;

    cifs_sb = CIFS_SB(inode->i_sb);
    tlink = cifs_sb_tlink(cifs_sb);
    if (IS_ERR(tlink))
        return PTR_ERR(tlink);

    pTcon = tlink_tcon(tlink);

    xid = get_xid();

    full_path = build_path_from_dentry(direntry);
    if (full_path == NULL) {
        rc = -ENOMEM;
        goto mknod_out;
    }

    if (pTcon->unix_ext) {
        struct cifs_unix_set_info_args args = {
            .mode	= mode & ~current_umask(),
            .ctime	= NO_CHANGE_64,
            .atime	= NO_CHANGE_64,
            .mtime	= NO_CHANGE_64,
            .device	= device_number,
        };
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
            args.uid = current_fsuid();
            args.gid = current_fsgid();
        } else {
            args.uid = INVALID_UID; /* no change */
            args.gid = INVALID_GID; /* no change */
        }
        rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args,
                                    cifs_sb->local_nls,
                                    cifs_sb->mnt_cifs_flags &
                                    CIFS_MOUNT_MAP_SPECIAL_CHR);
        if (rc)
            goto mknod_out;

        rc = cifs_get_inode_info_unix(&newinode, full_path,
                                      inode->i_sb, xid);

        if (rc == 0)
            d_instantiate(direntry, newinode);
        goto mknod_out;
    }

    if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL))
        goto mknod_out;


    cifs_dbg(FYI, "sfu compat create special file\n");

    buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
    if (buf == NULL) {
        kfree(full_path);
        rc = -ENOMEM;
        free_xid(xid);
        return rc;
    }

    if (backup_cred(cifs_sb))
        create_options |= CREATE_OPEN_BACKUP_INTENT;

    rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_CREATE,
                     GENERIC_WRITE, create_options,
                     &fileHandle, &oplock, buf, cifs_sb->local_nls,
                     cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
    if (rc)
        goto mknod_out;

    /* BB Do not bother to decode buf since no local inode yet to put
     * timestamps in, but we can reuse it safely */

    pdev = (struct win_dev *)buf;
    io_parms.netfid = fileHandle;
    io_parms.pid = current->tgid;
    io_parms.tcon = pTcon;
    io_parms.offset = 0;
    io_parms.length = sizeof(struct win_dev);
    if (S_ISCHR(mode)) {
        memcpy(pdev->type, "IntxCHR", 8);
        pdev->major =
            cpu_to_le64(MAJOR(device_number));
        pdev->minor =
            cpu_to_le64(MINOR(device_number));
        rc = CIFSSMBWrite(xid, &io_parms,
                          &bytes_written, (char *)pdev,
                          NULL, 0);
    } else if (S_ISBLK(mode)) {
        memcpy(pdev->type, "IntxBLK", 8);
        pdev->major =
            cpu_to_le64(MAJOR(device_number));
        pdev->minor =
            cpu_to_le64(MINOR(device_number));
        rc = CIFSSMBWrite(xid, &io_parms,
                          &bytes_written, (char *)pdev,
                          NULL, 0);
    } /* else if (S_ISFIFO) */
    CIFSSMBClose(xid, pTcon, fileHandle);
    d_drop(direntry);

    /* FIXME: add code here to set EAs */

mknod_out:
    kfree(full_path);
    kfree(buf);
    free_xid(xid);
    cifs_put_tlink(tlink);
    return rc;
}
Exemplo n.º 30
0
/*模块加载方法*/
static int __init hello_init(void){
	int err = -1;
	dev_t dev = 0;
	struct device* temp = NULL;

	printk(KERN_ALERT"Initializing hello device.\n");

	/*动态分配主设备和从设备号*/
	err = alloc_chrdev_region(&dev, 0, 1, HELLO_DEVICE_NODE_NAME);
	if(err < 0) {
		printk(KERN_ALERT"Failed to alloc char dev region.\n");
		goto fail;
	}

	hello_major = MAJOR(dev);
	hello_minor = MINOR(dev);

	/*分配helo设备结构体变量*/
	hello_dev = kmalloc(sizeof(struct hello_android_dev), GFP_KERNEL);
	if(!hello_dev) {
		err = -ENOMEM;
		printk(KERN_ALERT"Failed to alloc hello_dev.\n");
		goto unregister;
	}

	/*初始化设备*/
	err = __hello_setup_dev(hello_dev);
	if(err) {
		printk(KERN_ALERT"Failed to setup dev: %d.\n", err);
		goto cleanup;
	}

	/*在/sys/class/目录下创建设备类别目录hello*/
	hello_class = class_create(THIS_MODULE, HELLO_DEVICE_CLASS_NAME);
	if(IS_ERR(hello_class)) {
		err = PTR_ERR(hello_class);
		printk(KERN_ALERT"Failed to create hello class.\n");
		goto destroy_cdev;
	}

	/*在/dev/目录和/sys/class/hello目录下分别创建设备文件hello*/
	temp = device_create(hello_class, NULL, dev, "%s", HELLO_DEVICE_FILE_NAME);
	if(IS_ERR(temp)) {
		err = PTR_ERR(temp);
		printk(KERN_ALERT"Failed to create hello device.");
		goto destroy_class;
	}

	/*在/sys/class/hello/hello目录下创建属性文件val*/
	err = device_create_file(temp, &dev_attr_val);
	if(err < 0) {
		printk(KERN_ALERT"Failed to create attribute val.");
		goto destroy_device;
	}

	dev_set_drvdata(temp, hello_dev);

	/*创建/proc/hello文件*/
	/*hello_create_proc();*/

	printk(KERN_ALERT"Succedded to initialize hello device.\n");
	return 0;

destroy_device:
	device_destroy(hello_class, dev);

destroy_class:
	class_destroy(hello_class);

destroy_cdev:
	cdev_del(&(hello_dev->dev));

cleanup:
	kfree(hello_dev);

unregister:
	unregister_chrdev_region(MKDEV(hello_major, hello_minor), 1);

fail:
	return err;
}