patch-2.4.25 linux-2.4.25/fs/smbfs/dir.c
Next file: linux-2.4.25/fs/smbfs/file.c
Previous file: linux-2.4.25/fs/smbfs/Makefile
Back to the patch index
Back to the overall index
- Lines: 130
- Date:
2004-02-18 05:36:31.000000000 -0800
- Orig file:
linux-2.4.24/fs/smbfs/dir.c
- Orig date:
2001-10-02 17:03:34.000000000 -0700
diff -urN linux-2.4.24/fs/smbfs/dir.c linux-2.4.25/fs/smbfs/dir.c
@@ -30,6 +30,8 @@
static int smb_unlink(struct inode *, struct dentry *);
static int smb_rename(struct inode *, struct dentry *,
struct inode *, struct dentry *);
+static int smb_make_node(struct inode *,struct dentry *, int, int);
+static int smb_link(struct dentry *, struct inode *, struct dentry *);
struct file_operations smb_dir_operations =
{
@@ -51,6 +53,21 @@
setattr: smb_notify_change,
};
+struct inode_operations smb_dir_inode_operations_unix =
+{
+ create: smb_create,
+ lookup: smb_lookup,
+ unlink: smb_unlink,
+ mkdir: smb_mkdir,
+ rmdir: smb_rmdir,
+ rename: smb_rename,
+ revalidate: smb_revalidate_inode,
+ setattr: smb_notify_change,
+ symlink: smb_symlink,
+ mknod: smb_make_node,
+ link: smb_link,
+};
+
/*
* Read a directory, using filldir to fill the dirent memory.
* smb_proc_readdir does the actual reading from the smb server.
@@ -188,7 +205,7 @@
ctl.filled = 0;
ctl.valid = 1;
read_really:
- result = smb_proc_readdir(filp, dirent, filldir, &ctl);
+ result = server->ops->readdir(filp, dirent, filldir, &ctl);
if (ctl.idx == -1)
goto invalid_cache; /* retry */
ctl.head.end = ctl.fpos - 1;
@@ -477,14 +494,22 @@
static int
smb_create(struct inode *dir, struct dentry *dentry, int mode)
{
+ struct smb_sb_info *server = server_from_dentry(dentry);
__u16 fileid;
int error;
+ struct iattr attr;
VERBOSE("creating %s/%s, mode=%d\n", DENTRY_PATH(dentry), mode);
smb_invalid_dir_cache(dir);
error = smb_proc_create(dentry, 0, CURRENT_TIME, &fileid);
if (!error) {
+ if (server->opt.capabilities & SMB_CAP_UNIX) {
+ /* Set attributes for new file */
+ attr.ia_valid = ATTR_MODE;
+ attr.ia_mode = mode;
+ error = smb_proc_setattr_unix(dentry, &attr, 0, 0);
+ }
error = smb_instantiate(dentry, fileid, 1);
} else {
PARANOIA("%s/%s failed, error=%d\n",
@@ -497,11 +522,19 @@
static int
smb_mkdir(struct inode *dir, struct dentry *dentry, int mode)
{
+ struct smb_sb_info *server = server_from_dentry(dentry);
int error;
+ struct iattr attr;
smb_invalid_dir_cache(dir);
error = smb_proc_mkdir(dentry);
if (!error) {
+ if (server->opt.capabilities & SMB_CAP_UNIX) {
+ /* Set attributes for new directory */
+ attr.ia_valid = ATTR_MODE;
+ attr.ia_mode = mode;
+ error = smb_proc_setattr_unix(dentry, &attr, 0, 0);
+ }
error = smb_instantiate(dentry, 0, 0);
}
return error;
@@ -583,3 +616,46 @@
out:
return error;
}
+
+/*
+ * FIXME: samba servers won't let you create device nodes unless uid/gid
+ * matches the connection credentials (and we don't know which those are ...)
+ */
+static int
+smb_make_node(struct inode *dir, struct dentry *dentry, int mode, int dev)
+{
+ int error;
+ struct iattr attr;
+
+ attr.ia_valid = ATTR_MODE | ATTR_UID | ATTR_GID;
+ attr.ia_mode = mode;
+ attr.ia_uid = current->euid;
+ attr.ia_gid = current->egid;
+
+ smb_invalid_dir_cache(dir);
+ error = smb_proc_setattr_unix(dentry, &attr, MAJOR(dev), MINOR(dev));
+ if (!error) {
+ error = smb_instantiate(dentry, 0, 0);
+ }
+ return error;
+}
+
+/*
+ * dentry = existing file
+ * new_dentry = new file
+ */
+static int
+smb_link(struct dentry *dentry, struct inode *dir, struct dentry *new_dentry)
+{
+ int error;
+
+ DEBUG1("smb_link old=%s/%s new=%s/%s\n",
+ DENTRY_PATH(dentry), DENTRY_PATH(new_dentry));
+ smb_invalid_dir_cache(dir);
+ error = smb_proc_link(server_from_dentry(dentry), dentry, new_dentry);
+ if (!error) {
+ smb_renew_times(dentry);
+ error = smb_instantiate(new_dentry, 0, 0);
+ }
+ return error;
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)