patch-2.0.31 linux/fs/smbfs/inode.c
Next file: linux/fs/smbfs/proc.c
Previous file: linux/fs/smbfs/dir.c
Back to the patch index
Back to the overall index
- Lines: 205
- Date:
Mon Sep 15 10:02:41 1997
- Orig file:
v2.0.30/linux/fs/smbfs/inode.c
- Orig date:
Sun Dec 1 05:58:05 1996
diff -u --recursive --new-file v2.0.30/linux/fs/smbfs/inode.c linux/fs/smbfs/inode.c
@@ -59,7 +59,8 @@
{
/* Ok, now we're in trouble. The inode info is not
there. What should we do now??? */
- printk("smb_read_inode: inode info not found\n");
+ printk("smb_read_inode: inode %ld info not found\n",
+ inode->i_ino);
return;
}
inode_info->state = SMB_INODE_VALID;
@@ -92,24 +93,43 @@
static void
smb_put_inode(struct inode *inode)
{
- struct smb_dirent *finfo = SMB_FINFO(inode);
struct smb_server *server = SMB_SERVER(inode);
struct smb_inode_info *info = SMB_INOP(inode);
+ struct smb_dirent *finfo;
+ __u32 mtime = inode->i_mtime;
+
+ if (inode->i_count > 1) {
+ printk("smb_put_inode: in use device %s, inode %ld count=%d\n",
+ kdevname(inode->i_dev), inode->i_ino, inode->i_count);
+ return;
+ }
if (S_ISDIR(inode->i_mode))
{
smb_invalid_dir_cache(inode->i_ino);
}
- if (finfo->opened != 0)
- {
- if (smb_proc_close(server, finfo->fileid, inode->i_mtime))
+ clear_inode(inode);
+
+ /*
+ * We don't want the inode to be reused as free if we block here,
+ * so temporarily increment i_count.
+ */
+ inode->i_count++;
+ if (info) {
+ finfo = &info->finfo;
+ if (finfo->opened != 0)
{
- /* We can't do anything but complain. */
- DPRINTK("smb_put_inode: could not close\n");
+ if (smb_proc_close(server, finfo->fileid, mtime))
+ {
+ /* We can't do anything but complain. */
+ printk("smb_put_inode: could not close\n");
+ }
}
- }
- smb_free_inode_info(info);
- clear_inode(inode);
+ smb_free_inode_info(info);
+ } else
+ printk("smb_put_inode: no inode info??\n");
+
+ inode->i_count--;
}
static void
@@ -212,10 +232,13 @@
kdev_t dev = sb->s_dev;
int error;
+ MOD_INC_USE_COUNT;
+
if (smb_get_mount_data(&data, raw_data) != 0)
{
printk("smb_read_super: wrong data argument\n");
sb->s_dev = 0;
+ MOD_DEC_USE_COUNT;
return NULL;
}
fd = data.fd;
@@ -223,12 +246,14 @@
{
printk("smb_read_super: invalid file descriptor\n");
sb->s_dev = 0;
+ MOD_DEC_USE_COUNT;
return NULL;
}
if (!S_ISSOCK(filp->f_inode->i_mode))
{
printk("smb_read_super: not a socket!\n");
sb->s_dev = 0;
+ MOD_DEC_USE_COUNT;
return NULL;
}
/* We must malloc our own super-block info */
@@ -238,6 +263,8 @@
if (smb_sb == NULL)
{
printk("smb_read_super: could not alloc smb_sb_info\n");
+ sb->s_dev = 0;
+ MOD_DEC_USE_COUNT;
return NULL;
}
filp->f_count += 1;
@@ -308,7 +335,6 @@
printk("smb_read_super: get root inode failed\n");
goto fail;
}
- MOD_INC_USE_COUNT;
return sb;
fail:
@@ -320,6 +346,7 @@
filp->f_count -= 1;
smb_dont_catch_keepalive(server);
smb_kfree_s(SMB_SBP(sb), sizeof(struct smb_sb_info));
+ MOD_DEC_USE_COUNT;
return NULL;
}
@@ -362,12 +389,35 @@
return -EPERM;
if (((attr->ia_valid & ATTR_GID) &&
- (attr->ia_uid != SMB_SERVER(inode)->m.gid)))
+ (attr->ia_gid != SMB_SERVER(inode)->m.gid)))
return -EPERM;
- if (((attr->ia_valid & ATTR_MODE) &&
- (attr->ia_mode & ~(S_IFREG | S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO))))
- return -EPERM;
+ if (attr->ia_valid & ATTR_MODE) {
+ struct smb_dirent *fold = SMB_FINFO(inode);
+ struct smb_dirent finfo;
+
+ if (attr->ia_mode & ~(S_IFREG | S_IFDIR |
+ S_IRWXU | S_IRWXG | S_IRWXO))
+ return -EPERM;
+
+ memset((char *)&finfo, 0, sizeof(finfo));
+ finfo.attr = fold->attr;
+
+ if((attr->ia_mode & 0200) == 0)
+ finfo.attr |= aRONLY;
+ else
+ finfo.attr &= ~aRONLY;
+
+ if ((error = smb_proc_setattr(SMB_SERVER(inode),
+ inode, &finfo)) >= 0)
+ {
+ fold->attr = finfo.attr;
+ if ((attr->ia_mode & 0200) == 0)
+ inode->i_mode &= ~0222;
+ else
+ inode->i_mode |= 0222;
+ }
+ }
if ((attr->ia_valid & ATTR_SIZE) != 0)
{
@@ -381,41 +431,18 @@
goto fail;
}
- if ((attr->ia_valid & (ATTR_CTIME | ATTR_MTIME | ATTR_ATIME)) != 0)
- {
-
- struct smb_dirent finfo;
-
- finfo.attr = 0;
- finfo.f_size = inode->i_size;
- finfo.f_blksize = inode->i_blksize;
- if ((attr->ia_valid & ATTR_CTIME) != 0)
- finfo.f_ctime = attr->ia_ctime;
- else
- finfo.f_ctime = inode->i_ctime;
-
- if ((attr->ia_valid & ATTR_MTIME) != 0)
- finfo.f_mtime = attr->ia_mtime;
- else
- finfo.f_mtime = inode->i_mtime;
+ /* ATTR_CTIME and ATTR_ATIME can not be set via SMB, so ignore it. */
- if ((attr->ia_valid & ATTR_ATIME) != 0)
- finfo.f_atime = attr->ia_atime;
+ if (attr->ia_valid & ATTR_MTIME)
+ {
+ if (smb_make_open(inode, O_WRONLY) != 0)
+ error = -EACCES;
else
- finfo.f_atime = inode->i_atime;
-
- if ((error = smb_proc_setattr(SMB_SERVER(inode),
- inode, &finfo)) >= 0)
- {
- inode->i_ctime = finfo.f_ctime;
- inode->i_mtime = finfo.f_mtime;
- inode->i_atime = finfo.f_atime;
- }
+ inode->i_mtime = attr->ia_mtime;
}
fail:
smb_invalid_dir_cache(smb_info_ino(SMB_INOP(inode)->dir));
-
return error;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov