Re: [PATCH] Implement renaming for debugfs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon 07-05-07 09:28:30, Greg KH wrote:
> On Fri, May 04, 2007 at 04:14:28PM +0200, Jan Kara wrote:
> > On Thu 03-05-07 17:16:02, Greg KH wrote:
> > > On Thu, May 03, 2007 at 11:54:52AM +0200, Jan Kara wrote:
> > > > On Tue 01-05-07 20:26:27, Greg KH wrote:
> > > > > On Mon, Apr 30, 2007 at 07:55:36PM +0200, Jan Kara wrote:
> > > > > >   Hello,
> > > > > > 
> > > > > >   attached patch implements renaming for debugfs. I was asked for this
> > > > > > feature by WLAN guys and I guess it makes sence (they have some debug info
> > > > > > in the directory identified by interface name and that can change...).
> > > > > > Could someone have a look at what I wrote whether it looks reasonable?
> > > > > > Thanks.
> > > > > > 
> > > > > > 								Honza
> > > > > > 
> > > > > > -- 
> > > > > > Jan Kara <jack@xxxxxxx>
> > > > > > SuSE CR Labs
> > > > > 
> > > > > > Implement debugfs_rename() to allow renaming files/directories in debugfs.
> > > > > 
> > > > > I think you are going to need more infrastructure here, the caller
> > > > > doesn't want to have to allocate a new dentry themselves, they just want
> > > > > to pass in the new filename :)
> > > >   Actually, I wanted the call to be in the spirit of other debugfs calls.
> > > > So we have for example:
> > > > void debugfs_remove(struct dentry *dentry)
> > > 
> > > That is because 'debugfs_create' returns a dentry.
> > > 
> > > > struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
> > > > etc.
> > > 
> > > Same here, you already have a dentry to place this directory into, _and_
> > > all the user needs to provide is a name for the new directory.  They
> > > don't ever create a dentry themselves, which is what your function
> > > required them to do.
> > > 
> > > Try using your function and you'll see what I mean :)
> >   I've tried it when testing the function :). The code looked like:
> > dir1 = debugfs_create_dir("dir1", NULL);
> > dir2 = debugfs_create_dir("dir2", NULL);
> > file1 = debugfs_create_file("file1", 0644, dir1, NULL, NULL);
> > file2 = debugfs_rename(dir1, file1, dir2, "new_name");
> >   No new dentries needed to be created...
> 
> Ah, ok, sorry, that makes more sense, I missed that the dentry's passed
> in was the new directory location.  This will still work if you use the
> same directory like:
> 	debugfs_rename(dir1, file1, dir1, "new_name");
> 
> right?
  Yes, or even:

  debugfs_rename(file1->d_parent, file1, file1->d_parent, "new_name");

  (given you have no hardlinks to the file...). So renaming should be really
simple.
  Actually, I like the original interface slightly more because no new
dentry has to be created (and then dput()) in case you already have the dentry of
the file to rename (which usually seems to be the case). Attached is the
patch using the original interface - I've fixed some bugs in it since the
first version I've posted...

									Honza
-- 
Jan Kara <jack@xxxxxxx>
SuSE CR Labs
Implement debugfs_rename() to allow renaming files/directories in debugfs.

Signed-off-by: Jan Kara <jack@xxxxxxx>

diff -rupX /home/jack/.kerndiffexclude linux-2.6.21-rc6/fs/debugfs/inode.c linux-2.6.21-rc6-1-debugfs_rename/fs/debugfs/inode.c
--- linux-2.6.21-rc6/fs/debugfs/inode.c	2007-04-10 17:09:55.000000000 +0200
+++ linux-2.6.21-rc6-1-debugfs_rename/fs/debugfs/inode.c	2007-05-09 12:57:44.000000000 +0200
@@ -368,6 +368,69 @@ void debugfs_remove(struct dentry *dentr
 }
 EXPORT_SYMBOL_GPL(debugfs_remove);
 
