summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authormmusante <none@none>2007-06-29 11:14:08 -0700
committermmusante <none@none>2007-06-29 11:14:08 -0700
commit3a5a36bed7d37f89dd29cedbff57558e30629f6e (patch)
tree52f70273291e746a269ea618b737749540a83f43 /usr/src
parent9e8164f5f5658c6e38a931780d499f5cb622908a (diff)
downloadillumos-joyent-3a5a36bed7d37f89dd29cedbff57558e30629f6e.tar.gz
6355623 zfs rename to a valid dataset name, but its snapshot name becomes too long, panics the system
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/fs/zfs/dsl_dataset.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/usr/src/uts/common/fs/zfs/dsl_dataset.c b/usr/src/uts/common/fs/zfs/dsl_dataset.c
index 7a36057402..e5bfe207b2 100644
--- a/usr/src/uts/common/fs/zfs/dsl_dataset.c
+++ b/usr/src/uts/common/fs/zfs/dsl_dataset.c
@@ -1715,6 +1715,17 @@ dsl_recursive_rename(char *oldname, const char *newname)
return (err);
}
+static int
+dsl_valid_rename(char *oldname, void *arg)
+{
+ int delta = *(int *)arg;
+
+ if (strlen(oldname) + delta >= MAXNAMELEN)
+ return (ENAMETOOLONG);
+
+ return (0);
+}
+
#pragma weak dmu_objset_rename = dsl_dataset_rename
int
dsl_dataset_rename(char *oldname, const char *newname,
@@ -1729,7 +1740,15 @@ dsl_dataset_rename(char *oldname, const char *newname,
if (err)
return (err);
if (tail == NULL) {
- err = dsl_dir_rename(dd, newname);
+ int delta = strlen(newname) - strlen(oldname);
+
+ /* if we're growing, validate child size lengths */
+ if (delta > 0)
+ err = dmu_objset_find(oldname, dsl_valid_rename,
+ &delta, DS_FIND_CHILDREN | DS_FIND_SNAPSHOTS);
+
+ if (!err)
+ err = dsl_dir_rename(dd, newname);
dsl_dir_close(dd, FTAG);
return (err);
}