long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) { struct open_flags op; int lookup = build_open_flags(flags, mode, &op); char *tmp = getname(filename); int fd = PTR_ERR(tmp); if (!IS_ERR(tmp)) { fd = get_unused_fd_flags(flags); if (fd >= 0) { struct file *f = do_filp_open(dfd, tmp, &op, lookup); if (IS_ERR(f)) { put_unused_fd(fd); fd = PTR_ERR(f); } else { fsnotify_open(f); fd_install(fd, f); pre_allocate(f); } } putname(tmp); } return fd; }
/* * sys_execve() executes a new program. */ asmlinkage int sys_execve(struct pt_regs regs) { int error; char * filename; filename = getname((char __user *) regs.ebx); error = PTR_ERR(filename); if (IS_ERR(filename)) goto out; error = do_execve(filename, (char __user * __user *) regs.ecx, (char __user * __user *) regs.edx, ®s); if (error == 0) { task_lock(current); current->ptrace &= ~PT_DTRACE; task_unlock(current); /* Make sure we don't return using sysenter.. */ set_thread_flag(TIF_IRET); } putname(filename); out: return error; }
static int sunos_nfs_mount(char *dir_name, int linux_flags, void __user *data) { int server_fd, err; char *the_name, *mount_page; struct nfs_mount_data linux_nfs_mount; struct sunos_nfs_mount_args sunos_mount; /* Ok, here comes the fun part: Linux's nfs mount needs a * socket connection to the server, but SunOS mount does not * require this, so we use the information on the destination * address to create a socket and bind it to a reserved * port on this system */ if (copy_from_user(&sunos_mount, data, sizeof(sunos_mount))) return -EFAULT; server_fd = sys_socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (server_fd < 0) return -ENXIO; if (copy_from_user(&linux_nfs_mount.addr,sunos_mount.addr, sizeof(*sunos_mount.addr)) || copy_from_user(&linux_nfs_mount.root,sunos_mount.fh, sizeof(*sunos_mount.fh))) { sys_close (server_fd); return -EFAULT; } if (!sunos_nfs_get_server_fd (server_fd, &linux_nfs_mount.addr)) { sys_close (server_fd); return -ENXIO; } /* Now, bind it to a locally reserved port */ linux_nfs_mount.version = NFS_MOUNT_VERSION; linux_nfs_mount.flags = sunos_mount.flags; linux_nfs_mount.fd = server_fd; linux_nfs_mount.rsize = get_default (sunos_mount.rsize, 8192); linux_nfs_mount.wsize = get_default (sunos_mount.wsize, 8192); linux_nfs_mount.timeo = get_default (sunos_mount.timeo, 10); linux_nfs_mount.retrans = sunos_mount.retrans; linux_nfs_mount.acregmin = sunos_mount.acregmin; linux_nfs_mount.acregmax = sunos_mount.acregmax; linux_nfs_mount.acdirmin = sunos_mount.acdirmin; linux_nfs_mount.acdirmax = sunos_mount.acdirmax; the_name = getname(sunos_mount.hostname); if (IS_ERR(the_name)) return PTR_ERR(the_name); strlcpy(linux_nfs_mount.hostname, the_name, sizeof(linux_nfs_mount.hostname)); putname (the_name); mount_page = (char *) get_zeroed_page(GFP_KERNEL); if (!mount_page) return -ENOMEM; memcpy(mount_page, &linux_nfs_mount, sizeof(linux_nfs_mount)); err = do_mount("", dir_name, "nfs", linux_flags, mount_page); free_page((unsigned long) mount_page); return err; }
static void comwork(FILE *fd, Lextok *now, int m) { Lextok *v; int i, j; if (!now) { fprintf(fd, "0"); return; } switch (now->ntyp) { case CONST: sr_mesg(fd, now->val, now->ismtyp); break; case '!': Cat3("!(", now->lft, ")"); break; case UMIN: Cat3("-(", now->lft, ")"); break; case '~': Cat3("~(", now->lft, ")"); break; case '/': Cat1("/"); break; case '*': Cat1("*"); break; case '-': Cat1("-"); break; case '+': Cat1("+"); break; case '%': Cat1("%%"); break; case '&': Cat1("&"); break; case '^': Cat1("^"); break; case '|': Cat1("|"); break; case LE: Cat1("<="); break; case GE: Cat1(">="); break; case GT: Cat1(">"); break; case LT: Cat1("<"); break; case NE: Cat1("!="); break; case EQ: if (ltl_mode && now->lft->ntyp == 'p' && now->rgt->ntyp == 'q') /* remote ref */ { Lextok *p = now->lft->lft; fprintf(fd, "("); fprintf(fd, "%s", p->sym->name); if (p->lft) { fprintf(fd, "["); putstmnt(fd, p->lft, 0); /* pid */ fprintf(fd, "]"); } fprintf(fd, "@"); fprintf(fd, "%s", now->rgt->sym->name); fprintf(fd, ")"); break; } Cat1("=="); break; case OR: Cat1("||"); break; case AND: Cat1("&&"); break; case LSHIFT: Cat1("<<"); break; case RSHIFT: Cat1(">>"); break; case RUN: fprintf(fd, "run %s(", now->sym->name); for (v = now->lft; v; v = v->rgt) if (v == now->lft) { comwork(fd, v->lft, m); } else { Cat2(",", v->lft); } fprintf(fd, ")"); break; case LEN: putname(fd, "len(", now->lft, m, ")"); break; case FULL: putname(fd, "full(", now->lft, m, ")"); break; case EMPTY: putname(fd, "empty(", now->lft, m, ")"); break; case NFULL: putname(fd, "nfull(", now->lft, m, ")"); break; case NEMPTY: putname(fd, "nempty(", now->lft, m, ")"); break; case 's': putname(fd, "", now->lft, m, now->val?"!!":"!"); for (v = now->rgt, i=0; v; v = v->rgt, i++) { if (v != now->rgt) fprintf(fd,","); if (!symbolic(fd, v->lft)) comwork(fd,v->lft,m); } break; case 'r': putname(fd, "", now->lft, m, "?"); switch (now->val) { case 0: break; case 1: fprintf(fd, "?"); break; case 2: fprintf(fd, "<"); break; case 3: fprintf(fd, "?<"); break; } for (v = now->rgt, i=0; v; v = v->rgt, i++) { if (v != now->rgt) fprintf(fd,","); if (!symbolic(fd, v->lft)) comwork(fd,v->lft,m); } if (now->val >= 2) fprintf(fd, ">"); break; case 'R': putname(fd, "", now->lft, m, now->val?"??[":"?["); for (v = now->rgt, i=0; v; v = v->rgt, i++) { if (v != now->rgt) fprintf(fd,","); if (!symbolic(fd, v->lft)) comwork(fd,v->lft,m); } fprintf(fd, "]"); break; case ENABLED: Cat3("enabled(", now->lft, ")"); break; case EVAL: Cat3("eval(", now->lft, ")"); break; case NONPROGRESS: fprintf(fd, "np_"); break; case PC_VAL: Cat3("pc_value(", now->lft, ")"); break; case 'c': Cat3("(", now->lft, ")"); break; case '?': if (now->lft) { Cat3("( (", now->lft, ") -> "); } if (now->rgt) { Cat3("(", now->rgt->lft, ") : "); Cat3("(", now->rgt->rgt, ") )"); } break; case ASGN: comwork(fd,now->lft,m); fprintf(fd," = "); comwork(fd,now->rgt,m); break; case PRINT: { char c, buf[512]; strncpy(buf, now->sym->name, 510); for (i = j = 0; i < 510; i++, j++) { c = now->sym->name[i]; buf[j] = c; if (c == '\\') buf[++j] = c; if (c == '\"') buf[j] = '\''; if (c == '\0') break; } if (now->ntyp == PRINT) fprintf(fd, "printf"); else fprintf(fd, "annotate"); fprintf(fd, "(%s", buf); } for (v = now->lft; v; v = v->rgt) { Cat2(",", v->lft); } fprintf(fd, ")"); break; case PRINTM: fprintf(fd, "printm("); comwork(fd, now->lft, m); fprintf(fd, ")"); break; case NAME: putname(fd, "", now, m, ""); break; case 'p': if (ltl_mode) { fprintf(fd, "%s", now->lft->sym->name); /* proctype */ if (now->lft->lft) { fprintf(fd, "["); putstmnt(fd, now->lft->lft, 0); /* pid */ fprintf(fd, "]"); } fprintf(fd, ":"); /* remote varref */ fprintf(fd, "%s", now->sym->name); /* varname */ break; } putremote(fd, now, m); break; case 'q': fprintf(fd, "%s", now->sym->name); break; case C_EXPR: case C_CODE: fprintf(fd, "{%s}", now->sym->name); break; case ASSERT: Cat3("assert(", now->lft, ")"); break; case '.': fprintf(fd, ".(goto)"); break; case GOTO: fprintf(fd, "goto %s", now->sym->name); break; case BREAK: fprintf(fd, "break"); break; case ELSE: fprintf(fd, "else"); break; case '@': fprintf(fd, "-end-"); break; case D_STEP: fprintf(fd, "D_STEP"); break; case ATOMIC: fprintf(fd, "ATOMIC"); break; case NON_ATOMIC: fprintf(fd, "sub-sequence"); break; case IF: fprintf(fd, "IF"); break; case DO: fprintf(fd, "DO"); break; case UNLESS: fprintf(fd, "unless"); break; case TIMEOUT: fprintf(fd, "timeout"); break; default: if (isprint(now->ntyp)) fprintf(fd, "'%c'", now->ntyp); else fprintf(fd, "%d", now->ntyp); break; } }
/* fd_create_virtdevice(): (Part of se_subsystem_api_t template) * * */ static struct se_device *fd_create_virtdevice( struct se_hba *hba, struct se_subsystem_dev *se_dev, void *p) { char *dev_p = NULL; struct se_device *dev; struct se_dev_limits dev_limits; struct queue_limits *limits; struct fd_dev *fd_dev = p; struct fd_host *fd_host = hba->hba_ptr; mm_segment_t old_fs; struct file *file; struct inode *inode = NULL; int dev_flags = 0, flags, ret = -EINVAL; memset(&dev_limits, 0, sizeof(struct se_dev_limits)); old_fs = get_fs(); set_fs(get_ds()); dev_p = getname(fd_dev->fd_dev_name); set_fs(old_fs); if (IS_ERR(dev_p)) { pr_err("getname(%s) failed: %lu\n", fd_dev->fd_dev_name, IS_ERR(dev_p)); ret = PTR_ERR(dev_p); goto fail; } /* * Use O_DSYNC by default instead of O_SYNC to forgo syncing * of pure timestamp updates. */ flags = O_RDWR | O_CREAT | O_LARGEFILE | O_DSYNC; file = filp_open(dev_p, flags, 0600); if (IS_ERR(file)) { pr_err("filp_open(%s) failed\n", dev_p); ret = PTR_ERR(file); goto fail; } if (!file || !file->f_dentry) { pr_err("filp_open(%s) failed\n", dev_p); goto fail; } fd_dev->fd_file = file; /* * If using a block backend with this struct file, we extract * fd_dev->fd_[block,dev]_size from struct block_device. * * Otherwise, we use the passed fd_size= from configfs */ inode = file->f_mapping->host; if (S_ISBLK(inode->i_mode)) { struct request_queue *q; unsigned long long dev_size; /* * Setup the local scope queue_limits from struct request_queue->limits * to pass into transport_add_device_to_core_hba() as struct se_dev_limits. */ q = bdev_get_queue(inode->i_bdev); limits = &dev_limits.limits; limits->logical_block_size = bdev_logical_block_size(inode->i_bdev); limits->max_hw_sectors = queue_max_hw_sectors(q); limits->max_sectors = queue_max_sectors(q); /* * Determine the number of bytes from i_size_read() minus * one (1) logical sector from underlying struct block_device */ fd_dev->fd_block_size = bdev_logical_block_size(inode->i_bdev); dev_size = (i_size_read(file->f_mapping->host) - fd_dev->fd_block_size); pr_debug("FILEIO: Using size: %llu bytes from struct" " block_device blocks: %llu logical_block_size: %d\n", dev_size, div_u64(dev_size, fd_dev->fd_block_size), fd_dev->fd_block_size); } else { if (!(fd_dev->fbd_flags & FBDF_HAS_SIZE)) { pr_err("FILEIO: Missing fd_dev_size=" " parameter, and no backing struct" " block_device\n"); goto fail; } limits = &dev_limits.limits; limits->logical_block_size = FD_BLOCKSIZE; limits->max_hw_sectors = FD_MAX_SECTORS; limits->max_sectors = FD_MAX_SECTORS; fd_dev->fd_block_size = FD_BLOCKSIZE; } dev_limits.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH; dev_limits.queue_depth = FD_DEVICE_QUEUE_DEPTH; dev = transport_add_device_to_core_hba(hba, &fileio_template, se_dev, dev_flags, fd_dev, &dev_limits, "FILEIO", FD_VERSION); if (!dev) goto fail; fd_dev->fd_dev_id = fd_host->fd_host_dev_id_count++; fd_dev->fd_queue_depth = dev->queue_depth; pr_debug("CORE_FILE[%u] - Added TCM FILEIO Device ID: %u at %s," " %llu total bytes\n", fd_host->fd_host_id, fd_dev->fd_dev_id, fd_dev->fd_dev_name, fd_dev->fd_dev_size); putname(dev_p); return dev; fail: if (fd_dev->fd_file) { filp_close(fd_dev->fd_file, NULL); fd_dev->fd_file = NULL; } putname(dev_p); return ERR_PTR(ret); }
void undostmnt(Lextok *now, int m) { Lextok *v; int i, j; if (!now) { fprintf(tb, "0"); return; } lineno = now->ln; Fname = now->fn; switch (now->ntyp) { case CONST: case '!': case UMIN: case '~': case '/': case '*': case '-': case '+': case '%': case LT: case GT: case '&': case '|': case LE: case GE: case NE: case EQ: case OR: case AND: case LSHIFT: case RSHIFT: case TIMEOUT: case LEN: case NAME: case FULL: case EMPTY: case 'R': case NFULL: case NEMPTY: case ENABLED: case '?': case PC_VAL: case '^': case C_EXPR: case GET_P: case NONPROGRESS: putstmnt(tb, now, m); break; case RUN: fprintf(tb, "delproc(0, now._nr_pr-1)"); break; case 's': if (Pid == eventmapnr) break; if (m_loss) fprintf(tb, "if (_m == 2) "); putname(tb, "_m = unsend(", now->lft, m, ")"); break; case 'r': if (Pid == eventmapnr) break; for (v = now->rgt, i=j=0; v; v = v->rgt, i++) if (v->lft->ntyp != CONST && v->lft->ntyp != EVAL) j++; if (j == 0 && now->val >= 2) break; /* poll without side-effect */ { int ii = 0, jj; for (v = now->rgt; v; v = v->rgt) if ((v->lft->ntyp != CONST && v->lft->ntyp != EVAL)) ii++; /* nr of things bupped */ if (now->val == 1) { ii++; jj = multi_oval - ii - 1; fprintf(tb, "XX = trpt->bup.oval"); if (multi_oval > 0) { fprintf(tb, "s[%d]", jj); jj++; } fprintf(tb, ";\n\t\t"); } else { fprintf(tb, "XX = 1;\n\t\t"); jj = multi_oval - ii - 1; } if (now->val < 2) /* not for channel poll */ for (v = now->rgt, i = 0; v; v = v->rgt, i++) { switch(v->lft->ntyp) { case CONST: case EVAL: fprintf(tb, "unrecv"); putname(tb, "(", now->lft, m, ", XX-1, "); fprintf(tb, "%d, ", i); if (v->lft->ntyp == EVAL) undostmnt(v->lft->lft, m); else undostmnt(v->lft, m); fprintf(tb, ", %d);\n\t\t", (i==0)?1:0); break; default: fprintf(tb, "unrecv"); putname(tb, "(", now->lft, m, ", XX-1, "); fprintf(tb, "%d, ", i); if (v->lft->sym && !strcmp(v->lft->sym->name, "_")) { fprintf(tb, "trpt->bup.oval"); if (multi_oval > 0) fprintf(tb, "s[%d]", jj); } else putstmnt(tb, v->lft, m); fprintf(tb, ", %d);\n\t\t", (i==0)?1:0); if (multi_oval > 0) jj++; break; } } jj = multi_oval - ii - 1; if (now->val == 1 && multi_oval > 0) jj++; /* new 3.4.0 */ for (v = now->rgt, i = 0; v; v = v->rgt, i++) { switch(v->lft->ntyp) { case CONST: case EVAL: break; default: if (!v->lft->sym || strcmp(v->lft->sym->name, "_") != 0) { nocast=1; putstmnt(tb,v->lft,m); nocast=0; fprintf(tb, " = trpt->bup.oval"); if (multi_oval > 0) fprintf(tb, "s[%d]", jj); fprintf(tb, ";\n\t\t"); } if (multi_oval > 0) jj++; break; } } multi_oval -= ii; } break; case '@': fprintf(tb, "p_restor(II);\n\t\t"); break; case SET_P: fprintf(tb, "((P0 *)pptr((trpt->o_priority >> 8)))"); fprintf(tb, "->_priority = trpt->o_priority & 255"); break; case ASGN: if (check_track(now) == STRUCT) { break; } nocast=1; putstmnt(tb,now->lft,m); nocast=0; fprintf(tb, " = trpt->bup.oval"); if (multi_oval > 0) { multi_oval--; fprintf(tb, "s[%d]", multi_oval-1); } check_proc(now->rgt, m); break; case 'c': check_proc(now->lft, m); break; case '.': case GOTO: case ELSE: case BREAK: break; case C_CODE: fprintf(tb, "sv_restor();\n"); break; case ASSERT: case PRINT: check_proc(now, m); break; case PRINTM: break; default: printf("spin: bad node type %d (.b)\n", now->ntyp); alldone(1); } }
/* XXXXXXXXXXXXXXXXXXXX */ asmlinkage int sunos_mount(char *type, char *dir, int flags, void *data) { int linux_flags = 0; int ret = -EINVAL; char *dev_fname = 0; char *dir_page, *type_page; if (!capable (CAP_SYS_ADMIN)) return -EPERM; /* We don't handle the integer fs type */ if ((flags & SMNT_NEWTYPE) == 0) goto out; /* Do not allow for those flags we don't support */ if (flags & (SMNT_GRPID|SMNT_NOSUB|SMNT_MULTI|SMNT_SYS5)) goto out; if(flags & SMNT_REMOUNT) linux_flags |= MS_REMOUNT; if(flags & SMNT_RDONLY) linux_flags |= MS_RDONLY; if(flags & SMNT_NOSUID) linux_flags |= MS_NOSUID; dir_page = getname(dir); ret = PTR_ERR(dir_page); if (IS_ERR(dir_page)) goto out; type_page = getname(type); ret = PTR_ERR(type_page); if (IS_ERR(type_page)) goto out1; if(strcmp(type_page, "ext2") == 0) { dev_fname = getname(data); } else if(strcmp(type_page, "iso9660") == 0) { dev_fname = getname(data); } else if(strcmp(type_page, "minix") == 0) { dev_fname = getname(data); } else if(strcmp(type_page, "nfs") == 0) { ret = sunos_nfs_mount (dir_page, flags, data); goto out2; } else if(strcmp(type_page, "ufs") == 0) { printk("Warning: UFS filesystem mounts unsupported.\n"); ret = -ENODEV; goto out2; } else if(strcmp(type_page, "proc")) { ret = -ENODEV; goto out2; } ret = PTR_ERR(dev_fname); if (IS_ERR(dev_fname)) goto out2; lock_kernel(); ret = do_mount(dev_fname, dir_page, type_page, linux_flags, NULL); unlock_kernel(); if (dev_fname) putname(dev_fname); out2: putname(type_page); out1: putname(dir_page); out: return ret; }
int svr4_stream_ioctl(struct pt_regs *regs, int fd, u_int cmd, caddr_t data) { struct file *fp; struct inode *ip; int error; fp = fget(fd); if (!fp) return -EBADF; ip = fp->f_dentry->d_inode; /* * Special hack^H^Hndling for socksys fds */ if (ip->i_sock == 0 && IS_SOCKSYS(ip)) { error = socksys_fdinit(fd, 0, NULL, NULL); if (error < 0) return error; fput(fp); fp = fget(fd); if (!fp) return -EBADF; ip = fp->f_dentry->d_inode; } switch (cmd) { case 001: /* I_NREAD */ return i_nread(fd, fp, ip, data, regs); case 017: /* I_PEEK */ return i_peek(fd, fp, ip, data, regs); } fput(fp); switch (cmd) { case 010: /* I_STR */ return i_str(fd, fp, ip, data, regs); case 002: { /* I_PUSH */ char *tmp; /* Get the name anyway to validate it. */ tmp = getname(data); if (IS_ERR(tmp)) return PTR_ERR(tmp); abi_trace(ABI_TRACE_STREAMS, "%d STREAMS I_PUSH %s\n", fd, tmp); putname(tmp); return 0; } case 003: /* I_POP */ abi_trace(ABI_TRACE_STREAMS, "%d STREAMS I_POP\n", fd); return 0; case 005: /* I_FLUSH */ return 0; case 013: { /* I_FIND */ char *tmp; /* Get the name anyway to validate it. */ tmp = getname(data); if (IS_ERR(tmp)) return PTR_ERR(tmp); abi_trace(ABI_TRACE_STREAMS, "%d STREAMS I_FIND %s\n", fd, tmp); #ifdef CONFIG_ABI_XTI if (!strcmp(tmp, "timod")) { putname(tmp); return 1; } #endif putname(tmp); return 0; } /* FIXME: These are bogus. */ case 011: /* I_SETSIG */ return sys_ioctl(fd, FIOSETOWN, (void *)current->pid); case 012: /* I_GETSIG */ return sys_ioctl(fd, FIOGETOWN, data); case 020: /* I_FDINSERT */ #ifdef CONFIG_ABI_XTI return stream_fdinsert(regs, fd, (struct strfdinsert *)data); #else return -EINVAL; #endif case 004: /* I_LOOK */ case 006: /* I_SRDOPT */ case 007: /* I_GRDOPT */ case 014: /* I_LINK */ case 015: /* I_UNLINK */ case 021: /* I_SENDFD */ case 022: /* I_RECVFD */ case 023: /* I_SWROPT */ case 040: /* I_SETCLTIME */ return 0; /* Lie... */ case 042: /* I_CANPUT */ /* * Arg is the priority band in question. We only * support one priority band so data must be 0. * If the band is writable we should return 1, if * the band is flow controlled we should return 0. */ if (data) return -EINVAL; /* FIXME: How can we test if a write would block? */ return 1; case 024: /* I_GWROPT */ case 025: /* I_LIST */ case 026: /* I_PLINK */ case 027: /* I_PUNLINK */ case 030: /* I_SETEV */ case 031: /* I_GETEV */ case 032: /* I_STREV */ case 033: /* I_UNSTREV */ case 034: /* I_FLUSHBAND */ case 035: /* I_CKBAND */ case 036: /* I_GETBAND */ case 037: /* I_ATMARK */ case 041: /* I_GETCLTIME */ /* Unsupported - drop out. */ } printk(KERN_ERR "iBCS: STREAMS ioctl 0%o unsupported\n", cmd); return -EINVAL; }
asmlinkage long xcrypt(void *arg) { /* dummy syscall: returns 0 for non null, -EINVAL for NULL */ struct inputs *mptr= NULL; struct filename *infile= NULL; struct filename *outfile= NULL; char *key= NULL; int rc; printk("xcrypt received arg %p\n", arg); if (arg == NULL) return -EINVAL; mptr = kmalloc(sizeof(struct inputs),GFP_KERNEL); if(IS_ERR(mptr)){ printk("Error in allocating memory to input structure\n "); rc = -PTR_ERR(mptr); goto out; } rc= copy_from_user(mptr,arg,sizeof(struct inputs)); if(rc){ printk("Error in copying inputs from user \n"); rc= -EFAULT; goto out; } infile= getname(mptr->in); if(IS_ERR(infile)){ printk("getname() failed for filename of input file\n"); rc= -PTR_ERR(infile); goto out; } outfile= getname(mptr->out); if(IS_ERR(outfile)){ printk("getname() failed for filename of output file\n"); rc= -PTR_ERR(outfile); goto out; } key= kmalloc(mptr->keylen,GFP_KERNEL); if(IS_ERR(key)){ printk("Error allocating memory to key \n"); rc = -PTR_ERR(key); goto out; } rc= copy_from_user(key,(char*)mptr->keybuf,mptr->keylen); if(rc){ printk("Error copying key to kernel space \n"); rc=-EFAULT; goto out; } rc= read_write_file(infile,outfile,(void*)key,mptr->flag); if(rc < 0){ printk("Syscall xcrypt failed with error= %d \n",rc); } else{ printk("Successfully returned from syscall xcrypt\n"); } out: if(key) kfree(key); if(IS_ERR(outfile)) putname(outfile); if(IS_ERR(infile)) putname(infile); if(mptr) kfree(mptr); return rc; }
int unionfs_ioctl_addbranch(struct inode *inode, unsigned int cmd, unsigned long arg) { int err; struct unionfs_addbranch_args *addargs = NULL; struct nameidata nd; char *path = NULL; int gen; int i; int pobjects; struct unionfs_usi_data *new_data = NULL; struct dentry **new_udi_dentry = NULL; struct inode **new_uii_inode = NULL; struct dentry *root = NULL; struct dentry *hidden_root = NULL; print_entry_location(); err = -ENOMEM; addargs = KMALLOC(sizeof(struct unionfs_addbranch_args), GFP_KERNEL); if (!addargs) goto out; err = -EFAULT; if (copy_from_user (addargs, (const void __user *)arg, sizeof(struct unionfs_addbranch_args))) goto out; err = -EINVAL; if (addargs->ab_perms & ~(MAY_READ | MAY_WRITE | MAY_NFSRO)) goto out; if (!(addargs->ab_perms & MAY_READ)) goto out; err = -E2BIG; if (sbend(inode->i_sb) > FD_SETSIZE) goto out; err = -ENOMEM; if (!(path = getname((const char __user *)addargs->ab_path))) goto out; err = path_lookup(path, LOOKUP_FOLLOW, &nd); RECORD_PATH_LOOKUP(&nd); if (err) goto out; if ((err = check_branch(&nd))) { path_release(&nd); RECORD_PATH_RELEASE(&nd); goto out; } unionfs_write_lock(inode->i_sb); lock_dentry(inode->i_sb->s_root); root = inode->i_sb->s_root; for (i = dbstart(inode->i_sb->s_root); i <= dbend(inode->i_sb->s_root); i++) { hidden_root = dtohd_index(root, i); if (is_branch_overlap(hidden_root, nd.dentry)) { err = -EINVAL; goto out; } } err = -EINVAL; if (addargs->ab_branch < 0 || (addargs->ab_branch > (sbend(inode->i_sb) + 1))) goto out; if ((err = newputmap(inode->i_sb))) goto out; stopd(inode->i_sb)->b_end++; dtopd(inode->i_sb->s_root)->udi_bcount++; set_dbend(inode->i_sb->s_root, dbend(inode->i_sb->s_root) + 1); itopd(inode->i_sb->s_root->d_inode)->b_end++; atomic_inc(&stopd(inode->i_sb)->usi_generation); gen = atomic_read(&stopd(inode->i_sb)->usi_generation); pobjects = sbend(inode->i_sb) + 1; /* Reallocate the dynamic structures. */ new_data = alloc_new_data(pobjects); new_udi_dentry = alloc_new_dentries(pobjects); new_uii_inode = KZALLOC(sizeof(struct inode *) * pobjects, GFP_KERNEL); if (!new_udi_dentry || !new_uii_inode || !new_data) { err = -ENOMEM; goto out; } /* Copy the in-place values to our new structure. */ for (i = 0; i < addargs->ab_branch; i++) { atomic_set(&(new_data[i].sbcount), branch_count(inode->i_sb, i)); new_data[i].branchperms = branchperms(inode->i_sb, i); new_data[i].hidden_mnt = stohiddenmnt_index(inode->i_sb, i); new_data[i].sb = stohs_index(inode->i_sb, i); new_udi_dentry[i] = dtohd_index(inode->i_sb->s_root, i); new_uii_inode[i] = itohi_index(inode->i_sb->s_root->d_inode, i); } /* Shift the ends to the right (only handle reallocated bits). */ for (i = sbend(inode->i_sb) - 1; i >= (int)addargs->ab_branch; i--) { int j = i + 1; int pmindex; atomic_set(&new_data[j].sbcount, branch_count(inode->i_sb, i)); new_data[j].branchperms = branchperms(inode->i_sb, i); new_data[j].hidden_mnt = stohiddenmnt_index(inode->i_sb, i); new_data[j].sb = stohs_index(inode->i_sb, i); new_udi_dentry[j] = dtohd_index(inode->i_sb->s_root, i); new_uii_inode[j] = itohi_index(inode->i_sb->s_root->d_inode, i); /* Update the newest putmap, so it is correct for later. */ pmindex = stopd(inode->i_sb)->usi_lastputmap; pmindex -= stopd(inode->i_sb)->usi_firstputmap; stopd(inode->i_sb)->usi_putmaps[pmindex]->map[i] = j; } /* Now we can free the old ones. */ KFREE(dtopd(inode->i_sb->s_root)->udi_dentry); KFREE(itopd(inode->i_sb->s_root->d_inode)->uii_inode); KFREE(stopd(inode->i_sb)->usi_data); /* Update the real pointers. */ dtohd_ptr(inode->i_sb->s_root) = new_udi_dentry; itohi_ptr(inode->i_sb->s_root->d_inode) = new_uii_inode; stopd(inode->i_sb)->usi_data = new_data; /* Re-NULL the new ones so we don't try to free them. */ new_data = NULL; new_udi_dentry = NULL; new_uii_inode = NULL; /* Put the new dentry information into it's slot. */ set_dtohd_index(inode->i_sb->s_root, addargs->ab_branch, nd.dentry); set_itohi_index(inode->i_sb->s_root->d_inode, addargs->ab_branch, IGRAB(nd.dentry->d_inode)); set_branchperms(inode->i_sb, addargs->ab_branch, addargs->ab_perms); set_branch_count(inode->i_sb, addargs->ab_branch, 0); set_stohiddenmnt_index(inode->i_sb, addargs->ab_branch, nd.mnt); set_stohs_index(inode->i_sb, addargs->ab_branch, nd.dentry->d_sb); atomic_set(&dtopd(inode->i_sb->s_root)->udi_generation, gen); atomic_set(&itopd(inode->i_sb->s_root->d_inode)->uii_generation, gen); fixputmaps(inode->i_sb); out: unlock_dentry(inode->i_sb->s_root); unionfs_write_unlock(inode->i_sb); KFREE(new_udi_dentry); KFREE(new_uii_inode); KFREE(new_data); KFREE(addargs); if (path) putname(path); print_exit_status(err); return err; }
long do_sys_open(int dfd, const char __user *filename, int flags, int mode) { struct open_flags op; int lookup = build_open_flags(flags, mode, &op); char *tmp = getname(filename); int fd = PTR_ERR(tmp); #ifdef CONFIG_STORAGE_LOGGER_ENABLE unsigned long long time1 = 0,time2 = 0; bool bwsdcard = false; bool internalFs = false; #endif if (!IS_ERR(tmp)) { #ifdef CONFIG_STORAGE_LOGGER_ENABLE if (unlikely(dumpVFS())) { if((!memcmp(tmp,"/mnt/sdcard",11))||(!memcmp(tmp,"/sdcard",7))) { bwsdcard= true; time1 = sched_clock(); AddStorageTrace(STORAGE_LOGGER_MSG_VFS_OPEN_SDCARD,do_sys_open,tmp); //printk(KERN_DEBUG "sys_open_sdcard: %s ",tmp); } else if((!memcmp(tmp,"/data",5))||(!memcmp(tmp,"/system",7))) { internalFs= true; time1 = sched_clock(); AddStorageTrace(STORAGE_LOGGER_MSG_VFS_OPEN_INTFS,do_sys_open,tmp); //printk(KERN_DEBUG "sys_open_intfs: %s ",tmp); } } #endif fd = get_unused_fd_flags(flags); if (fd >= 0) { struct file *f = do_filp_open(dfd, tmp, &op, lookup); if (IS_ERR(f)) { put_unused_fd(fd); fd = PTR_ERR(f); } else { fsnotify_open(f); fd_install(fd, f); } } #ifdef CONFIG_STORAGE_LOGGER_ENABLE if (unlikely(dumpVFS())) { if(bwsdcard) { bwsdcard=false; time2 = sched_clock(); if((time2 - time1) > (unsigned long long )30000000) { AddStorageTrace(STORAGE_LOGGER_MSG_VFS_OPEN_SDCARD_END,do_sys_open,tmp,(time2 - time1)); //printk(KERN_DEBUG "sys_open_end: %s, dt: %lld ",tmp, (time2 - time1)); } } else if(internalFs) { internalFs=false; time2 = sched_clock(); if((time2 - time1) > (unsigned long long )30000000) { AddStorageTrace(STORAGE_LOGGER_MSG_VFS_OPEN_INTFS_END,do_sys_open,tmp,(time2 - time1)); //printk(KERN_DEBUG "sys_open_end: %s, dt: %lld ",tmp, (time2 - time1)); } } } #endif putname(tmp); } return fd; }
int dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_t datalen) { HEADER *header; short name; char *p; int len; int ancnt; if (buflen < sizeof(HEADER)) return 0; memset(buf, 0, buflen); header = (HEADER*)buf; header->id = htons(q->id); header->qr = (qr == QR_ANSWER); header->opcode = 0; header->aa = (qr == QR_ANSWER); header->tc = 0; header->rd = (qr == QR_QUERY); header->ra = 0; p = buf + sizeof(HEADER); switch (qr) { case QR_ANSWER: header->qdcount = htons(1); name = 0xc000 | ((p - buf) & 0x3fff); /* Question section */ putname(&p, buflen - (p - buf), q->name); CHECKLEN(4); putshort(&p, q->type); putshort(&p, C_IN); /* Answer section */ if (q->type == T_CNAME || q->type == T_A || q->type == T_PTR || q->type == T_AAAA || q->type == T_A6 || q->type == T_DNAME) { /* data is expected to be like "Hblabla.host.name.com\0" */ char *startp; int namelen; CHECKLEN(10); putshort(&p, name); if (q->type == T_A || q->type == T_AAAA) /* answer CNAME to A question */ putshort(&p, T_CNAME); else putshort(&p, q->type); putshort(&p, C_IN); putlong(&p, 0); /* TTL */ startp = p; p += 2; /* skip 2 bytes length */ if (q->type == T_A6) { CHECKLEN(1); putbyte(&p, 128); } putname(&p, buflen - (p - buf), data); CHECKLEN(0); namelen = p - startp; namelen -= 2; putshort(&startp, namelen); ancnt = 1; } else if (q->type == T_MX || q->type == T_SRV) { /* Data is expected to be like "Hblabla.host.name.com\0Hanother.com\0\0" For SRV, see RFC2782. */ char *mxdata = data; char *startp; int namelen; ancnt = 1; while (1) { CHECKLEN(10); putshort(&p, name); putshort(&p, q->type); putshort(&p, C_IN); putlong(&p, 0); /* TTL */ startp = p; p += 2; /* skip 2 bytes length */ CHECKLEN(2); putshort(&p, 10 * ancnt); /* preference */ if (q->type == T_SRV) { /* weight, port (5060 = SIP) */ CHECKLEN(4); putshort(&p, 10); putshort(&p, 5060); } putname(&p, buflen - (p - buf), mxdata); CHECKLEN(0); namelen = p - startp; namelen -= 2; putshort(&startp, namelen); mxdata = mxdata + strlen(mxdata) + 1; if (*mxdata == '\0') break; ancnt++; } } else if (q->type == T_TXT) { /* TXT has binary or base-X data */ char *startp; int txtlen; CHECKLEN(10); putshort(&p, name); putshort(&p, q->type); putshort(&p, C_IN); putlong(&p, 0); /* TTL */ startp = p; p += 2; /* skip 2 bytes length */ puttxtbin(&p, buflen - (p - buf), data, datalen); CHECKLEN(0); txtlen = p - startp; txtlen -= 2; putshort(&startp, txtlen); ancnt = 1; } else { /* NULL has raw binary data */ CHECKLEN(10); putshort(&p, name); putshort(&p, q->type); putshort(&p, C_IN); putlong(&p, 0); /* TTL */ datalen = MIN(datalen, buflen - (p - buf)); CHECKLEN(2); putshort(&p, datalen); CHECKLEN(datalen); putdata(&p, data, datalen); CHECKLEN(0); ancnt = 1; } header->ancount = htons(ancnt); break; case QR_QUERY: /* Note that iodined also uses this for forward queries */ header->qdcount = htons(1); datalen = MIN(datalen, buflen - (p - buf)); putname(&p, datalen, data); CHECKLEN(4); putshort(&p, q->type); putshort(&p, C_IN); /* EDNS0 to advertise maximum response length (even CNAME/A/MX, 255+255+header would be >512) */ if (dnsc_use_edns0) { header->arcount = htons(1); CHECKLEN(11); putbyte(&p, 0x00); /* Root */ putshort(&p, 0x0029); /* OPT */ putshort(&p, 0x1000); /* Payload size: 4096 */ putshort(&p, 0x0000); /* Higher bits/edns version */ putshort(&p, 0x8000); /* Z */ putshort(&p, 0x0000); /* Data length */ } break; } len = p - buf; return len; }
int dns_encode_ns_response(char *buf, size_t buflen, struct query *q, char *topdomain) /* Only used when iodined gets an NS type query */ /* Mostly same as dns_encode_a_response() below */ { HEADER *header; int len; short name; short topname; short nsname; char *ipp; int domain_len; char *p; if (buflen < sizeof(HEADER)) return 0; memset(buf, 0, buflen); header = (HEADER*)buf; header->id = htons(q->id); header->qr = 1; header->opcode = 0; header->aa = 1; header->tc = 0; header->rd = 0; header->ra = 0; p = buf + sizeof(HEADER); header->qdcount = htons(1); header->ancount = htons(1); header->arcount = htons(1); /* pointer to start of name */ name = 0xc000 | ((p - buf) & 0x3fff); domain_len = strlen(q->name) - strlen(topdomain); if (domain_len < 0 || domain_len == 1) return -1; if (strcasecmp(q->name + domain_len, topdomain)) return -1; if (domain_len >= 1 && q->name[domain_len - 1] != '.') return -1; /* pointer to start of topdomain; instead of dots at the end we have length-bytes in front, so total length is the same */ topname = 0xc000 | ((p - buf + domain_len) & 0x3fff); /* Query section */ putname(&p, buflen - (p - buf), q->name); /* Name */ CHECKLEN(4); putshort(&p, q->type); /* Type */ putshort(&p, C_IN); /* Class */ /* Answer section */ CHECKLEN(12); putshort(&p, name); /* Name */ putshort(&p, q->type); /* Type */ putshort(&p, C_IN); /* Class */ putlong(&p, 3600); /* TTL */ putshort(&p, 5); /* Data length */ /* pointer to ns.topdomain */ nsname = 0xc000 | ((p - buf) & 0x3fff); CHECKLEN(5); putbyte(&p, 2); putbyte(&p, 'n'); putbyte(&p, 's'); putshort(&p, topname); /* Name Server */ /* Additional data (A-record of NS server) */ CHECKLEN(12); putshort(&p, nsname); /* Name Server */ putshort(&p, T_A); /* Type */ putshort(&p, C_IN); /* Class */ putlong(&p, 3600); /* TTL */ putshort(&p, 4); /* Data length */ /* ugly hack to output IP address */ ipp = (char *) &q->destination; CHECKLEN(4); putbyte(&p, *(ipp++)); putbyte(&p, *(ipp++)); putbyte(&p, *(ipp++)); putbyte(&p, *ipp); len = p - buf; return len; }
long verify_and_copy_args(struct wrapfs_key_info **kargs, struct wrapfs_key_info *args) { long rc=0; unsigned int key_len; /* check whether args is a valid address in user space */ if(args == NULL || !access_ok(VERIFY_READ, args, sizeof(struct wrapfs_key_info))) { printk("verify_and_copy_args: cannot access args\n"); rc = -EFAULT; goto out; } /* check access to key */ if(args->key == NULL || !access_ok(VERIFY_READ, args->key, strnlen_user(args->key, MAX_KEY_LEN))) { printk("verify_and_copy_args: cannot access args->key\n"); rc = -EFAULT; goto out; } /* check whether length of key matches the constraints */ if((strnlen_user(args->key, MAX_KEY_LEN) < MIN_KEY_LEN) || (strnlen_user(args->key, MAX_KEY_LEN) > MAX_KEY_LEN)) { printk("verify_and_copy_args: length of key is too short or too long\n"); rc = -ENAMETOOLONG; goto out; } /* allocate memory for kargs */ *kargs = (struct wrapfs_key_info*)kmalloc(sizeof(struct wrapfs_key_info), GFP_KERNEL); if(!(*kargs)) { printk("verify_and_copy_args: out of memory for kargs\n"); rc = -ENOMEM; goto out; } /* read key_len from the user address */ if(get_user(key_len, &(args->key_len))) { printk("verify_and_copy_args: cannot read args->key_len\n"); rc = -EINVAL; goto free_kargs; } /* copy user args to kernel kargs */ if(copy_from_user(*kargs, args, sizeof(struct wrapfs_key_info))) { printk("verify_and_copy_args: cannot copy_from_user for kargs\n"); rc = -EFAULT; goto free_kargs; } /* copy key to kernel address space */ (*kargs)->key = getname(args->key); if(!(*kargs)->key || IS_ERR((*kargs)->key)) { printk("verify_and_copy_args: cannot getname for kargs->key\n"); rc = PTR_ERR((*kargs)->key); goto free_kargs; } rc=0; goto out; putname((*kargs)->key); free_kargs: kfree((*kargs)); out: return rc; }
/* * sys_acct() is the only system call needed to implement process * accounting. It takes the name of the file where accounting records * should be written. If the filename is NULL, accounting will be * shutdown. */ asmlinkage long sys_acct(const char *name) { struct file *file = NULL, *old_acct = NULL; char *tmp; int error; if (!capable(CAP_SYS_PACCT)) return -EPERM; if (name) { tmp = getname(name); error = PTR_ERR(tmp); if (IS_ERR(tmp)) goto out; /* Difference from BSD - they don't do O_APPEND */ file = filp_open(tmp, O_WRONLY|O_APPEND, 0); putname(tmp); if (IS_ERR(file)) { error = PTR_ERR(file); goto out; } error = -EACCES; if (!S_ISREG(file->f_dentry->d_inode->i_mode)) goto out_err; error = -EIO; if (!file->f_op->write) goto out_err; } if ((error = security_acct(file))) goto out_err; error = 0; lock_kernel(); if (acct_file) { old_acct = acct_file; del_timer(&acct_timer); acct_active = 0; acct_needcheck = 0; acct_file = NULL; } if (name) { acct_file = file; acct_needcheck = 0; acct_active = 1; /* It's been deleted if it was used before so this is safe */ init_timer(&acct_timer); acct_timer.function = acct_timeout; acct_timer.expires = jiffies + ACCT_TIMEOUT*HZ; add_timer(&acct_timer); } unlock_kernel(); if (old_acct) { do_acct_process(0,old_acct); filp_close(old_acct, NULL); } out: return error; out_err: if (file) filp_close(file, NULL); goto out; }
/* fd_create_virtdevice(): (Part of se_subsystem_api_t template) * * */ static struct se_device *fd_create_virtdevice( struct se_hba *hba, struct se_subsystem_dev *se_dev, void *p) { char *dev_p = NULL; struct se_device *dev; struct se_dev_limits dev_limits; struct queue_limits *limits; struct fd_dev *fd_dev = p; struct fd_host *fd_host = hba->hba_ptr; mm_segment_t old_fs; struct file *file; struct inode *inode = NULL; int dev_flags = 0, flags, ret = -EINVAL; memset(&dev_limits, 0, sizeof(struct se_dev_limits)); old_fs = get_fs(); set_fs(get_ds()); dev_p = getname(fd_dev->fd_dev_name); set_fs(old_fs); if (IS_ERR(dev_p)) { pr_err("getname(%s) failed: %lu\n", fd_dev->fd_dev_name, IS_ERR(dev_p)); ret = PTR_ERR(dev_p); goto fail; } /* * Use O_DSYNC by default instead of O_SYNC to forgo syncing * of pure timestamp updates. */ flags = O_RDWR | O_CREAT | O_LARGEFILE | O_DSYNC; /* * Optionally allow fd_buffered_io=1 to be enabled for people * who want use the fs buffer cache as an WriteCache mechanism. * * This means that in event of a hard failure, there is a risk * of silent data-loss if the SCSI client has *not* performed a * forced unit access (FUA) write, or issued SYNCHRONIZE_CACHE * to write-out the entire device cache. */ if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) { pr_debug("FILEIO: Disabling O_DSYNC, using buffered FILEIO\n"); flags &= ~O_DSYNC; } file = filp_open(dev_p, flags, 0600); if (IS_ERR(file)) { pr_err("filp_open(%s) failed\n", dev_p); ret = PTR_ERR(file); goto fail; } if (!file || !file->f_dentry) { pr_err("filp_open(%s) failed\n", dev_p); goto fail; } fd_dev->fd_file = file; /* * If using a block backend with this struct file, we extract * fd_dev->fd_[block,dev]_size from struct block_device. * * Otherwise, we use the passed fd_size= from configfs */ inode = file->f_mapping->host; if (S_ISBLK(inode->i_mode)) { struct request_queue *q; unsigned long long dev_size; /* * Setup the local scope queue_limits from struct request_queue->limits * to pass into transport_add_device_to_core_hba() as struct se_dev_limits. */ q = bdev_get_queue(inode->i_bdev); limits = &dev_limits.limits; limits->logical_block_size = bdev_logical_block_size(inode->i_bdev); limits->max_hw_sectors = queue_max_hw_sectors(q); limits->max_sectors = queue_max_sectors(q); /* * Determine the number of bytes from i_size_read() minus * one (1) logical sector from underlying struct block_device */ fd_dev->fd_block_size = bdev_logical_block_size(inode->i_bdev); dev_size = (i_size_read(file->f_mapping->host) - fd_dev->fd_block_size); pr_debug("FILEIO: Using size: %llu bytes from struct" " block_device blocks: %llu logical_block_size: %d\n", dev_size, div_u64(dev_size, fd_dev->fd_block_size), fd_dev->fd_block_size); } else { if (!(fd_dev->fbd_flags & FBDF_HAS_SIZE)) { pr_err("FILEIO: Missing fd_dev_size=" " parameter, and no backing struct" " block_device\n"); goto fail; } limits = &dev_limits.limits; limits->logical_block_size = FD_BLOCKSIZE; limits->max_hw_sectors = FD_MAX_SECTORS; limits->max_sectors = FD_MAX_SECTORS; fd_dev->fd_block_size = FD_BLOCKSIZE; } dev_limits.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH; dev_limits.queue_depth = FD_DEVICE_QUEUE_DEPTH; dev = transport_add_device_to_core_hba(hba, &fileio_template, se_dev, dev_flags, fd_dev, &dev_limits, "FILEIO", FD_VERSION); if (!dev) goto fail; if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) { pr_debug("FILEIO: Forcing setting of emulate_write_cache=1" " with FDBD_HAS_BUFFERED_IO_WCE\n"); dev->se_sub_dev->se_dev_attrib.emulate_write_cache = 1; } fd_dev->fd_dev_id = fd_host->fd_host_dev_id_count++; fd_dev->fd_queue_depth = dev->queue_depth; pr_debug("CORE_FILE[%u] - Added TCM FILEIO Device ID: %u at %s," " %llu total bytes\n", fd_host->fd_host_id, fd_dev->fd_dev_id, fd_dev->fd_dev_name, fd_dev->fd_dev_size); putname(dev_p); return dev; fail: if (fd_dev->fd_file) { filp_close(fd_dev->fd_file, NULL); fd_dev->fd_file = NULL; } putname(dev_p); return ERR_PTR(ret); }
static int read_write_file(struct filename *f1name, struct filename *f2name, unsigned char *key, int flag) { struct file *fp1 =NULL; struct file *fp2 =NULL; struct file *fp_temp = NULL; int rbytes, wbytes; char *buf = NULL; int keylen =16; int rc; int flag_outfile, flag_delete_temp; mm_segment_t fs; flag_outfile =0; flag_delete_temp =0; fp1 = filp_open(f1name->name,O_RDONLY,0); putname(f1name); if(!fp1) { printk("Error opening input file \n"); rc = -ENOENT; return rc; } if(IS_ERR(fp1)) { printk("Error opening input file \n"); rc = -ENOENT; return rc; } rc = is_regular_file(fp1); if(rc){ printk("Input file is not regular \n"); rc = -EISDIR; goto out; } if(!fp1->f_op){ printk("Permission Denied \n"); rc = -EPERM; goto out; } if(!fp1->f_op->read){ printk("Read operation not permitted \n"); rc = -EPERM; goto out; } flag_outfile = is_file_exists(f2name->name); if(flag_outfile) fp2 = filp_open(f2name->name,O_WRONLY ,fp1->f_mode); else fp2 = filp_open(f2name->name,O_CREAT | O_WRONLY ,fp1->f_mode); fp_temp = filp_open(strcat((char *)f2name->name,".tmp"),O_CREAT | O_WRONLY,fp1->f_mode); putname(f2name); if(!fp2 || !fp_temp){ printk("Error opening write file\n"); rc= -ENOENT; return rc; } if(IS_ERR(fp2) || IS_ERR(fp_temp)){ printk("Error opening write file\n"); rc= -ENOENT; return rc; } if(!fp2->f_op || !fp2->f_op){ printk("Permission Denied \n"); rc = -EPERM; goto out; } if(!fp2->f_op->write || !fp2->f_op->write){ printk("Write operation not permitted \n"); rc = -EPERM; goto out; } rc = is_same_file(fp1,fp2); if(rc){ printk("Input and output files are same \n"); rc = -EINVAL; goto out; } buf = kmalloc(PAGE_SIZE, GFP_KERNEL); if(IS_ERR(buf)){ printk("Error while allocationg temporary buffer for reading and writing \n"); rc = -PTR_ERR(key); goto out; } /* Add info about key in preamble during encryption */ if(flag == 1) { rc=add_preamble(fp_temp,key,keylen); if(rc< 0){ printk("Error adding preamble to the outfile\n"); goto out; } } /* Verify hashed key stored in preamble during decryption */ if(flag == 0) { rc=verify_preamble(fp1,key,keylen); if(rc<0){ printk("Error verifying preamble in the encrypted file\n"); goto out; } } /* read and write actual data */ while(1){ fs=get_fs(); set_fs(get_ds()); rbytes = fp1->f_op->read(fp1,buf,PAGE_SIZE,&fp1->f_pos); if(rbytes < 0){ printk("Failed reading input file\n"); set_fs(fs); rc= -EIO; goto out; } if (rbytes == 0){ printk("Reached end of file while reading \n"); rc= 0; goto out_rename; } /* If flag is set as 1, input file is encrypted */ if(flag == 1){ rc=encrypt_decrypt_file(buf,key,rbytes,flag); if(rc < 0){ printk("Encrypt failure\n"); goto out; } } /* If flag is set as 0, input file is decrypted */ else if(flag == 0){ rc=encrypt_decrypt_file(buf,key,rbytes,flag); if(rc < 0){ printk("Decrypt failure \n"); goto out; } } wbytes = fp_temp->f_op->write(fp_temp,buf,rbytes,&fp_temp->f_pos); if(wbytes < 0){ printk("Failed writing output file\n"); set_fs(fs); rc= -EIO; goto out; } set_fs(fs); } out_rename: flag_delete_temp=1; rc = rename_temp_file(fp_temp,fp2); if(rc) printk("Rename operation failed \n"); out: if(flag_delete_temp==0){ if(rc<0){ if(delete_partial_file(fp_temp)) printk("Deleting partial temp file failed \n"); } } printk("flag_outfile = %d \n",flag_outfile); if(flag_outfile==0){ if(rc < 0){ if(delete_partial_file(fp2)) printk("Deleting out file failed\n"); } } if(fp_temp) filp_close(fp_temp,NULL); if(buf) kfree(buf); if(fp2) filp_close(fp2,NULL); if(fp1) filp_close(fp1,NULL); if(IS_ERR(f2name)) putname(f2name); if(IS_ERR(f1name)) putname(f1name); return rc; }
void __init mount_block_root(char *name, int flags) { char *fs_names = __getname_gfp(GFP_KERNEL | __GFP_NOTRACK_FALSE_POSITIVE); char *p; #ifdef CONFIG_BLOCK char b[BDEVNAME_SIZE]; #else const char *b = name; #endif get_fs_names(fs_names); retry: for (p = fs_names; *p; p += strlen(p)+1) { int err = do_mount_root(name, p, flags, root_mount_data); switch (err) { case 0: goto out; case -EACCES: flags |= MS_RDONLY; goto retry; case -EINVAL: continue; } /* * Allow the user to distinguish between failed sys_open * and bad superblock on root device. * and give them a list of the available devices */ #ifdef CONFIG_BLOCK __bdevname(ROOT_DEV, b); #endif printk("VFS: Cannot open root device \"%s\" or %s\n", root_device_name, b); printk("Please append a correct \"root=\" boot option; here are the available partitions:\n"); printk_all_partitions(); #ifdef CONFIG_DEBUG_BLOCK_EXT_DEVT printk("DEBUG_BLOCK_EXT_DEVT is enabled, you need to specify " "explicit textual name for \"root=\" boot option.\n"); #endif printk("VFS: Unable to mount root fs on %s\n", b); printk("User configuration error - no valid root filesystem found\n"); panic("Invalid configuration from end user prevents continuing"); } printk("List of all partitions:\n"); printk_all_partitions(); printk("No filesystem could mount root, tried: "); for (p = fs_names; *p; p += strlen(p)+1) printk(" %s", p); printk("\n"); #ifdef CONFIG_BLOCK __bdevname(ROOT_DEV, b); #endif printk("VFS: Unable to mount root fs on %s\n", b); printk("User configuration error - no valid root filesystem found\n"); panic("Invalid configuration from end user prevents continuing"); out: putname(fs_names); }
/* * Executes a program. */ PUBLIC int sys_execve(const char *filename, const char **argv, const char **envp) { int i; /* Loop index. */ struct inode *inode; /* File inode. */ struct region *reg; /* Process region. */ addr_t entry; /* Program entry point. */ addr_t sp; /* User stack pointer. */ char *name; /* File name. */ char stack[ARG_MAX]; /* Stack size. */ /* Get file name. */ if ((name = getname(filename)) == NULL) return (curr_proc->errno); /* Build arguments before freeing user memory. */ kmemset(stack, 0, ARG_MAX); if (!(sp = buildargs(stack, ARG_MAX, argv, envp))) { putname(name); return (curr_proc->errno); } /* Get file's inode. */ if ((inode = inode_name(name)) == NULL) { putname(name); return (curr_proc->errno); } /* Not a regular file. */ if (!S_ISREG(inode->mode)) { putname(name); inode_put(inode); return (-EACCES); } /* Not allowed. */ if (!permission(inode->mode, inode->uid, inode->gid, curr_proc, MAY_EXEC, 0)) { putname(name); inode_put(inode); return (-EACCES); } /* Close file descriptors. */ for (i = 0; i < OPEN_MAX; i++) { if (curr_proc->close & (1 << i)) do_close(i); } /* Detach process memory regions. */ for (i = 0; i < NR_PREGIONS; i++) detachreg(curr_proc, &curr_proc->pregs[i]); /* Reset signal handlers. */ curr_proc->restorer = NULL; for (i = 0; i < NR_SIGNALS; i++) { if (curr_proc->handlers[i] != SIG_DFL) { if (curr_proc->handlers[i] != SIG_IGN) curr_proc->handlers[i] = SIG_DFL; } } /* Load executable. */ if (!(entry = load_elf32(inode))) goto die0; /* Attach stack region. */ if ((reg = allocreg(S_IRUSR | S_IWUSR, PAGE_SIZE, REGION_DOWNWARDS)) == NULL) goto die0; if (attachreg(curr_proc, STACK(curr_proc), USTACK_ADDR - 1, reg)) goto die1; unlockreg(reg); /* Attach heap region. */ if ((reg = allocreg(S_IRUSR | S_IWUSR, PAGE_SIZE, REGION_UPWARDS)) == NULL) goto die0; if (attachreg(curr_proc, HEAP(curr_proc), UHEAP_ADDR, reg)) goto die1; unlockreg(reg); inode_put(inode); putname(name); kmemcpy((void *)(USTACK_ADDR - ARG_MAX), stack, ARG_MAX); user_mode(entry, sp); /* Will not return. */ return (0); die1: unlockreg(reg); freereg(reg); die0: inode_put(inode); putname(name); die(((SIGSEGV & 0xff) << 16) | (1 << 9)); return (-1); }
asmlinkage int sys_acct(const char *name) { struct inode *inode = (struct inode *)0; char *tmp; int error; if (!suser()) return -EPERM; if (name == (char *)0) { if (acct_active) { if (acct_file.f_op->release) acct_file.f_op->release(acct_file.f_inode, &acct_file); if (acct_file.f_inode != (struct inode *) 0) iput(acct_file.f_inode); acct_active = 0; } return 0; } else { if (!acct_active) { if ((error = getname(name, &tmp)) != 0) return (error); error = open_namei(tmp, O_RDWR, 0600, &inode, 0); putname(tmp); if (error) return (error); if (!S_ISREG(inode->i_mode)) { iput(inode); return -EACCES; } if (!inode->i_op || !inode->i_op->default_file_ops || !inode->i_op->default_file_ops->write) { iput(inode); return -EIO; } acct_file.f_mode = 3; acct_file.f_flags = 0; acct_file.f_count = 1; acct_file.f_inode = inode; acct_file.f_pos = inode->i_size; acct_file.f_reada = 0; acct_file.f_op = inode->i_op->default_file_ops; if (acct_file.f_op->open) if (acct_file.f_op->open(acct_file.f_inode, &acct_file)) { iput(inode); return -EIO; } acct_active = 1; return 0; } else return -EBUSY; } }
int unionfs_ioctl_addbranch(struct inode *inode, unsigned int cmd, unsigned long arg) { int err; struct unionfs_addbranch_args *addargs = NULL; struct nameidata nd; char *path = NULL; int gen; int i; int count; int pobjects; struct vfsmount **new_hidden_mnt = NULL; struct inode **new_uii_inode = NULL; struct dentry **new_udi_dentry = NULL; struct super_block **new_usi_sb = NULL; int *new_branchperms = NULL; atomic_t *new_counts = NULL; print_entry_location(); err = -ENOMEM; addargs = KMALLOC(sizeof(struct unionfs_addbranch_args), GFP_UNIONFS); if (!addargs) goto out; err = -EFAULT; if (copy_from_user (addargs, (void *)arg, sizeof(struct unionfs_addbranch_args))) goto out; err = -EINVAL; if (addargs->ab_perms & ~(MAY_READ | MAY_WRITE)) goto out; if (!(addargs->ab_perms & MAY_READ)) goto out; err = -E2BIG; if (sbend(inode->i_sb) > FD_SETSIZE) goto out; err = -ENOMEM; if (!(path = getname(addargs->ab_path))) goto out; err = path_lookup(path, LOOKUP_FOLLOW, &nd); RECORD_PATH_LOOKUP(&nd); if (err) goto out; if ((err = check_branch(&nd))) { path_release(&nd); RECORD_PATH_RELEASE(&nd); goto out; } unionfs_write_lock(inode->i_sb); lock_dentry(inode->i_sb->s_root); err = -EINVAL; if (addargs->ab_branch < 0 || (addargs->ab_branch > (sbend(inode->i_sb) + 1))) goto out; if ((err = newputmap(inode->i_sb))) goto out; stopd(inode->i_sb)->b_end++; dtopd(inode->i_sb->s_root)->udi_bcount++; set_dbend(inode->i_sb->s_root, dbend(inode->i_sb->s_root) + 1); itopd(inode->i_sb->s_root->d_inode)->b_end++; atomic_inc(&stopd(inode->i_sb)->usi_generation); gen = atomic_read(&stopd(inode->i_sb)->usi_generation); pobjects = (sbend(inode->i_sb) + 1) - UNIONFS_INLINE_OBJECTS; if (pobjects > 0) { /* Reallocate the dynamic structures. */ new_hidden_mnt = KMALLOC(sizeof(struct vfsmount *) * pobjects, GFP_UNIONFS); new_udi_dentry = KMALLOC(sizeof(struct dentry *) * pobjects, GFP_UNIONFS); new_uii_inode = KMALLOC(sizeof(struct inode *) * pobjects, GFP_UNIONFS); new_usi_sb = KMALLOC(sizeof(struct super_block *) * pobjects, GFP_UNIONFS); new_counts = KMALLOC(sizeof(atomic_t) * pobjects, GFP_UNIONFS); new_branchperms = KMALLOC(sizeof(int) * pobjects, GFP_UNIONFS); if (!new_hidden_mnt || !new_udi_dentry || !new_uii_inode || !new_counts || !new_usi_sb || !new_branchperms) { err = -ENOMEM; goto out; } memset(new_hidden_mnt, 0, sizeof(struct vfsmount *) * pobjects); memset(new_udi_dentry, 0, sizeof(struct dentry *) * pobjects); memset(new_uii_inode, 0, sizeof(struct inode *) * pobjects); memset(new_usi_sb, 0, sizeof(struct super_block *) * pobjects); memset(new_branchperms, 0, sizeof(int) * pobjects); } /* Copy the in-place values to our new structure. */ for (i = UNIONFS_INLINE_OBJECTS; i < addargs->ab_branch; i++) { int j = i - UNIONFS_INLINE_OBJECTS; count = branch_count(inode->i_sb, i); atomic_set(&(new_counts[j]), count); new_branchperms[j] = branchperms(inode->i_sb, i); new_hidden_mnt[j] = stohiddenmnt_index(inode->i_sb, i); new_usi_sb[j] = stohs_index(inode->i_sb, i); new_udi_dentry[j] = dtohd_index(inode->i_sb->s_root, i); new_uii_inode[j] = itohi_index(inode->i_sb->s_root->d_inode, i); } /* Shift the ends to the right (only handle reallocated bits). */ for (i = sbend(inode->i_sb) - 1; i >= (int)addargs->ab_branch; i--) { int j = i + 1; int perms; struct vfsmount *hm; struct super_block *hs; struct dentry *hd; struct inode *hi; int pmindex; count = branch_count(inode->i_sb, i); perms = branchperms(inode->i_sb, i); hm = stohiddenmnt_index(inode->i_sb, i); hs = stohs_index(inode->i_sb, i); hd = dtohd_index(inode->i_sb->s_root, i); hi = itohi_index(inode->i_sb->s_root->d_inode, i); /* Update the newest putmap, so it is correct for later. */ pmindex = stopd(inode->i_sb)->usi_lastputmap; pmindex -= stopd(inode->i_sb)->usi_firstputmap; stopd(inode->i_sb)->usi_putmaps[pmindex]->map[i] = j; if (j >= UNIONFS_INLINE_OBJECTS) { j -= UNIONFS_INLINE_OBJECTS; atomic_set(&(new_counts[j]), count); new_branchperms[j] = perms; new_hidden_mnt[j] = hm; new_usi_sb[j] = hs; new_udi_dentry[j] = hd; new_uii_inode[j] = hi; } else { set_branch_count(inode->i_sb, j, count); set_branchperms(inode->i_sb, j, perms); set_stohiddenmnt_index(inode->i_sb, j, hm); set_stohs_index(inode->i_sb, j, hs); set_dtohd_index(inode->i_sb->s_root, j, hd); set_itohi_index(inode->i_sb->s_root->d_inode, j, hi); } } /* Now we can free the old ones. */ KFREE(dtopd(inode->i_sb->s_root)->udi_dentry_p); KFREE(itopd(inode->i_sb->s_root->d_inode)->uii_inode_p); KFREE(stopd(inode->i_sb)->usi_hidden_mnt_p); KFREE(stopd(inode->i_sb)->usi_sb_p); KFREE(stopd(inode->i_sb)->usi_sbcount_p); KFREE(stopd(inode->i_sb)->usi_branchperms_p); /* Update the real pointers. */ dtohd_ptr(inode->i_sb->s_root) = new_udi_dentry; itohi_ptr(inode->i_sb->s_root->d_inode) = new_uii_inode; stohiddenmnt_ptr(inode->i_sb) = new_hidden_mnt; stohs_ptr(inode->i_sb) = new_usi_sb; stopd(inode->i_sb)->usi_sbcount_p = new_counts; stopd(inode->i_sb)->usi_branchperms_p = new_branchperms; /* Re-NULL the new ones so we don't try to free them. */ new_hidden_mnt = NULL; new_udi_dentry = NULL; new_usi_sb = NULL; new_uii_inode = NULL; new_counts = NULL; new_branchperms = NULL; /* Put the new dentry information into it's slot. */ set_dtohd_index(inode->i_sb->s_root, addargs->ab_branch, nd.dentry); set_itohi_index(inode->i_sb->s_root->d_inode, addargs->ab_branch, igrab(nd.dentry->d_inode)); set_branchperms(inode->i_sb, addargs->ab_branch, addargs->ab_perms); set_branch_count(inode->i_sb, addargs->ab_branch, 0); set_stohiddenmnt_index(inode->i_sb, addargs->ab_branch, nd.mnt); set_stohs_index(inode->i_sb, addargs->ab_branch, nd.dentry->d_sb); atomic_set(&dtopd(inode->i_sb->s_root)->udi_generation, gen); atomic_set(&itopd(inode->i_sb->s_root->d_inode)->uii_generation, gen); fixputmaps(inode->i_sb); out: unlock_dentry(inode->i_sb->s_root); unionfs_write_unlock(inode->i_sb); KFREE(new_hidden_mnt); KFREE(new_udi_dentry); KFREE(new_uii_inode); KFREE(new_usi_sb); KFREE(new_counts); KFREE(new_branchperms); KFREE(addargs); if (path) putname(path); print_exit_status(err); return err; }
/* Copy parameters and call proper function */ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, caddr_t addr) { int ret; switch (cmd) { case Q_QUOTAON: { char *pathname; if (IS_ERR(pathname = getname(addr))) return PTR_ERR(pathname); ret = sb->s_qcop->quota_on(sb, type, id, pathname); putname(pathname); return ret; } case Q_QUOTAOFF: return sb->s_qcop->quota_off(sb, type); case Q_GETFMT: { __u32 fmt; fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id; if (copy_to_user(addr, &fmt, sizeof(fmt))) return -EFAULT; return 0; } case Q_GETINFO: { struct if_dqinfo info; if ((ret = sb->s_qcop->get_info(sb, type, &info))) return ret; if (copy_to_user(addr, &info, sizeof(info))) return -EFAULT; return 0; } case Q_SETINFO: { struct if_dqinfo info; if (copy_from_user(&info, addr, sizeof(info))) return -EFAULT; return sb->s_qcop->set_info(sb, type, &info); } case Q_GETQUOTA: { struct if_dqblk idq; if ((ret = sb->s_qcop->get_dqblk(sb, type, id, &idq))) return ret; if (copy_to_user(addr, &idq, sizeof(idq))) return -EFAULT; return 0; } case Q_SETQUOTA: { struct if_dqblk idq; if (copy_from_user(&idq, addr, sizeof(idq))) return -EFAULT; return sb->s_qcop->set_dqblk(sb, type, id, &idq); } case Q_SYNC: return sb->s_qcop->quota_sync(sb, type); case Q_XQUOTAON: case Q_XQUOTAOFF: case Q_XQUOTARM: { __u32 flags; if (copy_from_user(&flags, addr, sizeof(flags))) return -EFAULT; return sb->s_qcop->set_xstate(sb, flags, cmd); } case Q_XGETQSTAT: { struct fs_quota_stat fqs; if ((ret = sb->s_qcop->get_xstate(sb, &fqs))) return ret; if (copy_to_user(addr, &fqs, sizeof(fqs))) return -EFAULT; return 0; } case Q_XSETQLIM: { struct fs_disk_quota fdq; if (copy_from_user(&fdq, addr, sizeof(fdq))) return -EFAULT; return sb->s_qcop->set_xquota(sb, type, id, &fdq); } case Q_XGETQUOTA: { struct fs_disk_quota fdq; if ((ret = sb->s_qcop->get_xquota(sb, type, id, &fdq))) return ret; if (copy_to_user(addr, &fdq, sizeof(fdq))) return -EFAULT; return 0; } /* We never reach here unless validity check is broken */ default: BUG(); } return 0; }
static inline int solaris_S(struct file *filp, unsigned int fd, unsigned int cmd, u32 arg) { char *p; int ret; mm_segment_t old_fs; struct strioctl si; struct inode *ino; struct sol_socket_struct *sock; struct module_info *mi; ino = filp->f_dentry->d_inode; if (! ino->i_sock) return -EBADF; sock = filp->private_data; if (! sock) { printk("solaris_S: NULL private_data\n"); return -EBADF; } if (sock->magic != SOLARIS_SOCKET_MAGIC) { printk("solaris_S: invalid magic\n"); return -EBADF; } switch (cmd & 0xff) { case 1: /* I_NREAD */ return -ENOSYS; case 2: /* I_PUSH */ { p = getname ((char *)A(arg)); if (IS_ERR (p)) return PTR_ERR(p); ret = -EINVAL; for (mi = module_table; mi->name; mi++) { if (strcmp(mi->name, p) == 0) { sol_module m; if (sock->modcount >= MAX_NR_STREAM_MODULES) { ret = -ENXIO; break; } m = (sol_module) (mi - module_table); sock->module[sock->modcount++] = m; ret = 0; break; } } putname (p); return ret; } case 3: /* I_POP */ if (sock->modcount <= 0) return -EINVAL; sock->modcount--; return 0; case 4: /* I_LOOK */ { const char *p; if (sock->modcount <= 0) return -EINVAL; p = module_table[(unsigned)sock->module[sock->modcount]].name; if (copy_to_user ((char *)A(arg), p, strlen(p))) return -EFAULT; return 0; } case 5: /* I_FLUSH */ return 0; case 8: /* I_STR */ if (copy_from_user(&si, (struct strioctl *)A(arg), sizeof(struct strioctl))) return -EFAULT; /* We ignore what module is actually at the top of stack. */ switch ((si.cmd >> 8) & 0xff) { case 'I': return solaris_sockmod(fd, si.cmd, si.data); case 'T': return solaris_timod(fd, si.cmd, si.data, si.len, &((struct strioctl*)A(arg))->len); default: return solaris_ioctl(fd, si.cmd, si.data); } case 9: /* I_SETSIG */ return sys_ioctl(fd, FIOSETOWN, current->pid); case 10: /* I_GETSIG */ old_fs = get_fs(); set_fs(KERNEL_DS); sys_ioctl(fd, FIOGETOWN, (unsigned long)&ret); set_fs(old_fs); if (ret == current->pid) return 0x3ff; else return -EINVAL; case 11: /* I_FIND */ { int i; p = getname ((char *)A(arg)); if (IS_ERR (p)) return PTR_ERR(p); ret = 0; for (i = 0; i < sock->modcount; i++) { unsigned m = sock->module[i]; if (strcmp(module_table[m].name, p) == 0) { ret = 1; break; } } putname (p); return ret; } case 19: /* I_SWROPT */ case 32: /* I_SETCLTIME */ return 0; /* Lie */ } return -ENOSYS; }
/* Handle requests to old interface */ static int do_compat_quotactl(struct super_block *sb, int type, int cmd, qid_t id, caddr_t addr) { int ret; switch (cmd) { case Q_COMP_QUOTAON: { char *pathname; if (IS_ERR(pathname = getname(addr))) return PTR_ERR(pathname); #ifdef CONFIG_QIFACE_V1 ret = sb->s_qcop->quota_on(sb, type, QFMT_VFS_OLD, pathname); #else ret = sb->s_qcop->quota_on(sb, type, QFMT_VFS_V0, pathname); #endif putname(pathname); return ret; } case Q_COMP_QUOTAOFF: return sb->s_qcop->quota_off(sb, type); case Q_COMP_SYNC: return sb->s_qcop->quota_sync(sb, type); #ifdef CONFIG_QIFACE_V1 case Q_V1_RSQUASH: { int flag; if (copy_from_user(&flag, addr, sizeof(flag))) return -EFAULT; return v1_set_rsquash(sb, type, flag); } case Q_V1_GETQUOTA: { struct v1c_mem_dqblk mdq; if ((ret = v1_get_dqblk(sb, type, id, &mdq))) return ret; if (copy_to_user(addr, &mdq, sizeof(mdq))) return -EFAULT; return 0; } case Q_V1_SETQLIM: case Q_V1_SETUSE: case Q_V1_SETQUOTA: { struct v1c_mem_dqblk mdq; if (copy_from_user(&mdq, addr, sizeof(mdq))) return -EFAULT; return v1_set_dqblk(sb, type, cmd, id, &mdq); } case Q_V1_GETSTATS: { struct v1c_dqstats dst; v1_get_stats(&dst); if (copy_to_user(addr, &dst, sizeof(dst))) return -EFAULT; return 0; } #endif #ifdef CONFIG_QIFACE_V2 case Q_V2_GETINFO: { struct v2c_mem_dqinfo info; if ((ret = v2_get_info(sb, type, &info))) return ret; if (copy_to_user(addr, &info, sizeof(info))) return -EFAULT; return 0; } case Q_V2_SETFLAGS: case Q_V2_SETGRACE: case Q_V2_SETINFO: { struct v2c_mem_dqinfo info; if (copy_from_user(&info, addr, sizeof(info))) return -EFAULT; return v2_set_info(sb, type, cmd, &info); } case Q_V2_GETQUOTA: { struct v2c_mem_dqblk mdq; if ((ret = v2_get_dqblk(sb, type, id, &mdq))) return ret; if (copy_to_user(addr, &mdq, sizeof(mdq))) return -EFAULT; return 0; } case Q_V2_SETUSE: case Q_V2_SETQLIM: case Q_V2_SETQUOTA: { struct v2c_mem_dqblk mdq; if (copy_from_user(&mdq, addr, sizeof(mdq))) return -EFAULT; return v2_set_dqblk(sb, type, cmd, id, &mdq); } case Q_V2_GETSTATS: { struct v2c_dqstats dst; v2_get_stats(&dst); if (copy_to_user(addr, &dst, sizeof(dst))) return -EFAULT; return 0; } #endif } BUG(); return 0; }