diff -ru --new-file linux-1.0/config.in linux-1.0-quota+acct/config.in --- linux-1.0/config.in Mon Mar 14 22:45:47 1994 +++ linux-1.0-quota+acct/config.in Tue Mar 15 18:20:41 1994 @@ -101,6 +101,7 @@ bool 'ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS y bool 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS n bool 'System V and Coherent filesystem support' CONFIG_SYSV_FS n +bool 'Disk QUOTA support' CONFIG_QUOTA y * * character devices * diff -ru --new-file linux-1.0/drivers/char/tty_io.c linux-1.0-quota+acct/drivers/char/tty_io.c --- linux-1.0/drivers/char/tty_io.c Tue Mar 1 18:00:15 1994 +++ linux-1.0-quota+acct/drivers/char/tty_io.c Tue Mar 15 17:25:50 1994 @@ -235,27 +235,18 @@ tty_release /* hung_up_tty_release */ }; +extern set_tty_fops(dev_t dev, dev_t console, +struct file_operations *tty_fops, struct file_operations *fops); + void do_tty_hangup(struct tty_struct * tty, struct file_operations *fops) { - int i; - struct file * filp; struct task_struct *p; int dev; if (!tty) return; dev = MKDEV(TTY_MAJOR,tty->line); - for (filp = first_file, i=0; if_next) { - if (!filp->f_count) - continue; - if (filp->f_rdev != dev) - continue; - if (filp->f_inode && filp->f_inode->i_rdev == CONSOLE_DEV) - continue; - if (filp->f_op != &tty_fops) - continue; - filp->f_op = fops; - } + set_tty_fops(dev, CONSOLE_DEV, &tty_fops, fops); flush_input(tty); flush_output(tty); wake_up_interruptible(&tty->secondary.proc_list); @@ -289,7 +280,7 @@ do_tty_hangup(tty, &hung_up_tty_fops); } -int tty_hung_up_p(struct file * filp) +int tty_hung_up_p(struct file *filp) { return (filp->f_op == &hung_up_tty_fops); } @@ -1591,8 +1582,8 @@ return 0; } -static int normal_select(struct tty_struct * tty, struct inode * inode, - struct file * file, int sel_type, select_table *wait) +static int normal_select(struct tty_struct *tty, struct inode *inode, + struct file *filp, int sel_type, select_table *wait) { switch (sel_type) { case SEL_IN: @@ -1604,7 +1595,7 @@ return 1; if (tty->flags & (1 << TTY_SLAVE_CLOSED)) return 1; - if (tty_hung_up_p(file)) + if (tty_hung_up_p(filp)) return 1; select_wait(&tty->secondary.proc_list, wait); return 0; @@ -1843,3 +1834,4 @@ kmem_start = rs_init(kmem_start); return kmem_start; } + diff -ru --new-file linux-1.0/fs/ext2/super.c linux-1.0-quota+acct/fs/ext2/super.c --- linux-1.0/fs/ext2/super.c Thu Mar 10 17:48:35 1994 +++ linux-1.0-quota+acct/fs/ext2/super.c Tue Mar 15 17:25:50 1994 @@ -256,10 +256,7 @@ return 0; } } - else { - printk ("EXT2-fs: Unrecognized mount option %s\n", this_char); - return 0; - } + else return 1; } return 1; } diff -ru --new-file linux-1.0/fs/isofs/inode.c linux-1.0-quota+acct/fs/isofs/inode.c --- linux-1.0/fs/isofs/inode.c Sun Mar 13 19:39:14 1994 +++ linux-1.0-quota+acct/fs/isofs/inode.c Tue Mar 15 17:25:50 1994 @@ -115,7 +115,7 @@ if (ivalue != 1024 && ivalue != 2048) return 0; *blocksize = ivalue; } - else return 0; + else return 1; } return 1; } diff -ru --new-file linux-1.0/fs/msdos/inode.c linux-1.0-quota+acct/fs/msdos/inode.c --- linux-1.0/fs/msdos/inode.c Wed Dec 1 13:44:15 1993 +++ linux-1.0-quota+acct/fs/msdos/inode.c Tue Mar 15 17:25:50 1994 @@ -133,7 +133,7 @@ if (value) return 0; *quiet = 1; } - else return 0; + else return 1; } return 1; } diff -ru --new-file linux-1.0/fs/nfs/inode.c linux-1.0-quota+acct/fs/nfs/inode.c --- linux-1.0/fs/nfs/inode.c Wed Dec 1 13:44:15 1993 +++ linux-1.0-quota+acct/fs/nfs/inode.c Tue Mar 15 17:25:50 1994 @@ -18,7 +18,7 @@ #include #include -extern int close_fp(struct file *filp, unsigned int fd); +extern int close_filp(struct file *filp, unsigned int fd); static int nfs_notify_change(int, struct inode *); static void nfs_put_inode(struct inode *); @@ -44,7 +44,7 @@ void nfs_put_super(struct super_block *sb) { /* No locks should be open on this, so 0 should be safe as a fd. */ - close_fp(sb->u.nfs_sb.s_server.file, 0); + close_filp(sb->u.nfs_sb.s_server.file, 0); lock_super(sb); sb->s_dev = 0; unlock_super(sb); diff -ru --new-file linux-1.0/include/linux/fileio.h linux-1.0-quota+acct/include/linux/fileio.h --- linux-1.0/include/linux/fileio.h +++ linux-1.0-quota+acct/include/linux/fileio.h Tue Mar 15 17:25:50 1994 @@ -0,0 +1,93 @@ +/* + * + * Simple VFS definitions for fileio. + * + * Authors: Marco van Wieringen + * Edvard Tuinder + * + * Version: $Id: fileio.h,v 1.4 1994/03/12 16:20:23 mvw Exp mvw $ + * + */ +#ifndef _LINUX_FILEIO_H +#define _LINUX_FILEIO_H + +#include +#include + +#ifdef CONFIG_QUOTA + +int vfs_write(struct inode *ino, struct file *file, char *addr, size_t bytes); +int vfs_create(struct inode *dir, const char *basename, + int namelen, int mode, struct inode **res_ino); +int vfs_truncate(struct inode *ino, size_t lenght); +int vfs_mknod(struct inode *dir, const char *basename, + int namelen, int mode, dev_t dev); +int vfs_mkdir(struct inode *dir, const char *basename, int namelen, int mode); +int vfs_rmdir(struct inode *dir, const char *basename, int namelen); +int vfs_unlink(struct inode *dir, const char *basename, int namelen); +int vfs_symlink(struct inode *dir, const char *basename, + int namelen, const char *oldname); +int vfs_chown(struct inode *ino, uid_t uid, gid_t gid); +int vfs_rename(struct inode *old_dir, const char *old_base, int old_len, + struct inode *new_dir, const char *mew_base, int new_len); + +static inline void vfs_open_filp(struct file *filp) +{ + if (filp->f_inode && S_ISREG(filp->f_inode->i_mode) && (filp->f_mode & 2)) { + filp->f_inode->i_writecount++; + getinoquota(filp->f_inode, -1); + } +} + +static inline void vfs_close_filp(struct file *filp) +{ + if (filp->f_inode && S_ISREG(filp->f_inode->i_mode) && (filp->f_mode & 2)) { + filp->f_inode->i_writecount--; + putinoquota(filp->f_inode); + } +} + +#else /* CONFIG_QUOTA */ + +#define vfs_write(ino, file, addr, bytes) \ +(file)->f_op->write((ino),(file),(addr),(bytes)) + +#define vfs_create(dir, basename, namelen, mode, res_ino) \ +(dir)->i_op->create((dir),(basename),(namelen),(mode),(res_ino)) + +int vfs_truncate(struct inode *ino, size_t lenght); + +#define vfs_mknod(dir, basename, namelen, mode, dev) \ +(dir)->i_op->mknod((dir),(basename),(namelen),(mode),(dev)) + +#define vfs_mkdir(dir, basename, namelen, mode) \ +(dir)->i_op->mkdir((dir),(basename),(namelen),(mode)) + +#define vfs_rmdir(dir, basename, namelen) \ +(dir)->i_op->rmdir((dir),(basename),(namelen)) + +#define vfs_unlink(dir, basename, namelen) \ +(dir)->i_op->unlink((dir),(basename),(namelen)) + +#define vfs_symlink(dir, basename, namelen, oldname) \ +(dir)->i_op->symlink((dir),(basename),(namelen),(oldname)) + +vfs_chown(struct inode *ino, uid_t uid, gid_t gid); + +#define vfs_rename(old_dir, old_base, old_len, new_dir, new_base, new_len) +(dir)->i_op->rename((old_dir),(old_base),(old_len),(new_dir),(new_base),(new_len)) + +static inline void vfs_open_filp(struct file *filp) +{ + if (filp->f_inode && S_ISREG(filp->f_inode->i_mode) && (filp->f_mode & 2)) + filp->f_inode->i_writecount++; +} + +static inline void vfs_close_filp(struct file *filp) +{ + if (filp->f_inode && S_ISREG(filp->f_inode->i_mode) && (filp->f_mode & 2)) + filp->f_inode->i_writecount--; +} + +#endif /* CONFIG_QUOTA */ +#endif /* _LINUX_FILEIO_H */ diff -ru --new-file linux-1.0/include/linux/fs.h linux-1.0-quota+acct/include/linux/fs.h --- linux-1.0/include/linux/fs.h Wed Feb 16 08:29:36 1994 +++ linux-1.0-quota+acct/include/linux/fs.h Tue Mar 15 17:55:58 1994 @@ -12,7 +12,6 @@ #include #include #include -#include /* * It's silly to have NR_OPEN bigger than NR_FILE, but I'll fix @@ -156,33 +155,36 @@ #include #include #include +#include struct inode { - dev_t i_dev; - unsigned long i_ino; - umode_t i_mode; - nlink_t i_nlink; - uid_t i_uid; - gid_t i_gid; - dev_t i_rdev; - off_t i_size; - time_t i_atime; - time_t i_mtime; - time_t i_ctime; - unsigned long i_blksize; - unsigned long i_blocks; + dev_t i_dev; + unsigned long i_ino; + umode_t i_mode; + nlink_t i_nlink; + uid_t i_uid; + gid_t i_gid; + dev_t i_rdev; + off_t i_size; + time_t i_atime; + time_t i_mtime; + time_t i_ctime; + unsigned long i_blksize; + unsigned long i_blocks; struct semaphore i_sem; - struct inode_operations * i_op; - struct super_block * i_sb; - struct wait_queue * i_wait; - struct file_lock * i_flock; - struct vm_area_struct * i_mmap; - struct inode * i_next, * i_prev; - struct inode * i_hash_next, * i_hash_prev; - struct inode * i_bound_to, * i_bound_by; - struct inode * i_mount; - struct socket * i_socket; + struct inode_operations *i_op; + struct super_block *i_sb; + struct wait_queue *i_wait; + struct file_lock *i_flock; + struct vm_area_struct *i_mmap; + struct inode *i_next, *i_prev; + struct inode *i_hash_next, *i_hash_prev; + struct inode *i_bound_to, *i_bound_by; + struct inode *i_mount; + struct socket *i_socket; + struct dquot *i_dquot[MAXQUOTAS]; unsigned short i_count; + unsigned short i_writecount; unsigned short i_flags; unsigned char i_lock; unsigned char i_dirt; @@ -205,14 +207,14 @@ struct file { mode_t f_mode; - dev_t f_rdev; /* needed for /dev/tty */ + dev_t f_rdev; /* needed for /dev/tty */ off_t f_pos; unsigned short f_flags; unsigned short f_count; unsigned short f_reada; struct file *f_next, *f_prev; - struct inode * f_inode; - struct file_operations * f_op; + struct inode *f_inode; + struct file_operations *f_op; }; struct file_lock { @@ -247,8 +249,8 @@ unsigned long s_flags; unsigned long s_magic; unsigned long s_time; - struct inode * s_covered; - struct inode * s_mounted; + struct inode *s_covered; + struct inode *s_mounted; struct wait_queue * s_wait; union { struct minix_sb_info minix_sb; @@ -313,6 +315,9 @@ #ifdef __KERNEL__ +#include + + asmlinkage int sys_open(const char *, int, int); asmlinkage int sys_close(unsigned int); /* yes, it's really unsigned */ diff -ru --new-file linux-1.0/include/linux/mount.h linux-1.0-quota+acct/include/linux/mount.h --- linux-1.0/include/linux/mount.h +++ linux-1.0-quota+acct/include/linux/mount.h Tue Mar 15 17:58:21 1994 @@ -0,0 +1,33 @@ +/* + * + * Definitions for mount interface. This describes the in the kernel build + * linkedlist with mounted filesystems. + * + * Authors: Marco van Wieringen + * Edvard Tuinder + * + * Version: $Id: mount.h,v 1.1 1994/01/09 10:41:52 mvw Exp mvw $ + * + */ +#ifndef _LINUX_MOUNT_H +#define _LINUX_MOUNT_H + +#define QF_OPENING 0x01 +#define QF_CLOSING 0x02 + +struct vfsmount +{ + dev_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 */ + char mnt_flags; /* Flags of this device see above */ + struct super_block *mnt_sb; /* pointer to superblock */ + struct file *mnt_quotas[MAXQUOTAS]; /* fp's to quotafiles */ + time_t mnt_iexp[MAXQUOTAS]; /* expiretime for inodes */ + time_t mnt_bexp[MAXQUOTAS]; /* expiretime for blocks */ + struct vfsmount *mnt_next; /* pointer to next in linkedlist */ +}; + +struct vfsmount *lookup_vfsmnt(dev_t dev); + +#endif /* _LINUX_MOUNT_H */ diff -ru --new-file linux-1.0/include/linux/quota.h linux-1.0-quota+acct/include/linux/quota.h --- linux-1.0/include/linux/quota.h +++ linux-1.0-quota+acct/include/linux/quota.h Tue Mar 15 17:58:14 1994 @@ -0,0 +1,208 @@ +/* + * Copyright (c) 1982, 1986 Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Robert Elz at The University of Melbourne. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Version: $Id: quota.h,v 1.5 1994/01/06 20:45:20 mvw Exp mvw $ + */ + +#ifndef _LINUX_QUOTA_ +#define _LINUX_QUOTA_ + +#include + +/* + * Convert diskblocks to blocks and the other way around. + * currently only to fool the BSD source. :-) + */ +#define dbtob(num) (num << 10) +#define btodb(num) (num >> 10) + +/* + * Definitions for disk quotas imposed on the average user + * (big brother finally hits Linux). + * + * The following constants define the amount of time given a user + * before the soft limits are treated as hard limits (usually resulting + * in an allocation failure). The timer is started when the user crosses + * their soft limit, it is reset when they go below their soft limit. + */ +#define MAX_IQ_TIME 604800 /* (7*24*60*60) 1 week */ +#define MAX_DQ_TIME 604800 /* (7*24*60*60) 1 week */ + +#define MAXQUOTAS 2 +#define USRQUOTA 0 /* element used for user quotas */ +#define GRPQUOTA 1 /* element used for group quotas */ + +/* + * Definitions for the default names of the quotas files. + */ +#define INITQFNAMES { \ + "user", /* USRQUOTA */ \ + "group", /* GRPQUOTA */ \ + "undefined", \ +}; + +#define QUOTAFILENAME "quota" +#define QUOTAGROUP "staff" + +#define NR_DQHASH 43 /* Just an arbitrary number any suggestions ? */ +#define NR_DQUOTS 256 /* Number of quotas active at one time */ + +/* + * Command definitions for the 'quotactl' system call. + * The commands are broken into a main command defined below + * and a subcommand that is used to convey the type of + * quota that is being manipulated (see above). + */ +#define SUBCMDMASK 0x00ff +#define SUBCMDSHIFT 8 +#define QCMD(cmd, type) (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK)) + +#define Q_QUOTAON 0x0100 /* enable quotas */ +#define Q_QUOTAOFF 0x0200 /* disable quotas */ +#define Q_GETQUOTA 0x0300 /* get limits and usage */ +#define Q_SETQUOTA 0x0400 /* set limits and usage */ +#define Q_SETUSE 0x0500 /* set usage */ +#define Q_SYNC 0x0600 /* sync disk copy of a filesystems quotas */ +#define Q_SETQLIM 0x0700 /* set limits */ + +/* + * The following structure defines the format of the disk quota file + * (as it appears on disk) - the file is an array of these structures + * indexed by user or group number. + */ +struct dqblk + { + u_long dqb_bhardlimit; /* absolute limit on disk blks alloc */ + u_long dqb_bsoftlimit; /* preferred limit on disk blks */ + u_long dqb_curblocks; /* current block count */ + u_long dqb_ihardlimit; /* maximum # allocated inodes */ + u_long dqb_isoftlimit; /* preferred inode limit */ + u_long dqb_curinodes; /* current # allocated inodes */ + time_t dqb_btime; /* time limit for excessive disk use */ + time_t dqb_itime; /* time limit for excessive files */ + }; + +/* + * Shorthand notation. + */ +#define dq_bhardlimit dq_dqb.dqb_bhardlimit +#define dq_bsoftlimit dq_dqb.dqb_bsoftlimit +#define dq_curblocks dq_dqb.dqb_curblocks +#define dq_ihardlimit dq_dqb.dqb_ihardlimit +#define dq_isoftlimit dq_dqb.dqb_isoftlimit +#define dq_curinodes dq_dqb.dqb_curinodes +#define dq_btime dq_dqb.dqb_btime +#define dq_itime dq_dqb.dqb_itime + +#define dqoff(UID) ((off_t)((UID) * sizeof (struct dqblk))) + +#ifdef __KERNEL__ + +/* + * Maximum lenght of a message generated in the quota system, + * that needs to be kicked onto the tty. + */ +#define MAX_QUOTA_MESSAGE 75 + +#define DQ_LOCKED 0x01 /* locked for update */ +#define DQ_WANT 0x02 /* wanted for update */ +#define DQ_MOD 0x04 /* dquot modified since read */ +#define DQ_BLKS 0x10 /* uid/gid has been warned about blk limit */ +#define DQ_INODES 0x20 /* uid/gid has been warned about inode limit */ +#define DQ_FAKE 0x40 /* no limits only usage */ + +struct dquot +{ + unsigned int dq_id; /* id this applies to (uid, gid) */ + short dq_type; /* type of quota */ + dev_t dq_dev; /* Device this applies to */ + short dq_flags; /* see DQ_* */ + short dq_count; /* reference count */ + struct vfsmount *dq_mnt; /* vfsmountpoint this applies to */ + struct dqblk dq_dqb; /* diskquota usage */ + struct wait_queue *dq_wait; /* pointer to waitqueue */ + struct dquot *dq_prev; /* pointer to prev dquot */ + struct dquot *dq_next; /* pointer to next dquot */ + struct dquot *dq_hash_prev; /* pointer to prev dquot */ + struct dquot *dq_hash_next; /* pointer to next dquot */ +}; + +#define NODQUOT (struct dquot *)NULL + +/* + * Flags used for set_dqblk. + */ +#define QUOTA_SYSCALL 0x01 +#define SET_QUOTA 0x02 +#define SET_USE 0x04 +#define SET_QLIMIT 0x08 + +/* + * Return values when requesting quota. + */ +#define NO_QUOTA 0 /* no more quota available */ +#define QUOTA_OK 1 /* can allocate the space */ + +/* + * declaration of quota_function calls in kernel. + */ +struct dquot *dqget (dev_t dev, unsigned int id, short type); +void dqput (struct dquot *dquot); + +int quota_off (dev_t dev, short type); +int sync_dquots (dev_t dev, short type); + +u_long isize_to_blocks (size_t isize, size_t blksize); +size_t blocks_to_isize (u_long blocks, size_t blksize); + +void quota_remove (struct inode *inode, u_long inodes, u_long blocks); +int quota_alloc (struct inode *inode, u_long wantedinodes, + u_long wantedblocks, u_long * availblocks); +int quota_transfer (struct inode *inode, uid_t newuid, + gid_t newgid, u_long inodes, u_long blocks); + +void getinoquota (struct inode *inode, short type); +void putinoquota (struct inode *inode); + +#else + +#include + +__BEGIN_DECLS +int quotactl __P ((int, const char *, int, caddr_t)); +__END_DECLS + +#endif /* __KERNEL__ */ +#endif /* _QUOTA_ */ diff -ru --new-file linux-1.0/include/linux/sys.h linux-1.0-quota+acct/include/linux/sys.h --- linux-1.0/include/linux/sys.h Mon Jan 31 15:31:24 1994 +++ linux-1.0-quota+acct/include/linux/sys.h Tue Mar 15 17:26:06 1994 @@ -167,7 +167,6 @@ * but have an entry in the table for future expansion.. */ -#define sys_quotactl sys_ni_syscall #define sys_bdflush sys_ni_syscall typedef int (*fn_ptr)(); diff -ru --new-file linux-1.0/init/main.c linux-1.0-quota+acct/init/main.c --- linux-1.0/init/main.c Mon Feb 7 15:07:01 1994 +++ linux-1.0-quota+acct/init/main.c Tue Mar 15 17:26:06 1994 @@ -98,6 +98,9 @@ #ifdef CONFIG_SYSVIPC extern void ipc_init(void); #endif +#ifdef CONFIG_QUOTA +extern void quota_init(void); +#endif #ifdef CONFIG_SCSI extern unsigned long scsi_dev_init(unsigned long, unsigned long); #endif @@ -411,6 +414,9 @@ #ifdef CONFIG_SYSVIPC ipc_init(); #endif +#ifdef CONFIG_QUOTA + quota_init(); +#endif sti(); /* diff -ru --new-file linux-1.0/kernel/fork.c linux-1.0-quota+acct/kernel/fork.c --- linux-1.0/kernel/fork.c Fri Mar 4 13:11:01 1994 +++ linux-1.0-quota+acct/kernel/fork.c Tue Mar 15 17:57:31 1994 @@ -2,9 +2,7 @@ * linux/kernel/fork.c * * Copyright (C) 1991, 1992 Linus Torvalds - */ - -/* + * * 'fork.c' contains the help-routines for the 'fork' system call * (see also system_call.s). * Fork is rather simple, once you get the hang of it, but the memory @@ -21,6 +19,7 @@ #include #include #include +#include #include #include @@ -84,6 +83,7 @@ new_file->f_count = 0; new_file = NULL; } + vfs_open_filp(new_file); } } return new_file; @@ -203,8 +204,10 @@ p->filp[i] = copy_fd(f); } else { for (i=0; ifilp[i]) != NULL) + if ((f = p->filp[i]) != NULL) { f->f_count++; + vfs_open_filp(f); + } } if (current->pwd) current->pwd->i_count++;