1 /*
2    Copyright 2005-2010 Jakub Kruszona-Zawadzki, Gemius SA, 2013-2016 Skytechnology sp. z o.o.
3 
4    This file is part of LizardFS.
5 
6    LizardFS is free software: you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation, version 3.
9 
10    LizardFS is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with LizardFS. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include "common/platform.h"
20 
21 #include <fcntl.h>
22 
23 #include "mount/client_common.h"
24 #include "mount/special_inode.h"
25 #include "mount/stats.h"
26 
27 using namespace LizardClient;
28 
29 namespace InodeMasterInfo {
open(const Context & ctx,FileInfo * fi)30 static void open(const Context &ctx, FileInfo *fi) {
31 	if ((fi->flags & O_ACCMODE) != O_RDONLY) {
32 		oplog_printf(ctx, "open (%lu) (internal node: MASTERINFO): %s",
33 		            (unsigned long int)inode_, lizardfs_error_string(LIZARDFS_ERROR_EACCES));
34 		throw RequestException(LIZARDFS_ERROR_EACCES);
35 	}
36 	fi->fh = 0;
37 	fi->direct_io = 0;
38 	fi->keep_cache = 1;
39 	oplog_printf(ctx, "open (%lu) (internal node: MASTERINFO): OK (0,1)",
40 	            (unsigned long int)inode_);
41 }
42 } // InodeMasterInfo
43 
44 namespace InodeStats {
open(const Context & ctx,FileInfo * fi)45 static void open(const Context &ctx, FileInfo *fi) {
46 	sinfo *statsinfo;
47 	statsinfo = (sinfo*) malloc(sizeof(sinfo));
48 	if (statsinfo==NULL) {
49 		oplog_printf(ctx, "open (%lu) (internal node: STATS): %s",
50 		            (unsigned long int)inode_,
51 		            lizardfs_error_string(LIZARDFS_ERROR_OUTOFMEMORY));
52 		throw RequestException(LIZARDFS_ERROR_OUTOFMEMORY);
53 	}
54 	pthread_mutex_init(&(statsinfo->lock),NULL);         // make helgrind happy
55 	PthreadMutexWrapper lock((statsinfo->lock));         // make helgrind happy
56 	stats_show_all(&(statsinfo->buff),&(statsinfo->leng));
57 	statsinfo->reset = 0;
58 	fi->fh = reinterpret_cast<uintptr_t>(statsinfo);
59 	fi->direct_io = 1;
60 	fi->keep_cache = 0;
61 	oplog_printf(ctx, "open (%lu) (internal node: STATS): OK (1,0)",
62 	            (unsigned long int)inode_);
63 }
64 } // InodeStats
65 
66 namespace InodeOplog {
open(const Context & ctx,FileInfo * fi)67 static void open(const Context &ctx, FileInfo *fi) {
68 	if ((fi->flags & O_ACCMODE) != O_RDONLY) {
69 		oplog_printf(ctx, "open (%lu) (internal node: OPLOG): %s",
70 		            (unsigned long int)inode_,
71 		            lizardfs_error_string(LIZARDFS_ERROR_EACCES));
72 		throw RequestException(LIZARDFS_ERROR_EACCES);
73 	}
74 	fi->fh = oplog_newhandle(0);
75 	fi->direct_io = 1;
76 	fi->keep_cache = 0;
77 	oplog_printf(ctx, "open (%lu) (internal node: OPLOG): OK (1,0)",
78 	            (unsigned long int)inode_);
79 }
80 } // InodeOplog
81 
82 namespace InodeOphistory {
open(const Context & ctx,FileInfo * fi)83 static void open(const Context &ctx, FileInfo *fi) {
84 	if ((fi->flags & O_ACCMODE) != O_RDONLY) {
85 		oplog_printf(ctx, "open (%lu) (internal node: OPHISTORY): %s",
86 		            (unsigned long int)inode_,
87 		            lizardfs_error_string(LIZARDFS_ERROR_EACCES));
88 		throw RequestException(LIZARDFS_ERROR_EACCES);
89 	}
90 	fi->fh = oplog_newhandle(1);
91 	fi->direct_io = 1;
92 	fi->keep_cache = 0;
93 	oplog_printf(ctx, "open (%lu) (internal node: OPHISTORY): OK (1,0)",
94 	            (unsigned long int)inode_);
95 }
96 } // InodeOphistory
97 
98 namespace InodeTweaks {
open(const Context & ctx,FileInfo * fi)99 static void open(const Context &ctx, FileInfo *fi) {
100 	MagicFile *file = new MagicFile;
101 	fi->fh = reinterpret_cast<uintptr_t>(file);
102 	fi->direct_io = 1;
103 	fi->keep_cache = 0;
104 	oplog_printf(ctx, "open (%lu) (internal node: TWEAKS_FILE): OK (1,0)",
105 	            (unsigned long int)inode_);
106 }
107 } // InodeTweaks
108 
109 static const std::array<std::function<void
110 	(const Context&, FileInfo*)>, 16> funcs = {{
111 	 &InodeStats::open,             //0x0U
112 	 &InodeOplog::open,             //0x1U
113 	 &InodeOphistory::open,         //0x2U
114 	 &InodeTweaks::open,            //0x3U
115 	 nullptr,                       //0x5U
116 	 nullptr,                       //0x6U
117 	 nullptr,                       //0x7U
118 	 nullptr,                       //0x8U
119 	 nullptr,                       //0x9U
120 	 nullptr,                       //0xAU
121 	 nullptr,                       //0xBU
122 	 nullptr,                       //0xCU
123 	 nullptr,                       //0xDU
124 	 nullptr,                       //0xEU
125 	 nullptr,                       //0xEU
126 	 &InodeMasterInfo::open         //0xFU
127 }};
128 
special_open(Inode ino,const Context & ctx,FileInfo * fi)129 void special_open(Inode ino, const Context &ctx, FileInfo *fi) {
130 	auto func = funcs[ino - SPECIAL_INODE_BASE];
131 	if (!func) {
132 		lzfs_pretty_syslog(LOG_WARNING,
133 			"Trying to call unimplemented 'open' function for special inode");
134 		throw RequestException(LIZARDFS_ERROR_EINVAL);
135 	}
136 	return func(ctx, fi);
137 }
138