- pre1
[davej-history.git] / fs / smbfs / inode.c
blobb063860ee7ebc0771fb1807be69b88403abb5bdd
1 /*
2 * inode.c
4 * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
5 * Copyright (C) 1997 by Volker Lendecke
7 * Please add a note about your changes to smbfs in the ChangeLog file.
8 */
10 #include <linux/config.h>
11 #include <linux/module.h>
12 #include <linux/sched.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/malloc.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>
26 #include <linux/smb_fs.h>
27 #include <linux/smbno.h>
28 #include <linux/smb_mount.h>
30 #include <asm/system.h>
31 #include <asm/uaccess.h>
33 #include "smb_debug.h"
34 #include "getopt.h"
36 static void smb_delete_inode(struct inode *);
37 static void smb_put_super(struct super_block *);
38 static int smb_statfs(struct super_block *, struct statfs *);
39 static void smb_set_inode_attr(struct inode *, struct smb_fattr *);
41 static struct super_operations smb_sops =
43 put_inode: force_delete,
44 delete_inode: smb_delete_inode,
45 put_super: smb_put_super,
46 statfs: smb_statfs,
49 /* FIXME: Look at all inodes whether so that we do not get duplicate
50 * inode numbers. */
52 unsigned long
53 smb_invent_inos(unsigned long n)
55 static unsigned long ino = 2;
57 if (ino + 2*n < ino)
59 /* wrap around */
60 ino = 2;
62 ino += n;
63 return ino;
66 /* We are always generating a new inode here */
67 struct inode *
68 smb_iget(struct super_block *sb, struct smb_fattr *fattr)
70 struct inode *result;
72 DEBUG1("smb_iget: %p\n", fattr);
74 result = get_empty_inode();
75 if (!result)
76 return result;
77 result->i_sb = sb;
78 result->i_dev = sb->s_dev;
79 result->i_ino = fattr->f_ino;
80 memset(&(result->u.smbfs_i), 0, sizeof(result->u.smbfs_i));
81 smb_set_inode_attr(result, fattr);
82 if (S_ISREG(result->i_mode)) {
83 result->i_op = &smb_file_inode_operations;
84 result->i_fop = &smb_file_operations;
85 result->i_data.a_ops = &smb_file_aops;
86 } else if (S_ISDIR(result->i_mode)) {
87 result->i_op = &smb_dir_inode_operations;
88 result->i_fop = &smb_dir_operations;
90 insert_inode_hash(result);
91 return result;
95 * Copy the inode data to a smb_fattr structure.
97 void
98 smb_get_inode_attr(struct inode *inode, struct smb_fattr *fattr)
100 memset(fattr, 0, sizeof(struct smb_fattr));
101 fattr->f_mode = inode->i_mode;
102 fattr->f_nlink = inode->i_nlink;
103 fattr->f_ino = inode->i_ino;
104 fattr->f_uid = inode->i_uid;
105 fattr->f_gid = inode->i_gid;
106 fattr->f_rdev = inode->i_rdev;
107 fattr->f_size = inode->i_size;
108 fattr->f_mtime = inode->i_mtime;
109 fattr->f_ctime = inode->i_ctime;
110 fattr->f_atime = inode->i_atime;
111 fattr->f_blksize= inode->i_blksize;
112 fattr->f_blocks = inode->i_blocks;
114 fattr->attr = inode->u.smbfs_i.attr;
116 * Keep the attributes in sync with the inode permissions.
118 if (fattr->f_mode & S_IWUSR)
119 fattr->attr &= ~aRONLY;
120 else
121 fattr->attr |= aRONLY;
124 static void
125 smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr)
127 inode->i_mode = fattr->f_mode;
128 inode->i_nlink = fattr->f_nlink;
129 inode->i_uid = fattr->f_uid;
130 inode->i_gid = fattr->f_gid;
131 inode->i_rdev = fattr->f_rdev;
132 inode->i_ctime = fattr->f_ctime;
133 inode->i_blksize= fattr->f_blksize;
134 inode->i_blocks = fattr->f_blocks;
136 * Don't change the size and mtime/atime fields
137 * if we're writing to the file.
139 if (!(inode->u.smbfs_i.cache_valid & SMB_F_LOCALWRITE))
141 inode->i_size = fattr->f_size;
142 inode->i_mtime = fattr->f_mtime;
143 inode->i_atime = fattr->f_atime;
146 inode->u.smbfs_i.attr = fattr->attr;
148 * Update the "last time refreshed" field for revalidation.
150 inode->u.smbfs_i.oldmtime = jiffies;
154 * This is called if the connection has gone bad ...
155 * try to kill off all the current inodes.
157 void
158 smb_invalidate_inodes(struct smb_sb_info *server)
160 VERBOSE("\n");
161 shrink_dcache_sb(SB_of(server));
162 invalidate_inodes(SB_of(server));
166 * This is called to update the inode attributes after
167 * we've made changes to a file or directory.
169 static int
170 smb_refresh_inode(struct dentry *dentry)
172 struct inode *inode = dentry->d_inode;
173 int error;
174 struct smb_fattr fattr;
176 error = smb_proc_getattr(dentry, &fattr);
177 if (!error)
179 smb_renew_times(dentry);
181 * Check whether the type part of the mode changed,
182 * and don't update the attributes if it did.
184 if ((inode->i_mode & S_IFMT) == (fattr.f_mode & S_IFMT))
185 smb_set_inode_attr(inode, &fattr);
186 else
189 * Big trouble! The inode has become a new object,
190 * so any operations attempted on it are invalid.
192 * To limit damage, mark the inode as bad so that
193 * subsequent lookup validations will fail.
195 PARANOIA("%s/%s changed mode, %07o to %07o\n",
196 DENTRY_PATH(dentry),
197 inode->i_mode, fattr.f_mode);
199 fattr.f_mode = inode->i_mode; /* save mode */
200 make_bad_inode(inode);
201 inode->i_mode = fattr.f_mode; /* restore mode */
203 * No need to worry about unhashing the dentry: the
204 * lookup validation will see that the inode is bad.
205 * But we do want to invalidate the caches ...
207 if (!S_ISDIR(inode->i_mode))
208 invalidate_inode_pages(inode);
209 else
210 smb_invalid_dir_cache(inode);
211 error = -EIO;
214 return error;
218 * This is called when we want to check whether the inode
219 * has changed on the server. If it has changed, we must
220 * invalidate our local caches.
223 smb_revalidate_inode(struct dentry *dentry)
225 struct inode *inode = dentry->d_inode;
226 time_t last_time;
227 int error = 0;
229 DEBUG1("smb_revalidate_inode\n");
231 * If this is a file opened with write permissions,
232 * the inode will be up-to-date.
234 lock_kernel();
235 if (S_ISREG(inode->i_mode) && smb_is_open(inode))
237 if (inode->u.smbfs_i.access != SMB_O_RDONLY)
238 goto out;
242 * Check whether we've recently refreshed the inode.
244 if (time_before(jiffies, inode->u.smbfs_i.oldmtime + HZ/10))
246 VERBOSE("up-to-date, jiffies=%lu, oldtime=%lu\n",
247 jiffies, inode->u.smbfs_i.oldmtime);
248 goto out;
252 * Save the last modified time, then refresh the inode.
253 * (Note: a size change should have a different mtime.)
255 last_time = inode->i_mtime;
256 error = smb_refresh_inode(dentry);
257 if (error || inode->i_mtime != last_time)
259 VERBOSE("%s/%s changed, old=%ld, new=%ld\n",
260 DENTRY_PATH(dentry),
261 (long) last_time, (long) inode->i_mtime);
263 if (!S_ISDIR(inode->i_mode))
264 invalidate_inode_pages(inode);
265 else
266 smb_invalid_dir_cache(inode);
268 out:
269 unlock_kernel();
270 return error;
274 * This routine is called when i_nlink == 0 and i_count goes to 0.
275 * All blocking cleanup operations need to go here to avoid races.
277 static void
278 smb_delete_inode(struct inode *ino)
280 DEBUG1("\n");
281 lock_kernel();
282 if (smb_close(ino))
283 PARANOIA("could not close inode %ld\n", ino->i_ino);
284 unlock_kernel();
285 clear_inode(ino);
288 /* FIXME: flags and has_arg could probably be merged. */
289 struct option opts[] = {
290 { "version", 1, 0, 'v' },
291 { "win95", 0, SMB_MOUNT_WIN95, 1 },
292 { "oldattr", 0, SMB_MOUNT_OLDATTR, 1 },
293 { "dirattr", 0, SMB_MOUNT_DIRATTR, 1 },
294 { "case", 0, SMB_MOUNT_CASE, 1 },
295 { "uid", 1, 0, 'u' },
296 { "gid", 1, 0, 'g' },
297 { "file_mode", 1, 0, 'f' },
298 { "dir_mode", 1, 0, 'd' },
299 { "iocharset", 1, 0, 'i' },
300 { "codepage", 1, 0, 'c' },
301 { NULL, 0, 0, 0}
304 static int
305 parse_options(struct smb_mount_data_kernel *mnt, char *options)
307 int c;
308 unsigned long flags;
309 unsigned long value;
310 char *optarg;
311 char *optopt;
313 flags = 0;
314 while ( (c = smb_getopt("smbfs", &options, opts,
315 &optopt, &optarg, &flags, &value)) > 0) {
317 VERBOSE("'%s' -> '%s'\n", optopt, optarg ? optarg : "<none>");
319 switch (c) {
320 case 1:
321 /* got a "flag" option */
322 break;
323 case 'v':
324 if (value != SMB_MOUNT_VERSION) {
325 printk ("smbfs: Bad mount version %ld, expected %d\n",
326 value, SMB_MOUNT_VERSION);
327 return 0;
329 mnt->version = value;
330 break;
331 case 'u':
332 mnt->uid = value;
333 break;
334 case 'g':
335 mnt->gid = value;
336 break;
337 case 'f':
338 mnt->file_mode = value & (S_IRWXU | S_IRWXG | S_IRWXO);
339 mnt->file_mode |= S_IFREG;
340 break;
341 case 'd':
342 mnt->dir_mode = value & (S_IRWXU | S_IRWXG | S_IRWXO);
343 mnt->dir_mode |= S_IFDIR;
344 break;
345 case 'i':
346 strncpy(mnt->codepage.local_name, optarg,
347 SMB_NLS_MAXNAMELEN);
348 break;
349 case 'c':
350 strncpy(mnt->codepage.remote_name, optarg,
351 SMB_NLS_MAXNAMELEN);
352 break;
353 default:
354 printk ("smbfs: Unrecognized mount option %s\n",
355 optopt);
356 return -1;
359 mnt->flags = flags;
360 return c;
364 static void
365 smb_put_super(struct super_block *sb)
367 struct smb_sb_info *server = &(sb->u.smbfs_sb);
369 if (server->sock_file) {
370 smb_proc_disconnect(server);
371 smb_dont_catch_keepalive(server);
372 fput(server->sock_file);
375 if (server->conn_pid)
376 kill_proc(server->conn_pid, SIGTERM, 1);
378 kfree(server->mnt);
379 kfree(sb->u.smbfs_sb.temp_buf);
380 if (server->packet)
381 smb_vfree(server->packet);
383 if(sb->u.smbfs_sb.remote_nls) {
384 unload_nls(sb->u.smbfs_sb.remote_nls);
385 sb->u.smbfs_sb.remote_nls = NULL;
387 if(sb->u.smbfs_sb.local_nls) {
388 unload_nls(sb->u.smbfs_sb.local_nls);
389 sb->u.smbfs_sb.local_nls = NULL;
393 struct super_block *
394 smb_read_super(struct super_block *sb, void *raw_data, int silent)
396 struct smb_mount_data_kernel *mnt;
397 struct smb_mount_data *oldmnt;
398 struct inode *root_inode;
399 struct smb_fattr root;
400 int ver;
402 if (!raw_data)
403 goto out_no_data;
405 oldmnt = (struct smb_mount_data *) raw_data;
406 ver = oldmnt->version;
407 if (ver != SMB_MOUNT_OLDVERSION && cpu_to_be32(ver) != SMB_MOUNT_ASCII)
408 goto out_wrong_data;
410 sb->s_blocksize = 1024; /* Eh... Is this correct? */
411 sb->s_blocksize_bits = 10;
412 sb->s_magic = SMB_SUPER_MAGIC;
413 sb->s_flags = 0;
414 sb->s_op = &smb_sops;
416 sb->u.smbfs_sb.mnt = NULL;
417 sb->u.smbfs_sb.sock_file = NULL;
418 init_MUTEX(&sb->u.smbfs_sb.sem);
419 init_waitqueue_head(&sb->u.smbfs_sb.wait);
420 sb->u.smbfs_sb.conn_pid = 0;
421 sb->u.smbfs_sb.state = CONN_INVALID; /* no connection yet */
422 sb->u.smbfs_sb.generation = 0;
423 sb->u.smbfs_sb.packet_size = smb_round_length(SMB_INITIAL_PACKET_SIZE);
424 sb->u.smbfs_sb.packet = smb_vmalloc(sb->u.smbfs_sb.packet_size);
425 if (!sb->u.smbfs_sb.packet)
426 goto out_no_mem;
428 /* Allocate the global temp buffer */
429 sb->u.smbfs_sb.temp_buf = kmalloc(2*SMB_MAXPATHLEN + 20, GFP_KERNEL);
430 if (!sb->u.smbfs_sb.temp_buf)
431 goto out_no_temp;
433 /* Setup NLS stuff */
434 sb->u.smbfs_sb.remote_nls = NULL;
435 sb->u.smbfs_sb.local_nls = NULL;
436 sb->u.smbfs_sb.name_buf = sb->u.smbfs_sb.temp_buf + SMB_MAXPATHLEN + 20;
438 /* Allocate the mount data structure */
439 /* FIXME: merge this with the other malloc and get a whole page? */
440 mnt = kmalloc(sizeof(struct smb_mount_data_kernel), GFP_KERNEL);
441 if (!mnt)
442 goto out_no_mount;
443 sb->u.smbfs_sb.mnt = mnt;
445 memset(mnt, 0, sizeof(struct smb_mount_data_kernel));
446 strncpy(mnt->codepage.local_name, CONFIG_NLS_DEFAULT,
447 SMB_NLS_MAXNAMELEN);
448 strncpy(mnt->codepage.remote_name, CONFIG_SMB_NLS_REMOTE,
449 SMB_NLS_MAXNAMELEN);
451 if (ver == SMB_MOUNT_OLDVERSION) {
452 mnt->version = oldmnt->version;
454 /* FIXME: is this enough to convert uid/gid's ? */
455 mnt->mounted_uid = oldmnt->mounted_uid;
456 mnt->uid = oldmnt->uid;
457 mnt->gid = oldmnt->gid;
459 mnt->file_mode =
460 oldmnt->file_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
461 mnt->dir_mode =
462 oldmnt->dir_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
463 mnt->file_mode |= S_IFREG;
464 mnt->dir_mode |= S_IFDIR;
466 mnt->flags = (oldmnt->file_mode >> 9);
467 } else {
468 if (parse_options(mnt, raw_data))
469 goto out_bad_option;
471 mnt->mounted_uid = current->uid;
473 smb_setcodepage(&sb->u.smbfs_sb, &mnt->codepage);
474 if (!sb->u.smbfs_sb.convert)
475 PARANOIA("convert funcptr was NULL!\n");
478 * Display the enabled options
479 * Note: smb_proc_getattr uses these in 2.4 (but was changed in 2.2)
481 if (mnt->flags & SMB_MOUNT_OLDATTR)
482 printk("SMBFS: Using core getattr (Win 95 speedup)\n");
483 else if (mnt->flags & SMB_MOUNT_DIRATTR)
484 printk("SMBFS: Using dir ff getattr\n");
487 * Keep the super block locked while we get the root inode.
489 smb_init_root_dirent(&(sb->u.smbfs_sb), &root);
490 root_inode = smb_iget(sb, &root);
491 if (!root_inode)
492 goto out_no_root;
494 sb->s_root = d_alloc_root(root_inode);
495 if (!sb->s_root)
496 goto out_no_root;
498 return sb;
500 out_no_root:
501 iput(root_inode);
502 out_bad_option:
503 kfree(sb->u.smbfs_sb.mnt);
504 out_no_mount:
505 kfree(sb->u.smbfs_sb.temp_buf);
506 out_no_temp:
507 smb_vfree(sb->u.smbfs_sb.packet);
508 out_no_mem:
509 if (!sb->u.smbfs_sb.mnt)
510 printk(KERN_ERR "smb_read_super: allocation failure\n");
511 goto out_fail;
512 out_wrong_data:
513 printk(KERN_ERR "smbfs: mount_data version %d is not supported\n", ver);
514 goto out_fail;
515 out_no_data:
516 printk(KERN_ERR "smb_read_super: missing data argument\n");
517 out_fail:
518 return NULL;
521 static int
522 smb_statfs(struct super_block *sb, struct statfs *buf)
524 smb_proc_dskattr(sb, buf);
526 buf->f_type = SMB_SUPER_MAGIC;
527 buf->f_namelen = SMB_MAXPATHLEN;
528 return 0;
532 smb_notify_change(struct dentry *dentry, struct iattr *attr)
534 struct inode *inode = dentry->d_inode;
535 struct smb_sb_info *server = server_from_dentry(dentry);
536 unsigned int mask = (S_IFREG | S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO);
537 int error, changed, refresh = 0;
538 struct smb_fattr fattr;
540 error = smb_revalidate_inode(dentry);
541 if (error)
542 goto out;
544 if ((error = inode_change_ok(inode, attr)) < 0)
545 goto out;
547 error = -EPERM;
548 if ((attr->ia_valid & ATTR_UID) && (attr->ia_uid != server->mnt->uid))
549 goto out;
551 if ((attr->ia_valid & ATTR_GID) && (attr->ia_uid != server->mnt->gid))
552 goto out;
554 if ((attr->ia_valid & ATTR_MODE) && (attr->ia_mode & ~mask))
555 goto out;
557 if ((attr->ia_valid & ATTR_SIZE) != 0)
559 VERBOSE("changing %s/%s, old size=%ld, new size=%ld\n",
560 DENTRY_PATH(dentry),
561 (long) inode->i_size, (long) attr->ia_size);
562 error = smb_open(dentry, O_WRONLY);
563 if (error)
564 goto out;
565 error = smb_proc_trunc(server, inode->u.smbfs_i.fileid,
566 attr->ia_size);
567 if (error)
568 goto out;
569 vmtruncate(inode, attr->ia_size);
570 refresh = 1;
574 * Initialize the fattr and check for changed fields.
575 * Note: CTIME under SMB is creation time rather than
576 * change time, so we don't attempt to change it.
578 smb_get_inode_attr(inode, &fattr);
580 changed = 0;
581 if ((attr->ia_valid & ATTR_MTIME) != 0)
583 fattr.f_mtime = attr->ia_mtime;
584 changed = 1;
586 if ((attr->ia_valid & ATTR_ATIME) != 0)
588 fattr.f_atime = attr->ia_atime;
589 /* Earlier protocols don't have an access time */
590 if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2)
591 changed = 1;
593 if (changed)
595 error = smb_proc_settime(dentry, &fattr);
596 if (error)
597 goto out;
598 refresh = 1;
602 * Check for mode changes ... we're extremely limited in
603 * what can be set for SMB servers: just the read-only bit.
605 if ((attr->ia_valid & ATTR_MODE) != 0)
607 VERBOSE("%s/%s mode change, old=%x, new=%x\n",
608 DENTRY_PATH(dentry), fattr.f_mode, attr->ia_mode);
609 changed = 0;
610 if (attr->ia_mode & S_IWUSR)
612 if (fattr.attr & aRONLY)
614 fattr.attr &= ~aRONLY;
615 changed = 1;
617 } else {
618 if (!(fattr.attr & aRONLY))
620 fattr.attr |= aRONLY;
621 changed = 1;
624 if (changed)
626 error = smb_proc_setattr(dentry, &fattr);
627 if (error)
628 goto out;
629 refresh = 1;
632 error = 0;
634 out:
635 if (refresh)
636 smb_refresh_inode(dentry);
637 return error;
640 #ifdef DEBUG_SMB_MALLOC
641 int smb_malloced;
642 int smb_current_kmalloced;
643 int smb_current_vmalloced;
644 #endif
646 static DECLARE_FSTYPE( smb_fs_type, "smbfs", smb_read_super, 0);
648 static int __init init_smb_fs(void)
650 DEBUG1("registering ...\n");
652 #ifdef DEBUG_SMB_MALLOC
653 smb_malloced = 0;
654 smb_current_kmalloced = 0;
655 smb_current_vmalloced = 0;
656 #endif
658 return register_filesystem(&smb_fs_type);
661 static void __exit exit_smb_fs(void)
663 DEBUG1("unregistering ...\n");
664 unregister_filesystem(&smb_fs_type);
665 #ifdef DEBUG_SMB_MALLOC
666 printk(KERN_DEBUG "smb_malloced: %d\n", smb_malloced);
667 printk(KERN_DEBUG "smb_current_kmalloced: %d\n",smb_current_kmalloced);
668 printk(KERN_DEBUG "smb_current_vmalloced: %d\n",smb_current_vmalloced);
669 #endif
672 EXPORT_NO_SYMBOLS;
674 module_init(init_smb_fs)
675 module_exit(exit_smb_fs)