1 /*
2  * s3fs - FUSE-based file system backed by Amazon S3
3  *
4  * Copyright(C) 2007 Randy Rizun <rrizun@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 
21 #ifndef S3FS_FDCACHE_PAGE_H_
22 #define S3FS_FDCACHE_PAGE_H_
23 
24 #include <list>
25 #include <sys/types.h>
26 
27 #include "fdcache_stat.h"
28 
29 //------------------------------------------------
30 // Symbols
31 //------------------------------------------------
32 // [NOTE]
33 // If the following symbols in lseek whence are undefined, define them.
34 // If it is not supported by lseek, s3fs judges by the processing result of lseek.
35 //
36 #ifndef SEEK_DATA
37 #define SEEK_DATA               3
38 #endif
39 #ifndef SEEK_HOLE
40 #define SEEK_HOLE               4
41 #endif
42 
43 //------------------------------------------------
44 // Structure fdpage
45 //------------------------------------------------
46 // page block information
47 struct fdpage
48 {
49     off_t  offset;
50     off_t  bytes;
51     bool   loaded;
52     bool   modified;
53 
54     fdpage(off_t start = 0, off_t  size = 0, bool is_loaded = false, bool is_modified = false) :
offsetfdpage55         offset(start), bytes(size), loaded(is_loaded), modified(is_modified) {}
56 
nextfdpage57     off_t next() const
58     {
59         return (offset + bytes);
60     }
endfdpage61     off_t end() const
62     {
63         return (0 < bytes ? offset + bytes - 1 : 0);
64     }
65 };
66 typedef std::list<struct fdpage> fdpage_list_t;
67 
68 //------------------------------------------------
69 // Class PageList
70 //------------------------------------------------
71 class FdEntity;
72 
73 // cppcheck-suppress copyCtorAndEqOperator
74 class PageList
75 {
76     friend class FdEntity;    // only one method access directly pages.
77 
78     private:
79         fdpage_list_t pages;
80 
81     public:
82         enum page_status{
83             PAGE_NOT_LOAD_MODIFIED = 0,
84             PAGE_LOADED,
85             PAGE_MODIFIED,
86             PAGE_LOAD_MODIFIED
87         };
88 
89     private:
90         static bool GetSparseFilePages(int fd, size_t file_size, fdpage_list_t& sparse_list);
91         static bool CheckZeroAreaInFile(int fd, off_t start, size_t bytes);
92         static bool CheckAreaInSparseFile(const struct fdpage& checkpage, const fdpage_list_t& sparse_list, int fd, fdpage_list_t& err_area_list, fdpage_list_t& warn_area_list);
93 
94         void Clear();
95         bool Parse(off_t new_pos);
96 
97     public:
98         static void FreeList(fdpage_list_t& list);
99 
100         explicit PageList(off_t size = 0, bool is_loaded = false, bool is_modified = false);
101         explicit PageList(const PageList& other);
102         ~PageList();
103 
104         bool Init(off_t size, bool is_loaded, bool is_modified);
105         off_t Size() const;
106         bool Resize(off_t size, bool is_loaded, bool is_modified);
107 
108         bool IsPageLoaded(off_t start = 0, off_t size = 0) const;                  // size=0 is checking to end of list
109         bool SetPageLoadedStatus(off_t start, off_t size, PageList::page_status pstatus = PAGE_LOADED, bool is_compress = true);
110         bool FindUnloadedPage(off_t start, off_t& resstart, off_t& ressize) const;
111         off_t GetTotalUnloadedPageSize(off_t start = 0, off_t size = 0, off_t limit_size = 0) const;   // size=0 is checking to end of list
112         size_t GetUnloadedPages(fdpage_list_t& unloaded_list, off_t start = 0, off_t size = 0) const;  // size=0 is checking to end of list
113         bool GetPageListsForMultipartUpload(fdpage_list_t& dlpages, fdpage_list_t& mixuppages, off_t max_partsize);
114         bool GetNoDataPageLists(fdpage_list_t& nodata_pages, off_t start = 0, size_t size = 0);
115 
116         off_t BytesModified() const;
117         bool IsModified() const;
118         bool ClearAllModified();
119 
120         bool Compress();
121         bool Serialize(CacheFileStat& file, bool is_output, ino_t inode);
122         void Dump() const;
123         bool CompareSparseFile(int fd, size_t file_size, fdpage_list_t& err_area_list, fdpage_list_t& warn_area_list);
124 };
125 
126 #endif // S3FS_FDCACHE_PAGE_H_
127 
128 /*
129 * Local variables:
130 * tab-width: 4
131 * c-basic-offset: 4
132 * End:
133 * vim600: expandtab sw=4 ts=4 fdm=marker
134 * vim<600: expandtab sw=4 ts=4
135 */
136