inode.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:15k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * linux/fs/hfs/inode.c
  3.  *
  4.  * Copyright (C) 1995-1997  Paul H. Hargrove
  5.  * This file may be distributed under the terms of the GNU General Public License.
  6.  *
  7.  * This file contains inode-related functions which do not depend on
  8.  * which scheme is being used to represent forks.
  9.  *
  10.  * Based on the minix file system code, (C) 1991, 1992 by Linus Torvalds
  11.  *
  12.  * "XXX" in a comment is a note to myself to consider changing something.
  13.  *
  14.  * In function preconditions the term "valid" applied to a pointer to
  15.  * a structure means that the pointer is non-NULL and the structure it
  16.  * points to has all fields initialized to consistent values.
  17.  */
  18. #include "hfs.h"
  19. #include <linux/hfs_fs_sb.h>
  20. #include <linux/hfs_fs_i.h>
  21. #include <linux/hfs_fs.h>
  22. #include <linux/smp_lock.h>
  23. /*================ Variable-like macros ================*/
  24. #define HFS_VALID_MODE_BITS  (S_IFREG | S_IFDIR | S_IRWXUGO)
  25. /*================ File-local functions ================*/
  26. /*
  27.  * init_file_inode()
  28.  *
  29.  * Given an HFS catalog entry initialize an inode for a file.
  30.  */
  31. static void init_file_inode(struct inode *inode, hfs_u8 fork)
  32. {
  33. struct hfs_fork *fk;
  34. struct hfs_cat_entry *entry = HFS_I(inode)->entry;
  35. if (fork == HFS_FK_DATA) {
  36. inode->i_mode = S_IRWXUGO | S_IFREG;
  37. } else {
  38. inode->i_mode = S_IRUGO | S_IWUGO | S_IFREG;
  39. }
  40. if (fork == HFS_FK_DATA) {
  41. #if 0 /* XXX: disable crlf translations for now */
  42. hfs_u32 type = hfs_get_nl(entry->info.file.finfo.fdType);
  43. HFS_I(inode)->convert =
  44. ((HFS_SB(inode->i_sb)->s_conv == 't') ||
  45.  ((HFS_SB(inode->i_sb)->s_conv == 'a') &&
  46.   ((type == htonl(0x54455854)) ||   /* "TEXT" */
  47.    (type == htonl(0x7474726f)))));  /* "ttro" */
  48. #else
  49. HFS_I(inode)->convert = 0;
  50. #endif
  51. fk = &entry->u.file.data_fork;
  52. } else {
  53. fk = &entry->u.file.rsrc_fork;
  54. HFS_I(inode)->convert = 0;
  55. }
  56. HFS_I(inode)->fork = fk;
  57. inode->i_size = fk->lsize;
  58. inode->i_blocks = fk->psize;
  59. inode->i_nlink = 1;
  60. }
  61. /*================ Global functions ================*/
  62. /*
  63.  * hfs_put_inode()
  64.  *
  65.  * This is the put_inode() entry in the super_operations for HFS
  66.  * filesystems.  The purpose is to perform any filesystem-dependent 
  67.  * cleanup necessary when the use-count of an inode falls to zero.
  68.  */
  69. void hfs_put_inode(struct inode * inode)
  70. {
  71. struct hfs_cat_entry *entry = HFS_I(inode)->entry;
  72. lock_kernel();
  73. hfs_cat_put(entry);
  74. if (atomic_read(&inode->i_count) == 1) {
  75.   struct hfs_hdr_layout *tmp = HFS_I(inode)->layout;
  76.   if (tmp) {
  77. HFS_I(inode)->layout = NULL;
  78. HFS_DELETE(tmp);
  79.   }
  80. }
  81. unlock_kernel();
  82. }
  83. /*
  84.  * hfs_notify_change()
  85.  *
  86.  * Based very closely on fs/msdos/inode.c by Werner Almesberger
  87.  *
  88.  * This is the notify_change() field in the super_operations structure
  89.  * for HFS file systems.  The purpose is to take that changes made to
  90.  * an inode and apply then in a filesystem-dependent manner.  In this
  91.  * case the process has a few of tasks to do:
  92.  *  1) prevent changes to the i_uid and i_gid fields.
  93.  *  2) map file permissions to the closest allowable permissions
  94.  *  3) Since multiple Linux files can share the same on-disk inode under
  95.  *     HFS (for instance the data and resource forks of a file) a change
  96.  *     to permissions must be applied to all other in-core inodes which 
  97.  *     correspond to the same HFS file.
  98.  */
  99. enum {HFS_NORM, HFS_HDR, HFS_CAP};
  100. static int __hfs_notify_change(struct dentry *dentry, struct iattr * attr, int kind)
  101. {
  102. struct inode *inode = dentry->d_inode;
  103. struct hfs_cat_entry *entry = HFS_I(inode)->entry;
  104. struct dentry **de = entry->sys_entry;
  105. struct hfs_sb_info *hsb = HFS_SB(inode->i_sb);
  106. int error, i;
  107. error = inode_change_ok(inode, attr); /* basic permission checks */
  108. if (error) {
  109. /* Let netatalk's afpd think chmod() always succeeds */
  110. if (hsb->s_afpd &&
  111.     (attr->ia_valid == (ATTR_MODE | ATTR_CTIME))) {
  112. return 0;
  113. } else {
  114. return error;
  115. }
  116. }
  117. /* no uig/gid changes and limit which mode bits can be set */
  118. if (((attr->ia_valid & ATTR_UID) && 
  119.      (attr->ia_uid != hsb->s_uid)) ||
  120.     ((attr->ia_valid & ATTR_GID) && 
  121.      (attr->ia_gid != hsb->s_gid)) ||
  122.     ((attr->ia_valid & ATTR_MODE) &&
  123.      (((entry->type == HFS_CDR_DIR) &&
  124.        (attr->ia_mode != inode->i_mode))||
  125.       (attr->ia_mode & ~HFS_VALID_MODE_BITS)))) {
  126. return hsb->s_quiet ? 0 : error;
  127. }
  128. if (entry->type == HFS_CDR_DIR) {
  129. attr->ia_valid &= ~ATTR_MODE;
  130. } else if (attr->ia_valid & ATTR_MODE) {
  131. /* Only the 'w' bits can ever change and only all together. */
  132. if (attr->ia_mode & S_IWUSR) {
  133. attr->ia_mode = inode->i_mode | S_IWUGO;
  134. } else {
  135. attr->ia_mode = inode->i_mode & ~S_IWUGO;
  136. }
  137. attr->ia_mode &= ~hsb->s_umask;
  138. }
  139. /*
  140.  * Normal files handle size change in normal way.
  141.  * Oddballs are served here.
  142.  */
  143. if (attr->ia_valid & ATTR_SIZE) {
  144. if (kind == HFS_CAP) {
  145. inode->i_size = attr->ia_size;
  146. if (inode->i_size > HFS_FORK_MAX)
  147. inode->i_size = HFS_FORK_MAX;
  148. mark_inode_dirty(inode);
  149. attr->ia_valid &= ~ATTR_SIZE;
  150. } else if (kind == HFS_HDR) {
  151. hdr_truncate(inode, attr->ia_size);
  152. attr->ia_valid &= ~ATTR_SIZE;
  153. }
  154. }
  155. error = inode_setattr(inode, attr);
  156. if (error)
  157. return error;
  158. /* We wouldn't want to mess with the sizes of the other fork */
  159. attr->ia_valid &= ~ATTR_SIZE;
  160. /* We must change all in-core inodes corresponding to this file. */
  161. for (i = 0; i < 4; ++i) {
  162.   if (de[i] && (de[i] != dentry)) {
  163. inode_setattr(de[i]->d_inode, attr);
  164.   }
  165. }
  166. /* Change the catalog entry if needed */
  167. if (attr->ia_valid & ATTR_MTIME) {
  168. entry->modify_date = hfs_u_to_mtime(inode->i_mtime);
  169. hfs_cat_mark_dirty(entry);
  170. }
  171. if (attr->ia_valid & ATTR_MODE) {
  172. hfs_u8 new_flags;
  173. if (inode->i_mode & S_IWUSR) {
  174. new_flags = entry->u.file.flags & ~HFS_FIL_LOCK;
  175. } else {
  176. new_flags = entry->u.file.flags | HFS_FIL_LOCK;
  177. }
  178. if (new_flags != entry->u.file.flags) {
  179. entry->u.file.flags = new_flags;
  180. hfs_cat_mark_dirty(entry);
  181. }
  182. }
  183. /* size changes handled in hfs_extent_adj() */
  184. return 0;
  185. }
  186. int hfs_notify_change(struct dentry *dentry, struct iattr * attr)
  187. {
  188. return __hfs_notify_change(dentry, attr, HFS_NORM);
  189. }
  190. int hfs_notify_change_cap(struct dentry *dentry, struct iattr * attr)
  191. {
  192. return __hfs_notify_change(dentry, attr, HFS_CAP);
  193. }
  194. int hfs_notify_change_hdr(struct dentry *dentry, struct iattr * attr)
  195. {
  196. return __hfs_notify_change(dentry, attr, HFS_HDR);
  197. }
  198. static int hfs_writepage(struct page *page)
  199. {
  200. return block_write_full_page(page,hfs_get_block);
  201. }
  202. static int hfs_readpage(struct file *file, struct page *page)
  203. {
  204. return block_read_full_page(page,hfs_get_block);
  205. }
  206. static int hfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
  207. {
  208. return cont_prepare_write(page,from,to,hfs_get_block,
  209. &page->mapping->host->u.hfs_i.mmu_private);
  210. }
  211. static int hfs_bmap(struct address_space *mapping, long block)
  212. {
  213. return generic_block_bmap(mapping,block,hfs_get_block);
  214. }
  215. struct address_space_operations hfs_aops = {
  216. readpage: hfs_readpage,
  217. writepage: hfs_writepage,
  218. sync_page: block_sync_page,
  219. prepare_write: hfs_prepare_write,
  220. commit_write: generic_commit_write,
  221. bmap: hfs_bmap
  222. };
  223. /*
  224.  * __hfs_iget()
  225.  *
  226.  * Given the MDB for a HFS filesystem, a 'key' and an 'entry' in
  227.  * the catalog B-tree and the 'type' of the desired file return the
  228.  * inode for that file/directory or NULL.  Note that 'type' indicates
  229.  * whether we want the actual file or directory, or the corresponding
  230.  * metadata (AppleDouble header file or CAP metadata file).
  231.  *
  232.  * In an ideal world we could call iget() and would not need this
  233.  * function.  However, since there is no way to even know the inode
  234.  * number until we've found the file/directory in the catalog B-tree
  235.  * that simply won't happen.
  236.  *
  237.  * The main idea here is to look in the catalog B-tree to get the
  238.  * vital info about the file or directory (including the file id which
  239.  * becomes the inode number) and then to call iget() and return the
  240.  * inode if it is complete.  If it is not then we use the catalog
  241.  * entry to fill in the missing info, by calling the appropriate
  242.  * 'fillin' function.  Note that these fillin functions are
  243.  * essentially hfs_*_read_inode() functions, but since there is no way
  244.  * to pass the catalog entry through iget() to such a read_inode()
  245.  * function, we have to call them after iget() returns an incomplete
  246.  * inode to us.  This is pretty much the same problem faced in the NFS
  247.  * code, and pretty much the same solution. The SMB filesystem deals
  248.  * with this in a different way: by using the address of the
  249.  * kmalloc()'d space which holds the data as the inode number.
  250.  *
  251.  * XXX: Both this function and NFS's corresponding nfs_fhget() would
  252.  * benefit from a way to pass an additional (void *) through iget() to
  253.  * the VFS read_inode() function.
  254.  *
  255.  * this will hfs_cat_put() the entry if it fails.
  256.  */
  257. struct inode *hfs_iget(struct hfs_cat_entry *entry, ino_t type,
  258.        struct dentry *dentry)
  259. {
  260. struct dentry **sys_entry;
  261. struct super_block *sb;
  262. struct inode *inode;
  263. if (!entry) {
  264. return NULL;
  265. }
  266. /* If there are several processes all calling __iget() for
  267.    the same inode then they will all get the same one back.
  268.    The first one to return from __iget() will notice that the
  269.    i_mode field of the inode is blank and KNOW that it is
  270.    the first to return.  Therefore, it will set the appropriate
  271.    'sys_entry' field in the entry and initialize the inode.
  272.    All the initialization must be done without sleeping,
  273.    or else other processes could end up using a partially
  274.    initialized inode. */
  275. sb = entry->mdb->sys_mdb;
  276. sys_entry = &entry->sys_entry[HFS_ITYPE_TO_INT(type)];
  277. if (!(inode = iget(sb, ntohl(entry->cnid) | type))) {
  278.         hfs_cat_put(entry);
  279.         return NULL;
  280. }
  281. if (inode->i_dev != sb->s_dev) {
  282.         iput(inode); /* automatically does an hfs_cat_put */
  283. inode = NULL;
  284. } else if (!inode->i_mode || (*sys_entry == NULL)) {
  285. /* Initialize the inode */
  286. struct hfs_sb_info *hsb = HFS_SB(sb);
  287. inode->i_rdev = 0;
  288. inode->i_ctime = inode->i_atime = inode->i_mtime =
  289. hfs_m_to_utime(entry->modify_date);
  290. inode->i_blksize = HFS_SECTOR_SIZE;
  291. inode->i_uid = hsb->s_uid;
  292. inode->i_gid = hsb->s_gid;
  293. memset(HFS_I(inode), 0, sizeof(struct hfs_inode_info));
  294. HFS_I(inode)->magic = HFS_INO_MAGIC;
  295. HFS_I(inode)->entry = entry;
  296. HFS_I(inode)->tz_secondswest = hfs_to_utc(0);
  297. hsb->s_ifill(inode, type, hsb->s_version);
  298. if (!hsb->s_afpd && (entry->type == HFS_CDR_FIL) &&
  299.     (entry->u.file.flags & HFS_FIL_LOCK)) {
  300. inode->i_mode &= ~S_IWUGO;
  301. }
  302. inode->i_mode &= ~hsb->s_umask;
  303. if (!inode->i_mode) {
  304. iput(inode); /* does an hfs_cat_put */
  305. inode = NULL;
  306. } else
  307. *sys_entry = dentry; /* cache dentry */
  308. }
  309. return inode;
  310. }
  311. /*================ Scheme-specific functions ================*/
  312. /* 
  313.  * hfs_cap_ifill()
  314.  *
  315.  * This function serves the same purpose as a read_inode() function does
  316.  * in other filesystems.  It is called by __hfs_iget() to fill in
  317.  * the missing fields of an uninitialized inode under the CAP scheme.
  318.  */
  319. void hfs_cap_ifill(struct inode * inode, ino_t type, const int version)
  320. {
  321. struct hfs_cat_entry *entry = HFS_I(inode)->entry;
  322. HFS_I(inode)->d_drop_op = hfs_cap_drop_dentry;
  323. if (type == HFS_CAP_FNDR) {
  324. inode->i_size = sizeof(struct hfs_cap_info);
  325. inode->i_blocks = 0;
  326. inode->i_nlink = 1;
  327. inode->i_mode = S_IRUGO | S_IWUGO | S_IFREG;
  328. inode->i_op = &hfs_cap_info_inode_operations;
  329. inode->i_fop = &hfs_cap_info_operations;
  330. } else if (entry->type == HFS_CDR_FIL) {
  331. init_file_inode(inode, (type == HFS_CAP_DATA) ?
  332. HFS_FK_DATA : HFS_FK_RSRC);
  333. inode->i_op = &hfs_file_inode_operations;
  334. inode->i_fop = &hfs_file_operations;
  335. inode->i_mapping->a_ops = &hfs_aops;
  336. inode->u.hfs_i.mmu_private = inode->i_size;
  337. } else { /* Directory */
  338. struct hfs_dir *hdir = &entry->u.dir;
  339. inode->i_blocks = 0;
  340. inode->i_size = hdir->files + hdir->dirs + 5;
  341. HFS_I(inode)->dir_size = 1;
  342. if (type == HFS_CAP_NDIR) {
  343. inode->i_mode = S_IRWXUGO | S_IFDIR;
  344. inode->i_nlink = hdir->dirs + 4;
  345. inode->i_op = &hfs_cap_ndir_inode_operations;
  346. inode->i_fop = &hfs_cap_dir_operations;
  347. HFS_I(inode)->file_type = HFS_CAP_NORM;
  348. } else if (type == HFS_CAP_FDIR) {
  349. inode->i_mode = S_IRUGO | S_IXUGO | S_IFDIR;
  350. inode->i_nlink = 2;
  351. inode->i_op = &hfs_cap_fdir_inode_operations;
  352. inode->i_fop = &hfs_cap_dir_operations;
  353. HFS_I(inode)->file_type = HFS_CAP_FNDR;
  354. } else if (type == HFS_CAP_RDIR) {
  355. inode->i_mode = S_IRUGO | S_IXUGO | S_IFDIR;
  356. inode->i_nlink = 2;
  357. inode->i_op = &hfs_cap_rdir_inode_operations;
  358. inode->i_fop = &hfs_cap_dir_operations;
  359. HFS_I(inode)->file_type = HFS_CAP_RSRC;
  360. }
  361. }
  362. }
  363. /* 
  364.  * hfs_dbl_ifill()
  365.  *
  366.  * This function serves the same purpose as a read_inode() function does
  367.  * in other filesystems.  It is called by __hfs_iget() to fill in
  368.  * the missing fields of an uninitialized inode under the AppleDouble
  369.  * scheme.
  370.  */
  371. void hfs_dbl_ifill(struct inode * inode, ino_t type, const int version)
  372. {
  373. struct hfs_cat_entry *entry = HFS_I(inode)->entry;
  374. HFS_I(inode)->d_drop_op = hfs_dbl_drop_dentry;
  375. if (type == HFS_DBL_HDR) {
  376. if (entry->type == HFS_CDR_FIL) {
  377. init_file_inode(inode, HFS_FK_RSRC);
  378. inode->i_size += HFS_DBL_HDR_LEN;
  379. HFS_I(inode)->default_layout = &hfs_dbl_fil_hdr_layout;
  380. } else {
  381. inode->i_size = HFS_DBL_HDR_LEN;
  382. inode->i_mode = S_IRUGO | S_IWUGO | S_IFREG;
  383. inode->i_nlink = 1;
  384. HFS_I(inode)->default_layout = &hfs_dbl_dir_hdr_layout;
  385. }
  386. inode->i_op = &hfs_hdr_inode_operations;
  387. inode->i_fop = &hfs_hdr_operations;
  388. } else if (entry->type == HFS_CDR_FIL) {
  389. init_file_inode(inode, HFS_FK_DATA);
  390. inode->i_op = &hfs_file_inode_operations;
  391. inode->i_fop = &hfs_file_operations;
  392. inode->i_mapping->a_ops = &hfs_aops;
  393. inode->u.hfs_i.mmu_private = inode->i_size;
  394. } else { /* Directory */
  395. struct hfs_dir *hdir = &entry->u.dir;
  396. inode->i_blocks = 0;
  397. inode->i_nlink = hdir->dirs + 2;
  398. inode->i_size = 3 + 2 * (hdir->dirs + hdir->files);
  399. inode->i_mode = S_IRWXUGO | S_IFDIR;
  400. inode->i_op = &hfs_dbl_dir_inode_operations;
  401. inode->i_fop = &hfs_dbl_dir_operations;
  402. HFS_I(inode)->file_type = HFS_DBL_NORM;
  403. HFS_I(inode)->dir_size = 2;
  404. }
  405. }
  406. /* 
  407.  * hfs_nat_ifill()
  408.  *
  409.  * This function serves the same purpose as a read_inode() function does
  410.  * in other filesystems.  It is called by __hfs_iget() to fill in
  411.  * the missing fields of an uninitialized inode under the Netatalk
  412.  * scheme.
  413.  */
  414. void hfs_nat_ifill(struct inode * inode, ino_t type, const int version)
  415. {
  416. struct hfs_cat_entry *entry = HFS_I(inode)->entry;
  417. HFS_I(inode)->d_drop_op = hfs_nat_drop_dentry;
  418. if (type == HFS_NAT_HDR) {
  419. if (entry->type == HFS_CDR_FIL) {
  420. init_file_inode(inode, HFS_FK_RSRC);
  421. inode->i_size += HFS_NAT_HDR_LEN;
  422. } else {
  423. inode->i_size = HFS_NAT_HDR_LEN;
  424. inode->i_mode = S_IRUGO | S_IWUGO | S_IFREG;
  425. inode->i_nlink = 1;
  426. }
  427. inode->i_op = &hfs_hdr_inode_operations;
  428. inode->i_fop = &hfs_hdr_operations;
  429. HFS_I(inode)->default_layout = (version == 2) ?
  430. &hfs_nat2_hdr_layout : &hfs_nat_hdr_layout;
  431. } else if (entry->type == HFS_CDR_FIL) {
  432. init_file_inode(inode, HFS_FK_DATA);
  433. inode->i_op = &hfs_file_inode_operations;
  434. inode->i_fop = &hfs_file_operations;
  435. inode->i_mapping->a_ops = &hfs_aops;
  436. inode->u.hfs_i.mmu_private = inode->i_size;
  437. } else { /* Directory */
  438. struct hfs_dir *hdir = &entry->u.dir;
  439. inode->i_blocks = 0;
  440. inode->i_size = hdir->files + hdir->dirs + 4;
  441. inode->i_mode = S_IRWXUGO | S_IFDIR;
  442. HFS_I(inode)->dir_size = 1;
  443. if (type == HFS_NAT_NDIR) {
  444. inode->i_nlink = hdir->dirs + 3;
  445. inode->i_op = &hfs_nat_ndir_inode_operations;
  446. HFS_I(inode)->file_type = HFS_NAT_NORM;
  447. } else if (type == HFS_NAT_HDIR) {
  448. inode->i_nlink = 2;
  449. inode->i_op = &hfs_nat_hdir_inode_operations;
  450. HFS_I(inode)->file_type = HFS_NAT_HDR;
  451. }
  452. inode->i_fop = &hfs_nat_dir_operations;
  453. }
  454. }