static int nfs_sillyrename(struct inode *dir, const char *name, int len) { struct inode *inode; char silly[16]; int slen, ret; dir->i_count++; if (nfs_lookup(dir, name, len, &inode) < 0) return -EIO; /* arbitrary */ if (inode->i_count == 1 || NFS_RENAMED_DIR(inode)) { iput(inode); return -EIO; } slen = sprintf(silly, ".nfs%ld", inode->i_ino); if (len == slen && !strncmp(name, silly, len)) { iput(inode); return -EIO; /* DWIM */ } ret = nfs_proc_rename(NFS_SERVER(dir), NFS_FH(dir), name, NFS_FH(dir), silly, 0); if (ret >= 0) { nfs_lookup_cache_remove(dir, NULL, name); nfs_lookup_cache_remove(dir, NULL, silly); NFS_RENAMED_DIR(inode) = dir; dir->i_count++; } iput(inode); return ret; }
static int nfs_rename(struct inode *old_dir, const char *old_name, int old_len, struct inode *new_dir, const char *new_name, int new_len, int must_be_dir) { int error; if (!old_dir || !S_ISDIR(old_dir->i_mode)) { printk("nfs_rename: old inode is NULL or not a directory\n"); iput(old_dir); iput(new_dir); return -ENOENT; } if (!new_dir || !S_ISDIR(new_dir->i_mode)) { printk("nfs_rename: new inode is NULL or not a directory\n"); iput(old_dir); iput(new_dir); return -ENOENT; } if (old_len > NFS_MAXNAMLEN || new_len > NFS_MAXNAMLEN) { iput(old_dir); iput(new_dir); return -ENAMETOOLONG; } error = nfs_proc_rename(NFS_SERVER(old_dir), NFS_FH(old_dir), old_name, NFS_FH(new_dir), new_name, must_be_dir); nfs_lookup_cache_remove(old_dir, NULL, old_name); nfs_lookup_cache_remove(new_dir, NULL, new_name); iput(old_dir); iput(new_dir); return error; }
static int nfs_link(struct inode *oldinode, struct inode *dir, const char *name, int len) { int error; if (!oldinode) { printk("nfs_link: old inode is NULL\n"); iput(oldinode); iput(dir); return -ENOENT; } if (!dir || !S_ISDIR(dir->i_mode)) { printk("nfs_link: dir is NULL or not a directory\n"); iput(oldinode); iput(dir); return -ENOENT; } if (len > NFS_MAXNAMLEN) { iput(oldinode); iput(dir); return -ENAMETOOLONG; } error = nfs_proc_link(NFS_SERVER(oldinode), NFS_FH(oldinode), NFS_FH(dir), name); nfs_lookup_cache_remove(dir, oldinode, NULL); NFS_CACHEINV(oldinode); iput(oldinode); iput(dir); return error; }
static int nfs_mkdir(struct inode *dir, const char *name, int len, int mode) { struct nfs_sattr sattr; struct nfs_fattr fattr; struct nfs_fh fhandle; int error; if (!dir || !S_ISDIR(dir->i_mode)) { printk("nfs_mkdir: inode is NULL or not a directory\n"); iput(dir); return -ENOENT; } if (len > NFS_MAXNAMLEN) { iput(dir); return -ENAMETOOLONG; } sattr.mode = mode; sattr.uid = sattr.gid = sattr.size = (unsigned) -1; sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1; error = nfs_proc_mkdir(NFS_SERVER(dir), NFS_FH(dir), name, &sattr, &fhandle, &fattr); if (!error) { if (fattr.fileid == dir->i_ino) printk("Sony NewsOS 4.1R buggy nfs server?\n"); else nfs_lookup_cache_add(dir, name, &fhandle, &fattr); } iput(dir); /* The parent dir link count may have changed */ nfs_lookup_cache_remove( NULL, dir, NULL); return error; }
void nfs_sillyrename_cleanup(struct inode *inode) { struct inode *dir = NFS_RENAMED_DIR(inode); char silly[14]; int error, slen; slen = sprintf(silly, ".nfs%ld", inode->i_ino); error = nfs_proc_remove(NFS_SERVER(dir), NFS_FH(dir), silly); nfs_lookup_cache_remove(dir, NULL, silly); if (error < 0) printk("NFS silly_rename cleanup failed (err = %d)\n", -error); NFS_RENAMED_DIR(inode) = NULL; iput(dir); }
static int nfs_rmdir(struct inode *dir, const char *name, int len) { int error; if (!dir || !S_ISDIR(dir->i_mode)) { printk("nfs_rmdir: inode is NULL or not a directory\n"); iput(dir); return -ENOENT; } if (len > NFS_MAXNAMLEN) { iput(dir); return -ENAMETOOLONG; } error = nfs_proc_rmdir(NFS_SERVER(dir), NFS_FH(dir), name); nfs_lookup_cache_remove(dir, NULL, name); iput(dir); return error; }
static int nfs_mknod(struct inode *dir, const char *name, int len, int mode, int rdev) { struct nfs_sattr sattr; struct nfs_fattr fattr; struct nfs_fh fhandle; int error; if (!dir || !S_ISDIR(dir->i_mode)) { printk("nfs_mknod: inode is NULL or not a directory\n"); iput(dir); return -ENOENT; } if (len > NFS_MAXNAMLEN) { iput(dir); return -ENAMETOOLONG; } if (S_ISFIFO(mode)) sattr.mode = (mode & ~S_IFMT) | S_IFCHR; else sattr.mode = mode; sattr.uid = sattr.gid = (unsigned) -1; if (S_ISCHR(mode) || S_ISBLK(mode)) sattr.size = rdev; /* get out your barf bag */ else sattr.size = (unsigned) -1; sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1; error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir), name, &sattr, &fhandle, &fattr); if (error == -EINVAL && (S_ISFIFO(mode))) { sattr.mode = mode; error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir), name, &sattr, &fhandle, &fattr); } if (!error) { nfs_lookup_cache_add(dir, name, &fhandle, &fattr); /* The parent dir inode count may have changed ! */ nfs_lookup_cache_remove( NULL, dir, NULL); } iput(dir); return error; }