int sys_umount(char *name) { struct inode *inode; register struct inode *inodep; kdev_t dev; int retval; struct inode dummy_inode; if (!suser()) return -EPERM; retval = namei(name, &inode, 0, 0); if (retval) { retval = lnamei(name, &inode); if (retval) return retval; } inodep = inode; if (S_ISBLK(inodep->i_mode)) { dev = inodep->i_rdev; if (IS_NODEV(inodep)) { iput(inodep); return -EACCES; } } else { register struct super_block *sb = inodep->i_sb; if (!sb || inodep != sb->s_mounted) { iput(inodep); return -EINVAL; } dev = sb->s_dev; iput(inodep); memset(&dummy_inode, 0, sizeof(dummy_inode)); dummy_inode.i_rdev = dev; inodep = &dummy_inode; } if (MAJOR(dev) >= MAX_BLKDEV) { iput(inodep); return -ENXIO; } if (!(retval = do_umount(dev)) && dev != ROOT_DEV) { register struct file_operations *fops; fops = get_blkfops(MAJOR(dev)); if (fops && fops->release) fops->release(inodep, NULL); #ifdef NOT_YET if (MAJOR(dev) == UNNAMED_MAJOR) put_unnamed_dev(dev); #endif } if (inodep != &dummy_inode) iput(inodep); if (retval) return retval; fsync_dev(dev); return 0; }
asmlinkage int sys_chown(const char * filename, uid_t user, gid_t group) { struct inode * inode; int error; struct iattr newattrs; error = lnamei(filename,&inode); if (error) return error; if (IS_RDONLY(inode)) { iput(inode); return -EROFS; } if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) { iput(inode); return -EPERM; } if (user == (uid_t) -1) user = inode->i_uid; if (group == (gid_t) -1) group = inode->i_gid; newattrs.ia_mode = inode->i_mode; newattrs.ia_uid = user; newattrs.ia_gid = group; newattrs.ia_valid = ATTR_UID | ATTR_GID | ATTR_CTIME; /* * If the owner has been changed, remove the setuid bit */ if (inode->i_mode & S_ISUID) { newattrs.ia_mode &= ~S_ISUID; newattrs.ia_valid |= ATTR_MODE; } /* * If the group has been changed, remove the setgid bit * * Don't remove the setgid bit if no group execute bit. * This is a file marked for mandatory locking. */ if (((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) { newattrs.ia_mode &= ~S_ISGID; newattrs.ia_valid |= ATTR_MODE; } inode->i_dirt = 1; if (inode->i_sb->dq_op) { inode->i_sb->dq_op->initialize(inode, -1); if (inode->i_sb->dq_op->transfer(inode, &newattrs, 0)) return -EDQUOT; error = notify_change(inode, &newattrs); if (error) inode->i_sb->dq_op->transfer(inode, &newattrs, 1); } else error = notify_change(inode, &newattrs); iput(inode); return(error); }
long sys_umount(const char *name, size_t name_len) { struct inode * inode; dev_t dev; int retval, error; struct inode dummy_inode; struct file_operations * fops; error = verify_user_string(name, name_len); if (error) return error; //if (!suser()) // return -EPERM; retval = namei(name,&inode); if (retval) { retval = lnamei(name,&inode); if (retval) return retval; } if (S_ISBLK(inode->i_mode)) { dev = inode->i_rdev; if (IS_NODEV(inode)) { iput(inode); return -EACCES; } } else { if (!inode || !inode->i_sb || inode != inode->i_sb->s_mounted) { iput(inode); return -EINVAL; } dev = inode->i_sb->s_dev; iput(inode); memset(&dummy_inode, 0, sizeof(dummy_inode)); dummy_inode.i_dev = dev; inode = &dummy_inode; } if (major(dev) >= MAX_BLKDEV) { iput(inode); return -ENXIO; } if (!(retval = do_umount(dev)) && dev != ROOT_DEV) { fops = get_blkfops(major(dev)); if (fops && fops->release) fops->release(inode,NULL); if (major(dev) == UNNAMED_MAJOR) put_unnamed_dev(dev); } if (inode != &dummy_inode) iput(inode); if (retval) return retval; //fsync_dev(dev); return 0; }
int sys_newlstat(char * filename, struct new_stat * statbuf) { struct inode * inode; int error; error = lnamei(filename,&inode); if (error) return error; cp_new_stat(inode,statbuf); iput(inode); return 0; }
int sys_chown(char *filename, uid_t user, gid_t group) { struct inode *inode; int error; error = lnamei(filename, &inode); if (!error) { error = do_chown(inode, user, group); iput(inode); } return error; }
asmlinkage int sys_umount(char * name) { struct inode * inode; kdev_t dev; int retval; struct inode dummy_inode; if (!suser()) return -EPERM; retval = namei(name, &inode); if (retval) { retval = lnamei(name, &inode); if (retval) return retval; } if (S_ISBLK(inode->i_mode)) { dev = inode->i_rdev; if (IS_NODEV(inode)) { iput(inode); return -EACCES; } } else { if (!inode->i_sb || inode != inode->i_sb->s_mounted) { iput(inode); return -EINVAL; } dev = inode->i_sb->s_dev; iput(inode); memset(&dummy_inode, 0, sizeof(dummy_inode)); dummy_inode.i_rdev = dev; inode = &dummy_inode; } if (MAJOR(dev) >= MAX_BLKDEV) { iput(inode); return -ENXIO; } retval = do_umount(dev,0); if (!retval) { fsync_dev(dev); if (dev != ROOT_DEV) { blkdev_release (inode); if (MAJOR(dev) == UNNAMED_MAJOR) put_unnamed_dev(dev); } } if (inode != &dummy_inode) iput(inode); if (retval) return retval; fsync_dev(dev); return 0; }
asmlinkage int sys_newlstat(char * filename, struct new_stat * statbuf) { struct inode * inode; int error; error = verify_area(VERIFY_WRITE,statbuf,sizeof (*statbuf)); if (error) return error; error = lnamei(filename,&inode); if (error) return error; cp_new_stat(inode,statbuf); iput(inode); return 0; }
int sys_readlink(const char * path, char * buf, int bufsiz) { struct inode * inode; int error; if (bufsiz <= 0) return -EINVAL; verify_area(buf,bufsiz); error = lnamei(path,&inode); if (error) return error; if (!inode->i_op || !inode->i_op->readlink) { iput(inode); return -EINVAL; } return inode->i_op->readlink(inode,buf,bufsiz); }
int osi_lookupname(char *aname, uio_seg_t seg, int followlink, struct dentry **dpp) { struct dentry *dp = NULL; int code; code = ENOENT; if (seg == AFS_UIOUSER) { dp = followlink ? namei(aname) : lnamei(aname); } else { dp = lookup_dentry(aname, NULL, followlink ? 1 : 0); } if (dp && !IS_ERR(dp)) { if (dp->d_inode) { *dpp = dp; code = 0; } else dput(dp); } return code; }