diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-03-12 23:15:27 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-03-12 23:15:27 +0000 |
commit | ae38fd1e4c98588314a42097c5a5e77dcef23561 (patch) | |
tree | f9f10c203bb9e5fbad4810d1f8774c08dfad20ff /fs | |
parent | 466a823d79f41d0713b272e48fd73e494b0588e0 (diff) |
Merge with Linux 2.3.50.
Diffstat (limited to 'fs')
-rw-r--r-- | fs/adfs/dir.c | 8 | ||||
-rw-r--r-- | fs/affs/namei.c | 6 | ||||
-rw-r--r-- | fs/autofs/root.c | 4 | ||||
-rw-r--r-- | fs/binfmt_elf.c | 2 | ||||
-rw-r--r-- | fs/binfmt_em86.c | 4 | ||||
-rw-r--r-- | fs/block_dev.c | 2 | ||||
-rw-r--r-- | fs/buffer.c | 19 | ||||
-rw-r--r-- | fs/coda/dir.c | 10 | ||||
-rw-r--r-- | fs/devfs/base.c | 112 | ||||
-rw-r--r-- | fs/devpts/root.c | 4 | ||||
-rw-r--r-- | fs/exec.c | 3 | ||||
-rw-r--r-- | fs/fat/fatfs_syms.c | 1 | ||||
-rw-r--r-- | fs/fifo.c | 1 | ||||
-rw-r--r-- | fs/hfs/sysdep.c | 10 | ||||
-rw-r--r-- | fs/hpfs/dentry.c | 6 | ||||
-rw-r--r-- | fs/isofs/inode.c | 24 | ||||
-rw-r--r-- | fs/minix/namei.c | 6 | ||||
-rw-r--r-- | fs/msdos/namei.c | 8 | ||||
-rw-r--r-- | fs/namei.c | 217 | ||||
-rw-r--r-- | fs/ncpfs/dir.c | 8 | ||||
-rw-r--r-- | fs/nfs/dir.c | 9 | ||||
-rw-r--r-- | fs/nfsd/nfsfh.c | 5 | ||||
-rw-r--r-- | fs/nfsd/vfs.c | 106 | ||||
-rw-r--r-- | fs/ntfs/fs.c | 1 | ||||
-rw-r--r-- | fs/pipe.c | 19 | ||||
-rw-r--r-- | fs/proc/base.c | 17 | ||||
-rw-r--r-- | fs/proc/generic.c | 5 | ||||
-rw-r--r-- | fs/proc/proc_misc.c | 9 | ||||
-rw-r--r-- | fs/proc/root.c | 3 | ||||
-rw-r--r-- | fs/readdir.c | 73 | ||||
-rw-r--r-- | fs/smbfs/dir.c | 8 | ||||
-rw-r--r-- | fs/udf/udfdecl.h | 1 | ||||
-rw-r--r-- | fs/umsdos/dir.c | 6 | ||||
-rw-r--r-- | fs/vfat/namei.c | 26 |
34 files changed, 329 insertions, 414 deletions
diff --git a/fs/adfs/dir.c b/fs/adfs/dir.c index a7da5eeda..794097871 100644 --- a/fs/adfs/dir.c +++ b/fs/adfs/dir.c @@ -256,12 +256,8 @@ adfs_compare(struct dentry *parent, struct qstr *entry, struct qstr *name) } struct dentry_operations adfs_dentry_operations = { - NULL, /* revalidate */ - adfs_hash, - adfs_compare, - NULL, /* delete = called by dput */ - NULL, /* release - called by d_free */ - NULL /* iput - called by dentry_iput */ + d_hash: adfs_hash, + d_compare: adfs_compare, }; struct dentry *adfs_lookup(struct inode *dir, struct dentry *dentry) diff --git a/fs/affs/namei.c b/fs/affs/namei.c index 43085a64b..38e5bccbe 100644 --- a/fs/affs/namei.c +++ b/fs/affs/namei.c @@ -44,10 +44,8 @@ affs_intl_toupper(unsigned int ch) static int affs_hash_dentry(struct dentry *, struct qstr *); static int affs_compare_dentry(struct dentry *, struct qstr *, struct qstr *); struct dentry_operations affs_dentry_operations = { - NULL, /* d_validate */ - affs_hash_dentry, /* d_hash */ - affs_compare_dentry, /* d_compare */ - NULL /* d_delete */ + d_hash: affs_hash_dentry, + d_compare: affs_compare_dentry, }; /* diff --git a/fs/autofs/root.c b/fs/autofs/root.c index ea517f0b1..35afe3cdc 100644 --- a/fs/autofs/root.c +++ b/fs/autofs/root.c @@ -174,9 +174,7 @@ static int autofs_revalidate(struct dentry * dentry, int flags) } static struct dentry_operations autofs_dentry_operations = { - autofs_revalidate, /* d_revalidate */ - NULL, /* d_hash */ - NULL, /* d_compare */ + d_revalidate: autofs_revalidate, }; static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentry) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 52e9fe7b8..96190fed2 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -715,7 +715,9 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) __MOD_INC_USE_COUNT(current->binfmt->module); #ifndef VM_STACK_FLAGS + lock_kernel(); current->executable = dget(bprm->dentry); + unlock_kernel(); #endif compute_creds(bprm); current->flags &= ~PF_FORKNOEXEC; diff --git a/fs/binfmt_em86.c b/fs/binfmt_em86.c index 2c76e5592..d89bd9ca8 100644 --- a/fs/binfmt_em86.c +++ b/fs/binfmt_em86.c @@ -42,7 +42,9 @@ static int do_load_em86(struct linux_binprm *bprm,struct pt_regs *regs) } bprm->sh_bang++; /* Well, the bang-shell is implicit... */ + lock_kernel(); dput(bprm->dentry); + unlock_kernel(); bprm->dentry = NULL; /* Unlike in the script case, we don't have to do any hairy @@ -78,7 +80,9 @@ static int do_load_em86(struct linux_binprm *bprm,struct pt_regs *regs) * Note that we use open_namei() as the name is now in kernel * space, and we don't need to copy it. */ + lock_kernel(); dentry = open_namei(interp, 0, 0); + unlock_kernel(); if (IS_ERR(dentry)) return PTR_ERR(dentry); diff --git a/fs/block_dev.c b/fs/block_dev.c index 5a202c7e1..c455a735d 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -630,7 +630,7 @@ int blkdev_put(struct block_device *bdev, int kind) /* syncing will go here */ if (kind == BDEV_FILE || kind == BDEV_FS) fsync_dev(rdev); - if (atomic_dec_and_test(&bdev->bd_openers) && MAJOR(rdev) != RAMDISK_MAJOR) { + if (atomic_dec_and_test(&bdev->bd_openers)) { /* invalidating buffers will go here */ invalidate_buffers(rdev); } diff --git a/fs/buffer.c b/fs/buffer.c index 6d31f18e8..4e79483e4 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -2474,6 +2474,7 @@ asmlinkage long sys_bdflush(int func, long data) */ int bdflush(void * unused) { + struct task_struct *tsk = current; int flushed; /* * We have a bare-bones task_struct, and really should fill @@ -2481,17 +2482,17 @@ int bdflush(void * unused) * display semi-sane things. Not real crucial though... */ - current->session = 1; - current->pgrp = 1; - sprintf(current->comm, "kflushd"); - bdflush_tsk = current; + tsk->session = 1; + tsk->pgrp = 1; + strcpy(tsk->comm, "kflushd"); + bdflush_tsk = tsk; /* avoid getting signals */ - spin_lock_irq(¤t->sigmask_lock); - flush_signals(current); - sigfillset(¤t->blocked); - recalc_sigpending(current); - spin_unlock_irq(¤t->sigmask_lock); + spin_lock_irq(&tsk->sigmask_lock); + flush_signals(tsk); + sigfillset(&tsk->blocked); + recalc_sigpending(tsk); + spin_unlock_irq(&tsk->sigmask_lock); for (;;) { CHECK_EMERGENCY_SYNC diff --git a/fs/coda/dir.c b/fs/coda/dir.c index dac8e8884..8e25fccd6 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c @@ -57,10 +57,8 @@ int coda_hasmknod = 0; struct dentry_operations coda_dentry_operations = { - coda_dentry_revalidate, /* revalidate */ - NULL, /* hash */ - NULL, /* compare */ - coda_dentry_delete /* delete */ + d_revalidate: coda_dentry_revalidate, + d_delete: coda_dentry_delete, }; struct inode_operations coda_dir_inode_operations = @@ -541,9 +539,7 @@ int coda_readdir(struct file *file, void *dirent, filldir_t filldir) result = coda_venus_readdir(&open_file, dirent, filldir); } else { /* potemkin case: we are handed a directory inode */ - down(&cnp->c_ovp->i_sem); - result = open_file.f_op->readdir(&open_file, dirent, filldir); - up(&cnp->c_ovp->i_sem); + result = vfs_readdir(&open_file, filldir, dirent); } coda_restore_codafile(inode, file, cnp->c_ovp, &open_file); EXIT; diff --git a/fs/devfs/base.c b/fs/devfs/base.c index ad50e21b9..f2e09cd6e 100644 --- a/fs/devfs/base.c +++ b/fs/devfs/base.c @@ -426,6 +426,12 @@ Removed <devfs_fill_file>. Work sponsored by SGI. v0.92 + 20000306 Richard Gooch <rgooch@atnf.csiro.au> + Added DEVFS_FL_NO_PERSISTENCE flag. + Removed unnecessary call to <update_devfs_inode_from_entry> in + <devfs_readdir>. + Work sponsored by SGI. + v0.93 */ #include <linux/types.h> #include <linux/errno.h> @@ -460,7 +466,7 @@ #include <asm/bitops.h> #include <asm/atomic.h> -#define DEVFS_VERSION "0.92 (20000203)" +#define DEVFS_VERSION "0.93 (20000306)" #ifndef DEVFS_NAME # define DEVFS_NAME "devfs" @@ -601,6 +607,7 @@ struct devfs_entry unsigned char registered:1; unsigned char show_unreg:1; unsigned char hide:1; + unsigned char no_persistence:1; char name[1]; /* This is just a dummy: the allocated array is bigger. This is NULL-terminated */ }; @@ -1240,6 +1247,7 @@ devfs_handle_t devfs_register (devfs_handle_t dir, de->show_unreg = ( (boot_options & OPTION_SHOW) || (flags & DEVFS_FL_SHOW_UNREG) ) ? TRUE : FALSE; de->hide = (flags & DEVFS_FL_HIDE) ? TRUE : FALSE; + de->no_persistence = (flags & DEVFS_FL_NO_PERSISTENCE) ? TRUE : FALSE; devfsd_notify (de, DEVFSD_NOTIFY_REGISTERED, flags & DEVFS_FL_WAIT); return de; } /* End Function devfs_register */ @@ -1983,24 +1991,17 @@ static void update_devfs_inode_from_entry (struct devfs_inode *di) else { if (di->de->u.fcb.auto_owner) - { - mode_t mode = di->de->mode; - - di->mode = (mode & ~S_IALLUGO) | S_IRUGO | S_IWUGO; - } - else - { - di->mode = di->de->mode; - } + di->mode = (di->de->mode & ~S_IALLUGO) | S_IRUGO | S_IWUGO; + else di->mode = di->de->mode; di->uid = di->de->u.fcb.default_uid; di->gid = di->de->u.fcb.default_gid; } } /* End Function update_devfs_inode_from_entry */ -static struct devfs_inode *create_devfs_inode (struct devfs_entry *entry, +static struct devfs_inode *create_devfs_inode (struct devfs_entry *de, struct fs_info *fs_info) /* [SUMMARY] Create a devfs inode entry. - <entry> The devfs entry to associate the new inode with. + <de> The devfs entry to associate the new inode with. <fs_info> The FS info. [RETURNS] A pointer to the devfs inode on success, else NULL. */ @@ -2032,12 +2033,12 @@ static struct devfs_inode *create_devfs_inode (struct devfs_entry *entry, di->nlink = 1; fs_info->table[fs_info->num_inodes] = di; ++fs_info->num_inodes; - di->de = entry; + di->de = de; di->fs_info = fs_info; - di->prev = entry->last_inode; - if (entry->first_inode == NULL) entry->first_inode = di; - else entry->last_inode->next = di; - entry->last_inode = di; + di->prev = de->last_inode; + if (de->first_inode == NULL) de->first_inode = di; + else de->last_inode->next = di; + de->last_inode = di; update_devfs_inode_from_entry (di); #ifdef CONFIG_DEVFS_DEBUG if (devfs_debug & DEBUG_I_CREATE) @@ -2183,8 +2184,9 @@ static int get_removable_partition (struct devfs_entry *dir, const char *name, /* Superblock operations follow */ -extern struct inode_operations devfs_iops; +static struct inode_operations devfs_iops; static struct file_operations devfs_fops; +static struct inode_operations devfs_symlink_iops; static void devfs_read_inode (struct inode *inode) { @@ -2206,22 +2208,29 @@ static void devfs_read_inode (struct inode *inode) inode->i_blocks = 0; inode->i_blksize = 1024; inode->i_op = &devfs_iops; - inode->i_fop = &devfs_fops; inode->i_rdev = NODEV; - if ( S_ISCHR (di->mode) ) + if ( S_ISCHR (di->mode) ) { inode->i_rdev = MKDEV (di->de->u.fcb.u.device.major, di->de->u.fcb.u.device.minor); - else if ( S_ISBLK (di->mode) ) - { + inode->i_fop = &devfs_fops; + } else if ( S_ISBLK (di->mode) ) { inode->i_rdev = MKDEV (di->de->u.fcb.u.device.major, di->de->u.fcb.u.device.minor); inode->i_bdev = bdget (inode->i_rdev); if (inode->i_bdev) inode->i_bdev->bd_op = di->de->u.fcb.ops; else printk ("%s: read_inode(%d): no block device from bdget()\n", DEVFS_NAME, (int) inode->i_ino); + inode->i_fop = &devfs_fops; + } else if ( S_ISFIFO (di->mode) ) { + inode->i_fop = &def_fifo_fops; + } else if ( S_ISREG (di->mode) ) { + inode->i_size = di->de->u.fcb.u.file.size; + inode->i_fop = &devfs_fops; + } else if (S_ISLNK(di->mode)) { + inode->i_op = &devfs_symlink_iops; + } else { + inode->i_fop = &devfs_fops; } - else if ( S_ISFIFO (di->mode) ) inode->i_fop = &def_fifo_fops; - else if ( S_ISREG (di->mode) ) inode->i_size = di->de->u.fcb.u.file.size; inode->i_mode = di->mode; inode->i_uid = di->uid; inode->i_gid = di->gid; @@ -2438,11 +2447,10 @@ static int devfs_readdir (struct file *file, void *dirent, filldir_t filldir) if (di == NULL) { if (fs_info->require_explicit) continue; - /* Have to create the inode right now */ + /* Have to create the inode right now to get the inum */ di = create_devfs_inode (de, fs_info); if (di == NULL) return -ENOMEM; } - else if (di->ctime == 0) update_devfs_inode_from_entry (di); err = (*filldir) (dirent, de->name, de->namelen, file->f_pos, di->ino); if (err == -EINVAL) break; @@ -2659,6 +2667,7 @@ static int devfs_d_revalidate_wait (struct dentry *dentry, int flags) /* Create an inode, now that the driver information is available */ if (di == NULL) di = create_devfs_inode (de, fs_info); + else if (de->no_persistence) update_devfs_inode_from_entry (di); else if (di->ctime == 0) update_devfs_inode_from_entry (di); else di->mode = (de->mode & ~S_IALLUGO) | (di->mode & S_IALLUGO); if (di == NULL) return 1; @@ -2784,6 +2793,7 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry) } /* Create an inode, now that the driver information is available */ if (di == NULL) di = create_devfs_inode (de, fs_info); + else if (de->no_persistence) update_devfs_inode_from_entry (di); else if (di->ctime == 0) update_devfs_inode_from_entry (di); else di->mode = (de->mode & ~S_IALLUGO) | (di->mode & S_IALLUGO); if (di == NULL) return ERR_PTR (-ENOMEM); @@ -3079,49 +3089,24 @@ static int devfs_mknod (struct inode *dir, struct dentry *dentry, int mode, static int devfs_readlink (struct dentry *dentry, char *buffer, int buflen) { - struct inode *inode = dentry->d_inode; - struct devfs_inode *di; + struct devfs_inode *di=get_devfs_inode_from_vfs_inode(dentry->d_inode); + char *name = ERR_PTR(-ENOENT); - if ( !inode || !S_ISLNK (inode->i_mode) ) return -EINVAL; - di = get_devfs_inode_from_vfs_inode (inode); - if (di == NULL) return -ENOENT; - if (!di->de->registered) return -ENOENT; -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_I_RLINK) - printk ("%s: readlink(): dentry: %p\n", DEVFS_NAME, dentry); -#endif - if (buflen > di->de->u.symlink.length + 1) - buflen = di->de->u.symlink.length + 1; - if (copy_to_user (buffer, di->de->u.symlink.linkname, buflen) == 0) - return buflen; - return -EFAULT; + if (di && di->de->registered) + name = di->de->u.symlink.linkname; + return vfs_readlink(dentry, buffer, buflen, name); } /* End Function devfs_readlink */ static struct dentry *devfs_follow_link (struct dentry *dentry, struct dentry *base, unsigned int follow) { - struct inode *inode = dentry->d_inode; - struct devfs_inode *di; + struct devfs_inode *di=get_devfs_inode_from_vfs_inode(dentry->d_inode); + char *name = ERR_PTR(-ENOENT); - if ( !inode || !S_ISLNK (inode->i_mode) ) - { - dget (dentry); - dput (base); - return dentry; - } -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_I_FLINK) - printk ("%s: follow_link(): dentry: %p\n", DEVFS_NAME, dentry); -#endif - di = get_devfs_inode_from_vfs_inode (inode); - if ( (di == NULL) || !di->de->registered ) - { - dput (base); - return ERR_PTR (-ENOENT); - } - base = lookup_dentry (di->de->u.symlink.linkname, base, follow); - return base; + if (di && di->de->registered) + name = di->de->u.symlink.linkname; + return vfs_follow_link(dentry, base, follow, name); } /* End Function devfs_follow_link */ static struct inode_operations devfs_iops = @@ -3133,6 +3118,11 @@ static struct inode_operations devfs_iops = mkdir: devfs_mkdir, rmdir: devfs_rmdir, mknod: devfs_mknod, + setattr: devfs_notify_change, +}; + +static struct inode_operations devfs_symlink_iops = +{ readlink: devfs_readlink, follow_link: devfs_follow_link, setattr: devfs_notify_change, diff --git a/fs/devpts/root.c b/fs/devpts/root.c index ed6258663..93df8a8ec 100644 --- a/fs/devpts/root.c +++ b/fs/devpts/root.c @@ -30,9 +30,7 @@ struct inode_operations devpts_root_inode_operations = { }; static struct dentry_operations devpts_dentry_operations = { - devpts_revalidate, /* d_revalidate */ - NULL, /* d_hash */ - NULL, /* d_compare */ + d_revalidate: devpts_revalidate, }; /* @@ -84,6 +84,7 @@ int open_dentry(struct dentry * dentry, int mode) struct list_head * l = NULL; int fd, error; + lock_kernel(); if (inode->i_sb) l = &inode->i_sb->s_files; @@ -111,6 +112,7 @@ int open_dentry(struct dentry * dentry, int mode) fd_install(fd, f); dget(dentry); } + unlock_kernel(); return fd; out_filp: @@ -120,6 +122,7 @@ out_filp: out_fd: put_unused_fd(fd); out: + unlock_kernel(); return error; } diff --git a/fs/fat/fatfs_syms.c b/fs/fat/fatfs_syms.c index b8bcbd9e6..3a2e4ea82 100644 --- a/fs/fat/fatfs_syms.c +++ b/fs/fat/fatfs_syms.c @@ -52,6 +52,7 @@ EXPORT_SYMBOL(unlock_fat); EXPORT_SYMBOL(fat_dir_ioctl); EXPORT_SYMBOL(fat_add_entries); EXPORT_SYMBOL(fat_dir_empty); +EXPORT_SYMBOL(fat_truncate); int init_fat_fs(void) { @@ -41,6 +41,7 @@ static int fifo_open(struct inode *inode, struct file *filp) PIPE_BASE(*inode) = (char *) page; PIPE_START(*inode) = PIPE_LEN(*inode) = 0; PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0; + PIPE_WAITING_WRITERS(*inode) = PIPE_WAITING_READERS(*inode) = 0; } switch (filp->f_mode) { diff --git a/fs/hfs/sysdep.c b/fs/hfs/sysdep.c index fb68e9ab2..0caa01ad0 100644 --- a/fs/hfs/sysdep.c +++ b/fs/hfs/sysdep.c @@ -24,12 +24,10 @@ static int hfs_compare_dentry(struct dentry *, struct qstr *, struct qstr *); static void hfs_dentry_iput(struct dentry *, struct inode *); struct dentry_operations hfs_dentry_operations = { - hfs_revalidate_dentry, /* d_revalidate(struct dentry *) */ - hfs_hash_dentry, /* d_hash */ - hfs_compare_dentry, /* d_compare */ - NULL, /* d_delete(struct dentry *) */ - NULL, /* d_release(struct dentry *) */ - hfs_dentry_iput /* d_iput(struct dentry *, struct inode *) */ + d_revalidate: hfs_revalidate_dentry, + d_hash: hfs_hash_dentry, + d_compare: hfs_compare_dentry, + d_iput: hfs_dentry_iput, }; /* diff --git a/fs/hpfs/dentry.c b/fs/hpfs/dentry.c index b5c3cf2e8..3aad4ba50 100644 --- a/fs/hpfs/dentry.c +++ b/fs/hpfs/dentry.c @@ -50,10 +50,8 @@ int hpfs_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b) } struct dentry_operations hpfs_dentry_operations = { - NULL, /* d_validate */ - hpfs_hash_dentry, /* d_hash */ - hpfs_compare_dentry, /* d_compare */ - NULL /* d_delete */ + d_hash: hpfs_hash_dentry, + d_compare: hpfs_compare_dentry, }; void hpfs_set_dentry_operations(struct dentry *dentry) diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index b4a633e9f..996d5ba68 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -84,29 +84,21 @@ static struct super_operations isofs_sops = { static struct dentry_operations isofs_dentry_ops[] = { { - NULL, /* d_revalidate */ - isofs_hash, - isofs_cmp, - NULL /* d_delete */ + d_hash: isofs_hash, + d_compare: isofs_cmp, }, { - NULL, /* d_revalidate */ - isofs_hashi, - isofs_cmpi, - NULL /* d_delete */ + d_hash: isofs_hashi, + d_compare: isofs_cmpi, }, #ifdef CONFIG_JOLIET { - NULL, /* d_revalidate */ - isofs_hash_ms, - isofs_cmp_ms, - NULL /* d_delete */ + d_hash: isofs_hash_ms, + d_compare: isofs_cmp_ms, }, { - NULL, /* d_revalidate */ - isofs_hashi_ms, - isofs_cmpi_ms, - NULL /* d_delete */ + d_hash: isofs_hashi_ms, + d_compare: isofs_cmpi_ms, } #endif }; diff --git a/fs/minix/namei.c b/fs/minix/namei.c index baef110d2..c18b46a37 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c @@ -106,13 +106,9 @@ static int minix_hash(struct dentry *dentry, struct qstr *qstr) #endif struct dentry_operations minix_dentry_operations = { - 0, /* revalidate */ #ifndef NO_TRUNCATE - minix_hash, -#else - 0, + d_hash: minix_hash, #endif - 0 /* compare */ }; static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry) diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c index d74c71049..87a49fb47 100644 --- a/fs/msdos/namei.c +++ b/fs/msdos/namei.c @@ -200,12 +200,8 @@ old_compare: static struct dentry_operations msdos_dentry_operations = { - NULL, /* d_revalidate */ - msdos_hash, - msdos_cmp, - NULL, /* d_delete */ - NULL, - NULL + d_hash: msdos_hash, + d_compare: msdos_cmp, }; /* diff --git a/fs/namei.c b/fs/namei.c index 102f0e432..5f148b5a8 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -403,10 +403,10 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, unsigned if (IS_ERR(dentry)) break; } - } - /* Check mountpoints.. */ - dentry = follow_mount(dentry); + /* Check mountpoints.. */ + dentry = follow_mount(dentry); + } base = do_follow_link(base, dentry, flags); if (IS_ERR(base)) @@ -577,6 +577,9 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode) { int error; + mode &= S_IALLUGO & ~current->fs->umask; + mode |= S_IFREG; + error = may_create(dir, dentry); if (error) goto exit_lock; @@ -610,9 +613,6 @@ struct dentry * open_namei(const char * pathname, int flag, int mode) struct inode *inode; struct dentry *dentry; - mode &= S_IALLUGO & ~current->fs->umask; - mode |= S_IFREG; - dentry = lookup_dentry(pathname, NULL, lookup_flags(flag)); if (IS_ERR(dentry)) return dentry; @@ -739,14 +739,36 @@ exit: return ERR_PTR(error); } +int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) +{ + int error = -EPERM; + + mode &= ~current->fs->umask; + + if (!S_ISFIFO(mode) && !capable(CAP_MKNOD)) + goto exit_lock; + + error = may_create(dir, dentry); + if (error) + goto exit_lock; + + error = -EPERM; + if (!dir->i_op || !dir->i_op->mknod) + goto exit_lock; + + DQUOT_INIT(dir); + error = dir->i_op->mknod(dir, dentry, mode, dev); +exit_lock: + return error; +} + struct dentry * do_mknod(const char * filename, int mode, dev_t dev) { int error; struct dentry *dir; struct dentry *dentry, *retval; - mode &= ~current->fs->umask; - dentry = lookup_dentry(filename, NULL, LOOKUP_FOLLOW); + dentry = lookup_dentry(filename, NULL, 0); if (IS_ERR(dentry)) return dentry; @@ -755,16 +777,8 @@ struct dentry * do_mknod(const char * filename, int mode, dev_t dev) if (!check_parent(dir, dentry)) goto exit_lock; - error = may_create(dir->d_inode, dentry); - if (error) - goto exit_lock; + error = vfs_mknod(dir->d_inode, dentry, mode, dev); - error = -EPERM; - if (!dir->d_inode->i_op || !dir->d_inode->i_op->mknod) - goto exit_lock; - - DQUOT_INIT(dir->d_inode); - error = dir->d_inode->i_op->mknod(dir->d_inode, dentry, mode, dev); exit_lock: retval = ERR_PTR(error); if (!error) @@ -778,47 +792,66 @@ asmlinkage long sys_mknod(const char * filename, int mode, dev_t dev) { int error; char * tmp; - struct dentry * dentry; + struct dentry * dentry, *dir; - if (S_ISDIR(mode) || (!S_ISFIFO(mode) && !capable(CAP_MKNOD))) + if (S_ISDIR(mode)) return -EPERM; tmp = getname(filename); if (IS_ERR(tmp)) return PTR_ERR(tmp); - error = -EINVAL; lock_kernel(); + dentry = lookup_dentry(tmp, NULL, 0); + error = PTR_ERR(dentry); + if (IS_ERR(dentry)) + goto out; + dir = lock_parent(dentry); + error = -ENOENT; + if (!check_parent(dir, dentry)) + goto out_unlock; switch (mode & S_IFMT) { - case 0: - mode |= S_IFREG; /* fallthrough */ - case S_IFREG: - mode &= ~current->fs->umask; - dentry = lookup_dentry(filename, NULL, LOOKUP_FOLLOW); - if (IS_ERR(dentry)) - error = PTR_ERR(dentry); - else { - struct dentry *dir = lock_parent(dentry); - error = -ENOENT; - if (check_parent(dir, dentry)) - error = vfs_create(dir->d_inode, dentry, mode); - dput(dentry); - } + case 0: case S_IFREG: + error = vfs_create(dir->d_inode, dentry, mode); break; case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK: - dentry = do_mknod(tmp,mode,dev); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - dput(dentry); - error = 0; - } + error = vfs_mknod(dir->d_inode, dentry, mode, dev); break; + case S_IFDIR: + error = -EPERM; + break; + default: + error = -EINVAL; } +out_unlock: + unlock_dir(dir); + dput(dentry); +out: unlock_kernel(); putname(tmp); return error; } +int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) +{ + int error; + + error = may_create(dir, dentry); + if (error) + goto exit_lock; + + error = -EPERM; + if (!dir->i_op || !dir->i_op->mkdir) + goto exit_lock; + + DQUOT_INIT(dir); + mode &= (S_IRWXUGO|S_ISVTX) & ~current->fs->umask; + error = dir->i_op->mkdir(dir, dentry, mode); + +exit_lock: + return error; +} + static inline int do_mkdir(const char * pathname, int mode) { int error; @@ -843,17 +876,7 @@ static inline int do_mkdir(const char * pathname, int mode) if (!check_parent(dir, dentry)) goto exit_lock; - error = may_create(dir->d_inode, dentry); - if (error) - goto exit_lock; - - error = -EPERM; - if (!dir->d_inode->i_op || !dir->d_inode->i_op->mkdir) - goto exit_lock; - - DQUOT_INIT(dir->d_inode); - mode &= (S_IRWXUGO|S_ISVTX) & ~current->fs->umask; - error = dir->d_inode->i_op->mkdir(dir->d_inode, dentry, mode); + error = vfs_mkdir(dir->d_inode, dentry, mode); exit_lock: unlock_dir(dir); @@ -1027,6 +1050,25 @@ asmlinkage long sys_unlink(const char * pathname) return error; } +int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) +{ + int error; + + error = may_create(dir, dentry); + if (error) + goto exit_lock; + + error = -EPERM; + if (!dir->i_op || !dir->i_op->symlink) + goto exit_lock; + + DQUOT_INIT(dir); + error = dir->i_op->symlink(dir, dentry, oldname); + +exit_lock: + return error; +} + static inline int do_symlink(const char * oldname, const char * newname) { int error; @@ -1044,16 +1086,7 @@ static inline int do_symlink(const char * oldname, const char * newname) if (!check_parent(dir, dentry)) goto exit_lock; - error = may_create(dir->d_inode, dentry); - if (error) - goto exit_lock; - - error = -EPERM; - if (!dir->d_inode->i_op || !dir->d_inode->i_op->symlink) - goto exit_lock; - - DQUOT_INIT(dir->d_inode); - error = dir->d_inode->i_op->symlink(dir->d_inode, dentry, oldname); + error = vfs_symlink(dir->d_inode, dentry, oldname); exit_lock: unlock_dir(dir); @@ -1083,10 +1116,43 @@ asmlinkage long sys_symlink(const char * oldname, const char * newname) return error; } +int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) +{ + struct inode *inode; + int error; + + error = -ENOENT; + inode = old_dentry->d_inode; + if (!inode) + goto exit_lock; + + error = may_create(dir, new_dentry); + if (error) + goto exit_lock; + + error = -EXDEV; + if (dir->i_dev != inode->i_dev) + goto exit_lock; + + /* + * A link to an append-only or immutable file cannot be created. + */ + error = -EPERM; + if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) + goto exit_lock; + if (!dir->i_op || !dir->i_op->link) + goto exit_lock; + + DQUOT_INIT(dir); + error = dir->i_op->link(old_dentry, dir, new_dentry); + +exit_lock: + return error; +} + static inline int do_link(const char * oldname, const char * newname) { struct dentry *old_dentry, *new_dentry, *dir; - struct inode *inode; int error; /* @@ -1113,32 +1179,7 @@ static inline int do_link(const char * oldname, const char * newname) if (!check_parent(dir, new_dentry)) goto exit_lock; - error = -ENOENT; - inode = old_dentry->d_inode; - if (!inode) - goto exit_lock; - - error = may_create(dir->d_inode, new_dentry); - if (error) - goto exit_lock; - - error = -EXDEV; - if (dir->d_inode->i_dev != inode->i_dev) - goto exit_lock; - - /* - * A link to an append-only or immutable file cannot be created. - */ - error = -EPERM; - if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) - goto exit_lock; - - error = -EPERM; - if (!dir->d_inode->i_op || !dir->d_inode->i_op->link) - goto exit_lock; - - DQUOT_INIT(dir->d_inode); - error = dir->d_inode->i_op->link(old_dentry, dir->d_inode, new_dentry); + error = vfs_link(old_dentry, dir->d_inode, new_dentry); exit_lock: unlock_dir(dir); diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 5c23664e3..ae5c13962 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c @@ -75,10 +75,10 @@ static void ncp_delete_dentry(struct dentry *); struct dentry_operations ncp_dentry_operations = { - ncp_lookup_validate, /* d_revalidate(struct dentry *, int) */ - ncp_hash_dentry, /* d_hash */ - ncp_compare_dentry, /* d_compare */ - ncp_delete_dentry /* d_delete(struct dentry *) */ + d_revalidate: ncp_lookup_validate, + d_hash: ncp_hash_dentry, + d_compare: ncp_compare_dentry, + d_delete: ncp_delete_dentry, }; diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 9dfc2f055..d111076c0 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -654,12 +654,9 @@ static void nfs_dentry_release(struct dentry *dentry) } struct dentry_operations nfs_dentry_operations = { - nfs_lookup_revalidate, /* d_revalidate(struct dentry *, int) */ - NULL, /* d_hash */ - NULL, /* d_compare */ - nfs_dentry_delete, /* d_delete(struct dentry *) */ - nfs_dentry_release, /* d_release(struct dentry *) */ - NULL /* d_iput */ + d_revalidate: nfs_lookup_revalidate, + d_delete: nfs_dentry_delete, + d_release: nfs_dentry_release, }; #if 0 /* dead code */ diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index aa03c0a16..084a17d9b 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -63,7 +63,10 @@ dprintk("filldir_one: seq=%d, ino=%ld, name=%s\n", buf->sequence, ino, name); } /* - * Read a directory and return the name of the specified entry. i_sem is already down(). + * Read a directory and return the name of the specified entry. + * i_sem is already down(). + * The whole thing is a total BS. It should not be done via readdir(), damnit! + * Oh, well, as soon as it will be in filesystems... */ static int get_ino_name(struct dentry *dentry, struct qstr *name, unsigned long ino) { diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 55c351852..c8389381f 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -801,7 +801,6 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, { struct dentry *dentry, *dchild; struct inode *dirp; - nfsd_dirop_t opfunc = NULL; int err; err = nfserr_perm; @@ -856,45 +855,31 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, goto out; } + if (!(iap->ia_valid & ATTR_MODE)) + iap->ia_mode = 0; + iap->ia_mode = (iap->ia_mode & S_IALLUGO) | type; + /* * Get the dir op function pointer. */ err = nfserr_perm; switch (type) { case S_IFREG: - opfunc = (nfsd_dirop_t) dirp->i_op->create; + err = vfs_create(dirp, dchild, iap->ia_mode); break; case S_IFDIR: - opfunc = (nfsd_dirop_t) dirp->i_op->mkdir; + err = vfs_mkdir(dirp, dchild, iap->ia_mode); break; case S_IFCHR: case S_IFBLK: - /* The client is _NOT_ required to do security enforcement */ - if(!capable(CAP_SYS_ADMIN)) - { - err = -EPERM; - goto out; - } case S_IFIFO: case S_IFSOCK: - opfunc = dirp->i_op->mknod; + err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); break; default: printk("nfsd: bad file type %o in nfsd_create\n", type); - err = nfserr_inval; + err = -EINVAL; } - if (!opfunc) - goto out; - - if (!(iap->ia_valid & ATTR_MODE)) - iap->ia_mode = 0; - iap->ia_mode = (iap->ia_mode & S_IALLUGO) | type; - - /* - * Call the dir op function to create the object. - */ - DQUOT_INIT(dirp); - err = opfunc(dirp, dchild, iap->ia_mode, rdev); if (err < 0) goto out_nfserr; @@ -954,9 +939,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, err = nfserr_notdir; if(!dirp->i_op || !dirp->i_op->lookup) goto out; - err = nfserr_perm; - if(!dirp->i_op->create) - goto out; /* * Compose the response file handle. @@ -1003,7 +985,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, goto out; } - err = dirp->i_op->create(dirp, dchild, iap->ia_mode); + err = vfs_create(dirp, dchild, iap->ia_mode); if (err < 0) goto out_nfserr; @@ -1101,7 +1083,6 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap) { struct dentry *dentry, *dnew; - struct inode *dirp; int err; err = nfserr_noent; @@ -1113,11 +1094,6 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, goto out; dentry = fhp->fh_dentry; - err = nfserr_perm; - dirp = dentry->d_inode; - if (!dirp->i_op || !dirp->i_op->symlink) - goto out; - dnew = lookup_dentry(fname, dget(dentry), 0); err = PTR_ERR(dnew); if (IS_ERR(dnew)) @@ -1130,27 +1106,23 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, if (err) goto out_compose; - err = nfserr_exist; - if (!dnew->d_inode) { - DQUOT_INIT(dirp); - err = dirp->i_op->symlink(dirp, dnew, path); - if (!err) { - if (EX_ISSYNC(fhp->fh_export)) - nfsd_sync_dir(dentry); - if (iap) { - iap->ia_valid &= ATTR_MODE /* ~(ATTR_MODE|ATTR_UID|ATTR_GID)*/; - if (iap->ia_valid) { - iap->ia_valid |= ATTR_CTIME; - iap->ia_mode = (iap->ia_mode&S_IALLUGO) - | S_IFLNK; - err = notify_change(dnew, iap); - if (!err && EX_ISSYNC(fhp->fh_export)) - write_inode_now(dentry->d_inode); - } - } - } else - err = nfserrno(-err); - } + err = vfs_symlink(dentry->d_inode, dnew, path); + if (!err) { + if (EX_ISSYNC(fhp->fh_export)) + nfsd_sync_dir(dentry); + if (iap) { + iap->ia_valid &= ATTR_MODE /* ~(ATTR_MODE|ATTR_UID|ATTR_GID)*/; + if (iap->ia_valid) { + iap->ia_valid |= ATTR_CTIME; + iap->ia_mode = (iap->ia_mode&S_IALLUGO) + | S_IFLNK; + err = notify_change(dnew, iap); + if (!err && EX_ISSYNC(fhp->fh_export)) + write_inode_now(dentry->d_inode); + } + } + } else + err = nfserrno(-err); fh_unlock(fhp); /* Compose the fh so the dentry will be freed ... */ @@ -1201,34 +1173,22 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, if (err) goto out_dput; - err = nfserr_exist; - if (dnew->d_inode) - goto out_unlock; - dold = tfhp->fh_dentry; dest = dold->d_inode; - err = (rqstp->rq_vers == 2) ? nfserr_acces : nfserr_xdev; - if (dirp->i_dev != dest->i_dev) - goto out_unlock; - - err = nfserr_perm; - if (IS_IMMUTABLE(dest) || IS_APPEND(dest)) - goto out_unlock; - if (!dirp->i_op || !dirp->i_op->link) - goto out_unlock; - - DQUOT_INIT(dirp); - err = dirp->i_op->link(dold, dirp, dnew); + err = vfs_link(dold, dirp, dnew); if (!err) { if (EX_ISSYNC(ffhp->fh_export)) { nfsd_sync_dir(ddir); write_inode_now(dest); } - } else - err = nfserrno(-err); + } else { + if (err == -EXDEV && rqstp->rq_vers == 2) + err = nfserr_acces; + else + err = nfserrno(-err); + } -out_unlock: fh_unlock(ffhp); out_dput: dput(dnew); diff --git a/fs/ntfs/fs.c b/fs/ntfs/fs.c index 6db74a14e..89888bb60 100644 --- a/fs/ntfs/fs.c +++ b/fs/ntfs/fs.c @@ -31,6 +31,7 @@ /* Forward declarations */ static struct inode_operations ntfs_dir_inode_operations; +static struct file_operations ntfs_dir_operations; #define ITEM_SIZE 2040 @@ -41,6 +41,7 @@ static void pipe_wait(struct inode * inode) schedule(); remove_wait_queue(PIPE_WAIT(*inode), &wait); current->state = TASK_RUNNING; + down(PIPE_SEM(*inode)); } static ssize_t @@ -81,9 +82,7 @@ do_more_read: PIPE_WAITING_READERS(*inode)--; ret = -ERESTARTSYS; if (signal_pending(current)) - goto out_nolock; - if (down_interruptible(PIPE_SEM(*inode))) - goto out_nolock; + goto out; ret = 0; if (!PIPE_EMPTY(*inode)) break; @@ -162,7 +161,6 @@ pipe_write(struct file *filp, const char *buf, size_t count, loff_t *ppos) if (down_interruptible(PIPE_SEM(*inode))) goto out_nolock; -do_more_write: /* No readers yields SIGPIPE. */ if (!PIPE_READERS(*inode)) goto sigpipe; @@ -182,9 +180,7 @@ do_more_write: PIPE_WAITING_WRITERS(*inode)--; ret = -ERESTARTSYS; if (signal_pending(current)) - goto out_nolock; - if (down_interruptible(PIPE_SEM(*inode))) - goto out_nolock; + goto out; if (!PIPE_READERS(*inode)) goto sigpipe; @@ -230,20 +226,13 @@ do_more_write: pipe_wait(inode); PIPE_WAITING_WRITERS(*inode)--; if (signal_pending(current)) - goto out_nolock; - if (down_interruptible(PIPE_SEM(*inode))) - goto out_nolock; + goto out; if (!PIPE_READERS(*inode)) goto sigpipe; } while (!PIPE_FREE(*inode)); ret = -EFAULT; } - if (count && PIPE_WAITING_READERS(*inode) && - !(filp->f_flags & O_NONBLOCK)) { - wake_up_interruptible_sync(PIPE_WAIT(*inode)); - goto do_more_write; - } /* Signal readers asynchronously that there is more data. */ wake_up_interruptible(PIPE_WAIT(*inode)); diff --git a/fs/proc/base.c b/fs/proc/base.c index 54d93e131..4a191bfef 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -631,26 +631,19 @@ static void pid_delete_dentry(struct dentry * dentry) static struct dentry_operations pid_fd_dentry_operations = { - pid_fd_revalidate, /* revalidate */ - NULL, /* d_hash */ - NULL, /* d_compare */ - pid_delete_dentry /* d_delete(struct dentry *) */ + d_revalidate: pid_fd_revalidate, + d_delete: pid_delete_dentry, }; static struct dentry_operations pid_dentry_operations = { - NULL, /* revalidate */ - NULL, /* d_hash */ - NULL, /* d_compare */ - pid_delete_dentry /* d_delete(struct dentry *) */ + d_delete: pid_delete_dentry, }; static struct dentry_operations pid_base_dentry_operations = { - pid_base_revalidate, /* revalidate */ - NULL, /* d_hash */ - NULL, /* d_compare */ - pid_delete_dentry /* d_delete(struct dentry *) */ + d_revalidate: pid_base_revalidate, + d_delete: pid_delete_dentry, }; /* Lookups */ diff --git a/fs/proc/generic.c b/fs/proc/generic.c index fcfadbc99..28e0c08e5 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -226,10 +226,7 @@ proc_delete_dentry(struct dentry * dentry) static struct dentry_operations proc_dentry_operations = { - NULL, /* revalidate */ - NULL, /* d_hash */ - NULL, /* d_compare */ - proc_delete_dentry /* d_delete(struct dentry *) */ + d_delete: proc_delete_dentry, }; /* diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index 1f7ba6b99..b16b9a9df 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c @@ -665,8 +665,11 @@ void __init proc_misc_init(void) } } #ifdef __powerpc__ - entry = create_proc_entry("ppc_htab", S_IRUGO|S_IWUSR, NULL); - if (entry) - entry->proc_fops = &ppc_htab_operations; + { + extern struct file_operations ppc_htab_operations; + entry = create_proc_entry("ppc_htab", S_IRUGO|S_IWUSR, NULL); + if (entry) + entry->proc_fops = &ppc_htab_operations; + } #endif } diff --git a/fs/proc/root.c b/fs/proc/root.c index 6cdb2ad19..cce48d845 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -70,9 +70,6 @@ void __init proc_root_init(void) proc_mkdir("openprom", 0); #endif proc_tty_init(); -#ifdef __powerpc__ - proc_register(&proc_root, &proc_root_ppc_htab); -#endif #ifdef CONFIG_PROC_DEVICETREE proc_device_tree_init(); #endif diff --git a/fs/readdir.c b/fs/readdir.c index 31bc56cc2..4bf222288 100644 --- a/fs/readdir.c +++ b/fs/readdir.c @@ -13,6 +13,21 @@ #include <asm/uaccess.h> +int vfs_readdir(struct file *file, + int (*filler)(void *,const char *,int,off_t,ino_t), + void *buf) +{ + struct inode *inode = file->f_dentry->d_inode; + int res = -ENOTDIR; + if (!file->f_op || !file->f_op->readdir) + goto out; + down(&inode->i_sem); + res = file->f_op->readdir(file, buf, filler); + up(&inode->i_sem); +out: + return res; +} + /* * Traditional linux readdir() handling.. * @@ -57,46 +72,24 @@ asmlinkage int old_readdir(unsigned int fd, void * dirent, unsigned int count) { int error; struct file * file; - struct dentry * dentry; - struct inode * inode; struct readdir_callback buf; - lock_kernel(); error = -EBADF; file = fget(fd); if (!file) goto out; - dentry = file->f_dentry; - if (!dentry) - goto out_putf; - - inode = dentry->d_inode; - if (!inode) - goto out_putf; - buf.count = 0; buf.dirent = dirent; - error = -ENOTDIR; - if (!file->f_op || !file->f_op->readdir) - goto out_putf; - - /* - * Get the inode's semaphore to prevent changes - * to the directory while we read it. - */ - down(&inode->i_sem); - error = file->f_op->readdir(file, &buf, fillonedir); - up(&inode->i_sem); - if (error < 0) - goto out_putf; - error = buf.count; + lock_kernel(); + error = vfs_readdir(file, fillonedir, &buf); + if (error >= 0) + error = buf.count; + unlock_kernel(); -out_putf: fput(file); out: - unlock_kernel(); return error; } @@ -145,42 +138,22 @@ static int filldir(void * __buf, const char * name, int namlen, off_t offset, in asmlinkage long sys_getdents(unsigned int fd, void * dirent, unsigned int count) { struct file * file; - struct dentry * dentry; - struct inode * inode; struct linux_dirent * lastdirent; struct getdents_callback buf; int error; - lock_kernel(); error = -EBADF; file = fget(fd); if (!file) goto out; - dentry = file->f_dentry; - if (!dentry) - goto out_putf; - - inode = dentry->d_inode; - if (!inode) - goto out_putf; - buf.current_dir = (struct linux_dirent *) dirent; buf.previous = NULL; buf.count = count; buf.error = 0; - error = -ENOTDIR; - if (!file->f_op || !file->f_op->readdir) - goto out_putf; - - /* - * Get the inode's semaphore to prevent changes - * to the directory while we read it. - */ - down(&inode->i_sem); - error = file->f_op->readdir(file, &buf, filldir); - up(&inode->i_sem); + lock_kernel(); + error = vfs_readdir(file, filldir, &buf); if (error < 0) goto out_putf; error = buf.error; @@ -191,8 +164,8 @@ asmlinkage long sys_getdents(unsigned int fd, void * dirent, unsigned int count) } out_putf: + unlock_kernel(); fput(file); out: - unlock_kernel(); return error; } diff --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c index ca98fc9ca..91061a28f 100644 --- a/fs/smbfs/dir.c +++ b/fs/smbfs/dir.c @@ -172,10 +172,10 @@ static void smb_delete_dentry(struct dentry *); static struct dentry_operations smbfs_dentry_operations = { - smb_lookup_validate, /* d_revalidate(struct dentry *) */ - smb_hash_dentry, /* d_hash */ - smb_compare_dentry, /* d_compare */ - smb_delete_dentry /* d_delete(struct dentry *) */ + d_revalidate: smb_lookup_validate, + d_hash: smb_hash_dentry, + d_compare: smb_compare_dentry, + d_delete: smb_delete_dentry, }; /* diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index b2d7f1ab4..b92eed7db 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h @@ -9,6 +9,7 @@ #ifdef __KERNEL__ +#include <linux/config.h> #include <linux/types.h> #ifndef LINUX_VERSION_CODE diff --git a/fs/umsdos/dir.c b/fs/umsdos/dir.c index be27c54a7..18dd76572 100644 --- a/fs/umsdos/dir.c +++ b/fs/umsdos/dir.c @@ -46,10 +46,8 @@ static void umsdos_dentry_dput(struct dentry *dentry) struct dentry_operations umsdos_dentry_operations = { - umsdos_dentry_validate, /* d_revalidate(struct dentry *, int) */ - NULL, /* d_hash */ - NULL, /* d_compare */ - umsdos_dentry_dput /* d_delete(struct dentry *) */ + d_revalidate: umsdos_dentry_validate, + d_delete: umsdos_dentry_dput, }; struct UMSDOS_DIR_ONCE { diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c index b07708286..476a09e9c 100644 --- a/fs/vfat/namei.c +++ b/fs/vfat/namei.c @@ -59,28 +59,22 @@ static int vfat_revalidate(struct dentry *dentry, int); static struct dentry_operations vfat_dentry_ops[4] = { { - NULL, /* d_revalidate */ - vfat_hashi, - vfat_cmpi, - NULL /* d_delete */ + d_hash: vfat_hashi, + d_compare: vfat_cmpi, }, { - vfat_revalidate, - vfat_hashi, - vfat_cmpi, - NULL /* d_delete */ + d_revalidate: vfat_revalidate, + d_hash: vfat_hashi, + d_compare: vfat_cmpi, }, { - NULL, /* d_revalidate */ - vfat_hash, - vfat_cmp, - NULL /* d_delete */ + d_hash: vfat_hash, + d_compare: vfat_cmp, }, { - vfat_revalidate, - vfat_hash, - vfat_cmp, - NULL /* d_delete */ + d_revalidate: vfat_revalidate, + d_hash: vfat_hash, + d_compare: vfat_cmp, } }; |