Whamcloud - gitweb
- tagging RC_CURRENT
[fs/lustre-release.git] / lustre / kernel_patches / patches / linux-2.4.20-tmpfs-iopen.patch
1 diff -rupN --exclude='ide*' linux-2.4.20.orig/include/linux/mm.h linux-2.4.20/include/linux/mm.h
2 --- linux-2.4.20.orig/include/linux/mm.h        2004-02-10 11:43:10.000000000 +0200
3 +++ linux-2.4.20/include/linux/mm.h     2004-03-01 13:44:45.000000000 +0200
4 @@ -468,7 +468,8 @@ extern void clear_page_tables(struct mm_
5  extern int fail_writepage(struct page *);
6  struct page * shmem_nopage(struct vm_area_struct * vma, unsigned long address, int unused);
7  struct file *shmem_file_setup(char * name, loff_t size);
8 -int shmem_getpage(struct inode * inode, unsigned long idx, struct page **ptr);
9 +struct page *shmem_getpage_locked(struct inode *inode, unsigned long idx);
10 +struct page *shmem_getpage_unlocked(struct inode *inode, unsigned long idx);
11  extern void shmem_lock(struct file * file, int lock);
12  extern int shmem_zero_setup(struct vm_area_struct *);
13  
14 diff -rupN --exclude='ide*' linux-2.4.20.orig/include/linux/shmem_fs.h linux-2.4.20/include/linux/shmem_fs.h
15 --- linux-2.4.20.orig/include/linux/shmem_fs.h  2004-02-10 18:39:17.000000000 +0200
16 +++ linux-2.4.20/include/linux/shmem_fs.h       2004-02-23 12:40:28.000000000 +0200
17 @@ -7,6 +7,9 @@
18  
19  #define SHMEM_NR_DIRECT 16
20  
21 +#define SHMEM_MOUNT_IOPEN        0x8000        /* Allow access via iopen */
22 +#define SHMEM_MOUNT_IOPEN_NOPRIV  0x10000      /* Make iopen world-readable */
23 +
24  /*
25   * A swap entry has to fit into a "unsigned long", as
26   * the entry is hidden in the "index" field of the
27 @@ -38,6 +41,9 @@ struct shmem_inode_info {
28  };
29  
30  struct shmem_sb_info {
31 +       struct dentry *iopen;
32 +       unsigned long options;
33 +       unsigned long root_ino;
34         unsigned long max_blocks;   /* How many blocks are allowed */
35         unsigned long free_blocks;  /* How many are left for allocation */
36         unsigned long max_inodes;   /* How many inodes are allowed */
37 @@ -59,11 +65,9 @@ shmem_xattr_find(struct inode *inode, co
38  extern ssize_t
39  shmem_xattr_set(struct inode *inode, const char *name,
40                 const void *value, u16 valuelen, int flags);
41 -               
42  extern ssize_t
43  shmem_xattr_get(struct inode *inode, const char *name,
44                 void *value, size_t valuelen);
45 -               
46  extern int
47  shmem_xattr_delete(struct inode *inode, struct shmem_xattr *xattr);
48  
49 diff -rupN --exclude='ide*' linux-2.4.20.orig/mm/shmem.c linux-2.4.20/mm/shmem.c
50 --- linux-2.4.20.orig/mm/shmem.c        2004-02-10 18:44:05.000000000 +0200
51 +++ linux-2.4.20/mm/shmem.c     2004-03-01 14:37:21.000000000 +0200
52 @@ -36,29 +36,45 @@
53  #define TMPFS_MAGIC    0x01021994
54  
55  #define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long))
56 +
57  #define BLOCKS_PER_PAGE  (PAGE_CACHE_SIZE/512)
58  
59 -#define SHMEM_MAX_INDEX  (SHMEM_NR_DIRECT + ENTRIES_PER_PAGE * (ENTRIES_PER_PAGE/2) * (ENTRIES_PER_PAGE+1))
60 +#define SHMEM_MAX_INDEX  (SHMEM_NR_DIRECT + ENTRIES_PER_PAGE * \
61 +                         (ENTRIES_PER_PAGE/2) * (ENTRIES_PER_PAGE+1))
62 +
63  #define SHMEM_MAX_BYTES  ((unsigned long long)SHMEM_MAX_INDEX << PAGE_CACHE_SHIFT)
64  #define VM_ACCT(size)    (((size) + PAGE_CACHE_SIZE - 1) >> PAGE_SHIFT)
65  
66  /* Pretend that each entry is of this size in directory's i_size */
67 -#define BOGO_DIRENT_SIZE 20
68 -
69 +#define BOGO_DIRENT_SIZE (20)
70  #define SHMEM_SB(sb) (&sb->u.shmem_sb)
71  
72 +#define SHMEM_IOPEN_INO        2
73 +#define SHMEM_IOPEN_NAME_LEN   32
74 +
75 +#define ASSERT(cond)                                                    \
76 +do {                                                                   \
77 +       if (!(cond)) {                                                  \
78 +               printk (KERN_EMERG                                      \
79 +                       "Assertion failure in %s() at %s:%d: \"%s\"\n", \
80 +                       __FUNCTION__, __FILE__, __LINE__, # cond);      \
81 +               BUG();                                                  \
82 +       }                                                               \
83 +} while (0)
84 +
85  static struct super_operations shmem_ops;
86 +static struct vm_operations_struct shmem_vm_ops;
87  static struct address_space_operations shmem_aops;
88  static struct file_operations shmem_file_operations;
89  static struct inode_operations shmem_inode_operations;
90  static struct inode_operations shmem_dir_inode_operations;
91 -static struct vm_operations_struct shmem_vm_ops;
92  
93  LIST_HEAD (shmem_inodes);
94  static spinlock_t shmem_ilock = SPIN_LOCK_UNLOCKED;
95  atomic_t shmem_nrpages = ATOMIC_INIT(0); /* Not used right now */
96  
97 -static struct page *shmem_getpage_locked(struct shmem_inode_info *, struct inode *, unsigned long);
98 +struct page *shmem_getpage_locked(struct inode *inode, unsigned long idx);
99 +struct page *shmem_getpage_unlocked(struct inode *inode, unsigned long idx);
100  
101  #ifdef CONFIG_TMPFS
102  static struct inode_operations shmem_symlink_inode_operations;
103 @@ -327,7 +343,7 @@ shmem_getxattr(struct dentry *dentry, co
104   * inode attributes list.*/
105  static int
106  shmem_setxattr(struct dentry *dentry, const char *name,
107 -               void *value, size_t valuelen, int flags)
108 +               const void *value, size_t valuelen, int flags)
109  {
110          int error;
111          struct inode *inode = dentry->d_inode;
112 @@ -404,8 +420,8 @@ shmem_listxattr(struct dentry *dentry, c
113   * @inode: inode to recalc
114   * @swap:  additional swap pages freed externally
115   *
116 - * We have to calculate the free blocks since the mm can drop pages
117 - * behind our back
118 + * We have to calculate the free blocks since the mm can drop pages behind our
119 + * back
120   *
121   * But we know that normally
122   * inodes->i_blocks/BLOCKS_PER_PAGE == 
123 @@ -441,24 +457,23 @@ static void shmem_recalc_inode(struct in
124   * @page:  optional page to add to the structure. Has to be preset to
125   *         all zeros
126   *
127 - * If there is no space allocated yet it will return -ENOMEM when
128 - * page == 0 else it will use the page for the needed block.
129 + * If there is no space allocated yet it will return -ENOMEM when page == 0 else
130 + * it will use the page for the needed block.
131   *
132   * returns -EFBIG if the index is too big.
133   *
134   *
135   * The swap vector is organized the following way:
136   *
137 - * There are SHMEM_NR_DIRECT entries directly stored in the
138 - * shmem_inode_info structure. So small files do not need an addional
139 - * allocation.
140 - *
141 - * For pages with index > SHMEM_NR_DIRECT there is the pointer
142 - * i_indirect which points to a page which holds in the first half
143 - * doubly indirect blocks, in the second half triple indirect blocks:
144 + * There are SHMEM_NR_DIRECT entries directly stored in the shmem_inode_info
145 + * structure. So small files do not need an addional allocation.
146 + *
147 + * For pages with index > SHMEM_NR_DIRECT there is the pointer i_indirect which
148 + * points to a page which holds in the first half doubly indirect blocks, in the
149 + * second half triple indirect blocks:
150   *
151 - * For an artificial ENTRIES_PER_PAGE = 4 this would lead to the
152 - * following layout (for SHMEM_NR_DIRECT == 16):
153 + * For an artificial ENTRIES_PER_PAGE = 4 this would lead to the following
154 + * layout (for SHMEM_NR_DIRECT == 16):
155   *
156   * i_indirect -> dir --> 16-19
157   *           |      +-> 20-23
158 @@ -473,7 +488,9 @@ static void shmem_recalc_inode(struct in
159   *                    +-> 48-51
160   *                    +-> 52-55
161   */
162 -static swp_entry_t * shmem_swp_entry (struct shmem_inode_info *info, unsigned long index, unsigned long page) 
163 +static swp_entry_t *
164 +shmem_swp_entry (struct shmem_inode_info *info, unsigned long index,
165 +                unsigned long page) 
166  {
167         unsigned long offset;
168         void **dir;
169 @@ -520,7 +537,8 @@ static swp_entry_t * shmem_swp_entry (st
170   * @info:      info structure for the inode
171   * @index:     index of the page to find
172   */
173 -static inline swp_entry_t * shmem_alloc_entry (struct shmem_inode_info *info, unsigned long index)
174 +static inline swp_entry_t *
175 +shmem_alloc_entry(struct shmem_inode_info *info, unsigned long index)
176  {
177         unsigned long page = 0;
178         swp_entry_t * res;
179 @@ -545,7 +563,8 @@ static inline swp_entry_t * shmem_alloc_
180   * @dir:   pointer to the directory
181   * @count: number of entries to scan
182   */
183 -static int shmem_free_swp(swp_entry_t *dir, unsigned int count)
184 +static int
185 +shmem_free_swp(swp_entry_t *dir, unsigned int count)
186  {
187         swp_entry_t *ptr, entry;
188         int freed = 0;
189 @@ -573,7 +592,9 @@ static int shmem_free_swp(swp_entry_t *d
190   */
191  
192  static inline unsigned long 
193 -shmem_truncate_direct(swp_entry_t *** dir, unsigned long start, unsigned long len) {
194 +shmem_truncate_direct(swp_entry_t ***dir, unsigned long start,
195 +                     unsigned long len)
196 +{
197         swp_entry_t **last, **ptr;
198         unsigned long off, freed = 0;
199   
200 @@ -639,7 +660,8 @@ shmem_truncate_indirect(struct shmem_ino
201                         BUG();
202  
203                 baseidx = max & ~(ENTRIES_PER_PAGE*ENTRIES_PER_PAGE-1);
204 -               base = (swp_entry_t ***) info->i_indirect + ENTRIES_PER_PAGE/2 + baseidx/ENTRIES_PER_PAGE/ENTRIES_PER_PAGE ;
205 +               base = (swp_entry_t ***) info->i_indirect + ENTRIES_PER_PAGE/2 +
206 +                       baseidx/ENTRIES_PER_PAGE/ENTRIES_PER_PAGE ;
207                 len = max - baseidx + 1;
208                 baseidx += ENTRIES_PER_PAGE*ENTRIES_PER_PAGE/2+SHMEM_NR_DIRECT;
209         }
210 @@ -654,7 +676,8 @@ shmem_truncate_indirect(struct shmem_ino
211         return shmem_truncate_direct(base, start, len);
212  }
213  
214 -static void shmem_truncate (struct inode * inode)
215 +static void
216 +shmem_truncate(struct inode *inode)
217  {
218         unsigned long index;
219         unsigned long partial;
220 @@ -668,16 +691,16 @@ static void shmem_truncate (struct inode
221         partial = inode->i_size & ~PAGE_CACHE_MASK;
222  
223         if (partial) {
224 -               swp_entry_t *entry = shmem_swp_entry(info, index-1, 0);
225                 struct page *page;
226 -               /*
227 -                * This check is racy: it's faintly possible that page
228 -                * was assigned to swap during truncate_inode_pages,
229 -                * and now assigned to file; but better than nothing.
230 +               swp_entry_t *entry = shmem_swp_entry(info, index - 1, 0);
231 +               
232 +               /* This check is racy: it's faintly possible that page was
233 +                * assigned to swap during truncate_inode_pages, and now
234 +                * assigned to file; but better than nothing.
235                  */
236                 if (!IS_ERR(entry) && entry->val) {
237                         spin_unlock(&info->lock);
238 -                       page = shmem_getpage_locked(info, inode, index-1);
239 +                       page = shmem_getpage_locked(inode, index - 1);
240                         if (!IS_ERR(page)) {
241                                 memclear_highpage_flush(page, partial,
242                                         PAGE_CACHE_SIZE - partial);
243 @@ -697,8 +720,166 @@ static void shmem_truncate (struct inode
244         up(&info->sem);
245  }
246  
247 -static void shmem_delete_inode(struct inode * inode)
248 +static struct inode *
249 +shmem_find_inode(struct super_block *sb, long int ino)
250 +{
251 +       struct list_head *p;
252 +       struct inode *inode = NULL;
253 +       struct shmem_inode_info *info;
254 +
255 +       spin_lock (&shmem_ilock);
256 +       list_for_each(p, &shmem_inodes) {
257 +               info = list_entry(p, struct shmem_inode_info, list);
258 +               
259 +               if (info->inode->i_ino == ino && 
260 +                   info->inode->i_sb == sb) 
261 +               {
262 +                       inode = info->inode;
263 +                       break;
264 +               }
265 +       }
266 +       
267 +       spin_unlock (&shmem_ilock);
268 +       
269 +       if (inode)
270 +               igrab(inode);
271 +               
272 +       return inode;
273 +}
274 +
275 +#define switch_fields(x,y) do {   \
276 +       __typeof__ (x) __tmp = x; \
277 +       x = y; y = __tmp; } while (0)
278 +
279 +static inline void
280 +switch_names(struct dentry *dentry, struct dentry *target)
281 +{
282 +       const unsigned char *old_name, *new_name;
283 +
284 +       memcpy(dentry->d_iname, target->d_iname, 
285 +              DNAME_INLINE_LEN);
286 +       
287 +       old_name = target->d_name.name;
288 +       new_name = dentry->d_name.name;
289 +       
290 +       if (old_name == target->d_iname)
291 +               old_name = dentry->d_iname;
292 +       
293 +       if (new_name == dentry->d_iname)
294 +               new_name = target->d_iname;
295 +       
296 +       target->d_name.name = new_name;
297 +       dentry->d_name.name = old_name;
298 +}
299 +
300 +static struct dentry *
301 +shmem_iopen_lookup(struct inode *dir, 
302 +                  struct dentry *dentry)
303 +{
304 +       struct inode *inode;
305 +       unsigned long ino;
306 +       struct list_head *lp;
307 +       struct dentry *alternate;
308 +       char buf[SHMEM_IOPEN_NAME_LEN];
309 +       struct shmem_sb_info *sbinfo = SHMEM_SB(dir->i_sb);
310 +
311 +       if (dentry->d_name.len >= SHMEM_IOPEN_NAME_LEN)
312 +               return ERR_PTR(-ENAMETOOLONG);
313 +
314 +       memcpy(buf, dentry->d_name.name, dentry->d_name.len);
315 +       buf[dentry->d_name.len] = 0;
316 +
317 +       if (strcmp(buf, ".") == 0)
318 +               ino = dir->i_ino;
319 +       else if (strcmp(buf, "..") == 0)
320 +               ino = sbinfo->root_ino;
321 +       else
322 +               ino = simple_strtoul(buf, 0, 0);
323 +
324 +       if (ino < sbinfo->root_ino)
325 +               return ERR_PTR(-ENOENT);
326 +
327 +       if (!(inode = shmem_find_inode(dir->i_sb, ino)))
328 +               return ERR_PTR(-ENOENT);
329 +
330 +       ASSERT(list_empty(&dentry->d_alias));
331 +       ASSERT(list_empty(&dentry->d_hash));
332 +
333 +       /* preferrably return a connected dentry */
334 +       spin_lock(&dcache_lock);
335 +       list_for_each(lp, &inode->i_dentry) {
336 +               alternate = list_entry(lp, struct dentry, d_alias);
337 +               ASSERT(!(alternate->d_flags & DCACHE_NFSD_DISCONNECTED));
338 +       }
339 +
340 +       if (!list_empty(&inode->i_dentry)) {
341 +               alternate = list_entry(inode->i_dentry.next,
342 +                                      struct dentry, d_alias);
343 +               dget_locked(alternate);
344 +               alternate->d_vfs_flags |= DCACHE_REFERENCED;
345 +               iput(inode);
346 +               spin_unlock(&dcache_lock);
347 +               return alternate;
348 +       }
349 +       dentry->d_flags |= DCACHE_NFSD_DISCONNECTED;
350 +
351 +       /* d_add(), but don't drop dcache_lock before adding dentry to inode */
352 +       list_add(&dentry->d_alias, &inode->i_dentry);
353 +       dentry->d_inode = inode;
354 +
355 +       __d_rehash(dentry, 0);
356 +       spin_unlock(&dcache_lock);
357 +
358 +       return NULL;
359 +}
360 +
361 +struct dentry *
362 +shmem_iopen_unalias(struct dentry *dentry, struct inode *inode)
363 +{
364 +       struct dentry *tmp, *goal = NULL;
365 +       struct list_head *lp;
366 +
367 +       list_for_each(lp, &inode->i_dentry) {
368 +               tmp = list_entry(lp, struct dentry, d_alias);
369 +               if (tmp->d_flags & DCACHE_NFSD_DISCONNECTED) {
370 +                       ASSERT(tmp->d_alias.next == &inode->i_dentry);
371 +                       ASSERT(tmp->d_alias.prev == &inode->i_dentry);
372 +                       goal = tmp;
373 +                       dget_locked(goal);
374 +                       break;
375 +               }
376 +       }
377 +
378 +       if (!goal)
379 +               return NULL;
380 +
381 +       goal->d_flags &= ~DCACHE_NFSD_DISCONNECTED;
382 +       list_del_init(&goal->d_hash);
383 +
384 +       list_del(&goal->d_child);
385 +       list_del(&dentry->d_child);
386 +
387 +       switch_names(goal, dentry);
388 +       switch_fields(goal->d_parent, dentry->d_parent);
389 +       switch_fields(goal->d_name.len, dentry->d_name.len);
390 +       switch_fields(goal->d_name.hash, dentry->d_name.hash);
391 +
392 +       list_add(&goal->d_child, &goal->d_parent->d_subdirs);
393 +       list_add(&dentry->d_child, &dentry->d_parent->d_subdirs);
394 +       __d_rehash(goal, 0);
395 +
396 +       return goal;
397 +}
398 +
399 +static struct inode_operations iopen_inode_operations = {
400 +       lookup:         shmem_iopen_lookup,
401 +};
402 +
403 +static void
404 +shmem_delete_inode(struct inode *inode)
405  {
406 +       struct dentry *dentry;
407 +       
408  #ifdef CONFIG_TMPFS_XATTR
409         struct list_head *tmp, *p;
410         struct shmem_xattr *xattr;
411 @@ -706,16 +887,30 @@ static void shmem_delete_inode(struct in
412  #endif
413         struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
414  
415 -       if (inode->i_op->truncate == shmem_truncate) {
416 +       if (inode->i_ino != SHMEM_IOPEN_INO) {
417 +               /* eliminating iopen alias */
418 +               spin_lock(&dcache_lock);
419 +               if (!list_empty(&inode->i_dentry)) {
420 +                       dentry = list_entry(inode->i_dentry.next,
421 +                                           struct dentry, d_alias);
422 +                       shmem_iopen_unalias(dentry, inode);
423 +               }
424 +               spin_unlock(&dcache_lock);
425 +
426                 spin_lock (&shmem_ilock);
427                 list_del (&SHMEM_I(inode)->list);
428                 spin_unlock (&shmem_ilock);
429 -               inode->i_size = 0;
430 -               shmem_truncate (inode);
431 +       
432 +               if (inode->i_op->truncate == shmem_truncate) {
433 +                       inode->i_size = 0;
434 +                       shmem_truncate (inode);
435 +               }
436 +       
437 +               spin_lock (&sbinfo->stat_lock);
438 +               sbinfo->free_inodes++;
439 +               spin_unlock (&sbinfo->stat_lock);
440         }
441 -       spin_lock (&sbinfo->stat_lock);
442 -       sbinfo->free_inodes++;
443 -       spin_unlock (&sbinfo->stat_lock);
444 +       
445  #ifdef CONFIG_TMPFS_XATTR
446          list_for_each_safe(p, tmp, &info->xattrs) {
447                  xattr = list_entry(p, struct shmem_xattr, list);
448 @@ -725,7 +920,8 @@ static void shmem_delete_inode(struct in
449         clear_inode(inode);
450  }
451  
452 -static inline int shmem_find_swp(swp_entry_t entry, swp_entry_t *ptr, swp_entry_t *eptr)
453 +static inline int
454 +shmem_find_swp(swp_entry_t entry, swp_entry_t *ptr, swp_entry_t *eptr)
455  {
456         swp_entry_t *test;
457  
458 @@ -736,7 +932,9 @@ static inline int shmem_find_swp(swp_ent
459         return -1;
460  }
461  
462 -static int shmem_unuse_inode(struct shmem_inode_info *info, swp_entry_t entry, struct page *page)
463 +static int
464 +shmem_unuse_inode(struct shmem_inode_info *info, swp_entry_t entry,
465 +                 struct page *page)
466  {
467         swp_entry_t *ptr;
468         unsigned long idx;
469 @@ -875,9 +1073,11 @@ getswap:
470   * still need to guard against racing with shm_writepage(), which might
471   * be trying to move the page to the swap cache as we run.
472   */
473 -static struct page * shmem_getpage_locked(struct shmem_inode_info *info, struct inode * inode, unsigned long idx)
474 +struct page *
475 +shmem_getpage_locked(struct inode *inode, unsigned long idx)
476  {
477         struct address_space * mapping = inode->i_mapping;
478 +       struct shmem_inode_info *info = SHMEM_I(inode);
479         struct shmem_sb_info *sbinfo;
480         struct page * page;
481         swp_entry_t *entry;
482 @@ -941,7 +1141,8 @@ repeat:
483                 swap_free(*entry);
484                 *entry = (swp_entry_t) {0};
485                 delete_from_swap_cache(page);
486 -               flags = page->flags & ~((1 << PG_uptodate) | (1 << PG_error) | (1 << PG_referenced) | (1 << PG_arch_1));
487 +               flags = page->flags & ~((1 << PG_uptodate) | (1 << PG_error) |
488 +                                       (1 << PG_referenced) | (1 << PG_arch_1));
489                 page->flags = flags | (1 << PG_dirty);
490                 add_to_page_cache_locked(page, mapping, idx);
491                 info->swapped--;
492 @@ -985,46 +1186,53 @@ wait_retry:
493         goto repeat;
494  }
495  
496 -int shmem_getpage(struct inode * inode, unsigned long idx, struct page **ptr)
497 +struct page *
498 +shmem_getpage_unlocked(struct inode *inode, unsigned long idx)
499  {
500 +       struct page *page;
501         struct shmem_inode_info *info = SHMEM_I(inode);
502 -       int error;
503  
504 -       down (&info->sem);
505 -       *ptr = ERR_PTR(-EFAULT);
506 -       if (inode->i_size <= (loff_t) idx * PAGE_CACHE_SIZE)
507 +       down(&info->sem);
508 +       page = ERR_PTR(-EFAULT);
509 +       
510 +       if (inode->i_size <= (loff_t)idx * PAGE_CACHE_SIZE)
511                 goto failed;
512  
513 -       *ptr = shmem_getpage_locked(info, inode, idx);
514 -       if (IS_ERR (*ptr))
515 +       page = shmem_getpage_locked(inode, idx);
516 +       
517 +       if (IS_ERR(page))
518                 goto failed;
519  
520 -       UnlockPage(*ptr);
521 -       up (&info->sem);
522 -       return 0;
523 +       UnlockPage(page);
524 +       up(&info->sem);
525 +       return page;
526  failed:
527 -       up (&info->sem);
528 -       error = PTR_ERR(*ptr);
529 -       *ptr = NOPAGE_SIGBUS;
530 -       if (error == -ENOMEM)
531 -               *ptr = NOPAGE_OOM;
532 -       return error;
533 +       up(&info->sem);
534 +
535 +       if (PTR_ERR(page) == -ENOMEM)
536 +               return NOPAGE_OOM;
537 +       
538 +       return page;
539  }
540  
541 -struct page * shmem_nopage(struct vm_area_struct * vma, unsigned long address, int unused)
542 +struct page *
543 +shmem_nopage(struct vm_area_struct *vma, 
544 +            unsigned long address, int unused)
545  {
546 -       struct page * page;
547         unsigned int idx;
548 +       struct page * page;
549         struct inode * inode = vma->vm_file->f_dentry->d_inode;
550  
551 -       idx = (address - vma->vm_start) >> PAGE_CACHE_SHIFT;
552 -       idx += vma->vm_pgoff;
553 +       idx = ((address - vma->vm_start) >> PAGE_CACHE_SHIFT) +
554 +               vma->vm_pgoff;
555  
556 -       if (shmem_getpage(inode, idx, &page))
557 +       page = shmem_getpage_unlocked(inode, idx);
558 +       
559 +       if (IS_ERR(page))
560                 return page;
561  
562         flush_page_to_ram(page);
563 -       return(page);
564 +       return page;
565  }
566  
567  void shmem_lock(struct file * file, int lock)
568 @@ -1037,7 +1245,8 @@ void shmem_lock(struct file * file, int 
569         up(&info->sem);
570  }
571  
572 -static int shmem_mmap(struct file * file, struct vm_area_struct * vma)
573 +static int
574 +shmem_mmap(struct file * file, struct vm_area_struct * vma)
575  {
576         struct vm_operations_struct * ops;
577         struct inode *inode = file->f_dentry->d_inode;
578 @@ -1050,39 +1259,53 @@ static int shmem_mmap(struct file * file
579         return 0;
580  }
581  
582 -struct inode *shmem_get_inode(struct super_block *sb, int mode, int dev)
583 +static void
584 +shmem_fill_inode(struct inode *inode, int mode, int dev)
585  {
586 -       struct inode * inode;
587         struct shmem_inode_info *info;
588 -       struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
589 +       
590 +       info = SHMEM_I(inode);
591 +       info->inode = inode;
592 +       spin_lock_init (&info->lock);
593 +       sema_init (&info->sem, 1);
594  
595 -       spin_lock (&sbinfo->stat_lock);
596 -       if (!sbinfo->free_inodes) {
597 -               spin_unlock (&sbinfo->stat_lock);
598 -               return NULL;
599 -       }
600 -       sbinfo->free_inodes--;
601 -       spin_unlock (&sbinfo->stat_lock);
602 +#ifdef CONFIG_TMPFS_XATTR
603 +       INIT_LIST_HEAD(&info->xattrs);
604 +       info->xtail = &info->xattrs;
605 +#endif
606  
607 -       inode = new_inode(sb);
608 -       if (inode) {
609 +       inode->i_blocks = 0;
610 +       inode->i_rdev = NODEV;
611 +       inode->i_atime = CURRENT_TIME;
612 +       inode->i_ctime = CURRENT_TIME;
613 +       inode->i_mtime = CURRENT_TIME;
614 +       inode->i_blksize = PAGE_CACHE_SIZE;
615 +       
616 +       /* handling speciall iopen inode. */
617 +       if (inode->i_ino == SHMEM_IOPEN_INO) {
618 +               struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
619 +               
620 +               inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR;
621 +       
622 +               if (sbinfo->options & SHMEM_MOUNT_IOPEN_NOPRIV)
623 +                       inode->i_mode |= 0777;
624 +               
625 +               inode->i_uid = 0;
626 +               inode->i_gid = 0;
627 +               inode->i_nlink = 1;
628 +               inode->i_size = 2 * BOGO_DIRENT_SIZE;
629 +               inode->i_version = 1;
630 +               inode->i_generation = 0;
631 +
632 +               inode->i_op = &iopen_inode_operations;
633 +               inode->i_fop = &dcache_dir_ops;
634 +               inode->i_mapping->a_ops = 0;
635 +       } else {
636                 inode->i_mode = mode;
637                 inode->i_uid = current->fsuid;
638                 inode->i_gid = current->fsgid;
639 -               inode->i_blksize = PAGE_CACHE_SIZE;
640 -               inode->i_blocks = 0;
641 -               inode->i_rdev = NODEV;
642                 inode->i_mapping->a_ops = &shmem_aops;
643 -               inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
644 -               info = SHMEM_I(inode);
645 -               info->inode = inode;
646 -               spin_lock_init (&info->lock);
647 -               sema_init (&info->sem, 1);
648  
649 -#ifdef CONFIG_TMPFS_XATTR
650 -               INIT_LIST_HEAD(&info->xattrs);
651 -               info->xtail = &info->xattrs;
652 -#endif
653                 switch (mode & S_IFMT) {
654                 default:
655                         init_special_inode(inode, mode, dev);
656 @@ -1090,9 +1313,6 @@ struct inode *shmem_get_inode(struct sup
657                 case S_IFREG:
658                         inode->i_op = &shmem_inode_operations;
659                         inode->i_fop = &shmem_file_operations;
660 -                       spin_lock (&shmem_ilock);
661 -                       list_add_tail(&info->list, &shmem_inodes);
662 -                       spin_unlock (&shmem_ilock);
663                         break;
664                 case S_IFDIR:
665                         inode->i_nlink++;
666 @@ -1104,12 +1324,59 @@ struct inode *shmem_get_inode(struct sup
667                 case S_IFLNK:
668                         break;
669                 }
670 +               
671 +               spin_lock (&shmem_ilock);
672 +               list_add_tail(&info->list, &shmem_inodes);
673 +               spin_unlock (&shmem_ilock);
674 +       }
675 +}
676 +
677 +struct inode *
678 +shmem_get_inode(struct super_block *sb, 
679 +               int mode, int dev, int root)
680 +{
681 +       struct inode *inode;
682 +       struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
683 +
684 +       spin_lock (&sbinfo->stat_lock);
685 +       if (!sbinfo->free_inodes) {
686 +               spin_unlock (&sbinfo->stat_lock);
687 +               return NULL;
688 +       }
689 +       sbinfo->free_inodes--;
690 +       spin_unlock (&sbinfo->stat_lock);
691 +
692 +       if ((inode = new_inode(sb))) {
693 +               shmem_fill_inode(inode, mode, dev);
694 +               if (root)
695 +                       sbinfo->root_ino = inode->i_ino;
696         }
697 +       
698         return inode;
699  }
700  
701 -static int shmem_set_size(struct shmem_sb_info *info,
702 -                         unsigned long max_blocks, unsigned long max_inodes)
703 +void shmem_read_inode(struct inode *inode)
704 +{
705 +       struct shmem_sb_info *sbinfo;
706 +
707 +       if (inode->i_ino != SHMEM_IOPEN_INO)
708 +               return;
709 +               
710 +       sbinfo = SHMEM_SB(inode->i_sb);
711 +       
712 +       spin_lock (&sbinfo->stat_lock);
713 +       if (!sbinfo->free_inodes) {
714 +               spin_unlock (&sbinfo->stat_lock);
715 +               return;
716 +       }
717 +       sbinfo->free_inodes--;
718 +       spin_unlock (&sbinfo->stat_lock);
719 +       shmem_fill_inode(inode, 0, 0);
720 +}
721 +
722 +static int
723 +shmem_set_size(struct shmem_sb_info *info, unsigned long max_blocks, 
724 +              unsigned long max_inodes)
725  {
726         int error;
727         unsigned long blocks, inodes;
728 @@ -1192,7 +1459,6 @@ shmem_file_write(struct file *file,const
729  
730         while (count) {
731                 unsigned long bytes, index, offset;
732 -               char *kaddr;
733  
734                 /*
735                  * Try to find the page in the cache. If it isn't there,
736 @@ -1201,9 +1467,9 @@ shmem_file_write(struct file *file,const
737                 offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
738                 index = pos >> PAGE_CACHE_SHIFT;
739                 bytes = PAGE_CACHE_SIZE - offset;
740 -               if (bytes > count) {
741 +
742 +               if (bytes > count)
743                         bytes = count;
744 -               }
745  
746                 /*
747                  * Bring in the user page that we will copy from _first_.
748 @@ -1218,7 +1484,7 @@ shmem_file_write(struct file *file,const
749  
750                 info = SHMEM_I(inode);
751                 down (&info->sem);
752 -               page = shmem_getpage_locked(info, inode, index);
753 +               page = shmem_getpage_locked(inode, index);
754                 up (&info->sem);
755  
756                 status = PTR_ERR(page);
757 @@ -1226,17 +1492,19 @@ shmem_file_write(struct file *file,const
758                         break;
759  
760                 /* We have exclusive IO access to the page.. */
761 -               if (!PageLocked(page)) {
762 +               if (!PageLocked(page))
763                         PAGE_BUG(page);
764 -               }
765  
766 -               kaddr = kmap(page);
767 -               status = copy_from_user(kaddr+offset, buf, bytes);
768 +               status = copy_from_user(kmap(page) + offset,
769 +                                       buf, bytes);
770 +               
771                 kunmap(page);
772 +
773                 if (status)
774                         goto fail_write;
775  
776                 flush_dcache_page(page);
777 +               
778                 if (bytes > 0) {
779                         SetPageDirty(page);
780                         written += bytes;
781 @@ -1266,7 +1534,8 @@ fail_write:
782         goto unlock;
783  }
784  
785 -static void do_shmem_file_read(struct file * filp, loff_t *ppos, read_descriptor_t * desc)
786 +static void
787 +do_shmem_file_read(struct file * filp, loff_t *ppos, read_descriptor_t * desc)
788  {
789         struct inode *inode = filp->f_dentry->d_inode;
790         struct address_space *mapping = inode->i_mapping;
791 @@ -1292,15 +1561,18 @@ static void do_shmem_file_read(struct fi
792  
793                 nr = nr - offset;
794  
795 -               if ((desc->error = shmem_getpage(inode, index, &page)))
796 +               page = shmem_getpage_unlocked(inode, index);
797 +
798 +               if (IS_ERR(page)) {
799 +                       desc->error = PTR_ERR(page);
800                         break;
801 +               }
802  
803                 if (mapping->i_mmap_shared != NULL)
804                         flush_dcache_page(page);
805  
806 -               /*
807 -                * Ok, we have the page, and it's up-to-date, so
808 -                * now we can copy it to user space...
809 +               /* Ok, we have the page, and it's up-to-date, so now we can copy
810 +                * it to user space...
811                  *
812                  * The actor routine returns how many bytes were actually used..
813                  * NOTE! This may not be the same as how much of a user buffer
814 @@ -1309,6 +1581,8 @@ static void do_shmem_file_read(struct fi
815                  * pointers and the remaining count).
816                  */
817                 nr = file_read_actor(desc, page, offset, nr);
818 +
819 +               /* updating counters */
820                 offset += nr;
821                 index += offset >> PAGE_CACHE_SHIFT;
822                 offset &= ~PAGE_CACHE_MASK;
823 @@ -1320,7 +1594,8 @@ static void do_shmem_file_read(struct fi
824         UPDATE_ATIME(inode);
825  }
826  
827 -static ssize_t shmem_file_read(struct file * filp, char * buf, size_t count, loff_t *ppos)
828 +static ssize_t
829 +shmem_file_read(struct file * filp, char * buf, size_t count, loff_t *ppos)
830  {
831         ssize_t retval;
832  
833 @@ -1345,7 +1620,8 @@ static ssize_t shmem_file_read(struct fi
834         return retval;
835  }
836  
837 -static int shmem_statfs(struct super_block *sb, struct statfs *buf)
838 +static int
839 +shmem_statfs(struct super_block *sb, struct statfs *buf)
840  {
841         struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
842  
843 @@ -1361,22 +1637,62 @@ static int shmem_statfs(struct super_blo
844         return 0;
845  }
846  
847 -/*
848 - * Lookup the data. This is trivial - if the dentry didn't already
849 - * exist, we know it is negative.
850 - */
851 -static struct dentry * shmem_lookup(struct inode *dir, struct dentry *dentry)
852 +static int
853 +match_dentry(struct dentry *dentry, const char *name)
854 +{
855 +       int len = strlen(name);
856 +       
857 +       if (dentry->d_name.len != len)
858 +               return 0;
859 +               
860 +       if (strncmp(dentry->d_name.name, name, len))
861 +               return 0;
862 +               
863 +       return 1;
864 +}
865 +
866 +static int
867 +shmem_iopen_check(struct inode *dir, struct dentry *dentry)
868 +{
869 +       struct inode *inode;
870 +       struct shmem_sb_info *sbinfo = SHMEM_SB(dir->i_sb);
871 +
872 +       if (dir->i_ino != sbinfo->root_ino ||
873 +           !(sbinfo->options & SHMEM_MOUNT_IOPEN) ||
874 +           !match_dentry(dentry, "__iopen__"))
875 +       {
876 +               return 0;
877 +       }
878 +
879 +       if (!(inode = iget(dir->i_sb, SHMEM_IOPEN_INO)))
880 +               return 0;
881 +               
882 +       d_add(dentry, inode);
883 +       
884 +       spin_lock (&sbinfo->stat_lock);
885 +       sbinfo->iopen = dentry;
886 +       spin_unlock (&sbinfo->stat_lock);
887 +       
888 +       dget(dentry);
889 +       return 1;
890 +}
891 +
892 +static struct dentry *
893 +shmem_lookup(struct inode *dir, struct dentry *dentry)
894  {
895 -       d_add(dentry, NULL);
896 +       if (!shmem_iopen_check(dir, dentry))
897 +               d_add(dentry, NULL);
898 +       
899         return NULL;
900  }
901  
902  /*
903   * File creation. Allocate an inode, and we're done..
904   */
905 -static int shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
906 +static int
907 +shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
908  {
909 -       struct inode * inode = shmem_get_inode(dir->i_sb, mode, dev);
910 +       struct inode *inode = shmem_get_inode(dir->i_sb, mode, dev, 0);
911         int error = -ENOSPC;
912  
913         if (inode) {
914 @@ -1386,20 +1702,24 @@ static int shmem_mknod(struct inode *dir
915                 dget(dentry); /* Extra count - pin the dentry in core */
916                 error = 0;
917         }
918 +       
919         return error;
920  }
921  
922 -static int shmem_mkdir(struct inode * dir, struct dentry * dentry, int mode)
923 +static int
924 +shmem_mkdir(struct inode * dir, struct dentry * dentry, int mode)
925  {
926         int error;
927  
928         if ((error = shmem_mknod(dir, dentry, mode | S_IFDIR, 0)))
929                 return error;
930 +               
931         dir->i_nlink++;
932         return 0;
933  }
934  
935 -static int shmem_create(struct inode *dir, struct dentry *dentry, int mode)
936 +static int
937 +shmem_create(struct inode *dir, struct dentry *dentry, int mode)
938  {
939         return shmem_mknod(dir, dentry, mode | S_IFREG, 0);
940  }
941 @@ -1407,7 +1727,8 @@ static int shmem_create(struct inode *di
942  /*
943   * Link a file..
944   */
945 -static int shmem_link(struct dentry *old_dentry, struct inode * dir, struct dentry * dentry)
946 +static int
947 +shmem_link(struct dentry *old_dentry, struct inode * dir, struct dentry * dentry)
948  {
949         struct inode *inode = old_dentry->d_inode;
950  
951 @@ -1429,13 +1750,11 @@ static inline int shmem_positive(struct 
952  }
953  
954  /*
955 - * Check that a directory is empty (this works
956 - * for regular files too, they'll just always be
957 - * considered empty..).
958 + * Check that a directory is empty (this works for regular files too, they'll
959 + * just always be considered empty..).
960   *
961 - * Note that an empty directory can still have
962 - * children, they just all have to be negative..
963 - */
964 + * Note that an empty directory can still have children, they just all have to
965 + * be negative.. */
966  static int shmem_empty(struct dentry *dentry)
967  {
968         struct list_head *list;
969 @@ -1456,18 +1775,22 @@ static int shmem_empty(struct dentry *de
970         return 1;
971  }
972  
973 -static int shmem_unlink(struct inode * dir, struct dentry *dentry)
974 +static int
975 +shmem_unlink(struct inode *dir, struct dentry *dentry)
976  {
977         struct inode *inode = dentry->d_inode;
978  
979         dir->i_size -= BOGO_DIRENT_SIZE;
980         inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
981         inode->i_nlink--;
982 -       dput(dentry);   /* Undo the count from "create" - this does all the work */
983 +       
984 +       /* undo the count from "create" - this does all the work. */
985 +       dput(dentry);
986         return 0;
987  }
988  
989 -static int shmem_rmdir(struct inode * dir, struct dentry *dentry)
990 +static int
991 +shmem_rmdir(struct inode *dir, struct dentry *dentry)
992  {
993         if (!shmem_empty(dentry))
994                 return -ENOTEMPTY;
995 @@ -1477,12 +1800,13 @@ static int shmem_rmdir(struct inode * di
996  }
997  
998  /*
999 - * The VFS layer already does all the dentry stuff for rename,
1000 - * we just have to decrement the usage count for the target if
1001 - * it exists so that the VFS layer correctly free's it when it
1002 - * gets overwritten.
1003 + * The VFS layer already does all the dentry stuff for rename, we just have to
1004 + * decrement the usage count for the target if it exists so that the VFS layer
1005 + * correctly free's it when it gets overwritten.
1006   */
1007 -static int shmem_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,struct dentry *new_dentry)
1008 +static int
1009 +shmem_rename(struct inode *old_dir, struct dentry *old_dentry,
1010 +            struct inode *new_dir, struct dentry *new_dentry)
1011  {
1012         struct inode *inode = old_dentry->d_inode;
1013         int they_are_dirs = S_ISDIR(inode->i_mode);
1014 @@ -1507,19 +1831,20 @@ static int shmem_rename(struct inode * o
1015         return 0;
1016  }
1017  
1018 -static int shmem_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
1019 +static int
1020 +shmem_symlink(struct inode *dir, struct dentry *dentry,
1021 +             const char *symname)
1022  {
1023         int len;
1024 -       struct inode *inode;
1025         struct page *page;
1026 -       char *kaddr;
1027 -       struct shmem_inode_info * info;
1028 +       struct inode *inode;
1029 +       struct shmem_inode_info *info;
1030  
1031         len = strlen(symname) + 1;
1032         if (len > PAGE_CACHE_SIZE)
1033                 return -ENAMETOOLONG;
1034  
1035 -       inode = shmem_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0);
1036 +       inode = shmem_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0, 0);
1037         if (!inode)
1038                 return -ENOSPC;
1039  
1040 @@ -1531,7 +1856,7 @@ static int shmem_symlink(struct inode * 
1041                 inode->i_op = &shmem_symlink_inline_operations;
1042         } else {
1043                 down(&info->sem);
1044 -               page = shmem_getpage_locked(info, inode, 0);
1045 +               page = shmem_getpage_locked(inode, 0);
1046                 if (IS_ERR(page)) {
1047                         up(&info->sem);
1048                         iput(inode);
1049 @@ -1541,8 +1866,7 @@ static int shmem_symlink(struct inode * 
1050                 spin_lock (&shmem_ilock);
1051                 list_add_tail(&info->list, &shmem_inodes);
1052                 spin_unlock (&shmem_ilock);
1053 -               kaddr = kmap(page);
1054 -               memcpy(kaddr, symname, len);
1055 +               memcpy(kmap(page), symname, len);
1056                 kunmap(page);
1057                 SetPageDirty(page);
1058                 UnlockPage(page);
1059 @@ -1556,40 +1880,52 @@ static int shmem_symlink(struct inode * 
1060         return 0;
1061  }
1062  
1063 -static int shmem_readlink_inline(struct dentry *dentry, char *buffer, int buflen)
1064 +static int
1065 +shmem_readlink_inline(struct dentry *dentry, char *buffer, int buflen)
1066  {
1067 -       return vfs_readlink(dentry,buffer,buflen, (const char *)SHMEM_I(dentry->d_inode));
1068 +       return vfs_readlink(dentry,buffer, buflen,
1069 +                           (const char *)SHMEM_I(dentry->d_inode));
1070  }
1071  
1072 -static int shmem_follow_link_inline(struct dentry *dentry, struct nameidata *nd)
1073 +static int
1074 +shmem_follow_link_inline(struct dentry *dentry, struct nameidata *nd)
1075  {
1076         return vfs_follow_link(nd, (const char *)SHMEM_I(dentry->d_inode));
1077  }
1078  
1079 -static int shmem_readlink(struct dentry *dentry, char *buffer, int buflen)
1080 +static int
1081 +shmem_readlink(struct dentry *dentry, char *buffer, int buflen)
1082  {
1083 -       struct page * page;
1084 -       int res = shmem_getpage(dentry->d_inode, 0, &page);
1085 +       int res;
1086 +       struct page *page;
1087 +
1088 +       page = shmem_getpage_unlocked(dentry->d_inode, 0);
1089  
1090 -       if (res)
1091 -               return res;
1092 +       if (IS_ERR(page))
1093 +               return PTR_ERR(page);
1094  
1095         res = vfs_readlink(dentry,buffer,buflen, kmap(page));
1096         kunmap(page);
1097         page_cache_release(page);
1098 +       
1099         return res;
1100  }
1101  
1102 -static int shmem_follow_link(struct dentry *dentry, struct nameidata *nd)
1103 +static int
1104 +shmem_follow_link(struct dentry *dentry, struct nameidata *nd)
1105  {
1106         struct page * page;
1107 -       int res = shmem_getpage(dentry->d_inode, 0, &page);
1108 -       if (res)
1109 -               return res;
1110 +       int res;
1111 +
1112 +       page = shmem_getpage_unlocked(dentry->d_inode, 0);
1113 +
1114 +       if (IS_ERR(page))
1115 +               return PTR_ERR(page);
1116  
1117         res = vfs_follow_link(nd, kmap(page));
1118         kunmap(page);
1119         page_cache_release(page);
1120 +
1121         return res;
1122  }
1123  
1124 @@ -1610,7 +1946,10 @@ static struct inode_operations shmem_sym
1125  #endif
1126  };
1127  
1128 -static int shmem_parse_options(char *options, int *mode, uid_t *uid, gid_t *gid, unsigned long * blocks, unsigned long *inodes)
1129 +static int
1130 +shmem_parse_options(char *options, int *mode, uid_t *uid, gid_t *gid, 
1131 +                   unsigned long *blocks, unsigned long *inodes, 
1132 +                   unsigned long *opts)
1133  {
1134         char *this_char, *value, *rest;
1135  
1136 @@ -1620,11 +1959,6 @@ static int shmem_parse_options(char *opt
1137         for ( ; this_char; this_char = strtok(NULL,",")) {
1138                 if ((value = strchr(this_char,'=')) != NULL) {
1139                         *value++ = 0;
1140 -               } else {
1141 -                       printk(KERN_ERR 
1142 -                           "tmpfs: No value for mount option '%s'\n", 
1143 -                           this_char);
1144 -                       return 1;
1145                 }
1146  
1147                 if (!strcmp(this_char,"size")) {
1148 @@ -1659,6 +1993,17 @@ static int shmem_parse_options(char *opt
1149                         *gid = simple_strtoul(value,&rest,0);
1150                         if (*rest)
1151                                 goto bad_val;
1152 +               } else if (!strcmp(this_char, "iopen")) {
1153 +                       *opts |= SHMEM_MOUNT_IOPEN;
1154 +                       *opts &= ~SHMEM_MOUNT_IOPEN_NOPRIV;
1155 +               }
1156 +               else if (!strcmp(this_char, "noiopen")) {
1157 +                       *opts &= ~SHMEM_MOUNT_IOPEN;
1158 +                       *opts &= ~SHMEM_MOUNT_IOPEN_NOPRIV;
1159 +               }
1160 +               else if (!strcmp (this_char, "iopen_nopriv")) {
1161 +                       *opts |= SHMEM_MOUNT_IOPEN;
1162 +                       *opts |= SHMEM_MOUNT_IOPEN_NOPRIV;
1163                 } else {
1164                         printk(KERN_ERR "tmpfs: Bad mount option %s\n",
1165                                this_char);
1166 @@ -1674,14 +2019,19 @@ bad_val:
1167  
1168  }
1169  
1170 -static int shmem_remount_fs (struct super_block *sb, int *flags, char *data)
1171 +static int
1172 +shmem_remount_fs(struct super_block *sb, int *flags, char *data)
1173  {
1174         struct shmem_sb_info *sbinfo = &sb->u.shmem_sb;
1175         unsigned long max_blocks = sbinfo->max_blocks;
1176         unsigned long max_inodes = sbinfo->max_inodes;
1177  
1178 -       if (shmem_parse_options (data, NULL, NULL, NULL, &max_blocks, &max_inodes))
1179 +       if (shmem_parse_options (data, NULL, NULL, NULL, &max_blocks, 
1180 +                                &max_inodes, &sbinfo->options))
1181 +       {
1182                 return -EINVAL;
1183 +       }
1184 +               
1185         return shmem_set_size(sbinfo, max_blocks, max_inodes);
1186  }
1187  
1188 @@ -1691,7 +2041,8 @@ int shmem_sync_file(struct file * file, 
1189  }
1190  #endif
1191  
1192 -static struct super_block *shmem_read_super(struct super_block * sb, void * data, int silent)
1193 +static struct super_block *
1194 +shmem_read_super(struct super_block * sb, void * data, int silent)
1195  {
1196         struct inode * inode;
1197         struct dentry * root;
1198 @@ -1710,11 +2061,15 @@ static struct super_block *shmem_read_su
1199         blocks = inodes = si.totalram / 2;
1200  
1201  #ifdef CONFIG_TMPFS
1202 -       if (shmem_parse_options (data, &mode, &uid, &gid, &blocks, &inodes))
1203 +       if (shmem_parse_options (data, &mode, &uid, &gid, &blocks, 
1204 +                                &inodes, &sbinfo->options))
1205 +       {
1206                 return NULL;
1207 +       }
1208  #endif
1209  
1210         spin_lock_init (&sbinfo->stat_lock);
1211 +       sbinfo->iopen = NULL;
1212         sbinfo->max_blocks = blocks;
1213         sbinfo->free_blocks = blocks;
1214         sbinfo->max_inodes = inodes;
1215 @@ -1724,7 +2079,7 @@ static struct super_block *shmem_read_su
1216         sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
1217         sb->s_magic = TMPFS_MAGIC;
1218         sb->s_op = &shmem_ops;
1219 -       inode = shmem_get_inode(sb, S_IFDIR | mode, 0);
1220 +       inode = shmem_get_inode(sb, S_IFDIR | mode, 0, 1);
1221         if (!inode)
1222                 return NULL;
1223  
1224 @@ -1739,7 +2094,19 @@ static struct super_block *shmem_read_su
1225         return sb;
1226  }
1227  
1228 +void shmem_put_super(struct super_block *sb)
1229 +{
1230 +       struct dentry *iopen;
1231 +       struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
1232  
1233 +       spin_lock(&sbinfo->stat_lock);
1234 +       iopen = sbinfo->iopen;
1235 +       sbinfo->iopen = NULL;
1236 +       spin_unlock(&sbinfo->stat_lock);
1237 +
1238 +       if (iopen)
1239 +               dput(iopen);
1240 +}
1241  
1242  static struct address_space_operations shmem_aops = {
1243         writepage:      shmem_writepage,
1244 @@ -1790,11 +2157,13 @@ static struct super_operations shmem_ops
1245         remount_fs:     shmem_remount_fs,
1246  #endif
1247         delete_inode:   shmem_delete_inode,
1248 -       put_inode:      force_delete,   
1249 +       read_inode:     shmem_read_inode,
1250 +       put_inode:      force_delete,
1251 +       put_super:      shmem_put_super,
1252  };
1253  
1254  static struct vm_operations_struct shmem_vm_ops = {
1255 -       nopage: shmem_nopage,
1256 +       nopage:         shmem_nopage,
1257  };
1258  
1259  #ifdef CONFIG_TMPFS
1260 @@ -1885,7 +2254,7 @@ struct file *shmem_file_setup(char * nam
1261                 goto put_dentry;
1262  
1263         error = -ENOSPC;
1264 -       inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0);
1265 +       inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0, 0);
1266         if (!inode) 
1267                 goto close_file;
1268  
1269 @@ -1921,15 +2290,17 @@ int shmem_zero_setup(struct vm_area_stru
1270  
1271         if (vma->vm_file)
1272                 fput (vma->vm_file);
1273 +       
1274         vma->vm_file = file;
1275         vma->vm_ops = &shmem_vm_ops;
1276         return 0;
1277  }
1278  
1279  EXPORT_SYMBOL(shmem_file_setup);
1280 -EXPORT_SYMBOL(shmem_getpage);
1281  EXPORT_SYMBOL(shmem_xattr_find);
1282  EXPORT_SYMBOL(shmem_xattr_set);
1283  EXPORT_SYMBOL(shmem_xattr_get);
1284  EXPORT_SYMBOL(shmem_xattr_delete);
1285  EXPORT_SYMBOL(shmem_xattr_remove);
1286 +EXPORT_SYMBOL(shmem_getpage_locked);
1287 +EXPORT_SYMBOL(shmem_getpage_unlocked);