From d5daaaff24026d59130e97a406f2999118bafdc3 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 19 Mar 2013 19:46:45 -0400 Subject: reiserfs: don't wank with EFBIG before calling do_sync_write() look for file_capable() in there... Signed-off-by: Al Viro --- fs/reiserfs/file.c | 61 +----------------------------------------------------- 1 file changed, 1 insertion(+), 60 deletions(-) (limited to 'fs/reiserfs') diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index 6165bd4784f..dcaafcfc23b 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c @@ -234,68 +234,9 @@ int reiserfs_commit_page(struct inode *inode, struct page *page, return ret; } -/* Write @count bytes at position @ppos in a file indicated by @file - from the buffer @buf. - - generic_file_write() is only appropriate for filesystems that are not seeking to optimize performance and want - something simple that works. It is not for serious use by general purpose filesystems, excepting the one that it was - written for (ext2/3). This is for several reasons: - - * It has no understanding of any filesystem specific optimizations. - - * It enters the filesystem repeatedly for each page that is written. - - * It depends on reiserfs_get_block() function which if implemented by reiserfs performs costly search_by_key - * operation for each page it is supplied with. By contrast reiserfs_file_write() feeds as much as possible at a time - * to reiserfs which allows for fewer tree traversals. - - * Each indirect pointer insertion takes a lot of cpu, because it involves memory moves inside of blocks. - - * Asking the block allocation code for blocks one at a time is slightly less efficient. - - All of these reasons for not using only generic file write were understood back when reiserfs was first miscoded to - use it, but we were in a hurry to make code freeze, and so it couldn't be revised then. This new code should make - things right finally. - - Future Features: providing search_by_key with hints. - -*/ -static ssize_t reiserfs_file_write(struct file *file, /* the file we are going to write into */ - const char __user * buf, /* pointer to user supplied data - (in userspace) */ - size_t count, /* amount of bytes to write */ - loff_t * ppos /* pointer to position in file that we start writing at. Should be updated to - * new current position before returning. */ - ) -{ - struct inode *inode = file_inode(file); // Inode of the file that we are writing to. - /* To simplify coding at this time, we store - locked pages in array for now */ - struct reiserfs_transaction_handle th; - th.t_trans_id = 0; - - /* If a filesystem is converted from 3.5 to 3.6, we'll have v3.5 items - * lying around (most of the disk, in fact). Despite the filesystem - * now being a v3.6 format, the old items still can't support large - * file sizes. Catch this case here, as the rest of the VFS layer is - * oblivious to the different limitations between old and new items. - * reiserfs_setattr catches this for truncates. This chunk is lifted - * from generic_write_checks. */ - if (get_inode_item_key_version (inode) == KEY_FORMAT_3_5 && - *ppos + count > MAX_NON_LFS) { - if (*ppos >= MAX_NON_LFS) { - return -EFBIG; - } - if (count > MAX_NON_LFS - (unsigned long)*ppos) - count = MAX_NON_LFS - (unsigned long)*ppos; - } - - return do_sync_write(file, buf, count, ppos); -} - const struct file_operations reiserfs_file_operations = { .read = do_sync_read, - .write = reiserfs_file_write, + .write = do_sync_write, .unlocked_ioctl = reiserfs_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = reiserfs_compat_ioctl, -- cgit v1.2.3-70-g09d2 From 121daf5f8b4a60158e26f357eb286acf83eb33b4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 30 Mar 2013 20:16:20 -0400 Subject: reiserfs: use proc_remove_subtree() Signed-off-by: Al Viro --- fs/reiserfs/procfs.c | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) (limited to 'fs/reiserfs') diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c index 9cc0740adff..274adea363f 100644 --- a/fs/reiserfs/procfs.c +++ b/fs/reiserfs/procfs.c @@ -499,29 +499,17 @@ int reiserfs_proc_info_init(struct super_block *sb) int reiserfs_proc_info_done(struct super_block *sb) { struct proc_dir_entry *de = REISERFS_SB(sb)->procdir; - char b[BDEVNAME_SIZE]; - char *s; + if (de) { + char b[BDEVNAME_SIZE]; + char *s; - /* Some block devices use /'s */ - strlcpy(b, reiserfs_bdevname(sb), BDEVNAME_SIZE); - s = strchr(b, '/'); - if (s) - *s = '!'; + /* Some block devices use /'s */ + strlcpy(b, reiserfs_bdevname(sb), BDEVNAME_SIZE); + s = strchr(b, '/'); + if (s) + *s = '!'; - if (de) { - remove_proc_entry("journal", de); - remove_proc_entry("oidmap", de); - remove_proc_entry("on-disk-super", de); - remove_proc_entry("bitmap", de); - remove_proc_entry("per-level", de); - remove_proc_entry("super", de); - remove_proc_entry("version", de); - } - spin_lock(&__PINFO(sb).lock); - __PINFO(sb).exiting = 1; - spin_unlock(&__PINFO(sb).lock); - if (proc_info_root) { - remove_proc_entry(b, proc_info_root); + remove_proc_subtree(b, proc_info_root); REISERFS_SB(sb)->procdir = NULL; } return 0; -- cgit v1.2.3-70-g09d2 From 270b5ac2151707c25d3327722c5badfbd95945bc Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 12 Apr 2013 02:48:30 +0100 Subject: proc: Add proc_mkdir_data() Add proc_mkdir_data() to allow procfs directories to be created that are annotated at the time of creation with private data rather than doing this post-creation. This means no access is then required to the proc_dir_entry struct to set this. Signed-off-by: David Howells Acked-by: Mauro Carvalho Chehab Acked-by: Greg Kroah-Hartman cc: Neela Syam Kolli cc: Jerry Chuang cc: linux-scsi@vger.kernel.org cc: devel@driverdev.osuosl.org cc: linux-wireless@vger.kernel.org Signed-off-by: Al Viro --- drivers/message/i2o/i2o_proc.c | 8 ++------ drivers/scsi/megaraid.c | 4 ++-- drivers/staging/rtl8192u/r8192U_core.c | 3 +-- fs/proc/generic.c | 30 ++++++++++++------------------ fs/reiserfs/procfs.c | 3 +-- include/linux/proc_fs.h | 13 ++++++++++--- 6 files changed, 28 insertions(+), 33 deletions(-) (limited to 'fs/reiserfs') diff --git a/drivers/message/i2o/i2o_proc.c b/drivers/message/i2o/i2o_proc.c index 70a840f9b28..b7d87cd227a 100644 --- a/drivers/message/i2o/i2o_proc.c +++ b/drivers/message/i2o/i2o_proc.c @@ -1913,14 +1913,12 @@ static void i2o_proc_device_add(struct proc_dir_entry *dir, osm_debug("adding device /proc/i2o/%s/%s\n", dev->iop->name, buff); - devdir = proc_mkdir(buff, dir); + devdir = proc_mkdir_data(buff, 0, dir, dev); if (!devdir) { osm_warn("Could not allocate procdir!\n"); return; } - devdir->data = dev; - i2o_proc_create_entries(devdir, generic_dev_entries, dev); /* Inform core that we want updates about this device's status */ @@ -1954,12 +1952,10 @@ static int i2o_proc_iop_add(struct proc_dir_entry *dir, osm_debug("adding IOP /proc/i2o/%s\n", c->name); - iopdir = proc_mkdir(c->name, dir); + iopdir = proc_mkdir_data(c->name, 0, dir, c); if (!iopdir) return -1; - iopdir->data = c; - i2o_proc_create_entries(iopdir, i2o_proc_generic_iop_entries, c); list_for_each_entry(dev, &c->devices, list) diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index a1c90bd34e7..ef3384d39e1 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -2818,12 +2818,12 @@ mega_create_proc_entry(int index, struct proc_dir_entry *parent) sprintf(string, "hba%d", adapter->host->host_no); - dir = adapter->controller_proc_dir_entry = proc_mkdir(string, parent); + dir = adapter->controller_proc_dir_entry = + proc_mkdir_data(string, 0, parent, adapter); if(!dir) { printk(KERN_WARNING "\nmegaraid: proc_mkdir failed\n"); return; } - dir->data = adapter; for (f = mega_proc_files; f->name; f++) { de = proc_create_data(f->name, S_IRUSR, dir, &mega_proc_fops, diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 433c3df95de..d81d7d55f25 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -672,13 +672,12 @@ void rtl8192_proc_init_one(struct net_device *dev) struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); if (rtl8192_proc) { - priv->dir_dev = proc_mkdir(dev->name, rtl8192_proc); + priv->dir_dev = proc_mkdir_data(dev->name, 0, rtl8192_proc, dev); if (!priv->dir_dev) { RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n", dev->name); return; } - priv->dir_dev->data = dev; for (f = rtl8192_proc_files; f->name[0]; f++) { if (!proc_create_data(f->name, S_IFREG | S_IRUGO, diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 5f6f6c38701..4074da57c99 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -428,13 +428,17 @@ struct proc_dir_entry *proc_symlink(const char *name, } EXPORT_SYMBOL(proc_symlink); -struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode, - struct proc_dir_entry *parent) +struct proc_dir_entry *proc_mkdir_data(const char *name, umode_t mode, + struct proc_dir_entry *parent, void *data) { struct proc_dir_entry *ent; + if (mode == 0) + mode = S_IRUGO | S_IXUGO; + ent = __proc_create(&parent, name, S_IFDIR | mode, 2); if (ent) { + ent->data = data; if (proc_register(parent, ent) < 0) { kfree(ent); ent = NULL; @@ -442,29 +446,19 @@ struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode, } return ent; } -EXPORT_SYMBOL(proc_mkdir_mode); +EXPORT_SYMBOL_GPL(proc_mkdir_data); -struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name, - struct proc_dir_entry *parent) +struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode, + struct proc_dir_entry *parent) { - struct proc_dir_entry *ent; - - ent = __proc_create(&parent, name, S_IFDIR | S_IRUGO | S_IXUGO, 2); - if (ent) { - ent->data = net; - if (proc_register(parent, ent) < 0) { - kfree(ent); - ent = NULL; - } - } - return ent; + return proc_mkdir_data(name, mode, parent, NULL); } -EXPORT_SYMBOL_GPL(proc_net_mkdir); +EXPORT_SYMBOL(proc_mkdir_mode); struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent) { - return proc_mkdir_mode(name, S_IRUGO | S_IXUGO, parent); + return proc_mkdir_data(name, 0, parent, NULL); } EXPORT_SYMBOL(proc_mkdir); diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c index 274adea363f..07c2162ef55 100644 --- a/fs/reiserfs/procfs.c +++ b/fs/reiserfs/procfs.c @@ -479,9 +479,8 @@ int reiserfs_proc_info_init(struct super_block *sb) *s = '!'; spin_lock_init(&__PINFO(sb).lock); - REISERFS_SB(sb)->procdir = proc_mkdir(b, proc_info_root); + REISERFS_SB(sb)->procdir = proc_mkdir_data(b, 0, proc_info_root, sb); if (REISERFS_SB(sb)->procdir) { - REISERFS_SB(sb)->procdir->data = sb; add_file(sb, "version", show_version); add_file(sb, "super", show_super); add_file(sb, "per-level", show_per_level); diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 80d9e24a79a..a0fb1c2f1d8 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -73,6 +73,8 @@ extern int remove_proc_subtree(const char *name, struct proc_dir_entry *parent); extern struct proc_dir_entry *proc_symlink(const char *, struct proc_dir_entry *, const char *); extern struct proc_dir_entry *proc_mkdir(const char *,struct proc_dir_entry *); +extern struct proc_dir_entry *proc_mkdir_data(const char *, umode_t, + struct proc_dir_entry *, void *); extern struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode, struct proc_dir_entry *parent); @@ -82,9 +84,6 @@ static inline struct proc_dir_entry *proc_create(const char *name, umode_t mode, return proc_create_data(name, mode, parent, proc_fops, NULL); } -extern struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name, - struct proc_dir_entry *parent); - extern void proc_set_size(struct proc_dir_entry *, loff_t); extern void proc_set_user(struct proc_dir_entry *, kuid_t, kgid_t); #else @@ -108,6 +107,8 @@ static inline struct proc_dir_entry *proc_symlink(const char *name, struct proc_dir_entry *parent,const char *dest) {return NULL;} static inline struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent) {return NULL;} +static inline struct proc_dir_entry *proc_mkdir_data(const char *name, + umode_t mode, struct proc_dir_entry *parent, void *data) { return NULL; } static inline struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode, struct proc_dir_entry *parent) { return NULL; } static inline void proc_set_size(struct proc_dir_entry *de, loff_t size) {} @@ -153,4 +154,10 @@ static inline void *PDE_DATA(const struct inode *inode) return PROC_I(inode)->pde->data; } +static inline struct proc_dir_entry *proc_net_mkdir( + struct net *net, const char *name, struct proc_dir_entry *parent) +{ + return proc_mkdir_data(name, 0, parent, net); +} + #endif /* _LINUX_PROC_FS_H */ -- cgit v1.2.3-70-g09d2 From e42270a19e357d7808890bdbeb0cae97f2a2d234 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 12 Apr 2013 11:17:06 +0100 Subject: reiserfs: Don't access the proc_dir_entry in r_open(), r_start() r_show() Don't access the proc_dir_entry in ReiserFS's r_open(), r_start() r_show() procfs interface functions. ReiserFS stores the ->show() method pointer in PDE->data and the super_block pointer in PDE->parent->data. This isn't changing. Currently, ReiserFS passes the PDE pointer into seq_file::private from r_open() so that r_start() and r_show() can then access it. Instead, use seq_open_private() to allocate a two-pointer struct that's passed through seq_file::private and put the ->show() method and the sb pointers in there. Signed-off-by: David Howells cc: reiserfs-devel@vger.kernel.org Signed-off-by: Al Viro --- fs/reiserfs/procfs.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) (limited to 'fs/reiserfs') diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c index 07c2162ef55..33532f79b4f 100644 --- a/fs/reiserfs/procfs.c +++ b/fs/reiserfs/procfs.c @@ -394,20 +394,24 @@ static int set_sb(struct super_block *sb, void *data) return -ENOENT; } +struct reiserfs_seq_private { + struct super_block *sb; + int (*show) (struct seq_file *, struct super_block *); +}; + static void *r_start(struct seq_file *m, loff_t * pos) { - struct proc_dir_entry *de = m->private; - struct super_block *s = de->parent->data; + struct reiserfs_seq_private *priv = m->private; loff_t l = *pos; if (l) return NULL; - if (IS_ERR(sget(&reiserfs_fs_type, test_sb, set_sb, 0, s))) + if (IS_ERR(sget(&reiserfs_fs_type, test_sb, set_sb, 0, priv->sb))) return NULL; - up_write(&s->s_umount); - return s; + up_write(&priv->sb->s_umount); + return priv->sb; } static void *r_next(struct seq_file *m, void *v, loff_t * pos) @@ -426,9 +430,8 @@ static void r_stop(struct seq_file *m, void *v) static int r_show(struct seq_file *m, void *v) { - struct proc_dir_entry *de = m->private; - int (*show) (struct seq_file *, struct super_block *) = de->data; - return show(m, v); + struct reiserfs_seq_private *priv = m->private; + return priv->show(m, v); } static const struct seq_operations r_ops = { @@ -440,11 +443,15 @@ static const struct seq_operations r_ops = { static int r_open(struct inode *inode, struct file *file) { - int ret = seq_open(file, &r_ops); + struct reiserfs_seq_private *priv; + int ret = seq_open_private(file, &r_ops, + sizeof(struct reiserfs_seq_private)); if (!ret) { struct seq_file *m = file->private_data; - m->private = PDE(inode); + priv = m->private; + priv->sb = proc_get_parent_data(inode); + priv->show = PDE_DATA(inode); } return ret; } @@ -453,7 +460,7 @@ static const struct file_operations r_file_operations = { .open = r_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = seq_release_private, .owner = THIS_MODULE, }; -- cgit v1.2.3-70-g09d2