Hi Al, I did the following hack for a debugging patch recently, and one of the things it brought up for me is the challenge of printing a pathname for debugging purposes. I don't necessary need the pathname used to open the file, but often all I have is a dentry, because for whatever reason (I suspect historical), we don't pass in the struct path into the low-level file systems, but just the struct dentry instead. So see the kludges I did below --- in one case, a stiched together a struct path using the vfsmnt found in the struct nameidata passed to the lookup function. In another, much more grotesque case, I grabbed the vfsmnt for the root file system from current->fs->root (which is wrong wrong wrong, but I checked the code and experimentally speaking, it looks like it should do the same thing as the non-exported dentry_path() function). I wonder if we would be better off simply exporting dentry_path(), perhaps as EXPORT_SYMBOL_GPL, with a warning that it should only be used for debugging purposes, or some such. I suspect it's not worth changing all of the inode_ops interfaces to pass in a struct path intead of a struct dentry if it's only to be used for debugging. Or maybe I should just keep on doing these ugly things and justify them because it's only for debugging (yelch). What do you think? Thanks, - Ted diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 52e6201..faa230b 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -34,6 +34,9 @@ #include <linux/quotaops.h> #include <linux/buffer_head.h> #include <linux/bio.h> +#include <linux/path.h> +#include <linux/namei.h> +#include <linux/fs_struct.h> #include "ext4.h" #include "ext4_jbd2.h" @@ -337,6 +340,36 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir, } #endif /* DX_DEBUG */ +#define ext4_time_check(sb, start, duration, path) \ + __ext4_time_check((sb),(start),(duration),(path), __func__, __LINE__) + +#define TIME_DEADLINE 5*HZ + +static void __ext4_time_check(struct super_block *sb, unsigned long start, + unsigned duration, const struct path *path, + const char *where, unsigned int line) +{ + unsigned long t = jiffies - start; + char pathname[80], *fn = 0; + + if (t < duration) + return; + if (path) + fn = d_path(path, pathname, sizeof(pathname)); + if (fn) + warn_slowpath_fmt(where, line, + "EXT4-fs (%s): comm %s: %s: " + "deadline exceeded: %lu.%02lus", + sb->s_id, current->comm, fn, + t / HZ, ((t * 100) / HZ) % 100); + else + warn_slowpath_fmt(where, line, + "EXT4-fs (%s): comm %s: " + "deadline exceeded: %lu.%02lus", + sb->s_id, current->comm, + t / HZ, ((t * 100) / HZ) % 100); +} + /* * Probe for a directory leaf block to search. * @@ -1052,6 +1085,9 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, stru struct inode *inode; struct ext4_dir_entry_2 *de; struct buffer_head *bh; + unsigned long s_time = jiffies; + struct path path; + struct dentry *new; if (dentry->d_name.len > EXT4_NAME_LEN) return ERR_PTR(-ENAMETOOLONG); @@ -1077,7 +1113,15 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, stru } } } +#if 0 return d_splice_alias(inode, dentry); +#else + new = d_splice_alias(inode, dentry); + path.mnt = nd->path.mnt; + path.dentry = dentry; + ext4_time_check(dir->i_sb, s_time, TIME_DEADLINE, &path); + return new; +#endif } @@ -2424,6 +2468,8 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, struct buffer_head *old_bh, *new_bh, *dir_bh; struct ext4_dir_entry_2 *old_de, *new_de; int retval, force_da_alloc = 0; + unsigned long s_time = jiffies; + struct path path; dquot_initialize(old_dir); dquot_initialize(new_dir); @@ -2580,12 +2626,16 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, retval = 0; end_rename: + path.mnt = current->fs->root.mnt; /* hack hack hack */ + path.dentry = old_dentry; + ext4_time_check(old_dir->i_sb, s_time, TIME_DEADLINE, &path); brelse(dir_bh); brelse(old_bh); brelse(new_bh); ext4_journal_stop(handle); if (retval == 0 && force_da_alloc) ext4_alloc_da_blocks(old_inode); + ext4_time_check(old_dir->i_sb, s_time, TIME_DEADLINE, &path); return retval; } -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html