inode.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032
  1. /*
  2. * fs/scfs/inode.c
  3. *
  4. * Copyright (C) 2014 Samsung Electronics Co., Ltd.
  5. * Authors: Sunghwan Yun <sunghwan.yun@samsung.com>
  6. * Jongmin Kim <jm45.kim@samsung.com>
  7. * Sangwoo Lee <sangwoo2.lee@samsung.com>
  8. * Inbae Lee <inbae.lee@samsung.com>
  9. *
  10. * This program has been developed as a stackable file system based on
  11. * the WrapFS, which was written by:
  12. *
  13. * Copyright (C) 1997-2003 Erez Zadok
  14. * Copyright (C) 2001-2003 Stony Brook University
  15. * Copyright (C) 2004-2006 International Business Machines Corp.
  16. * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
  17. * Michael C. Thompson <mcthomps@us.ibm.com>
  18. *
  19. * This program is free software: you can redistribute it and/or modify
  20. * it under the terms of the GNU General Public License as published by
  21. * the Free Software Foundation, either version 2 of the License, or
  22. * (at your option) any later version.
  23. *
  24. * This program is distributed in the hope that it will be useful, but
  25. * WITHOUT ANY WARRANTY; without even the implied warranty of
  26. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  27. * General Public License for more details.
  28. *
  29. * You should have received a copy of the GNU General Public License
  30. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  31. */
  32. #include <linux/dcache.h>
  33. #include <linux/xattr.h>
  34. #include "scfs.h"
  35. /********************/
  36. /* helper functions */
  37. /********************/
  38. static void unlock_dir(struct dentry *dir)
  39. {
  40. mutex_unlock(&dir->d_inode->i_mutex);
  41. dput(dir);
  42. }
  43. static struct dentry *lock_parent(struct dentry *dentry)
  44. {
  45. struct dentry *dir;
  46. dir = dget_parent(dentry);
  47. mutex_lock_nested(&(dir->d_inode->i_mutex), I_MUTEX_PARENT);
  48. return dir;
  49. }
  50. static int scfs_inode_test(struct inode *inode, void *lower_inode)
  51. {
  52. if (scfs_lower_inode(inode) == (struct inode *)lower_inode)
  53. return 1;
  54. return 0;
  55. }
  56. static int scfs_inode_set(struct inode *inode, void *opaque)
  57. {
  58. struct inode *lower_inode = opaque;
  59. scfs_set_lower_inode(inode, lower_inode);
  60. fsstack_copy_attr_all(inode, lower_inode);
  61. fsstack_copy_inode_size(inode, lower_inode);
  62. inode->i_ino = lower_inode->i_ino;
  63. inode->i_version++;
  64. inode->i_mapping->a_ops = &scfs_aops;
  65. inode->i_mapping->backing_dev_info = inode->i_sb->s_bdi;
  66. if (S_ISLNK(inode->i_mode))
  67. inode->i_op = &scfs_symlink_iops;
  68. else if (S_ISDIR(inode->i_mode))
  69. inode->i_op = &scfs_dir_iops;
  70. else
  71. inode->i_op = &scfs_file_iops;
  72. if (S_ISDIR(inode->i_mode))
  73. inode->i_fop = &scfs_dir_fops;
  74. else if (special_file(inode->i_mode))
  75. init_special_inode(inode, inode->i_mode, inode->i_rdev);
  76. else
  77. inode->i_fop = &scfs_file_fops;
  78. return 0;
  79. }
  80. static struct inode *_scfs_get_inode(struct inode *lower_inode,
  81. struct super_block *sb)
  82. {
  83. struct inode *inode;
  84. if (lower_inode->i_sb != SCFS_S(sb)->lower_sb)
  85. return ERR_PTR(-EXDEV);
  86. if (!igrab(lower_inode))
  87. return ERR_PTR(-ESTALE);
  88. inode = iget5_locked(sb, (unsigned long)lower_inode->i_ino,
  89. scfs_inode_test, scfs_inode_set,
  90. lower_inode);
  91. if (!inode) {
  92. iput(lower_inode);
  93. return ERR_PTR(-EACCES);
  94. }
  95. if (!(inode->i_state & I_NEW))
  96. iput(lower_inode);
  97. return inode;
  98. }
  99. struct inode *scfs_get_inode(struct inode *lower_inode,
  100. struct super_block *sb)
  101. {
  102. struct inode *inode = _scfs_get_inode(lower_inode, sb);
  103. if (!IS_ERR(inode) && (inode->i_state & I_NEW))
  104. unlock_new_inode(inode);
  105. return inode;
  106. }
  107. static int scfs_interpose(struct dentry *lower_dentry,
  108. struct dentry *dentry, struct super_block *sb)
  109. {
  110. struct inode *inode = scfs_get_inode(lower_dentry->d_inode, sb);
  111. if (IS_ERR(inode))
  112. return PTR_ERR(inode);
  113. d_instantiate(dentry, inode);
  114. return 0;
  115. }
  116. int scfs_make_header(struct file *lower_file, struct inode *scfs_inode)
  117. {
  118. struct scfs_sb_info *sbi = SCFS_S(scfs_inode->i_sb);
  119. struct comp_footer cf;
  120. loff_t pos = 0;
  121. int ret;
  122. if (!lower_file) {
  123. SCFS_PRINT_ERROR("lower_file is null\n");
  124. return -EIO;
  125. }
  126. cf.footer_size = CF_SIZE;
  127. cf.cluster_size = sbi->options.cluster_size;
  128. cf.original_file_size = 0;
  129. cf.comp_type = sbi->options.comp_type;
  130. cf.magic = SCFS_MAGIC;
  131. ret = scfs_lower_write(lower_file, (char *)&cf, CF_SIZE, &pos);
  132. mark_inode_dirty_sync(scfs_inode);
  133. if (ret < 0) {
  134. SCFS_PRINT_ERROR("error in writing header\n");
  135. return ret;
  136. }
  137. ret = 0;
  138. return ret;
  139. }
  140. #if 0
  141. int scfs_make_header(struct dentry *scfs_dentry, struct inode *scfs_inode)
  142. {
  143. struct scfs_sb_info *sbi = SCFS_S(scfs_inode->i_sb);
  144. struct file *lower_file = SCFS_I(scfs_inode)->lower_file;
  145. struct comp_footer cf;
  146. loff_t pos = 0;
  147. int ret;
  148. if (!lower_file) {
  149. SCFS_PRINT_ERROR("lower_file is null\n");
  150. return -EIO;
  151. }
  152. cf.footer_size = CF_SIZE;
  153. cf.cluster_size = sbi->options.cluster_size;
  154. cf.original_file_size = 0;
  155. cf.comp_type = sbi->options.comp_type;
  156. cf.magic = SCFS_MAGIC;
  157. ret = scfs_lower_write(lower_file, (char *)&cf, CF_SIZE, &pos);
  158. mark_inode_dirty_sync(scfs_inode);
  159. if (ret < 0) {
  160. SCFS_PRINT_ERROR("error in writing header\n");
  161. return ret;
  162. }
  163. ret = 0;
  164. return ret;
  165. }
  166. #endif
  167. int scfs_initialize_file(struct dentry *scfs_dentry, struct inode *scfs_inode)
  168. {
  169. struct scfs_inode_info *sii = SCFS_I(scfs_inode);
  170. int ret = 0;
  171. struct file *lower_file;
  172. copy_mount_flags_to_inode_flags(scfs_inode, scfs_inode->i_sb);
  173. if (S_ISDIR(scfs_inode->i_mode)) {
  174. SCFS_PRINT_ERROR("it's a directory\n");
  175. sii->flags &= ~(SCFS_DATA_COMPRESSABLE);
  176. goto out;
  177. }
  178. ret = scfs_initialize_lower_file(scfs_dentry, &lower_file, O_RDWR);
  179. if (ret) {
  180. SCFS_PRINT_ERROR("error in get_lower_file, ret : %d\n", ret);
  181. goto out;
  182. }
  183. ret = scfs_make_header(lower_file, scfs_inode);
  184. if (ret)
  185. SCFS_PRINT_ERROR("error in make header\n");
  186. fput(lower_file);
  187. out:
  188. return ret;
  189. }
  190. #if 0
  191. int scfs_initialize_file(struct dentry *scfs_dentry, struct inode *scfs_inode)
  192. {
  193. struct scfs_inode_info *sii = SCFS_I(scfs_inode);
  194. int ret = 0;
  195. copy_mount_flags_to_inode_flags(scfs_inode, scfs_inode->i_sb);
  196. if (S_ISDIR(scfs_inode->i_mode)) {
  197. SCFS_PRINT_ERROR("it's a directory\n");
  198. sii->flags &= ~(SCFS_DATA_COMPRESSABLE);
  199. goto out;
  200. }
  201. /* last parameter may be O_RDWR */
  202. ret = scfs_get_lower_file(scfs_dentry, scfs_inode, EMPTY_FLAG);
  203. if (ret) {
  204. SCFS_PRINT_ERROR("error in get_lower_file, ret : %d\n", ret);
  205. goto out;
  206. }
  207. ret = scfs_make_header(scfs_dentry, scfs_inode);
  208. if (ret)
  209. SCFS_PRINT_ERROR("error in make header\n");
  210. scfs_put_lower_file(scfs_inode);
  211. out:
  212. return ret;
  213. }
  214. #endif
  215. static struct inode * scfs_do_create(struct inode *parent_inode,
  216. struct dentry *scfs_dentry, umode_t mode)
  217. {
  218. struct dentry *lower_file_dentry;
  219. struct dentry *lower_parent_dentry;
  220. struct inode *inode;
  221. int ret;
  222. lower_file_dentry = scfs_lower_dentry(scfs_dentry);
  223. lower_parent_dentry = lock_parent(lower_file_dentry);
  224. if (IS_ERR(lower_parent_dentry)) {
  225. SCFS_PRINT_ERROR("lower_parent_dentry is invalid\n");
  226. inode = ERR_CAST(lower_parent_dentry);
  227. goto out;
  228. }
  229. #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  230. ret = vfs_create(lower_parent_dentry->d_inode, lower_file_dentry, mode, true);
  231. #else
  232. ret = vfs_create(lower_parent_dentry->d_inode, lower_file_dentry, mode, NULL);
  233. #endif
  234. if (ret) {
  235. SCFS_PRINT_ERROR("error in vfs_create, lower create, ret : %d\n", ret);
  236. inode = ERR_PTR(ret);
  237. goto unlock;
  238. }
  239. inode = _scfs_get_inode(lower_file_dentry->d_inode, parent_inode->i_sb);
  240. if (IS_ERR(inode)) {
  241. SCFS_PRINT_ERROR("error in get_inode, so lower thing will be unlinked\n");
  242. vfs_unlink(lower_parent_dentry->d_inode, lower_file_dentry);
  243. goto unlock;
  244. }
  245. fsstack_copy_attr_times(parent_inode, lower_parent_dentry->d_inode);
  246. fsstack_copy_inode_size(parent_inode, lower_parent_dentry->d_inode);
  247. unlock:
  248. unlock_dir(lower_parent_dentry);
  249. out:
  250. return inode;
  251. }
  252. static int scfs_do_unlink(struct inode *dir, struct dentry *dentry, struct inode *inode)
  253. {
  254. struct dentry *lower_dentry = scfs_lower_dentry(dentry);
  255. struct inode *lower_dir_inode = scfs_lower_inode(dir);
  256. struct dentry *lower_dir_dentry;
  257. int ret;
  258. dget(lower_dentry);
  259. lower_dir_dentry = lock_parent(lower_dentry);
  260. ret = vfs_unlink(lower_dir_inode, lower_dentry);
  261. if (ret) {
  262. SCFS_PRINT_ERROR("error in vfs_unlink, ret : %d\n", ret);
  263. goto out;
  264. }
  265. fsstack_copy_attr_times(dir, lower_dir_inode);
  266. set_nlink(inode, scfs_lower_inode(inode)->i_nlink);
  267. inode->i_ctime = dir->i_ctime;
  268. d_drop(dentry);
  269. out:
  270. unlock_dir(lower_dir_dentry);
  271. dput(lower_dentry);
  272. return ret;
  273. }
  274. /************************/
  275. /* directory operations */
  276. /************************/
  277. /*
  278. * scfs_mkdir
  279. *
  280. * Parameters:
  281. * @*dir: inode of the dir to create
  282. * @*scfs_dentry: dentry of the dir to create
  283. * @mode:
  284. *
  285. * Return:
  286. * SCFS_SUCCESS if success, otherwise if error
  287. *
  288. * Description:
  289. * mkdir() for SCFS.
  290. */
  291. static int scfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
  292. {
  293. struct dentry *lower_dir_dentry;
  294. struct dentry *lower_parent_dentry;
  295. int ret;
  296. lower_dir_dentry = scfs_lower_dentry(dentry);
  297. lower_parent_dentry = lock_parent(lower_dir_dentry);
  298. ret = vfs_mkdir(lower_parent_dentry->d_inode, lower_dir_dentry, mode);
  299. if (ret || !lower_dir_dentry->d_inode) {
  300. SCFS_PRINT_ERROR("dir %s vfs_mkdir failed, "
  301. "lower_dir %s lower_parent %s mode %x\n",
  302. dentry->d_name.name,
  303. lower_dir_dentry->d_name.name,
  304. lower_parent_dentry->d_name.name, mode);
  305. goto out;
  306. }
  307. ret = scfs_interpose(lower_dir_dentry, dentry, dir->i_sb);
  308. if (ret) {
  309. SCFS_PRINT_ERROR("dir %s interpose failed, "
  310. "lower_dir %s lower_parent %s mode %x\n",
  311. dentry->d_name.name,
  312. lower_dir_dentry->d_name.name,
  313. lower_parent_dentry->d_name.name, mode);
  314. vfs_rmdir(lower_parent_dentry->d_inode, lower_dir_dentry);
  315. goto out;
  316. }
  317. fsstack_copy_attr_times(dir, lower_parent_dentry->d_inode);
  318. fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode);
  319. set_nlink(dir, lower_parent_dentry->d_inode->i_nlink);
  320. out:
  321. unlock_dir(lower_parent_dentry);
  322. if (!dentry->d_inode)
  323. d_drop(dentry);
  324. return ret;
  325. }
  326. /*
  327. * scfs_create
  328. *
  329. * Parameters:
  330. * @*parent_inode: inode of the parent directory
  331. * @*scfs_dentry: dentry of the file to create
  332. * @mode:
  333. * @*nd: nameidata
  334. *
  335. * Return:
  336. * SCFS_SUCCESS if success, otherwise if error
  337. *
  338. * Description:
  339. * create() for SCFS.
  340. */
  341. static int scfs_create(struct inode *parent_inode, struct dentry *scfs_dentry,
  342. #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  343. umode_t mode, bool dummy)
  344. #else
  345. umode_t mode, struct nameidata *nd)
  346. #endif
  347. {
  348. struct inode *scfs_inode;
  349. int ret;
  350. scfs_inode = scfs_do_create(parent_inode, scfs_dentry, mode);
  351. if (IS_ERR(scfs_inode)) {
  352. SCFS_PRINT_ERROR("file %s error in do_create\n",
  353. scfs_dentry->d_name.name);
  354. return PTR_ERR(scfs_inode);
  355. }
  356. ret = scfs_initialize_file(scfs_dentry, scfs_inode);
  357. if (ret) {
  358. scfs_do_unlink(parent_inode, scfs_dentry,
  359. scfs_inode);
  360. make_bad_inode(scfs_inode);
  361. unlock_new_inode(scfs_inode);
  362. iput(scfs_inode);
  363. } else {
  364. d_instantiate(scfs_dentry, scfs_inode);
  365. unlock_new_inode(scfs_inode);
  366. }
  367. return ret;
  368. }
  369. int scfs_footer_read(struct inode *inode, struct file *lower_file)
  370. {
  371. struct comp_footer cf;
  372. struct dentry *lower_dentry = lower_file->f_dentry;
  373. struct scfs_inode_info *sii = SCFS_I(inode);
  374. loff_t offset;
  375. loff_t lower_file_size;
  376. int ret = 0;
  377. if (S_ISDIR(inode->i_mode))
  378. return -EISDIR;
  379. lower_file_size = i_size_read(lower_file->f_mapping->host);
  380. offset = lower_file_size - CF_SIZE;
  381. if (offset < 0) {
  382. SCFS_PRINT("missing footer, %s\n", lower_dentry->d_name.name);
  383. return SCFS_MISSING_META;
  384. }
  385. ret = scfs_lower_read(lower_file, (char *)&cf, CF_SIZE, &offset);
  386. if (ret < 0) {
  387. SCFS_PRINT_ERROR("f:%s read comp_footer error, %d \n",
  388. lower_dentry->d_name.name, ret);
  389. return ret;
  390. }
  391. ret = 0;
  392. if (cf.magic != SCFS_MAGIC || cf.footer_size < CF_SIZE ||
  393. cf.footer_size > lower_file_size ||
  394. cf.cluster_size < 0 ||
  395. cf.cluster_size > SCFS_CLUSTER_SIZE_MAX) {
  396. SCFS_PRINT("f:%s invalid meta, magic : %x,"
  397. "cf.cluster_size %u, cf.comp_type %d, "
  398. "cf.footer_size %d, cf.original_file_size %lld, "
  399. "lower file size : %lld, cf_size %d, offset %lld\n",
  400. lower_dentry->d_name.name, cf.magic, cf.cluster_size,
  401. cf.comp_type, cf.footer_size, cf.original_file_size,
  402. lower_file_size, CF_SIZE, offset);
  403. return SCFS_MISSING_META;
  404. }
  405. sii->cinfo_array_size = cf.footer_size - CF_SIZE;
  406. sii->cluster_size = cf.cluster_size;
  407. i_size_write(inode, cf.original_file_size);
  408. sii->comp_type = cf.comp_type;
  409. if (cf.original_file_size) {
  410. if (!sii->cinfo_array_size) {
  411. sii->flags &= ~SCFS_DATA_COMPRESSABLE;
  412. sii->compressed = 0;
  413. } else
  414. sii->compressed = 1;
  415. } else
  416. sii->compressed = 0;
  417. return ret;
  418. }
  419. static int scfs_lookup_interpose(struct dentry *dentry, struct dentry *lower_dentry,
  420. struct inode *dir)
  421. {
  422. struct inode *inode, *lower_inode = lower_dentry->d_inode;
  423. struct scfs_dentry_info *dentry_info;
  424. struct vfsmount *lower_mnt;
  425. struct scfs_inode_info *sii;
  426. struct file *lower_file;
  427. int ret = 0;
  428. lower_mnt = mntget(scfs_dentry_to_lower_mnt(dentry->d_parent));
  429. fsstack_copy_attr_atime(dir, lower_dentry->d_parent->d_inode);
  430. BUG_ON(!lower_dentry->d_count);
  431. if (!dentry->d_fsdata) {
  432. dentry_info = kmem_cache_alloc(scfs_dentry_info_cache, GFP_KERNEL);
  433. dentry->d_fsdata = dentry_info;
  434. if (!dentry_info) {
  435. SCFS_PRINT_ERROR("dentry_info alloc failed\n");
  436. dput(lower_dentry);
  437. mntput(lower_mnt);
  438. d_drop(dentry);
  439. return -ENOMEM;
  440. }
  441. profile_add_kmcached(sizeof(struct scfs_dentry_info), SCFS_S(dir->i_sb));
  442. }
  443. scfs_set_lower_dentry(dentry, lower_dentry);
  444. scfs_set_dentry_lower_mnt(dentry, lower_mnt);
  445. if (!lower_dentry->d_inode) {
  446. d_add(dentry, NULL);
  447. return 0;
  448. }
  449. inode = _scfs_get_inode(lower_inode, dir->i_sb);
  450. if (IS_ERR(inode)) {
  451. SCFS_PRINT_ERROR("error in get_inode\n");
  452. return PTR_ERR(inode);
  453. }
  454. i_size_write(inode, i_size_read(lower_inode));
  455. if (S_ISREG(inode->i_mode)) {
  456. ret = scfs_initialize_lower_file(dentry, &lower_file, O_RDONLY);
  457. if (ret) {
  458. SCFS_PRINT_ERROR("err in get_lower_file %s\n",
  459. dentry->d_name.name);
  460. return ret;
  461. }
  462. /* retrieve i_size via footer read */
  463. ret = scfs_footer_read(inode, lower_file);
  464. fput(lower_file);
  465. /* if there is no footer, treat as not-compressed file */
  466. if (ret == SCFS_MISSING_META) {
  467. SCFS_PRINT("missing footer\n", ret);
  468. sii = SCFS_I(inode);
  469. sii->cinfo_array_size = 0;
  470. sii->flags &= ~SCFS_DATA_COMPRESSABLE;
  471. sii->cluster_size = SCFS_S(dentry->d_sb)->options.cluster_size;
  472. sii->comp_type = SCFS_S(dentry->d_sb)->options.comp_type;
  473. } else if (ret) {
  474. /* give a chance to handle the problem in loading meta */
  475. SCFS_PRINT_ERROR("error in loading footer, %s ret : %d\n",
  476. dentry->d_name.name, ret);
  477. MAKE_META_INVALID(SCFS_I(inode));
  478. }
  479. ret = 0;
  480. }
  481. if (inode->i_state & I_NEW)
  482. unlock_new_inode(inode);
  483. d_add(dentry, inode);
  484. return ret;
  485. }
  486. /*
  487. * scfs_lookup
  488. *
  489. */
  490. static struct dentry * scfs_lookup(struct inode *dir, struct dentry *dentry,
  491. #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  492. unsigned int flags)
  493. #else
  494. struct nameidata *nd)
  495. #endif
  496. {
  497. struct dentry *lower_dir_dentry, *lower_dentry;
  498. int ret = 0;
  499. lower_dir_dentry = scfs_lower_dentry(dentry->d_parent);
  500. mutex_lock(&lower_dir_dentry->d_inode->i_mutex);
  501. lower_dentry = lookup_one_len(dentry->d_name.name, lower_dir_dentry,
  502. dentry->d_name.len);
  503. mutex_unlock(&lower_dir_dentry->d_inode->i_mutex);
  504. if (IS_ERR(lower_dentry)) {
  505. d_drop(dentry);
  506. return lower_dentry;
  507. }
  508. ret = scfs_lookup_interpose(dentry, lower_dentry, dir);
  509. return ERR_PTR(ret);
  510. }
  511. static int scfs_rename(struct inode *old_dir, struct dentry *old_dentry,
  512. struct inode *new_dir, struct dentry *new_dentry)
  513. {
  514. struct dentry *lower_old_dentry;
  515. struct dentry *lower_new_dentry;
  516. struct dentry *lower_old_dir_dentry;
  517. struct dentry *lower_new_dir_dentry;
  518. struct dentry *trap = NULL;
  519. struct inode *target_inode;
  520. int ret;
  521. lower_old_dentry = scfs_lower_dentry(old_dentry);
  522. lower_new_dentry = scfs_lower_dentry(new_dentry);
  523. dget(lower_old_dentry);
  524. dget(lower_new_dentry);
  525. lower_old_dir_dentry = dget_parent(lower_old_dentry);
  526. lower_new_dir_dentry = dget_parent(lower_new_dentry);
  527. target_inode = new_dentry->d_inode;
  528. trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
  529. /* source should not be ancestor of target */
  530. if (trap == lower_old_dentry) {
  531. ret = -EINVAL;
  532. goto out_lock;
  533. }
  534. /* target should not be ancestor of source */
  535. if (trap == lower_new_dentry) {
  536. ret = -ENOTEMPTY;
  537. goto out_lock;
  538. }
  539. ret = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry,
  540. lower_new_dir_dentry->d_inode, lower_new_dentry);
  541. if (ret)
  542. goto out_lock;
  543. if (target_inode)
  544. fsstack_copy_attr_all(target_inode,
  545. scfs_lower_inode(target_inode));
  546. fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode);
  547. if (new_dir != old_dir)
  548. fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode);
  549. out_lock:
  550. unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
  551. dput(lower_new_dir_dentry);
  552. dput(lower_old_dir_dentry);
  553. dput(lower_new_dentry);
  554. dput(lower_old_dentry);
  555. return ret;
  556. }
  557. static int scfs_rmdir(struct inode *dir, struct dentry *dentry)
  558. {
  559. struct dentry *lower_dentry;
  560. struct dentry *lower_dir_dentry;
  561. int ret;
  562. lower_dentry = scfs_lower_dentry(dentry);
  563. dget(dentry);
  564. lower_dir_dentry = lock_parent(lower_dentry);
  565. dget(lower_dentry);
  566. ret = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
  567. dput(lower_dentry);
  568. if (!ret && dentry->d_inode)
  569. clear_nlink(dentry->d_inode);
  570. fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
  571. set_nlink(dir, lower_dir_dentry->d_inode->i_nlink);
  572. unlock_dir(lower_dir_dentry);
  573. if (!ret)
  574. d_drop(dentry);
  575. dput(dentry);
  576. return ret;
  577. }
  578. static int scfs_permission(struct inode *inode, int mask)
  579. {
  580. return inode_permission(scfs_lower_inode(inode), mask);
  581. }
  582. int scfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
  583. {
  584. struct kstat lower_stat;
  585. int ret;
  586. #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  587. struct path path = {scfs_dentry_to_lower_mnt(dentry),
  588. scfs_lower_dentry(dentry)};
  589. #endif
  590. ret = vfs_getattr(
  591. #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  592. &path,
  593. #else
  594. scfs_dentry_to_lower_mnt(dentry),
  595. scfs_lower_dentry(dentry),
  596. #endif
  597. &lower_stat);
  598. if (!ret) {
  599. fsstack_copy_attr_all(dentry->d_inode,
  600. scfs_lower_inode(dentry->d_inode));
  601. generic_fillattr(dentry->d_inode, stat);
  602. stat->blocks = lower_stat.blocks;
  603. }
  604. return ret;
  605. }
  606. static int scfs_unlink(struct inode *dir, struct dentry *dentry)
  607. {
  608. return scfs_do_unlink(dir, dentry, dentry->d_inode);
  609. }
  610. static int scfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
  611. {
  612. struct dentry *lower_dentry;
  613. struct dentry *lower_dir_dentry;
  614. int ret;
  615. lower_dentry = scfs_lower_dentry(dentry);
  616. dget(lower_dentry);
  617. lower_dir_dentry = lock_parent(lower_dentry);
  618. ret = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, symname);
  619. if (ret || !lower_dentry->d_inode)
  620. goto out;
  621. ret = scfs_interpose(lower_dentry, dentry, dir->i_sb);
  622. if (ret)
  623. goto out;
  624. fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
  625. fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode);
  626. out:
  627. unlock_dir(lower_dir_dentry);
  628. dput(lower_dentry);
  629. if (!dentry->d_inode)
  630. d_drop(dentry);
  631. return ret;
  632. }
  633. static int scfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
  634. {
  635. struct dentry *lower_dentry;
  636. struct dentry *lower_dir_dentry;
  637. int ret;
  638. lower_dentry = scfs_lower_dentry(dentry);
  639. lower_dir_dentry = lock_parent(lower_dentry);
  640. ret = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev);
  641. if (ret || !lower_dentry->d_inode)
  642. goto out;
  643. ret = scfs_interpose(lower_dentry, dentry, dir->i_sb);
  644. if (ret)
  645. goto out;
  646. fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
  647. fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode);
  648. out:
  649. unlock_dir(lower_dir_dentry);
  650. if (!dentry->d_inode)
  651. d_drop(dentry);
  652. return ret;
  653. }
  654. static int scfs_link(struct dentry *old_dentry, struct inode *dir,
  655. struct dentry *new_dentry)
  656. {
  657. struct dentry *lower_old_dentry;
  658. struct dentry *lower_new_dentry;
  659. struct dentry *lower_dir_dentry;
  660. u64 file_size_save;
  661. int ret;
  662. file_size_save = i_size_read(old_dentry->d_inode);
  663. lower_old_dentry = scfs_lower_dentry(old_dentry);
  664. lower_new_dentry = scfs_lower_dentry(new_dentry);
  665. dget(lower_old_dentry);
  666. dget(lower_new_dentry);
  667. lower_dir_dentry = lock_parent(lower_new_dentry);
  668. ret = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode,
  669. lower_new_dentry);
  670. if (ret || !lower_new_dentry->d_inode)
  671. goto out;
  672. ret = scfs_interpose(lower_new_dentry, new_dentry, dir->i_sb);
  673. if (ret)
  674. goto out;
  675. fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
  676. fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode);
  677. set_nlink(old_dentry->d_inode,
  678. scfs_lower_inode(old_dentry->d_inode)->i_nlink);
  679. i_size_write(new_dentry->d_inode, file_size_save);
  680. out:
  681. unlock_dir(lower_dir_dentry);
  682. dput(lower_new_dentry);
  683. dput(lower_old_dentry);
  684. return ret;
  685. }
  686. static int scfs_setattr(struct dentry *dentry, struct iattr *ia)
  687. {
  688. struct inode *inode;
  689. struct inode *lower_inode;
  690. struct dentry *lower_dentry;
  691. struct iattr lower_ia;
  692. int ret = 0;
  693. inode = dentry->d_inode;
  694. lower_inode = scfs_lower_inode(inode);
  695. lower_dentry = scfs_lower_dentry(dentry);
  696. ret = inode_change_ok(inode, ia);
  697. if (ret)
  698. goto out;
  699. memcpy(&lower_ia, ia, sizeof(lower_ia));
  700. if (ia->ia_valid & ATTR_FILE)
  701. lower_ia.ia_file = scfs_lower_file(ia->ia_file);
  702. if (ia->ia_valid & ATTR_SIZE) {
  703. ret = scfs_truncate(dentry, ia->ia_size);
  704. if (ret)
  705. goto out;
  706. lower_ia.ia_valid &= ~ATTR_SIZE;
  707. }
  708. if (lower_ia.ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
  709. lower_ia.ia_valid &= ~ATTR_MODE;
  710. mutex_lock(&lower_dentry->d_inode->i_mutex);
  711. ret = notify_change(lower_dentry, &lower_ia);
  712. mutex_unlock(&lower_dentry->d_inode->i_mutex);
  713. out:
  714. fsstack_copy_attr_all(inode, lower_inode);
  715. return ret;
  716. }
  717. static int scfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
  718. {
  719. struct dentry *lower_dentry;
  720. char *kbuf;
  721. size_t kbufsiz = PATH_MAX, copied;
  722. mm_segment_t old_fs;
  723. int ret;
  724. lower_dentry = scfs_lower_dentry(dentry);
  725. kbuf = kmalloc(kbufsiz, GFP_KERNEL);
  726. if (!kbuf)
  727. return -ENOMEM;
  728. profile_add_kmalloced(PATH_MAX, SCFS_S(dentry->d_sb));
  729. old_fs = get_fs();
  730. set_fs(get_ds());
  731. ret = lower_dentry->d_inode->i_op->readlink(lower_dentry,
  732. (char __user *)kbuf,
  733. kbufsiz);
  734. set_fs(old_fs);
  735. if (ret < 0)
  736. goto out;
  737. kbufsiz = ret;
  738. copied = min_t(size_t, bufsiz, kbufsiz);
  739. ret = copy_to_user(buf, kbuf, copied) ? -EFAULT : copied;
  740. fsstack_copy_attr_atime(dentry->d_inode,
  741. scfs_lower_dentry(dentry)->d_inode);
  742. out:
  743. kfree(kbuf);
  744. profile_sub_kmalloced(PATH_MAX, SCFS_S(dentry->d_sb));
  745. return ret;
  746. }
  747. static void *scfs_follow_link(struct dentry *dentry, struct nameidata *nd)
  748. {
  749. char *buf;
  750. int len = PAGE_SIZE, ret;
  751. mm_segment_t old_fs;
  752. buf = kmalloc(len, GFP_KERNEL);
  753. if (!buf) {
  754. buf = ERR_PTR(-ENOMEM);
  755. goto out;
  756. }
  757. profile_add_kmalloced(len, SCFS_S(dentry->d_sb));
  758. old_fs = get_fs();
  759. set_fs(get_ds());
  760. ret = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len);
  761. set_fs(old_fs);
  762. if (ret < 0) {
  763. kfree(buf);
  764. profile_sub_kmalloced(len, SCFS_S(dentry->d_sb));
  765. buf = ERR_PTR(ret);
  766. } else
  767. buf[ret] = '\0';
  768. out:
  769. nd_set_link(nd, buf);
  770. return NULL;
  771. }
  772. static void scfs_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr)
  773. {
  774. char *buf = nd_get_link(nd);
  775. if (!IS_ERR(buf)) {
  776. kfree(buf);
  777. profile_sub_kmalloced(PAGE_SIZE, SCFS_S(dentry->d_sb));
  778. }
  779. }
  780. int scfs_setxattr(struct dentry *dentry, const char *name, const void *value,
  781. size_t size, int flags)
  782. {
  783. struct dentry *lower_dentry;
  784. int ret = 0;
  785. lower_dentry = scfs_lower_dentry(dentry);
  786. if (!lower_dentry->d_inode->i_op->setxattr) {
  787. ret = -EOPNOTSUPP;
  788. goto out;
  789. }
  790. ret = vfs_setxattr(lower_dentry, name, value, size, flags);
  791. if (!ret)
  792. fsstack_copy_attr_all(dentry->d_inode, lower_dentry->d_inode);
  793. out:
  794. return ret;
  795. }
  796. ssize_t scfs_getxattr_lower(struct dentry *lower_dentry, const char *name,
  797. void *value, size_t size)
  798. {
  799. int ret = 0;
  800. if (!lower_dentry->d_inode->i_op->getxattr) {
  801. ret = -EOPNOTSUPP;
  802. goto out;
  803. }
  804. mutex_lock(&lower_dentry->d_inode->i_mutex);
  805. ret = lower_dentry->d_inode->i_op->getxattr(lower_dentry, name, value,
  806. size);
  807. mutex_unlock(&lower_dentry->d_inode->i_mutex);
  808. out:
  809. return ret;
  810. }
  811. static ssize_t scfs_getxattr(struct dentry *dentry, const char *name, void *value,
  812. size_t size)
  813. {
  814. return scfs_getxattr_lower(scfs_lower_dentry(dentry), name,
  815. value, size);
  816. }
  817. static ssize_t scfs_listxattr(struct dentry *dentry, char *list, size_t size)
  818. {
  819. struct dentry *lower_dentry;
  820. int ret = 0;
  821. lower_dentry = scfs_lower_dentry(dentry);
  822. if (!lower_dentry->d_inode->i_op->listxattr) {
  823. ret = -EOPNOTSUPP;
  824. goto out;
  825. }
  826. mutex_lock(&lower_dentry->d_inode->i_mutex);
  827. ret = lower_dentry->d_inode->i_op->listxattr(lower_dentry, list, size);
  828. mutex_unlock(&lower_dentry->d_inode->i_mutex);
  829. out:
  830. return ret;
  831. }
  832. static int scfs_removexattr(struct dentry *dentry, const char *name)
  833. {
  834. struct dentry *lower_dentry;
  835. int ret = 0;
  836. lower_dentry = scfs_lower_dentry(dentry);
  837. if (!lower_dentry->d_inode->i_op->removexattr) {
  838. ret = -EOPNOTSUPP;
  839. goto out;
  840. }
  841. mutex_lock(&lower_dentry->d_inode->i_mutex);
  842. ret = lower_dentry->d_inode->i_op->removexattr(lower_dentry, name);
  843. mutex_unlock(&lower_dentry->d_inode->i_mutex);
  844. out:
  845. return ret;
  846. }
  847. /*******************************/
  848. /* inode_operations structures */
  849. /*******************************/
  850. const struct inode_operations scfs_dir_iops = {
  851. .create = scfs_create,
  852. .lookup = scfs_lookup,
  853. .link = scfs_link,
  854. .mkdir = scfs_mkdir,
  855. .rmdir = scfs_rmdir,
  856. .mknod = scfs_mknod,
  857. .rename = scfs_rename,
  858. .permission = scfs_permission,
  859. .unlink = scfs_unlink,
  860. .symlink = scfs_symlink,
  861. .setattr = scfs_setattr,
  862. .setxattr = scfs_setxattr,
  863. .getxattr = scfs_getxattr,
  864. .listxattr = scfs_listxattr,
  865. .removexattr = scfs_removexattr
  866. };
  867. const struct inode_operations scfs_file_iops = {
  868. .permission = scfs_permission,
  869. .setattr = scfs_setattr,
  870. .getattr = scfs_getattr,
  871. .setxattr = scfs_setxattr,
  872. .getxattr = scfs_getxattr,
  873. .listxattr = scfs_listxattr,
  874. .removexattr = scfs_removexattr
  875. };
  876. const struct inode_operations scfs_symlink_iops = {
  877. .readlink = scfs_readlink,
  878. .follow_link = scfs_follow_link,
  879. .put_link = scfs_put_link,
  880. .permission = scfs_permission,
  881. .setattr = scfs_setattr,
  882. .getattr = scfs_getattr,
  883. .setxattr = scfs_setxattr,
  884. .getxattr = scfs_getxattr,
  885. .listxattr = scfs_listxattr,
  886. .removexattr = scfs_removexattr
  887. };