Commit 1eafe709 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.3.99pre2-2

parent cef52a34
......@@ -3059,7 +3059,7 @@ do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
lock_kernel();
dentry = open_namei(filename, 0, 0);
dentry = open_namei(filename);
unlock_kernel();
retval = PTR_ERR(dentry);
......@@ -4154,7 +4154,7 @@ asmlinkage long sparc32_open(const char * filename, int flags, int mode)
if (fd >= 0) {
struct file * f;
lock_kernel();
f = filp_open(tmp, flags, mode);
f = filp_open(tmp, flags, mode, NULL);
unlock_kernel();
error = PTR_ERR(f);
if (IS_ERR(f))
......
......@@ -102,7 +102,7 @@ int raw_open(struct inode *inode, struct file *filp)
*/
sector_size = 512;
if (lookup_vfsmnt(rdev) != NULL) {
if (get_super(rdev) != NULL) {
if (blksize_size[MAJOR(rdev)])
sector_size = blksize_size[MAJOR(rdev)][MINOR(rdev)];
} else {
......
......@@ -203,7 +203,7 @@ static void go_sync(kdev_t dev, int remount_flag)
file->f_mode &= ~2;
}
file_list_unlock();
DQUOT_OFF(dev);
DQUOT_OFF(sb);
fsync_dev(dev);
flags = MS_RDONLY;
if (sb->s_op && sb->s_op->remount_fs) {
......@@ -212,8 +212,6 @@ static void go_sync(kdev_t dev, int remount_flag)
printk("error %d\n", ret);
else {
sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
if ((vfsmnt = lookup_vfsmnt(sb->s_dev)))
vfsmnt->mnt_flags = sb->s_flags;
printk("OK\n");
}
} else
......
......@@ -18,7 +18,6 @@
#include <linux/isapnp.h>
#include <linux/string.h>
static void __init quirk_awe32_resources(struct pci_dev *dev)
{
struct isapnp_port *port, *port2, *port3;
......@@ -67,6 +66,37 @@ static void __init quirk_cmi8330_resources(struct pci_dev *dev)
printk(KERN_INFO "isapnp: CMI8330 quirk - fixing interrupts and dma\n");
}
static void __init quirk_sb16audio_resources(struct pci_dev *dev)
{
struct isapnp_port *port;
struct isapnp_resources *res = dev->sysdata;
int changed = 0;
/*
* The default range on the mtu port for these devices is 0x388-0x388.
* Here we increase that range so that two such cards can be
* auto-configured.
*/
for( ; res ; res = res->alt ) {
port = res->port;
if(!port)
continue;
port = port->next;
if(!port)
continue;
port = port->next;
if(!port)
continue;
if(port->min != port->max)
continue;
port->max += 0x70;
changed = 1;
}
if(changed)
printk(KERN_INFO "ISAPnP: SB audio device quirk - increasing port range\n");
return;
}
/*
* ISAPnP Quirks
......@@ -74,14 +104,31 @@ static void __init quirk_cmi8330_resources(struct pci_dev *dev)
*/
static struct isapnp_fixup isapnp_fixups[] __initdata = {
/* Soundblaster awe io port quirk */
{ ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0021),
quirk_awe32_resources },
{ ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0022),
quirk_awe32_resources },
{ ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0023),
quirk_awe32_resources },
{ ISAPNP_VENDOR('@','X','@'), ISAPNP_DEVICE(0x0001), // CMI8330
/* CMI 8330 interrupt and dma fix */
{ ISAPNP_VENDOR('@','X','@'), ISAPNP_DEVICE(0x0001),
quirk_cmi8330_resources },
/* Soundblaster audio device io port range quirk */
{ ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0001),
quirk_sb16audio_resources },
{ ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0031),
quirk_sb16audio_resources },
{ ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0041),
quirk_sb16audio_resources },
{ ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0042),
quirk_sb16audio_resources },
{ ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0043),
quirk_sb16audio_resources },
{ ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0044),
quirk_sb16audio_resources },
{ ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0045),
quirk_sb16audio_resources },
{ 0 }
};
......
......@@ -495,16 +495,14 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
current->personality = PER_SVR4;
lock_kernel();
interpreter_dentry = open_namei(elf_interpreter,
0, 0);
interpreter_dentry = open_namei(elf_interpreter);
unlock_kernel();
current->personality = old_pers;
} else
#endif
{
lock_kernel();
interpreter_dentry = open_namei(elf_interpreter,
0, 0);
interpreter_dentry = open_namei(elf_interpreter);
unlock_kernel();
}
set_fs(old_fs);
......
......@@ -81,7 +81,7 @@ static int load_em86(struct linux_binprm *bprm,struct pt_regs *regs)
* space, and we don't need to copy it.
*/
lock_kernel();
dentry = open_namei(interp, 0, 0);
dentry = open_namei(interp);
unlock_kernel();
if (IS_ERR(dentry))
return PTR_ERR(dentry);
......
......@@ -213,7 +213,7 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
bprm->argc++;
bprm->filename = iname; /* for binfmt_script */
dentry = open_namei(iname, 0, 0);
dentry = open_namei(iname);
retval = PTR_ERR(dentry);
if (IS_ERR(dentry))
goto _ret;
......
......@@ -82,7 +82,7 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
* OK, now restart the process with the interpreter's dentry.
*/
lock_kernel();
dentry = open_namei(interp, 0, 0);
dentry = open_namei(interp);
unlock_kernel();
if (IS_ERR(dentry))
return PTR_ERR(dentry);
......
......@@ -66,6 +66,11 @@ static char *quotatypes[] = INITQFNAMES;
static kmem_cache_t *dquot_cachep;
static inline struct quota_mount_options *sb_dqopt(struct super_block *sb)
{
return &sb->s_dquot;
}
/*
* Dquot List Management:
* The quota code uses three lists for dquot management: the inuse_list,
......@@ -98,29 +103,20 @@ static DECLARE_WAIT_QUEUE_HEAD(update_wait);
static void dqput(struct dquot *);
static struct dquot *dqduplicate(struct dquot *);
static inline char is_enabled(struct vfsmount *vfsmnt, short type)
static inline char is_enabled(struct quota_mount_options *dqopt, short type)
{
switch (type) {
case USRQUOTA:
return((vfsmnt->mnt_dquot.flags & DQUOT_USR_ENABLED) != 0);
return((dqopt->flags & DQUOT_USR_ENABLED) != 0);
case GRPQUOTA:
return((vfsmnt->mnt_dquot.flags & DQUOT_GRP_ENABLED) != 0);
return((dqopt->flags & DQUOT_GRP_ENABLED) != 0);
}
return(0);
}
static inline char sb_has_quota_enabled(struct super_block *sb, short type)
{
struct vfsmount *vfsmnt;
return((vfsmnt = lookup_vfsmnt(sb->s_dev)) != (struct vfsmount *)NULL && is_enabled(vfsmnt, type));
}
static inline char dev_has_quota_enabled(kdev_t dev, short type)
{
struct vfsmount *vfsmnt;
return((vfsmnt = lookup_vfsmnt(dev)) != (struct vfsmount *)NULL && is_enabled(vfsmnt, type));
return is_enabled(sb_dqopt(sb), type);
}
static inline int const hashfn(kdev_t dev, unsigned int id, short type)
......@@ -253,15 +249,15 @@ static void write_dquot(struct dquot *dquot)
mm_segment_t fs;
loff_t offset;
ssize_t ret;
struct semaphore *sem = &dquot->dq_mnt->mnt_dquot.dqio_sem;
struct semaphore *sem = &dquot->dq_sb->s_dquot.dqio_sem;
lock_dquot(dquot);
if (!dquot->dq_mnt) { /* Invalidated quota? */
if (!dquot->dq_sb) { /* Invalidated quota? */
unlock_dquot(dquot);
return;
}
down(sem);
filp = dquot->dq_mnt->mnt_dquot.files[type];
filp = dquot->dq_sb->s_dquot.files[type];
offset = dqoff(dquot->dq_id);
fs = get_fs();
set_fs(KERNEL_DS);
......@@ -293,20 +289,20 @@ static void read_dquot(struct dquot *dquot)
mm_segment_t fs;
loff_t offset;
filp = dquot->dq_mnt->mnt_dquot.files[type];
filp = dquot->dq_sb->s_dquot.files[type];
if (filp == (struct file *)NULL)
return;
lock_dquot(dquot);
if (!dquot->dq_mnt) /* Invalidated quota? */
if (!dquot->dq_sb) /* Invalidated quota? */
goto out_lock;
/* Now we are sure filp is valid - the dquot isn't invalidated */
down(&dquot->dq_mnt->mnt_dquot.dqio_sem);
down(&dquot->dq_sb->s_dquot.dqio_sem);
offset = dqoff(dquot->dq_id);
fs = get_fs();
set_fs(KERNEL_DS);
filp->f_op->read(filp, (char *)&dquot->dq_dqb, sizeof(struct dqblk), &offset);
up(&dquot->dq_mnt->mnt_dquot.dqio_sem);
up(&dquot->dq_sb->s_dquot.dqio_sem);
set_fs(fs);
if (dquot->dq_bhardlimit == 0 && dquot->dq_bsoftlimit == 0 &&
......@@ -326,7 +322,7 @@ void clear_dquot(struct dquot *dquot)
{
/* unhash it first */
unhash_dquot(dquot);
dquot->dq_mnt = NULL;
dquot->dq_sb = NULL;
dquot->dq_flags = 0;
dquot->dq_referenced = 0;
memset(&dquot->dq_dqb, 0, sizeof(struct dqblk));
......@@ -346,7 +342,7 @@ void invalidate_dquots(kdev_t dev, short type)
continue;
if (dquot->dq_type != type)
continue;
if (!dquot->dq_mnt) /* Already invalidated entry? */
if (!dquot->dq_sb) /* Already invalidated entry? */
continue;
if (dquot->dq_flags & DQ_LOCKED) {
__wait_on_dquot(dquot);
......@@ -360,7 +356,7 @@ void invalidate_dquots(kdev_t dev, short type)
continue;
if (dquot->dq_type != type)
continue;
if (!dquot->dq_mnt)
if (!dquot->dq_sb)
continue;
}
/*
......@@ -368,7 +364,7 @@ void invalidate_dquots(kdev_t dev, short type)
* the quota needn't to be written to disk. So we write it
* ourselves before discarding the data just for sure...
*/
if (dquot->dq_flags & DQ_MOD && dquot->dq_mnt)
if (dquot->dq_flags & DQ_MOD && dquot->dq_sb)
{
write_dquot(dquot);
need_restart = 1; /* We slept on IO */
......@@ -397,7 +393,7 @@ int sync_dquots(kdev_t dev, short type)
continue;
if (type != -1 && dquot->dq_type != type)
continue;
if (!dquot->dq_mnt) /* Invalidated? */
if (!dquot->dq_sb) /* Invalidated? */
continue;
if (!(dquot->dq_flags & (DQ_LOCKED | DQ_MOD)))
continue;
......@@ -435,11 +431,11 @@ static void dqput(struct dquot *dquot)
}
/*
* If the dq_mnt pointer isn't initialized this entry needs no
* If the dq_sb pointer isn't initialized this entry needs no
* checking and doesn't need to be written. It's just an empty
* dquot that is put back on to the freelist.
*/
if (dquot->dq_mnt)
if (dquot->dq_sb)
dqstats.drops++;
we_slept:
if (dquot->dq_count > 1) {
......@@ -451,7 +447,7 @@ static void dqput(struct dquot *dquot)
printk(KERN_ERR "VFS: Locked quota to be put on the free list.\n");
dquot->dq_flags &= ~DQ_LOCKED;
}
if (dquot->dq_mnt && dquot->dq_flags & DQ_MOD) {
if (dquot->dq_sb && dquot->dq_flags & DQ_MOD) {
write_dquot(dquot);
goto we_slept;
}
......@@ -571,17 +567,17 @@ struct dquot *get_empty_dquot(void)
goto repeat;
}
struct dquot *dqget(kdev_t dev, unsigned int id, short type)
static struct dquot *dqget(struct super_block *sb, unsigned int id, short type)
{
unsigned int hashent = hashfn(dev, id, type);
unsigned int hashent = hashfn(sb->s_dev, id, type);
struct dquot *dquot, *empty = NULL;
struct vfsmount *vfsmnt;
struct quota_mount_options *dqopt = sb_dqopt(sb);
if ((vfsmnt = lookup_vfsmnt(dev)) == (struct vfsmount *)NULL || !is_enabled(vfsmnt, type))
if (!is_enabled(dqopt, type))
return(NODQUOT);
we_slept:
if ((dquot = find_dquot(hashent, dev, id, type)) == NULL) {
if ((dquot = find_dquot(hashent, sb->s_dev, id, type)) == NULL) {
if (empty == NULL) {
dquot_updating[hashent]++;
empty = get_empty_dquot();
......@@ -592,8 +588,8 @@ struct dquot *dqget(kdev_t dev, unsigned int id, short type)
dquot = empty;
dquot->dq_id = id;
dquot->dq_type = type;
dquot->dq_dev = dev;
dquot->dq_mnt = vfsmnt;
dquot->dq_dev = sb->s_dev;
dquot->dq_sb = sb;
/* hash it first so it can be found */
hash_dquot(dquot);
read_dquot(dquot);
......@@ -610,7 +606,7 @@ struct dquot *dqget(kdev_t dev, unsigned int id, short type)
while (dquot_updating[hashent])
sleep_on(&update_wait);
if (!dquot->dq_mnt) { /* Has somebody invalidated entry under us? */
if (!dquot->dq_sb) { /* Has somebody invalidated entry under us? */
/*
* Do it as if the quota was invalidated before we started
*/
......@@ -625,11 +621,11 @@ struct dquot *dqget(kdev_t dev, unsigned int id, short type)
static struct dquot *dqduplicate(struct dquot *dquot)
{
if (dquot == NODQUOT || !dquot->dq_mnt)
if (dquot == NODQUOT || !dquot->dq_sb)
return NODQUOT;
dquot->dq_count++;
wait_on_dquot(dquot);
if (!dquot->dq_mnt) {
if (!dquot->dq_sb) {
dquot->dq_count--;
return NODQUOT;
}
......@@ -642,13 +638,12 @@ static struct dquot *dqduplicate(struct dquot *dquot)
static inline int is_quotafile(struct inode *inode)
{
int cnt;
struct vfsmount *vfsmnt;
struct quota_mount_options *dqopt = sb_dqopt(inode->i_sb);
struct file **files;
vfsmnt = lookup_vfsmnt(inode->i_dev);
if (!vfsmnt)
if (!dqopt)
return 0;
files = vfsmnt->mnt_dquot.files;
files = dqopt->files;
for (cnt = 0; cnt < MAXQUOTAS; cnt++)
if (files[cnt] && files[cnt]->f_dentry->d_inode == inode)
return 1;
......@@ -671,13 +666,12 @@ static int dqinit_needed(struct inode *inode, short type)
return 0;
}
static void add_dquot_ref(kdev_t dev, short type)
static void add_dquot_ref(struct super_block *sb, short type)
{
struct super_block *sb = get_super(dev);
struct list_head *p;
struct inode *inode;
if (!sb || !sb->dq_op)
if (!sb->dq_op)
return; /* nothing to do */
restart:
......@@ -804,7 +798,7 @@ static void print_warning(struct dquot *dquot, int flag, const char *fmtstr)
if (!need_print_warning(dquot, flag))
return;
root = dquot->dq_mnt->mnt_sb->s_root;
root = dquot->dq_sb->s_root;
dget(root);
buffer = (char *) __get_free_page(GFP_KERNEL);
path = buffer ? d_path(root, buffer, PAGE_SIZE) : "?";
......@@ -817,7 +811,7 @@ static void print_warning(struct dquot *dquot, int flag, const char *fmtstr)
static inline char ignore_hardlimit(struct dquot *dquot)
{
return capable(CAP_SYS_RESOURCE) && !dquot->dq_mnt->mnt_dquot.rsquash[dquot->dq_type];
return capable(CAP_SYS_RESOURCE) && !dquot->dq_sb->s_dquot.rsquash[dquot->dq_type];
}
static int check_idq(struct dquot *dquot, u_long inodes)
......@@ -844,7 +838,7 @@ static int check_idq(struct dquot *dquot, u_long inodes)
(dquot->dq_curinodes + inodes) > dquot->dq_isoftlimit &&
dquot->dq_itime == 0) {
print_warning(dquot, 0, "%s: warning, %s file quota exceeded\n");
dquot->dq_itime = CURRENT_TIME + dquot->dq_mnt->mnt_dquot.inode_expire[dquot->dq_type];
dquot->dq_itime = CURRENT_TIME + dquot->dq_sb->s_dquot.inode_expire[dquot->dq_type];
}
return QUOTA_OK;
......@@ -877,7 +871,7 @@ static int check_bdq(struct dquot *dquot, u_long blocks, char prealloc)
dquot->dq_btime == 0) {
if (!prealloc) {
print_warning(dquot, 0, "%s: warning, %s disk quota exceeded\n");
dquot->dq_btime = CURRENT_TIME + dquot->dq_mnt->mnt_dquot.block_expire[dquot->dq_type];
dquot->dq_btime = CURRENT_TIME + dquot->dq_sb->s_dquot.block_expire[dquot->dq_type];
}
else
/*
......@@ -894,7 +888,7 @@ static int check_bdq(struct dquot *dquot, u_long blocks, char prealloc)
* Initialize a dquot-struct with new quota info. This is used by the
* system call interface functions.
*/
static int set_dqblk(kdev_t dev, int id, short type, int flags, struct dqblk *dqblk)
static int set_dqblk(struct super_block *sb, int id, short type, int flags, struct dqblk *dqblk)
{
struct dquot *dquot;
int error = -EFAULT;
......@@ -909,7 +903,7 @@ static int set_dqblk(kdev_t dev, int id, short type, int flags, struct dqblk *dq
} else
memcpy((caddr_t)&dq_dqblk, (caddr_t)dqblk, sizeof(struct dqblk));
if ((dquot = dqget(dev, id, type)) != NODQUOT) {
if (sb && (dquot = dqget(sb, id, type)) != NODQUOT) {
lock_dquot(dquot);
if (id > 0 && ((flags & SET_QUOTA) || (flags & SET_QLIMIT))) {
......@@ -923,22 +917,22 @@ static int set_dqblk(kdev_t dev, int id, short type, int flags, struct dqblk *dq
if (dquot->dq_isoftlimit &&
dquot->dq_curinodes < dquot->dq_isoftlimit &&
dq_dqblk.dqb_curinodes >= dquot->dq_isoftlimit)
dquot->dq_itime = CURRENT_TIME + dquot->dq_mnt->mnt_dquot.inode_expire[type];
dquot->dq_itime = CURRENT_TIME + dquot->dq_sb->s_dquot.inode_expire[type];
dquot->dq_curinodes = dq_dqblk.dqb_curinodes;
if (dquot->dq_curinodes < dquot->dq_isoftlimit)
dquot->dq_flags &= ~DQ_INODES;
if (dquot->dq_bsoftlimit &&
dquot->dq_curblocks < dquot->dq_bsoftlimit &&
dq_dqblk.dqb_curblocks >= dquot->dq_bsoftlimit)
dquot->dq_btime = CURRENT_TIME + dquot->dq_mnt->mnt_dquot.block_expire[type];
dquot->dq_btime = CURRENT_TIME + dquot->dq_sb->s_dquot.block_expire[type];
dquot->dq_curblocks = dq_dqblk.dqb_curblocks;
if (dquot->dq_curblocks < dquot->dq_bsoftlimit)
dquot->dq_flags &= ~DQ_BLKS;
}
if (id == 0) {
dquot->dq_mnt->mnt_dquot.block_expire[type] = dquot->dq_btime = dq_dqblk.dqb_btime;
dquot->dq_mnt->mnt_dquot.inode_expire[type] = dquot->dq_itime = dq_dqblk.dqb_itime;
dquot->dq_sb->s_dquot.block_expire[type] = dquot->dq_btime = dq_dqblk.dqb_btime;
dquot->dq_sb->s_dquot.inode_expire[type] = dquot->dq_itime = dq_dqblk.dqb_itime;
}
if (dq_dqblk.dqb_bhardlimit == 0 && dq_dqblk.dqb_bsoftlimit == 0 &&
......@@ -954,14 +948,14 @@ static int set_dqblk(kdev_t dev, int id, short type, int flags, struct dqblk *dq
return(0);
}
static int get_quota(kdev_t dev, int id, short type, struct dqblk *dqblk)
static int get_quota(struct super_block *sb, int id, short type, struct dqblk *dqblk)
{
struct dquot *dquot;
int error = -ESRCH;
if (!dev_has_quota_enabled(dev, type))
if (!sb || !sb_has_quota_enabled(sb, type))
goto out;
dquot = dqget(dev, id, type);
dquot = dqget(sb, id, type);
if (dquot == NODQUOT)
goto out;
......@@ -990,17 +984,16 @@ static int get_stats(caddr_t addr)
return error;
}
static int quota_root_squash(kdev_t dev, short type, int *addr)
static int quota_root_squash(struct super_block *sb, short type, int *addr)
{
struct vfsmount *vfsmnt;
int new_value, error;
if ((vfsmnt = lookup_vfsmnt(dev)) == (struct vfsmount *)NULL)
if (!sb)
return(-ENODEV);
error = -EFAULT;
if (!copy_from_user(&new_value, addr, sizeof(int))) {
vfsmnt->mnt_dquot.rsquash[type] = new_value;
sb_dqopt(sb)->rsquash[type] = new_value;
error = 0;
}
return error;
......@@ -1063,7 +1056,7 @@ void dquot_initialize(struct inode *inode, short type)
id = inode->i_gid;
break;
}
dquot = dqget(inode->i_dev, id, cnt);
dquot = dqget(inode->i_sb, id, cnt);
if (dquot == NODQUOT)
continue;
if (inode->i_dquot[cnt] != NODQUOT) {
......@@ -1219,10 +1212,13 @@ int dquot_transfer(struct dentry *dentry, struct iattr *iattr)
if (!inode)
return -ENOENT;
/* Arguably we could consider that as error, but... no fs - no quota */
if (!inode->i_sb)
return 0;
/*
* Find out if this filesystem uses i_blocks.
*/
if (!inode->i_sb || !inode->i_sb->s_blocksize)
if (!inode->i_sb->s_blocksize)
blocks = isize_to_blocks(inode->i_size, BLOCK_SIZE_BITS);
else
blocks = (inode->i_blocks >> 1);
......@@ -1243,14 +1239,14 @@ int dquot_transfer(struct dentry *dentry, struct iattr *iattr)
if (inode->i_uid == iattr->ia_uid)
continue;
/* We can get transfer_from from inode, can't we? */
transfer_from[cnt] = dqget(inode->i_dev, inode->i_uid, cnt);
transfer_to[cnt] = dqget(inode->i_dev, iattr->ia_uid, cnt);
transfer_from[cnt] = dqget(inode->i_sb, inode->i_uid, cnt);
transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_uid, cnt);
break;
case GRPQUOTA:
if (inode->i_gid == iattr->ia_gid)
continue;
transfer_from[cnt] = dqget(inode->i_dev, inode->i_gid, cnt);
transfer_to[cnt] = dqget(inode->i_dev, iattr->ia_gid, cnt);
transfer_from[cnt] = dqget(inode->i_sb, inode->i_gid, cnt);
transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_gid, cnt);
break;
}
......@@ -1286,7 +1282,7 @@ int dquot_transfer(struct dentry *dentry, struct iattr *iattr)
* dqget() could block and so the first structure might got
* invalidated or locked...
*/
if (!transfer_to[cnt]->dq_mnt || !transfer_from[cnt]->dq_mnt ||
if (!transfer_to[cnt]->dq_sb || !transfer_from[cnt]->dq_sb ||
check_idq(transfer_to[cnt], 1) == NO_QUOTA ||
check_bdq(transfer_to[cnt], blocks, 0) == NO_QUOTA) {
cnt++;
......@@ -1371,26 +1367,26 @@ struct dquot_operations dquot_operations = {
dquot_transfer
};
static inline void set_enable_flags(struct vfsmount *vfsmnt, short type)
static inline void set_enable_flags(struct quota_mount_options *dqopt, short type)
{
switch (type) {
case USRQUOTA:
vfsmnt->mnt_dquot.flags |= DQUOT_USR_ENABLED;
dqopt->flags |= DQUOT_USR_ENABLED;
break;
case GRPQUOTA:
vfsmnt->mnt_dquot.flags |= DQUOT_GRP_ENABLED;
dqopt->flags |= DQUOT_GRP_ENABLED;
break;
}
}
static inline void reset_enable_flags(struct vfsmount *vfsmnt, short type)
static inline void reset_enable_flags(struct quota_mount_options *dqopt, short type)
{
switch (type) {
case USRQUOTA:
vfsmnt->mnt_dquot.flags &= ~DQUOT_USR_ENABLED;
dqopt->flags &= ~DQUOT_USR_ENABLED;
break;
case GRPQUOTA:
vfsmnt->mnt_dquot.flags &= ~DQUOT_GRP_ENABLED;
dqopt->flags &= ~DQUOT_GRP_ENABLED;
break;
}
}
......@@ -1401,38 +1397,36 @@ extern void remove_dquot_ref(kdev_t, short);
/*
* Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
*/
int quota_off(kdev_t dev, short type)
int quota_off(struct super_block *sb, short type)
{
struct vfsmount *vfsmnt;
struct file *filp;
short cnt;
int enabled = 0;
struct quota_mount_options *dqopt = sb_dqopt(sb);
/* We don't need to search for vfsmnt each time - umount has to wait for us */
vfsmnt = lookup_vfsmnt(dev);
if (!vfsmnt || !vfsmnt->mnt_sb)
if (!sb)
goto out;
/* We need to serialize quota_off() for device */
down(&vfsmnt->mnt_dquot.dqoff_sem);
down(&dqopt->dqoff_sem);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (type != -1 && cnt != type)
continue;
if (!is_enabled(vfsmnt, cnt))
if (!is_enabled(dqopt, cnt))
continue;
reset_enable_flags(vfsmnt, cnt);
reset_enable_flags(dqopt, cnt);
/* Note: these are blocking operations */
remove_dquot_ref(dev, cnt);
invalidate_dquots(dev, cnt);
remove_dquot_ref(sb->s_dev, cnt);
invalidate_dquots(sb->s_dev, cnt);
/* Wait for any pending IO - remove me as soon as invalidate is more polite */
down(&vfsmnt->mnt_dquot.dqio_sem);
filp = vfsmnt->mnt_dquot.files[cnt];
vfsmnt->mnt_dquot.files[cnt] = (struct file *)NULL;
vfsmnt->mnt_dquot.inode_expire[cnt] = 0;
vfsmnt->mnt_dquot.block_expire[cnt] = 0;
up(&vfsmnt->mnt_dquot.dqio_sem);
down(&dqopt->dqio_sem);
filp = dqopt->files[cnt];
dqopt->files[cnt] = (struct file *)NULL;
dqopt->inode_expire[cnt] = 0;
dqopt->block_expire[cnt] = 0;
up(&dqopt->dqio_sem);
fput(filp);
}
......@@ -1441,10 +1435,10 @@ int quota_off(kdev_t dev, short type)
* and if not clear the dq_op pointer.
*/
for (cnt = 0; cnt < MAXQUOTAS; cnt++)
enabled |= is_enabled(vfsmnt, cnt);
enabled |= is_enabled(dqopt, cnt);
if (!enabled)
vfsmnt->mnt_sb->dq_op = NULL;
up(&vfsmnt->mnt_dquot.dqoff_sem);
sb->dq_op = NULL;
up(&dqopt->dqoff_sem);
out:
return(0);
}
......@@ -1457,31 +1451,25 @@ static inline int check_quotafile_size(loff_t size)
return !(((blocks % sizeof(struct dqblk)) * BLOCK_SIZE + off % sizeof(struct dqblk)) % sizeof(struct dqblk));
}
int quota_on(kdev_t dev, short type, char *path)
static int quota_on(struct super_block *sb, short type, char *path)
{
struct file *f;
struct vfsmount *vfsmnt;
struct inode *inode;
struct dquot *dquot;
struct quota_mount_options *mnt_dquot;
struct quota_mount_options *dqopt = sb_dqopt(sb);
char *tmp;
int error;
vfsmnt = lookup_vfsmnt(dev);
if (vfsmnt == (struct vfsmount *)NULL)
return -ENODEV;
if (is_enabled(vfsmnt, type))
if (is_enabled(dqopt, type))
return -EBUSY;
mnt_dquot = &vfsmnt->mnt_dquot;
down(&mnt_dquot->dqoff_sem);
down(&dqopt->dqoff_sem);
tmp = getname(path);
error = PTR_ERR(tmp);
if (IS_ERR(tmp))
goto out_lock;
f = filp_open(tmp, O_RDWR, 0600);
f = filp_open(tmp, O_RDWR, 0600, NULL);
putname(tmp);
error = PTR_ERR(f);
......@@ -1499,24 +1487,24 @@ int quota_on(kdev_t dev, short type, char *path)
goto out_f;
dquot_drop(inode); /* We don't want quota on quota files */
set_enable_flags(vfsmnt, type);
mnt_dquot->files[type] = f;
set_enable_flags(dqopt, type);
dqopt->files[type] = f;
dquot = dqget(dev, 0, type);
mnt_dquot->inode_expire[type] = (dquot != NODQUOT) ? dquot->dq_itime : MAX_IQ_TIME;
mnt_dquot->block_expire[type] = (dquot != NODQUOT) ? dquot->dq_btime : MAX_DQ_TIME;
dquot = dqget(sb, 0, type);
dqopt->inode_expire[type] = (dquot != NODQUOT) ? dquot->dq_itime : MAX_IQ_TIME;
dqopt->block_expire[type] = (dquot != NODQUOT) ? dquot->dq_btime : MAX_DQ_TIME;
dqput(dquot);
vfsmnt->mnt_sb->dq_op = &dquot_operations;
add_dquot_ref(dev, type);
sb->dq_op = &dquot_operations;
add_dquot_ref(sb, type);
up(&mnt_dquot->dqoff_sem);
up(&dqopt->dqoff_sem);
return 0;
out_f:
filp_close(f, NULL);
out_lock:
up(&mnt_dquot->dqoff_sem);
up(&dqopt->dqoff_sem);
return error;
}
......@@ -1531,6 +1519,7 @@ asmlinkage long sys_quotactl(int cmd, const char *special, int id, caddr_t addr)
{
int cmds = 0, type = 0, flags = 0;
kdev_t dev;
struct super_block *sb = NULL;
int ret = -EINVAL;
lock_kernel();
......@@ -1575,18 +1564,19 @@ asmlinkage long sys_quotactl(int cmd, const char *special, int id, caddr_t addr)
ret = -ENOTBLK;
if (!S_ISBLK(mode))
goto out;
sb = get_super(dev);
}
ret = -EINVAL;
switch (cmds) {
case Q_QUOTAON:
ret = quota_on(dev, type, (char *) addr);
ret = sb ? quota_on(sb, type, (char *) addr) : -ENODEV;
goto out;
case Q_QUOTAOFF:
ret = quota_off(dev, type);
ret = quota_off(sb, type);
goto out;
case Q_GETQUOTA:
ret = get_quota(dev, id, type, (struct dqblk *) addr);
ret = get_quota(sb, id, type, (struct dqblk *) addr);
goto out;
case Q_SETQUOTA:
flags |= SET_QUOTA;
......@@ -1604,7 +1594,7 @@ asmlinkage long sys_quotactl(int cmd, const char *special, int id, caddr_t addr)
ret = get_stats(addr);
goto out;
case Q_RSQUASH:
ret = quota_root_squash(dev, type, (int *) addr);
ret = quota_root_squash(sb, type, (int *) addr);
goto out;
default:
goto out;
......@@ -1613,8 +1603,8 @@ asmlinkage long sys_quotactl(int cmd, const char *special, int id, caddr_t addr)
flags |= QUOTA_SYSCALL;
ret = -ESRCH;
if (dev_has_quota_enabled(dev, type))
ret = set_dqblk(dev, id, type, flags, (struct dqblk *) addr);
if (sb && sb_has_quota_enabled(sb, type))
ret = set_dqblk(sb, id, type, flags, (struct dqblk *) addr);
out:
unlock_kernel();
return ret;
......
......@@ -775,7 +775,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
bprm_loader.page[i] = NULL;
lock_kernel();
dentry = open_namei(dynloader[0], 0, 0);
dentry = open_namei(dynloader[0]);
unlock_kernel();
retval = PTR_ERR(dentry);
if (IS_ERR(dentry))
......@@ -855,7 +855,7 @@ int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs
memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
lock_kernel();
dentry = open_namei(filename, 0, 0);
dentry = open_namei(filename);
unlock_kernel();
retval = PTR_ERR(dentry);
......@@ -944,7 +944,7 @@ int do_coredump(long signr, struct pt_regs * regs)
#else
corename[4] = '\0';
#endif
file = filp_open(corename, O_CREAT | 2 | O_TRUNC | O_NOFOLLOW, 0600);
file = filp_open(corename, O_CREAT | 2 | O_TRUNC | O_NOFOLLOW, 0600, NULL);
if (IS_ERR(file))
goto fail;
dentry = file->f_dentry;
......
......@@ -609,13 +609,13 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode)
* which is a lot more logical, and also allows the "no perm" needed
* for symlinks (where the permissions are checked later).
*/
struct dentry * open_namei(const char * pathname, int flag, int mode)
struct dentry * __open_namei(const char * pathname, int flag, int mode, struct dentry * dir)
{
int acc_mode, error;
struct inode *inode;
struct dentry *dentry;
dentry = lookup_dentry(pathname, NULL, lookup_flags(flag));
dentry = lookup_dentry(pathname, dir, lookup_flags(flag));
if (IS_ERR(dentry))
return dentry;
......@@ -1012,13 +1012,13 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry)
return error;
}
int do_unlink(const char * name)
int do_unlink(const char * name, struct dentry * base)
{
int error;
struct dentry *dir;
struct dentry *dentry;
dentry = lookup_dentry(name, NULL, 0);
dentry = lookup_dentry(name, base, 0);
error = PTR_ERR(dentry);
if (IS_ERR(dentry))
goto exit;
......@@ -1043,7 +1043,7 @@ asmlinkage long sys_unlink(const char * pathname)
if(IS_ERR(tmp))
return PTR_ERR(tmp);
lock_kernel();
error = do_unlink(tmp);
error = do_unlink(tmp, NULL);
unlock_kernel();
putname(tmp);
......
......@@ -644,7 +644,7 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group)
* for the internal routines (ie open_namei()/follow_link() etc). 00 is
* used by symlinks.
*/
struct file *filp_open(const char * filename, int flags, int mode)
struct file *filp_open(const char * filename, int flags, int mode, struct dentry * base)
{
struct inode * inode;
struct dentry * dentry;
......@@ -661,7 +661,7 @@ struct file *filp_open(const char * filename, int flags, int mode)
flag++;
if (flag & O_TRUNC)
flag |= 2;
dentry = open_namei(filename,flag,mode);
dentry = __open_namei(filename, flag, mode, base);
error = PTR_ERR(dentry);
if (IS_ERR(dentry))
goto cleanup_file;
......@@ -787,7 +787,7 @@ asmlinkage long sys_open(const char * filename, int flags, int mode)
if (fd >= 0) {
struct file * f;
lock_kernel();
f = filp_open(tmp, flags, mode);
f = filp_open(tmp, flags, mode, NULL);
unlock_kernel();
error = PTR_ERR(f);
if (IS_ERR(f))
......
......@@ -247,32 +247,9 @@ static struct file_system_type *get_fs_type(const char *name)
return fs;
}
struct vfsmount *vfsmntlist = NULL;
static struct vfsmount *vfsmnttail = NULL, *mru_vfsmnt = NULL;
/*
* This part handles the management of the list of mounted filesystems.
*/
struct vfsmount *lookup_vfsmnt(kdev_t dev)
{
struct vfsmount *lptr;
if (vfsmntlist == NULL)
return NULL;
if (mru_vfsmnt != NULL && mru_vfsmnt->mnt_dev == dev)
return (mru_vfsmnt);
for (lptr = vfsmntlist; lptr != NULL; lptr = lptr->mnt_next)
if (lptr->mnt_dev == dev) {
mru_vfsmnt = lptr;
return (lptr);
}
return NULL;
}
static struct vfsmount *add_vfsmnt(struct super_block *sb,
const char *dev_name, const char *dir_name)
{
......@@ -286,11 +263,6 @@ static struct vfsmount *add_vfsmnt(struct super_block *sb,
lptr->mnt_sb = sb;
lptr->mnt_dev = sb->s_dev;
lptr->mnt_flags = sb->s_flags;
sema_init(&lptr->mnt_dquot.dqio_sem, 1);
sema_init(&lptr->mnt_dquot.dqoff_sem, 1);
lptr->mnt_dquot.flags = 0;
/* N.B. Is it really OK to have a vfsmount without names? */
if (dev_name && !IS_ERR(tmp = getname(dev_name))) {
......@@ -399,9 +371,9 @@ int get_filesystem_info( char *buf )
len += sprintf( buf + len, "%s %s %s %s",
tmp->mnt_devname, path,
tmp->mnt_sb->s_type->name,
tmp->mnt_flags & MS_RDONLY ? "ro" : "rw" );
tmp->mnt_sb->s_flags & MS_RDONLY ? "ro" : "rw" );
for (fs_infop = fs_info; fs_infop->flag; fs_infop++) {
if (tmp->mnt_flags & fs_infop->flag) {
if (tmp->mnt_sb->s_flags & fs_infop->flag) {
strcpy(buf + len, fs_infop->str);
len += strlen(fs_infop->str);
}
......@@ -592,6 +564,9 @@ static struct super_block * read_super(kdev_t dev, struct block_device *bdev,
sema_init(&s->s_vfs_rename_sem,1);
sema_init(&s->s_nfsd_free_path_sem,1);
s->s_type = type;
sema_init(&s->s_dquot.dqio_sem, 1);
sema_init(&s->s_dquot.dqoff_sem, 1);
s->s_dquot.flags = 0;
lock_super(s);
if (!type->read_super(s, data, silent))
goto out_fail;
......@@ -688,7 +663,7 @@ static struct block_device *do_umount(kdev_t dev, int unmount_root, int flags)
* on the device. If the umount fails, too bad -- there
* are no quotas running any more. Just turn them on again.
*/
DQUOT_OFF(dev);
DQUOT_OFF(sb);
acct_auto_close(dev);
/*
......@@ -990,7 +965,6 @@ int do_mount(struct block_device *bdev, const char *dev_name,
static int do_remount_sb(struct super_block *sb, int flags, char *data)
{
int retval;
struct vfsmount *vfsmnt;
if (!(flags & MS_RDONLY) && sb->s_dev && is_read_only(sb->s_dev))
return -EACCES;
......@@ -1007,9 +981,6 @@ static int do_remount_sb(struct super_block *sb, int flags, char *data)
return retval;
}
sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
vfsmnt = lookup_vfsmnt(sb->s_dev);
if (vfsmnt)
vfsmnt->mnt_flags = sb->s_flags;
/*
* Invalidate the inodes, as some mount options may be changed.
......
......@@ -589,6 +589,7 @@ struct super_block {
struct list_head s_files;
struct block_device *s_bdev;
struct quota_mount_options s_dquot; /* Diskquota specific options */
union {
struct minix_sb_info minix_sb;
......@@ -821,7 +822,7 @@ extern int do_truncate(struct dentry *, loff_t start);
extern int get_unused_fd(void);
extern void put_unused_fd(unsigned int);
extern struct file *filp_open(const char *, int, int);
extern struct file *filp_open(const char *, int, int, struct dentry *);
extern int filp_close(struct file *, fl_owner_t id);
extern char * getname(const char *);
......@@ -936,10 +937,15 @@ extern int notify_change(struct dentry *, struct iattr *);
extern int permission(struct inode *, int);
extern int get_write_access(struct inode *);
extern void put_write_access(struct inode *);
extern struct dentry * open_namei(const char *, int, int);
extern struct dentry * do_mknod(const char *, int, dev_t);
extern int do_pipe(int *);
extern int do_unlink(const char * name);
extern int do_unlink(const char * name, struct dentry *);
extern struct dentry * __open_namei(const char *, int, int, struct dentry *);
static inline struct dentry * open_namei(const char *pathname)
{
return __open_namei(pathname, 0, 0, NULL);
}
/* fs/dcache.c -- generic fs support functions */
extern int is_subdir(struct dentry *, struct dentry *);
......
......@@ -30,14 +30,10 @@ struct vfsmount
kdev_t mnt_dev; /* Device this applies to */
char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
char *mnt_dirname; /* Name of directory mounted on */
unsigned int mnt_flags; /* Flags of this device */
struct super_block *mnt_sb; /* pointer to superblock */
struct quota_mount_options mnt_dquot; /* Diskquota specific mount options */
struct vfsmount *mnt_next; /* pointer to next in linkedlist */
};
struct vfsmount *lookup_vfsmnt(kdev_t dev);
/*
* Umount options
*/
......
......@@ -174,7 +174,7 @@ struct dquot {
int dq_count; /* Reference count */
/* fields after this point are cleared when invalidating */
struct vfsmount *dq_mnt; /* VFS_mount_point this applies to */
struct super_block *dq_sb; /* superblock this applies to */
unsigned int dq_id; /* ID this applies to (uid, gid) */
kdev_t dq_dev; /* Device this applies to */
short dq_type; /* Type of quota */
......
......@@ -20,7 +20,7 @@
extern void dquot_initialize(struct inode *inode, short type);
extern void dquot_drop(struct inode *inode);
extern void invalidate_dquots(kdev_t dev, short type);
extern int quota_off(kdev_t dev, short type);
extern int quota_off(struct super_block *sb, short type);
extern int sync_dquots(kdev_t dev, short type);
extern int dquot_alloc_block(const struct inode *inode, unsigned long number, char prealloc);
......@@ -103,7 +103,7 @@ extern __inline__ int DQUOT_TRANSFER(struct dentry *dentry, struct iattr *iattr)
}
#define DQUOT_SYNC(dev) sync_dquots(dev, -1)
#define DQUOT_OFF(dev) quota_off(dev, -1)
#define DQUOT_OFF(sb) quota_off(sb, -1)
#else
......@@ -118,7 +118,7 @@ extern __inline__ int DQUOT_TRANSFER(struct dentry *dentry, struct iattr *iattr)
#define DQUOT_FREE_BLOCK(sb, inode, nr) do { } while(0)
#define DQUOT_FREE_INODE(sb, inode) do { } while(0)
#define DQUOT_SYNC(dev) do { } while(0)
#define DQUOT_OFF(dev) do { } while(0)
#define DQUOT_OFF(sb) do { } while(0)
/*
* Special case expands to a simple notify_change.
......
......@@ -18,10 +18,8 @@
* 1) It only can handle one directory.
* 2) Because the directory is represented by the SYSV shm array it
* can only be mounted one time.
* 3) This again leads to SYSV shm not working properly in a chrooted
* environment
* 4) Read and write are not implemented (should they?)
* 5) No special nodes are supported
* 3) Read and write are not implemented (should they?)
* 4) No special nodes are supported
*/
#include <linux/config.h>
......@@ -57,8 +55,6 @@ static void shm_delete (struct inode *);
static int shm_mmap (struct file *, struct vm_area_struct *);
static int shm_readdir (struct file *, void *, filldir_t);
char shm_path[256] = "/var/shm";
#define SHM_NAME_LEN NAME_MAX
#define SHM_FMT ".IPC_%08x"
#define SHM_FMT_LEN 13
......@@ -71,7 +67,6 @@ struct shmid_kernel /* private to the kernel */
unsigned long shm_npages; /* size of segment (pages) */
pte_t **shm_dir; /* ptr to arr of ptrs to frames */
int id;
int destroyed; /* set if the final detach kills */
union permap {
struct shmem {
time_t atime;
......@@ -116,7 +111,6 @@ static int newseg (key_t key, const char *name, int namelen, int shmflg, size_t
static void killseg_core(struct shmid_kernel *shp, int doacc);
static void shm_open (struct vm_area_struct *shmd);
static void shm_close (struct vm_area_struct *shmd);
static void shm_remove_name(int id);
static struct page * shm_nopage(struct vm_area_struct *, unsigned long, int);
static int shm_swapout(struct page *, struct file *);
#ifdef CONFIG_PROC_FS
......@@ -312,20 +306,6 @@ static int shm_remount_fs (struct super_block *sb, int *flags, char *data)
return 0;
}
static struct fs_struct *shm_push_root(void)
{
struct fs_struct *old,*new;
new=init_task_union.task.fs;
old=current->fs;
current->fs=new;
return old;
}
static void shm_pop_root(struct fs_struct *saved)
{
current->fs=saved;
}
static void shm_put_super(struct super_block *sb)
{
struct super_block **p = &shm_sb;
......@@ -893,17 +873,6 @@ static inline unsigned long copy_shminfo_to_user(void *buf, struct shminfo64 *in
}
}
char * shm_getname(int id)
{
char *result;
if (!(result = __getname ()))
return ERR_PTR(-ENOMEM);
sprintf (result, "%s/" SHM_FMT, shm_path, id);
return result;
}
asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds *buf)
{
struct shm_setbuf setbuf;
......@@ -1033,36 +1002,15 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds *buf)
}
case IPC_RMID:
{
/*
* We cannot simply remove the file. The SVID states
* that the block remains until the last person
* detaches from it, then is deleted. A shmat() on
* an RMID segment is legal in older Linux and if
* we change it apps break...
*
* Instead we set a destroyed flag, and then blow
* the name away when the usage hits zero.
*/
char name[SHM_FMT_LEN+1];
if ((shmid % SEQ_MULTIPLIER)== zero_id)
return -EINVAL;
sprintf (name, SHM_FMT, shmid);
lock_kernel();
shp = shm_lock(shmid);
if(shp==NULL)
{
unlock_kernel();
return -EINVAL;
}
err=-EIDRM;
if(shm_checkid(shp,shmid)==0)
{
if(shp->shm_nattch==0)
shm_remove_name(shmid);
else
shp->destroyed=1;
err=0;
}
shm_unlock(shmid);
err = do_unlink (name, dget(shm_sb->s_root));
unlock_kernel();
if (err == -ENOENT)
err = -EINVAL;
return err;
}
......@@ -1141,8 +1089,7 @@ asmlinkage long sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
struct file * file;
int err;
int flags;
char *name;
struct fs_struct *saved;
char name[SHM_FMT_LEN+1];
if (!shm_sb || (shmid % SEQ_MULTIPLIER) == zero_id)
return -EINVAL;
......@@ -1159,19 +1106,13 @@ asmlinkage long sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
} else
flags = MAP_SHARED;
name = shm_getname(shmid);
if (IS_ERR (name))
return PTR_ERR (name);
sprintf (name, SHM_FMT, shmid);
lock_kernel();
saved=shm_push_root();
file = filp_open (name, O_RDWR, 0);
shm_pop_root(saved);
putname (name);
if (IS_ERR (file))
file = filp_open(name, O_RDWR, 0, dget(shm_sb->s_root));
if (IS_ERR (file)) {
unlock_kernel();
goto bad_file;
}
*raddr = do_mmap (file, addr, file->f_dentry->d_inode->i_size,
(shmflg & SHM_RDONLY ? PROT_READ :
PROT_READ | PROT_WRITE), flags, 0);
......@@ -1184,7 +1125,6 @@ asmlinkage long sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
return err;
bad_file:
unlock_kernel();
if ((err = PTR_ERR(file)) == -ENOENT)
return -EINVAL;
return err;
......@@ -1196,23 +1136,6 @@ static void shm_open (struct vm_area_struct *shmd)
shm_inc (shmd->vm_file->f_dentry->d_inode->i_ino);
}
/*
* Remove a name. Must be called with lock_kernel
*/
static void shm_remove_name(int id)
{
char *name = shm_getname(id);
if (!IS_ERR(name))
{
struct fs_struct *saved;
saved=shm_push_root();
do_unlink (name);
shm_pop_root(saved);
putname (name);
}
}
/*
* remove the attach descriptor shmd.
* free memory for segment if it is marked destroyed.
......@@ -1230,14 +1153,7 @@ static void shm_close (struct vm_area_struct *shmd)
shp->shm_lprid = current->pid;
shp->shm_dtim = CURRENT_TIME;
shp->shm_nattch--;
if(shp->shm_nattch==0 && shp->destroyed)
{
shp->destroyed=0;
shm_remove_name(id);
shm_unlock(id);
}
else
shm_unlock(id);
shm_unlock(id);
}
/*
......
......@@ -154,7 +154,7 @@ asmlinkage long sys_acct(const char *name)
if (IS_ERR(tmp))
goto out;
/* Difference from BSD - they don't do O_APPEND */
file = filp_open(tmp, O_WRONLY|O_APPEND, 0);
file = filp_open(tmp, O_WRONLY|O_APPEND, 0, NULL);
putname(tmp);
if (IS_ERR(file)) {
error = PTR_ERR(file);
......
......@@ -141,7 +141,7 @@ EXPORT_SYMBOL(iget4);
EXPORT_SYMBOL(iput);
EXPORT_SYMBOL(__namei);
EXPORT_SYMBOL(lookup_dentry);
EXPORT_SYMBOL(open_namei);
EXPORT_SYMBOL(__open_namei);
EXPORT_SYMBOL(sys_close);
EXPORT_SYMBOL(d_alloc_root);
EXPORT_SYMBOL(d_delete);
......
......@@ -57,7 +57,6 @@ extern int sg_big_buff;
#endif
#ifdef CONFIG_SYSVIPC
extern size_t shm_ctlmax;
extern char shm_path[];
extern int msg_ctlmax;
extern int msg_ctlmnb;
extern int msg_ctlmni;
......@@ -199,8 +198,6 @@ static ctl_table kern_table[] = {
{KERN_RTSIGMAX, "rtsig-max", &max_queued_signals, sizeof(int),
0644, NULL, &proc_dointvec},
#ifdef CONFIG_SYSVIPC
{KERN_SHMPATH, "shmpath", &shm_path, 256,
0644, NULL, &proc_dostring, &sysctl_string },
{KERN_SHMMAX, "shmmax", &shm_ctlmax, sizeof (size_t),
0644, NULL, &proc_doulongvec_minmax},
{KERN_MSGMAX, "msgmax", &msg_ctlmax, sizeof (int),
......
......@@ -569,7 +569,7 @@ static unix_socket *unix_find_other(struct sockaddr_un *sunname, int len,
/* Do not believe to VFS, grab kernel lock */
lock_kernel();
dentry = open_namei(sunname->sun_path, 2|O_NOFOLLOW, S_IFSOCK);
dentry = __open_namei(sunname->sun_path, 2|O_NOFOLLOW, S_IFSOCK, NULL);
if (IS_ERR(dentry)) {
*error = PTR_ERR(dentry);
unlock_kernel();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment