1. A method of operating a file server, the file server having data storage storing a production file, a data processor coupled to the data storage for access to the production file, and non-transitory computer readable storage medium coupled to the data processor and storing computer instructions, the production file having data blocks and indirect blocks that are allocated to the production file and contain pointers to the data blocks for mapping block offsets in a logical extent of the production file to corresponding ones of the data blocks, and the computer instructions, when executed by the data processor, create a series of snapshot copies of the production file while preserving the allocations of the indirect blocks to the production file by performing the steps of: (a) creating a first snapshot copy of the production file by allocating a first inode to the first snapshot copy and building a first tree of pointers extending from the first inode to a first group of the indirect blocks of the production file; and then (b) creating a second snapshot copy of the production file by allocating a second inode to the second snapshot copy and building a second tree of pointers extending from the second inode to a second group of the indirect blocks of the production file, wherein the first tree of pointers and the second tree of pointers share pointers to indirect blocks that are included in a third group of indirect blocks that are included in both the first group of the indirect blocks of the production file and the second group of the indirect blocks of the production file, and then (c) in response to a request from a client of the file server to write a block of new data to a specified block offset in the logical extent of the production file, writing the block of new data to the data storage, searching one of the first tree of pointers and the second tree of pointers to find one of the pointers to one of the indirect blocks that maps the specified block offset in the logical extent of the production file to a corresponding one of the data blocks including a block of old data, said one of the indirect blocks being included in the third group of indirect blocks, and allocating a new indirect block to the snapshots, copying contents of said one of the indirect blocks to the new indirect block, changing said one of the pointers to said one of the indirect blocks to point to the new indirect block, and changing the contents of one of the new indirect block and said one of the indirect blocks so that the new indirect block maps the block of old data to the specified block offset in the logical extent of the first snapshot copy and the second snapshot copy, and said one of the indirect blocks maps the block of new data to the specified block offset in the logical extent of the production file.