+/**
+ * debugfs_rename - rename a file/directory in the debugfs filesystem
+ * @old_dir: a pointer to the parent dentry for the renamed object. This
+ *          should be a directory dentry.
+ * @old_dentry: dentry of an object to be renamed.
+ * @new_dir: a pointer to the parent dentry where the object should be
+ *          moved. This should be a directory dentry.
+ * @new_name: a pointer to a string containing the target name.
+ *
+ * This function renames a file/directory in debugfs.  The target must not
+ * exist for rename to succeed.
+ *
+ * This function will return a pointer to old_dentry (which is updated to
+ * reflect renaming) if it succeeds. If an error occurs, %NULL will be
+ * returned.
+ *
+ * If debugfs is not enabled in the kernel, the value -%ENODEV will be
+ * returned.
+ */
+struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
+		struct dentry *new_dir, const char *new_name)
+{
+	int error;
+	struct dentry *dentry = NULL, *trap;
+	const char *old_name;
+
+	trap = lock_rename(new_dir, old_dir);
+	/* Source or destination directories don't exist? */
+	if (!old_dir->d_inode || !new_dir->d_inode)
+		goto exit;
+	/* Source does not exist, cyclic rename, or mountpoint? */
+	if (!old_dentry->d_inode || old_dentry == trap ||
+	    d_mountpoint(old_dentry))
+		goto exit;
+	dentry = lookup_one_len(new_name, new_dir, strlen(new_name));
+	/* Lookup failed, cyclic rename or target exists? */
+	if (IS_ERR(dentry) || dentry == trap || dentry->d_inode)
+		goto exit;
+
+	old_name = fsnotify_oldname_init(old_dentry->d_name.name);
+
+	error = simple_rename(old_dir->d_inode, old_dentry, new_dir->d_inode,
+		dentry);
+	if (error) {
+		fsnotify_oldname_free(old_name);
+		goto exit;
+	}
+	d_move(old_dentry, dentry);
+	fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name,
+		old_dentry->d_name.name, S_ISDIR(old_dentry->d_inode->i_mode),
+		NULL, old_dentry->d_inode);
+	fsnotify_oldname_free(old_name);
+	unlock_rename(new_dir, old_dir);
+	dput(dentry);
+	return old_dentry;
+exit:
+	if (dentry && !IS_ERR(dentry))
+		dput(dentry);
+	unlock_rename(new_dir, old_dir);
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(debugfs_rename);
+
 static decl_subsys(debug, NULL, NULL);
 
 static int __init debugfs_init(void)
diff -rupX /home/jack/.kerndiffexclude linux-2.6.21-rc6/include/linux/debugfs.h linux-2.6.21-rc6-1-debugfs_rename/include/linux/debugfs.h
--- linux-2.6.21-rc6/include/linux/debugfs.h	2007-04-10 17:09:58.000000000 +0200
+++ linux-2.6.21-rc6-1-debugfs_rename/include/linux/debugfs.h	2007-05-09 12:59:08.000000000 +0200
@@ -38,6 +38,9 @@ struct dentry *debugfs_create_symlink(co
 
 void debugfs_remove(struct dentry *dentry);
 
+struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
+                struct dentry *new_dir, const char *new_name);
+
 struct dentry *debugfs_create_u8(const char *name, mode_t mode,
 				 struct dentry *parent, u8 *value);
 struct dentry *debugfs_create_u16(const char *name, mode_t mode,
@@ -83,6 +86,12 @@ static inline struct dentry *debugfs_cre
 static inline void debugfs_remove(struct dentry *dentry)
 { }
 
+static inline struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
+                struct dentry *new_dir, char *new_name)
+{
+	return ERR_PTR(-ENODEV);
+}
+
 static inline struct dentry *debugfs_create_u8(const char *name, mode_t mode,
 					       struct dentry *parent,
 					       u8 *value)

[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux