From 1f33c41c03daece85a84b8dcea5733f3efe3e2b0 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 29 Sep 2014 16:08:21 -0700 Subject: seq_file: Rename seq_overflow() to seq_has_overflowed() and make public The return values of seq_printf/puts/putc are frequently misused. Start down a path to remove all the return value uses of these functions. Move the seq_overflow() to a global inlined function called seq_has_overflowed() that can be used by the users of seq_file() calls. Update the documentation to not show return types for seq_printf et al. Add a description of seq_has_overflowed(). Link: http://lkml.kernel.org/p/848ac7e3d1c31cddf638a8526fa3c59fa6fdeb8a.1412031505.git.joe@perches.com Cc: Al Viro Signed-off-by: Joe Perches [ Reworked the original patch from Joe ] Signed-off-by: Steven Rostedt --- Documentation/filesystems/seq_file.txt | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/seq_file.txt b/Documentation/filesystems/seq_file.txt index 8ea3e90ace07..b797ed38de46 100644 --- a/Documentation/filesystems/seq_file.txt +++ b/Documentation/filesystems/seq_file.txt @@ -180,23 +180,19 @@ output must be passed to the seq_file code. Some utility functions have been defined which make this task easy. Most code will simply use seq_printf(), which works pretty much like -printk(), but which requires the seq_file pointer as an argument. It is -common to ignore the return value from seq_printf(), but a function -producing complicated output may want to check that value and quit if -something non-zero is returned; an error return means that the seq_file -buffer has been filled and further output will be discarded. +printk(), but which requires the seq_file pointer as an argument. For straight character output, the following functions may be used: - int seq_putc(struct seq_file *m, char c); - int seq_puts(struct seq_file *m, const char *s); - int seq_escape(struct seq_file *m, const char *s, const char *esc); + seq_putc(struct seq_file *m, char c); + seq_puts(struct seq_file *m, const char *s); + seq_escape(struct seq_file *m, const char *s, const char *esc); The first two output a single character and a string, just like one would expect. seq_escape() is like seq_puts(), except that any character in s which is in the string esc will be represented in octal form in the output. -There is also a pair of functions for printing filenames: +There are also a pair of functions for printing filenames: int seq_path(struct seq_file *m, struct path *path, char *esc); int seq_path_root(struct seq_file *m, struct path *path, @@ -209,6 +205,14 @@ root is desired, it can be used with seq_path_root(). Note that, if it turns out that path cannot be reached from root, the value of root will be changed in seq_file_root() to a root which *does* work. +A function producing complicated output may want to check + bool seq_has_overflowed(struct seq_file *m); +and avoid further seq_ calls if true is returned. + +A true return from seq_has_overflowed means that the seq_file buffer will +be discarded and the seq_show function will attempt to allocate a larger +buffer and retry printing. + Making it all work -- cgit v1.2.3 From a3816ab0e8fe542a89a53b82506a8ddac063fbe3 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 29 Sep 2014 16:08:25 -0700 Subject: fs: Convert show_fdinfo functions to void seq_printf functions shouldn't really check the return value. Checking seq_has_overflowed() occasionally is used instead. Update vfs documentation. Link: http://lkml.kernel.org/p/e37e6e7b76acbdcc3bb4ab2a57c8f8ca1ae11b9a.1412031505.git.joe@perches.com Cc: David S. Miller Cc: Al Viro Signed-off-by: Joe Perches [ did a few clean ups ] Signed-off-by: Steven Rostedt --- Documentation/filesystems/vfs.txt | 2 +- drivers/net/tun.c | 4 +- fs/eventfd.c | 9 ++--- fs/eventpoll.c | 13 +++---- fs/notify/fdinfo.c | 78 ++++++++++++++++----------------------- fs/notify/fdinfo.h | 4 +- fs/proc/fd.c | 3 +- fs/signalfd.c | 4 +- fs/timerfd.c | 27 +++++++------- include/linux/fs.h | 2 +- 10 files changed, 63 insertions(+), 83 deletions(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index fceff7c00a3c..af1dbc1823bb 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -828,7 +828,7 @@ struct file_operations { ssize_t (*splice_read)(struct file *, struct pipe_inode_info *, size_t, unsigned int); int (*setlease)(struct file *, long arg, struct file_lock **, void **); long (*fallocate)(struct file *, int mode, loff_t offset, loff_t len); - int (*show_fdinfo)(struct seq_file *m, struct file *f); + void (*show_fdinfo)(struct seq_file *m, struct file *f); }; Again, all methods are called without any locks being held, unless diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 186ce541c657..a3420e091689 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -2209,7 +2209,7 @@ static int tun_chr_close(struct inode *inode, struct file *file) } #ifdef CONFIG_PROC_FS -static int tun_chr_show_fdinfo(struct seq_file *m, struct file *f) +static void tun_chr_show_fdinfo(struct seq_file *m, struct file *f) { struct tun_struct *tun; struct ifreq ifr; @@ -2225,7 +2225,7 @@ static int tun_chr_show_fdinfo(struct seq_file *m, struct file *f) if (tun) tun_put(tun); - return seq_printf(m, "iff:\t%s\n", ifr.ifr_name); + seq_printf(m, "iff:\t%s\n", ifr.ifr_name); } #endif diff --git a/fs/eventfd.c b/fs/eventfd.c index d6a88e7812f3..4b0a226024fa 100644 --- a/fs/eventfd.c +++ b/fs/eventfd.c @@ -287,17 +287,14 @@ static ssize_t eventfd_write(struct file *file, const char __user *buf, size_t c } #ifdef CONFIG_PROC_FS -static int eventfd_show_fdinfo(struct seq_file *m, struct file *f) +static void eventfd_show_fdinfo(struct seq_file *m, struct file *f) { struct eventfd_ctx *ctx = f->private_data; - int ret; spin_lock_irq(&ctx->wqh.lock); - ret = seq_printf(m, "eventfd-count: %16llx\n", - (unsigned long long)ctx->count); + seq_printf(m, "eventfd-count: %16llx\n", + (unsigned long long)ctx->count); spin_unlock_irq(&ctx->wqh.lock); - - return ret; } #endif diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 7bcfff900f05..d77f94491352 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -870,25 +870,22 @@ static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait) } #ifdef CONFIG_PROC_FS -static int ep_show_fdinfo(struct seq_file *m, struct file *f) +static void ep_show_fdinfo(struct seq_file *m, struct file *f) { struct eventpoll *ep = f->private_data; struct rb_node *rbp; - int ret = 0; mutex_lock(&ep->mtx); for (rbp = rb_first(&ep->rbr); rbp; rbp = rb_next(rbp)) { struct epitem *epi = rb_entry(rbp, struct epitem, rbn); - ret = seq_printf(m, "tfd: %8d events: %8x data: %16llx\n", - epi->ffd.fd, epi->event.events, - (long long)epi->event.data); - if (ret) + seq_printf(m, "tfd: %8d events: %8x data: %16llx\n", + epi->ffd.fd, epi->event.events, + (long long)epi->event.data); + if (seq_has_overflowed(m)) break; } mutex_unlock(&ep->mtx); - - return ret; } #endif diff --git a/fs/notify/fdinfo.c b/fs/notify/fdinfo.c index 9d7e2b9659cb..6ffd220eb14d 100644 --- a/fs/notify/fdinfo.c +++ b/fs/notify/fdinfo.c @@ -20,25 +20,24 @@ #if defined(CONFIG_INOTIFY_USER) || defined(CONFIG_FANOTIFY) -static int show_fdinfo(struct seq_file *m, struct file *f, - int (*show)(struct seq_file *m, struct fsnotify_mark *mark)) +static void show_fdinfo(struct seq_file *m, struct file *f, + void (*show)(struct seq_file *m, + struct fsnotify_mark *mark)) { struct fsnotify_group *group = f->private_data; struct fsnotify_mark *mark; - int ret = 0; mutex_lock(&group->mark_mutex); list_for_each_entry(mark, &group->marks_list, g_list) { - ret = show(m, mark); - if (ret) + show(m, mark); + if (seq_has_overflowed(m)) break; } mutex_unlock(&group->mark_mutex); - return ret; } #if defined(CONFIG_EXPORTFS) -static int show_mark_fhandle(struct seq_file *m, struct inode *inode) +static void show_mark_fhandle(struct seq_file *m, struct inode *inode) { struct { struct file_handle handle; @@ -52,71 +51,62 @@ static int show_mark_fhandle(struct seq_file *m, struct inode *inode) ret = exportfs_encode_inode_fh(inode, (struct fid *)f.handle.f_handle, &size, 0); if ((ret == FILEID_INVALID) || (ret < 0)) { WARN_ONCE(1, "Can't encode file handler for inotify: %d\n", ret); - return 0; + return; } f.handle.handle_type = ret; f.handle.handle_bytes = size * sizeof(u32); - ret = seq_printf(m, "fhandle-bytes:%x fhandle-type:%x f_handle:", - f.handle.handle_bytes, f.handle.handle_type); + seq_printf(m, "fhandle-bytes:%x fhandle-type:%x f_handle:", + f.handle.handle_bytes, f.handle.handle_type); for (i = 0; i < f.handle.handle_bytes; i++) - ret |= seq_printf(m, "%02x", (int)f.handle.f_handle[i]); - - return ret; + seq_printf(m, "%02x", (int)f.handle.f_handle[i]); } #else -static int show_mark_fhandle(struct seq_file *m, struct inode *inode) +static void show_mark_fhandle(struct seq_file *m, struct inode *inode) { - return 0; } #endif #ifdef CONFIG_INOTIFY_USER -static int inotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark) +static void inotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark) { struct inotify_inode_mark *inode_mark; struct inode *inode; - int ret = 0; if (!(mark->flags & (FSNOTIFY_MARK_FLAG_ALIVE | FSNOTIFY_MARK_FLAG_INODE))) - return 0; + return; inode_mark = container_of(mark, struct inotify_inode_mark, fsn_mark); inode = igrab(mark->i.inode); if (inode) { - ret = seq_printf(m, "inotify wd:%x ino:%lx sdev:%x " - "mask:%x ignored_mask:%x ", - inode_mark->wd, inode->i_ino, - inode->i_sb->s_dev, - mark->mask, mark->ignored_mask); - ret |= show_mark_fhandle(m, inode); - ret |= seq_putc(m, '\n'); + seq_printf(m, "inotify wd:%x ino:%lx sdev:%x mask:%x ignored_mask:%x ", + inode_mark->wd, inode->i_ino, inode->i_sb->s_dev, + mark->mask, mark->ignored_mask); + show_mark_fhandle(m, inode); + seq_putc(m, '\n'); iput(inode); } - - return ret; } -int inotify_show_fdinfo(struct seq_file *m, struct file *f) +void inotify_show_fdinfo(struct seq_file *m, struct file *f) { - return show_fdinfo(m, f, inotify_fdinfo); + show_fdinfo(m, f, inotify_fdinfo); } #endif /* CONFIG_INOTIFY_USER */ #ifdef CONFIG_FANOTIFY -static int fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark) +static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark) { unsigned int mflags = 0; struct inode *inode; - int ret = 0; if (!(mark->flags & FSNOTIFY_MARK_FLAG_ALIVE)) - return 0; + return; if (mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY) mflags |= FAN_MARK_IGNORED_SURV_MODIFY; @@ -124,26 +114,22 @@ static int fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark) if (mark->flags & FSNOTIFY_MARK_FLAG_INODE) { inode = igrab(mark->i.inode); if (!inode) - goto out; - ret = seq_printf(m, "fanotify ino:%lx sdev:%x " - "mflags:%x mask:%x ignored_mask:%x ", - inode->i_ino, inode->i_sb->s_dev, - mflags, mark->mask, mark->ignored_mask); - ret |= show_mark_fhandle(m, inode); - ret |= seq_putc(m, '\n'); + return; + seq_printf(m, "fanotify ino:%lx sdev:%x mflags:%x mask:%x ignored_mask:%x ", + inode->i_ino, inode->i_sb->s_dev, + mflags, mark->mask, mark->ignored_mask); + show_mark_fhandle(m, inode); + seq_putc(m, '\n'); iput(inode); } else if (mark->flags & FSNOTIFY_MARK_FLAG_VFSMOUNT) { struct mount *mnt = real_mount(mark->m.mnt); - ret = seq_printf(m, "fanotify mnt_id:%x mflags:%x mask:%x " - "ignored_mask:%x\n", mnt->mnt_id, mflags, - mark->mask, mark->ignored_mask); + seq_printf(m, "fanotify mnt_id:%x mflags:%x mask:%x ignored_mask:%x\n", + mnt->mnt_id, mflags, mark->mask, mark->ignored_mask); } -out: - return ret; } -int fanotify_show_fdinfo(struct seq_file *m, struct file *f) +void fanotify_show_fdinfo(struct seq_file *m, struct file *f) { struct fsnotify_group *group = f->private_data; unsigned int flags = 0; @@ -169,7 +155,7 @@ int fanotify_show_fdinfo(struct seq_file *m, struct file *f) seq_printf(m, "fanotify flags:%x event-flags:%x\n", flags, group->fanotify_data.f_flags); - return show_fdinfo(m, f, fanotify_fdinfo); + show_fdinfo(m, f, fanotify_fdinfo); } #endif /* CONFIG_FANOTIFY */ diff --git a/fs/notify/fdinfo.h b/fs/notify/fdinfo.h index 556afda990e9..9664c4904d6b 100644 --- a/fs/notify/fdinfo.h +++ b/fs/notify/fdinfo.h @@ -10,11 +10,11 @@ struct file; #ifdef CONFIG_PROC_FS #ifdef CONFIG_INOTIFY_USER -extern int inotify_show_fdinfo(struct seq_file *m, struct file *f); +void inotify_show_fdinfo(struct seq_file *m, struct file *f); #endif #ifdef CONFIG_FANOTIFY -extern int fanotify_show_fdinfo(struct seq_file *m, struct file *f); +void fanotify_show_fdinfo(struct seq_file *m, struct file *f); #endif #else /* CONFIG_PROC_FS */ diff --git a/fs/proc/fd.c b/fs/proc/fd.c index e11d7c590bb0..8e5ad83b629a 100644 --- a/fs/proc/fd.c +++ b/fs/proc/fd.c @@ -53,7 +53,8 @@ static int seq_show(struct seq_file *m, void *v) (long long)file->f_pos, f_flags, real_mount(file->f_path.mnt)->mnt_id); if (file->f_op->show_fdinfo) - ret = file->f_op->show_fdinfo(m, file); + file->f_op->show_fdinfo(m, file); + ret = seq_has_overflowed(m); fput(file); } diff --git a/fs/signalfd.c b/fs/signalfd.c index 424b7b65321f..7e412ad74836 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c @@ -230,7 +230,7 @@ static ssize_t signalfd_read(struct file *file, char __user *buf, size_t count, } #ifdef CONFIG_PROC_FS -static int signalfd_show_fdinfo(struct seq_file *m, struct file *f) +static void signalfd_show_fdinfo(struct seq_file *m, struct file *f) { struct signalfd_ctx *ctx = f->private_data; sigset_t sigmask; @@ -238,8 +238,6 @@ static int signalfd_show_fdinfo(struct seq_file *m, struct file *f) sigmask = ctx->sigmask; signotset(&sigmask); render_sigset_t(m, "sigmask:\t", &sigmask); - - return 0; } #endif diff --git a/fs/timerfd.c b/fs/timerfd.c index b46ffa94372a..b94fa6c3c6eb 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c @@ -288,7 +288,7 @@ static ssize_t timerfd_read(struct file *file, char __user *buf, size_t count, } #ifdef CONFIG_PROC_FS -static int timerfd_show(struct seq_file *m, struct file *file) +static void timerfd_show(struct seq_file *m, struct file *file) { struct timerfd_ctx *ctx = file->private_data; struct itimerspec t; @@ -298,18 +298,19 @@ static int timerfd_show(struct seq_file *m, struct file *file) t.it_interval = ktime_to_timespec(ctx->tintv); spin_unlock_irq(&ctx->wqh.lock); - return seq_printf(m, - "clockid: %d\n" - "ticks: %llu\n" - "settime flags: 0%o\n" - "it_value: (%llu, %llu)\n" - "it_interval: (%llu, %llu)\n", - ctx->clockid, (unsigned long long)ctx->ticks, - ctx->settime_flags, - (unsigned long long)t.it_value.tv_sec, - (unsigned long long)t.it_value.tv_nsec, - (unsigned long long)t.it_interval.tv_sec, - (unsigned long long)t.it_interval.tv_nsec); + seq_printf(m, + "clockid: %d\n" + "ticks: %llu\n" + "settime flags: 0%o\n" + "it_value: (%llu, %llu)\n" + "it_interval: (%llu, %llu)\n", + ctx->clockid, + (unsigned long long)ctx->ticks, + ctx->settime_flags, + (unsigned long long)t.it_value.tv_sec, + (unsigned long long)t.it_value.tv_nsec, + (unsigned long long)t.it_interval.tv_sec, + (unsigned long long)t.it_interval.tv_nsec); } #else #define timerfd_show NULL diff --git a/include/linux/fs.h b/include/linux/fs.h index a957d4366c24..01dd9052a142 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1491,7 +1491,7 @@ struct file_operations { int (*setlease)(struct file *, long, struct file_lock **, void **); long (*fallocate)(struct file *file, int mode, loff_t offset, loff_t len); - int (*show_fdinfo)(struct seq_file *m, struct file *f); + void (*show_fdinfo)(struct seq_file *m, struct file *f); }; struct inode_operations { -- cgit v1.2.3 From 9761536e1d9e9e1f325fb04d4ad46b15a39eb94a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 29 Sep 2014 16:08:26 -0700 Subject: debugfs: Have debugfs_print_regs32() return void The seq_printf() will soon just return void, and seq_has_overflowed() should be used instead to see if the seq can no longer accept input. As the return value of debugfs_print_regs32() has no users and the seq_file descriptor should be checked with seq_has_overflowed() instead of return values of functions, it is better to just have debugfs_print_regs32() also return void. Link: http://lkml.kernel.org/p/2634b19eb1c04a9d31148c1fe6f1f3819be95349.1412031505.git.joe@perches.com Acked-by: Greg Kroah-Hartman Signed-off-by: Joe Perches [ original change only updated seq_printf() return, added return of void to debugfs_print_regs32() as well ] Signed-off-by: Steven Rostedt --- Documentation/filesystems/debugfs.txt | 2 +- fs/debugfs/file.c | 15 ++++++++------- include/linux/debugfs.h | 7 +++---- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/debugfs.txt b/Documentation/filesystems/debugfs.txt index 3a863f692728..88ab81c79109 100644 --- a/Documentation/filesystems/debugfs.txt +++ b/Documentation/filesystems/debugfs.txt @@ -140,7 +140,7 @@ file. struct dentry *parent, struct debugfs_regset32 *regset); - int debugfs_print_regs32(struct seq_file *s, struct debugfs_reg32 *regs, + void debugfs_print_regs32(struct seq_file *s, struct debugfs_reg32 *regs, int nregs, void __iomem *base, char *prefix); The "base" argument may be 0, but you may want to build the reg32 array diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index 76c08c2beb2f..8e0f2f410189 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -692,18 +692,19 @@ EXPORT_SYMBOL_GPL(debugfs_create_u32_array); * because some peripherals have several blocks of identical registers, * for example configuration of dma channels */ -int debugfs_print_regs32(struct seq_file *s, const struct debugfs_reg32 *regs, - int nregs, void __iomem *base, char *prefix) +void debugfs_print_regs32(struct seq_file *s, const struct debugfs_reg32 *regs, + int nregs, void __iomem *base, char *prefix) { - int i, ret = 0; + int i; for (i = 0; i < nregs; i++, regs++) { if (prefix) - ret += seq_printf(s, "%s", prefix); - ret += seq_printf(s, "%s = 0x%08x\n", regs->name, - readl(base + regs->offset)); + seq_printf(s, "%s", prefix); + seq_printf(s, "%s = 0x%08x\n", regs->name, + readl(base + regs->offset)); + if (seq_has_overflowed(s)) + break; } - return ret; } EXPORT_SYMBOL_GPL(debugfs_print_regs32); diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index 4d0b4d1aa132..d84f8c254a87 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -92,8 +92,8 @@ struct dentry *debugfs_create_regset32(const char *name, umode_t mode, struct dentry *parent, struct debugfs_regset32 *regset); -int debugfs_print_regs32(struct seq_file *s, const struct debugfs_reg32 *regs, - int nregs, void __iomem *base, char *prefix); +void debugfs_print_regs32(struct seq_file *s, const struct debugfs_reg32 *regs, + int nregs, void __iomem *base, char *prefix); struct dentry *debugfs_create_u32_array(const char *name, umode_t mode, struct dentry *parent, @@ -233,10 +233,9 @@ static inline struct dentry *debugfs_create_regset32(const char *name, return ERR_PTR(-ENODEV); } -static inline int debugfs_print_regs32(struct seq_file *s, const struct debugfs_reg32 *regs, +static inline void debugfs_print_regs32(struct seq_file *s, const struct debugfs_reg32 *regs, int nregs, void __iomem *base, char *prefix) { - return 0; } static inline bool debugfs_initialized(void) -- cgit v1.2.3 From 41d28bca2da4bd75a8915c1ccf2cacf7f4a2e531 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 12 Oct 2014 22:24:21 -0400 Subject: switch d_materialise_unique() users to d_splice_alias() Signed-off-by: Al Viro --- Documentation/filesystems/nfs/Exporting | 23 +++++------------------ Documentation/filesystems/porting | 4 ++++ fs/9p/vfs_inode.c | 2 +- fs/btrfs/inode.c | 2 +- fs/ceph/inode.c | 2 +- fs/cifs/readdir.c | 2 +- fs/fuse/dir.c | 4 ++-- fs/kernfs/dir.c | 2 +- fs/nfs/dir.c | 4 ++-- fs/nfs/getroot.c | 2 +- include/linux/dcache.h | 1 - 11 files changed, 19 insertions(+), 29 deletions(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/nfs/Exporting b/Documentation/filesystems/nfs/Exporting index c8f036a9b13f..520a4becb75c 100644 --- a/Documentation/filesystems/nfs/Exporting +++ b/Documentation/filesystems/nfs/Exporting @@ -72,24 +72,11 @@ c/ Helper routines to allocate anonymous dentries, and to help attach DCACHE_DISCONNECTED) dentry is allocated and attached. In the case of a directory, care is taken that only one dentry can ever be attached. - d_splice_alias(inode, dentry) or d_materialise_unique(dentry, inode) - will introduce a new dentry into the tree; either the passed-in - dentry or a preexisting alias for the given inode (such as an - anonymous one created by d_obtain_alias), if appropriate. The two - functions differ in their handling of directories with preexisting - aliases: - d_splice_alias will use any existing IS_ROOT dentry, but it will - return -EIO rather than try to move a dentry with a different - parent. This is appropriate for local filesystems, which - should never see such an alias unless the filesystem is - corrupted somehow (for example, if two on-disk directory - entries refer to the same directory.) - d_materialise_unique will attempt to move any dentry. This is - appropriate for distributed filesystems, where finding a - directory other than where we last cached it may be a normal - consequence of concurrent operations on other hosts. - Both functions return NULL when the passed-in dentry is used, - following the calling convention of ->lookup. + d_splice_alias(inode, dentry) will introduce a new dentry into the tree; + either the passed-in dentry or a preexisting alias for the given inode + (such as an anonymous one created by d_obtain_alias), if appropriate. + It returns NULL when the passed-in dentry is used, following the calling + convention of ->lookup. Filesystem Issues diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index 0f3a1390bf00..b6b55a9cffee 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting @@ -463,3 +463,7 @@ in your dentry operations instead. of the in-tree instances did). inode_hash_lock is still held, of course, so they are still serialized wrt removal from inode hash, as well as wrt set() callback of iget5_locked(). +-- +[mandatory] + d_materialise_unique() is gone; d_splice_alias() does everything you + need now. Remember that they have opposite orders of arguments ;-/ diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 296482fc77a9..9ee5343d4884 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -832,7 +832,7 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, * moved b under k and client parallely did a lookup for * k/b. */ - res = d_materialise_unique(dentry, inode); + res = d_splice_alias(inode, dentry); if (!res) v9fs_fid_add(dentry, fid); else if (!IS_ERR(res)) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index d23362f4464e..ff0dcc016b71 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -5303,7 +5303,7 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, return ERR_CAST(inode); } - return d_materialise_unique(dentry, inode); + return d_splice_alias(inode, dentry); } unsigned char btrfs_filetype_table[] = { diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 7a1df90c7771..90ec8e32c138 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -967,7 +967,7 @@ static struct dentry *splice_dentry(struct dentry *dn, struct inode *in, /* dn must be unhashed */ if (!d_unhashed(dn)) d_drop(dn); - realdn = d_materialise_unique(dn, in); + realdn = d_splice_alias(in, dn); if (IS_ERR(realdn)) { pr_err("splice_dentry error %ld %p inode %p ino %llx.%llx\n", PTR_ERR(realdn), dn, in, ceph_vinop(in)); diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 8fd2a95860ba..586e3d3b204e 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -123,7 +123,7 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name, if (!inode) goto out; - alias = d_materialise_unique(dentry, inode); + alias = d_splice_alias(inode, dentry); if (alias && !IS_ERR(alias)) dput(alias); out: diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index dbab798f5caf..df562cc87763 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -372,7 +372,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, if (inode && get_node_id(inode) == FUSE_ROOT_ID) goto out_iput; - newent = d_materialise_unique(entry, inode); + newent = d_splice_alias(inode, entry); err = PTR_ERR(newent); if (IS_ERR(newent)) goto out_err; @@ -1320,7 +1320,7 @@ static int fuse_direntplus_link(struct file *file, if (!inode) goto out; - alias = d_materialise_unique(dentry, inode); + alias = d_splice_alias(inode, dentry); err = PTR_ERR(alias); if (IS_ERR(alias)) goto out; diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 1c771931bb60..37989f02a226 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -807,7 +807,7 @@ static struct dentry *kernfs_iop_lookup(struct inode *dir, } /* instantiate and hash dentry */ - ret = d_materialise_unique(dentry, inode); + ret = d_splice_alias(inode, dentry); out_unlock: mutex_unlock(&kernfs_mutex); return ret; diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 06e8cfcbb670..44d7d0c7e376 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -499,7 +499,7 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) if (IS_ERR(inode)) goto out; - alias = d_materialise_unique(dentry, inode); + alias = d_splice_alias(inode, dentry); if (IS_ERR(alias)) goto out; else if (alias) { @@ -1393,7 +1393,7 @@ struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned in nfs_advise_use_readdirplus(dir); no_entry: - res = d_materialise_unique(dentry, inode); + res = d_splice_alias(inode, dentry); if (res != NULL) { if (IS_ERR(res)) goto out_unblock_sillyrename; diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c index ebc6a0add5ae..9ac3846cb59e 100644 --- a/fs/nfs/getroot.c +++ b/fs/nfs/getroot.c @@ -51,7 +51,7 @@ static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *i /* * Ensure that this dentry is invisible to d_find_alias(). * Otherwise, it may be spliced into the tree by - * d_materialise_unique if a parent directory from the same + * d_splice_alias if a parent directory from the same * filesystem gets mounted at a later time. * This again causes shrink_dcache_for_umount_subtree() to * Oops, since the test for IS_ROOT() will fail. diff --git a/include/linux/dcache.h b/include/linux/dcache.h index ee569da27b72..5a813988e6d4 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -230,7 +230,6 @@ extern seqlock_t rename_lock; */ extern void d_instantiate(struct dentry *, struct inode *); extern struct dentry * d_instantiate_unique(struct dentry *, struct inode *); -#define d_materialise_unique(d, i) d_splice_alias(i, d) extern int d_instantiate_no_diralias(struct dentry *, struct inode *); extern void __d_drop(struct dentry *dentry); extern void d_drop(struct dentry *dentry); -- cgit v1.2.3 From 78d28e651f97866d608d9b41f8ad291e65d47dd5 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 31 Oct 2014 01:22:04 -0400 Subject: kill f_dentry macro Signed-off-by: Al Viro --- Documentation/filesystems/porting | 4 ++++ include/linux/fs.h | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index b6b55a9cffee..fa2db081505e 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting @@ -467,3 +467,7 @@ in your dentry operations instead. [mandatory] d_materialise_unique() is gone; d_splice_alias() does everything you need now. Remember that they have opposite orders of arguments ;-/ +-- +[mandatory] + f_dentry is gone; use f_path.dentry, or, better yet, see if you can avoid + it entirely. diff --git a/include/linux/fs.h b/include/linux/fs.h index 1c12c681803f..1a8bb3c023a1 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -789,7 +789,6 @@ struct file { struct rcu_head fu_rcuhead; } f_u; struct path f_path; -#define f_dentry f_path.dentry struct inode *f_inode; /* cached value */ const struct file_operations *f_op; -- cgit v1.2.3