diff options
author | mmusante <none@none> | 2007-06-29 11:14:08 -0700 |
---|---|---|
committer | mmusante <none@none> | 2007-06-29 11:14:08 -0700 |
commit | 3a5a36bed7d37f89dd29cedbff57558e30629f6e (patch) | |
tree | 52f70273291e746a269ea618b737749540a83f43 /usr/src | |
parent | 9e8164f5f5658c6e38a931780d499f5cb622908a (diff) | |
download | illumos-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.c | 21 |
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); } |