[PATCH] smbfs LFS
[opensuse:kernel.git] / fs / smbfs / inode.c
1 /*
2  *  inode.c
3  *
4  *  Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
5  *  Copyright (C) 1997 by Volker Lendecke
6  *
7  *  Please add a note about your changes to smbfs in the ChangeLog file.
8  */
9
10 #include <linux/config.h>
11 #include <linux/module.h>
12 #include <linux/time.h>
13 #include <linux/kernel.h>
14 #include <linux/mm.h>
15 #include <linux/string.h>
16 #include <linux/stat.h>
17 #include <linux/errno.h>
18 #include <linux/locks.h>
19 #include <linux/slab.h>
20 #include <linux/init.h>
21 #include <linux/file.h>
22 #include <linux/dcache.h>
23 #include <linux/smp_lock.h>
24 #include <linux/nls.h>
25 #include <linux/seq_file.h>
26
27 #include <linux/smb_fs.h>
28 #include <linux/smbno.h>
29 #include <linux/smb_mount.h>
30
31 #include <asm/system.h>
32 #include <asm/uaccess.h>
33
34 #include "smb_debug.h"
35 #include "getopt.h"
36 #include "proto.h"
37
38 /* Always pick a default string */
39 #ifdef CONFIG_SMB_NLS_REMOTE
40 #define SMB_NLS_REMOTE CONFIG_SMB_NLS_REMOTE
41 #else
42 #define SMB_NLS_REMOTE ""
43 #endif
44
45 #define SMB_TTL_DEFAULT 1000
46
47 static void smb_delete_inode(struct inode *);
48 static void smb_put_super(struct super_block *);
49 static int  smb_statfs(struct super_block *, struct statfs *);
50 static int  smb_show_options(struct seq_file *, struct vfsmount *);
51
52 static kmem_cache_t *smb_inode_cachep;
53
54 static struct inode *smb_alloc_inode(struct super_block *sb)
55 {
56         struct smb_inode_info *ei;
57         ei = (struct smb_inode_info *)kmem_cache_alloc(smb_inode_cachep, SLAB_KERNEL);
58         if (!ei)
59                 return NULL;
60         return &ei->vfs_inode;
61 }
62
63 static void smb_destroy_inode(struct inode *inode)
64 {
65         kmem_cache_free(smb_inode_cachep, SMB_I(inode));
66 }
67
68 static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
69 {
70         struct smb_inode_info *ei = (struct smb_inode_info *) foo;
71         unsigned long flagmask = SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR;
72
73         if ((flags & flagmask) == SLAB_CTOR_CONSTRUCTOR)
74                 inode_init_once(&ei->vfs_inode);
75 }
76  
77 static int init_inodecache(void)
78 {
79         smb_inode_cachep = kmem_cache_create("smb_inode_cache",
80                                              sizeof(struct smb_inode_info),
81                                              0, SLAB_HWCACHE_ALIGN,
82                                              init_once, NULL);
83         if (smb_inode_cachep == NULL)
84                 return -ENOMEM;
85         return 0;
86 }
87
88 static void destroy_inodecache(void)
89 {
90         if (kmem_cache_destroy(smb_inode_cachep))
91                 printk(KERN_INFO "smb_inode_cache: not all structures were freed\n");
92 }
93
94 static struct super_operations smb_sops =
95 {
96         alloc_inode:    smb_alloc_inode,
97         destroy_inode:  smb_destroy_inode,
98         put_inode:      force_delete,
99         delete_inode:   smb_delete_inode,
100         put_super:      smb_put_super,
101         statfs:         smb_statfs,
102         show_options:   smb_show_options,
103 };
104
105
106 /* We are always generating a new inode here */
107 struct inode *
108 smb_iget(struct super_block *sb, struct smb_fattr *fattr)
109 {
110         struct inode *result;
111
112         DEBUG1("smb_iget: %p\n", fattr);
113
114         result = new_inode(sb);
115         if (!result)
116                 return result;
117         result->i_ino = fattr->f_ino;
118         SMB_I(result)->open = 0;
119         SMB_I(result)->fileid = 0;
120         SMB_I(result)->access = 0;
121         SMB_I(result)->flags = 0;
122         SMB_I(result)->closed = 0;
123         SMB_I(result)->openers = 0;
124         smb_set_inode_attr(result, fattr);
125         if (S_ISREG(result->i_mode)) {
126                 result->i_op = &smb_file_inode_operations;
127                 result->i_fop = &smb_file_operations;
128                 result->i_data.a_ops = &smb_file_aops;
129         } else if (S_ISDIR(result->i_mode)) {
130                 result->i_op = &smb_dir_inode_operations;
131                 result->i_fop = &smb_dir_operations;
132         }
133         insert_inode_hash(result);
134         return result;
135 }
136
137 /*
138  * Copy the inode data to a smb_fattr structure.
139  */
140 void
141 smb_get_inode_attr(struct inode *inode, struct smb_fattr *fattr)
142 {
143         memset(fattr, 0, sizeof(struct smb_fattr));
144         fattr->f_mode   = inode->i_mode;
145         fattr->f_nlink  = inode->i_nlink;
146         fattr->f_ino    = inode->i_ino;
147         fattr->f_uid    = inode->i_uid;
148         fattr->f_gid    = inode->i_gid;
149         fattr->f_rdev   = inode->i_rdev;
150         fattr->f_size   = inode->i_size;
151         fattr->f_mtime  = inode->i_mtime;
152         fattr->f_ctime  = inode->i_ctime;
153         fattr->f_atime  = inode->i_atime;
154         fattr->f_blksize= inode->i_blksize;
155         fattr->f_blocks = inode->i_blocks;
156
157         fattr->attr     = SMB_I(inode)->attr;
158         /*
159          * Keep the attributes in sync with the inode permissions.
160          */
161         if (fattr->f_mode & S_IWUSR)
162                 fattr->attr &= ~aRONLY;
163         else
164                 fattr->attr |= aRONLY;
165 }
166
167 /*
168  * Update the inode, possibly causing it to invalidate its pages if mtime/size
169  * is different from last time.
170  */
171 void
172 smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr)
173 {
174         struct smb_inode_info *ei = SMB_I(inode);
175
176         /*
177          * A size change should have a different mtime, or same mtime
178          * but different size.
179          */
180         time_t last_time = inode->i_mtime;
181         loff_t last_sz = inode->i_size;
182
183         inode->i_mode   = fattr->f_mode;
184         inode->i_nlink  = fattr->f_nlink;
185         inode->i_uid    = fattr->f_uid;
186         inode->i_gid    = fattr->f_gid;
187         inode->i_rdev   = fattr->f_rdev;
188         inode->i_ctime  = fattr->f_ctime;
189         inode->i_blksize= fattr->f_blksize;
190         inode->i_blocks = fattr->f_blocks;
191         inode->i_size   = fattr->f_size;
192         inode->i_mtime  = fattr->f_mtime;
193         inode->i_atime  = fattr->f_atime;
194         ei->attr = fattr->attr;
195
196         /*
197          * Update the "last time refreshed" field for revalidation.
198          */
199         ei->oldmtime = jiffies;
200
201         if (inode->i_mtime != last_time || inode->i_size != last_sz) {
202                 VERBOSE("%ld changed, old=%ld, new=%ld, oz=%ld, nz=%ld\n",
203                         inode->i_ino,
204                         (long) last_time, (long) inode->i_mtime,
205                         (long) last_sz, (long) inode->i_size);
206
207                 if (!S_ISDIR(inode->i_mode))
208                         invalidate_inode_pages(inode);
209         }
210 }
211
212 /*
213  * This is called if the connection has gone bad ...
214  * try to kill off all the current inodes.
215  */
216 void
217 smb_invalidate_inodes(struct smb_sb_info *server)
218 {
219         VERBOSE("\n");
220         shrink_dcache_sb(SB_of(server));
221         invalidate_inodes(SB_of(server));
222 }
223
224 /*
225  * This is called to update the inode attributes after
226  * we've made changes to a file or directory.
227  */
228 static int
229 smb_refresh_inode(struct dentry *dentry)
230 {
231         struct inode *inode = dentry->d_inode;
232         int error;
233         struct smb_fattr fattr;
234
235         error = smb_proc_getattr(dentry, &fattr);
236         if (!error) {
237                 smb_renew_times(dentry);
238                 /*
239                  * Check whether the type part of the mode changed,
240                  * and don't update the attributes if it did.
241                  */
242                 if ((inode->i_mode & S_IFMT) == (fattr.f_mode & S_IFMT)) {
243                         smb_set_inode_attr(inode, &fattr);
244                 } else {
245                         /*
246                          * Big trouble! The inode has become a new object,
247                          * so any operations attempted on it are invalid.
248                          *
249                          * To limit damage, mark the inode as bad so that
250                          * subsequent lookup validations will fail.
251                          */
252                         PARANOIA("%s/%s changed mode, %07o to %07o\n",
253                                  DENTRY_PATH(dentry),
254                                  inode->i_mode, fattr.f_mode);
255
256                         fattr.f_mode = inode->i_mode; /* save mode */
257                         make_bad_inode(inode);
258                         inode->i_mode = fattr.f_mode; /* restore mode */
259                         /*
260                          * No need to worry about unhashing the dentry: the
261                          * lookup validation will see that the inode is bad.
262                          * But we do want to invalidate the caches ...
263                          */
264                         if (!S_ISDIR(inode->i_mode))
265                                 invalidate_inode_pages(inode);
266                         else
267                                 smb_invalid_dir_cache(inode);
268                         error = -EIO;
269                 }
270         }
271         return error;
272 }
273
274 /*
275  * This is called when we want to check whether the inode
276  * has changed on the server.  If it has changed, we must
277  * invalidate our local caches.
278  */
279 int
280 smb_revalidate_inode(struct dentry *dentry)
281 {
282         struct smb_sb_info *s = server_from_dentry(dentry);
283         struct inode *inode = dentry->d_inode;
284         int error = 0;
285
286         DEBUG1("smb_revalidate_inode\n");
287         lock_kernel();
288
289         /*
290          * Check whether we've recently refreshed the inode.
291          */
292         if (time_before(jiffies, SMB_I(inode)->oldmtime + SMB_MAX_AGE(s))) {
293                 VERBOSE("up-to-date, ino=%ld, jiffies=%lu, oldtime=%lu\n",
294                         inode->i_ino, jiffies, SMB_I(inode)->oldmtime);
295                 goto out;
296         }
297
298         error = smb_refresh_inode(dentry);
299 out:
300         unlock_kernel();
301         return error;
302 }
303
304 /*
305  * This routine is called when i_nlink == 0 and i_count goes to 0.
306  * All blocking cleanup operations need to go here to avoid races.
307  */
308 static void
309 smb_delete_inode(struct inode *ino)
310 {
311         DEBUG1("ino=%ld\n", ino->i_ino);
312         lock_kernel();
313         if (smb_close(ino))
314                 PARANOIA("could not close inode %ld\n", ino->i_ino);
315         unlock_kernel();
316         clear_inode(ino);
317 }
318
319 static struct option opts[] = {
320         { "version",    0, 'v' },
321         { "win95",      SMB_MOUNT_WIN95, 1 },
322         { "oldattr",    SMB_MOUNT_OLDATTR, 1 },
323         { "dirattr",    SMB_MOUNT_DIRATTR, 1 },
324         { "case",       SMB_MOUNT_CASE, 1 },
325         { "uid",        0, 'u' },
326         { "gid",        0, 'g' },
327         { "file_mode",  0, 'f' },
328         { "dir_mode",   0, 'd' },
329         { "iocharset",  0, 'i' },
330         { "codepage",   0, 'c' },
331         { "ttl",        0, 't' },
332         { NULL,         0, 0}
333 };
334
335 static int
336 parse_options(struct smb_mount_data_kernel *mnt, char *options)
337 {
338         int c;
339         unsigned long flags;
340         unsigned long value;
341         char *optarg;
342         char *optopt;
343
344         flags = 0;
345         while ( (c = smb_getopt("smbfs", &options, opts,
346                                 &optopt, &optarg, &flags, &value)) > 0) {
347
348                 VERBOSE("'%s' -> '%s'\n", optopt, optarg ? optarg : "<none>");
349
350                 switch (c) {
351                 case 1:
352                         /* got a "flag" option */
353                         break;
354                 case 'v':
355                         if (value != SMB_MOUNT_VERSION) {
356                         printk ("smbfs: Bad mount version %ld, expected %d\n",
357                                 value, SMB_MOUNT_VERSION);
358                                 return 0;
359                         }
360                         mnt->version = value;
361                         break;
362                 case 'u':
363                         mnt->uid = value;
364                         break;
365                 case 'g':
366                         mnt->gid = value;
367                         break;
368                 case 'f':
369                         mnt->file_mode = (value & S_IRWXUGO) | S_IFREG;
370                         break;
371                 case 'd':
372                         mnt->dir_mode = (value & S_IRWXUGO) | S_IFDIR;
373                         break;
374                 case 'i':
375                         strncpy(mnt->codepage.local_name, optarg, 
376                                 SMB_NLS_MAXNAMELEN);
377                         break;
378                 case 'c':
379                         strncpy(mnt->codepage.remote_name, optarg,
380                                 SMB_NLS_MAXNAMELEN);
381                         break;
382                 case 't':
383                         mnt->ttl = value;
384                         break;
385                 default:
386                         printk ("smbfs: Unrecognized mount option %s\n",
387                                 optopt);
388                         return -1;
389                 }
390         }
391         mnt->flags = flags;
392         return c;
393 }
394
395 /*
396  * smb_show_options() is for displaying mount options in /proc/mounts.
397  * It tries to avoid showing settings that were not changed from their
398  * defaults.
399  */
400 static int
401 smb_show_options(struct seq_file *s, struct vfsmount *m)
402 {
403         struct smb_mount_data_kernel *mnt = m->mnt_sb->u.smbfs_sb.mnt;
404         int i;
405
406         for (i = 0; opts[i].name != NULL; i++)
407                 if (mnt->flags & opts[i].flag)
408                         seq_printf(s, ",%s", opts[i].name);
409
410         if (mnt->uid != 0)
411                 seq_printf(s, ",uid=%d", mnt->uid);
412         if (mnt->gid != 0)
413                 seq_printf(s, ",gid=%d", mnt->gid);
414         if (mnt->mounted_uid != 0)
415                 seq_printf(s, ",mounted_uid=%d", mnt->mounted_uid);
416
417         /* 
418          * Defaults for file_mode and dir_mode are unknown to us; they
419          * depend on the current umask of the user doing the mount.
420          */
421         seq_printf(s, ",file_mode=%04o", mnt->file_mode & S_IRWXUGO);
422         seq_printf(s, ",dir_mode=%04o", mnt->dir_mode & S_IRWXUGO);
423
424         if (strcmp(mnt->codepage.local_name, CONFIG_NLS_DEFAULT))
425                 seq_printf(s, ",iocharset=%s", mnt->codepage.local_name);
426         if (strcmp(mnt->codepage.remote_name, SMB_NLS_REMOTE))
427                 seq_printf(s, ",codepage=%s", mnt->codepage.remote_name);
428
429         if (mnt->ttl != SMB_TTL_DEFAULT)
430                 seq_printf(s, ",ttl=%d", mnt->ttl);
431
432         return 0;
433 }
434
435 static void
436 smb_put_super(struct super_block *sb)
437 {
438         struct smb_sb_info *server = &(sb->u.smbfs_sb);
439
440         if (server->sock_file) {
441                 smb_dont_catch_keepalive(server);
442                 fput(server->sock_file);
443         }
444
445         if (server->conn_pid)
446                kill_proc(server->conn_pid, SIGTERM, 1);
447
448         smb_kfree(server->ops);
449         if (server->packet)
450                 smb_vfree(server->packet);
451
452         if (server->remote_nls) {
453                 unload_nls(server->remote_nls);
454                 server->remote_nls = NULL;
455         }
456         if (server->local_nls) {
457                 unload_nls(server->local_nls);
458                 server->local_nls = NULL;
459         }
460 }
461
462 int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
463 {
464         struct smb_sb_info *server = &sb->u.smbfs_sb;
465         struct smb_mount_data_kernel *mnt;
466         struct smb_mount_data *oldmnt;
467         struct inode *root_inode;
468         struct smb_fattr root;
469         int ver;
470         void *mem;
471
472         if (!raw_data)
473                 goto out_no_data;
474
475         oldmnt = (struct smb_mount_data *) raw_data;
476         ver = oldmnt->version;
477         if (ver != SMB_MOUNT_OLDVERSION && cpu_to_be32(ver) != SMB_MOUNT_ASCII)
478                 goto out_wrong_data;
479
480         sb->s_blocksize = 1024; /* Eh...  Is this correct? */
481         sb->s_blocksize_bits = 10;
482         sb->s_magic = SMB_SUPER_MAGIC;
483         sb->s_op = &smb_sops;
484
485         server->mnt = NULL;
486         server->sock_file = NULL;
487         init_MUTEX(&server->sem);
488         init_waitqueue_head(&server->wait);
489         server->conn_pid = 0;
490         server->state = CONN_INVALID; /* no connection yet */
491         server->generation = 0;
492         server->packet_size = smb_round_length(SMB_INITIAL_PACKET_SIZE);
493         server->packet = smb_vmalloc(server->packet_size);
494         if (!server->packet)
495                 goto out_no_mem;
496
497         /* Allocate the global temp buffer and some superblock helper structs */
498         VERBOSE("alloc chunk = %d\n", sizeof(struct smb_ops) +
499                 sizeof(struct smb_mount_data_kernel) +
500                 2*SMB_MAXPATHLEN + 20);
501         mem = smb_kmalloc(sizeof(struct smb_ops) +
502                           sizeof(struct smb_mount_data_kernel) +
503                           2*SMB_MAXPATHLEN + 20, GFP_KERNEL);
504         if (!mem)
505                 goto out_no_temp;
506
507         server->ops = mem;
508         server->mnt = mem + sizeof(struct smb_ops);
509         server->name_buf = mem + sizeof(struct smb_ops) +
510                 sizeof(struct smb_mount_data_kernel);
511         server->temp_buf = mem + sizeof(struct smb_ops) +
512                 sizeof(struct smb_mount_data_kernel) +
513                 SMB_MAXPATHLEN + 1;
514
515         /* Setup NLS stuff */
516         server->remote_nls = NULL;
517         server->local_nls = NULL;
518
519         mnt = server->mnt;
520
521         memset(mnt, 0, sizeof(struct smb_mount_data_kernel));
522         strncpy(mnt->codepage.local_name, CONFIG_NLS_DEFAULT,
523                 SMB_NLS_MAXNAMELEN);
524         strncpy(mnt->codepage.remote_name, SMB_NLS_REMOTE,
525                 SMB_NLS_MAXNAMELEN);
526
527         mnt->ttl = SMB_TTL_DEFAULT;
528         if (ver == SMB_MOUNT_OLDVERSION) {
529                 mnt->version = oldmnt->version;
530
531                 /* FIXME: is this enough to convert uid/gid's ? */
532                 mnt->mounted_uid = oldmnt->mounted_uid;
533                 mnt->uid = oldmnt->uid;
534                 mnt->gid = oldmnt->gid;
535
536                 mnt->file_mode = (oldmnt->file_mode & S_IRWXUGO) | S_IFREG;
537                 mnt->dir_mode = (oldmnt->dir_mode & S_IRWXUGO) | S_IFDIR;
538
539                 mnt->flags = (oldmnt->file_mode >> 9);
540         } else {
541                 if (parse_options(mnt, raw_data))
542                         goto out_bad_option;
543
544                 mnt->mounted_uid = current->uid;
545         }
546         smb_setcodepage(server, &mnt->codepage);
547
548         /*
549          * Display the enabled options
550          * Note: smb_proc_getattr uses these in 2.4 (but was changed in 2.2)
551          */
552         if (mnt->flags & SMB_MOUNT_OLDATTR)
553                 printk("SMBFS: Using core getattr (Win 95 speedup)\n");
554         else if (mnt->flags & SMB_MOUNT_DIRATTR)
555                 printk("SMBFS: Using dir ff getattr\n");
556
557         /*
558          * Keep the super block locked while we get the root inode.
559          */
560         smb_init_root_dirent(server, &root);
561         root_inode = smb_iget(sb, &root);
562         if (!root_inode)
563                 goto out_no_root;
564
565         sb->s_root = d_alloc_root(root_inode);
566         if (!sb->s_root)
567                 goto out_no_root;
568         smb_new_dentry(sb->s_root);
569
570         return 0;
571
572 out_no_root:
573         iput(root_inode);
574 out_bad_option:
575         smb_kfree(mem);
576 out_no_temp:
577         smb_vfree(server->packet);
578 out_no_mem:
579         if (!server->mnt)
580                 printk(KERN_ERR "smb_fill_super: allocation failure\n");
581         goto out_fail;
582 out_wrong_data:
583         printk(KERN_ERR "smbfs: mount_data version %d is not supported\n", ver);
584         goto out_fail;
585 out_no_data:
586         printk(KERN_ERR "smb_fill_super: missing data argument\n");
587 out_fail:
588         return -EINVAL;
589 }
590
591 static int
592 smb_statfs(struct super_block *sb, struct statfs *buf)
593 {
594         int result = smb_proc_dskattr(sb, buf);
595
596         buf->f_type = SMB_SUPER_MAGIC;
597         buf->f_namelen = SMB_MAXPATHLEN;
598         return result;
599 }
600
601 int
602 smb_notify_change(struct dentry *dentry, struct iattr *attr)
603 {
604         struct inode *inode = dentry->d_inode;
605         struct smb_sb_info *server = server_from_dentry(dentry);
606         unsigned int mask = (S_IFREG | S_IFDIR | S_IRWXUGO);
607         int error, changed, refresh = 0;
608         struct smb_fattr fattr;
609
610         error = smb_revalidate_inode(dentry);
611         if (error)
612                 goto out;
613
614         if ((error = inode_change_ok(inode, attr)) < 0)
615                 goto out;
616
617         error = -EPERM;
618         if ((attr->ia_valid & ATTR_UID) && (attr->ia_uid != server->mnt->uid))
619                 goto out;
620
621         if ((attr->ia_valid & ATTR_GID) && (attr->ia_uid != server->mnt->gid))
622                 goto out;
623
624         if ((attr->ia_valid & ATTR_MODE) && (attr->ia_mode & ~mask))
625                 goto out;
626
627         if ((attr->ia_valid & ATTR_SIZE) != 0) {
628                 VERBOSE("changing %s/%s, old size=%ld, new size=%ld\n",
629                         DENTRY_PATH(dentry),
630                         (long) inode->i_size, (long) attr->ia_size);
631
632                 filemap_fdatasync(inode->i_mapping);
633                 filemap_fdatawait(inode->i_mapping);
634
635                 error = smb_open(dentry, O_WRONLY);
636                 if (error)
637                         goto out;
638                 error = server->ops->truncate(inode, attr->ia_size);
639                 if (error)
640                         goto out;
641                 error = vmtruncate(inode, attr->ia_size);
642                 if (error)
643                         goto out;
644                 refresh = 1;
645         }
646
647         /*
648          * Initialize the fattr and check for changed fields.
649          * Note: CTIME under SMB is creation time rather than
650          * change time, so we don't attempt to change it.
651          */
652         smb_get_inode_attr(inode, &fattr);
653
654         changed = 0;
655         if ((attr->ia_valid & ATTR_MTIME) != 0) {
656                 fattr.f_mtime = attr->ia_mtime;
657                 changed = 1;
658         }
659         if ((attr->ia_valid & ATTR_ATIME) != 0) {
660                 fattr.f_atime = attr->ia_atime;
661                 /* Earlier protocols don't have an access time */
662                 if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2)
663                         changed = 1;
664         }
665         if (changed) {
666                 error = smb_proc_settime(dentry, &fattr);
667                 if (error)
668                         goto out;
669                 refresh = 1;
670         }
671
672         /*
673          * Check for mode changes ... we're extremely limited in
674          * what can be set for SMB servers: just the read-only bit.
675          */
676         if ((attr->ia_valid & ATTR_MODE) != 0) {
677                 VERBOSE("%s/%s mode change, old=%x, new=%x\n",
678                         DENTRY_PATH(dentry), fattr.f_mode, attr->ia_mode);
679                 changed = 0;
680                 if (attr->ia_mode & S_IWUSR) {
681                         if (fattr.attr & aRONLY) {
682                                 fattr.attr &= ~aRONLY;
683                                 changed = 1;
684                         }
685                 } else {
686                         if (!(fattr.attr & aRONLY)) {
687                                 fattr.attr |= aRONLY;
688                                 changed = 1;
689                         }
690                 }
691                 if (changed) {
692                         error = smb_proc_setattr(dentry, &fattr);
693                         if (error)
694                                 goto out;
695                         refresh = 1;
696                 }
697         }
698         error = 0;
699
700 out:
701         if (refresh)
702                 smb_refresh_inode(dentry);
703         return error;
704 }
705
706 #ifdef DEBUG_SMB_MALLOC
707 int smb_malloced;
708 int smb_current_kmalloced;
709 int smb_current_vmalloced;
710 #endif
711
712 static struct super_block *smb_get_sb(struct file_system_type *fs_type,
713         int flags, char *dev_name, void *data)
714 {
715         return get_sb_nodev(fs_type, flags, data, smb_fill_super);
716 }
717
718 static struct file_system_type smb_fs_type = {
719         owner:          THIS_MODULE,
720         name:           "smbfs",
721         get_sb:         smb_get_sb,
722 };
723
724 static int __init init_smb_fs(void)
725 {
726         int err;
727         DEBUG1("registering ...\n");
728
729 #ifdef DEBUG_SMB_MALLOC
730         smb_malloced = 0;
731         smb_current_kmalloced = 0;
732         smb_current_vmalloced = 0;
733 #endif
734
735         err = init_inodecache();
736         if (err)
737                 goto out1;
738         err = register_filesystem(&smb_fs_type);
739         if (err)
740                 goto out;
741         return 0;
742 out:
743         destroy_inodecache();
744 out1:
745         return err;
746 }
747
748 static void __exit exit_smb_fs(void)
749 {
750         DEBUG1("unregistering ...\n");
751         unregister_filesystem(&smb_fs_type);
752         destroy_inodecache();
753 #ifdef DEBUG_SMB_MALLOC
754         printk(KERN_DEBUG "smb_malloced: %d\n", smb_malloced);
755         printk(KERN_DEBUG "smb_current_kmalloced: %d\n",smb_current_kmalloced);
756         printk(KERN_DEBUG "smb_current_vmalloced: %d\n",smb_current_vmalloced);
757 #endif
758 }
759
760 EXPORT_NO_SYMBOLS;
761
762 module_init(init_smb_fs)
763 module_exit(exit_smb_fs)
764 MODULE_LICENSE("GPL");