From 35df63c46c8605d00140ec4833d2104e2e9f1acc Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Fri, 20 Nov 2009 16:08:50 -0800 Subject: sysfs: Fix locking and factor out sysfs_sd_setattr Cleanly separate the work that is specific to setting the attributes of a sysfs_dirent from what is needed to update the attributes of a vfs inode. Additionally grab the sysfs_mutex to keep any nasties from surprising us when updating the sysfs_dirent. Acked-by: Tejun Heo Signed-off-by: Eric W. Biederman Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/sysfs.h | 1 + 1 file changed, 1 insertion(+) (limited to 'fs/sysfs/sysfs.h') diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index af4c4e7482ac..a96d9678ae73 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h @@ -155,6 +155,7 @@ static inline void __sysfs_put(struct sysfs_dirent *sd) */ struct inode *sysfs_get_inode(struct sysfs_dirent *sd); void sysfs_delete_inode(struct inode *inode); +int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr); int sysfs_setattr(struct dentry *dentry, struct iattr *iattr); int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags); -- cgit v1.2.2 From e61ab4ae48fbf477f5b9fcbec9e1b8dc789920d0 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Fri, 20 Nov 2009 16:08:53 -0800 Subject: sysfs: Implement sysfs_getattr & sysfs_permission With the implementation of sysfs_getattr and sysfs_permission sysfs becomes able to lazily propogate inode attribute changes from the sysfs_dirents to the vfs inodes. This paves the way for deleting significant chunks of now unnecessary code. While doing this we did not reference sysfs_setattr from sysfs_symlink_inode_operations so I added along with sysfs_getattr and sysfs_permission. Acked-by: Tejun Heo Acked-by: Serge Hallyn Signed-off-by: Eric W. Biederman Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/sysfs.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'fs/sysfs/sysfs.h') diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index a96d9678ae73..12ccc07459d8 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h @@ -156,7 +156,9 @@ static inline void __sysfs_put(struct sysfs_dirent *sd) struct inode *sysfs_get_inode(struct sysfs_dirent *sd); void sysfs_delete_inode(struct inode *inode); int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr); +int sysfs_permission(struct inode *inode, int mask); int sysfs_setattr(struct dentry *dentry, struct iattr *iattr); +int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags); int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name); -- cgit v1.2.2 From a16bbc3430ed94b543222f4c8ef68025f8493e93 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Fri, 20 Nov 2009 16:08:55 -0800 Subject: sysfs: Gut sysfs_addrm_start and sysfs_addrm_finish With lazy inode updates and dentry operations bringing everything into sync on demand there is no longer any need to immediately update the vfs or grab i_mutex to protect those updates as we make changes to sysfs. Acked-by: Serge Hallyn Acked-by: Tejun Heo Signed-off-by: Eric W. Biederman Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/sysfs.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'fs/sysfs/sysfs.h') diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index 12ccc07459d8..90b35012abb2 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h @@ -89,9 +89,7 @@ static inline unsigned int sysfs_type(struct sysfs_dirent *sd) */ struct sysfs_addrm_cxt { struct sysfs_dirent *parent_sd; - struct inode *parent_inode; struct sysfs_dirent *removed; - int cnt; }; /* -- cgit v1.2.2 From 832b6af198aefe6034310e124594cc8b833c0ef9 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Fri, 20 Nov 2009 16:08:56 -0800 Subject: sysfs: Propagate renames to the vfs on demand By teaching sysfs_revalidate to hide a dentry for a sysfs_dirent if the sysfs_dirent has been renamed, and by teaching sysfs_lookup to return the original dentry if the sysfs dirent has been renamed. I can show the results of renames correctly without having to update the dcache during the directory rename. This massively simplifies the rename logic allowing a lot of weird sysfs special cases to be removed along with a lot of now unnecesary helper code. Acked-by: Tejun Heo Signed-off-by: Eric W. Biederman Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/sysfs.h | 1 - 1 file changed, 1 deletion(-) (limited to 'fs/sysfs/sysfs.h') diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index 90b35012abb2..98a15bf1efe1 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h @@ -103,7 +103,6 @@ extern struct kmem_cache *sysfs_dir_cachep; * dir.c */ extern struct mutex sysfs_mutex; -extern struct mutex sysfs_rename_mutex; extern spinlock_t sysfs_assoc_lock; extern const struct file_operations sysfs_dir_operations; -- cgit v1.2.2 From ca1bab38195d66bdf42320a99cc7359434a271d3 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Fri, 20 Nov 2009 16:08:57 -0800 Subject: sysfs: Factor out sysfs_rename from sysfs_rename_dir and sysfs_move_dir These two functions do 90% of the same work and it doesn't significantly obfuscate the function to allow both the parent dir and the name to change at the same time. So merge them together to simplify maintenance, and increase testing. Acked-by: Tejun Heo Acked-by: Serge Hallyn Signed-off-by: Eric W. Biederman Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/sysfs.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'fs/sysfs/sysfs.h') diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index 98a15bf1efe1..ca52e7b9d8f8 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h @@ -130,6 +130,9 @@ int sysfs_create_subdir(struct kobject *kobj, const char *name, struct sysfs_dirent **p_sd); void sysfs_remove_subdir(struct sysfs_dirent *sd); +int sysfs_rename(struct sysfs_dirent *sd, + struct sysfs_dirent *new_parent_sd, const char *new_name); + static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd) { if (sd) { -- cgit v1.2.2