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 "mount/client_common.h"
22 #include "mount/special_inode.h"
23 #include "mount/stats.h"
24 
25 using namespace LizardClient;
26 
27 namespace InodeMasterInfo {
release(FileInfo *)28 static void release(FileInfo */*fi*/) {
29 	oplog_printf("release (%lu) (internal node: MASTERINFO): OK",
30 	            (unsigned long int)inode_);
31 }
32 } // InodeMasterInfo
33 
34 namespace InodeStats {
release(FileInfo * fi)35 static void release(FileInfo *fi) {
36 	sinfo *statsinfo = reinterpret_cast<sinfo*>(fi->fh);
37 	if (statsinfo!=NULL) {
38 		PthreadMutexWrapper lock((statsinfo->lock));         // make helgrind happy
39 		if (statsinfo->buff!=NULL) {
40 			free(statsinfo->buff);
41 		}
42 		if (statsinfo->reset) {
43 			stats_reset_all();
44 		}
45 		lock.unlock(); // This unlock is needed, since we want to destroy the mutex
46 		pthread_mutex_destroy(&(statsinfo->lock));      // make helgrind happy
47 		free(statsinfo);
48 	}
49 	oplog_printf("release (%lu) (internal node: STATS): OK",
50 	            (unsigned long int)inode_);
51 }
52 } // InodeStats
53 
54 namespace InodeOplog {
release(FileInfo * fi)55 static void release(FileInfo *fi) {
56 	oplog_releasehandle(fi->fh);
57 	oplog_printf("release (%lu) (internal node: OPLOG): OK",
58 	            (unsigned long int)inode_);
59 }
60 } // InodeOplog
61 
62 namespace InodeOphistory {
release(FileInfo * fi)63 static void release(FileInfo *fi) {
64 	oplog_releasehandle(fi->fh);
65 	oplog_printf("release (%lu) (internal node: OPHISTORY): OK",
66 	            (unsigned long int)inode_);
67 }
68 } // InodeOphistory
69 
70 namespace InodeTweaks {
release(FileInfo * fi)71 static void release(FileInfo *fi) {
72 	MagicFile *file = reinterpret_cast<MagicFile*>(fi->fh);
73 	if (file->wasWritten) {
74 		auto separatorPos = file->value.find('=');
75 		if (separatorPos == file->value.npos) {
76 			lzfs_pretty_syslog(LOG_INFO, "TWEAKS_FILE: Wrong value '%s'",
77 			                   file->value.c_str());
78 		} else {
79 			std::string name = file->value.substr(0, separatorPos);
80 			std::string value = file->value.substr(separatorPos + 1);
81 			if (!value.empty() && value.back() == '\n') {
82 				value.resize(value.size() - 1);
83 			}
84 			gTweaks.setValue(name, value);
85 			lzfs_pretty_syslog(LOG_INFO, "TWEAKS_FILE: Setting '%s' to '%s'",
86 			                   name.c_str(), value.c_str());
87 		}
88 	}
89 	delete file;
90 	oplog_printf("release (%lu) (internal node: TWEAKS_FILE): OK",
91 	            (unsigned long int)inode_);
92 }
93 } // InodeTweaks
94 
95 typedef void (*ReleaseFunc)(FileInfo *);
96 static const std::array<ReleaseFunc, 16> funcs = {{
97 	 &InodeStats::release,          //0x0U
98 	 &InodeOplog::release,          //0x1U
99 	 &InodeOphistory::release,      //0x2U
100 	 &InodeTweaks::release,         //0x3U
101 	 nullptr,                       //0x5U
102 	 nullptr,                       //0x6U
103 	 nullptr,                       //0x7U
104 	 nullptr,                       //0x8U
105 	 nullptr,                       //0x9U
106 	 nullptr,                       //0xAU
107 	 nullptr,                       //0xBU
108 	 nullptr,                       //0xCU
109 	 nullptr,                       //0xDU
110 	 nullptr,                       //0xEU
111 	 nullptr,                       //0xEU
112 	 &InodeMasterInfo::release      //0xFU
113 }};
114 
special_release(Inode ino,FileInfo * fi)115 void special_release(Inode ino, FileInfo *fi) {
116 	auto func = funcs[ino - SPECIAL_INODE_BASE];
117 	if (!func) {
118 		lzfs_pretty_syslog(LOG_WARNING,
119 			"Trying to call unimplemented 'release' function for special inode");
120 		throw RequestException(LIZARDFS_ERROR_EINVAL);
121 	}
122 	return func(fi);
123 }
124