This will split it differently to what you have, but is still quite a nice list structure I think:
chunk.2 <- function(x, n, force.number.of.groups = TRUE, len = length(x), groups = trunc(len/n), overflow = len%%n) { 
   if(force.number.of.groups) {
      f1 <- as.character(sort(rep(1:n, groups)))
      f <- as.character(c(f1, rep(n, overflow)))
   } else {
      f1 <- as.character(sort(rep(1:groups, n)))
      f <- as.character(c(f1, rep("overflow", overflow)))
   }
   split(x, f)
}
Which will give you the following, depending on how you want it formatted:
> x <- 1:10; n <- 3
> chunk.2(x, n, force.number.of.groups = FALSE)
$`1`
[1] 1 2 3
$`2`
[1] 4 5 6
$`3`
[1] 7 8 9
$overflow
[1] 10
> chunk.2(x, n, force.number.of.groups = TRUE)
$`1`
[1] 1 2 3
$`2`
[1] 4 5 6
$`3`
[1]  7  8  9 10
Running a couple of timings using these settings:
set.seed(42)
x <- rnorm(1:1e7)
n <- 3
Then we have the following results:
> system.time(chunk(x, n)) # your function 
   user  system elapsed 
 29.500   0.620  30.125 
> system.time(chunk.2(x, n, force.number.of.groups = TRUE))
   user  system elapsed 
  5.360   0.300   5.663 
EDIT: Changing from as.factor() to as.character() in my function made it twice as fast.