diff options
Diffstat (limited to 'fs')
49 files changed, 427 insertions, 447 deletions
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index ae0f06b3c11a..2c4fa75be025 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c @@ -91,7 +91,7 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses, sb->s_op = &v9fs_super_ops; sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC | - MS_NODIRATIME | MS_NOATIME; + MS_NOATIME; } /** diff --git a/fs/Kconfig b/fs/Kconfig index 382e3b2883d5..ef78e3a42d32 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -798,7 +798,7 @@ config PROC_KCORE config PROC_VMCORE bool "/proc/vmcore support (EXPERIMENTAL)" - depends on PROC_FS && EMBEDDED && EXPERIMENTAL && CRASH_DUMP + depends on PROC_FS && EXPERIMENTAL && CRASH_DUMP help Exports the dump image of crashed kernel in ELF format. diff --git a/fs/Makefile b/fs/Makefile index 35e9aec608e4..1db711319c80 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -14,7 +14,7 @@ obj-y := open.o read_write.o file_table.o buffer.o bio.o super.o \ obj-$(CONFIG_INOTIFY) += inotify.o obj-$(CONFIG_EPOLL) += eventpoll.o -obj-$(CONFIG_COMPAT) += compat.o +obj-$(CONFIG_COMPAT) += compat.o compat_ioctl.o nfsd-$(CONFIG_NFSD) := nfsctl.o obj-y += $(nfsd-y) $(nfsd-m) diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 541b19e6fec9..14aa70282e8c 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c @@ -86,7 +86,7 @@ static int autofs4_root_readdir(struct file *file, void *dirent, /* Update usage from here to top of tree, so that scan of top-level directories will give a useful result */ -static void autofs4_update_usage(struct dentry *dentry) +static void autofs4_update_usage(struct vfsmount *mnt, struct dentry *dentry) { struct dentry *top = dentry->d_sb->s_root; @@ -95,7 +95,7 @@ static void autofs4_update_usage(struct dentry *dentry) struct autofs_info *ino = autofs4_dentry_ino(dentry); if (ino) { - update_atime(dentry->d_inode); + touch_atime(mnt, dentry); ino->last_used = jiffies; } } @@ -289,10 +289,10 @@ out: return autofs4_dcache_readdir(file, dirent, filldir); } -static int try_to_fill_dentry(struct dentry *dentry, - struct super_block *sb, - struct autofs_sb_info *sbi, int flags) +static int try_to_fill_dentry(struct vfsmount *mnt, struct dentry *dentry, int flags) { + struct super_block *sb = mnt->mnt_sb; + struct autofs_sb_info *sbi = autofs4_sbi(sb); struct autofs_info *de_info = autofs4_dentry_ino(dentry); int status = 0; @@ -367,7 +367,7 @@ static int try_to_fill_dentry(struct dentry *dentry, /* We don't update the usages for the autofs daemon itself, this is necessary for recursive autofs mounts */ if (!autofs4_oz_mode(sbi)) - autofs4_update_usage(dentry); + autofs4_update_usage(mnt, dentry); spin_lock(&dentry->d_lock); dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; @@ -392,7 +392,7 @@ static int autofs4_revalidate(struct dentry * dentry, struct nameidata *nd) /* Pending dentry */ if (autofs4_ispending(dentry)) { if (!oz_mode) - status = try_to_fill_dentry(dentry, dir->i_sb, sbi, flags); + status = try_to_fill_dentry(nd->mnt, dentry, flags); return status; } @@ -409,14 +409,14 @@ static int autofs4_revalidate(struct dentry * dentry, struct nameidata *nd) dentry, dentry->d_name.len, dentry->d_name.name); spin_unlock(&dcache_lock); if (!oz_mode) - status = try_to_fill_dentry(dentry, dir->i_sb, sbi, flags); + status = try_to_fill_dentry(nd->mnt, dentry, flags); return status; } spin_unlock(&dcache_lock); /* Update the usage list */ if (!oz_mode) - autofs4_update_usage(dentry); + autofs4_update_usage(nd->mnt, dentry); return 1; } diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index 72011826f0cb..f312103434d4 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c @@ -33,8 +33,6 @@ static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs); static int load_aout_library(struct file*); static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file); -extern void dump_thread(struct pt_regs *, struct user *); - static struct linux_binfmt aout_format = { .module = THIS_MODULE, .load_binary = load_aout_binary, diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 80ca932ba0bd..a4f6f57d91aa 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -622,7 +622,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) goto out_free_file; retval = -ENOMEM; - elf_interpreter = (char *) kmalloc(elf_ppnt->p_filesz, + elf_interpreter = kmalloc(elf_ppnt->p_filesz, GFP_KERNEL); if (!elf_interpreter) goto out_free_file; diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index e0344f69c79d..5b3076e8ee90 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -187,7 +187,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, struct pt_regs *regs goto error; /* read the name of the interpreter into memory */ - interpreter_name = (char *) kmalloc(phdr->p_filesz, GFP_KERNEL); + interpreter_name = kmalloc(phdr->p_filesz, GFP_KERNEL); if (!interpreter_name) goto error; diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 9d6625829b99..b72dc31a0970 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -77,8 +77,6 @@ static int load_flat_shared_library(int id, struct lib_info *p); static int load_flat_binary(struct linux_binprm *, struct pt_regs * regs); static int flat_core_dump(long signr, struct pt_regs * regs, struct file *file); -extern void dump_thread(struct pt_regs *, struct user *); - static struct linux_binfmt flat_format = { .module = THIS_MODULE, .load_binary = load_flat_binary, diff --git a/fs/cifs/cifs_uniupr.h b/fs/cifs/cifs_uniupr.h index decd138f14d4..da2ad5b451ac 100644 --- a/fs/cifs/cifs_uniupr.h +++ b/fs/cifs/cifs_uniupr.h @@ -242,7 +242,7 @@ static signed char UniCaseRangeLff20[27] = { /* * Lower Case Range */ -const static struct UniCaseRange CifsUniLowerRange[] = { +static const struct UniCaseRange CifsUniLowerRange[] = { 0x0380, 0x03ab, UniCaseRangeL0380, 0x0400, 0x042f, UniCaseRangeL0400, 0x0490, 0x04cb, UniCaseRangeL0490, diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 55d9a3a954cf..890bc30fbe20 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -10,7 +10,6 @@ * ioctls. */ -#ifdef INCLUDES #include <linux/config.h> #include <linux/types.h> #include <linux/compat.h> @@ -81,13 +80,9 @@ #include <linux/capi.h> #include <scsi/scsi.h> -/* Ugly hack. */ -#undef __KERNEL__ #include <scsi/scsi_ioctl.h> -#define __KERNEL__ #include <scsi/sg.h> -#include <asm/types.h> #include <asm/uaccess.h> #include <linux/ethtool.h> #include <linux/mii.h> @@ -95,7 +90,6 @@ #include <linux/watchdog.h> #include <linux/dm-ioctl.h> -#include <asm/module.h> #include <linux/soundcard.h> #include <linux/lp.h> #include <linux/ppdev.h> @@ -128,11 +122,6 @@ #include <linux/dvb/frontend.h> #include <linux/dvb/video.h> -#undef INCLUDES -#endif - -#ifdef CODE - /* Aiee. Someone does not find a difference between int and long */ #define EXT2_IOC32_GETFLAGS _IOR('f', 1, int) #define EXT2_IOC32_SETFLAGS _IOW('f', 2, int) @@ -148,6 +137,12 @@ #define EXT2_IOC32_GETVERSION _IOR('v', 1, int) #define EXT2_IOC32_SETVERSION _IOW('v', 2, int) +static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd, + unsigned long arg, struct file *f) +{ + return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg)); +} + static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg) { mm_segment_t old_fs = get_fs(); @@ -2475,6 +2470,49 @@ static int old_bridge_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg return -EINVAL; } +#define RTC_IRQP_READ32 _IOR('p', 0x0b, compat_ulong_t) +#define RTC_IRQP_SET32 _IOW('p', 0x0c, compat_ulong_t) +#define RTC_EPOCH_READ32 _IOR('p', 0x0d, compat_ulong_t) +#define RTC_EPOCH_SET32 _IOW('p', 0x0e, compat_ulong_t) + +static int rtc_ioctl(unsigned fd, unsigned cmd, unsigned long arg) +{ + mm_segment_t oldfs = get_fs(); + compat_ulong_t val32; + unsigned long kval; + int ret; + + switch (cmd) { + case RTC_IRQP_READ32: + case RTC_EPOCH_READ32: + set_fs(KERNEL_DS); + ret = sys_ioctl(fd, (cmd == RTC_IRQP_READ32) ? + RTC_IRQP_READ : RTC_EPOCH_READ, + (unsigned long)&kval); + set_fs(oldfs); + if (ret) + return ret; + val32 = kval; + return put_user(val32, (unsigned int __user *)arg); + case RTC_IRQP_SET32: + case RTC_EPOCH_SET32: + ret = get_user(val32, (unsigned int __user *)arg); + if (ret) + return ret; + kval = val32; + + set_fs(KERNEL_DS); + ret = sys_ioctl(fd, (cmd == RTC_IRQP_SET32) ? + RTC_IRQP_SET : RTC_EPOCH_SET, + (unsigned long)&kval); + set_fs(oldfs); + return ret; + default: + /* unreached */ + return -ENOIOCTLCMD; + } +} + #if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE) struct ncp_ioctl_request_32 { u32 function; @@ -2662,10 +2700,20 @@ static int do_ncp_setprivatedata(unsigned int fd, unsigned int cmd, unsigned lon } #endif -#undef CODE -#endif +#define HANDLE_IOCTL(cmd,handler) \ + { (cmd), (ioctl_trans_handler_t)(handler) }, + +/* pointer to compatible structure or no argument */ +#define COMPATIBLE_IOCTL(cmd) \ + { (cmd), do_ioctl32_pointer }, + +/* argument is an unsigned long integer, not a pointer */ +#define ULONG_IOCTL(cmd) \ + { (cmd), (ioctl_trans_handler_t)sys_ioctl }, -#ifdef DECLARES + +struct ioctl_trans ioctl_start[] = { +#include <linux/compat_ioctl.h> HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob) HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob) #ifdef CONFIG_NET @@ -2858,6 +2906,10 @@ HANDLE_IOCTL(SIOCSIWENCODE, do_wireless_ioctl) HANDLE_IOCTL(SIOCGIWENCODE, do_wireless_ioctl) HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl) HANDLE_IOCTL(SIOCGIFBR, old_bridge_ioctl) +HANDLE_IOCTL(RTC_IRQP_READ32, rtc_ioctl) +HANDLE_IOCTL(RTC_IRQP_SET32, rtc_ioctl) +HANDLE_IOCTL(RTC_EPOCH_READ32, rtc_ioctl) +HANDLE_IOCTL(RTC_EPOCH_SET32, rtc_ioctl) #if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE) HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest) @@ -2874,6 +2926,6 @@ HANDLE_IOCTL(DMX_GET_EVENT, do_dmx_get_event) HANDLE_IOCTL(VIDEO_GET_EVENT, do_video_get_event) HANDLE_IOCTL(VIDEO_STILLPICTURE, do_video_stillpicture) HANDLE_IOCTL(VIDEO_SET_SPU_PALETTE, do_video_set_spu_palette) +}; -#undef DECLARES -#endif +int ioctl_table_size = ARRAY_SIZE(ioctl_start); diff --git a/fs/dcache.c b/fs/dcache.c index 1536f15c4d4c..134d6775183f 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -808,10 +808,14 @@ void d_instantiate(struct dentry *entry, struct inode * inode) * * Fill in inode information in the entry. On success, it returns NULL. * If an unhashed alias of "entry" already exists, then we return the - * aliased dentry instead. + * aliased dentry instead and drop one reference to inode. * * Note that in order to avoid conflicts with rename() etc, the caller * had better be holding the parent directory semaphore. + * + * This also assumes that the inode count has been incremented + * (or otherwise set) by the caller to indicate that it is now + * in use by the dcache. */ struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode) { @@ -838,6 +842,7 @@ struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode) dget_locked(alias); spin_unlock(&dcache_lock); BUG_ON(!d_unhashed(alias)); + iput(inode); return alias; } list_add(&entry->d_alias, &inode->i_dentry); diff --git a/fs/exec.c b/fs/exec.c index fd02ea4a81e9..b5bcf1aae0ab 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -632,10 +632,10 @@ static inline int de_thread(struct task_struct *tsk) * synchronize with any firing (by calling del_timer_sync) * before we can safely let the old group leader die. */ - sig->real_timer.data = (unsigned long)current; + sig->real_timer.data = current; spin_unlock_irq(lock); - if (del_timer_sync(&sig->real_timer)) - add_timer(&sig->real_timer); + if (hrtimer_cancel(&sig->real_timer)) + hrtimer_restart(&sig->real_timer); spin_lock_irq(lock); } while (atomic_read(&sig->count) > count) { diff --git a/fs/ext2/bitmap.c b/fs/ext2/bitmap.c index 20145b74623f..e9983a0dd396 100644 --- a/fs/ext2/bitmap.c +++ b/fs/ext2/bitmap.c @@ -7,8 +7,12 @@ * Universite Pierre et Marie Curie (Paris VI) */ +#ifdef EXT2FS_DEBUG + #include <linux/buffer_head.h> +#include "ext2.h" + static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0}; unsigned long ext2_count_free (struct buffer_head * map, unsigned int numchars) @@ -23,3 +27,6 @@ unsigned long ext2_count_free (struct buffer_head * map, unsigned int numchars) nibblemap[(map->b_data[i] >> 4) & 0xf]; return (sum); } + +#endif /* EXT2FS_DEBUG */ + diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index f7a3b5fee274..a2ca3107d475 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c @@ -389,10 +389,6 @@ ext2_xattr_set(struct inode *inode, int name_index, const char *name, ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld", name_index, name, value, (long)value_len); - if (IS_RDONLY(inode)) - return -EROFS; - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - return -EPERM; if (value == NULL) value_len = 0; if (name == NULL) diff --git a/fs/ext2/xattr_trusted.c b/fs/ext2/xattr_trusted.c index 52b30ee6a25f..2c072bfea23b 100644 --- a/fs/ext2/xattr_trusted.c +++ b/fs/ext2/xattr_trusted.c @@ -38,8 +38,6 @@ ext2_xattr_trusted_get(struct inode *inode, const char *name, { if (strcmp(name, "") == 0) return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; return ext2_xattr_get(inode, EXT2_XATTR_INDEX_TRUSTED, name, buffer, size); } @@ -50,8 +48,6 @@ ext2_xattr_trusted_set(struct inode *inode, const char *name, { if (strcmp(name, "") == 0) return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; return ext2_xattr_set(inode, EXT2_XATTR_INDEX_TRUSTED, name, value, size, flags); } diff --git a/fs/ext2/xattr_user.c b/fs/ext2/xattr_user.c index 0c03ea131a94..f383e7c3a7b5 100644 --- a/fs/ext2/xattr_user.c +++ b/fs/ext2/xattr_user.c @@ -35,16 +35,10 @@ static int ext2_xattr_user_get(struct inode *inode, const char *name, void *buffer, size_t size) { - int error; - if (strcmp(name, "") == 0) return -EINVAL; if (!test_opt(inode->i_sb, XATTR_USER)) return -EOPNOTSUPP; - error = permission(inode, MAY_READ, NULL); - if (error) - return error; - return ext2_xattr_get(inode, EXT2_XATTR_INDEX_USER, name, buffer, size); } @@ -52,18 +46,10 @@ static int ext2_xattr_user_set(struct inode *inode, const char *name, const void *value, size_t size, int flags) { - int error; - if (strcmp(name, "") == 0) return -EINVAL; if (!test_opt(inode->i_sb, XATTR_USER)) return -EOPNOTSUPP; - if ( !S_ISREG(inode->i_mode) && - (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX)) - return -EPERM; - error = permission(inode, MAY_WRITE, NULL); - if (error) - return error; return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER, name, value, size, flags); diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index ae1148c24c53..c6393fb4c35a 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c @@ -20,8 +20,6 @@ #include <linux/quotaops.h> #include <linux/buffer_head.h> -#include "bitmap.h" - /* * balloc.c contains the blocks allocation and deallocation routines */ diff --git a/fs/ext3/bitmap.c b/fs/ext3/bitmap.c index 5b4ba3e246e6..cb16b4c5d5df 100644 --- a/fs/ext3/bitmap.c +++ b/fs/ext3/bitmap.c @@ -7,8 +7,11 @@ * Universite Pierre et Marie Curie (Paris VI) */ +#ifdef EXT3FS_DEBUG + #include <linux/buffer_head.h> -#include "bitmap.h" + +#include "ext3_fs.h" static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0}; @@ -24,3 +27,6 @@ unsigned long ext3_count_free (struct buffer_head * map, unsigned int numchars) nibblemap[(map->b_data[i] >> 4) & 0xf]; return (sum); } + +#endif /* EXT3FS_DEBUG */ + diff --git a/fs/ext3/bitmap.h b/fs/ext3/bitmap.h deleted file mode 100644 index 6ee503a6bb4e..000000000000 --- a/fs/ext3/bitmap.h +++ /dev/null @@ -1,8 +0,0 @@ -/* linux/fs/ext3/bitmap.c - * - * Copyright (C) 2005 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * -*/ - -extern unsigned long ext3_count_free (struct buffer_head *, unsigned int ); diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index 69078079b19c..dc826464f313 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c @@ -26,7 +26,6 @@ #include <asm/byteorder.h> -#include "bitmap.h" #include "xattr.h" #include "acl.h" diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c index 238199d82ce5..e8d60bf6b7df 100644 --- a/fs/ext3/xattr.c +++ b/fs/ext3/xattr.c @@ -946,10 +946,6 @@ ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index, }; int error; - if (IS_RDONLY(inode)) - return -EROFS; - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - return -EPERM; if (!name) return -EINVAL; if (strlen(name) > 255) diff --git a/fs/ext3/xattr_trusted.c b/fs/ext3/xattr_trusted.c index f68bfd1cf519..7c693c94f14d 100644 --- a/fs/ext3/xattr_trusted.c +++ b/fs/ext3/xattr_trusted.c @@ -39,8 +39,6 @@ ext3_xattr_trusted_get(struct inode *inode, const char *name, { if (strcmp(name, "") == 0) return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; return ext3_xattr_get(inode, EXT3_XATTR_INDEX_TRUSTED, name, buffer, size); } @@ -51,8 +49,6 @@ ext3_xattr_trusted_set(struct inode *inode, const char *name, { if (strcmp(name, "") == 0) return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; return ext3_xattr_set(inode, EXT3_XATTR_INDEX_TRUSTED, name, value, size, flags); } diff --git a/fs/ext3/xattr_user.c b/fs/ext3/xattr_user.c index e907cae7a07c..a85a0a17c4fd 100644 --- a/fs/ext3/xattr_user.c +++ b/fs/ext3/xattr_user.c @@ -37,16 +37,10 @@ static int ext3_xattr_user_get(struct inode *inode, const char *name, void *buffer, size_t size) { - int error; - if (strcmp(name, "") == 0) return -EINVAL; if (!test_opt(inode->i_sb, XATTR_USER)) return -EOPNOTSUPP; - error = permission(inode, MAY_READ, NULL); - if (error) - return error; - return ext3_xattr_get(inode, EXT3_XATTR_INDEX_USER, name, buffer, size); } @@ -54,19 +48,10 @@ static int ext3_xattr_user_set(struct inode *inode, const char *name, const void *value, size_t size, int flags) { - int error; - if (strcmp(name, "") == 0) return -EINVAL; if (!test_opt(inode->i_sb, XATTR_USER)) return -EOPNOTSUPP; - if ( !S_ISREG(inode->i_mode) && - (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX)) - return -EPERM; - error = permission(inode, MAY_WRITE, NULL); - if (error) - return error; - return ext3_xattr_set(inode, EXT3_XATTR_INDEX_USER, name, value, size, flags); } diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index df16fcbff3fb..0fa1ab6250bf 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h @@ -143,9 +143,6 @@ struct hfsplus_sb_info { unsigned long flags; - atomic_t inode_cnt; - u32 last_inode_cnt; - struct hlist_head rsrc_inodes; }; diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 983bcd02ac1c..7acff6c5464f 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -182,11 +182,6 @@ static struct dentry *hfsplus_file_lookup(struct inode *dir, struct dentry *dent igrab(dir); hlist_add_head(&inode->i_hash, &HFSPLUS_SB(sb).rsrc_inodes); mark_inode_dirty(inode); - { - void hfsplus_inode_check(struct super_block *sb); - atomic_inc(&HFSPLUS_SB(sb).inode_cnt); - hfsplus_inode_check(sb); - } out: d_add(dentry, inode); return NULL; @@ -317,11 +312,6 @@ struct inode *hfsplus_new_inode(struct super_block *sb, int mode) if (!inode) return NULL; - { - void hfsplus_inode_check(struct super_block *sb); - atomic_inc(&HFSPLUS_SB(sb).inode_cnt); - hfsplus_inode_check(sb); - } inode->i_ino = HFSPLUS_SB(sb).next_cnid++; inode->i_mode = mode; inode->i_uid = current->fsuid; diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 6daaf7c755a6..d791780def50 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -22,29 +22,12 @@ static void hfsplus_destroy_inode(struct inode *inode); #include "hfsplus_fs.h" -void hfsplus_inode_check(struct super_block *sb) -{ -#if 0 - u32 cnt = atomic_read(&HFSPLUS_SB(sb).inode_cnt); - u32 last_cnt = HFSPLUS_SB(sb).last_inode_cnt; - - if (cnt <= (last_cnt / 2) || - cnt >= (last_cnt * 2)) { - HFSPLUS_SB(sb).last_inode_cnt = cnt; - printk("inode_check: %u,%u,%u\n", cnt, last_cnt, - HFSPLUS_SB(sb).cat_tree ? HFSPLUS_SB(sb).cat_tree->node_hash_cnt : 0); - } -#endif -} - static void hfsplus_read_inode(struct inode *inode) { struct hfs_find_data fd; struct hfsplus_vh *vhdr; int err; - atomic_inc(&HFSPLUS_SB(inode->i_sb).inode_cnt); - hfsplus_inode_check(inode->i_sb); INIT_LIST_HEAD(&HFSPLUS_I(inode).open_dir_list); init_MUTEX(&HFSPLUS_I(inode).extents_lock); HFSPLUS_I(inode).flags = 0; @@ -155,12 +138,10 @@ static int hfsplus_write_inode(struct inode *inode, int unused) static void hfsplus_clear_inode(struct inode *inode) { dprint(DBG_INODE, "hfsplus_clear_inode: %lu\n", inode->i_ino); - atomic_dec(&HFSPLUS_SB(inode->i_sb).inode_cnt); if (HFSPLUS_IS_RSRC(inode)) { HFSPLUS_I(HFSPLUS_I(inode).rsrc_inode).rsrc_inode = NULL; iput(HFSPLUS_I(inode).rsrc_inode); } - hfsplus_inode_check(inode->i_sb); } static void hfsplus_write_super(struct super_block *sb) diff --git a/fs/inode.c b/fs/inode.c index e08767fd57b0..108138d4e909 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -22,6 +22,7 @@ #include <linux/cdev.h> #include <linux/bootmem.h> #include <linux/inotify.h> +#include <linux/mount.h> /* * This is needed for the following functions: @@ -1176,22 +1177,33 @@ sector_t bmap(struct inode * inode, sector_t block) EXPORT_SYMBOL(bmap); /** - * update_atime - update the access time + * touch_atime - update the access time + * @mnt: mount the inode is accessed on * @inode: inode accessed * * Update the accessed time on an inode and mark it for writeback. * This function automatically handles read only file systems and media, * as well as the "noatime" flag and inode specific "noatime" markers. */ -void update_atime(struct inode *inode) +void touch_atime(struct vfsmount *mnt, struct dentry *dentry) { + struct inode *inode = dentry->d_inode; struct timespec now; - if (IS_NOATIME(inode)) + if (IS_RDONLY(inode)) return; - if (IS_NODIRATIME(inode) && S_ISDIR(inode->i_mode)) + + if ((inode->i_flags & S_NOATIME) || + (inode->i_sb->s_flags & MS_NOATIME) || + ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode))) return; - if (IS_RDONLY(inode)) + + /* + * We may have a NULL vfsmount when coming from NFSD + */ + if (mnt && + ((mnt->mnt_flags & MNT_NOATIME) || + ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)))) return; now = current_fs_time(inode->i_sb); @@ -1201,19 +1213,23 @@ void update_atime(struct inode *inode) } } -EXPORT_SYMBOL(update_atime); +EXPORT_SYMBOL(touch_atime); /** - * inode_update_time - update mtime and ctime time - * @inode: inode accessed - * @ctime_too: update ctime too + * file_update_time - update mtime and ctime time + * @file: file accessed * - * Update the mtime time on an inode and mark it for writeback. - * When ctime_too is specified update the ctime too. + * Update the mtime and ctime members of an inode and mark the inode + * for writeback. Note that this function is meant exclusively for + * usage in the file write path of filesystems, and filesystems may + * choose to explicitly ignore update via this function with the + * S_NOCTIME inode flag, e.g. for network filesystem where these + * timestamps are handled by the server. */ -void inode_update_time(struct inode *inode, int ctime_too) +void file_update_time(struct file *file) { + struct inode *inode = file->f_dentry->d_inode; struct timespec now; int sync_it = 0; @@ -1227,16 +1243,15 @@ void inode_update_time(struct inode *inode, int ctime_too) sync_it = 1; inode->i_mtime = now; - if (ctime_too) { - if (!timespec_equal(&inode->i_ctime, &now)) - sync_it = 1; - inode->i_ctime = now; - } + if (!timespec_equal(&inode->i_ctime, &now)) + sync_it = 1; + inode->i_ctime = now; + if (sync_it) mark_inode_dirty_sync(inode); } -EXPORT_SYMBOL(inode_update_time); +EXPORT_SYMBOL(file_update_time); int inode_needs_sync(struct inode *inode) { diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index 23aa5066b5a4..952da5f917cd 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c @@ -83,21 +83,6 @@ struct ea_buffer { #define EA_NEW 0x0004 #define EA_MALLOC 0x0008 -/* Namespaces */ -#define XATTR_SYSTEM_PREFIX "system." -#define XATTR_SYSTEM_PREFIX_LEN (sizeof (XATTR_SYSTEM_PREFIX) - 1) - -#define XATTR_USER_PREFIX "user." -#define XATTR_USER_PREFIX_LEN (sizeof (XATTR_USER_PREFIX) - 1) - -#define XATTR_OS2_PREFIX "os2." -#define XATTR_OS2_PREFIX_LEN (sizeof (XATTR_OS2_PREFIX) - 1) - -/* XATTR_SECURITY_PREFIX is defined in include/linux/xattr.h */ -#define XATTR_SECURITY_PREFIX_LEN (sizeof (XATTR_SECURITY_PREFIX) - 1) - -#define XATTR_TRUSTED_PREFIX "trusted." -#define XATTR_TRUSTED_PREFIX_LEN (sizeof (XATTR_TRUSTED_PREFIX) - 1) /* * These three routines are used to recognize on-disk extended attributes @@ -773,36 +758,23 @@ static int can_set_system_xattr(struct inode *inode, const char *name, static int can_set_xattr(struct inode *inode, const char *name, const void *value, size_t value_len) { - if (IS_RDONLY(inode)) - return -EROFS; - - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - return -EPERM; - - if(strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) == 0) - /* - * "system.*" - */ + if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) return can_set_system_xattr(inode, name, value, value_len); - if(strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) - return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM); - -#ifdef CONFIG_JFS_SECURITY - if (strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) - == 0) - return 0; /* Leave it to the security module */ -#endif - - if((strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) != 0) && - (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) != 0)) + /* + * Don't allow setting an attribute in an unknown namespace. + */ + if (strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) && + strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) && + strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) && + strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)) return -EOPNOTSUPP; if (!S_ISREG(inode->i_mode) && (!S_ISDIR(inode->i_mode) || inode->i_mode &S_ISVTX)) return -EPERM; - return permission(inode, MAY_WRITE, NULL); + return 0; } int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name, @@ -972,22 +944,6 @@ int jfs_setxattr(struct dentry *dentry, const char *name, const void *value, return rc; } -static int can_get_xattr(struct inode *inode, const char *name) -{ -#ifdef CONFIG_JFS_SECURITY - if(strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) == 0) - return 0; -#endif - - if(strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) - return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM); - - if(strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) == 0) - return 0; - - return permission(inode, MAY_READ, NULL); -} - ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data, size_t buf_size) { @@ -998,12 +954,8 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data, ssize_t size; int namelen = strlen(name); char *os2name = NULL; - int rc; char *value; - if ((rc = can_get_xattr(inode, name))) - return rc; - if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) { os2name = kmalloc(namelen - XATTR_OS2_PREFIX_LEN + 1, GFP_KERNEL); diff --git a/fs/namespace.c b/fs/namespace.c index f0e353f5bc30..2ca6145f43d6 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -355,14 +355,14 @@ static int show_vfsmnt(struct seq_file *m, void *v) { MS_SYNCHRONOUS, ",sync" }, { MS_DIRSYNC, ",dirsync" }, { MS_MANDLOCK, ",mand" }, - { MS_NOATIME, ",noatime" }, - { MS_NODIRATIME, ",nodiratime" }, { 0, NULL } }; static struct proc_fs_info mnt_info[] = { { MNT_NOSUID, ",nosuid" }, { MNT_NODEV, ",nodev" }, { MNT_NOEXEC, ",noexec" }, + { MNT_NOATIME, ",noatime" }, + { MNT_NODIRATIME, ",nodiratime" }, { 0, NULL } }; struct proc_fs_info *fs_infop; @@ -1286,7 +1286,13 @@ long do_mount(char *dev_name, char *dir_name, char *type_page, mnt_flags |= MNT_NODEV; if (flags & MS_NOEXEC) mnt_flags |= MNT_NOEXEC; - flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE); + if (flags & MS_NOATIME) + mnt_flags |= MNT_NOATIME; + if (flags & MS_NODIRATIME) + mnt_flags |= MNT_NODIRATIME; + + flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | + MS_NOATIME | MS_NODIRATIME); /* ... and get the mountpoint */ retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd); diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c index 4947d9b11fc1..973b444d6914 100644 --- a/fs/ncpfs/file.c +++ b/fs/ncpfs/file.c @@ -262,7 +262,7 @@ ncp_file_write(struct file *file, const char __user *buf, size_t count, loff_t * } vfree(bouncebuffer); - inode_update_time(inode, 1); + file_update_time(file); *ppos = pos; diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 3e4ba9cb7f80..a77ee95b7efb 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -950,11 +950,20 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) /* Flush out writes to the server in order to update c/mtime */ nfs_sync_inode(inode, 0, 0, FLUSH_WAIT|FLUSH_NOCOMMIT); - if (__IS_FLG(inode, MS_NOATIME)) - need_atime = 0; - else if (__IS_FLG(inode, MS_NODIRATIME) && S_ISDIR(inode->i_mode)) + + /* + * We may force a getattr if the user cares about atime. + * + * Note that we only have to check the vfsmount flags here: + * - NFS always sets S_NOATIME by so checking it would give a + * bogus result + * - NFS never sets MS_NOATIME or MS_NODIRATIME so there is + * no point in checking those. + */ + if ((mnt->mnt_flags & MNT_NOATIME) || + ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))) need_atime = 0; - /* We may force a getattr if the user cares about atime */ + if (need_atime) err = __nfs_revalidate_inode(NFS_SERVER(inode), inode); else diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index bb36b4304491..eef0576a7785 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -48,8 +48,8 @@ #include <linux/fsnotify.h> #include <linux/posix_acl.h> #include <linux/posix_acl_xattr.h> -#ifdef CONFIG_NFSD_V4 #include <linux/xattr.h> +#ifdef CONFIG_NFSD_V4 #include <linux/nfs4.h> #include <linux/nfs4_acl.h> #include <linux/nfsd_idmap.h> @@ -365,8 +365,30 @@ out_nfserr: goto out; } -#if defined(CONFIG_NFSD_V4) +#if defined(CONFIG_NFSD_V2_ACL) || \ + defined(CONFIG_NFSD_V3_ACL) || \ + defined(CONFIG_NFSD_V4) +static ssize_t nfsd_getxattr(struct dentry *dentry, char *key, void **buf) +{ + ssize_t buflen; + int error; + + buflen = vfs_getxattr(dentry, key, NULL, 0); + if (buflen <= 0) + return buflen; + *buf = kmalloc(buflen, GFP_KERNEL); + if (!*buf) + return -ENOMEM; + + error = vfs_getxattr(dentry, key, *buf, buflen); + if (error < 0) + return error; + return buflen; +} +#endif + +#if defined(CONFIG_NFSD_V4) static int set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key) { @@ -374,7 +396,6 @@ set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key) size_t buflen; char *buf = NULL; int error = 0; - struct inode *inode = dentry->d_inode; buflen = posix_acl_xattr_size(pacl->a_count); buf = kmalloc(buflen, GFP_KERNEL); @@ -388,15 +409,7 @@ set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key) goto out; } - error = -EOPNOTSUPP; - if (inode->i_op && inode->i_op->setxattr) { - mutex_lock(&inode->i_mutex); - security_inode_setxattr(dentry, key, buf, len, 0); - error = inode->i_op->setxattr(dentry, key, buf, len, 0); - if (!error) - security_inode_post_setxattr(dentry, key, buf, len, 0); - mutex_unlock(&inode->i_mutex); - } + error = vfs_setxattr(dentry, key, buf, len, 0); out: kfree(buf); return error; @@ -455,44 +468,19 @@ out_nfserr: static struct posix_acl * _get_posix_acl(struct dentry *dentry, char *key) { - struct inode *inode = dentry->d_inode; - char *buf = NULL; - int buflen, error = 0; + void *buf = NULL; struct posix_acl *pacl = NULL; + int buflen; - error = -EOPNOTSUPP; - if (inode->i_op == NULL) - goto out_err; - if (inode->i_op->getxattr == NULL) - goto out_err; - - error = security_inode_getxattr(dentry, key); - if (error) - goto out_err; - - buflen = inode->i_op->getxattr(dentry, key, NULL, 0); - if (buflen <= 0) { - error = buflen < 0 ? buflen : -ENODATA; - goto out_err; - } - - buf = kmalloc(buflen, GFP_KERNEL); - if (buf == NULL) { - error = -ENOMEM; - goto out_err; - } - - error = inode->i_op->getxattr(dentry, key, buf, buflen); - if (error < 0) - goto out_err; + buflen = nfsd_getxattr(dentry, key, &buf); + if (!buflen) + buflen = -ENODATA; + if (buflen <= 0) + return ERR_PTR(buflen); pacl = posix_acl_from_xattr(buf, buflen); - out: kfree(buf); return pacl; - out_err: - pacl = ERR_PTR(error); - goto out; } int @@ -1884,39 +1872,25 @@ nfsd_get_posix_acl(struct svc_fh *fhp, int type) ssize_t size; struct posix_acl *acl; - if (!IS_POSIXACL(inode) || !inode->i_op || !inode->i_op->getxattr) + if (!IS_POSIXACL(inode)) + return ERR_PTR(-EOPNOTSUPP); + + switch (type) { + case ACL_TYPE_ACCESS: + name = POSIX_ACL_XATTR_ACCESS; + break; + case ACL_TYPE_DEFAULT: + name = POSIX_ACL_XATTR_DEFAULT; + break; + default: return ERR_PTR(-EOPNOTSUPP); - switch(type) { - case ACL_TYPE_ACCESS: - name = POSIX_ACL_XATTR_ACCESS; - break; - case ACL_TYPE_DEFAULT: - name = POSIX_ACL_XATTR_DEFAULT; - break; - default: - return ERR_PTR(-EOPNOTSUPP); } - size = inode->i_op->getxattr(fhp->fh_dentry, name, NULL, 0); + size = nfsd_getxattr(fhp->fh_dentry, name, &value); + if (size < 0) + return ERR_PTR(size); - if (size < 0) { - acl = ERR_PTR(size); - goto getout; - } else if (size > 0) { - value = kmalloc(size, GFP_KERNEL); - if (!value) { - acl = ERR_PTR(-ENOMEM); - goto getout; - } - size = inode->i_op->getxattr(fhp->fh_dentry, name, value, size); - if (size < 0) { - acl = ERR_PTR(size); - goto getout; - } - } acl = posix_acl_from_xattr(value, size); - -getout: kfree(value); return acl; } @@ -1957,16 +1931,13 @@ nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl) } else size = 0; - if (!fhp->fh_locked) - fh_lock(fhp); /* unlocking is done automatically */ if (size) - error = inode->i_op->setxattr(fhp->fh_dentry, name, - value, size, 0); + error = vfs_setxattr(fhp->fh_dentry, name, value, size, 0); else { if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT) error = 0; else { - error = inode->i_op->removexattr(fhp->fh_dentry, name); + error = vfs_removexattr(fhp->fh_dentry, name); if (error == -ENODATA) error = 0; } diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index 30f71acdc1cb..fb413d3d8618 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -2173,7 +2173,7 @@ static ssize_t ntfs_file_aio_write_nolock(struct kiocb *iocb, err = remove_suid(file->f_dentry); if (err) goto out; - inode_update_time(inode, 1); + file_update_time(file); written = ntfs_file_buffered_write(iocb, iov, nr_segs, pos, ppos, count); out: diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index bda7a08911a5..ea1bd3feea1b 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c @@ -2767,7 +2767,25 @@ unm_done: up_write(&ni->runlist.lock); done: /* Update the mtime and ctime on the base inode. */ - inode_update_time(VFS_I(base_ni), 1); + /* normally ->truncate shouldn't update ctime or mtime, + * but ntfs did before so it got a copy & paste version + * of file_update_time. one day someone should fix this + * for real. + */ + if (!IS_NOCMTIME(VFS_I(base_ni)) && !IS_RDONLY(VFS_I(base_ni))) { + struct timespec now = current_fs_time(VFS_I(base_ni)->i_sb); + int sync_it = 0; + + if (!timespec_equal(&VFS_I(base_ni)->i_mtime, &now) || + !timespec_equal(&VFS_I(base_ni)->i_ctime, &now)) + sync_it = 1; + VFS_I(base_ni)->i_mtime = now; + VFS_I(base_ni)->i_ctime = now; + + if (sync_it) + mark_inode_dirty_sync(VFS_I(base_ni)); + } + if (likely(!err)) { NInoClearTruncateFailed(ni); ntfs_debug("Done."); diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 280e383fc84e..c3a3f1a8310b 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -443,8 +443,8 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt) ntfs_debug("Entering with remount options string: %s", opt); #ifndef NTFS_RW - /* For read-only compiled driver, enforce all read-only flags. */ - *flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; + /* For read-only compiled driver, enforce read-only flag. */ + *flags |= MS_RDONLY; #else /* NTFS_RW */ /* * For the read-write compiled driver, if we are remounting read-write, @@ -1721,7 +1721,7 @@ static BOOL load_system_files(ntfs_volume *vol) es3); goto iput_mirr_err_out; } - sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; + sb->s_flags |= MS_RDONLY; ntfs_error(sb, "%s. Mounting read-only%s", !vol->mftmirr_ino ? es1 : es2, es3); } else @@ -1837,7 +1837,7 @@ get_ctx_vol_failed: es1, es2); goto iput_vol_err_out; } - sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; + sb->s_flags |= MS_RDONLY; ntfs_error(sb, "%s. Mounting read-only%s", es1, es2); } else ntfs_warning(sb, "%s. Will not be able to remount " @@ -1874,7 +1874,7 @@ get_ctx_vol_failed: } goto iput_logfile_err_out; } - sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; + sb->s_flags |= MS_RDONLY; ntfs_error(sb, "%s. Mounting read-only%s", es1, es2); } else ntfs_warning(sb, "%s. Will not be able to remount " @@ -1919,7 +1919,7 @@ get_ctx_vol_failed: es1, es2); goto iput_root_err_out; } - sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; + sb->s_flags |= MS_RDONLY; ntfs_error(sb, "%s. Mounting read-only%s", es1, es2); } else ntfs_warning(sb, "%s. Will not be able to remount " @@ -1943,7 +1943,7 @@ get_ctx_vol_failed: goto iput_root_err_out; } ntfs_error(sb, "%s. Mounting read-only%s", es1, es2); - sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; + sb->s_flags |= MS_RDONLY; /* * Do not set NVolErrors() because ntfs_remount() might manage * to set the dirty flag in which case all would be well. @@ -1970,7 +1970,7 @@ get_ctx_vol_failed: goto iput_root_err_out; } ntfs_error(sb, "%s. Mounting read-only%s", es1, es2); - sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; + sb->s_flags |= MS_RDONLY; NVolSetErrors(vol); } #endif @@ -1989,7 +1989,7 @@ get_ctx_vol_failed: goto iput_root_err_out; } ntfs_error(sb, "%s. Mounting read-only%s", es1, es2); - sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; + sb->s_flags |= MS_RDONLY; NVolSetErrors(vol); } #endif /* NTFS_RW */ @@ -2030,7 +2030,7 @@ get_ctx_vol_failed: es1, es2); goto iput_quota_err_out; } - sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; + sb->s_flags |= MS_RDONLY; ntfs_error(sb, "%s. Mounting read-only%s", es1, es2); } else ntfs_warning(sb, "%s. Will not be able to remount " @@ -2053,7 +2053,7 @@ get_ctx_vol_failed: goto iput_quota_err_out; } ntfs_error(sb, "%s. Mounting read-only%s", es1, es2); - sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; + sb->s_flags |= MS_RDONLY; NVolSetErrors(vol); } /* @@ -2074,7 +2074,7 @@ get_ctx_vol_failed: es1, es2); goto iput_usnjrnl_err_out; } - sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; + sb->s_flags |= MS_RDONLY; ntfs_error(sb, "%s. Mounting read-only%s", es1, es2); } else ntfs_warning(sb, "%s. Will not be able to remount " @@ -2097,7 +2097,7 @@ get_ctx_vol_failed: goto iput_usnjrnl_err_out; } ntfs_error(sb, "%s. Mounting read-only%s", es1, es2); - sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; + sb->s_flags |= MS_RDONLY; NVolSetErrors(vol); } #endif /* NTFS_RW */ @@ -2689,7 +2689,7 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent) ntfs_debug("Entering."); #ifndef NTFS_RW - sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; + sb->s_flags |= MS_RDONLY; #endif /* ! NTFS_RW */ /* Allocate a new ntfs_volume and place it in sb->s_fs_info. */ sb->s_fs_info = kmalloc(sizeof(ntfs_volume), GFP_NOFS); diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c index afdeec4b0eef..843cf9ddefe8 100644 --- a/fs/ocfs2/mmap.c +++ b/fs/ocfs2/mmap.c @@ -80,12 +80,8 @@ static struct vm_operations_struct ocfs2_file_vm_ops = { .nopage = ocfs2_nopage, }; -int ocfs2_mmap(struct file *file, - struct vm_area_struct *vma) +int ocfs2_mmap(struct file *file, struct vm_area_struct *vma) { - struct address_space *mapping = file->f_dentry->d_inode->i_mapping; - struct inode *inode = mapping->host; - /* We don't want to support shared writable mappings yet. */ if (((vma->vm_flags & VM_SHARED) || (vma->vm_flags & VM_MAYSHARE)) && ((vma->vm_flags & VM_WRITE) || (vma->vm_flags & VM_MAYWRITE))) { @@ -95,7 +91,7 @@ int ocfs2_mmap(struct file *file, return -EINVAL; } - update_atime(inode); + file_accessed(file); vma->vm_ops = &ocfs2_file_vm_ops; return 0; } diff --git a/fs/pipe.c b/fs/pipe.c index acb030b61fb0..eef0f29e86ef 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -347,7 +347,7 @@ out: kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN); } if (ret > 0) - inode_update_time(inode, 1); /* mtime and ctime */ + file_update_time(filp); return ret; } diff --git a/fs/proc/array.c b/fs/proc/array.c index 5e9251f65317..7eb1bd7f800c 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -330,7 +330,7 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) unsigned long min_flt = 0, maj_flt = 0; cputime_t cutime, cstime, utime, stime; unsigned long rsslim = 0; - unsigned long it_real_value = 0; + DEFINE_KTIME(it_real_value); struct task_struct *t; char tcomm[sizeof(task->comm)]; @@ -386,7 +386,7 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) utime = cputime_add(utime, task->signal->utime); stime = cputime_add(stime, task->signal->stime); } - it_real_value = task->signal->it_real_value; + it_real_value = task->signal->real_timer.expires; } ppid = pid_alive(task) ? task->group_leader->real_parent->tgid : 0; read_unlock(&tasklist_lock); @@ -435,7 +435,7 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) priority, nice, num_threads, - jiffies_to_clock_t(it_real_value), + (long) ktime_to_clock_t(it_real_value), start_time, vsize, mm ? get_mm_rss(mm) : 0, diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 3b2e7b69e63a..5378d7c78419 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c @@ -35,6 +35,9 @@ static size_t elfcorebuf_sz; /* Total size of vmcore file. */ static u64 vmcore_size; +/* Stores the physical address of elf header of crash image. */ +unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX; + struct proc_dir_entry *proc_vmcore = NULL; /* Reads a page from the oldmem device from given offset. */ diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index 127e7d2cabdd..ad6fa964b0e7 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c @@ -1360,7 +1360,7 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t if (res) goto out; - inode_update_time(inode, 1); /* Both mtime and ctime */ + file_update_time(file); // Ok, we are done with all the checks. diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index f1895f0a278e..6f99e01f94ab 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -497,12 +497,6 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, struct iattr newattrs; __u32 xahash = 0; - if (IS_RDONLY(inode)) - return -EROFS; - - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - return -EPERM; - if (get_inode_sd_version(inode) == STAT_DATA_V1) return -EOPNOTSUPP; @@ -758,9 +752,6 @@ int reiserfs_xattr_del(struct inode *inode, const char *name) struct dentry *dir; int err; - if (IS_RDONLY(inode)) - return -EROFS; - dir = open_xa_dir(inode, FL_READONLY); if (IS_ERR(dir)) { err = PTR_ERR(dir); @@ -984,12 +975,6 @@ reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value, get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) return -EOPNOTSUPP; - if (IS_RDONLY(dentry->d_inode)) - return -EROFS; - - if (IS_IMMUTABLE(dentry->d_inode) || IS_APPEND(dentry->d_inode)) - return -EROFS; - reiserfs_write_lock_xattr_i(dentry->d_inode); lock = !has_xattr_dir(dentry->d_inode); if (lock) @@ -1019,12 +1004,6 @@ int reiserfs_removexattr(struct dentry *dentry, const char *name) get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) return -EOPNOTSUPP; - if (IS_RDONLY(dentry->d_inode)) - return -EROFS; - - if (IS_IMMUTABLE(dentry->d_inode) || IS_APPEND(dentry->d_inode)) - return -EPERM; - reiserfs_write_lock_xattr_i(dentry->d_inode); reiserfs_read_lock_xattrs(dentry->d_sb); diff --git a/fs/reiserfs/xattr_user.c b/fs/reiserfs/xattr_user.c index 51458048ca66..073f39364b11 100644 --- a/fs/reiserfs/xattr_user.c +++ b/fs/reiserfs/xattr_user.c @@ -16,18 +16,10 @@ static int user_get(struct inode *inode, const char *name, void *buffer, size_t size) { - int error; - if (strlen(name) < sizeof(XATTR_USER_PREFIX)) return -EINVAL; - if (!reiserfs_xattrs_user(inode->i_sb)) return -EOPNOTSUPP; - - error = reiserfs_permission_locked(inode, MAY_READ, NULL); - if (error) - return error; - return reiserfs_xattr_get(inode, name, buffer, size); } @@ -36,43 +28,21 @@ user_set(struct inode *inode, const char *name, const void *buffer, size_t size, int flags) { - int error; - if (strlen(name) < sizeof(XATTR_USER_PREFIX)) return -EINVAL; if (!reiserfs_xattrs_user(inode->i_sb)) return -EOPNOTSUPP; - - if (!S_ISREG(inode->i_mode) && - (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX)) - return -EPERM; - - error = reiserfs_permission_locked(inode, MAY_WRITE, NULL); - if (error) - return error; - return reiserfs_xattr_set(inode, name, buffer, size, flags); } static int user_del(struct inode *inode, const char *name) { - int error; - if (strlen(name) < sizeof(XATTR_USER_PREFIX)) return -EINVAL; if (!reiserfs_xattrs_user(inode->i_sb)) return -EOPNOTSUPP; - - if (!S_ISREG(inode->i_mode) && - (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX)) - return -EPERM; - - error = reiserfs_permission_locked(inode, MAY_WRITE, NULL); - if (error) - return error; - return 0; } diff --git a/fs/xattr.c b/fs/xattr.c index 386a532ee5a9..80eca7d3d69f 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -19,6 +19,149 @@ #include <linux/fsnotify.h> #include <asm/uaccess.h> + +/* + * Check permissions for extended attribute access. This is a bit complicated + * because different namespaces have very different rules. + */ +static int +xattr_permission(struct inode *inode, const char *name, int mask) +{ + /* + * We can never set or remove an extended attribute on a read-only + * filesystem or on an immutable / append-only inode. + */ + if (mask & MAY_WRITE) { + if (IS_RDONLY(inode)) + return -EROFS; + if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) + return -EPERM; + } + + /* + * No restriction for security.* and system.* from the VFS. Decision + * on these is left to the underlying filesystem / security module. + */ + if (!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) || + !strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) + return 0; + + /* + * The trusted.* namespace can only accessed by a privilegued user. + */ + if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) + return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM); + + if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) { + if (!S_ISREG(inode->i_mode) && + (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX)) + return -EPERM; + } + + return permission(inode, mask, NULL); +} + +int +vfs_setxattr(struct dentry *dentry, char *name, void *value, + size_t size, int flags) +{ + struct inode *inode = dentry->d_inode; + int error; + + error = xattr_permission(inode, name, MAY_WRITE); + if (error) + return error; + + mutex_lock(&inode->i_mutex); + error = security_inode_setxattr(dentry, name, value, size, flags); + if (error) + goto out; + error = -EOPNOTSUPP; + if (inode->i_op->setxattr) { + error = inode->i_op->setxattr(dentry, name, value, size, flags); + if (!error) { + fsnotify_xattr(dentry); + security_inode_post_setxattr(dentry, name, value, + size, flags); + } + } else if (!strncmp(name, XATTR_SECURITY_PREFIX, + XATTR_SECURITY_PREFIX_LEN)) { + const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; + error = security_inode_setsecurity(inode, suffix, value, + size, flags); + if (!error) + fsnotify_xattr(dentry); + } +out: + mutex_unlock(&inode->i_mutex); + return error; +} +EXPORT_SYMBOL_GPL(vfs_setxattr); + +ssize_t +vfs_getxattr(struct dentry *dentry, char *name, void *value, size_t size) +{ + struct inode *inode = dentry->d_inode; + int error; + + error = xattr_permission(inode, name, MAY_READ); + if (error) + return error; + + error = security_inode_getxattr(dentry, name); + if (error) + return error; + + if (inode->i_op->getxattr) + error = inode->i_op->getxattr(dentry, name, value, size); + else + error = -EOPNOTSUPP; + + if (!strncmp(name, XATTR_SECURITY_PREFIX, + XATTR_SECURITY_PREFIX_LEN)) { + const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; + int ret = security_inode_getsecurity(inode, suffix, value, + size, error); + /* + * Only overwrite the return value if a security module + * is actually active. + */ + if (ret != -EOPNOTSUPP) + error = ret; + } + + return error; +} +EXPORT_SYMBOL_GPL(vfs_getxattr); + +int +vfs_removexattr(struct dentry *dentry, char *name) +{ + struct inode *inode = dentry->d_inode; + int error; + + if (!inode->i_op->removexattr) + return -EOPNOTSUPP; + + error = xattr_permission(inode, name, MAY_WRITE); + if (error) + return error; + + error = security_inode_removexattr(dentry, name); + if (error) + return error; + + mutex_lock(&inode->i_mutex); + error = inode->i_op->removexattr(dentry, name); + mutex_unlock(&inode->i_mutex); + + if (!error) + fsnotify_xattr(dentry); + return error; +} +EXPORT_SYMBOL_GPL(vfs_removexattr); + + /* * Extended attribute SET operations */ @@ -51,29 +194,7 @@ setxattr(struct dentry *d, char __user *name, void __user *value, } } - mutex_lock(&d->d_inode->i_mutex); - error = security_inode_setxattr(d, kname, kvalue, size, flags); - if (error) - goto out; - error = -EOPNOTSUPP; - if (d->d_inode->i_op && d->d_inode->i_op->setxattr) { - error = d->d_inode->i_op->setxattr(d, kname, kvalue, - size, flags); - if (!error) { - fsnotify_xattr(d); - security_inode_post_setxattr(d, kname, kvalue, - size, flags); - } - } else if (!strncmp(kname, XATTR_SECURITY_PREFIX, - sizeof XATTR_SECURITY_PREFIX - 1)) { - const char *suffix = kname + sizeof XATTR_SECURITY_PREFIX - 1; - error = security_inode_setsecurity(d->d_inode, suffix, kvalue, - size, flags); - if (!error) - fsnotify_xattr(d); - } -out: - mutex_unlock(&d->d_inode->i_mutex); + error = vfs_setxattr(d, kname, kvalue, size, flags); kfree(kvalue); return error; } @@ -147,22 +268,7 @@ getxattr(struct dentry *d, char __user *name, void __user *value, size_t size) return -ENOMEM; } - error = security_inode_getxattr(d, kname); - if (error) - goto out; - error = -EOPNOTSUPP; - if (d->d_inode->i_op && d->d_inode->i_op->getxattr) - error = d->d_inode->i_op->getxattr(d, kname, kvalue, size); - - if (!strncmp(kname, XATTR_SECURITY_PREFIX, - sizeof XATTR_SECURITY_PREFIX - 1)) { - const char *suffix = kname + sizeof XATTR_SECURITY_PREFIX - 1; - int rv = security_inode_getsecurity(d->d_inode, suffix, kvalue, - size, error); - /* Security module active: overwrite error value */ - if (rv != -EOPNOTSUPP) - error = rv; - } + error = vfs_getxattr(d, kname, kvalue, size); if (error > 0) { if (size && copy_to_user(value, kvalue, error)) error = -EFAULT; @@ -171,7 +277,6 @@ getxattr(struct dentry *d, char __user *name, void __user *value, size_t size) than XATTR_SIZE_MAX bytes. Not possible. */ error = -E2BIG; } -out: kfree(kvalue); return error; } @@ -318,19 +423,7 @@ removexattr(struct dentry *d, char __user *name) if (error < 0) return error; - error = -EOPNOTSUPP; - if (d->d_inode->i_op && d->d_inode->i_op->removexattr) { - error = security_inode_removexattr(d, kname); - if (error) - goto out; - mutex_lock(&d->d_inode->i_mutex); - error = d->d_inode->i_op->removexattr(d, kname); - mutex_unlock(&d->d_inode->i_mutex); - if (!error) - fsnotify_xattr(d); - } -out: - return error; + return vfs_removexattr(d, kname); } asmlinkage long diff --git a/fs/xfs/Kbuild b/fs/xfs/Kbuild new file mode 100644 index 000000000000..2566e96706f1 --- /dev/null +++ b/fs/xfs/Kbuild @@ -0,0 +1,6 @@ +# +# The xfs people like to share Makefile with 2.6 and 2.4. +# Utilise file named Kbuild file which has precedence over Makefile. +# + +include $(srctree)/$(obj)/Makefile-linux-2.6 diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index b78b5eb9e96c..f98c5be3dfe7 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c @@ -530,6 +530,8 @@ xfs_attrmulti_attr_set( char *kbuf; int error = EFAULT; + if (IS_RDONLY(&vp->v_inode)) + return -EROFS; if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode)) return EPERM; if (len > XATTR_SIZE_MAX) @@ -557,6 +559,9 @@ xfs_attrmulti_attr_remove( { int error; + + if (IS_RDONLY(&vp->v_inode)) + return -EROFS; if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode)) return EPERM; diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c index c83ae15bb0e6..a7c9ba1a9f7b 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl32.c +++ b/fs/xfs/linux-2.6/xfs_ioctl32.c @@ -19,7 +19,6 @@ #include <linux/compat.h> #include <linux/init.h> #include <linux/ioctl.h> -#include <linux/ioctl32.h> #include <linux/syscalls.h> #include <linux/types.h> #include <linux/fs.h> diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 41c478bb1ffc..97fb1470cf28 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c @@ -54,6 +54,9 @@ #include <linux/xattr.h> #include <linux/namei.h> +#define IS_NOATIME(inode) ((inode->i_sb->s_flags & MS_NOATIME) || \ + (S_ISDIR(inode->i_mode) && inode->i_sb->s_flags & MS_NODIRATIME)) + /* * Change the requested timestamp in the given inode. * We don't lock across timestamp updates, and we don't log them but diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 5675117ef227..885dfafeabee 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c @@ -713,7 +713,7 @@ start: } if (likely(!(ioflags & IO_INVIS))) { - inode_update_time(inode, 1); + file_update_time(file); xfs_ichgtime_fast(xip, inode, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); } diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index 5484eeb460c8..1a11c2b51701 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c @@ -117,11 +117,6 @@ xfs_attr_fetch(xfs_inode_t *ip, const char *name, int namelen, ip->i_d.di_anextents == 0)) return(ENOATTR); - if (!(flags & (ATTR_KERNACCESS|ATTR_SECURE))) { - if ((error = xfs_iaccess(ip, S_IRUSR, cred))) - return(XFS_ERROR(error)); - } - /* * Fill in the arg structure for this request. */ @@ -425,7 +420,7 @@ xfs_attr_set(bhv_desc_t *bdp, const char *name, char *value, int valuelen, int f struct cred *cred) { xfs_inode_t *dp; - int namelen, error; + int namelen; namelen = strlen(name); if (namelen >= MAXNAMELEN) @@ -437,14 +432,6 @@ xfs_attr_set(bhv_desc_t *bdp, const char *name, char *value, int valuelen, int f if (XFS_FORCED_SHUTDOWN(dp->i_mount)) return (EIO); - xfs_ilock(dp, XFS_ILOCK_SHARED); - if (!(flags & ATTR_SECURE) && - (error = xfs_iaccess(dp, S_IWUSR, cred))) { - xfs_iunlock(dp, XFS_ILOCK_SHARED); - return(XFS_ERROR(error)); - } - xfs_iunlock(dp, XFS_ILOCK_SHARED); - return xfs_attr_set_int(dp, name, namelen, value, valuelen, flags); } @@ -579,7 +566,7 @@ int xfs_attr_remove(bhv_desc_t *bdp, const char *name, int flags, struct cred *cred) { xfs_inode_t *dp; - int namelen, error; + int namelen; namelen = strlen(name); if (namelen >= MAXNAMELEN) @@ -592,11 +579,7 @@ xfs_attr_remove(bhv_desc_t *bdp, const char *name, int flags, struct cred *cred) return (EIO); xfs_ilock(dp, XFS_ILOCK_SHARED); - if (!(flags & ATTR_SECURE) && - (error = xfs_iaccess(dp, S_IWUSR, cred))) { - xfs_iunlock(dp, XFS_ILOCK_SHARED); - return(XFS_ERROR(error)); - } else if (XFS_IFORK_Q(dp) == 0 || + if (XFS_IFORK_Q(dp) == 0 || (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && dp->i_d.di_anextents == 0)) { xfs_iunlock(dp, XFS_ILOCK_SHARED); @@ -668,12 +651,6 @@ xfs_attr_list(bhv_desc_t *bdp, char *buffer, int bufsize, int flags, return (EIO); xfs_ilock(dp, XFS_ILOCK_SHARED); - if (!(flags & ATTR_SECURE) && - (error = xfs_iaccess(dp, S_IRUSR, cred))) { - xfs_iunlock(dp, XFS_ILOCK_SHARED); - return(XFS_ERROR(error)); - } - /* * Decide on what work routines to call based on the inode size. */ |
