file_hdr.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:26k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * linux/fs/hfs/file_hdr.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 the file_ops and inode_ops for the metadata
  8.  * files under the AppleDouble and Netatalk representations.
  9.  *
  10.  * The source code distributions of Netatalk, versions 1.3.3b2 and
  11.  * 1.4b2, were used as a specification of the location and format of
  12.  * files used by Netatalk's afpd.  No code from Netatalk appears in
  13.  * hfs_fs.  hfs_fs is not a work ``derived'' from Netatalk in the
  14.  * sense of intellectual property law.
  15.  *
  16.  * "XXX" in a comment is a note to myself to consider changing something.
  17.  *
  18.  * In function preconditions the term "valid" applied to a pointer to
  19.  * a structure means that the pointer is non-NULL and the structure it
  20.  * points to has all fields initialized to consistent values.
  21.  *
  22.  * XXX: Note the reason that there is not bmap() for AppleDouble
  23.  * header files is that dynamic nature of their structure make it
  24.  * very difficult to safely mmap them.  Maybe in the distant future
  25.  * I'll get bored enough to implement it.
  26.  */
  27. #include "hfs.h"
  28. #include <linux/hfs_fs_sb.h>
  29. #include <linux/hfs_fs_i.h>
  30. #include <linux/hfs_fs.h>
  31. /* prodos types */
  32. #define PRODOSI_FTYPE_DIR   0x0F
  33. #define PRODOSI_FTYPE_TEXT  0x04
  34. #define PRODOSI_FTYPE_8BIT  0xFF
  35. #define PRODOSI_FTYPE_16BIT 0xB3
  36. #define PRODOSI_AUXTYPE_DIR 0x0200
  37. /*================ Forward declarations ================*/
  38. static loff_t      hdr_llseek(struct file *, loff_t, int);
  39. static hfs_rwret_t hdr_read(struct file *, char *, hfs_rwarg_t, loff_t *);
  40. static hfs_rwret_t hdr_write(struct file *, const char *,
  41.      hfs_rwarg_t, loff_t *);
  42. /*================ Global variables ================*/
  43. struct file_operations hfs_hdr_operations = {
  44. llseek: hdr_llseek,
  45. read: hdr_read,
  46. write: hdr_write,
  47. fsync: file_fsync,
  48. };
  49. struct inode_operations hfs_hdr_inode_operations = {
  50. setattr: hfs_notify_change_hdr,
  51. };
  52. const struct hfs_hdr_layout hfs_dbl_fil_hdr_layout = {
  53. __constant_htonl(HFS_DBL_MAGIC), /* magic   */
  54. __constant_htonl(HFS_HDR_VERSION_2), /* version */
  55. 6, /* entries */
  56. { /* descr[] */
  57. {HFS_HDR_FNAME, offsetof(struct hfs_dbl_hdr, real_name),   ~0},
  58. {HFS_HDR_DATES, offsetof(struct hfs_dbl_hdr, create_time), 16},
  59. {HFS_HDR_FINFO, offsetof(struct hfs_dbl_hdr, finderinfo),  32},
  60. {HFS_HDR_MACI,  offsetof(struct hfs_dbl_hdr, fileinfo),     4},
  61. {HFS_HDR_DID,   offsetof(struct hfs_dbl_hdr, cnid),         4},
  62. {HFS_HDR_RSRC,  HFS_DBL_HDR_LEN,                           ~0}
  63. },
  64. { /* order[] */
  65. (struct hfs_hdr_descr *)&hfs_dbl_fil_hdr_layout.descr[0],
  66. (struct hfs_hdr_descr *)&hfs_dbl_fil_hdr_layout.descr[1],
  67. (struct hfs_hdr_descr *)&hfs_dbl_fil_hdr_layout.descr[2],
  68. (struct hfs_hdr_descr *)&hfs_dbl_fil_hdr_layout.descr[3],
  69. (struct hfs_hdr_descr *)&hfs_dbl_fil_hdr_layout.descr[4],
  70. (struct hfs_hdr_descr *)&hfs_dbl_fil_hdr_layout.descr[5]
  71. }
  72. };
  73. const struct hfs_hdr_layout hfs_dbl_dir_hdr_layout = {
  74. __constant_htonl(HFS_DBL_MAGIC), /* magic   */
  75. __constant_htonl(HFS_HDR_VERSION_2), /* version */
  76. 5, /* entries */
  77. { /* descr[] */
  78. {HFS_HDR_FNAME, offsetof(struct hfs_dbl_hdr, real_name),   ~0},
  79. {HFS_HDR_DATES, offsetof(struct hfs_dbl_hdr, create_time), 16},
  80. {HFS_HDR_FINFO, offsetof(struct hfs_dbl_hdr, finderinfo),  32},
  81. {HFS_HDR_MACI,  offsetof(struct hfs_dbl_hdr, fileinfo),     4},
  82. {HFS_HDR_DID,   offsetof(struct hfs_dbl_hdr, cnid),         4}
  83. },
  84. { /* order[] */
  85. (struct hfs_hdr_descr *)&hfs_dbl_dir_hdr_layout.descr[0],
  86. (struct hfs_hdr_descr *)&hfs_dbl_dir_hdr_layout.descr[1],
  87. (struct hfs_hdr_descr *)&hfs_dbl_dir_hdr_layout.descr[2],
  88. (struct hfs_hdr_descr *)&hfs_dbl_dir_hdr_layout.descr[3],
  89. (struct hfs_hdr_descr *)&hfs_dbl_dir_hdr_layout.descr[4]
  90. }
  91. };
  92. const struct hfs_hdr_layout hfs_nat2_hdr_layout = {
  93. __constant_htonl(HFS_DBL_MAGIC), /* magic   */
  94. __constant_htonl(HFS_HDR_VERSION_2), /* version */
  95. 9, /* entries */
  96. { /* descr[] */
  97. {HFS_HDR_FNAME, offsetof(struct hfs_dbl_hdr, real_name),   ~0},
  98. {HFS_HDR_COMNT, offsetof(struct hfs_dbl_hdr, comment),      0},
  99. {HFS_HDR_DATES, offsetof(struct hfs_dbl_hdr, create_time), 16},
  100. {HFS_HDR_FINFO, offsetof(struct hfs_dbl_hdr, finderinfo),  32},
  101. {HFS_HDR_AFPI,  offsetof(struct hfs_dbl_hdr, fileinfo),     4},
  102. {HFS_HDR_DID,   offsetof(struct hfs_dbl_hdr, cnid),         4},
  103. {HFS_HDR_SNAME,  offsetof(struct hfs_dbl_hdr, short_name), ~0},
  104. {HFS_HDR_PRODOSI,  offsetof(struct hfs_dbl_hdr, prodosi),   8},
  105. {HFS_HDR_RSRC,  HFS_NAT_HDR_LEN,                           ~0}
  106. },
  107. { /* order[] */
  108. (struct hfs_hdr_descr *)&hfs_nat_hdr_layout.descr[0],
  109. (struct hfs_hdr_descr *)&hfs_nat_hdr_layout.descr[1],
  110. (struct hfs_hdr_descr *)&hfs_nat_hdr_layout.descr[2],
  111. (struct hfs_hdr_descr *)&hfs_nat_hdr_layout.descr[3],
  112. (struct hfs_hdr_descr *)&hfs_nat_hdr_layout.descr[4],
  113. (struct hfs_hdr_descr *)&hfs_nat_hdr_layout.descr[5],
  114. (struct hfs_hdr_descr *)&hfs_nat_hdr_layout.descr[6],
  115. (struct hfs_hdr_descr *)&hfs_nat_hdr_layout.descr[7],
  116. (struct hfs_hdr_descr *)&hfs_nat_hdr_layout.descr[8]
  117. }
  118. };
  119. const struct hfs_hdr_layout hfs_nat_hdr_layout = {
  120. __constant_htonl(HFS_DBL_MAGIC), /* magic   */
  121. __constant_htonl(HFS_HDR_VERSION_1), /* version */
  122. 5, /* entries */
  123. { /* descr[] */
  124. {HFS_HDR_FNAME, offsetof(struct hfs_dbl_hdr, real_name),   ~0},
  125. {HFS_HDR_COMNT, offsetof(struct hfs_dbl_hdr, comment),      0},
  126. {HFS_HDR_OLDI,  offsetof(struct hfs_dbl_hdr, create_time), 16},
  127. {HFS_HDR_FINFO, offsetof(struct hfs_dbl_hdr, finderinfo),  32},
  128. {HFS_HDR_RSRC,  HFS_NAT_HDR_LEN,                           ~0},
  129. },
  130. { /* order[] */
  131. (struct hfs_hdr_descr *)&hfs_nat_hdr_layout.descr[0],
  132. (struct hfs_hdr_descr *)&hfs_nat_hdr_layout.descr[1],
  133. (struct hfs_hdr_descr *)&hfs_nat_hdr_layout.descr[2],
  134. (struct hfs_hdr_descr *)&hfs_nat_hdr_layout.descr[3],
  135. (struct hfs_hdr_descr *)&hfs_nat_hdr_layout.descr[4]
  136. }
  137. };
  138. /*================ File-local variables ================*/
  139. static const char fstype[16] =
  140. {'M','a','c','i','n','t','o','s','h',' ',' ',' ',' ',' ',' ',' '};
  141. /*================ File-local data types ================*/
  142. struct hdr_hdr {
  143.         hfs_lword_t magic;
  144.         hfs_lword_t version;
  145.         hfs_byte_t filler[16];
  146.         hfs_word_t entries;
  147.         hfs_byte_t descrs[12*HFS_HDR_MAX];
  148. }  __attribute__((packed));
  149. /*================ File-local functions ================*/
  150. /*
  151.  * dlength()
  152.  */
  153. static int dlength(const struct hfs_hdr_descr *descr,
  154.    const struct hfs_cat_entry *entry)
  155. {
  156. hfs_u32 length = descr->length;
  157. /* handle auto-sized entries */
  158. if (length == ~0) {
  159. switch (descr->id) {
  160. case HFS_HDR_DATA:
  161. if (entry->type == HFS_CDR_FIL) {
  162. length = entry->u.file.data_fork.lsize;
  163. } else {
  164. length = 0;
  165. }
  166. break;
  167. case HFS_HDR_RSRC:
  168. if (entry->type == HFS_CDR_FIL) {
  169. length = entry->u.file.rsrc_fork.lsize;
  170. } else {
  171. length = 0;
  172. }
  173. break;
  174. case HFS_HDR_FNAME:
  175. length = entry->key.CName.Len;
  176. break;
  177. case HFS_HDR_SNAME:
  178. default:
  179. length = 0;
  180. }
  181. }
  182. return length;
  183. }
  184. /*
  185.  * hdr_build_meta()
  186.  */
  187. static void hdr_build_meta(struct hdr_hdr *meta,
  188.    const struct hfs_hdr_layout *layout,
  189.    const struct hfs_cat_entry *entry)
  190. {
  191. const struct hfs_hdr_descr *descr;
  192. hfs_byte_t *ptr;
  193. int lcv;
  194. hfs_put_nl(layout->magic,   meta->magic);
  195. hfs_put_nl(layout->version, meta->version);
  196. if (layout->version == htonl(HFS_HDR_VERSION_1)) {
  197. memcpy(meta->filler, fstype, 16);
  198. } else {
  199. memset(meta->filler, 0, 16);
  200. }
  201. hfs_put_hs(layout->entries, meta->entries);
  202. memset(meta->descrs, 0, sizeof(meta->descrs));
  203. for (lcv = 0, descr = layout->descr, ptr = meta->descrs;
  204.      lcv < layout->entries; ++lcv, ++descr, ptr += 12) {
  205. hfs_put_hl(descr->id,             ptr);
  206. hfs_put_hl(descr->offset,         ptr + 4);
  207. hfs_put_hl(dlength(descr, entry), ptr + 8);
  208. }
  209. }
  210. /*
  211.  * dup_layout ()
  212.  */
  213. static struct hfs_hdr_layout *dup_layout(const struct hfs_hdr_layout *old)
  214. {
  215. struct hfs_hdr_layout *new;
  216. int lcv;
  217. if (HFS_NEW(new)) {
  218. memcpy(new, old, sizeof(*new));
  219. for (lcv = 0; lcv < new->entries; ++lcv) {
  220. (char *)(new->order[lcv]) += (char *)new - (char *)old;
  221. }
  222. }
  223. return new;
  224. }
  225. /*
  226.  * init_layout()
  227.  */
  228. static inline void init_layout(struct hfs_hdr_layout *layout,
  229.        const hfs_byte_t *descrs)
  230. {
  231. struct hfs_hdr_descr **base, **p, **q, *tmp;
  232. int lcv, entries = layout->entries;
  233. for (lcv = 0; lcv < entries; ++lcv, descrs += 12) {
  234. layout->order[lcv] = &layout->descr[lcv];
  235. layout->descr[lcv].id     = hfs_get_hl(descrs);
  236. layout->descr[lcv].offset = hfs_get_hl(descrs + 4);
  237. layout->descr[lcv].length = hfs_get_hl(descrs + 8);
  238. }
  239. for (lcv = layout->entries; lcv < HFS_HDR_MAX; ++lcv) {
  240. layout->order[lcv] = NULL;
  241. layout->descr[lcv].id     = 0;
  242. layout->descr[lcv].offset = 0;
  243. layout->descr[lcv].length = 0;
  244. }
  245. /* Sort the 'order' array using an insertion sort */
  246. base = &layout->order[0];
  247. for (p = (base+1); p < (base+entries); ++p) {
  248. q=p;
  249. while ((*q)->offset < (*(q-1))->offset) {
  250. tmp = *q;
  251. *q = *(q-1);
  252. *(--q) = tmp;
  253. if (q == base) break;
  254. }
  255. }
  256. }
  257. /*
  258.  * adjust_forks()
  259.  */
  260. static inline void adjust_forks(struct hfs_cat_entry *entry,
  261. const struct hfs_hdr_layout *layout)
  262. {
  263. int lcv;
  264. for (lcv = 0; lcv < layout->entries; ++lcv) {
  265. const struct hfs_hdr_descr *descr = &layout->descr[lcv];
  266. if ((descr->id == HFS_HDR_DATA) &&
  267.     (descr->length != entry->u.file.data_fork.lsize)) {
  268. entry->u.file.data_fork.lsize = descr->length;
  269. hfs_extent_adj(&entry->u.file.data_fork);
  270. } else if ((descr->id == HFS_HDR_RSRC) &&
  271.    (descr->length != entry->u.file.rsrc_fork.lsize)) {
  272. entry->u.file.rsrc_fork.lsize = descr->length;
  273. hfs_extent_adj(&entry->u.file.rsrc_fork);
  274. }
  275. }
  276. }
  277. /*
  278.  * get_dates()
  279.  */
  280. static void get_dates(const struct hfs_cat_entry *entry,
  281.       const struct inode *inode,  hfs_u32 dates[3])
  282. {
  283. dates[0] = hfs_m_to_htime(entry->create_date);
  284. dates[1] = hfs_m_to_htime(entry->modify_date);
  285. dates[2] = hfs_m_to_htime(entry->backup_date);
  286. }
  287. /*
  288.  * set_dates()
  289.  */
  290. static void set_dates(struct hfs_cat_entry *entry, struct inode *inode,
  291.       const hfs_u32 *dates)
  292. {
  293. hfs_u32 tmp;
  294. tmp = hfs_h_to_mtime(dates[0]);
  295. if (entry->create_date != tmp) {
  296. entry->create_date = tmp;
  297. hfs_cat_mark_dirty(entry);
  298. }
  299. tmp = hfs_h_to_mtime(dates[1]);
  300. if (entry->modify_date != tmp) {
  301. entry->modify_date = tmp;
  302. inode->i_ctime = inode->i_atime = inode->i_mtime = 
  303. hfs_h_to_utime(dates[1]);
  304. hfs_cat_mark_dirty(entry);
  305. }
  306. tmp = hfs_h_to_mtime(dates[2]);
  307. if (entry->backup_date != tmp) {
  308. entry->backup_date = tmp;
  309. hfs_cat_mark_dirty(entry);
  310. }
  311. }
  312. loff_t hdr_llseek(struct file *file, loff_t offset, int origin)
  313. {
  314. long long retval;
  315. switch (origin) {
  316. case 2:
  317. offset += file->f_dentry->d_inode->i_size;
  318. break;
  319. case 1:
  320. offset += file->f_pos;
  321. }
  322. retval = -EINVAL;
  323. if (offset>=0 && offset<file->f_dentry->d_inode->i_size) {
  324. if (offset != file->f_pos) {
  325. file->f_pos = offset;
  326. file->f_reada = 0;
  327. file->f_version = ++event;
  328. }
  329. retval = offset;
  330. }
  331. return retval;
  332. }
  333. /*
  334.  * hdr_read()
  335.  *
  336.  * This is the read field in the inode_operations structure for
  337.  * header files.  The purpose is to transfer up to 'count' bytes
  338.  * from the file corresponding to 'inode', beginning at
  339.  * 'filp->offset' bytes into the file. The data is transferred to
  340.  * user-space at the address 'buf'.  Returns the number of bytes
  341.  * successfully transferred.
  342.  */
  343. /* XXX: what about the entry count changing on us? */
  344. static hfs_rwret_t hdr_read(struct file * filp, char * buf, 
  345.     hfs_rwarg_t count, loff_t *ppos)
  346. {
  347. struct inode *inode = filp->f_dentry->d_inode;
  348. struct hfs_cat_entry *entry = HFS_I(inode)->entry;
  349. const struct hfs_hdr_layout *layout;
  350. off_t start, length, offset;
  351. off_t pos = *ppos;
  352. int left, lcv, read = 0;
  353. if (!S_ISREG(inode->i_mode)) {
  354. hfs_warn("hfs_hdr_read: mode = %07on",inode->i_mode);
  355. return -EINVAL;
  356. }
  357. if (HFS_I(inode)->layout) {
  358. layout = HFS_I(inode)->layout;
  359. } else {
  360. layout = HFS_I(inode)->default_layout;
  361. }
  362. /* Adjust count to fit within the bounds of the file */
  363. if ((pos >= inode->i_size) || (count <= 0)) {
  364. return 0;
  365. } else if (count > inode->i_size - pos) {
  366. count = inode->i_size - pos;
  367. }
  368. /* Handle the fixed-location portion */
  369. length = sizeof(hfs_u32) + sizeof(hfs_u32) + 16 +
  370.  sizeof(hfs_u16) + layout->entries * (3 * sizeof(hfs_u32));
  371. if (pos < length) {
  372. struct hdr_hdr meta;
  373. left = length - pos;
  374. if (left > count) {
  375. left = count;
  376. }
  377. hdr_build_meta(&meta, layout, entry);
  378. left -= copy_to_user(buf, ((char *)&meta) + pos, left);
  379. count -= left;
  380. read += left;
  381. pos += left;
  382. buf += left;
  383. }
  384. if (!count) {
  385. goto done;
  386. }
  387. /* Handle the actual data */
  388. for (lcv = 0; count && (lcv < layout->entries); ++lcv) {
  389. const struct hfs_hdr_descr *descr = layout->order[lcv];
  390. struct hfs_fork *fork;
  391. char tmp[16], *p;
  392. off_t limit;
  393. /* stop reading if we run out of descriptors early */
  394. if (!descr) {
  395. break;
  396. }
  397. /* find start and length of this entry */
  398. start = descr->offset;
  399. length = dlength(descr, entry);
  400. /* Skip to next entry if this one is empty or isn't needed */
  401. if (!length || (pos >= start + length)) {
  402. continue;
  403. }
  404. /* Pad with zeros to the start of this entry if needed */
  405. if (pos < start) {
  406. left = start - pos;
  407. if (left > count) {
  408. left = count;
  409. }
  410. clear_user(buf, left);
  411. count -= left;
  412. read += left;
  413. pos += left;
  414. buf += left;
  415. }
  416. if (!count) {
  417. goto done;
  418. }
  419. /* locate and/or construct the data for this entry */
  420. fork = NULL;
  421. p = NULL;
  422. switch (descr->id) {
  423. case HFS_HDR_DATA:
  424. fork = &entry->u.file.data_fork;
  425. limit = fork->lsize;
  426. break;
  427. case HFS_HDR_RSRC:
  428. fork = &entry->u.file.rsrc_fork;
  429. limit = fork->lsize;
  430. break;
  431. case HFS_HDR_FNAME:
  432. p = entry->key.CName.Name;
  433. limit = entry->key.CName.Len;
  434. break;
  435. case HFS_HDR_OLDI:
  436. case HFS_HDR_DATES:
  437. get_dates(entry, inode, (hfs_u32 *)tmp);
  438. if (descr->id == HFS_HDR_DATES) {
  439. /* XXX: access date. hfsplus actually
  440.                                    has this. */
  441. memcpy(tmp + 12, tmp + 4, 4);
  442. } else if ((entry->type == HFS_CDR_FIL) &&
  443.    (entry->u.file.flags & HFS_FIL_LOCK)) {
  444. hfs_put_hl(HFS_AFP_RDONLY, tmp + 12);
  445. } else {
  446. hfs_put_nl(0, tmp + 12);
  447. }
  448. p = tmp;
  449. limit = 16;
  450. break;
  451. case HFS_HDR_FINFO:
  452. p = (char *)&entry->info;
  453. limit = 32;
  454. break;
  455. case HFS_HDR_AFPI:
  456. /* XXX: this needs to do more mac->afp mappings */
  457. hfs_put_ns(0, tmp);
  458. if ((entry->type == HFS_CDR_FIL) &&
  459.     (entry->u.file.flags & HFS_FIL_LOCK)) {
  460. hfs_put_hs(HFS_AFP_RDONLY, tmp + 2);
  461. } else {
  462. hfs_put_ns(0, tmp + 2);
  463. }
  464. p = tmp;
  465. limit = 4;
  466.         break;
  467. case HFS_HDR_PRODOSI:
  468. /* XXX: this needs to do mac->prodos translations */
  469. memset(tmp, 0, 8);
  470. #if 0
  471. hfs_put_ns(0, tmp); /* access */
  472. hfs_put_ns(0, tmp); /* type */
  473. hfs_put_nl(0, tmp); /* aux type */
  474. #endif
  475. p = tmp;
  476. limit = 8;
  477.         break;
  478. case HFS_HDR_MACI:
  479. hfs_put_ns(0, tmp);
  480. if (entry->type == HFS_CDR_FIL) {
  481. hfs_put_hs(entry->u.file.flags, tmp + 2);
  482. } else {
  483. hfs_put_ns(entry->u.dir.flags, tmp + 2);
  484. }
  485. p = tmp;
  486. limit = 4;
  487. break;
  488. case HFS_HDR_DID:
  489.         /* if it's rootinfo, stick the next available did in
  490.  * the did slot. */
  491. limit = 4;
  492. if (entry->cnid == htonl(HFS_ROOT_CNID)) {
  493. struct hfs_mdb *mdb = entry->mdb;
  494. const struct hfs_name *reserved = 
  495. HFS_SB(mdb->sys_mdb)->s_reserved2;
  496. while (reserved->Len) {
  497. if (hfs_streq(reserved->Name,
  498.       reserved->Len,
  499.       entry->key.CName.Name,
  500.       entry->key.CName.Len)) {
  501. hfs_put_hl(mdb->next_id, tmp);
  502. p = tmp;
  503. goto hfs_did_done;
  504. }
  505. reserved++;
  506. }
  507. }
  508. p = (char *) &entry->cnid;
  509. hfs_did_done:
  510. break;
  511. case HFS_HDR_SNAME:
  512. default:
  513. limit = 0;
  514. }
  515. /* limit the transfer to the available data
  516.    of to the stated length of the entry. */
  517. if (length > limit) {
  518. length = limit;
  519. }
  520. offset = pos - start;
  521. left = length - offset;
  522. if (left > count) {
  523. left = count;
  524. }
  525. if (left <= 0) {
  526. continue;
  527. }
  528. /* transfer the data */
  529. if (p) {
  530. left -= copy_to_user(buf, p + offset, left);
  531. } else if (fork) {
  532. left = hfs_do_read(inode, fork, offset, buf, left,
  533.    filp->f_reada != 0);
  534. if (left > 0) {
  535. filp->f_reada = 1;
  536. } else if (!read) {
  537. return left;
  538. } else {
  539. goto done;
  540. }
  541. }
  542. count -= left;
  543. read += left;
  544. pos += left;
  545. buf += left;
  546. }
  547. /* Pad the file out with zeros */
  548. if (count) {
  549. clear_user(buf, count);
  550. read += count;
  551. pos += count;
  552. }
  553. done:
  554. if (read) {
  555. inode->i_atime = CURRENT_TIME;
  556. *ppos = pos;
  557. mark_inode_dirty(inode);
  558. }
  559. return read;
  560. }
  561. /*
  562.  * hdr_write()
  563.  *
  564.  * This is the write() entry in the file_operations structure for
  565.  * header files.  The purpose is to transfer up to 'count' bytes
  566.  * to the file corresponding to 'inode' beginning at offset
  567.  * '*ppos' from user-space at the address 'buf'.
  568.  * The return value is the number of bytes actually transferred.
  569.  */
  570. static hfs_rwret_t hdr_write(struct file *filp, const char *buf,
  571.      hfs_rwarg_t count, loff_t *ppos)
  572. {
  573. struct inode *inode = filp->f_dentry->d_inode;
  574.         struct hfs_cat_entry *entry = HFS_I(inode)->entry;
  575.         struct hfs_hdr_layout *layout;
  576.         off_t start, length, offset;
  577.         int left, lcv, written = 0;
  578. struct hdr_hdr meta;
  579. int built_meta = 0;
  580.         off_t pos;
  581. if (!S_ISREG(inode->i_mode)) {
  582. hfs_warn("hfs_hdr_write: mode = %07on", inode->i_mode);
  583. return -EINVAL;
  584. }
  585. if (count <= 0) {
  586. return 0;
  587. }
  588. pos = (filp->f_flags & O_APPEND) ? inode->i_size : *ppos;
  589. if (!HFS_I(inode)->layout) {
  590. HFS_I(inode)->layout = dup_layout(HFS_I(inode)->default_layout);
  591. }
  592. layout = HFS_I(inode)->layout;
  593. /* Handle the 'magic', 'version', 'filler' and 'entries' fields */
  594. length = sizeof(hfs_u32) + sizeof(hfs_u32) + 16 + sizeof(hfs_u16);
  595. if (pos < length) {
  596. hdr_build_meta(&meta, layout, entry);
  597. built_meta = 1;
  598. left = length - pos;
  599. if (left > count) {
  600. left = count;
  601. }
  602. left -= copy_from_user(((char *)&meta) + pos, buf, left);
  603. layout->magic   = hfs_get_nl(meta.magic);
  604. layout->version = hfs_get_nl(meta.version);
  605. layout->entries = hfs_get_hs(meta.entries);
  606. if (layout->entries > HFS_HDR_MAX) {
  607. /* XXX: should allocate slots dynamically */
  608. hfs_warn("hfs_hdr_write: TRUNCATING TO %d "
  609.  "DESCRIPTORSn", HFS_HDR_MAX);
  610. layout->entries = HFS_HDR_MAX;
  611. }
  612. count -= left;
  613. written += left;
  614. pos += left;
  615. buf += left;
  616. }
  617. if (!count) {
  618. goto done;
  619. }
  620. /* We know for certain how many entries we have, so process them */
  621. length += layout->entries * 3 * sizeof(hfs_u32);
  622. if (pos < length) {
  623. if (!built_meta) {
  624. hdr_build_meta(&meta, layout, entry);
  625. }
  626. left = length - pos;
  627. if (left > count) {
  628. left = count;
  629. }
  630. left -= copy_from_user(((char *)&meta) + pos, buf, left);
  631. init_layout(layout, meta.descrs);
  632. count -= left;
  633. written += left;
  634. pos += left;
  635. buf += left;
  636. /* Handle possible size changes for the forks */
  637. if (entry->type == HFS_CDR_FIL) {
  638. adjust_forks(entry, layout);
  639. hfs_cat_mark_dirty(entry);
  640. }
  641. }
  642. /* Handle the actual data */
  643. for (lcv = 0; count && (lcv < layout->entries); ++lcv) {
  644. struct hfs_hdr_descr *descr = layout->order[lcv];
  645. struct hfs_fork *fork;
  646. char tmp[16], *p;
  647. off_t limit;
  648. /* stop writing if we run out of descriptors early */
  649. if (!descr) {
  650. break;
  651. }
  652. /* find start and length of this entry */
  653. start = descr->offset;
  654. if ((descr->id == HFS_HDR_DATA) ||
  655.     (descr->id == HFS_HDR_RSRC)) {
  656. if (entry->type == HFS_CDR_FIL) {
  657. length = 0x7fffffff - start;
  658. } else {
  659. continue;
  660. }
  661. } else {
  662. length = dlength(descr, entry);
  663. }
  664. /* Trim length to avoid overlap with the next entry */
  665. if (layout->order[lcv+1] &&
  666.     ((start + length) > layout->order[lcv+1]->offset)) {
  667. length = layout->order[lcv+1]->offset - start;
  668. }
  669. /* Skip to next entry if this one is empty or isn't needed */
  670. if (!length || (pos >= start + length)) {
  671. continue;
  672. }
  673. /* Skip any padding that may exist between entries */
  674. if (pos < start) {
  675. left = start - pos;
  676. if (left > count) {
  677. left = count;
  678. }
  679. count -= left;
  680. written += left;
  681. pos += left;
  682. buf += left;
  683. }
  684. if (!count) {
  685. goto done;
  686. }
  687. /* locate and/or construct the data for this entry */
  688. fork = NULL;
  689. p = NULL;
  690. switch (descr->id) {
  691. case HFS_HDR_DATA:
  692. #if 0
  693. /* Can't yet write to the data fork via a header file, since there is the
  694.  * possibility to write via the data file, and the only locking is at the
  695.  * inode level.
  696.  */
  697. fork = &entry->u.file.data_fork;
  698. limit = length;
  699. #else
  700. limit = 0;
  701. #endif
  702. break;
  703. case HFS_HDR_RSRC:
  704. fork = &entry->u.file.rsrc_fork;
  705. limit = length;
  706. break;
  707. case HFS_HDR_OLDI:
  708. case HFS_HDR_DATES:
  709. get_dates(entry, inode, (hfs_u32 *)tmp);
  710. if (descr->id == HFS_HDR_DATES) {
  711. memcpy(tmp + 12, tmp + 4, 4);
  712. } else if ((entry->type == HFS_CDR_FIL) &&
  713.    (entry->u.file.flags & HFS_FIL_LOCK)) {
  714. hfs_put_hl(HFS_AFP_RDONLY, tmp + 12);
  715. } else {
  716. hfs_put_nl(0, tmp + 12);
  717. }
  718. p = tmp;
  719. limit = 16;
  720. break;
  721. case HFS_HDR_FINFO:
  722. p = (char *)&entry->info;
  723. limit = 32;
  724. break;
  725. case HFS_HDR_AFPI:
  726. hfs_put_ns(0, tmp);
  727. if ((entry->type == HFS_CDR_FIL) &&
  728.     (entry->u.file.flags & HFS_FIL_LOCK)) {
  729. hfs_put_hs(HFS_AFP_RDONLY, tmp + 2);
  730. } else {
  731. hfs_put_ns(0, tmp + 2);
  732. }
  733. p = tmp;
  734. limit = 4;
  735. break;
  736. case HFS_HDR_PRODOSI:
  737. /* XXX: this needs to do mac->prodos translations */
  738. memset(tmp, 0, 8); 
  739. #if 0
  740. hfs_put_ns(0, tmp); /* access */
  741. hfs_put_ns(0, tmp); /* type */
  742. hfs_put_nl(0, tmp); /* aux type */
  743. #endif
  744. p = tmp;
  745. limit = 8;
  746.         break;
  747. case HFS_HDR_MACI:
  748. hfs_put_ns(0, tmp);
  749. if (entry->type == HFS_CDR_FIL) {
  750. hfs_put_hs(entry->u.file.flags, tmp + 2);
  751. } else {
  752. hfs_put_ns(entry->u.dir.flags, tmp + 2);
  753. }
  754. p = tmp;
  755. limit = 4;
  756. break;
  757. case HFS_HDR_FNAME: /* Can't rename a file this way */
  758. case HFS_HDR_DID:       /* can't specify a did this way */
  759. default:
  760. limit = 0;
  761. }
  762. /* limit the transfer to the available data
  763.    of to the stated length of the entry. */
  764. if (length > limit) {
  765. length = limit;
  766. }
  767. offset = pos - start;
  768. left = length - offset;
  769. if (left > count) {
  770. left = count;
  771. }
  772. if (left <= 0) {
  773. continue;
  774. }
  775. /* transfer the data from user space */
  776. if (p) {
  777. left -= copy_from_user(p + offset, buf, left);
  778. } else if (fork) {
  779. left = hfs_do_write(inode, fork, offset, buf, left);
  780. }
  781. /* process the data */
  782. switch (descr->id) {
  783. case HFS_HDR_OLDI:
  784. set_dates(entry, inode, (hfs_u32 *)tmp);
  785. if (entry->type == HFS_CDR_FIL) {
  786. hfs_u8 new_flags = entry->u.file.flags;
  787. if (hfs_get_nl(tmp+12) & htonl(HFS_AFP_WRI)) {
  788. new_flags |= HFS_FIL_LOCK;
  789. } else {
  790. new_flags &= ~HFS_FIL_LOCK;
  791. }
  792. if (new_flags != entry->u.file.flags) {
  793. entry->u.file.flags = new_flags;
  794. hfs_cat_mark_dirty(entry);
  795. hfs_file_fix_mode(entry);
  796. }
  797. }
  798. break;
  799. case HFS_HDR_DATES:
  800. set_dates(entry, inode, (hfs_u32 *)tmp);
  801. break;
  802. case HFS_HDR_FINFO:
  803. hfs_cat_mark_dirty(entry);
  804. break;
  805. case HFS_HDR_MACI:
  806. if (entry->type == HFS_CDR_DIR) {
  807. hfs_u16 new_flags = hfs_get_ns(tmp + 2);
  808. if (entry->u.dir.flags != new_flags) {
  809. entry->u.dir.flags = new_flags;
  810. hfs_cat_mark_dirty(entry);
  811. }
  812. } else {
  813. hfs_u8 new_flags = tmp[3];
  814. hfs_u8 changed = entry->u.file.flags^new_flags;
  815. if (changed) {
  816. entry->u.file.flags = new_flags;
  817. hfs_cat_mark_dirty(entry);
  818. if (changed & HFS_FIL_LOCK) {
  819. hfs_file_fix_mode(entry);
  820. }
  821. }
  822. }
  823. break;
  824. case HFS_HDR_DATA:
  825. case HFS_HDR_RSRC:
  826. if (left <= 0) {
  827. if (!written) {
  828. return left;
  829. } else {
  830. goto done;
  831. }
  832. } else if (fork->lsize > descr->length) {
  833. descr->length = fork->lsize;
  834. }
  835. break;
  836. case HFS_HDR_FNAME: /* Can't rename a file this way */
  837. case HFS_HDR_DID:       /* Can't specify a did this way */
  838. case HFS_HDR_PRODOSI:   /* not implemented yet */
  839. case HFS_HDR_AFPI:      /* ditto */
  840. default:
  841. break;
  842. }
  843. count -= left;
  844. written += left;
  845. pos += left;
  846. buf += left;
  847. }
  848. /* Skip any padding at the end */
  849. if (count) {
  850. written += count;
  851. pos += count;
  852. }
  853. done:
  854. *ppos = pos;
  855. if (written > 0) {
  856.         if (pos > inode->i_size)
  857.         inode->i_size = pos;
  858.         inode->i_mtime = inode->i_atime = CURRENT_TIME;
  859. mark_inode_dirty(inode);
  860. }
  861. return written;
  862. }
  863. /*
  864.  * hdr_truncate()
  865.  *
  866.  * This is the truncate field in the inode_operations structure for
  867.  * header files.  The purpose is to allocate or release blocks as needed
  868.  * to satisfy a change in file length.
  869.  */
  870. void hdr_truncate(struct inode *inode, size_t size)
  871. {
  872. struct hfs_cat_entry *entry = HFS_I(inode)->entry;
  873. struct hfs_hdr_layout *layout;
  874. int lcv, last;
  875. inode->i_size = size;
  876. if (!HFS_I(inode)->layout) {
  877. HFS_I(inode)->layout = dup_layout(HFS_I(inode)->default_layout);
  878. }
  879. layout = HFS_I(inode)->layout;
  880. last = layout->entries - 1;
  881. for (lcv = 0; lcv <= last; ++lcv) {
  882. struct hfs_hdr_descr *descr = layout->order[lcv];
  883. struct hfs_fork *fork;
  884. hfs_u32 offset;
  885. if (!descr) {
  886. break;
  887. }
  888. if (descr->id == HFS_HDR_RSRC) {
  889. fork = &entry->u.file.rsrc_fork;
  890. #if 0
  891. /* Can't yet truncate the data fork via a header file, since there is the
  892.  * possibility to truncate via the data file, and the only locking is at
  893.  * the inode level.
  894.  */
  895. } else if (descr->id == HFS_HDR_DATA) {
  896. fork = &entry->u.file.data_fork;
  897. #endif
  898. } else {
  899. continue;
  900. }
  901. offset = descr->offset;
  902. if ((lcv != last) && ((offset + descr->length) <= size)) {
  903. continue;
  904. }
  905. if (offset < size) {
  906. descr->length = size - offset;
  907. } else {
  908. descr->length = 0;
  909. }
  910. if (fork->lsize != descr->length) {
  911. fork->lsize = descr->length;
  912. hfs_extent_adj(fork);
  913. hfs_cat_mark_dirty(entry);
  914. }
  915. }
  916. }