aboutsummaryrefslogtreecommitdiff
path: root/fs/dcache.c
diff options
context:
space:
mode:
authorNick Piggin <npiggin@kernel.dk>2011-01-07 17:49:26 +1100
committerNick Piggin <npiggin@kernel.dk>2011-01-07 17:50:19 +1100
commitfb2d5b86aff355a27ebfc132d3c99f4a940cc3fe (patch)
tree7fed12adf54473131e8b86c0c302c443b1d6a846 /fs/dcache.c
parent2bc334dcc7c77be3700dd443d92a78603f76976b (diff)
fs: name case update method
smpfs and ncpfs want to update a live dentry name in-place. Rather than have them open code the locking, provide a documented dcache API. Signed-off-by: Nick Piggin <npiggin@kernel.dk>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 6ee6bc40cb6..814e5f491e9 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1589,6 +1589,33 @@ void d_rehash(struct dentry * entry)
}
EXPORT_SYMBOL(d_rehash);
+/**
+ * dentry_update_name_case - update case insensitive dentry with a new name
+ * @dentry: dentry to be updated
+ * @name: new name
+ *
+ * Update a case insensitive dentry with new case of name.
+ *
+ * dentry must have been returned by d_lookup with name @name. Old and new
+ * name lengths must match (ie. no d_compare which allows mismatched name
+ * lengths).
+ *
+ * Parent inode i_mutex must be held over d_lookup and into this call (to
+ * keep renames and concurrent inserts, and readdir(2) away).
+ */
+void dentry_update_name_case(struct dentry *dentry, struct qstr *name)
+{
+ BUG_ON(!mutex_is_locked(&dentry->d_inode->i_mutex));
+ BUG_ON(dentry->d_name.len != name->len); /* d_lookup gives this */
+
+ spin_lock(&dcache_lock);
+ spin_lock(&dentry->d_lock);
+ memcpy((unsigned char *)dentry->d_name.name, name->name, name->len);
+ spin_unlock(&dentry->d_lock);
+ spin_unlock(&dcache_lock);
+}
+EXPORT_SYMBOL(dentry_update_name_case);
+
/*
* When switching names, the actual string doesn't strictly have to
* be preserved in the target - because we're dropping the target