Messages in this thread Patch in this message | | | Date | Wed, 10 Dec 1997 14:45:48 +0000 (GMT) | From | Matthew Kirkwood <> | Subject | [PATCH-V3!][2.1.71] BSD revoke() syscall |
| |
On Tue, 9 Dec 1997, Theodore Y. Ts'o wrote:
> You really want to do the close as part of the revoke, and then make the > revoke'd close be pretty much a no-op. (See the tty code, which does > something a bit more complex, but it's the same basic idea.)
Done. (Attached.)
Now, however, when I revoke() a tty, I get the famous old "tty->count != #fd's".
C/A/F/e Matthew.
diff -ruN linux-2.1.71-clean/Makefile linux/Makefile --- linux-2.1.71-clean/Makefile Thu Dec 4 01:14:04 1997 +++ linux/Makefile Tue Dec 9 17:23:54 1997 @@ -11,7 +11,7 @@ # # NOTE! SMP is experimental. See the file Documentation/SMP.txt # -SMP = 1 +# SMP = 1 # # SMP profiling options # SMP_PROF = 1 diff -ruN linux-2.1.71-clean/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S --- linux-2.1.71-clean/arch/i386/kernel/entry.S Tue Dec 2 17:15:11 1997 +++ linux/arch/i386/kernel/entry.S Tue Dec 9 13:10:32 1997 @@ -535,7 +535,8 @@ .long SYMBOL_NAME(sys_rt_sigsuspend) .long SYMBOL_NAME(sys_pread) /* 180 */ .long SYMBOL_NAME(sys_pwrite) + .long SYMBOL_NAME(sys_revoke) - .rept NR_syscalls-181 + .rept NR_syscalls-182 .long SYMBOL_NAME(sys_ni_syscall) .endr diff -ruN linux-2.1.71-clean/fs/Makefile linux/fs/Makefile --- linux-2.1.71-clean/fs/Makefile Tue Dec 2 22:24:04 1997 +++ linux/fs/Makefile Tue Dec 9 13:11:05 1997 @@ -13,7 +13,7 @@ O_OBJS = open.o read_write.o devices.o file_table.o buffer.o \ super.o block_dev.o stat.o exec.o pipe.o namei.o fcntl.o \ ioctl.o readdir.o select.o fifo.o locks.o filesystems.o \ - inode.o dcache.o attr.o bad_inode.o $(BINFMTS) + inode.o dcache.o attr.o bad_inode.o revoke.o $(BINFMTS) MOD_LIST_NAME := FS_MODULES ALL_SUB_DIRS = coda minix ext2 fat msdos vfat proc isofs nfs umsdos \ diff -ruN linux-2.1.71-clean/fs/revoke.c linux/fs/revoke.c --- linux-2.1.71-clean/fs/revoke.c Thu Jan 1 01:00:00 1970 +++ linux/fs/revoke.c Wed Dec 10 12:40:22 1997 @@ -0,0 +1,120 @@ +/* + * linux/fs/revoke.c + * + * Copyright (C) 1997 Matthew Kirkwood + * + */ + +#include <linux/kernel.h> +#include <linux/linkage.h> +#include <linux/sched.h> +#include <linux/errno.h> +#include <linux/smp_lock.h> +#include <linux/fs.h> +#include <linux/malloc.h> + +#include <linux/stat.h> + + +static int ret_ebadf(void) +{ + return -EBADF; +} + +static int revoked_release(struct inode * inode, struct file * filp) +{ + filp->f_op = NULL; + return 0; +} + +static struct file_operations revokedf_ops = { + ret_ebadf, /* llseek */ + ret_ebadf, /* read */ + ret_ebadf, /* write */ + ret_ebadf, /* readdir */ + ret_ebadf, /* poll */ + ret_ebadf, /* ioctl */ + ret_ebadf, /* mmap */ + ret_ebadf, /* open */ + revoked_release, /* release */ + ret_ebadf, /* fsync */ + ret_ebadf, /* fasync */ + ret_ebadf, /* check_media_change */ + ret_ebadf, /* revalidate */ + ret_ebadf, /* lock */ +}; + + +static void do_revoke(struct inode * inode, struct file * filp) +{ + printk("revoking a file!\n"); + +/* Close the file */ + if(filp->f_op->release) + (*filp->f_op->release)(inode, filp); + +/* The file_ops to do what we want... */ + filp->f_op = &revokedf_ops; +} + +asmlinkage int sys_revoke(char * path) +{ +int error; +struct dentry * dentry; +struct inode * inode; +kdev_t dev; +unsigned long inum; + +struct file * filp; + + lock_kernel(); + dentry = namei(path); + + error = PTR_ERR(dentry); + if(IS_ERR(dentry)) + goto out; + + inode = dentry->d_inode; + +/* Check if owner or superuser */ + if( (inode->i_uid != current->uid) + && (inode->i_uid != current->euid) + && !suser()) { + error = -EPERM; + goto dput_out; + } + +/* Why only devices? */ + if(!(inode->i_mode & (S_IFBLK | S_IFCHR))) { + error = -EINVAL; + goto dput_out; + } + +/* + * Now, trawl the file table and see if we can revoke anything. + * + * Should I canonify the name, or is it OK to rely on the dev + * and inode values? + */ + dev = inode->i_dev; + inum = inode->i_ino; + + filp = inuse_filps; + while(filp) { + if(!filp->f_dentry) + continue; + + inode = filp->f_dentry->d_inode; + if((inode->i_dev == dev) && (inode->i_ino == inum)) { + do_revoke(inode,filp); + } + + filp = filp->f_next; + } + +dput_out: + dput(dentry); +out: + unlock_kernel(); + return error; +}
| |